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: Style/NumericPredicate:
EnforcedStyle: comparison EnforcedStyle: comparison
Style/FloatDivision:
Enabled: false
Cop/BanCatchThrow: Cop/BanCatchThrow:
Enabled: true 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> <script>
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import notebookLab from '~/notebook/index.vue'; import NotebookLab from '~/notebook/index.vue';
export default { export default {
components: { components: {
notebookLab, NotebookLab,
GlLoadingIcon, GlLoadingIcon,
}, },
props: { props: {

View File

@ -11,11 +11,11 @@ import {
import addAdminVariable from '../graphql/mutations/admin_add_variable.mutation.graphql'; import addAdminVariable from '../graphql/mutations/admin_add_variable.mutation.graphql';
import deleteAdminVariable from '../graphql/mutations/admin_delete_variable.mutation.graphql'; import deleteAdminVariable from '../graphql/mutations/admin_delete_variable.mutation.graphql';
import updateAdminVariable from '../graphql/mutations/admin_update_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 { export default {
components: { components: {
ciVariableSettings, CiVariableSettings,
}, },
inject: ['endpoint'], inject: ['endpoint'],
data() { data() {

View File

@ -14,11 +14,11 @@ import {
import addGroupVariable from '../graphql/mutations/group_add_variable.mutation.graphql'; import addGroupVariable from '../graphql/mutations/group_add_variable.mutation.graphql';
import deleteGroupVariable from '../graphql/mutations/group_delete_variable.mutation.graphql'; import deleteGroupVariable from '../graphql/mutations/group_delete_variable.mutation.graphql';
import updateGroupVariable from '../graphql/mutations/group_update_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 { export default {
components: { components: {
ciVariableSettings, CiVariableSettings,
}, },
mixins: [glFeatureFlagsMixin()], mixins: [glFeatureFlagsMixin()],
inject: ['endpoint', 'groupPath', 'groupId'], inject: ['endpoint', 'groupPath', 'groupId'],

View File

@ -16,11 +16,11 @@ import {
import addProjectVariable from '../graphql/mutations/project_add_variable.mutation.graphql'; import addProjectVariable from '../graphql/mutations/project_add_variable.mutation.graphql';
import deleteProjectVariable from '../graphql/mutations/project_delete_variable.mutation.graphql'; import deleteProjectVariable from '../graphql/mutations/project_delete_variable.mutation.graphql';
import updateProjectVariable from '../graphql/mutations/project_update_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 { export default {
components: { components: {
ciVariableSettings, CiVariableSettings,
}, },
inject: ['endpoint', 'projectFullPath', 'projectId'], inject: ['endpoint', 'projectFullPath', 'projectId'],
data() { data() {

View File

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

View File

@ -10,7 +10,7 @@ export const displayText = {
}; };
export const variableTypes = { export const variableTypes = {
variableType: 'ENV_VAR', envType: 'ENV_VAR',
fileType: 'FILE', fileType: 'FILE',
}; };
@ -29,13 +29,13 @@ export const allEnvironments = {
export const variableText = { export const variableText = {
[types.variableType]: __('Variable'), [types.variableType]: __('Variable'),
[types.fileType]: __('File'), [types.fileType]: __('File'),
[variableTypes.variableType]: __('Variable'), [variableTypes.envType]: __('Variable'),
[variableTypes.fileType]: __('File'), [variableTypes.fileType]: __('File'),
}; };
export const variableOptions = [ export const variableOptions = [
{ value: types.variableType, text: variableText[types.variableType] }, { value: variableTypes.envType, text: variableText[variableTypes.envType] },
{ value: types.fileType, text: variableText[types.fileType] }, { value: variableTypes.fileType, text: variableText[variableTypes.fileType] },
]; ];
export const defaultVariableState = { export const defaultVariableState = {
@ -44,7 +44,7 @@ export const defaultVariableState = {
masked: false, masked: false,
protected: false, protected: false,
value: '', value: '',
variableType: types.variableType, variableType: variableTypes.envType,
}; };
// eslint-disable-next-line @gitlab/require-i18n-strings // 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 */, category: 'Customer Relations' /* eslint-disable-line @gitlab/require-i18n-strings */,
action: 'view_contacts_list', 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 VueApollo from 'vue-apollo';
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import createDefaultClient from '~/lib/graphql'; import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
import CrmOrganizationsRoot from './components/organizations_root.vue'; import CrmOrganizationsRoot from './components/organizations_root.vue';
import routes from './routes'; import routes from './routes';
@ -21,7 +22,14 @@ export default () => {
return false; return false;
} }
const { basePath, canAdminCrmOrganization, groupFullPath, groupId, groupIssuesPath } = el.dataset; const {
basePath,
canAdminCrmOrganization,
groupFullPath,
groupId,
groupIssuesPath,
textQuery,
} = el.dataset;
const router = new VueRouter({ const router = new VueRouter({
base: basePath, base: basePath,
@ -33,7 +41,13 @@ export default () => {
el, el,
router, router,
apolloProvider, apolloProvider,
provide: { canAdminCrmOrganization, groupFullPath, groupId, groupIssuesPath }, provide: {
canAdminCrmOrganization: parseBoolean(canAdminCrmOrganization),
groupFullPath,
groupId,
groupIssuesPath,
textQuery,
},
render(createElement) { render(createElement) {
return createElement(CrmOrganizationsRoot); return createElement(CrmOrganizationsRoot);
}, },

View File

@ -1,12 +1,37 @@
#import "./crm_organization_fields.fragment.graphql" #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) { group(fullPath: $groupFullPath) {
id id
organizations { organizations(
state: $state
search: $searchTerm
sort: $sort
first: $firstPageSize
last: $lastPageSize
after: $nextPageCursor
before: $prevPageCursor
ids: $ids
) {
nodes { nodes {
...OrganizationFragment ...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() { getQuery() {
return { return {
query: getGroupOrganizationsQuery, query: getGroupOrganizationsQuery,
variables: { groupFullPath: this.groupFullPath }, variables: { groupFullPath: this.groupFullPath, ids: [this.organizationGraphQLId] },
}; };
}, },
title() { title() {

View File

@ -1,36 +1,54 @@
<script> <script>
import { GlAlert, GlButton, GlLoadingIcon, GlTable, GlTooltipDirective } from '@gitlab/ui'; import { GlButton, GlLoadingIcon, GlTable, GlTooltipDirective } from '@gitlab/ui';
import { parseBoolean } from '~/lib/utils/common_utils';
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; 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 getGroupOrganizationsQuery from './graphql/get_group_organizations.query.graphql';
import getGroupOrganizationsCountByStateQuery from './graphql/get_group_organizations_count_by_state.query.graphql';
export default { export default {
components: { components: {
GlAlert,
GlButton, GlButton,
GlLoadingIcon, GlLoadingIcon,
GlTable, GlTable,
PaginatedTableWithSearchAndTabs,
}, },
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
}, },
inject: ['canAdminCrmOrganization', 'groupFullPath', 'groupIssuesPath'], inject: ['canAdminCrmOrganization', 'groupFullPath', 'groupIssuesPath', 'textQuery'],
data() { data() {
return { return {
organizations: [], organizations: { list: [] },
organizationsCount: {},
error: false, error: false,
filteredByStatus: '',
pagination: initialPaginationState,
statusFilter: 'all',
searchTerm: this.textQuery,
sort: 'NAME_ASC',
sortDesc: false,
}; };
}, },
apollo: { apollo: {
organizations: { organizations: {
query() { query: getGroupOrganizationsQuery,
return getGroupOrganizationsQuery;
},
variables() { variables() {
return { return {
groupFullPath: this.groupFullPath, 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) { update(data) {
@ -40,19 +58,52 @@ export default {
this.error = true; 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: { computed: {
isLoading() { isLoading() {
return this.$apollo.queries.organizations.loading; return this.$apollo.queries.organizations.loading;
}, },
canAdmin() { tbodyTrClass() {
return parseBoolean(this.canAdminCrmOrganization); return {
[bodyTrClass]: !this.loading && !this.isEmpty,
};
}, },
}, },
methods: { methods: {
errorAlertDismissed() {
this.error = false;
},
extractOrganizations(data) { extractOrganizations(data) {
const organizations = data?.group?.organizations?.nodes || []; 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) { getIssuesPath(path, value) {
return `${path}?crm_organization_id=${value}`; return `${path}?crm_organization_id=${value}`;
@ -60,6 +111,13 @@ export default {
getEditRoute(id) { getEditRoute(id) {
return { name: this.$options.EDIT_ROUTE_NAME, params: { 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: [ fields: [
{ key: 'name', sortable: true }, { key: 'name', sortable: true },
@ -83,60 +141,113 @@ export default {
}, },
EDIT_ROUTE_NAME, EDIT_ROUTE_NAME,
NEW_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> </script>
<template> <template>
<div> <div>
<gl-alert v-if="error" variant="danger" class="gl-mt-6" @dismiss="error = false"> <paginated-table-with-search-and-tabs
{{ $options.i18n.errorText }} :show-items="true"
</gl-alert> :show-error-msg="false"
<div :i18n="$options.i18n"
class="gl-display-flex gl-align-items-baseline gl-flex-direction-row gl-justify-content-space-between gl-mt-6" :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"> <template #header-actions>
{{ $options.i18n.title }} <router-link v-if="canAdminCrmOrganization" :to="{ name: $options.NEW_ROUTE_NAME }">
</h2> <gl-button
<div class="gl-my-3 gl-mr-5"
v-if="canAdmin" variant="confirm"
class="gl-display-none gl-md-display-flex gl-align-items-center gl-justify-content-end" data-testid="new-organization-button"
> >
<router-link :to="{ name: $options.NEW_ROUTE_NAME }">
<gl-button variant="confirm" data-testid="new-organization-button">
{{ $options.i18n.newOrganization }} {{ $options.i18n.newOrganization }}
</gl-button> </gl-button>
</router-link> </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> </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> </div>
</template> </template>

View File

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

View File

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

View File

@ -1,11 +1,11 @@
import Vue from 'vue'; import Vue from 'vue';
import deployKeysApp from './components/app.vue'; import DeployKeysApp from './components/app.vue';
export default () => export default () =>
new Vue({ new Vue({
el: document.getElementById('js-deploy-keys'), el: document.getElementById('js-deploy-keys'),
components: { components: {
deployKeysApp, DeployKeysApp,
}, },
data() { data() {
return { 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 NotDiffableViewer from '~/vue_shared/components/diff_viewer/viewers/not_diffable.vue';
import NoteForm from '~/notes/components/note_form.vue'; import NoteForm from '~/notes/components/note_form.vue';
import eventHub from '~/notes/event_hub'; 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 { IMAGE_DIFF_POSITION_TYPE } from '../constants';
import { getDiffMode } from '../store/utils'; import { getDiffMode } from '../store/utils';
import DiffDiscussions from './diff_discussions.vue'; import DiffDiscussions from './diff_discussions.vue';
@ -28,7 +28,7 @@ export default {
ImageDiffOverlay, ImageDiffOverlay,
NotDiffableViewer, NotDiffableViewer,
NoPreviewViewer, NoPreviewViewer,
userAvatarLink, UserAvatarLink,
DiffFileDrafts, DiffFileDrafts,
}, },
mixins: [diffLineNoteFormMixin, draftCommentsMixin], mixins: [diffLineNoteFormMixin, draftCommentsMixin],

View File

@ -2,11 +2,11 @@
import { GlIcon } from '@gitlab/ui'; import { GlIcon } from '@gitlab/ui';
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import DesignNotePin from '~/vue_shared/components/design_management/design_note_pin.vue'; 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 { export default {
components: { components: {
noteableDiscussion, NoteableDiscussion,
GlIcon, GlIcon,
DesignNotePin, 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 glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import MultilineCommentForm from '~/notes/components/multiline_comment_form.vue'; import MultilineCommentForm from '~/notes/components/multiline_comment_form.vue';
import { commentLineOptions, formatLineRange } from '~/notes/components/multiline_comment_utils'; 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 autosave from '~/notes/mixins/autosave';
import { import {
DIFF_NOTE_TYPE, DIFF_NOTE_TYPE,
@ -18,7 +18,7 @@ import {
export default { export default {
components: { components: {
noteForm, NoteForm,
MultilineCommentForm, MultilineCommentForm,
}, },
mixins: [autosave, diffLineNoteFormMixin, glFeatureFlagsMixin()], 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 { getCookie, parseBoolean, removeCookie } from '~/lib/utils/common_utils';
import eventHub from '../notes/event_hub'; 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 { TREE_LIST_STORAGE_KEY, DIFF_WHITESPACE_COOKIE_NAME } from './constants';
import { getReviewsForMergeRequest } from './utils/file_reviews'; import { getReviewsForMergeRequest } from './utils/file_reviews';
@ -14,7 +14,7 @@ export default function initDiffsApp(store) {
el: '#js-diffs-app', el: '#js-diffs-app',
name: 'MergeRequestDiffs', name: 'MergeRequestDiffs',
components: { components: {
diffsApp, DiffsApp,
}, },
store, store,
data() { data() {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,11 +26,17 @@ export const GROUPS_CATEGORY = s__('GlobalSearch|Groups');
export const PROJECTS_CATEGORY = s__('GlobalSearch|Projects'); 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; 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_SEARCHING = 'is-searching';
export const IS_FOCUSED = 'is-focused'; export const IS_FOCUSED = 'is-focused';
export const IS_NOT_FOCUSED = 'is-not-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 axios from '~/lib/utils/axios_utils';
import { FETCH_TYPES } from '../constants';
import * as types from './mutation_types'; import * as types from './mutation_types';
export const fetchAutocompleteOptions = ({ commit, getters }) => { export const autocompleteQuery = ({ state, fetchType }) => {
commit(types.REQUEST_AUTOCOMPLETE); 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 return axios
.get(getters.autocompleteQuery) .get(autocompleteQuery({ state, fetchType }))
.then(({ data }) => { .then(({ data }) => {
commit(types.RECEIVE_AUTOCOMPLETE_SUCCESS, 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 }) => { export const clearAutocomplete = ({ commit }) => {
commit(types.CLEAR_AUTOCOMPLETE); commit(types.CLEAR_AUTOCOMPLETE);
}; };

View File

@ -14,6 +14,7 @@ import {
PROJECTS_CATEGORY, PROJECTS_CATEGORY,
GROUPS_CATEGORY, GROUPS_CATEGORY,
SEARCH_SHORTCUTS_MIN_CHARACTERS, SEARCH_SHORTCUTS_MIN_CHARACTERS,
DROPDOWN_ORDER,
} from '../constants'; } from '../constants';
export const searchQuery = (state) => { export const searchQuery = (state) => {
@ -34,19 +35,6 @@ export const searchQuery = (state) => {
return `${state.searchPath}?${objectToQuery(query)}`; 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) => { export const scopedIssuesPath = (state) => {
return ( return (
state.searchContext?.project_metadata?.issues_path || 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) => { export const searchOptions = (state, getters) => {

View File

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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,10 @@
<script> <script>
/* eslint-disable @gitlab/vue-require-i18n-strings */ /* 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 { export default {
components: { components: {
timeAgoTooltip, TimeAgoTooltip,
}, },
props: { props: {
updatedAt: { updatedAt: {

View File

@ -1,11 +1,11 @@
<script> <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 { helpPagePath } from '~/helpers/help_page_helper';
import updateMixin from '../../mixins/update'; import updateMixin from '../../mixins/update';
export default { export default {
components: { components: {
markdownField, MarkdownField,
}, },
mixins: [updateMixin], mixins: [updateMixin],
props: { props: {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,11 +1,11 @@
<script> <script>
/* eslint-disable @gitlab/vue-require-i18n-strings */ /* 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 { export default {
name: 'EditedNoteText', name: 'EditedNoteText',
components: { components: {
timeAgoTooltip, TimeAgoTooltip,
}, },
props: { props: {
actionText: { actionText: {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,16 +14,17 @@ import NpmInstallation from './npm_installation.vue';
import NugetInstallation from './nuget_installation.vue'; import NugetInstallation from './nuget_installation.vue';
import PypiInstallation from './pypi_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 { export default {
name: 'InstallationCommands', 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: { props: {
packageEntity: { packageEntity: {
type: Object, type: Object,
@ -32,7 +33,7 @@ export default {
}, },
computed: { computed: {
installationComponent() { installationComponent() {
return this.$options.components[this.packageEntity.packageType]; return components[this.packageEntity.packageType];
}, },
}, },
}; };

View File

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

View File

@ -9,7 +9,7 @@ import GpgBadges from '~/gpg_badges';
import createDefaultClient from '~/lib/graphql'; import createDefaultClient from '~/lib/graphql';
import initBlob from '~/pages/projects/init_blob'; import initBlob from '~/pages/projects/init_blob';
import initWebIdeLink from '~/pages/projects/shared/web_ide_link'; 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 BlobContentViewer from '~/repository/components/blob_content_viewer.vue';
import '~/sourcegraph/load'; import '~/sourcegraph/load';
import createStore from '~/code_navigation/store'; import createStore from '~/code_navigation/store';
@ -64,7 +64,7 @@ if (statusLink) {
new Vue({ new Vue({
el: CommitPipelineStatusEl, el: CommitPipelineStatusEl,
components: { components: {
commitPipelineStatus, CommitPipelineStatus,
}, },
render(createElement) { render(createElement) {
return createElement('commit-pipeline-status', { 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 setupNativeFormVariableList from '~/ci_variable_list/native_form_variable_list';
import GlFieldErrors from '~/gl_field_errors'; import GlFieldErrors from '~/gl_field_errors';
import Translate from '~/vue_shared/translate'; 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'; import TimezoneDropdown from './components/timezone_dropdown';
Vue.use(Translate); Vue.use(Translate);
@ -19,7 +19,7 @@ function initIntervalPatternInput() {
return new Vue({ return new Vue({
el: intervalPatternMount, el: intervalPatternMount,
components: { components: {
intervalPatternInput, IntervalPatternInput,
}, },
render(createElement) { render(createElement) {
return createElement('interval-pattern-input', { return createElement('interval-pattern-input', {

View File

@ -14,8 +14,8 @@ import {
featureAccessLevelDescriptions, featureAccessLevelDescriptions,
} from '../constants'; } from '../constants';
import { toggleHiddenClassBySelector } from '../external'; import { toggleHiddenClassBySelector } from '../external';
import projectFeatureSetting from './project_feature_setting.vue'; import ProjectFeatureSetting from './project_feature_setting.vue';
import projectSettingRow from './project_setting_row.vue'; import ProjectSettingRow from './project_setting_row.vue';
const FEATURE_ACCESS_LEVEL_ANONYMOUS = [30, s__('ProjectSettings|Everyone')]; const FEATURE_ACCESS_LEVEL_ANONYMOUS = [30, s__('ProjectSettings|Everyone')];
@ -56,8 +56,8 @@ export default {
}, },
components: { components: {
projectFeatureSetting, ProjectFeatureSetting,
projectSettingRow, ProjectSettingRow,
GlButton, GlButton,
GlIcon, GlIcon,
GlSprintf, GlSprintf,
@ -65,7 +65,7 @@ export default {
GlFormCheckbox, GlFormCheckbox,
GlToggle, GlToggle,
ConfirmDanger, ConfirmDanger,
otherProjectSettings: () => OtherProjectSettings: () =>
import( import(
'jh_component/pages/projects/shared/permissions/components/other_project_settings.vue' '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 pdfjsLib from 'pdfjs-dist/build/pdf';
import workerSrc from 'pdfjs-dist/build/pdf.worker.min'; import workerSrc from 'pdfjs-dist/build/pdf.worker.min';
import page from './page/index.vue'; import Page from './page/index.vue';
export default { export default {
components: { page }, components: { Page },
props: { props: {
pdf: { pdf: {
type: [String, Uint8Array], type: [String, Uint8Array],

View File

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

View File

@ -1,5 +1,5 @@
<script> <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. * 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 { export default {
components: { components: {
ciIcon, CiIcon,
}, },
props: { props: {
name: { name: {

View File

@ -1,9 +1,9 @@
<script> <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 { export default {
components: { components: {
tooltipOnTruncate, TooltipOnTruncate,
}, },
props: { props: {
jobName: { jobName: {

View File

@ -1,10 +1,10 @@
<script> <script>
import { capitalize, escape } from 'lodash'; 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 { export default {
components: { components: {
tooltipOnTruncate, TooltipOnTruncate,
}, },
props: { props: {
stageName: { stageName: {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
<script> <script>
import { GlButton, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui'; import { GlButton, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
import { __, n__, sprintf } from '~/locale'; 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 { export default {
directives: { directives: {
@ -11,7 +11,7 @@ export default {
GlButton, GlButton,
GlIcon, GlIcon,
GlLoadingIcon, GlLoadingIcon,
userAvatarImage, UserAvatarImage,
}, },
props: { props: {
loading: { loading: {

View File

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

View File

@ -89,6 +89,19 @@ export default {
if (e.key !== 'Escape') return; if (e.key !== 'Escape') return;
this.$emit('close'); this.$emit('close');
this.$refs.dismisser?.dismiss(); 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" icon="close"
@click=" @click="
dismiss(); dismiss();
$emit('close'); close();
" "
/> />
<div <div

View File

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

View File

@ -1,10 +1,10 @@
<script> <script>
import { GlLoadingIcon } from '@gitlab/ui'; 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 { export default {
components: { components: {
ciIcon, CiIcon,
GlLoadingIcon, GlLoadingIcon,
}, },
props: { props: {

View File

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

View File

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

View File

@ -1,12 +1,12 @@
<script> <script>
import MrWidgetAuthorTime from '../mr_widget_author_time.vue'; 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 { export default {
name: 'MRWidgetClosed', name: 'MRWidgetClosed',
components: { components: {
MrWidgetAuthorTime, MrWidgetAuthorTime,
statusIcon, StatusIcon,
}, },
props: { props: {
/* TODO: This is providing all store and service down when it /* 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 { stripHtml } from '~/lib/utils/text_utility';
import { sprintf, s__, n__ } from '~/locale'; import { sprintf, s__, n__ } from '~/locale';
import eventHub from '../../event_hub'; import eventHub from '../../event_hub';
import statusIcon from '../mr_widget_status_icon.vue'; import StatusIcon from '../mr_widget_status_icon.vue';
export default { export default {
name: 'MRWidgetFailedToMerge', name: 'MRWidgetFailedToMerge',
components: { components: {
GlButton, GlButton,
statusIcon, StatusIcon,
}, },
props: { props: {

View File

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

View File

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

View File

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

View File

@ -59,28 +59,28 @@ export default {
Loading, Loading,
ExtensionsContainer, ExtensionsContainer,
WidgetContainer, WidgetContainer,
'mr-widget-suggest-pipeline': WidgetSuggestPipeline, MrWidgetSuggestPipeline: WidgetSuggestPipeline,
MrWidgetPipelineContainer, MrWidgetPipelineContainer,
MrWidgetAlertMessage, MrWidgetAlertMessage,
'mr-widget-merged': MergedState, MrWidgetMerged: MergedState,
'mr-widget-closed': ClosedState, MrWidgetClosed: ClosedState,
'mr-widget-merging': MergingState, MrWidgetMerging: MergingState,
'mr-widget-failed-to-merge': FailedToMerge, MrWidgetFailedToMerge: FailedToMerge,
'mr-widget-wip': WorkInProgressState, MrWidgetWip: WorkInProgressState,
'mr-widget-archived': ArchivedState, MrWidgetArchived: ArchivedState,
'mr-widget-conflicts': ConflictsState, MrWidgetConflicts: ConflictsState,
'mr-widget-nothing-to-merge': NothingToMergeState, MrWidgetNothingToMerge: NothingToMergeState,
'mr-widget-not-allowed': NotAllowedState, MrWidgetNotAllowed: NotAllowedState,
'mr-widget-missing-branch': MissingBranchState, MrWidgetMissingBranch: MissingBranchState,
'mr-widget-ready-to-merge': () => import('./components/states/new_ready_to_merge.vue'), MrWidgetReadyToMerge: () => import('./components/states/new_ready_to_merge.vue'),
'sha-mismatch': ShaMismatch, ShaMismatch,
'mr-widget-checking': CheckingState, MrWidgetChecking: CheckingState,
'mr-widget-unresolved-discussions': UnresolvedDiscussionsState, MrWidgetUnresolvedDiscussions: UnresolvedDiscussionsState,
'mr-widget-pipeline-blocked': PipelineBlockedState, MrWidgetPipelineBlocked: PipelineBlockedState,
'mr-widget-pipeline-failed': PipelineFailedState, MrWidgetPipelineFailed: PipelineFailedState,
MrWidgetAutoMergeEnabled, MrWidgetAutoMergeEnabled,
'mr-widget-auto-merge-failed': AutoMergeFailed, MrWidgetAutoMergeFailed: AutoMergeFailed,
'mr-widget-rebase': RebaseState, MrWidgetRebase: RebaseState,
SourceBranchRemovalStatus, SourceBranchRemovalStatus,
GroupedCodequalityReportsApp: () => GroupedCodequalityReportsApp: () =>
import('../reports/codequality_report/grouped_codequality_reports_app.vue'), 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 '~/behaviors/markdown/render_gfm';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale'; 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 glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { spriteIcon } from '~/lib/utils/common_utils'; import { spriteIcon } from '~/lib/utils/common_utils';
import TimelineEntryItem from './timeline_entry_item.vue'; import TimelineEntryItem from './timeline_entry_item.vue';
@ -43,7 +43,7 @@ export default {
name: 'SystemNote', name: 'SystemNote',
components: { components: {
GlIcon, GlIcon,
noteHeader, NoteHeader,
TimelineEntryItem, TimelineEntryItem,
GlButton, GlButton,
GlSkeletonLoader, GlSkeletonLoader,

View File

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

View File

@ -44,8 +44,7 @@ class MergeRequestsFinder < IssuableFinder
:reviewer_id, :reviewer_id,
:reviewer_username, :reviewer_username,
:target_branch, :target_branch,
:wip, :wip
:attention
] ]
end end
@ -70,7 +69,6 @@ class MergeRequestsFinder < IssuableFinder
items = by_approvals(items) items = by_approvals(items)
items = by_deployments(items) items = by_deployments(items)
items = by_reviewer(items) items = by_reviewer(items)
items = by_attention(items)
by_source_project_id(items) by_source_project_id(items)
end end
@ -220,12 +218,6 @@ class MergeRequestsFinder < IssuableFinder
end end
end end
def by_attention(items)
return items unless params.attention?
items.attention(params.attention)
end
def parse_datetime(input) 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/ # 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 DateTime.parse(input.byteslice(0, 128)) if input

View File

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

View File

@ -6,20 +6,12 @@ module MergeRequestReviewerState
included do included do
enum state: { enum state: {
unreviewed: 0, unreviewed: 0,
reviewed: 1, reviewed: 1
attention_requested: 2 # 2 was removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95446
} }
validates :state, validates :state,
presence: true, presence: true,
inclusion: { in: self.states.keys } 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
end end

View File

@ -153,7 +153,7 @@ class Group < Namespace
after_create :post_create_hook after_create :post_create_hook
after_destroy :post_destroy_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_update :path_changed_hook, if: :saved_change_to_path?
after_create -> { create_or_load_association(:group_feature) } after_create -> { create_or_load_association(:group_feature) }
@ -898,6 +898,10 @@ class Group < Namespace
end end
end end
def update_two_factor_requirement_for_members
direct_and_indirect_members.find_each(&:update_two_factor_requirement)
end
private private
def feature_flag_enabled_for_self_or_ancestor?(feature_flag) def feature_flag_enabled_for_self_or_ancestor?(feature_flag)
@ -920,7 +924,7 @@ class Group < Namespace
def update_two_factor_requirement def update_two_factor_requirement
return unless saved_change_to_require_two_factor_authentication? || saved_change_to_two_factor_grace_period? 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 end
def path_changed_hook def path_changed_hook

View File

@ -417,17 +417,6 @@ class MergeRequest < ApplicationRecord
) )
end 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 def self.total_time_to_merge
join_metrics join_metrics
.merge(MergeRequest::Metrics.with_valid_time_to_merge) .merge(MergeRequest::Metrics.with_valid_time_to_merge)

View File

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

View File

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

View File

@ -47,8 +47,7 @@ module Users
storage_enforcement_banner_second_enforcement_threshold: 44, storage_enforcement_banner_second_enforcement_threshold: 44,
storage_enforcement_banner_third_enforcement_threshold: 45, storage_enforcement_banner_third_enforcement_threshold: 45,
storage_enforcement_banner_fourth_enforcement_threshold: 46, storage_enforcement_banner_fourth_enforcement_threshold: 46,
attention_requests_top_nav: 47, # 47 and 48 were removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95446
attention_requests_side_nav: 48,
# 49 was removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91533 # 49 was removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91533
# because the banner was no longer relevant. # because the banner was no longer relevant.
# Records will be migrated with https://gitlab.com/gitlab-org/gitlab/-/issues/367293 # 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 end
expose :reviewed, if: satisfies(:present?, :allows_reviewers?) do |user, options| 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 end
expose :approved, if: satisfies(:present?) do |user, options| 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 # makes one query per merge request, whereas #approved_by? makes one per user
options[:merge_request].approvals.any? { |app| app.user_id == user.id } options[:merge_request].approvals.any? { |app| app.user_id == user.id }
end 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 end
MergeRequestUserEntity.prepend_mod_with('MergeRequestUserEntity') MergeRequestUserEntity.prepend_mod_with('MergeRequestUserEntity')

View File

@ -43,8 +43,6 @@ module MergeRequests
end end
def handle_assignees_change(merge_request, old_assignees) def handle_assignees_change(merge_request, old_assignees)
bulk_update_assignees_state(merge_request, merge_request.assignees - old_assignees)
MergeRequests::HandleAssigneesChangeService MergeRequests::HandleAssigneesChangeService
.new(project: project, current_user: current_user) .new(project: project, current_user: current_user)
.async_execute(merge_request, old_assignees) .async_execute(merge_request, old_assignees)
@ -60,7 +58,6 @@ module MergeRequests
new_reviewers = merge_request.reviewers - old_reviewers new_reviewers = merge_request.reviewers - old_reviewers
merge_request_activity_counter.track_users_review_requested(users: new_reviewers) merge_request_activity_counter.track_users_review_requested(users: new_reviewers)
merge_request_activity_counter.track_reviewers_changed_action(user: current_user) merge_request_activity_counter.track_reviewers_changed_action(user: current_user)
bulk_update_reviewers_state(merge_request, new_reviewers)
end end
def cleanup_environments(merge_request) def cleanup_environments(merge_request)
@ -247,46 +244,6 @@ module MergeRequests
Milestones::MergeRequestsCountService.new(milestone).delete_cache Milestones::MergeRequestsCountService.new(milestone).delete_cache
end 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
end end

View File

@ -20,8 +20,6 @@ module MergeRequests
attrs = update_attrs.merge(assignee_ids: new_ids) attrs = update_attrs.merge(assignee_ids: new_ids)
merge_request.update!(**attrs) 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 # Defer the more expensive operations (handle_assignee_changes) to the background
MergeRequests::HandleAssigneesChangeService MergeRequests::HandleAssigneesChangeService
.new(project: project, current_user: current_user) .new(project: project, current_user: current_user)

View File

@ -5,4 +5,4 @@
= content_for :after_content do = content_for :after_content do
#js-crm-form-portal #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 :weight: 1
:idempotent: true :idempotent: true
:tags: [] :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 - :name: import_issues_csv
:worker_name: ImportIssuesCsvWorker :worker_name: ImportIssuesCsvWorker
:feature_category: :team_planning :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 - 1
- - groups_update_statistics - - groups_update_statistics
- 1 - 1
- - groups_update_two_factor_requirement_for_members
- 1
- - hashed_storage - - hashed_storage
- 1 - 1
- - import_issues_csv - - import_issues_csv

View File

@ -20190,7 +20190,6 @@ State of a review of a GitLab merge request.
| Value | Description | | 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="mergerequestreviewstatereviewed"></a>`REVIEWED` | The merge request is reviewed. |
| <a id="mergerequestreviewstateunreviewed"></a>`UNREVIEWED` | The merge request is unreviewed. | | <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 | | Value | Description |
| ----- | ----------- | | ----- | ----------- |
| <a id="usercalloutfeaturenameenumactive_user_count_threshold"></a>`ACTIVE_USER_COUNT_THRESHOLD` | Callout feature name for active_user_count_threshold. | | <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="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="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. | | <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