Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
86ace8a66c
commit
73507eaf1a
|
@ -602,9 +602,6 @@ Style/MultilineWhenThen:
|
|||
Style/NumericPredicate:
|
||||
EnforcedStyle: comparison
|
||||
|
||||
Style/FloatDivision:
|
||||
Enabled: false
|
||||
|
||||
Cop/BanCatchThrow:
|
||||
Enabled: true
|
||||
|
||||
|
|
|
@ -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'
|
|
@ -1,11 +1,11 @@
|
|||
<script>
|
||||
import { GlLoadingIcon } from '@gitlab/ui';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import notebookLab from '~/notebook/index.vue';
|
||||
import NotebookLab from '~/notebook/index.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
notebookLab,
|
||||
NotebookLab,
|
||||
GlLoadingIcon,
|
||||
},
|
||||
props: {
|
||||
|
|
|
@ -11,11 +11,11 @@ import {
|
|||
import addAdminVariable from '../graphql/mutations/admin_add_variable.mutation.graphql';
|
||||
import deleteAdminVariable from '../graphql/mutations/admin_delete_variable.mutation.graphql';
|
||||
import updateAdminVariable from '../graphql/mutations/admin_update_variable.mutation.graphql';
|
||||
import ciVariableSettings from './ci_variable_settings.vue';
|
||||
import CiVariableSettings from './ci_variable_settings.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ciVariableSettings,
|
||||
CiVariableSettings,
|
||||
},
|
||||
inject: ['endpoint'],
|
||||
data() {
|
||||
|
|
|
@ -14,11 +14,11 @@ import {
|
|||
import addGroupVariable from '../graphql/mutations/group_add_variable.mutation.graphql';
|
||||
import deleteGroupVariable from '../graphql/mutations/group_delete_variable.mutation.graphql';
|
||||
import updateGroupVariable from '../graphql/mutations/group_update_variable.mutation.graphql';
|
||||
import ciVariableSettings from './ci_variable_settings.vue';
|
||||
import CiVariableSettings from './ci_variable_settings.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ciVariableSettings,
|
||||
CiVariableSettings,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
inject: ['endpoint', 'groupPath', 'groupId'],
|
||||
|
|
|
@ -16,11 +16,11 @@ import {
|
|||
import addProjectVariable from '../graphql/mutations/project_add_variable.mutation.graphql';
|
||||
import deleteProjectVariable from '../graphql/mutations/project_delete_variable.mutation.graphql';
|
||||
import updateProjectVariable from '../graphql/mutations/project_update_variable.mutation.graphql';
|
||||
import ciVariableSettings from './ci_variable_settings.vue';
|
||||
import CiVariableSettings from './ci_variable_settings.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ciVariableSettings,
|
||||
CiVariableSettings,
|
||||
},
|
||||
inject: ['endpoint', 'projectFullPath', 'projectId'],
|
||||
data() {
|
||||
|
|
|
@ -108,7 +108,6 @@ export default {
|
|||
return {
|
||||
newEnvironments: [],
|
||||
isTipDismissed: getCookie(AWS_TIP_DISMISSED_COOKIE_NAME) === 'true',
|
||||
typeOptions: variableOptions,
|
||||
validationErrorEventProperty: '',
|
||||
variable: { ...defaultVariableState, ...this.selectedVariable },
|
||||
};
|
||||
|
@ -259,6 +258,7 @@ export default {
|
|||
},
|
||||
},
|
||||
defaultScope: allEnvironments.text,
|
||||
variableOptions,
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -298,16 +298,20 @@ export default {
|
|||
/>
|
||||
</gl-form-group>
|
||||
|
||||
<div class="d-flex">
|
||||
<gl-form-group :label="__('Type')" label-for="ci-variable-type" class="w-50 gl-mr-5">
|
||||
<div class="gl-display-flex">
|
||||
<gl-form-group :label="__('Type')" label-for="ci-variable-type" class="gl-w-half gl-mr-5">
|
||||
<gl-form-select
|
||||
id="ci-variable-type"
|
||||
v-model="variable.variableType"
|
||||
:options="typeOptions"
|
||||
:options="$options.variableOptions"
|
||||
/>
|
||||
</gl-form-group>
|
||||
|
||||
<gl-form-group label-for="ci-variable-env" class="w-50" data-testid="environment-scope">
|
||||
<gl-form-group
|
||||
label-for="ci-variable-env"
|
||||
class="gl-w-half"
|
||||
data-testid="environment-scope"
|
||||
>
|
||||
<template #label>
|
||||
{{ __('Environment scope') }}
|
||||
<gl-link
|
||||
|
|
|
@ -10,7 +10,7 @@ export const displayText = {
|
|||
};
|
||||
|
||||
export const variableTypes = {
|
||||
variableType: 'ENV_VAR',
|
||||
envType: 'ENV_VAR',
|
||||
fileType: 'FILE',
|
||||
};
|
||||
|
||||
|
@ -29,13 +29,13 @@ export const allEnvironments = {
|
|||
export const variableText = {
|
||||
[types.variableType]: __('Variable'),
|
||||
[types.fileType]: __('File'),
|
||||
[variableTypes.variableType]: __('Variable'),
|
||||
[variableTypes.envType]: __('Variable'),
|
||||
[variableTypes.fileType]: __('File'),
|
||||
};
|
||||
|
||||
export const variableOptions = [
|
||||
{ value: types.variableType, text: variableText[types.variableType] },
|
||||
{ value: types.fileType, text: variableText[types.fileType] },
|
||||
{ value: variableTypes.envType, text: variableText[variableTypes.envType] },
|
||||
{ value: variableTypes.fileType, text: variableText[variableTypes.fileType] },
|
||||
];
|
||||
|
||||
export const defaultVariableState = {
|
||||
|
@ -44,7 +44,7 @@ export const defaultVariableState = {
|
|||
masked: false,
|
||||
protected: false,
|
||||
value: '',
|
||||
variableType: types.variableType,
|
||||
variableType: variableTypes.envType,
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||
|
|
|
@ -5,3 +5,7 @@ export const trackViewsOptions = {
|
|||
category: 'Customer Relations' /* eslint-disable-line @gitlab/require-i18n-strings */,
|
||||
action: 'view_contacts_list',
|
||||
};
|
||||
export const organizationTrackViewsOptions = {
|
||||
category: 'Customer Relations' /* eslint-disable-line @gitlab/require-i18n-strings */,
|
||||
action: 'view_organizations_list',
|
||||
};
|
||||
|
|
|
@ -3,6 +3,7 @@ import Vue from 'vue';
|
|||
import VueApollo from 'vue-apollo';
|
||||
import VueRouter from 'vue-router';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import CrmOrganizationsRoot from './components/organizations_root.vue';
|
||||
import routes from './routes';
|
||||
|
||||
|
@ -21,7 +22,14 @@ export default () => {
|
|||
return false;
|
||||
}
|
||||
|
||||
const { basePath, canAdminCrmOrganization, groupFullPath, groupId, groupIssuesPath } = el.dataset;
|
||||
const {
|
||||
basePath,
|
||||
canAdminCrmOrganization,
|
||||
groupFullPath,
|
||||
groupId,
|
||||
groupIssuesPath,
|
||||
textQuery,
|
||||
} = el.dataset;
|
||||
|
||||
const router = new VueRouter({
|
||||
base: basePath,
|
||||
|
@ -33,7 +41,13 @@ export default () => {
|
|||
el,
|
||||
router,
|
||||
apolloProvider,
|
||||
provide: { canAdminCrmOrganization, groupFullPath, groupId, groupIssuesPath },
|
||||
provide: {
|
||||
canAdminCrmOrganization: parseBoolean(canAdminCrmOrganization),
|
||||
groupFullPath,
|
||||
groupId,
|
||||
groupIssuesPath,
|
||||
textQuery,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(CrmOrganizationsRoot);
|
||||
},
|
||||
|
|
|
@ -1,12 +1,37 @@
|
|||
#import "./crm_organization_fields.fragment.graphql"
|
||||
|
||||
query organizations($groupFullPath: ID!) {
|
||||
query organizations(
|
||||
$groupFullPath: ID!
|
||||
$state: CustomerRelationsOrganizationState
|
||||
$searchTerm: String
|
||||
$sort: OrganizationSort
|
||||
$firstPageSize: Int
|
||||
$lastPageSize: Int
|
||||
$prevPageCursor: String = ""
|
||||
$nextPageCursor: String = ""
|
||||
$ids: [CustomerRelationsOrganizationID!]
|
||||
) {
|
||||
group(fullPath: $groupFullPath) {
|
||||
id
|
||||
organizations {
|
||||
organizations(
|
||||
state: $state
|
||||
search: $searchTerm
|
||||
sort: $sort
|
||||
first: $firstPageSize
|
||||
last: $lastPageSize
|
||||
after: $nextPageCursor
|
||||
before: $prevPageCursor
|
||||
ids: $ids
|
||||
) {
|
||||
nodes {
|
||||
...OrganizationFragment
|
||||
}
|
||||
pageInfo {
|
||||
hasNextPage
|
||||
endCursor
|
||||
hasPreviousPage
|
||||
startCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
query organizationsCountByState($groupFullPath: ID!, $searchTerm: String) {
|
||||
group(fullPath: $groupFullPath) {
|
||||
__typename
|
||||
id
|
||||
organizationStateCounts(search: $searchTerm) {
|
||||
all
|
||||
active
|
||||
inactive
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ export default {
|
|||
getQuery() {
|
||||
return {
|
||||
query: getGroupOrganizationsQuery,
|
||||
variables: { groupFullPath: this.groupFullPath },
|
||||
variables: { groupFullPath: this.groupFullPath, ids: [this.organizationGraphQLId] },
|
||||
};
|
||||
},
|
||||
title() {
|
||||
|
|
|
@ -1,36 +1,54 @@
|
|||
<script>
|
||||
import { GlAlert, GlButton, GlLoadingIcon, GlTable, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import { GlButton, GlLoadingIcon, GlTable, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { s__, __ } from '~/locale';
|
||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import { EDIT_ROUTE_NAME, NEW_ROUTE_NAME } from '../../constants';
|
||||
import PaginatedTableWithSearchAndTabs from '~/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue';
|
||||
import {
|
||||
bodyTrClass,
|
||||
initialPaginationState,
|
||||
} from '~/vue_shared/components/paginated_table_with_search_and_tabs/constants';
|
||||
import { convertToSnakeCase } from '~/lib/utils/text_utility';
|
||||
import { EDIT_ROUTE_NAME, NEW_ROUTE_NAME, organizationTrackViewsOptions } from '../../constants';
|
||||
import getGroupOrganizationsQuery from './graphql/get_group_organizations.query.graphql';
|
||||
import getGroupOrganizationsCountByStateQuery from './graphql/get_group_organizations_count_by_state.query.graphql';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlAlert,
|
||||
GlButton,
|
||||
GlLoadingIcon,
|
||||
GlTable,
|
||||
PaginatedTableWithSearchAndTabs,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
inject: ['canAdminCrmOrganization', 'groupFullPath', 'groupIssuesPath'],
|
||||
inject: ['canAdminCrmOrganization', 'groupFullPath', 'groupIssuesPath', 'textQuery'],
|
||||
data() {
|
||||
return {
|
||||
organizations: [],
|
||||
organizations: { list: [] },
|
||||
organizationsCount: {},
|
||||
error: false,
|
||||
filteredByStatus: '',
|
||||
pagination: initialPaginationState,
|
||||
statusFilter: 'all',
|
||||
searchTerm: this.textQuery,
|
||||
sort: 'NAME_ASC',
|
||||
sortDesc: false,
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
organizations: {
|
||||
query() {
|
||||
return getGroupOrganizationsQuery;
|
||||
},
|
||||
query: getGroupOrganizationsQuery,
|
||||
variables() {
|
||||
return {
|
||||
groupFullPath: this.groupFullPath,
|
||||
searchTerm: this.searchTerm,
|
||||
state: this.statusFilter,
|
||||
sort: this.sort,
|
||||
firstPageSize: this.pagination.firstPageSize,
|
||||
lastPageSize: this.pagination.lastPageSize,
|
||||
prevPageCursor: this.pagination.prevPageCursor,
|
||||
nextPageCursor: this.pagination.nextPageCursor,
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
|
@ -40,19 +58,52 @@ export default {
|
|||
this.error = true;
|
||||
},
|
||||
},
|
||||
organizationsCount: {
|
||||
query: getGroupOrganizationsCountByStateQuery,
|
||||
variables() {
|
||||
return {
|
||||
groupFullPath: this.groupFullPath,
|
||||
searchTerm: this.searchTerm,
|
||||
};
|
||||
},
|
||||
update(data) {
|
||||
return data?.group?.organizationStateCounts;
|
||||
},
|
||||
error() {
|
||||
this.error = true;
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isLoading() {
|
||||
return this.$apollo.queries.organizations.loading;
|
||||
},
|
||||
canAdmin() {
|
||||
return parseBoolean(this.canAdminCrmOrganization);
|
||||
tbodyTrClass() {
|
||||
return {
|
||||
[bodyTrClass]: !this.loading && !this.isEmpty,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
errorAlertDismissed() {
|
||||
this.error = false;
|
||||
},
|
||||
extractOrganizations(data) {
|
||||
const organizations = data?.group?.organizations?.nodes || [];
|
||||
return organizations.slice().sort((a, b) => a.name.localeCompare(b.name));
|
||||
const pageInfo = data?.group?.organizations?.pageInfo || {};
|
||||
return {
|
||||
list: organizations,
|
||||
pageInfo,
|
||||
};
|
||||
},
|
||||
fetchSortedData({ sortBy, sortDesc }) {
|
||||
const sortingColumn = convertToSnakeCase(sortBy).toUpperCase();
|
||||
const sortingDirection = sortDesc ? 'DESC' : 'ASC';
|
||||
this.pagination = initialPaginationState;
|
||||
this.sort = `${sortingColumn}_${sortingDirection}`;
|
||||
},
|
||||
filtersChanged({ searchTerm }) {
|
||||
this.searchTerm = searchTerm;
|
||||
},
|
||||
getIssuesPath(path, value) {
|
||||
return `${path}?crm_organization_id=${value}`;
|
||||
|
@ -60,6 +111,13 @@ export default {
|
|||
getEditRoute(id) {
|
||||
return { name: this.$options.EDIT_ROUTE_NAME, params: { id } };
|
||||
},
|
||||
pageChanged(pagination) {
|
||||
this.pagination = pagination;
|
||||
},
|
||||
statusChanged({ filters, status }) {
|
||||
this.statusFilter = filters;
|
||||
this.filteredByStatus = status;
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{ key: 'name', sortable: true },
|
||||
|
@ -83,60 +141,113 @@ export default {
|
|||
},
|
||||
EDIT_ROUTE_NAME,
|
||||
NEW_ROUTE_NAME,
|
||||
statusTabs: [
|
||||
{
|
||||
title: __('Active'),
|
||||
status: 'ACTIVE',
|
||||
filters: 'active',
|
||||
},
|
||||
{
|
||||
title: __('Inactive'),
|
||||
status: 'INACTIVE',
|
||||
filters: 'inactive',
|
||||
},
|
||||
{
|
||||
title: __('All'),
|
||||
status: 'ALL',
|
||||
filters: 'all',
|
||||
},
|
||||
],
|
||||
organizationTrackViewsOptions,
|
||||
emptyArray: [],
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<gl-alert v-if="error" variant="danger" class="gl-mt-6" @dismiss="error = false">
|
||||
{{ $options.i18n.errorText }}
|
||||
</gl-alert>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-baseline gl-flex-direction-row gl-justify-content-space-between gl-mt-6"
|
||||
<paginated-table-with-search-and-tabs
|
||||
:show-items="true"
|
||||
:show-error-msg="false"
|
||||
:i18n="$options.i18n"
|
||||
:items="organizations.list"
|
||||
:page-info="organizations.pageInfo"
|
||||
:items-count="organizationsCount"
|
||||
:status-tabs="$options.statusTabs"
|
||||
:track-views-options="$options.organizationTrackViewsOptions"
|
||||
:filter-search-tokens="$options.emptyArray"
|
||||
filter-search-key="organizations"
|
||||
@page-changed="pageChanged"
|
||||
@tabs-changed="statusChanged"
|
||||
@filters-changed="filtersChanged"
|
||||
@error-alert-dismissed="errorAlertDismissed"
|
||||
>
|
||||
<h2 class="gl-font-size-h2 gl-my-0">
|
||||
{{ $options.i18n.title }}
|
||||
</h2>
|
||||
<div
|
||||
v-if="canAdmin"
|
||||
class="gl-display-none gl-md-display-flex gl-align-items-center gl-justify-content-end"
|
||||
>
|
||||
<router-link :to="{ name: $options.NEW_ROUTE_NAME }">
|
||||
<gl-button variant="confirm" data-testid="new-organization-button">
|
||||
<template #header-actions>
|
||||
<router-link v-if="canAdminCrmOrganization" :to="{ name: $options.NEW_ROUTE_NAME }">
|
||||
<gl-button
|
||||
class="gl-my-3 gl-mr-5"
|
||||
variant="confirm"
|
||||
data-testid="new-organization-button"
|
||||
>
|
||||
{{ $options.i18n.newOrganization }}
|
||||
</gl-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<router-view />
|
||||
<gl-loading-icon v-if="isLoading" class="gl-mt-5" size="lg" />
|
||||
<gl-table
|
||||
v-else
|
||||
class="gl-mt-5"
|
||||
:items="organizations"
|
||||
:fields="$options.fields"
|
||||
:empty-text="$options.i18n.emptyText"
|
||||
show-empty
|
||||
>
|
||||
<template #cell(id)="{ value: id }">
|
||||
<gl-button
|
||||
v-gl-tooltip.hover.bottom="$options.i18n.issuesButtonLabel"
|
||||
class="gl-mr-3"
|
||||
data-testid="issues-link"
|
||||
icon="issues"
|
||||
:aria-label="$options.i18n.issuesButtonLabel"
|
||||
:href="getIssuesPath(groupIssuesPath, id)"
|
||||
/>
|
||||
<router-link :to="getEditRoute(id)">
|
||||
<gl-button
|
||||
v-if="canAdmin"
|
||||
v-gl-tooltip.hover.bottom="$options.i18n.editButtonLabel"
|
||||
data-testid="edit-organization-button"
|
||||
icon="pencil"
|
||||
:aria-label="$options.i18n.editButtonLabel"
|
||||
/>
|
||||
</router-link>
|
||||
</template>
|
||||
</gl-table>
|
||||
|
||||
<template #title>
|
||||
{{ $options.i18n.title }}
|
||||
</template>
|
||||
|
||||
<template #table>
|
||||
<gl-table
|
||||
:items="organizations.list"
|
||||
:fields="$options.fields"
|
||||
:busy="isLoading"
|
||||
stacked="md"
|
||||
:tbody-tr-class="tbodyTrClass"
|
||||
sort-direction="asc"
|
||||
:sort-desc.sync="sortDesc"
|
||||
sort-by="createdAt"
|
||||
show-empty
|
||||
no-local-sorting
|
||||
sort-icon-left
|
||||
fixed
|
||||
@sort-changed="fetchSortedData"
|
||||
>
|
||||
<template #cell(id)="{ value: id }">
|
||||
<gl-button
|
||||
v-gl-tooltip.hover.bottom="$options.i18n.issuesButtonLabel"
|
||||
class="gl-mr-3"
|
||||
data-testid="issues-link"
|
||||
icon="issues"
|
||||
:aria-label="$options.i18n.issuesButtonLabel"
|
||||
:href="getIssuesPath(groupIssuesPath, id)"
|
||||
/>
|
||||
<router-link :to="getEditRoute(id)">
|
||||
<gl-button
|
||||
v-if="canAdminCrmOrganization"
|
||||
v-gl-tooltip.hover.bottom="$options.i18n.editButtonLabel"
|
||||
data-testid="edit-organization-button"
|
||||
icon="pencil"
|
||||
:aria-label="$options.i18n.editButtonLabel"
|
||||
/>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<template #table-busy>
|
||||
<gl-loading-icon size="lg" color="dark" class="mt-3" />
|
||||
</template>
|
||||
|
||||
<template #empty>
|
||||
<span v-if="error">
|
||||
{{ $options.i18n.errorText }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ $options.i18n.emptyText }}
|
||||
</span>
|
||||
</template>
|
||||
</gl-table>
|
||||
</template>
|
||||
</paginated-table-with-search-and-tabs>
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -4,11 +4,11 @@ import { head, tail } from 'lodash';
|
|||
import { s__, sprintf } from '~/locale';
|
||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||
|
||||
import actionBtn from './action_btn.vue';
|
||||
import ActionBtn from './action_btn.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
actionBtn,
|
||||
ActionBtn,
|
||||
GlButton,
|
||||
GlIcon,
|
||||
GlLink,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script>
|
||||
import deployKey from './key.vue';
|
||||
import DeployKey from './key.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
deployKey,
|
||||
DeployKey,
|
||||
},
|
||||
props: {
|
||||
keys: {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import Vue from 'vue';
|
||||
import deployKeysApp from './components/app.vue';
|
||||
import DeployKeysApp from './components/app.vue';
|
||||
|
||||
export default () =>
|
||||
new Vue({
|
||||
el: document.getElementById('js-deploy-keys'),
|
||||
components: {
|
||||
deployKeysApp,
|
||||
DeployKeysApp,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
@ -11,7 +11,7 @@ import NoPreviewViewer from '~/vue_shared/components/diff_viewer/viewers/no_prev
|
|||
import NotDiffableViewer from '~/vue_shared/components/diff_viewer/viewers/not_diffable.vue';
|
||||
import NoteForm from '~/notes/components/note_form.vue';
|
||||
import eventHub from '~/notes/event_hub';
|
||||
import userAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import { IMAGE_DIFF_POSITION_TYPE } from '../constants';
|
||||
import { getDiffMode } from '../store/utils';
|
||||
import DiffDiscussions from './diff_discussions.vue';
|
||||
|
@ -28,7 +28,7 @@ export default {
|
|||
ImageDiffOverlay,
|
||||
NotDiffableViewer,
|
||||
NoPreviewViewer,
|
||||
userAvatarLink,
|
||||
UserAvatarLink,
|
||||
DiffFileDrafts,
|
||||
},
|
||||
mixins: [diffLineNoteFormMixin, draftCommentsMixin],
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
import { GlIcon } from '@gitlab/ui';
|
||||
import { mapActions } from 'vuex';
|
||||
import DesignNotePin from '~/vue_shared/components/design_management/design_note_pin.vue';
|
||||
import noteableDiscussion from '~/notes/components/noteable_discussion.vue';
|
||||
import NoteableDiscussion from '~/notes/components/noteable_discussion.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
noteableDiscussion,
|
||||
NoteableDiscussion,
|
||||
GlIcon,
|
||||
DesignNotePin,
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';
|
|||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import MultilineCommentForm from '~/notes/components/multiline_comment_form.vue';
|
||||
import { commentLineOptions, formatLineRange } from '~/notes/components/multiline_comment_utils';
|
||||
import noteForm from '~/notes/components/note_form.vue';
|
||||
import NoteForm from '~/notes/components/note_form.vue';
|
||||
import autosave from '~/notes/mixins/autosave';
|
||||
import {
|
||||
DIFF_NOTE_TYPE,
|
||||
|
@ -18,7 +18,7 @@ import {
|
|||
|
||||
export default {
|
||||
components: {
|
||||
noteForm,
|
||||
NoteForm,
|
||||
MultilineCommentForm,
|
||||
},
|
||||
mixins: [autosave, diffLineNoteFormMixin, glFeatureFlagsMixin()],
|
||||
|
|
|
@ -3,7 +3,7 @@ import { mapActions, mapState, mapGetters } from 'vuex';
|
|||
import { getCookie, parseBoolean, removeCookie } from '~/lib/utils/common_utils';
|
||||
|
||||
import eventHub from '../notes/event_hub';
|
||||
import diffsApp from './components/app.vue';
|
||||
import DiffsApp from './components/app.vue';
|
||||
|
||||
import { TREE_LIST_STORAGE_KEY, DIFF_WHITESPACE_COOKIE_NAME } from './constants';
|
||||
import { getReviewsForMergeRequest } from './utils/file_reviews';
|
||||
|
@ -14,7 +14,7 @@ export default function initDiffsApp(store) {
|
|||
el: '#js-diffs-app',
|
||||
name: 'MergeRequestDiffs',
|
||||
components: {
|
||||
diffsApp,
|
||||
DiffsApp,
|
||||
},
|
||||
store,
|
||||
data() {
|
||||
|
|
|
@ -20,13 +20,13 @@ import {
|
|||
} from '@gitlab/ui';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { s__, n__ } from '~/locale';
|
||||
import instanceComponent from '~/vue_shared/components/deployment_instance.vue';
|
||||
import InstanceComponent from '~/vue_shared/components/deployment_instance.vue';
|
||||
import { STATUS_MAP, CANARY_STATUS } from '../constants';
|
||||
import CanaryIngress from './canary_ingress.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
instanceComponent,
|
||||
InstanceComponent,
|
||||
CanaryIngress,
|
||||
GlIcon,
|
||||
GlLoadingIcon,
|
||||
|
|
|
@ -2,7 +2,7 @@ import Vue from 'vue';
|
|||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import Translate from '~/vue_shared/translate';
|
||||
import environmentsFolderApp from './environments_folder_view.vue';
|
||||
import EnvironmentsFolderApp from './environments_folder_view.vue';
|
||||
|
||||
Vue.use(Translate);
|
||||
Vue.use(VueApollo);
|
||||
|
@ -17,7 +17,7 @@ export default () => {
|
|||
return new Vue({
|
||||
el,
|
||||
components: {
|
||||
environmentsFolderApp,
|
||||
EnvironmentsFolderApp,
|
||||
},
|
||||
apolloProvider,
|
||||
provide: {
|
||||
|
|
|
@ -21,10 +21,10 @@ import { VISIBILITY_TYPE_ICON, GROUP_VISIBILITY_TYPE, ITEM_TYPE } from '../const
|
|||
|
||||
import eventHub from '../event_hub';
|
||||
|
||||
import itemActions from './item_actions.vue';
|
||||
import itemCaret from './item_caret.vue';
|
||||
import itemStats from './item_stats.vue';
|
||||
import itemTypeIcon from './item_type_icon.vue';
|
||||
import ItemActions from './item_actions.vue';
|
||||
import ItemCaret from './item_caret.vue';
|
||||
import ItemStats from './item_stats.vue';
|
||||
import ItemTypeIcon from './item_type_icon.vue';
|
||||
|
||||
export default {
|
||||
directives: {
|
||||
|
@ -41,10 +41,10 @@ export default {
|
|||
GlPopover,
|
||||
GlLink,
|
||||
UserAccessRoleBadge,
|
||||
itemCaret,
|
||||
itemTypeIcon,
|
||||
itemActions,
|
||||
itemStats,
|
||||
ItemCaret,
|
||||
ItemTypeIcon,
|
||||
ItemActions,
|
||||
ItemStats,
|
||||
},
|
||||
inject: ['currentGroupVisibility'],
|
||||
props: {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
<script>
|
||||
import { GlBadge } from '@gitlab/ui';
|
||||
import isProjectPendingRemoval from 'ee_else_ce/groups/mixins/is_project_pending_removal';
|
||||
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import {
|
||||
ITEM_TYPE,
|
||||
VISIBILITY_TYPE_ICON,
|
||||
GROUP_VISIBILITY_TYPE,
|
||||
PROJECT_VISIBILITY_TYPE,
|
||||
} from '../constants';
|
||||
import itemStatsValue from './item_stats_value.vue';
|
||||
import ItemStatsValue from './item_stats_value.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
timeAgoTooltip,
|
||||
itemStatsValue,
|
||||
TimeAgoTooltip,
|
||||
ItemStatsValue,
|
||||
GlBadge,
|
||||
},
|
||||
mixins: [isProjectPendingRemoval],
|
||||
|
|
|
@ -4,9 +4,9 @@ import { parseBoolean } from '~/lib/utils/common_utils';
|
|||
import UserCallout from '~/user_callout';
|
||||
import Translate from '../vue_shared/translate';
|
||||
|
||||
import groupsApp from './components/app.vue';
|
||||
import groupFolderComponent from './components/group_folder.vue';
|
||||
import groupItemComponent from './components/group_item.vue';
|
||||
import GroupsApp from './components/app.vue';
|
||||
import GroupFolderComponent from './components/group_folder.vue';
|
||||
import GroupItemComponent from './components/group_item.vue';
|
||||
import { GROUPS_LIST_HOLDER_CLASS, CONTENT_LIST_CLASS } from './constants';
|
||||
import GroupFilterableList from './groups_filterable_list';
|
||||
import GroupsService from './service/groups_service';
|
||||
|
@ -33,8 +33,8 @@ export default (containerId = 'js-groups-tree', endpoint, action = '') => {
|
|||
dataEl = containerEl.querySelector(CONTENT_LIST_CLASS);
|
||||
}
|
||||
|
||||
Vue.component('GroupFolder', groupFolderComponent);
|
||||
Vue.component('GroupItem', groupItemComponent);
|
||||
Vue.component('GroupFolder', GroupFolderComponent);
|
||||
Vue.component('GroupItem', GroupItemComponent);
|
||||
|
||||
Vue.use(GlToast);
|
||||
|
||||
|
@ -42,7 +42,7 @@ export default (containerId = 'js-groups-tree', endpoint, action = '') => {
|
|||
new Vue({
|
||||
el,
|
||||
components: {
|
||||
groupsApp,
|
||||
GroupsApp,
|
||||
},
|
||||
provide() {
|
||||
const {
|
||||
|
|
|
@ -26,11 +26,17 @@ export const GROUPS_CATEGORY = s__('GlobalSearch|Groups');
|
|||
|
||||
export const PROJECTS_CATEGORY = s__('GlobalSearch|Projects');
|
||||
|
||||
export const ISSUES_CATEGORY = 'Recent issues';
|
||||
export const ISSUES_CATEGORY = s__('GlobalSearch|Recent issues');
|
||||
|
||||
export const MERGE_REQUEST_CATEGORY = 'Recent merge requests';
|
||||
export const MERGE_REQUEST_CATEGORY = s__('GlobalSearch|Recent merge requests');
|
||||
|
||||
export const RECENT_EPICS_CATEGORY = 'Recent epics';
|
||||
export const RECENT_EPICS_CATEGORY = s__('GlobalSearch|Recent epics');
|
||||
|
||||
export const IN_THIS_PROJECT_CATEGORY = s__('GlobalSearch|In this project');
|
||||
|
||||
export const SETTINGS_CATEGORY = s__('GlobalSearch|Settings');
|
||||
|
||||
export const HELP_CATEGORY = s__('GlobalSearch|Help');
|
||||
|
||||
export const LARGE_AVATAR_PX = 32;
|
||||
|
||||
|
@ -55,3 +61,16 @@ export const HEADER_INIT_EVENTS = ['input', 'focus'];
|
|||
export const IS_SEARCHING = 'is-searching';
|
||||
export const IS_FOCUSED = 'is-focused';
|
||||
export const IS_NOT_FOCUSED = 'is-not-focused';
|
||||
|
||||
export const DROPDOWN_ORDER = [
|
||||
MERGE_REQUEST_CATEGORY,
|
||||
ISSUES_CATEGORY,
|
||||
RECENT_EPICS_CATEGORY,
|
||||
GROUPS_CATEGORY,
|
||||
PROJECTS_CATEGORY,
|
||||
IN_THIS_PROJECT_CATEGORY,
|
||||
SETTINGS_CATEGORY,
|
||||
HELP_CATEGORY,
|
||||
];
|
||||
|
||||
export const FETCH_TYPES = ['generic', 'search'];
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
import { omitBy, isNil } from 'lodash';
|
||||
import { objectToQuery } from '~/lib/utils/url_utility';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { FETCH_TYPES } from '../constants';
|
||||
import * as types from './mutation_types';
|
||||
|
||||
export const fetchAutocompleteOptions = ({ commit, getters }) => {
|
||||
commit(types.REQUEST_AUTOCOMPLETE);
|
||||
export const autocompleteQuery = ({ state, fetchType }) => {
|
||||
const query = omitBy(
|
||||
{
|
||||
term: state.search,
|
||||
project_id: state.searchContext?.project?.id,
|
||||
project_ref: state.searchContext?.ref,
|
||||
filter: fetchType,
|
||||
},
|
||||
isNil,
|
||||
);
|
||||
|
||||
return `${state.autocompletePath}?${objectToQuery(query)}`;
|
||||
};
|
||||
|
||||
const doFetch = ({ commit, state, fetchType }) => {
|
||||
return axios
|
||||
.get(getters.autocompleteQuery)
|
||||
.get(autocompleteQuery({ state, fetchType }))
|
||||
.then(({ data }) => {
|
||||
commit(types.RECEIVE_AUTOCOMPLETE_SUCCESS, data);
|
||||
})
|
||||
|
@ -13,6 +29,13 @@ export const fetchAutocompleteOptions = ({ commit, getters }) => {
|
|||
});
|
||||
};
|
||||
|
||||
export const fetchAutocompleteOptions = ({ commit, state }) => {
|
||||
commit(types.REQUEST_AUTOCOMPLETE);
|
||||
const promises = FETCH_TYPES.map((fetchType) => doFetch({ commit, state, fetchType }));
|
||||
|
||||
return Promise.all(promises);
|
||||
};
|
||||
|
||||
export const clearAutocomplete = ({ commit }) => {
|
||||
commit(types.CLEAR_AUTOCOMPLETE);
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ import {
|
|||
PROJECTS_CATEGORY,
|
||||
GROUPS_CATEGORY,
|
||||
SEARCH_SHORTCUTS_MIN_CHARACTERS,
|
||||
DROPDOWN_ORDER,
|
||||
} from '../constants';
|
||||
|
||||
export const searchQuery = (state) => {
|
||||
|
@ -34,19 +35,6 @@ export const searchQuery = (state) => {
|
|||
return `${state.searchPath}?${objectToQuery(query)}`;
|
||||
};
|
||||
|
||||
export const autocompleteQuery = (state) => {
|
||||
const query = omitBy(
|
||||
{
|
||||
term: state.search,
|
||||
project_id: state.searchContext?.project?.id,
|
||||
project_ref: state.searchContext?.ref,
|
||||
},
|
||||
isNil,
|
||||
);
|
||||
|
||||
return `${state.autocompletePath}?${objectToQuery(query)}`;
|
||||
};
|
||||
|
||||
export const scopedIssuesPath = (state) => {
|
||||
return (
|
||||
state.searchContext?.project_metadata?.issues_path ||
|
||||
|
@ -197,7 +185,9 @@ export const autocompleteGroupedSearchOptions = (state) => {
|
|||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
return results.sort(
|
||||
(a, b) => DROPDOWN_ORDER.indexOf(a.category) - DROPDOWN_ORDER.indexOf(b.category),
|
||||
);
|
||||
};
|
||||
|
||||
export const searchOptions = (state, getters) => {
|
||||
|
|
|
@ -8,9 +8,11 @@ export default {
|
|||
},
|
||||
[types.RECEIVE_AUTOCOMPLETE_SUCCESS](state, data) {
|
||||
state.loading = false;
|
||||
state.autocompleteOptions = data.map((d, i) => {
|
||||
return { html_id: `autocomplete-${d.category}-${i}`, ...d };
|
||||
});
|
||||
state.autocompleteOptions = [...state.autocompleteOptions].concat(
|
||||
data.map((d, i) => {
|
||||
return { html_id: `autocomplete-${d.category}-${i}`, ...d };
|
||||
}),
|
||||
);
|
||||
state.autocompleteError = false;
|
||||
},
|
||||
[types.RECEIVE_AUTOCOMPLETE_ERROR](state) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
|
|||
import { mapActions, mapState, mapGetters } from 'vuex';
|
||||
import timeAgoMixin from '~/vue_shared/mixins/timeago';
|
||||
import CiIcon from '~/vue_shared/components/ci_icon.vue';
|
||||
import userAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import { rightSidebarViews } from '../constants';
|
||||
import IdeStatusList from './ide_status_list.vue';
|
||||
import IdeStatusMr from './ide_status_mr.vue';
|
||||
|
@ -12,7 +12,7 @@ import IdeStatusMr from './ide_status_mr.vue';
|
|||
export default {
|
||||
components: {
|
||||
GlIcon,
|
||||
userAvatarImage,
|
||||
UserAvatarImage,
|
||||
CiIcon,
|
||||
IdeStatusList,
|
||||
IdeStatusMr,
|
||||
|
|
|
@ -4,12 +4,12 @@ import { mapActions } from 'vuex';
|
|||
import { modalTypes } from '../../constants';
|
||||
import ItemButton from './button.vue';
|
||||
import NewModal from './modal.vue';
|
||||
import upload from './upload.vue';
|
||||
import Upload from './upload.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GlIcon,
|
||||
upload,
|
||||
Upload,
|
||||
ItemButton,
|
||||
NewModal,
|
||||
},
|
||||
|
|
|
@ -17,11 +17,11 @@ import eventHub from '../event_hub';
|
|||
import getIssueStateQuery from '../queries/get_issue_state.query.graphql';
|
||||
import Service from '../services/index';
|
||||
import Store from '../stores';
|
||||
import descriptionComponent from './description.vue';
|
||||
import editedComponent from './edited.vue';
|
||||
import formComponent from './form.vue';
|
||||
import DescriptionComponent from './description.vue';
|
||||
import EditedComponent from './edited.vue';
|
||||
import FormComponent from './form.vue';
|
||||
import PinnedLinks from './pinned_links.vue';
|
||||
import titleComponent from './title.vue';
|
||||
import TitleComponent from './title.vue';
|
||||
|
||||
export default {
|
||||
WorkspaceType,
|
||||
|
@ -29,9 +29,9 @@ export default {
|
|||
GlIcon,
|
||||
GlBadge,
|
||||
GlIntersectionObserver,
|
||||
titleComponent,
|
||||
editedComponent,
|
||||
formComponent,
|
||||
TitleComponent,
|
||||
EditedComponent,
|
||||
FormComponent,
|
||||
PinnedLinks,
|
||||
ConfidentialityBadge,
|
||||
},
|
||||
|
@ -181,7 +181,7 @@ export default {
|
|||
type: Object,
|
||||
required: false,
|
||||
default: () => {
|
||||
return descriptionComponent;
|
||||
return DescriptionComponent;
|
||||
},
|
||||
},
|
||||
showTitleBorder: {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
/* eslint-disable @gitlab/vue-require-i18n-strings */
|
||||
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
timeAgoTooltip,
|
||||
TimeAgoTooltip,
|
||||
},
|
||||
props: {
|
||||
updatedAt: {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script>
|
||||
import markdownField from '~/vue_shared/components/markdown/field.vue';
|
||||
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import updateMixin from '../../mixins/update';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
markdownField,
|
||||
MarkdownField,
|
||||
},
|
||||
mixins: [updateMixin],
|
||||
props: {
|
||||
|
|
|
@ -4,14 +4,14 @@ import { isEmpty } from 'lodash';
|
|||
import Mousetrap from 'mousetrap';
|
||||
import { s__ } from '~/locale';
|
||||
import CiIcon from '~/vue_shared/components/ci_icon.vue';
|
||||
import clipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
|
||||
import { clickCopyToClipboardButton } from '~/behaviors/copy_to_clipboard';
|
||||
import { keysFor, MR_COPY_SOURCE_BRANCH_NAME } from '~/behaviors/shortcuts/keybindings';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CiIcon,
|
||||
clipboardButton,
|
||||
ClipboardButton,
|
||||
GlDropdown,
|
||||
GlDropdownItem,
|
||||
GlLink,
|
||||
|
|
|
@ -22,7 +22,7 @@ export default function initLinkedResources() {
|
|||
name: 'LinkedResourcesRoot',
|
||||
apolloProvider,
|
||||
components: {
|
||||
resourceLinksBlock: ResourceLinksBlock,
|
||||
ResourceLinksBlock,
|
||||
},
|
||||
render: (createElement) =>
|
||||
createElement('resource-links-block', {
|
||||
|
|
|
@ -5,7 +5,7 @@ import initRevertCommitModal from '~/projects/commit/init_revert_commit_modal';
|
|||
import initDiffsApp from '../diffs';
|
||||
import { resetServiceWorkersPublicPath } from '../lib/utils/webpack';
|
||||
import MergeRequest from '../merge_request';
|
||||
import discussionCounter from '../notes/components/discussion_counter.vue';
|
||||
import DiscussionCounter from '../notes/components/discussion_counter.vue';
|
||||
import initDiscussionFilters from '../notes/discussion_filters';
|
||||
import initNotesApp from './init_notes';
|
||||
|
||||
|
@ -37,7 +37,7 @@ export default function initMrNotes() {
|
|||
el,
|
||||
name: 'DiscussionCounter',
|
||||
components: {
|
||||
discussionCounter,
|
||||
DiscussionCounter,
|
||||
},
|
||||
store,
|
||||
render(createElement) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { mapActions, mapState, mapGetters } from 'vuex';
|
|||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import store from '~/mr_notes/stores';
|
||||
import discussionNavigator from '../notes/components/discussion_navigator.vue';
|
||||
import notesApp from '../notes/components/notes_app.vue';
|
||||
import NotesApp from '../notes/components/notes_app.vue';
|
||||
import initWidget from '../vue_merge_request_widget';
|
||||
|
||||
export default () => {
|
||||
|
@ -13,7 +13,7 @@ export default () => {
|
|||
el: '#js-vue-mr-discussions',
|
||||
name: 'MergeRequestDiscussions',
|
||||
components: {
|
||||
notesApp,
|
||||
NotesApp,
|
||||
},
|
||||
store,
|
||||
data() {
|
||||
|
|
|
@ -137,7 +137,7 @@ marked.setOptions({
|
|||
|
||||
export default {
|
||||
components: {
|
||||
prompt: Prompt,
|
||||
Prompt,
|
||||
},
|
||||
directives: {
|
||||
SafeHtml,
|
||||
|
|
|
@ -3,7 +3,7 @@ import Prompt from '../prompt.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
prompt: Prompt,
|
||||
Prompt,
|
||||
},
|
||||
props: {
|
||||
count: {
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
slugifyWithUnderscore,
|
||||
} from '~/lib/utils/text_utility';
|
||||
import { sprintf } from '~/locale';
|
||||
import markdownField from '~/vue_shared/components/markdown/field.vue';
|
||||
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
|
||||
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
|
||||
|
@ -25,8 +25,8 @@ import { COMMENT_FORM } from '../i18n';
|
|||
import issuableStateMixin from '../mixins/issuable_state';
|
||||
import CommentFieldLayout from './comment_field_layout.vue';
|
||||
import CommentTypeDropdown from './comment_type_dropdown.vue';
|
||||
import discussionLockedWidget from './discussion_locked_widget.vue';
|
||||
import noteSignedOutWidget from './note_signed_out_widget.vue';
|
||||
import DiscussionLockedWidget from './discussion_locked_widget.vue';
|
||||
import NoteSignedOutWidget from './note_signed_out_widget.vue';
|
||||
|
||||
const { UNPROCESSABLE_ENTITY } = httpStatusCodes;
|
||||
|
||||
|
@ -34,9 +34,9 @@ export default {
|
|||
name: 'CommentForm',
|
||||
i18n: COMMENT_FORM,
|
||||
components: {
|
||||
noteSignedOutWidget,
|
||||
discussionLockedWidget,
|
||||
markdownField,
|
||||
NoteSignedOutWidget,
|
||||
DiscussionLockedWidget,
|
||||
MarkdownField,
|
||||
GlAlert,
|
||||
GlButton,
|
||||
TimelineEntryItem,
|
||||
|
|
|
@ -4,16 +4,16 @@ import { escape } from 'lodash';
|
|||
import { mapActions } from 'vuex';
|
||||
import { truncateSha } from '~/lib/utils/text_utility';
|
||||
import { s__, __, sprintf } from '~/locale';
|
||||
import noteEditedText from './note_edited_text.vue';
|
||||
import noteHeader from './note_header.vue';
|
||||
import NoteEditedText from './note_edited_text.vue';
|
||||
import NoteHeader from './note_header.vue';
|
||||
|
||||
export default {
|
||||
name: 'DiffDiscussionHeader',
|
||||
components: {
|
||||
GlAvatar,
|
||||
GlAvatarLink,
|
||||
noteEditedText,
|
||||
noteHeader,
|
||||
NoteEditedText,
|
||||
NoteHeader,
|
||||
},
|
||||
directives: {
|
||||
SafeHtml,
|
||||
|
|
|
@ -8,17 +8,17 @@ import { __ } from '~/locale';
|
|||
import '~/behaviors/markdown/render_gfm';
|
||||
import Suggestions from '~/vue_shared/components/markdown/suggestions.vue';
|
||||
import autosave from '../mixins/autosave';
|
||||
import noteAttachment from './note_attachment.vue';
|
||||
import noteAwardsList from './note_awards_list.vue';
|
||||
import noteEditedText from './note_edited_text.vue';
|
||||
import noteForm from './note_form.vue';
|
||||
import NoteAttachment from './note_attachment.vue';
|
||||
import NoteAwardsList from './note_awards_list.vue';
|
||||
import NoteEditedText from './note_edited_text.vue';
|
||||
import NoteForm from './note_form.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
noteEditedText,
|
||||
noteAwardsList,
|
||||
noteAttachment,
|
||||
noteForm,
|
||||
NoteEditedText,
|
||||
NoteAwardsList,
|
||||
NoteAttachment,
|
||||
NoteForm,
|
||||
Suggestions,
|
||||
},
|
||||
directives: {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script>
|
||||
/* eslint-disable @gitlab/vue-require-i18n-strings */
|
||||
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
|
||||
export default {
|
||||
name: 'EditedNoteText',
|
||||
components: {
|
||||
timeAgoTooltip,
|
||||
TimeAgoTooltip,
|
||||
},
|
||||
props: {
|
||||
actionText: {
|
||||
|
|
|
@ -4,7 +4,7 @@ import { mapGetters, mapActions, mapState } from 'vuex';
|
|||
import { getDraft, updateDraft } from '~/lib/utils/autosave';
|
||||
import { mergeUrlParams } from '~/lib/utils/url_utility';
|
||||
import { __ } from '~/locale';
|
||||
import markdownField from '~/vue_shared/components/markdown/field.vue';
|
||||
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
|
||||
import eventHub from '../event_hub';
|
||||
import issuableStateMixin from '../mixins/issuable_state';
|
||||
import resolvable from '../mixins/resolvable';
|
||||
|
@ -15,7 +15,7 @@ export default {
|
|||
i18n: COMMENT_FORM,
|
||||
name: 'NoteForm',
|
||||
components: {
|
||||
markdownField,
|
||||
MarkdownField,
|
||||
CommentFieldLayout,
|
||||
GlButton,
|
||||
GlSprintf,
|
||||
|
|
|
@ -8,13 +8,13 @@ import {
|
|||
} from '@gitlab/ui';
|
||||
import { mapActions } from 'vuex';
|
||||
import { __, s__ } from '~/locale';
|
||||
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||
import UserNameWithStatus from '~/sidebar/components/assignees/user_name_with_status.vue';
|
||||
|
||||
export default {
|
||||
safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
|
||||
components: {
|
||||
timeAgoTooltip,
|
||||
TimeAgoTooltip,
|
||||
GitlabTeamMemberBadge: () =>
|
||||
import('ee_component/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue'),
|
||||
GlIcon,
|
||||
|
|
|
@ -10,25 +10,25 @@ import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';
|
|||
import { s__, __, sprintf } from '~/locale';
|
||||
import diffLineNoteFormMixin from '~/notes/mixins/diff_line_note_form';
|
||||
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
|
||||
import userAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
|
||||
import eventHub from '../event_hub';
|
||||
import noteable from '../mixins/noteable';
|
||||
import resolvable from '../mixins/resolvable';
|
||||
import diffDiscussionHeader from './diff_discussion_header.vue';
|
||||
import diffWithNote from './diff_with_note.vue';
|
||||
import DiffDiscussionHeader from './diff_discussion_header.vue';
|
||||
import DiffWithNote from './diff_with_note.vue';
|
||||
import DiscussionActions from './discussion_actions.vue';
|
||||
import DiscussionNotes from './discussion_notes.vue';
|
||||
import noteForm from './note_form.vue';
|
||||
import noteSignedOutWidget from './note_signed_out_widget.vue';
|
||||
import NoteForm from './note_form.vue';
|
||||
import NoteSignedOutWidget from './note_signed_out_widget.vue';
|
||||
|
||||
export default {
|
||||
name: 'NoteableDiscussion',
|
||||
components: {
|
||||
GlIcon,
|
||||
userAvatarLink,
|
||||
diffDiscussionHeader,
|
||||
noteSignedOutWidget,
|
||||
noteForm,
|
||||
UserAvatarLink,
|
||||
DiffDiscussionHeader,
|
||||
NoteSignedOutWidget,
|
||||
NoteForm,
|
||||
DraftNote,
|
||||
TimelineEntryItem,
|
||||
DiscussionNotes,
|
||||
|
@ -120,7 +120,7 @@ export default {
|
|||
return !this.shouldRenderDiffs;
|
||||
},
|
||||
wrapperComponent() {
|
||||
return this.shouldRenderDiffs ? diffWithNote : 'div';
|
||||
return this.shouldRenderDiffs ? DiffWithNote : 'div';
|
||||
},
|
||||
wrapperComponentProps() {
|
||||
if (this.shouldRenderDiffs) {
|
||||
|
|
|
@ -22,16 +22,16 @@ import {
|
|||
commentLineOptions,
|
||||
formatLineRange,
|
||||
} from './multiline_comment_utils';
|
||||
import noteActions from './note_actions.vue';
|
||||
import NoteActions from './note_actions.vue';
|
||||
import NoteBody from './note_body.vue';
|
||||
import noteHeader from './note_header.vue';
|
||||
import NoteHeader from './note_header.vue';
|
||||
|
||||
export default {
|
||||
name: 'NoteableNote',
|
||||
components: {
|
||||
GlSprintf,
|
||||
noteHeader,
|
||||
noteActions,
|
||||
NoteHeader,
|
||||
NoteActions,
|
||||
NoteBody,
|
||||
TimelineEntryItem,
|
||||
GlAvatarLink,
|
||||
|
|
|
@ -6,34 +6,34 @@ import { __ } from '~/locale';
|
|||
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
|
||||
import OrderedLayout from '~/vue_shared/components/ordered_layout.vue';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import draftNote from '~/batch_comments/components/draft_note.vue';
|
||||
import DraftNote from '~/batch_comments/components/draft_note.vue';
|
||||
import { getLocationHash, doesHashExistInUrl } from '~/lib/utils/url_utility';
|
||||
import placeholderNote from '~/vue_shared/components/notes/placeholder_note.vue';
|
||||
import placeholderSystemNote from '~/vue_shared/components/notes/placeholder_system_note.vue';
|
||||
import skeletonLoadingContainer from '~/vue_shared/components/notes/skeleton_note.vue';
|
||||
import systemNote from '~/vue_shared/components/notes/system_note.vue';
|
||||
import PlaceholderNote from '~/vue_shared/components/notes/placeholder_note.vue';
|
||||
import PlaceholderSystemNote from '~/vue_shared/components/notes/placeholder_system_note.vue';
|
||||
import SkeletonLoadingContainer from '~/vue_shared/components/notes/skeleton_note.vue';
|
||||
import SystemNote from '~/vue_shared/components/notes/system_note.vue';
|
||||
import * as constants from '../constants';
|
||||
import eventHub from '../event_hub';
|
||||
import commentForm from './comment_form.vue';
|
||||
import discussionFilterNote from './discussion_filter_note.vue';
|
||||
import noteableDiscussion from './noteable_discussion.vue';
|
||||
import noteableNote from './noteable_note.vue';
|
||||
import CommentForm from './comment_form.vue';
|
||||
import DiscussionFilterNote from './discussion_filter_note.vue';
|
||||
import NoteableDiscussion from './noteable_discussion.vue';
|
||||
import NoteableNote from './noteable_note.vue';
|
||||
import SidebarSubscription from './sidebar_subscription.vue';
|
||||
|
||||
export default {
|
||||
name: 'NotesApp',
|
||||
components: {
|
||||
noteableNote,
|
||||
noteableDiscussion,
|
||||
systemNote,
|
||||
commentForm,
|
||||
placeholderNote,
|
||||
placeholderSystemNote,
|
||||
skeletonLoadingContainer,
|
||||
discussionFilterNote,
|
||||
NoteableNote,
|
||||
NoteableDiscussion,
|
||||
SystemNote,
|
||||
CommentForm,
|
||||
PlaceholderNote,
|
||||
PlaceholderSystemNote,
|
||||
SkeletonLoadingContainer,
|
||||
DiscussionFilterNote,
|
||||
OrderedLayout,
|
||||
SidebarSubscription,
|
||||
draftNote,
|
||||
DraftNote,
|
||||
TimelineEntryItem,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Vue from 'vue';
|
||||
import notesApp from './components/notes_app.vue';
|
||||
import NotesApp from './components/notes_app.vue';
|
||||
import initDiscussionFilters from './discussion_filters';
|
||||
import { store } from './stores';
|
||||
import initTimelineToggle from './timeline';
|
||||
|
@ -15,7 +15,7 @@ export default () => {
|
|||
el,
|
||||
name: 'NotesRoot',
|
||||
components: {
|
||||
notesApp,
|
||||
NotesApp,
|
||||
},
|
||||
store,
|
||||
data() {
|
||||
|
|
|
@ -14,16 +14,17 @@ import NpmInstallation from './npm_installation.vue';
|
|||
import NugetInstallation from './nuget_installation.vue';
|
||||
import PypiInstallation from './pypi_installation.vue';
|
||||
|
||||
const components = {
|
||||
[PACKAGE_TYPE_CONAN]: ConanInstallation,
|
||||
[PACKAGE_TYPE_MAVEN]: MavenInstallation,
|
||||
[PACKAGE_TYPE_NPM]: NpmInstallation,
|
||||
[PACKAGE_TYPE_NUGET]: NugetInstallation,
|
||||
[PACKAGE_TYPE_PYPI]: PypiInstallation,
|
||||
[PACKAGE_TYPE_COMPOSER]: ComposerInstallation,
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'InstallationCommands',
|
||||
components: {
|
||||
[PACKAGE_TYPE_CONAN]: ConanInstallation,
|
||||
[PACKAGE_TYPE_MAVEN]: MavenInstallation,
|
||||
[PACKAGE_TYPE_NPM]: NpmInstallation,
|
||||
[PACKAGE_TYPE_NUGET]: NugetInstallation,
|
||||
[PACKAGE_TYPE_PYPI]: PypiInstallation,
|
||||
[PACKAGE_TYPE_COMPOSER]: ComposerInstallation,
|
||||
},
|
||||
props: {
|
||||
packageEntity: {
|
||||
type: Object,
|
||||
|
@ -32,7 +33,7 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
installationComponent() {
|
||||
return this.$options.components[this.packageEntity.packageType];
|
||||
return components[this.packageEntity.packageType];
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Vue from 'vue';
|
||||
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
|
||||
import Translate from '~/vue_shared/translate';
|
||||
import stopJobsModal from './components/stop_jobs_modal.vue';
|
||||
import StopJobsModal from './components/stop_jobs_modal.vue';
|
||||
|
||||
Vue.use(Translate);
|
||||
|
||||
|
@ -14,7 +14,7 @@ function initJobs() {
|
|||
new Vue({
|
||||
el: `#js-${modalId}`,
|
||||
components: {
|
||||
stopJobsModal,
|
||||
StopJobsModal,
|
||||
},
|
||||
mounted() {
|
||||
stopJobsButton.classList.remove('disabled');
|
||||
|
|
|
@ -9,7 +9,7 @@ import GpgBadges from '~/gpg_badges';
|
|||
import createDefaultClient from '~/lib/graphql';
|
||||
import initBlob from '~/pages/projects/init_blob';
|
||||
import initWebIdeLink from '~/pages/projects/shared/web_ide_link';
|
||||
import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
|
||||
import CommitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
|
||||
import BlobContentViewer from '~/repository/components/blob_content_viewer.vue';
|
||||
import '~/sourcegraph/load';
|
||||
import createStore from '~/code_navigation/store';
|
||||
|
@ -64,7 +64,7 @@ if (statusLink) {
|
|||
new Vue({
|
||||
el: CommitPipelineStatusEl,
|
||||
components: {
|
||||
commitPipelineStatus,
|
||||
CommitPipelineStatus,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement('commit-pipeline-status', {
|
||||
|
|
|
@ -6,7 +6,7 @@ import { REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants';
|
|||
import setupNativeFormVariableList from '~/ci_variable_list/native_form_variable_list';
|
||||
import GlFieldErrors from '~/gl_field_errors';
|
||||
import Translate from '~/vue_shared/translate';
|
||||
import intervalPatternInput from './components/interval_pattern_input.vue';
|
||||
import IntervalPatternInput from './components/interval_pattern_input.vue';
|
||||
import TimezoneDropdown from './components/timezone_dropdown';
|
||||
|
||||
Vue.use(Translate);
|
||||
|
@ -19,7 +19,7 @@ function initIntervalPatternInput() {
|
|||
return new Vue({
|
||||
el: intervalPatternMount,
|
||||
components: {
|
||||
intervalPatternInput,
|
||||
IntervalPatternInput,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement('interval-pattern-input', {
|
||||
|
|
|
@ -14,8 +14,8 @@ import {
|
|||
featureAccessLevelDescriptions,
|
||||
} from '../constants';
|
||||
import { toggleHiddenClassBySelector } from '../external';
|
||||
import projectFeatureSetting from './project_feature_setting.vue';
|
||||
import projectSettingRow from './project_setting_row.vue';
|
||||
import ProjectFeatureSetting from './project_feature_setting.vue';
|
||||
import ProjectSettingRow from './project_setting_row.vue';
|
||||
|
||||
const FEATURE_ACCESS_LEVEL_ANONYMOUS = [30, s__('ProjectSettings|Everyone')];
|
||||
|
||||
|
@ -56,8 +56,8 @@ export default {
|
|||
},
|
||||
|
||||
components: {
|
||||
projectFeatureSetting,
|
||||
projectSettingRow,
|
||||
ProjectFeatureSetting,
|
||||
ProjectSettingRow,
|
||||
GlButton,
|
||||
GlIcon,
|
||||
GlSprintf,
|
||||
|
@ -65,7 +65,7 @@ export default {
|
|||
GlFormCheckbox,
|
||||
GlToggle,
|
||||
ConfirmDanger,
|
||||
otherProjectSettings: () =>
|
||||
OtherProjectSettings: () =>
|
||||
import(
|
||||
'jh_component/pages/projects/shared/permissions/components/other_project_settings.vue'
|
||||
),
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
import pdfjsLib from 'pdfjs-dist/build/pdf';
|
||||
import workerSrc from 'pdfjs-dist/build/pdf.worker.min';
|
||||
|
||||
import page from './page/index.vue';
|
||||
import Page from './page/index.vue';
|
||||
|
||||
export default {
|
||||
components: { page },
|
||||
components: { Page },
|
||||
props: {
|
||||
pdf: {
|
||||
type: [String, Uint8Array],
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
} from '@gitlab/ui';
|
||||
import { setUrlFragment, redirectTo } from '~/lib/utils/url_utility';
|
||||
import { __ } from '~/locale';
|
||||
import ciHeader from '~/vue_shared/components/header_ci_component.vue';
|
||||
import CiHeader from '~/vue_shared/components/header_ci_component.vue';
|
||||
import {
|
||||
LOAD_FAILURE,
|
||||
POST_FAILURE,
|
||||
|
@ -33,7 +33,7 @@ export default {
|
|||
pipelineRetry: 'pipelineRetry',
|
||||
finishedStatuses: ['FAILED', 'SUCCESS', 'CANCELED'],
|
||||
components: {
|
||||
ciHeader,
|
||||
CiHeader,
|
||||
GlAlert,
|
||||
GlButton,
|
||||
GlLoadingIcon,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import ciIcon from '~/vue_shared/components/ci_icon.vue';
|
||||
import CiIcon from '~/vue_shared/components/ci_icon.vue';
|
||||
|
||||
/**
|
||||
* Component that renders both the CI icon status and the job name.
|
||||
|
@ -9,7 +9,7 @@ import ciIcon from '~/vue_shared/components/ci_icon.vue';
|
|||
*/
|
||||
export default {
|
||||
components: {
|
||||
ciIcon,
|
||||
CiIcon,
|
||||
},
|
||||
props: {
|
||||
name: {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script>
|
||||
import tooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
|
||||
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
tooltipOnTruncate,
|
||||
TooltipOnTruncate,
|
||||
},
|
||||
props: {
|
||||
jobName: {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
import { capitalize, escape } from 'lodash';
|
||||
import tooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
|
||||
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
tooltipOnTruncate,
|
||||
TooltipOnTruncate,
|
||||
},
|
||||
props: {
|
||||
stageName: {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import pipelineHeader from './components/header_component.vue';
|
||||
import PipelineHeader from './components/header_component.vue';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
||||
|
@ -16,7 +16,7 @@ export const createPipelineHeaderApp = (elSelector, apolloProvider, graphqlResou
|
|||
new Vue({
|
||||
el,
|
||||
components: {
|
||||
pipelineHeader,
|
||||
PipelineHeader,
|
||||
},
|
||||
apolloProvider,
|
||||
provide: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Vue from 'vue';
|
||||
import { BV_SHOW_MODAL } from '~/lib/utils/constants';
|
||||
import Translate from '~/vue_shared/translate';
|
||||
import deleteAccountModal from './components/delete_account_modal.vue';
|
||||
import DeleteAccountModal from './components/delete_account_modal.vue';
|
||||
import UpdateUsername from './components/update_username.vue';
|
||||
|
||||
export default () => {
|
||||
|
@ -27,7 +27,7 @@ export default () => {
|
|||
new Vue({
|
||||
el: deleteAccountModalEl,
|
||||
components: {
|
||||
deleteAccountModal,
|
||||
DeleteAccountModal,
|
||||
},
|
||||
mounted() {
|
||||
deleteAccountButton.disabled = false;
|
||||
|
|
|
@ -4,7 +4,7 @@ import Visibility from 'visibilityjs';
|
|||
import createFlash from '~/flash';
|
||||
import Poll from '~/lib/utils/poll';
|
||||
import { __, s__, sprintf } from '~/locale';
|
||||
import ciIcon from '~/vue_shared/components/ci_icon.vue';
|
||||
import CiIcon from '~/vue_shared/components/ci_icon.vue';
|
||||
import CommitPipelineService from '../services/commit_pipeline_service';
|
||||
|
||||
export default {
|
||||
|
@ -12,7 +12,7 @@ export default {
|
|||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
components: {
|
||||
ciIcon,
|
||||
CiIcon,
|
||||
GlLoadingIcon,
|
||||
},
|
||||
props: {
|
||||
|
|
|
@ -7,14 +7,14 @@ import {
|
|||
inputPlaceholderTextMap,
|
||||
issuableTypesMap,
|
||||
} from '../constants';
|
||||
import issueToken from './issue_token.vue';
|
||||
import IssueToken from './issue_token.vue';
|
||||
|
||||
const SPACE_FACTOR = 1;
|
||||
|
||||
export default {
|
||||
name: 'RelatedIssuableInput',
|
||||
components: {
|
||||
issueToken,
|
||||
IssueToken,
|
||||
},
|
||||
props: {
|
||||
inputId: {
|
||||
|
|
|
@ -40,7 +40,7 @@ import RelatedIssuesBlock from './related_issues_block.vue';
|
|||
export default {
|
||||
name: 'RelatedIssuesRoot',
|
||||
components: {
|
||||
relatedIssuesBlock: RelatedIssuesBlock,
|
||||
RelatedIssuesBlock,
|
||||
},
|
||||
props: {
|
||||
endpoint: {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
import { GlSprintf } from '@gitlab/ui';
|
||||
import editFormButtons from './edit_form_buttons.vue';
|
||||
import EditFormButtons from './edit_form_buttons.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
editFormButtons,
|
||||
EditFormButtons,
|
||||
GlSprintf,
|
||||
},
|
||||
props: {
|
||||
|
|
|
@ -6,7 +6,7 @@ import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
|||
import createFlash from '~/flash';
|
||||
import eventHub from '~/sidebar/event_hub';
|
||||
import toast from '~/vue_shared/plugins/global_toast';
|
||||
import editForm from './edit_form.vue';
|
||||
import EditForm from './edit_form.vue';
|
||||
|
||||
export default {
|
||||
issue: 'issue',
|
||||
|
@ -23,7 +23,7 @@ export default {
|
|||
displayText: __('Unlocked'),
|
||||
},
|
||||
components: {
|
||||
editForm,
|
||||
EditForm,
|
||||
GlIcon,
|
||||
},
|
||||
directives: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { GlButton, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { __, n__, sprintf } from '~/locale';
|
||||
import userAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
|
||||
|
||||
export default {
|
||||
directives: {
|
||||
|
@ -11,7 +11,7 @@ export default {
|
|||
GlButton,
|
||||
GlIcon,
|
||||
GlLoadingIcon,
|
||||
userAvatarImage,
|
||||
UserAvatarImage,
|
||||
},
|
||||
props: {
|
||||
loading: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Vue from 'vue';
|
||||
import { IssuableType } from '~/issues/constants';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import timeTracker from './components/time_tracking/time_tracker.vue';
|
||||
import TimeTracker from './components/time_tracking/time_tracker.vue';
|
||||
|
||||
export default class SidebarMilestone {
|
||||
constructor() {
|
||||
|
@ -23,13 +23,13 @@ export default class SidebarMilestone {
|
|||
el,
|
||||
name: 'SidebarMilestoneRoot',
|
||||
components: {
|
||||
timeTracker,
|
||||
TimeTracker,
|
||||
},
|
||||
provide: {
|
||||
issuableType: IssuableType.Milestone,
|
||||
},
|
||||
render: (createElement) =>
|
||||
createElement('timeTracker', {
|
||||
createElement('time-tracker', {
|
||||
props: {
|
||||
limitToHours: parseBoolean(limitToHours),
|
||||
issuableIid: iid.toString(),
|
||||
|
|
|
@ -89,6 +89,19 @@ export default {
|
|||
if (e.key !== 'Escape') return;
|
||||
this.$emit('close');
|
||||
this.$refs.dismisser?.dismiss();
|
||||
this.trackDismissal();
|
||||
},
|
||||
close() {
|
||||
this.trackDismissal();
|
||||
this.$emit('close');
|
||||
},
|
||||
trackDismissal() {
|
||||
this.track('survey:mr_experience', {
|
||||
label: 'dismiss',
|
||||
extra: {
|
||||
accountAge: this.accountAge,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -119,7 +132,7 @@ export default {
|
|||
icon="close"
|
||||
@click="
|
||||
dismiss();
|
||||
$emit('close');
|
||||
close();
|
||||
"
|
||||
/>
|
||||
<div
|
||||
|
|
|
@ -24,7 +24,7 @@ const nonStandardEvents = {
|
|||
},
|
||||
issues: {
|
||||
uniqueUser: {
|
||||
expand: ['i_testing_load_performance_widget_total'],
|
||||
expand: ['i_testing_issues_widget_total'],
|
||||
},
|
||||
counter: {},
|
||||
},
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
import { GlLoadingIcon } from '@gitlab/ui';
|
||||
import ciIcon from '~/vue_shared/components/ci_icon.vue';
|
||||
import CiIcon from '~/vue_shared/components/ci_icon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ciIcon,
|
||||
CiIcon,
|
||||
GlLoadingIcon,
|
||||
},
|
||||
props: {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
import statusIcon from '../mr_widget_status_icon.vue';
|
||||
import StatusIcon from '../mr_widget_status_icon.vue';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetArchived',
|
||||
components: {
|
||||
statusIcon,
|
||||
StatusIcon,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
import statusIcon from '../mr_widget_status_icon.vue';
|
||||
import StatusIcon from '../mr_widget_status_icon.vue';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetChecking',
|
||||
components: {
|
||||
statusIcon,
|
||||
StatusIcon,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script>
|
||||
import MrWidgetAuthorTime from '../mr_widget_author_time.vue';
|
||||
import statusIcon from '../mr_widget_status_icon.vue';
|
||||
import StatusIcon from '../mr_widget_status_icon.vue';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetClosed',
|
||||
components: {
|
||||
MrWidgetAuthorTime,
|
||||
statusIcon,
|
||||
StatusIcon,
|
||||
},
|
||||
props: {
|
||||
/* TODO: This is providing all store and service down when it
|
||||
|
|
|
@ -3,14 +3,14 @@ import { GlButton } from '@gitlab/ui';
|
|||
import { stripHtml } from '~/lib/utils/text_utility';
|
||||
import { sprintf, s__, n__ } from '~/locale';
|
||||
import eventHub from '../../event_hub';
|
||||
import statusIcon from '../mr_widget_status_icon.vue';
|
||||
import StatusIcon from '../mr_widget_status_icon.vue';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetFailedToMerge',
|
||||
|
||||
components: {
|
||||
GlButton,
|
||||
statusIcon,
|
||||
StatusIcon,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
|
|
@ -4,7 +4,7 @@ import simplePoll from '~/lib/utils/simple_poll';
|
|||
import MergeRequest from '~/merge_request';
|
||||
import eventHub from '../../event_hub';
|
||||
import { MERGE_ACTIVE_STATUS_PHRASES, STATE_MACHINE } from '../../constants';
|
||||
import statusIcon from '../mr_widget_status_icon.vue';
|
||||
import StatusIcon from '../mr_widget_status_icon.vue';
|
||||
|
||||
const { transitions } = STATE_MACHINE;
|
||||
const { MERGE_FAILURE } = transitions;
|
||||
|
@ -12,7 +12,7 @@ const { MERGE_FAILURE } = transitions;
|
|||
export default {
|
||||
name: 'MRWidgetMerging',
|
||||
components: {
|
||||
statusIcon,
|
||||
StatusIcon,
|
||||
},
|
||||
props: {
|
||||
mr: {
|
||||
|
|
|
@ -9,7 +9,7 @@ import {
|
|||
MR_WIDGET_MISSING_BRANCH_RESTORE,
|
||||
MR_WIDGET_MISSING_BRANCH_MANUALCLI,
|
||||
} from '../../i18n';
|
||||
import statusIcon from '../mr_widget_status_icon.vue';
|
||||
import StatusIcon from '../mr_widget_status_icon.vue';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetMissingBranch',
|
||||
|
@ -19,7 +19,7 @@ export default {
|
|||
components: {
|
||||
GlIcon,
|
||||
GlSprintf,
|
||||
statusIcon,
|
||||
StatusIcon,
|
||||
},
|
||||
mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
|
||||
apollo: {
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
import { GlLink, GlSprintf } from '@gitlab/ui';
|
||||
import { helpPagePath } from '~/helpers/help_page_helper';
|
||||
import { s__ } from '~/locale';
|
||||
import statusIcon from '../mr_widget_status_icon.vue';
|
||||
import StatusIcon from '../mr_widget_status_icon.vue';
|
||||
|
||||
export default {
|
||||
name: 'PipelineFailed',
|
||||
components: {
|
||||
GlLink,
|
||||
GlSprintf,
|
||||
statusIcon,
|
||||
StatusIcon,
|
||||
},
|
||||
computed: {
|
||||
troubleshootingDocsPath() {
|
||||
|
|
|
@ -59,28 +59,28 @@ export default {
|
|||
Loading,
|
||||
ExtensionsContainer,
|
||||
WidgetContainer,
|
||||
'mr-widget-suggest-pipeline': WidgetSuggestPipeline,
|
||||
MrWidgetSuggestPipeline: WidgetSuggestPipeline,
|
||||
MrWidgetPipelineContainer,
|
||||
MrWidgetAlertMessage,
|
||||
'mr-widget-merged': MergedState,
|
||||
'mr-widget-closed': ClosedState,
|
||||
'mr-widget-merging': MergingState,
|
||||
'mr-widget-failed-to-merge': FailedToMerge,
|
||||
'mr-widget-wip': WorkInProgressState,
|
||||
'mr-widget-archived': ArchivedState,
|
||||
'mr-widget-conflicts': ConflictsState,
|
||||
'mr-widget-nothing-to-merge': NothingToMergeState,
|
||||
'mr-widget-not-allowed': NotAllowedState,
|
||||
'mr-widget-missing-branch': MissingBranchState,
|
||||
'mr-widget-ready-to-merge': () => import('./components/states/new_ready_to_merge.vue'),
|
||||
'sha-mismatch': ShaMismatch,
|
||||
'mr-widget-checking': CheckingState,
|
||||
'mr-widget-unresolved-discussions': UnresolvedDiscussionsState,
|
||||
'mr-widget-pipeline-blocked': PipelineBlockedState,
|
||||
'mr-widget-pipeline-failed': PipelineFailedState,
|
||||
MrWidgetMerged: MergedState,
|
||||
MrWidgetClosed: ClosedState,
|
||||
MrWidgetMerging: MergingState,
|
||||
MrWidgetFailedToMerge: FailedToMerge,
|
||||
MrWidgetWip: WorkInProgressState,
|
||||
MrWidgetArchived: ArchivedState,
|
||||
MrWidgetConflicts: ConflictsState,
|
||||
MrWidgetNothingToMerge: NothingToMergeState,
|
||||
MrWidgetNotAllowed: NotAllowedState,
|
||||
MrWidgetMissingBranch: MissingBranchState,
|
||||
MrWidgetReadyToMerge: () => import('./components/states/new_ready_to_merge.vue'),
|
||||
ShaMismatch,
|
||||
MrWidgetChecking: CheckingState,
|
||||
MrWidgetUnresolvedDiscussions: UnresolvedDiscussionsState,
|
||||
MrWidgetPipelineBlocked: PipelineBlockedState,
|
||||
MrWidgetPipelineFailed: PipelineFailedState,
|
||||
MrWidgetAutoMergeEnabled,
|
||||
'mr-widget-auto-merge-failed': AutoMergeFailed,
|
||||
'mr-widget-rebase': RebaseState,
|
||||
MrWidgetAutoMergeFailed: AutoMergeFailed,
|
||||
MrWidgetRebase: RebaseState,
|
||||
SourceBranchRemovalStatus,
|
||||
GroupedCodequalityReportsApp: () =>
|
||||
import('../reports/codequality_report/grouped_codequality_reports_app.vue'),
|
||||
|
|
|
@ -29,7 +29,7 @@ import descriptionVersionHistoryMixin from 'ee_else_ce/notes/mixins/description_
|
|||
import '~/behaviors/markdown/render_gfm';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { __ } from '~/locale';
|
||||
import noteHeader from '~/notes/components/note_header.vue';
|
||||
import NoteHeader from '~/notes/components/note_header.vue';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { spriteIcon } from '~/lib/utils/common_utils';
|
||||
import TimelineEntryItem from './timeline_entry_item.vue';
|
||||
|
@ -43,7 +43,7 @@ export default {
|
|||
name: 'SystemNote',
|
||||
components: {
|
||||
GlIcon,
|
||||
noteHeader,
|
||||
NoteHeader,
|
||||
TimelineEntryItem,
|
||||
GlButton,
|
||||
GlSkeletonLoader,
|
||||
|
|
|
@ -24,7 +24,7 @@ export default function initWorkItemLinks() {
|
|||
name: 'WorkItemLinksRoot',
|
||||
apolloProvider,
|
||||
components: {
|
||||
workItemLinks: WorkItemLinks,
|
||||
WorkItemLinks,
|
||||
},
|
||||
provide: {
|
||||
projectPath,
|
||||
|
|
|
@ -44,8 +44,7 @@ class MergeRequestsFinder < IssuableFinder
|
|||
:reviewer_id,
|
||||
:reviewer_username,
|
||||
:target_branch,
|
||||
:wip,
|
||||
:attention
|
||||
:wip
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -70,7 +69,6 @@ class MergeRequestsFinder < IssuableFinder
|
|||
items = by_approvals(items)
|
||||
items = by_deployments(items)
|
||||
items = by_reviewer(items)
|
||||
items = by_attention(items)
|
||||
|
||||
by_source_project_id(items)
|
||||
end
|
||||
|
@ -220,12 +218,6 @@ class MergeRequestsFinder < IssuableFinder
|
|||
end
|
||||
end
|
||||
|
||||
def by_attention(items)
|
||||
return items unless params.attention?
|
||||
|
||||
items.attention(params.attention)
|
||||
end
|
||||
|
||||
def parse_datetime(input)
|
||||
# To work around http://www.ruby-lang.org/en/news/2021/11/15/date-parsing-method-regexp-dos-cve-2021-41817/
|
||||
DateTime.parse(input.byteslice(0, 128)) if input
|
||||
|
|
|
@ -21,11 +21,5 @@ class MergeRequestsFinder
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def attention
|
||||
strong_memoize(:attention) do
|
||||
User.find_by_username(params[:attention])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,20 +6,12 @@ module MergeRequestReviewerState
|
|||
included do
|
||||
enum state: {
|
||||
unreviewed: 0,
|
||||
reviewed: 1,
|
||||
attention_requested: 2
|
||||
reviewed: 1
|
||||
# 2 was removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95446
|
||||
}
|
||||
|
||||
validates :state,
|
||||
presence: true,
|
||||
inclusion: { in: self.states.keys }
|
||||
|
||||
belongs_to :updated_state_by, class_name: 'User', foreign_key: :updated_state_by_user_id
|
||||
|
||||
def attention_requested_by
|
||||
return unless attention_requested?
|
||||
|
||||
updated_state_by
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -153,7 +153,7 @@ class Group < Namespace
|
|||
|
||||
after_create :post_create_hook
|
||||
after_destroy :post_destroy_hook
|
||||
after_save :update_two_factor_requirement
|
||||
after_commit :update_two_factor_requirement
|
||||
after_update :path_changed_hook, if: :saved_change_to_path?
|
||||
after_create -> { create_or_load_association(:group_feature) }
|
||||
|
||||
|
@ -898,6 +898,10 @@ class Group < Namespace
|
|||
end
|
||||
end
|
||||
|
||||
def update_two_factor_requirement_for_members
|
||||
direct_and_indirect_members.find_each(&:update_two_factor_requirement)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def feature_flag_enabled_for_self_or_ancestor?(feature_flag)
|
||||
|
@ -920,7 +924,7 @@ class Group < Namespace
|
|||
def update_two_factor_requirement
|
||||
return unless saved_change_to_require_two_factor_authentication? || saved_change_to_two_factor_grace_period?
|
||||
|
||||
direct_and_indirect_members.find_each(&:update_two_factor_requirement)
|
||||
Groups::UpdateTwoFactorRequirementForMembersWorker.perform_async(self.id)
|
||||
end
|
||||
|
||||
def path_changed_hook
|
||||
|
|
|
@ -417,17 +417,6 @@ class MergeRequest < ApplicationRecord
|
|||
)
|
||||
end
|
||||
|
||||
scope :attention, ->(user) do
|
||||
# rubocop: disable Gitlab/Union
|
||||
union = Gitlab::SQL::Union.new([
|
||||
MergeRequestReviewer.select(:merge_request_id).where(user_id: user.id, state: MergeRequestReviewer.states[:attention_requested]),
|
||||
MergeRequestAssignee.select(:merge_request_id).where(user_id: user.id, state: MergeRequestAssignee.states[:attention_requested])
|
||||
])
|
||||
# rubocop: enable Gitlab/Union
|
||||
|
||||
with(Gitlab::SQL::CTE.new(:reviewers_and_assignees, union).to_arel).where('merge_requests.id in (select merge_request_id from reviewers_and_assignees)')
|
||||
end
|
||||
|
||||
def self.total_time_to_merge
|
||||
join_metrics
|
||||
.merge(MergeRequest::Metrics.with_valid_time_to_merge)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MergeRequestAssignee < ApplicationRecord
|
||||
include MergeRequestReviewerState
|
||||
|
||||
belongs_to :merge_request, touch: true
|
||||
belongs_to :assignee, class_name: "User", foreign_key: :user_id, inverse_of: :merge_request_assignees
|
||||
|
||||
|
@ -11,6 +9,6 @@ class MergeRequestAssignee < ApplicationRecord
|
|||
scope :in_projects, ->(project_ids) { joins(:merge_request).where(merge_requests: { target_project_id: project_ids }) }
|
||||
|
||||
def cache_key
|
||||
[model_name.cache_key, id, state, assignee.cache_key]
|
||||
[model_name.cache_key, id, assignee.cache_key]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2152,10 +2152,6 @@ class User < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def mr_attention_requests_enabled?
|
||||
Feature.enabled?(:mr_attention_requests, self)
|
||||
end
|
||||
|
||||
def account_age_in_days
|
||||
(Date.current - created_at.to_date).to_i
|
||||
end
|
||||
|
|
|
@ -47,8 +47,7 @@ module Users
|
|||
storage_enforcement_banner_second_enforcement_threshold: 44,
|
||||
storage_enforcement_banner_third_enforcement_threshold: 45,
|
||||
storage_enforcement_banner_fourth_enforcement_threshold: 46,
|
||||
attention_requests_top_nav: 47,
|
||||
attention_requests_side_nav: 48,
|
||||
# 47 and 48 were removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95446
|
||||
# 49 was removed with https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91533
|
||||
# because the banner was no longer relevant.
|
||||
# Records will be migrated with https://gitlab.com/gitlab-org/gitlab/-/issues/367293
|
||||
|
|
|
@ -17,7 +17,7 @@ class MergeRequestUserEntity < ::API::Entities::UserBasic
|
|||
end
|
||||
|
||||
expose :reviewed, if: satisfies(:present?, :allows_reviewers?) do |user, options|
|
||||
find_reviewer_or_assignee(user, options)&.reviewed?
|
||||
options[:merge_request].find_reviewer(user)&.reviewed?
|
||||
end
|
||||
|
||||
expose :approved, if: satisfies(:present?) do |user, options|
|
||||
|
@ -25,16 +25,6 @@ class MergeRequestUserEntity < ::API::Entities::UserBasic
|
|||
# makes one query per merge request, whereas #approved_by? makes one per user
|
||||
options[:merge_request].approvals.any? { |app| app.user_id == user.id }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_reviewer_or_assignee(user, options)
|
||||
if options[:type] == :reviewers
|
||||
options[:merge_request].find_reviewer(user)
|
||||
else
|
||||
options[:merge_request].find_assignee(user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
MergeRequestUserEntity.prepend_mod_with('MergeRequestUserEntity')
|
||||
|
|
|
@ -43,8 +43,6 @@ module MergeRequests
|
|||
end
|
||||
|
||||
def handle_assignees_change(merge_request, old_assignees)
|
||||
bulk_update_assignees_state(merge_request, merge_request.assignees - old_assignees)
|
||||
|
||||
MergeRequests::HandleAssigneesChangeService
|
||||
.new(project: project, current_user: current_user)
|
||||
.async_execute(merge_request, old_assignees)
|
||||
|
@ -60,7 +58,6 @@ module MergeRequests
|
|||
new_reviewers = merge_request.reviewers - old_reviewers
|
||||
merge_request_activity_counter.track_users_review_requested(users: new_reviewers)
|
||||
merge_request_activity_counter.track_reviewers_changed_action(user: current_user)
|
||||
bulk_update_reviewers_state(merge_request, new_reviewers)
|
||||
end
|
||||
|
||||
def cleanup_environments(merge_request)
|
||||
|
@ -247,46 +244,6 @@ module MergeRequests
|
|||
|
||||
Milestones::MergeRequestsCountService.new(milestone).delete_cache
|
||||
end
|
||||
|
||||
def bulk_update_assignees_state(merge_request, new_assignees)
|
||||
return unless current_user.mr_attention_requests_enabled?
|
||||
return if new_assignees.empty?
|
||||
|
||||
assignees_map = merge_request.merge_request_assignees_with(new_assignees).to_h do |assignee|
|
||||
state = if assignee.user_id == current_user&.id
|
||||
:unreviewed
|
||||
else
|
||||
merge_request.find_reviewer(assignee.assignee)&.state || :attention_requested
|
||||
end
|
||||
|
||||
[
|
||||
assignee,
|
||||
{ state: MergeRequestAssignee.states[state], updated_state_by_user_id: current_user.id }
|
||||
]
|
||||
end
|
||||
|
||||
::Gitlab::Database::BulkUpdate.execute(%i[state updated_state_by_user_id], assignees_map)
|
||||
end
|
||||
|
||||
def bulk_update_reviewers_state(merge_request, new_reviewers)
|
||||
return unless current_user.mr_attention_requests_enabled?
|
||||
return if new_reviewers.empty?
|
||||
|
||||
reviewers_map = merge_request.merge_request_reviewers_with(new_reviewers).to_h do |reviewer|
|
||||
state = if reviewer.user_id == current_user&.id
|
||||
:unreviewed
|
||||
else
|
||||
merge_request.find_assignee(reviewer.reviewer)&.state || :attention_requested
|
||||
end
|
||||
|
||||
[
|
||||
reviewer,
|
||||
{ state: MergeRequestReviewer.states[state], updated_state_by_user_id: current_user.id }
|
||||
]
|
||||
end
|
||||
|
||||
::Gitlab::Database::BulkUpdate.execute(%i[state updated_state_by_user_id], reviewers_map)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@ module MergeRequests
|
|||
attrs = update_attrs.merge(assignee_ids: new_ids)
|
||||
merge_request.update!(**attrs)
|
||||
|
||||
bulk_update_assignees_state(merge_request, merge_request.assignees - old_assignees)
|
||||
|
||||
# Defer the more expensive operations (handle_assignee_changes) to the background
|
||||
MergeRequests::HandleAssigneesChangeService
|
||||
.new(project: project, current_user: current_user)
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
= content_for :after_content do
|
||||
#js-crm-form-portal
|
||||
|
||||
#js-crm-organizations-app{ data: { base_path: group_crm_organizations_path(@group), can_admin_crm_organization: can?(current_user, :admin_crm_organization, @group).to_s, group_full_path: @group.full_path, group_id: @group.id, group_issues_path: issues_group_path(@group) } }
|
||||
#js-crm-organizations-app{ data: { base_path: group_crm_organizations_path(@group), can_admin_crm_organization: can?(current_user, :admin_crm_organization, @group).to_s, group_full_path: @group.full_path, group_id: @group.id, group_issues_path: issues_group_path(@group), text_query: params[:search] } }
|
||||
|
|
|
@ -2415,6 +2415,15 @@
|
|||
:weight: 1
|
||||
:idempotent: true
|
||||
:tags: []
|
||||
- :name: groups_update_two_factor_requirement_for_members
|
||||
:worker_name: Groups::UpdateTwoFactorRequirementForMembersWorker
|
||||
:feature_category: :authentication_and_authorization
|
||||
:has_external_dependencies: false
|
||||
:urgency: :low
|
||||
:resource_boundary: :unknown
|
||||
:weight: 1
|
||||
:idempotent: true
|
||||
:tags: []
|
||||
- :name: import_issues_csv
|
||||
:worker_name: ImportIssuesCsvWorker
|
||||
:feature_category: :team_planning
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -221,6 +221,8 @@
|
|||
- 1
|
||||
- - groups_update_statistics
|
||||
- 1
|
||||
- - groups_update_two_factor_requirement_for_members
|
||||
- 1
|
||||
- - hashed_storage
|
||||
- 1
|
||||
- - import_issues_csv
|
||||
|
|
|
@ -20190,7 +20190,6 @@ State of a review of a GitLab merge request.
|
|||
|
||||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| <a id="mergerequestreviewstateattention_requested"></a>`ATTENTION_REQUESTED` | The merge request is attention_requested. |
|
||||
| <a id="mergerequestreviewstatereviewed"></a>`REVIEWED` | The merge request is reviewed. |
|
||||
| <a id="mergerequestreviewstateunreviewed"></a>`UNREVIEWED` | The merge request is unreviewed. |
|
||||
|
||||
|
@ -20864,8 +20863,6 @@ Name of the feature that the callout is for.
|
|||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| <a id="usercalloutfeaturenameenumactive_user_count_threshold"></a>`ACTIVE_USER_COUNT_THRESHOLD` | Callout feature name for active_user_count_threshold. |
|
||||
| <a id="usercalloutfeaturenameenumattention_requests_side_nav"></a>`ATTENTION_REQUESTS_SIDE_NAV` | Callout feature name for attention_requests_side_nav. |
|
||||
| <a id="usercalloutfeaturenameenumattention_requests_top_nav"></a>`ATTENTION_REQUESTS_TOP_NAV` | Callout feature name for attention_requests_top_nav. |
|
||||
| <a id="usercalloutfeaturenameenumbuy_pipeline_minutes_notification_dot"></a>`BUY_PIPELINE_MINUTES_NOTIFICATION_DOT` | Callout feature name for buy_pipeline_minutes_notification_dot. |
|
||||
| <a id="usercalloutfeaturenameenumcanary_deployment"></a>`CANARY_DEPLOYMENT` | Callout feature name for canary_deployment. |
|
||||
| <a id="usercalloutfeaturenameenumci_deprecation_warning_for_types_keyword"></a>`CI_DEPRECATION_WARNING_FOR_TYPES_KEYWORD` | Callout feature name for ci_deprecation_warning_for_types_keyword. |
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue