Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-08-25 12:12:20 +00:00
parent 86ace8a66c
commit 73507eaf1a
154 changed files with 1160 additions and 1017 deletions

View File

@ -602,9 +602,6 @@ Style/MultilineWhenThen:
Style/NumericPredicate:
EnforcedStyle: comparison
Style/FloatDivision:
Enabled: false
Cop/BanCatchThrow:
Enabled: true

View File

@ -0,0 +1,8 @@
---
Style/FloatDivision:
Exclude:
- 'ee/app/models/geo_node_status.rb'
- 'ee/app/models/namespaces/storage/root_size.rb'
- 'lib/learn_gitlab/onboarding.rb'
- 'qa/qa/support/formatters/allure_metadata_formatter.rb'
- 'qa/qa/tools/reliable_report.rb'

View File

@ -1,11 +1,11 @@
<script>
import { GlLoadingIcon } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
import notebookLab from '~/notebook/index.vue';
import NotebookLab from '~/notebook/index.vue';
export default {
components: {
notebookLab,
NotebookLab,
GlLoadingIcon,
},
props: {

View File

@ -11,11 +11,11 @@ import {
import addAdminVariable from '../graphql/mutations/admin_add_variable.mutation.graphql';
import deleteAdminVariable from '../graphql/mutations/admin_delete_variable.mutation.graphql';
import updateAdminVariable from '../graphql/mutations/admin_update_variable.mutation.graphql';
import ciVariableSettings from './ci_variable_settings.vue';
import CiVariableSettings from './ci_variable_settings.vue';
export default {
components: {
ciVariableSettings,
CiVariableSettings,
},
inject: ['endpoint'],
data() {

View File

@ -14,11 +14,11 @@ import {
import addGroupVariable from '../graphql/mutations/group_add_variable.mutation.graphql';
import deleteGroupVariable from '../graphql/mutations/group_delete_variable.mutation.graphql';
import updateGroupVariable from '../graphql/mutations/group_update_variable.mutation.graphql';
import ciVariableSettings from './ci_variable_settings.vue';
import CiVariableSettings from './ci_variable_settings.vue';
export default {
components: {
ciVariableSettings,
CiVariableSettings,
},
mixins: [glFeatureFlagsMixin()],
inject: ['endpoint', 'groupPath', 'groupId'],

View File

@ -16,11 +16,11 @@ import {
import addProjectVariable from '../graphql/mutations/project_add_variable.mutation.graphql';
import deleteProjectVariable from '../graphql/mutations/project_delete_variable.mutation.graphql';
import updateProjectVariable from '../graphql/mutations/project_update_variable.mutation.graphql';
import ciVariableSettings from './ci_variable_settings.vue';
import CiVariableSettings from './ci_variable_settings.vue';
export default {
components: {
ciVariableSettings,
CiVariableSettings,
},
inject: ['endpoint', 'projectFullPath', 'projectId'],
data() {

View File

@ -108,7 +108,6 @@ export default {
return {
newEnvironments: [],
isTipDismissed: getCookie(AWS_TIP_DISMISSED_COOKIE_NAME) === 'true',
typeOptions: variableOptions,
validationErrorEventProperty: '',
variable: { ...defaultVariableState, ...this.selectedVariable },
};
@ -259,6 +258,7 @@ export default {
},
},
defaultScope: allEnvironments.text,
variableOptions,
};
</script>
@ -298,16 +298,20 @@ export default {
/>
</gl-form-group>
<div class="d-flex">
<gl-form-group :label="__('Type')" label-for="ci-variable-type" class="w-50 gl-mr-5">
<div class="gl-display-flex">
<gl-form-group :label="__('Type')" label-for="ci-variable-type" class="gl-w-half gl-mr-5">
<gl-form-select
id="ci-variable-type"
v-model="variable.variableType"
:options="typeOptions"
:options="$options.variableOptions"
/>
</gl-form-group>
<gl-form-group label-for="ci-variable-env" class="w-50" data-testid="environment-scope">
<gl-form-group
label-for="ci-variable-env"
class="gl-w-half"
data-testid="environment-scope"
>
<template #label>
{{ __('Environment scope') }}
<gl-link

View File

@ -10,7 +10,7 @@ export const displayText = {
};
export const variableTypes = {
variableType: 'ENV_VAR',
envType: 'ENV_VAR',
fileType: 'FILE',
};
@ -29,13 +29,13 @@ export const allEnvironments = {
export const variableText = {
[types.variableType]: __('Variable'),
[types.fileType]: __('File'),
[variableTypes.variableType]: __('Variable'),
[variableTypes.envType]: __('Variable'),
[variableTypes.fileType]: __('File'),
};
export const variableOptions = [
{ value: types.variableType, text: variableText[types.variableType] },
{ value: types.fileType, text: variableText[types.fileType] },
{ value: variableTypes.envType, text: variableText[variableTypes.envType] },
{ value: variableTypes.fileType, text: variableText[variableTypes.fileType] },
];
export const defaultVariableState = {
@ -44,7 +44,7 @@ export const defaultVariableState = {
masked: false,
protected: false,
value: '',
variableType: types.variableType,
variableType: variableTypes.envType,
};
// eslint-disable-next-line @gitlab/require-i18n-strings

View File

@ -5,3 +5,7 @@ export const trackViewsOptions = {
category: 'Customer Relations' /* eslint-disable-line @gitlab/require-i18n-strings */,
action: 'view_contacts_list',
};
export const organizationTrackViewsOptions = {
category: 'Customer Relations' /* eslint-disable-line @gitlab/require-i18n-strings */,
action: 'view_organizations_list',
};

View File

@ -3,6 +3,7 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo';
import VueRouter from 'vue-router';
import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
import CrmOrganizationsRoot from './components/organizations_root.vue';
import routes from './routes';
@ -21,7 +22,14 @@ export default () => {
return false;
}
const { basePath, canAdminCrmOrganization, groupFullPath, groupId, groupIssuesPath } = el.dataset;
const {
basePath,
canAdminCrmOrganization,
groupFullPath,
groupId,
groupIssuesPath,
textQuery,
} = el.dataset;
const router = new VueRouter({
base: basePath,
@ -33,7 +41,13 @@ export default () => {
el,
router,
apolloProvider,
provide: { canAdminCrmOrganization, groupFullPath, groupId, groupIssuesPath },
provide: {
canAdminCrmOrganization: parseBoolean(canAdminCrmOrganization),
groupFullPath,
groupId,
groupIssuesPath,
textQuery,
},
render(createElement) {
return createElement(CrmOrganizationsRoot);
},

View File

@ -1,12 +1,37 @@
#import "./crm_organization_fields.fragment.graphql"
query organizations($groupFullPath: ID!) {
query organizations(
$groupFullPath: ID!
$state: CustomerRelationsOrganizationState
$searchTerm: String
$sort: OrganizationSort
$firstPageSize: Int
$lastPageSize: Int
$prevPageCursor: String = ""
$nextPageCursor: String = ""
$ids: [CustomerRelationsOrganizationID!]
) {
group(fullPath: $groupFullPath) {
id
organizations {
organizations(
state: $state
search: $searchTerm
sort: $sort
first: $firstPageSize
last: $lastPageSize
after: $nextPageCursor
before: $prevPageCursor
ids: $ids
) {
nodes {
...OrganizationFragment
}
pageInfo {
hasNextPage
endCursor
hasPreviousPage
startCursor
}
}
}
}

View File

@ -0,0 +1,11 @@
query organizationsCountByState($groupFullPath: ID!, $searchTerm: String) {
group(fullPath: $groupFullPath) {
__typename
id
organizationStateCounts(search: $searchTerm) {
all
active
inactive
}
}
}

View File

@ -36,7 +36,7 @@ export default {
getQuery() {
return {
query: getGroupOrganizationsQuery,
variables: { groupFullPath: this.groupFullPath },
variables: { groupFullPath: this.groupFullPath, ids: [this.organizationGraphQLId] },
};
},
title() {

View File

@ -1,36 +1,54 @@
<script>
import { GlAlert, GlButton, GlLoadingIcon, GlTable, GlTooltipDirective } from '@gitlab/ui';
import { parseBoolean } from '~/lib/utils/common_utils';
import { GlButton, GlLoadingIcon, GlTable, GlTooltipDirective } from '@gitlab/ui';
import { s__, __ } from '~/locale';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { EDIT_ROUTE_NAME, NEW_ROUTE_NAME } from '../../constants';
import PaginatedTableWithSearchAndTabs from '~/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue';
import {
bodyTrClass,
initialPaginationState,
} from '~/vue_shared/components/paginated_table_with_search_and_tabs/constants';
import { convertToSnakeCase } from '~/lib/utils/text_utility';
import { EDIT_ROUTE_NAME, NEW_ROUTE_NAME, organizationTrackViewsOptions } from '../../constants';
import getGroupOrganizationsQuery from './graphql/get_group_organizations.query.graphql';
import getGroupOrganizationsCountByStateQuery from './graphql/get_group_organizations_count_by_state.query.graphql';
export default {
components: {
GlAlert,
GlButton,
GlLoadingIcon,
GlTable,
PaginatedTableWithSearchAndTabs,
},
directives: {
GlTooltip: GlTooltipDirective,
},
inject: ['canAdminCrmOrganization', 'groupFullPath', 'groupIssuesPath'],
inject: ['canAdminCrmOrganization', 'groupFullPath', 'groupIssuesPath', 'textQuery'],
data() {
return {
organizations: [],
organizations: { list: [] },
organizationsCount: {},
error: false,
filteredByStatus: '',
pagination: initialPaginationState,
statusFilter: 'all',
searchTerm: this.textQuery,
sort: 'NAME_ASC',
sortDesc: false,
};
},
apollo: {
organizations: {
query() {
return getGroupOrganizationsQuery;
},
query: getGroupOrganizationsQuery,
variables() {
return {
groupFullPath: this.groupFullPath,
searchTerm: this.searchTerm,
state: this.statusFilter,
sort: this.sort,
firstPageSize: this.pagination.firstPageSize,
lastPageSize: this.pagination.lastPageSize,
prevPageCursor: this.pagination.prevPageCursor,
nextPageCursor: this.pagination.nextPageCursor,
};
},
update(data) {
@ -40,19 +58,52 @@ export default {
this.error = true;
},
},
organizationsCount: {
query: getGroupOrganizationsCountByStateQuery,
variables() {
return {
groupFullPath: this.groupFullPath,
searchTerm: this.searchTerm,
};
},
update(data) {
return data?.group?.organizationStateCounts;
},
error() {
this.error = true;
},
},
},
computed: {
isLoading() {
return this.$apollo.queries.organizations.loading;
},
canAdmin() {
return parseBoolean(this.canAdminCrmOrganization);
tbodyTrClass() {
return {
[bodyTrClass]: !this.loading && !this.isEmpty,
};
},
},
methods: {
errorAlertDismissed() {
this.error = false;
},
extractOrganizations(data) {
const organizations = data?.group?.organizations?.nodes || [];
return organizations.slice().sort((a, b) => a.name.localeCompare(b.name));
const pageInfo = data?.group?.organizations?.pageInfo || {};
return {
list: organizations,
pageInfo,
};
},
fetchSortedData({ sortBy, sortDesc }) {
const sortingColumn = convertToSnakeCase(sortBy).toUpperCase();
const sortingDirection = sortDesc ? 'DESC' : 'ASC';
this.pagination = initialPaginationState;
this.sort = `${sortingColumn}_${sortingDirection}`;
},
filtersChanged({ searchTerm }) {
this.searchTerm = searchTerm;
},
getIssuesPath(path, value) {
return `${path}?crm_organization_id=${value}`;
@ -60,6 +111,13 @@ export default {
getEditRoute(id) {
return { name: this.$options.EDIT_ROUTE_NAME, params: { id } };
},
pageChanged(pagination) {
this.pagination = pagination;
},
statusChanged({ filters, status }) {
this.statusFilter = filters;
this.filteredByStatus = status;
},
},
fields: [
{ key: 'name', sortable: true },
@ -83,60 +141,113 @@ export default {
},
EDIT_ROUTE_NAME,
NEW_ROUTE_NAME,
statusTabs: [
{
title: __('Active'),
status: 'ACTIVE',
filters: 'active',
},
{
title: __('Inactive'),
status: 'INACTIVE',
filters: 'inactive',
},
{
title: __('All'),
status: 'ALL',
filters: 'all',
},
],
organizationTrackViewsOptions,
emptyArray: [],
};
</script>
<template>
<div>
<gl-alert v-if="error" variant="danger" class="gl-mt-6" @dismiss="error = false">
{{ $options.i18n.errorText }}
</gl-alert>
<div
class="gl-display-flex gl-align-items-baseline gl-flex-direction-row gl-justify-content-space-between gl-mt-6"
<paginated-table-with-search-and-tabs
:show-items="true"
:show-error-msg="false"
:i18n="$options.i18n"
:items="organizations.list"
:page-info="organizations.pageInfo"
:items-count="organizationsCount"
:status-tabs="$options.statusTabs"
:track-views-options="$options.organizationTrackViewsOptions"
:filter-search-tokens="$options.emptyArray"
filter-search-key="organizations"
@page-changed="pageChanged"
@tabs-changed="statusChanged"
@filters-changed="filtersChanged"
@error-alert-dismissed="errorAlertDismissed"
>
<h2 class="gl-font-size-h2 gl-my-0">
{{ $options.i18n.title }}
</h2>
<div
v-if="canAdmin"
class="gl-display-none gl-md-display-flex gl-align-items-center gl-justify-content-end"
>
<router-link :to="{ name: $options.NEW_ROUTE_NAME }">
<gl-button variant="confirm" data-testid="new-organization-button">
<template #header-actions>
<router-link v-if="canAdminCrmOrganization" :to="{ name: $options.NEW_ROUTE_NAME }">
<gl-button
class="gl-my-3 gl-mr-5"
variant="confirm"
data-testid="new-organization-button"
>
{{ $options.i18n.newOrganization }}
</gl-button>
</router-link>
</div>
</div>
<router-view />
<gl-loading-icon v-if="isLoading" class="gl-mt-5" size="lg" />
<gl-table
v-else
class="gl-mt-5"
:items="organizations"
:fields="$options.fields"
:empty-text="$options.i18n.emptyText"
show-empty
>
<template #cell(id)="{ value: id }">
<gl-button
v-gl-tooltip.hover.bottom="$options.i18n.issuesButtonLabel"
class="gl-mr-3"
data-testid="issues-link"
icon="issues"
:aria-label="$options.i18n.issuesButtonLabel"
:href="getIssuesPath(groupIssuesPath, id)"
/>
<router-link :to="getEditRoute(id)">
<gl-button
v-if="canAdmin"
v-gl-tooltip.hover.bottom="$options.i18n.editButtonLabel"
data-testid="edit-organization-button"
icon="pencil"
:aria-label="$options.i18n.editButtonLabel"
/>
</router-link>
</template>
</gl-table>
<template #title>
{{ $options.i18n.title }}
</template>
<template #table>
<gl-table
:items="organizations.list"
:fields="$options.fields"
:busy="isLoading"
stacked="md"
:tbody-tr-class="tbodyTrClass"
sort-direction="asc"
:sort-desc.sync="sortDesc"
sort-by="createdAt"
show-empty
no-local-sorting
sort-icon-left
fixed
@sort-changed="fetchSortedData"
>
<template #cell(id)="{ value: id }">
<gl-button
v-gl-tooltip.hover.bottom="$options.i18n.issuesButtonLabel"
class="gl-mr-3"
data-testid="issues-link"
icon="issues"
:aria-label="$options.i18n.issuesButtonLabel"
:href="getIssuesPath(groupIssuesPath, id)"
/>
<router-link :to="getEditRoute(id)">
<gl-button
v-if="canAdminCrmOrganization"
v-gl-tooltip.hover.bottom="$options.i18n.editButtonLabel"
data-testid="edit-organization-button"
icon="pencil"
:aria-label="$options.i18n.editButtonLabel"
/>
</router-link>
</template>
<template #table-busy>
<gl-loading-icon size="lg" color="dark" class="mt-3" />
</template>
<template #empty>
<span v-if="error">
{{ $options.i18n.errorText }}
</span>
<span v-else>
{{ $options.i18n.emptyText }}
</span>
</template>
</gl-table>
</template>
</paginated-table-with-search-and-tabs>
<router-view />
</div>
</template>

View File

@ -4,11 +4,11 @@ import { head, tail } from 'lodash';
import { s__, sprintf } from '~/locale';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import actionBtn from './action_btn.vue';
import ActionBtn from './action_btn.vue';
export default {
components: {
actionBtn,
ActionBtn,
GlButton,
GlIcon,
GlLink,

View File

@ -1,9 +1,9 @@
<script>
import deployKey from './key.vue';
import DeployKey from './key.vue';
export default {
components: {
deployKey,
DeployKey,
},
props: {
keys: {

View File

@ -1,11 +1,11 @@
import Vue from 'vue';
import deployKeysApp from './components/app.vue';
import DeployKeysApp from './components/app.vue';
export default () =>
new Vue({
el: document.getElementById('js-deploy-keys'),
components: {
deployKeysApp,
DeployKeysApp,
},
data() {
return {

View File

@ -11,7 +11,7 @@ import NoPreviewViewer from '~/vue_shared/components/diff_viewer/viewers/no_prev
import NotDiffableViewer from '~/vue_shared/components/diff_viewer/viewers/not_diffable.vue';
import NoteForm from '~/notes/components/note_form.vue';
import eventHub from '~/notes/event_hub';
import userAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import { IMAGE_DIFF_POSITION_TYPE } from '../constants';
import { getDiffMode } from '../store/utils';
import DiffDiscussions from './diff_discussions.vue';
@ -28,7 +28,7 @@ export default {
ImageDiffOverlay,
NotDiffableViewer,
NoPreviewViewer,
userAvatarLink,
UserAvatarLink,
DiffFileDrafts,
},
mixins: [diffLineNoteFormMixin, draftCommentsMixin],

View File

@ -2,11 +2,11 @@
import { GlIcon } from '@gitlab/ui';
import { mapActions } from 'vuex';
import DesignNotePin from '~/vue_shared/components/design_management/design_note_pin.vue';
import noteableDiscussion from '~/notes/components/noteable_discussion.vue';
import NoteableDiscussion from '~/notes/components/noteable_discussion.vue';
export default {
components: {
noteableDiscussion,
NoteableDiscussion,
GlIcon,
DesignNotePin,
},

View File

@ -7,7 +7,7 @@ import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import MultilineCommentForm from '~/notes/components/multiline_comment_form.vue';
import { commentLineOptions, formatLineRange } from '~/notes/components/multiline_comment_utils';
import noteForm from '~/notes/components/note_form.vue';
import NoteForm from '~/notes/components/note_form.vue';
import autosave from '~/notes/mixins/autosave';
import {
DIFF_NOTE_TYPE,
@ -18,7 +18,7 @@ import {
export default {
components: {
noteForm,
NoteForm,
MultilineCommentForm,
},
mixins: [autosave, diffLineNoteFormMixin, glFeatureFlagsMixin()],

View File

@ -3,7 +3,7 @@ import { mapActions, mapState, mapGetters } from 'vuex';
import { getCookie, parseBoolean, removeCookie } from '~/lib/utils/common_utils';
import eventHub from '../notes/event_hub';
import diffsApp from './components/app.vue';
import DiffsApp from './components/app.vue';
import { TREE_LIST_STORAGE_KEY, DIFF_WHITESPACE_COOKIE_NAME } from './constants';
import { getReviewsForMergeRequest } from './utils/file_reviews';
@ -14,7 +14,7 @@ export default function initDiffsApp(store) {
el: '#js-diffs-app',
name: 'MergeRequestDiffs',
components: {
diffsApp,
DiffsApp,
},
store,
data() {

View File

@ -20,13 +20,13 @@ import {
} from '@gitlab/ui';
import { isEmpty } from 'lodash';
import { s__, n__ } from '~/locale';
import instanceComponent from '~/vue_shared/components/deployment_instance.vue';
import InstanceComponent from '~/vue_shared/components/deployment_instance.vue';
import { STATUS_MAP, CANARY_STATUS } from '../constants';
import CanaryIngress from './canary_ingress.vue';
export default {
components: {
instanceComponent,
InstanceComponent,
CanaryIngress,
GlIcon,
GlLoadingIcon,

View File

@ -2,7 +2,7 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import Translate from '~/vue_shared/translate';
import environmentsFolderApp from './environments_folder_view.vue';
import EnvironmentsFolderApp from './environments_folder_view.vue';
Vue.use(Translate);
Vue.use(VueApollo);
@ -17,7 +17,7 @@ export default () => {
return new Vue({
el,
components: {
environmentsFolderApp,
EnvironmentsFolderApp,
},
apolloProvider,
provide: {

View File

@ -21,10 +21,10 @@ import { VISIBILITY_TYPE_ICON, GROUP_VISIBILITY_TYPE, ITEM_TYPE } from '../const
import eventHub from '../event_hub';
import itemActions from './item_actions.vue';
import itemCaret from './item_caret.vue';
import itemStats from './item_stats.vue';
import itemTypeIcon from './item_type_icon.vue';
import ItemActions from './item_actions.vue';
import ItemCaret from './item_caret.vue';
import ItemStats from './item_stats.vue';
import ItemTypeIcon from './item_type_icon.vue';
export default {
directives: {
@ -41,10 +41,10 @@ export default {
GlPopover,
GlLink,
UserAccessRoleBadge,
itemCaret,
itemTypeIcon,
itemActions,
itemStats,
ItemCaret,
ItemTypeIcon,
ItemActions,
ItemStats,
},
inject: ['currentGroupVisibility'],
props: {

View File

@ -1,19 +1,19 @@
<script>
import { GlBadge } from '@gitlab/ui';
import isProjectPendingRemoval from 'ee_else_ce/groups/mixins/is_project_pending_removal';
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import {
ITEM_TYPE,
VISIBILITY_TYPE_ICON,
GROUP_VISIBILITY_TYPE,
PROJECT_VISIBILITY_TYPE,
} from '../constants';
import itemStatsValue from './item_stats_value.vue';
import ItemStatsValue from './item_stats_value.vue';
export default {
components: {
timeAgoTooltip,
itemStatsValue,
TimeAgoTooltip,
ItemStatsValue,
GlBadge,
},
mixins: [isProjectPendingRemoval],

View File

@ -4,9 +4,9 @@ import { parseBoolean } from '~/lib/utils/common_utils';
import UserCallout from '~/user_callout';
import Translate from '../vue_shared/translate';
import groupsApp from './components/app.vue';
import groupFolderComponent from './components/group_folder.vue';
import groupItemComponent from './components/group_item.vue';
import GroupsApp from './components/app.vue';
import GroupFolderComponent from './components/group_folder.vue';
import GroupItemComponent from './components/group_item.vue';
import { GROUPS_LIST_HOLDER_CLASS, CONTENT_LIST_CLASS } from './constants';
import GroupFilterableList from './groups_filterable_list';
import GroupsService from './service/groups_service';
@ -33,8 +33,8 @@ export default (containerId = 'js-groups-tree', endpoint, action = '') => {
dataEl = containerEl.querySelector(CONTENT_LIST_CLASS);
}
Vue.component('GroupFolder', groupFolderComponent);
Vue.component('GroupItem', groupItemComponent);
Vue.component('GroupFolder', GroupFolderComponent);
Vue.component('GroupItem', GroupItemComponent);
Vue.use(GlToast);
@ -42,7 +42,7 @@ export default (containerId = 'js-groups-tree', endpoint, action = '') => {
new Vue({
el,
components: {
groupsApp,
GroupsApp,
},
provide() {
const {

View File

@ -26,11 +26,17 @@ export const GROUPS_CATEGORY = s__('GlobalSearch|Groups');
export const PROJECTS_CATEGORY = s__('GlobalSearch|Projects');
export const ISSUES_CATEGORY = 'Recent issues';
export const ISSUES_CATEGORY = s__('GlobalSearch|Recent issues');
export const MERGE_REQUEST_CATEGORY = 'Recent merge requests';
export const MERGE_REQUEST_CATEGORY = s__('GlobalSearch|Recent merge requests');
export const RECENT_EPICS_CATEGORY = 'Recent epics';
export const RECENT_EPICS_CATEGORY = s__('GlobalSearch|Recent epics');
export const IN_THIS_PROJECT_CATEGORY = s__('GlobalSearch|In this project');
export const SETTINGS_CATEGORY = s__('GlobalSearch|Settings');
export const HELP_CATEGORY = s__('GlobalSearch|Help');
export const LARGE_AVATAR_PX = 32;
@ -55,3 +61,16 @@ export const HEADER_INIT_EVENTS = ['input', 'focus'];
export const IS_SEARCHING = 'is-searching';
export const IS_FOCUSED = 'is-focused';
export const IS_NOT_FOCUSED = 'is-not-focused';
export const DROPDOWN_ORDER = [
MERGE_REQUEST_CATEGORY,
ISSUES_CATEGORY,
RECENT_EPICS_CATEGORY,
GROUPS_CATEGORY,
PROJECTS_CATEGORY,
IN_THIS_PROJECT_CATEGORY,
SETTINGS_CATEGORY,
HELP_CATEGORY,
];
export const FETCH_TYPES = ['generic', 'search'];

View File

@ -1,10 +1,26 @@
import { omitBy, isNil } from 'lodash';
import { objectToQuery } from '~/lib/utils/url_utility';
import axios from '~/lib/utils/axios_utils';
import { FETCH_TYPES } from '../constants';
import * as types from './mutation_types';
export const fetchAutocompleteOptions = ({ commit, getters }) => {
commit(types.REQUEST_AUTOCOMPLETE);
export const autocompleteQuery = ({ state, fetchType }) => {
const query = omitBy(
{
term: state.search,
project_id: state.searchContext?.project?.id,
project_ref: state.searchContext?.ref,
filter: fetchType,
},
isNil,
);
return `${state.autocompletePath}?${objectToQuery(query)}`;
};
const doFetch = ({ commit, state, fetchType }) => {
return axios
.get(getters.autocompleteQuery)
.get(autocompleteQuery({ state, fetchType }))
.then(({ data }) => {
commit(types.RECEIVE_AUTOCOMPLETE_SUCCESS, data);
})
@ -13,6 +29,13 @@ export const fetchAutocompleteOptions = ({ commit, getters }) => {
});
};
export const fetchAutocompleteOptions = ({ commit, state }) => {
commit(types.REQUEST_AUTOCOMPLETE);
const promises = FETCH_TYPES.map((fetchType) => doFetch({ commit, state, fetchType }));
return Promise.all(promises);
};
export const clearAutocomplete = ({ commit }) => {
commit(types.CLEAR_AUTOCOMPLETE);
};

View File

@ -14,6 +14,7 @@ import {
PROJECTS_CATEGORY,
GROUPS_CATEGORY,
SEARCH_SHORTCUTS_MIN_CHARACTERS,
DROPDOWN_ORDER,
} from '../constants';
export const searchQuery = (state) => {
@ -34,19 +35,6 @@ export const searchQuery = (state) => {
return `${state.searchPath}?${objectToQuery(query)}`;
};
export const autocompleteQuery = (state) => {
const query = omitBy(
{
term: state.search,
project_id: state.searchContext?.project?.id,
project_ref: state.searchContext?.ref,
},
isNil,
);
return `${state.autocompletePath}?${objectToQuery(query)}`;
};
export const scopedIssuesPath = (state) => {
return (
state.searchContext?.project_metadata?.issues_path ||
@ -197,7 +185,9 @@ export const autocompleteGroupedSearchOptions = (state) => {
}
});
return results;
return results.sort(
(a, b) => DROPDOWN_ORDER.indexOf(a.category) - DROPDOWN_ORDER.indexOf(b.category),
);
};
export const searchOptions = (state, getters) => {

View File

@ -8,9 +8,11 @@ export default {
},
[types.RECEIVE_AUTOCOMPLETE_SUCCESS](state, data) {
state.loading = false;
state.autocompleteOptions = data.map((d, i) => {
return { html_id: `autocomplete-${d.category}-${i}`, ...d };
});
state.autocompleteOptions = [...state.autocompleteOptions].concat(
data.map((d, i) => {
return { html_id: `autocomplete-${d.category}-${i}`, ...d };
}),
);
state.autocompleteError = false;
},
[types.RECEIVE_AUTOCOMPLETE_ERROR](state) {

View File

@ -4,7 +4,7 @@ import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { mapActions, mapState, mapGetters } from 'vuex';
import timeAgoMixin from '~/vue_shared/mixins/timeago';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import userAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
import { rightSidebarViews } from '../constants';
import IdeStatusList from './ide_status_list.vue';
import IdeStatusMr from './ide_status_mr.vue';
@ -12,7 +12,7 @@ import IdeStatusMr from './ide_status_mr.vue';
export default {
components: {
GlIcon,
userAvatarImage,
UserAvatarImage,
CiIcon,
IdeStatusList,
IdeStatusMr,

View File

@ -4,12 +4,12 @@ import { mapActions } from 'vuex';
import { modalTypes } from '../../constants';
import ItemButton from './button.vue';
import NewModal from './modal.vue';
import upload from './upload.vue';
import Upload from './upload.vue';
export default {
components: {
GlIcon,
upload,
Upload,
ItemButton,
NewModal,
},

View File

@ -17,11 +17,11 @@ import eventHub from '../event_hub';
import getIssueStateQuery from '../queries/get_issue_state.query.graphql';
import Service from '../services/index';
import Store from '../stores';
import descriptionComponent from './description.vue';
import editedComponent from './edited.vue';
import formComponent from './form.vue';
import DescriptionComponent from './description.vue';
import EditedComponent from './edited.vue';
import FormComponent from './form.vue';
import PinnedLinks from './pinned_links.vue';
import titleComponent from './title.vue';
import TitleComponent from './title.vue';
export default {
WorkspaceType,
@ -29,9 +29,9 @@ export default {
GlIcon,
GlBadge,
GlIntersectionObserver,
titleComponent,
editedComponent,
formComponent,
TitleComponent,
EditedComponent,
FormComponent,
PinnedLinks,
ConfidentialityBadge,
},
@ -181,7 +181,7 @@ export default {
type: Object,
required: false,
default: () => {
return descriptionComponent;
return DescriptionComponent;
},
},
showTitleBorder: {

View File

@ -1,10 +1,10 @@
<script>
/* eslint-disable @gitlab/vue-require-i18n-strings */
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
export default {
components: {
timeAgoTooltip,
TimeAgoTooltip,
},
props: {
updatedAt: {

View File

@ -1,11 +1,11 @@
<script>
import markdownField from '~/vue_shared/components/markdown/field.vue';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import { helpPagePath } from '~/helpers/help_page_helper';
import updateMixin from '../../mixins/update';
export default {
components: {
markdownField,
MarkdownField,
},
mixins: [updateMixin],
props: {

View File

@ -4,14 +4,14 @@ import { isEmpty } from 'lodash';
import Mousetrap from 'mousetrap';
import { s__ } from '~/locale';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import clipboardButton from '~/vue_shared/components/clipboard_button.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import { clickCopyToClipboardButton } from '~/behaviors/copy_to_clipboard';
import { keysFor, MR_COPY_SOURCE_BRANCH_NAME } from '~/behaviors/shortcuts/keybindings';
export default {
components: {
CiIcon,
clipboardButton,
ClipboardButton,
GlDropdown,
GlDropdownItem,
GlLink,

View File

@ -22,7 +22,7 @@ export default function initLinkedResources() {
name: 'LinkedResourcesRoot',
apolloProvider,
components: {
resourceLinksBlock: ResourceLinksBlock,
ResourceLinksBlock,
},
render: (createElement) =>
createElement('resource-links-block', {

View File

@ -5,7 +5,7 @@ import initRevertCommitModal from '~/projects/commit/init_revert_commit_modal';
import initDiffsApp from '../diffs';
import { resetServiceWorkersPublicPath } from '../lib/utils/webpack';
import MergeRequest from '../merge_request';
import discussionCounter from '../notes/components/discussion_counter.vue';
import DiscussionCounter from '../notes/components/discussion_counter.vue';
import initDiscussionFilters from '../notes/discussion_filters';
import initNotesApp from './init_notes';
@ -37,7 +37,7 @@ export default function initMrNotes() {
el,
name: 'DiscussionCounter',
components: {
discussionCounter,
DiscussionCounter,
},
store,
render(createElement) {

View File

@ -4,7 +4,7 @@ import { mapActions, mapState, mapGetters } from 'vuex';
import { parseBoolean } from '~/lib/utils/common_utils';
import store from '~/mr_notes/stores';
import discussionNavigator from '../notes/components/discussion_navigator.vue';
import notesApp from '../notes/components/notes_app.vue';
import NotesApp from '../notes/components/notes_app.vue';
import initWidget from '../vue_merge_request_widget';
export default () => {
@ -13,7 +13,7 @@ export default () => {
el: '#js-vue-mr-discussions',
name: 'MergeRequestDiscussions',
components: {
notesApp,
NotesApp,
},
store,
data() {

View File

@ -137,7 +137,7 @@ marked.setOptions({
export default {
components: {
prompt: Prompt,
Prompt,
},
directives: {
SafeHtml,

View File

@ -3,7 +3,7 @@ import Prompt from '../prompt.vue';
export default {
components: {
prompt: Prompt,
Prompt,
},
props: {
count: {

View File

@ -14,7 +14,7 @@ import {
slugifyWithUnderscore,
} from '~/lib/utils/text_utility';
import { sprintf } from '~/locale';
import markdownField from '~/vue_shared/components/markdown/field.vue';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@ -25,8 +25,8 @@ import { COMMENT_FORM } from '../i18n';
import issuableStateMixin from '../mixins/issuable_state';
import CommentFieldLayout from './comment_field_layout.vue';
import CommentTypeDropdown from './comment_type_dropdown.vue';
import discussionLockedWidget from './discussion_locked_widget.vue';
import noteSignedOutWidget from './note_signed_out_widget.vue';
import DiscussionLockedWidget from './discussion_locked_widget.vue';
import NoteSignedOutWidget from './note_signed_out_widget.vue';
const { UNPROCESSABLE_ENTITY } = httpStatusCodes;
@ -34,9 +34,9 @@ export default {
name: 'CommentForm',
i18n: COMMENT_FORM,
components: {
noteSignedOutWidget,
discussionLockedWidget,
markdownField,
NoteSignedOutWidget,
DiscussionLockedWidget,
MarkdownField,
GlAlert,
GlButton,
TimelineEntryItem,

View File

@ -4,16 +4,16 @@ import { escape } from 'lodash';
import { mapActions } from 'vuex';
import { truncateSha } from '~/lib/utils/text_utility';
import { s__, __, sprintf } from '~/locale';
import noteEditedText from './note_edited_text.vue';
import noteHeader from './note_header.vue';
import NoteEditedText from './note_edited_text.vue';
import NoteHeader from './note_header.vue';
export default {
name: 'DiffDiscussionHeader',
components: {
GlAvatar,
GlAvatarLink,
noteEditedText,
noteHeader,
NoteEditedText,
NoteHeader,
},
directives: {
SafeHtml,

View File

@ -8,17 +8,17 @@ import { __ } from '~/locale';
import '~/behaviors/markdown/render_gfm';
import Suggestions from '~/vue_shared/components/markdown/suggestions.vue';
import autosave from '../mixins/autosave';
import noteAttachment from './note_attachment.vue';
import noteAwardsList from './note_awards_list.vue';
import noteEditedText from './note_edited_text.vue';
import noteForm from './note_form.vue';
import NoteAttachment from './note_attachment.vue';
import NoteAwardsList from './note_awards_list.vue';
import NoteEditedText from './note_edited_text.vue';
import NoteForm from './note_form.vue';
export default {
components: {
noteEditedText,
noteAwardsList,
noteAttachment,
noteForm,
NoteEditedText,
NoteAwardsList,
NoteAttachment,
NoteForm,
Suggestions,
},
directives: {

View File

@ -1,11 +1,11 @@
<script>
/* eslint-disable @gitlab/vue-require-i18n-strings */
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
export default {
name: 'EditedNoteText',
components: {
timeAgoTooltip,
TimeAgoTooltip,
},
props: {
actionText: {

View File

@ -4,7 +4,7 @@ import { mapGetters, mapActions, mapState } from 'vuex';
import { getDraft, updateDraft } from '~/lib/utils/autosave';
import { mergeUrlParams } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import markdownField from '~/vue_shared/components/markdown/field.vue';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
import eventHub from '../event_hub';
import issuableStateMixin from '../mixins/issuable_state';
import resolvable from '../mixins/resolvable';
@ -15,7 +15,7 @@ export default {
i18n: COMMENT_FORM,
name: 'NoteForm',
components: {
markdownField,
MarkdownField,
CommentFieldLayout,
GlButton,
GlSprintf,

View File

@ -8,13 +8,13 @@ import {
} from '@gitlab/ui';
import { mapActions } from 'vuex';
import { __, s__ } from '~/locale';
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import UserNameWithStatus from '~/sidebar/components/assignees/user_name_with_status.vue';
export default {
safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
components: {
timeAgoTooltip,
TimeAgoTooltip,
GitlabTeamMemberBadge: () =>
import('ee_component/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue'),
GlIcon,

View File

@ -10,25 +10,25 @@ import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';
import { s__, __, sprintf } from '~/locale';
import diffLineNoteFormMixin from '~/notes/mixins/diff_line_note_form';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
import userAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import eventHub from '../event_hub';
import noteable from '../mixins/noteable';
import resolvable from '../mixins/resolvable';
import diffDiscussionHeader from './diff_discussion_header.vue';
import diffWithNote from './diff_with_note.vue';
import DiffDiscussionHeader from './diff_discussion_header.vue';
import DiffWithNote from './diff_with_note.vue';
import DiscussionActions from './discussion_actions.vue';
import DiscussionNotes from './discussion_notes.vue';
import noteForm from './note_form.vue';
import noteSignedOutWidget from './note_signed_out_widget.vue';
import NoteForm from './note_form.vue';
import NoteSignedOutWidget from './note_signed_out_widget.vue';
export default {
name: 'NoteableDiscussion',
components: {
GlIcon,
userAvatarLink,
diffDiscussionHeader,
noteSignedOutWidget,
noteForm,
UserAvatarLink,
DiffDiscussionHeader,
NoteSignedOutWidget,
NoteForm,
DraftNote,
TimelineEntryItem,
DiscussionNotes,
@ -120,7 +120,7 @@ export default {
return !this.shouldRenderDiffs;
},
wrapperComponent() {
return this.shouldRenderDiffs ? diffWithNote : 'div';
return this.shouldRenderDiffs ? DiffWithNote : 'div';
},
wrapperComponentProps() {
if (this.shouldRenderDiffs) {

View File

@ -22,16 +22,16 @@ import {
commentLineOptions,
formatLineRange,
} from './multiline_comment_utils';
import noteActions from './note_actions.vue';
import NoteActions from './note_actions.vue';
import NoteBody from './note_body.vue';
import noteHeader from './note_header.vue';
import NoteHeader from './note_header.vue';
export default {
name: 'NoteableNote',
components: {
GlSprintf,
noteHeader,
noteActions,
NoteHeader,
NoteActions,
NoteBody,
TimelineEntryItem,
GlAvatarLink,

View File

@ -6,34 +6,34 @@ import { __ } from '~/locale';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
import OrderedLayout from '~/vue_shared/components/ordered_layout.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import draftNote from '~/batch_comments/components/draft_note.vue';
import DraftNote from '~/batch_comments/components/draft_note.vue';
import { getLocationHash, doesHashExistInUrl } from '~/lib/utils/url_utility';
import placeholderNote from '~/vue_shared/components/notes/placeholder_note.vue';
import placeholderSystemNote from '~/vue_shared/components/notes/placeholder_system_note.vue';
import skeletonLoadingContainer from '~/vue_shared/components/notes/skeleton_note.vue';
import systemNote from '~/vue_shared/components/notes/system_note.vue';
import PlaceholderNote from '~/vue_shared/components/notes/placeholder_note.vue';
import PlaceholderSystemNote from '~/vue_shared/components/notes/placeholder_system_note.vue';
import SkeletonLoadingContainer from '~/vue_shared/components/notes/skeleton_note.vue';
import SystemNote from '~/vue_shared/components/notes/system_note.vue';
import * as constants from '../constants';
import eventHub from '../event_hub';
import commentForm from './comment_form.vue';
import discussionFilterNote from './discussion_filter_note.vue';
import noteableDiscussion from './noteable_discussion.vue';
import noteableNote from './noteable_note.vue';
import CommentForm from './comment_form.vue';
import DiscussionFilterNote from './discussion_filter_note.vue';
import NoteableDiscussion from './noteable_discussion.vue';
import NoteableNote from './noteable_note.vue';
import SidebarSubscription from './sidebar_subscription.vue';
export default {
name: 'NotesApp',
components: {
noteableNote,
noteableDiscussion,
systemNote,
commentForm,
placeholderNote,
placeholderSystemNote,
skeletonLoadingContainer,
discussionFilterNote,
NoteableNote,
NoteableDiscussion,
SystemNote,
CommentForm,
PlaceholderNote,
PlaceholderSystemNote,
SkeletonLoadingContainer,
DiscussionFilterNote,
OrderedLayout,
SidebarSubscription,
draftNote,
DraftNote,
TimelineEntryItem,
},
mixins: [glFeatureFlagsMixin()],

View File

@ -1,5 +1,5 @@
import Vue from 'vue';
import notesApp from './components/notes_app.vue';
import NotesApp from './components/notes_app.vue';
import initDiscussionFilters from './discussion_filters';
import { store } from './stores';
import initTimelineToggle from './timeline';
@ -15,7 +15,7 @@ export default () => {
el,
name: 'NotesRoot',
components: {
notesApp,
NotesApp,
},
store,
data() {

View File

@ -14,16 +14,17 @@ import NpmInstallation from './npm_installation.vue';
import NugetInstallation from './nuget_installation.vue';
import PypiInstallation from './pypi_installation.vue';
const components = {
[PACKAGE_TYPE_CONAN]: ConanInstallation,
[PACKAGE_TYPE_MAVEN]: MavenInstallation,
[PACKAGE_TYPE_NPM]: NpmInstallation,
[PACKAGE_TYPE_NUGET]: NugetInstallation,
[PACKAGE_TYPE_PYPI]: PypiInstallation,
[PACKAGE_TYPE_COMPOSER]: ComposerInstallation,
};
export default {
name: 'InstallationCommands',
components: {
[PACKAGE_TYPE_CONAN]: ConanInstallation,
[PACKAGE_TYPE_MAVEN]: MavenInstallation,
[PACKAGE_TYPE_NPM]: NpmInstallation,
[PACKAGE_TYPE_NUGET]: NugetInstallation,
[PACKAGE_TYPE_PYPI]: PypiInstallation,
[PACKAGE_TYPE_COMPOSER]: ComposerInstallation,
},
props: {
packageEntity: {
type: Object,
@ -32,7 +33,7 @@ export default {
},
computed: {
installationComponent() {
return this.$options.components[this.packageEntity.packageType];
return components[this.packageEntity.packageType];
},
},
};

View File

@ -1,7 +1,7 @@
import Vue from 'vue';
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
import Translate from '~/vue_shared/translate';
import stopJobsModal from './components/stop_jobs_modal.vue';
import StopJobsModal from './components/stop_jobs_modal.vue';
Vue.use(Translate);
@ -14,7 +14,7 @@ function initJobs() {
new Vue({
el: `#js-${modalId}`,
components: {
stopJobsModal,
StopJobsModal,
},
mounted() {
stopJobsButton.classList.remove('disabled');

View File

@ -9,7 +9,7 @@ import GpgBadges from '~/gpg_badges';
import createDefaultClient from '~/lib/graphql';
import initBlob from '~/pages/projects/init_blob';
import initWebIdeLink from '~/pages/projects/shared/web_ide_link';
import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import CommitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import BlobContentViewer from '~/repository/components/blob_content_viewer.vue';
import '~/sourcegraph/load';
import createStore from '~/code_navigation/store';
@ -64,7 +64,7 @@ if (statusLink) {
new Vue({
el: CommitPipelineStatusEl,
components: {
commitPipelineStatus,
CommitPipelineStatus,
},
render(createElement) {
return createElement('commit-pipeline-status', {

View File

@ -6,7 +6,7 @@ import { REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants';
import setupNativeFormVariableList from '~/ci_variable_list/native_form_variable_list';
import GlFieldErrors from '~/gl_field_errors';
import Translate from '~/vue_shared/translate';
import intervalPatternInput from './components/interval_pattern_input.vue';
import IntervalPatternInput from './components/interval_pattern_input.vue';
import TimezoneDropdown from './components/timezone_dropdown';
Vue.use(Translate);
@ -19,7 +19,7 @@ function initIntervalPatternInput() {
return new Vue({
el: intervalPatternMount,
components: {
intervalPatternInput,
IntervalPatternInput,
},
render(createElement) {
return createElement('interval-pattern-input', {

View File

@ -14,8 +14,8 @@ import {
featureAccessLevelDescriptions,
} from '../constants';
import { toggleHiddenClassBySelector } from '../external';
import projectFeatureSetting from './project_feature_setting.vue';
import projectSettingRow from './project_setting_row.vue';
import ProjectFeatureSetting from './project_feature_setting.vue';
import ProjectSettingRow from './project_setting_row.vue';
const FEATURE_ACCESS_LEVEL_ANONYMOUS = [30, s__('ProjectSettings|Everyone')];
@ -56,8 +56,8 @@ export default {
},
components: {
projectFeatureSetting,
projectSettingRow,
ProjectFeatureSetting,
ProjectSettingRow,
GlButton,
GlIcon,
GlSprintf,
@ -65,7 +65,7 @@ export default {
GlFormCheckbox,
GlToggle,
ConfirmDanger,
otherProjectSettings: () =>
OtherProjectSettings: () =>
import(
'jh_component/pages/projects/shared/permissions/components/other_project_settings.vue'
),

View File

@ -2,10 +2,10 @@
import pdfjsLib from 'pdfjs-dist/build/pdf';
import workerSrc from 'pdfjs-dist/build/pdf.worker.min';
import page from './page/index.vue';
import Page from './page/index.vue';
export default {
components: { page },
components: { Page },
props: {
pdf: {
type: [String, Uint8Array],

View File

@ -9,7 +9,7 @@ import {
} from '@gitlab/ui';
import { setUrlFragment, redirectTo } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import ciHeader from '~/vue_shared/components/header_ci_component.vue';
import CiHeader from '~/vue_shared/components/header_ci_component.vue';
import {
LOAD_FAILURE,
POST_FAILURE,
@ -33,7 +33,7 @@ export default {
pipelineRetry: 'pipelineRetry',
finishedStatuses: ['FAILED', 'SUCCESS', 'CANCELED'],
components: {
ciHeader,
CiHeader,
GlAlert,
GlButton,
GlLoadingIcon,

View File

@ -1,5 +1,5 @@
<script>
import ciIcon from '~/vue_shared/components/ci_icon.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
/**
* Component that renders both the CI icon status and the job name.
@ -9,7 +9,7 @@ import ciIcon from '~/vue_shared/components/ci_icon.vue';
*/
export default {
components: {
ciIcon,
CiIcon,
},
props: {
name: {

View File

@ -1,9 +1,9 @@
<script>
import tooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
export default {
components: {
tooltipOnTruncate,
TooltipOnTruncate,
},
props: {
jobName: {

View File

@ -1,10 +1,10 @@
<script>
import { capitalize, escape } from 'lodash';
import tooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
export default {
components: {
tooltipOnTruncate,
TooltipOnTruncate,
},
props: {
stageName: {

View File

@ -1,6 +1,6 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import pipelineHeader from './components/header_component.vue';
import PipelineHeader from './components/header_component.vue';
Vue.use(VueApollo);
@ -16,7 +16,7 @@ export const createPipelineHeaderApp = (elSelector, apolloProvider, graphqlResou
new Vue({
el,
components: {
pipelineHeader,
PipelineHeader,
},
apolloProvider,
provide: {

View File

@ -1,7 +1,7 @@
import Vue from 'vue';
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
import Translate from '~/vue_shared/translate';
import deleteAccountModal from './components/delete_account_modal.vue';
import DeleteAccountModal from './components/delete_account_modal.vue';
import UpdateUsername from './components/update_username.vue';
export default () => {
@ -27,7 +27,7 @@ export default () => {
new Vue({
el: deleteAccountModalEl,
components: {
deleteAccountModal,
DeleteAccountModal,
},
mounted() {
deleteAccountButton.disabled = false;

View File

@ -4,7 +4,7 @@ import Visibility from 'visibilityjs';
import createFlash from '~/flash';
import Poll from '~/lib/utils/poll';
import { __, s__, sprintf } from '~/locale';
import ciIcon from '~/vue_shared/components/ci_icon.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import CommitPipelineService from '../services/commit_pipeline_service';
export default {
@ -12,7 +12,7 @@ export default {
GlTooltip: GlTooltipDirective,
},
components: {
ciIcon,
CiIcon,
GlLoadingIcon,
},
props: {

View File

@ -7,14 +7,14 @@ import {
inputPlaceholderTextMap,
issuableTypesMap,
} from '../constants';
import issueToken from './issue_token.vue';
import IssueToken from './issue_token.vue';
const SPACE_FACTOR = 1;
export default {
name: 'RelatedIssuableInput',
components: {
issueToken,
IssueToken,
},
props: {
inputId: {

View File

@ -40,7 +40,7 @@ import RelatedIssuesBlock from './related_issues_block.vue';
export default {
name: 'RelatedIssuesRoot',
components: {
relatedIssuesBlock: RelatedIssuesBlock,
RelatedIssuesBlock,
},
props: {
endpoint: {

View File

@ -1,10 +1,10 @@
<script>
import { GlSprintf } from '@gitlab/ui';
import editFormButtons from './edit_form_buttons.vue';
import EditFormButtons from './edit_form_buttons.vue';
export default {
components: {
editFormButtons,
EditFormButtons,
GlSprintf,
},
props: {

View File

@ -6,7 +6,7 @@ import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import createFlash from '~/flash';
import eventHub from '~/sidebar/event_hub';
import toast from '~/vue_shared/plugins/global_toast';
import editForm from './edit_form.vue';
import EditForm from './edit_form.vue';
export default {
issue: 'issue',
@ -23,7 +23,7 @@ export default {
displayText: __('Unlocked'),
},
components: {
editForm,
EditForm,
GlIcon,
},
directives: {

View File

@ -1,7 +1,7 @@
<script>
import { GlButton, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
import { __, n__, sprintf } from '~/locale';
import userAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
export default {
directives: {
@ -11,7 +11,7 @@ export default {
GlButton,
GlIcon,
GlLoadingIcon,
userAvatarImage,
UserAvatarImage,
},
props: {
loading: {

View File

@ -1,7 +1,7 @@
import Vue from 'vue';
import { IssuableType } from '~/issues/constants';
import { parseBoolean } from '~/lib/utils/common_utils';
import timeTracker from './components/time_tracking/time_tracker.vue';
import TimeTracker from './components/time_tracking/time_tracker.vue';
export default class SidebarMilestone {
constructor() {
@ -23,13 +23,13 @@ export default class SidebarMilestone {
el,
name: 'SidebarMilestoneRoot',
components: {
timeTracker,
TimeTracker,
},
provide: {
issuableType: IssuableType.Milestone,
},
render: (createElement) =>
createElement('timeTracker', {
createElement('time-tracker', {
props: {
limitToHours: parseBoolean(limitToHours),
issuableIid: iid.toString(),

View File

@ -89,6 +89,19 @@ export default {
if (e.key !== 'Escape') return;
this.$emit('close');
this.$refs.dismisser?.dismiss();
this.trackDismissal();
},
close() {
this.trackDismissal();
this.$emit('close');
},
trackDismissal() {
this.track('survey:mr_experience', {
label: 'dismiss',
extra: {
accountAge: this.accountAge,
},
});
},
},
};
@ -119,7 +132,7 @@ export default {
icon="close"
@click="
dismiss();
$emit('close');
close();
"
/>
<div

View File

@ -24,7 +24,7 @@ const nonStandardEvents = {
},
issues: {
uniqueUser: {
expand: ['i_testing_load_performance_widget_total'],
expand: ['i_testing_issues_widget_total'],
},
counter: {},
},

View File

@ -1,10 +1,10 @@
<script>
import { GlLoadingIcon } from '@gitlab/ui';
import ciIcon from '~/vue_shared/components/ci_icon.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
export default {
components: {
ciIcon,
CiIcon,
GlLoadingIcon,
},
props: {

View File

@ -1,10 +1,10 @@
<script>
import statusIcon from '../mr_widget_status_icon.vue';
import StatusIcon from '../mr_widget_status_icon.vue';
export default {
name: 'MRWidgetArchived',
components: {
statusIcon,
StatusIcon,
},
};
</script>

View File

@ -1,10 +1,10 @@
<script>
import statusIcon from '../mr_widget_status_icon.vue';
import StatusIcon from '../mr_widget_status_icon.vue';
export default {
name: 'MRWidgetChecking',
components: {
statusIcon,
StatusIcon,
},
};
</script>

View File

@ -1,12 +1,12 @@
<script>
import MrWidgetAuthorTime from '../mr_widget_author_time.vue';
import statusIcon from '../mr_widget_status_icon.vue';
import StatusIcon from '../mr_widget_status_icon.vue';
export default {
name: 'MRWidgetClosed',
components: {
MrWidgetAuthorTime,
statusIcon,
StatusIcon,
},
props: {
/* TODO: This is providing all store and service down when it

View File

@ -3,14 +3,14 @@ import { GlButton } from '@gitlab/ui';
import { stripHtml } from '~/lib/utils/text_utility';
import { sprintf, s__, n__ } from '~/locale';
import eventHub from '../../event_hub';
import statusIcon from '../mr_widget_status_icon.vue';
import StatusIcon from '../mr_widget_status_icon.vue';
export default {
name: 'MRWidgetFailedToMerge',
components: {
GlButton,
statusIcon,
StatusIcon,
},
props: {

View File

@ -4,7 +4,7 @@ import simplePoll from '~/lib/utils/simple_poll';
import MergeRequest from '~/merge_request';
import eventHub from '../../event_hub';
import { MERGE_ACTIVE_STATUS_PHRASES, STATE_MACHINE } from '../../constants';
import statusIcon from '../mr_widget_status_icon.vue';
import StatusIcon from '../mr_widget_status_icon.vue';
const { transitions } = STATE_MACHINE;
const { MERGE_FAILURE } = transitions;
@ -12,7 +12,7 @@ const { MERGE_FAILURE } = transitions;
export default {
name: 'MRWidgetMerging',
components: {
statusIcon,
StatusIcon,
},
props: {
mr: {

View File

@ -9,7 +9,7 @@ import {
MR_WIDGET_MISSING_BRANCH_RESTORE,
MR_WIDGET_MISSING_BRANCH_MANUALCLI,
} from '../../i18n';
import statusIcon from '../mr_widget_status_icon.vue';
import StatusIcon from '../mr_widget_status_icon.vue';
export default {
name: 'MRWidgetMissingBranch',
@ -19,7 +19,7 @@ export default {
components: {
GlIcon,
GlSprintf,
statusIcon,
StatusIcon,
},
mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
apollo: {

View File

@ -2,14 +2,14 @@
import { GlLink, GlSprintf } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
import { s__ } from '~/locale';
import statusIcon from '../mr_widget_status_icon.vue';
import StatusIcon from '../mr_widget_status_icon.vue';
export default {
name: 'PipelineFailed',
components: {
GlLink,
GlSprintf,
statusIcon,
StatusIcon,
},
computed: {
troubleshootingDocsPath() {

View File

@ -59,28 +59,28 @@ export default {
Loading,
ExtensionsContainer,
WidgetContainer,
'mr-widget-suggest-pipeline': WidgetSuggestPipeline,
MrWidgetSuggestPipeline: WidgetSuggestPipeline,
MrWidgetPipelineContainer,
MrWidgetAlertMessage,
'mr-widget-merged': MergedState,
'mr-widget-closed': ClosedState,
'mr-widget-merging': MergingState,
'mr-widget-failed-to-merge': FailedToMerge,
'mr-widget-wip': WorkInProgressState,
'mr-widget-archived': ArchivedState,
'mr-widget-conflicts': ConflictsState,
'mr-widget-nothing-to-merge': NothingToMergeState,
'mr-widget-not-allowed': NotAllowedState,
'mr-widget-missing-branch': MissingBranchState,
'mr-widget-ready-to-merge': () => import('./components/states/new_ready_to_merge.vue'),
'sha-mismatch': ShaMismatch,
'mr-widget-checking': CheckingState,
'mr-widget-unresolved-discussions': UnresolvedDiscussionsState,
'mr-widget-pipeline-blocked': PipelineBlockedState,
'mr-widget-pipeline-failed': PipelineFailedState,
MrWidgetMerged: MergedState,
MrWidgetClosed: ClosedState,
MrWidgetMerging: MergingState,
MrWidgetFailedToMerge: FailedToMerge,
MrWidgetWip: WorkInProgressState,
MrWidgetArchived: ArchivedState,
MrWidgetConflicts: ConflictsState,
MrWidgetNothingToMerge: NothingToMergeState,
MrWidgetNotAllowed: NotAllowedState,
MrWidgetMissingBranch: MissingBranchState,
MrWidgetReadyToMerge: () => import('./components/states/new_ready_to_merge.vue'),
ShaMismatch,
MrWidgetChecking: CheckingState,
MrWidgetUnresolvedDiscussions: UnresolvedDiscussionsState,
MrWidgetPipelineBlocked: PipelineBlockedState,
MrWidgetPipelineFailed: PipelineFailedState,
MrWidgetAutoMergeEnabled,
'mr-widget-auto-merge-failed': AutoMergeFailed,
'mr-widget-rebase': RebaseState,
MrWidgetAutoMergeFailed: AutoMergeFailed,
MrWidgetRebase: RebaseState,
SourceBranchRemovalStatus,
GroupedCodequalityReportsApp: () =>
import('../reports/codequality_report/grouped_codequality_reports_app.vue'),

View File

@ -29,7 +29,7 @@ import descriptionVersionHistoryMixin from 'ee_else_ce/notes/mixins/description_
import '~/behaviors/markdown/render_gfm';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
import noteHeader from '~/notes/components/note_header.vue';
import NoteHeader from '~/notes/components/note_header.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { spriteIcon } from '~/lib/utils/common_utils';
import TimelineEntryItem from './timeline_entry_item.vue';
@ -43,7 +43,7 @@ export default {
name: 'SystemNote',
components: {
GlIcon,
noteHeader,
NoteHeader,
TimelineEntryItem,
GlButton,
GlSkeletonLoader,

View File

@ -24,7 +24,7 @@ export default function initWorkItemLinks() {
name: 'WorkItemLinksRoot',
apolloProvider,
components: {
workItemLinks: WorkItemLinks,
WorkItemLinks,
},
provide: {
projectPath,

View File

@ -44,8 +44,7 @@ class MergeRequestsFinder < IssuableFinder
:reviewer_id,
:reviewer_username,
:target_branch,
:wip,
:attention
:wip
]
end
@ -70,7 +69,6 @@ class MergeRequestsFinder < IssuableFinder
items = by_approvals(items)
items = by_deployments(items)
items = by_reviewer(items)
items = by_attention(items)
by_source_project_id(items)
end
@ -220,12 +218,6 @@ class MergeRequestsFinder < IssuableFinder
end
end
def by_attention(items)
return items unless params.attention?
items.attention(params.attention)
end
def parse_datetime(input)
# To work around http://www.ruby-lang.org/en/news/2021/11/15/date-parsing-method-regexp-dos-cve-2021-41817/
DateTime.parse(input.byteslice(0, 128)) if input

View File

@ -21,11 +21,5 @@ class MergeRequestsFinder
end
end
end
def attention
strong_memoize(:attention) do
User.find_by_username(params[:attention])
end
end
end
end

View File

@ -6,20 +6,12 @@ module MergeRequestReviewerState
included do
enum state: {
unreviewed: 0,
reviewed: 1,
attention_requested: 2
reviewed: 1
# 2 was removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95446
}
validates :state,
presence: true,
inclusion: { in: self.states.keys }
belongs_to :updated_state_by, class_name: 'User', foreign_key: :updated_state_by_user_id
def attention_requested_by
return unless attention_requested?
updated_state_by
end
end
end

View File

@ -153,7 +153,7 @@ class Group < Namespace
after_create :post_create_hook
after_destroy :post_destroy_hook
after_save :update_two_factor_requirement
after_commit :update_two_factor_requirement
after_update :path_changed_hook, if: :saved_change_to_path?
after_create -> { create_or_load_association(:group_feature) }
@ -898,6 +898,10 @@ class Group < Namespace
end
end
def update_two_factor_requirement_for_members
direct_and_indirect_members.find_each(&:update_two_factor_requirement)
end
private
def feature_flag_enabled_for_self_or_ancestor?(feature_flag)
@ -920,7 +924,7 @@ class Group < Namespace
def update_two_factor_requirement
return unless saved_change_to_require_two_factor_authentication? || saved_change_to_two_factor_grace_period?
direct_and_indirect_members.find_each(&:update_two_factor_requirement)
Groups::UpdateTwoFactorRequirementForMembersWorker.perform_async(self.id)
end
def path_changed_hook

View File

@ -417,17 +417,6 @@ class MergeRequest < ApplicationRecord
)
end
scope :attention, ->(user) do
# rubocop: disable Gitlab/Union
union = Gitlab::SQL::Union.new([
MergeRequestReviewer.select(:merge_request_id).where(user_id: user.id, state: MergeRequestReviewer.states[:attention_requested]),
MergeRequestAssignee.select(:merge_request_id).where(user_id: user.id, state: MergeRequestAssignee.states[:attention_requested])
])
# rubocop: enable Gitlab/Union
with(Gitlab::SQL::CTE.new(:reviewers_and_assignees, union).to_arel).where('merge_requests.id in (select merge_request_id from reviewers_and_assignees)')
end
def self.total_time_to_merge
join_metrics
.merge(MergeRequest::Metrics.with_valid_time_to_merge)

View File

@ -1,8 +1,6 @@
# frozen_string_literal: true
class MergeRequestAssignee < ApplicationRecord
include MergeRequestReviewerState
belongs_to :merge_request, touch: true
belongs_to :assignee, class_name: "User", foreign_key: :user_id, inverse_of: :merge_request_assignees
@ -11,6 +9,6 @@ class MergeRequestAssignee < ApplicationRecord
scope :in_projects, ->(project_ids) { joins(:merge_request).where(merge_requests: { target_project_id: project_ids }) }
def cache_key
[model_name.cache_key, id, state, assignee.cache_key]
[model_name.cache_key, id, assignee.cache_key]
end
end

View File

@ -2152,10 +2152,6 @@ class User < ApplicationRecord
end
end
def mr_attention_requests_enabled?
Feature.enabled?(:mr_attention_requests, self)
end
def account_age_in_days
(Date.current - created_at.to_date).to_i
end

View File

@ -47,8 +47,7 @@ module Users
storage_enforcement_banner_second_enforcement_threshold: 44,
storage_enforcement_banner_third_enforcement_threshold: 45,
storage_enforcement_banner_fourth_enforcement_threshold: 46,
attention_requests_top_nav: 47,
attention_requests_side_nav: 48,
# 47 and 48 were removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95446
# 49 was removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91533
# because the banner was no longer relevant.
# Records will be migrated with https://gitlab.com/gitlab-org/gitlab/-/issues/367293

View File

@ -17,7 +17,7 @@ class MergeRequestUserEntity < ::API::Entities::UserBasic
end
expose :reviewed, if: satisfies(:present?, :allows_reviewers?) do |user, options|
find_reviewer_or_assignee(user, options)&.reviewed?
options[:merge_request].find_reviewer(user)&.reviewed?
end
expose :approved, if: satisfies(:present?) do |user, options|
@ -25,16 +25,6 @@ class MergeRequestUserEntity < ::API::Entities::UserBasic
# makes one query per merge request, whereas #approved_by? makes one per user
options[:merge_request].approvals.any? { |app| app.user_id == user.id }
end
private
def find_reviewer_or_assignee(user, options)
if options[:type] == :reviewers
options[:merge_request].find_reviewer(user)
else
options[:merge_request].find_assignee(user)
end
end
end
MergeRequestUserEntity.prepend_mod_with('MergeRequestUserEntity')

View File

@ -43,8 +43,6 @@ module MergeRequests
end
def handle_assignees_change(merge_request, old_assignees)
bulk_update_assignees_state(merge_request, merge_request.assignees - old_assignees)
MergeRequests::HandleAssigneesChangeService
.new(project: project, current_user: current_user)
.async_execute(merge_request, old_assignees)
@ -60,7 +58,6 @@ module MergeRequests
new_reviewers = merge_request.reviewers - old_reviewers
merge_request_activity_counter.track_users_review_requested(users: new_reviewers)
merge_request_activity_counter.track_reviewers_changed_action(user: current_user)
bulk_update_reviewers_state(merge_request, new_reviewers)
end
def cleanup_environments(merge_request)
@ -247,46 +244,6 @@ module MergeRequests
Milestones::MergeRequestsCountService.new(milestone).delete_cache
end
def bulk_update_assignees_state(merge_request, new_assignees)
return unless current_user.mr_attention_requests_enabled?
return if new_assignees.empty?
assignees_map = merge_request.merge_request_assignees_with(new_assignees).to_h do |assignee|
state = if assignee.user_id == current_user&.id
:unreviewed
else
merge_request.find_reviewer(assignee.assignee)&.state || :attention_requested
end
[
assignee,
{ state: MergeRequestAssignee.states[state], updated_state_by_user_id: current_user.id }
]
end
::Gitlab::Database::BulkUpdate.execute(%i[state updated_state_by_user_id], assignees_map)
end
def bulk_update_reviewers_state(merge_request, new_reviewers)
return unless current_user.mr_attention_requests_enabled?
return if new_reviewers.empty?
reviewers_map = merge_request.merge_request_reviewers_with(new_reviewers).to_h do |reviewer|
state = if reviewer.user_id == current_user&.id
:unreviewed
else
merge_request.find_assignee(reviewer.reviewer)&.state || :attention_requested
end
[
reviewer,
{ state: MergeRequestReviewer.states[state], updated_state_by_user_id: current_user.id }
]
end
::Gitlab::Database::BulkUpdate.execute(%i[state updated_state_by_user_id], reviewers_map)
end
end
end

View File

@ -20,8 +20,6 @@ module MergeRequests
attrs = update_attrs.merge(assignee_ids: new_ids)
merge_request.update!(**attrs)
bulk_update_assignees_state(merge_request, merge_request.assignees - old_assignees)
# Defer the more expensive operations (handle_assignee_changes) to the background
MergeRequests::HandleAssigneesChangeService
.new(project: project, current_user: current_user)

View File

@ -5,4 +5,4 @@
= content_for :after_content do
#js-crm-form-portal
#js-crm-organizations-app{ data: { base_path: group_crm_organizations_path(@group), can_admin_crm_organization: can?(current_user, :admin_crm_organization, @group).to_s, group_full_path: @group.full_path, group_id: @group.id, group_issues_path: issues_group_path(@group) } }
#js-crm-organizations-app{ data: { base_path: group_crm_organizations_path(@group), can_admin_crm_organization: can?(current_user, :admin_crm_organization, @group).to_s, group_full_path: @group.full_path, group_id: @group.id, group_issues_path: issues_group_path(@group), text_query: params[:search] } }

View File

@ -2415,6 +2415,15 @@
:weight: 1
:idempotent: true
:tags: []
- :name: groups_update_two_factor_requirement_for_members
:worker_name: Groups::UpdateTwoFactorRequirementForMembersWorker
:feature_category: :authentication_and_authorization
:has_external_dependencies: false
:urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent: true
:tags: []
- :name: import_issues_csv
:worker_name: ImportIssuesCsvWorker
:feature_category: :team_planning

View File

@ -0,0 +1,22 @@
# frozen_string_literal: true
# Worker for updating two factor requirement for all group members
module Groups
class UpdateTwoFactorRequirementForMembersWorker
include ApplicationWorker
data_consistency :always
idempotent!
feature_category :authentication_and_authorization
def perform(group_id)
group = Group.find_by_id(group_id)
return unless group
group.update_two_factor_requirement_for_members
end
end
end

View File

@ -1,8 +0,0 @@
---
name: mr_attention_requests
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72773
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343528
milestone: '14.4'
type: development
group: group::code review
default_enabled: false

View File

@ -221,6 +221,8 @@
- 1
- - groups_update_statistics
- 1
- - groups_update_two_factor_requirement_for_members
- 1
- - hashed_storage
- 1
- - import_issues_csv

View File

@ -20190,7 +20190,6 @@ State of a review of a GitLab merge request.
| Value | Description |
| ----- | ----------- |
| <a id="mergerequestreviewstateattention_requested"></a>`ATTENTION_REQUESTED` | The merge request is attention_requested. |
| <a id="mergerequestreviewstatereviewed"></a>`REVIEWED` | The merge request is reviewed. |
| <a id="mergerequestreviewstateunreviewed"></a>`UNREVIEWED` | The merge request is unreviewed. |
@ -20864,8 +20863,6 @@ Name of the feature that the callout is for.
| Value | Description |
| ----- | ----------- |
| <a id="usercalloutfeaturenameenumactive_user_count_threshold"></a>`ACTIVE_USER_COUNT_THRESHOLD` | Callout feature name for active_user_count_threshold. |
| <a id="usercalloutfeaturenameenumattention_requests_side_nav"></a>`ATTENTION_REQUESTS_SIDE_NAV` | Callout feature name for attention_requests_side_nav. |
| <a id="usercalloutfeaturenameenumattention_requests_top_nav"></a>`ATTENTION_REQUESTS_TOP_NAV` | Callout feature name for attention_requests_top_nav. |
| <a id="usercalloutfeaturenameenumbuy_pipeline_minutes_notification_dot"></a>`BUY_PIPELINE_MINUTES_NOTIFICATION_DOT` | Callout feature name for buy_pipeline_minutes_notification_dot. |
| <a id="usercalloutfeaturenameenumcanary_deployment"></a>`CANARY_DEPLOYMENT` | Callout feature name for canary_deployment. |
| <a id="usercalloutfeaturenameenumci_deprecation_warning_for_types_keyword"></a>`CI_DEPRECATION_WARNING_FOR_TYPES_KEYWORD` | Callout feature name for ci_deprecation_warning_for_types_keyword. |

Some files were not shown because too many files have changed in this diff Show More