Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
77b22b2119
commit
db299d28dc
|
|
@ -146,6 +146,12 @@ rules:
|
|||
methods: 'sanitize'
|
||||
# This rule will be enabled later.
|
||||
unicorn/no-array-callback-reference: off
|
||||
vue/no-undef-components:
|
||||
- error
|
||||
- ignorePatterns:
|
||||
- '^router-link$'
|
||||
- '^router-view$'
|
||||
- '^gl-emoji$'
|
||||
overrides:
|
||||
- files:
|
||||
- '{,ee/,jh/}spec/frontend*/**/*'
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {
|
|||
flashAnimationDuration,
|
||||
listsQuery,
|
||||
updateListQueries,
|
||||
ListType,
|
||||
} from 'ee_else_ce/boards/constants';
|
||||
import { calculateNewPosition } from 'ee_else_ce/boards/boards_util';
|
||||
import { setError } from '../graphql/cache_updates';
|
||||
|
|
@ -99,6 +100,14 @@ export default {
|
|||
|
||||
return this.canDragColumns ? options : {};
|
||||
},
|
||||
backlogListId() {
|
||||
const backlogList = this.boardListsToUse.find((list) => list.listType === ListType.backlog);
|
||||
return backlogList?.id || '';
|
||||
},
|
||||
closedListId() {
|
||||
const closedList = this.boardListsToUse.find((list) => list.listType === ListType.closed);
|
||||
return closedList?.id || '';
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
afterFormEnters() {
|
||||
|
|
@ -275,8 +284,18 @@ export default {
|
|||
</div>
|
||||
</epics-swimlanes>
|
||||
|
||||
<board-content-sidebar v-if="isIssueBoard" data-testid="issue-boards-sidebar" />
|
||||
<board-content-sidebar
|
||||
v-if="isIssueBoard"
|
||||
:backlog-list-id="backlogListId"
|
||||
:closed-list-id="closedListId"
|
||||
data-testid="issue-boards-sidebar"
|
||||
/>
|
||||
|
||||
<epic-board-content-sidebar v-else-if="isEpicBoard" data-testid="epic-boards-sidebar" />
|
||||
<epic-board-content-sidebar
|
||||
v-else-if="isEpicBoard"
|
||||
:backlog-list-id="backlogListId"
|
||||
:closed-list-id="closedListId"
|
||||
data-testid="epic-boards-sidebar"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
<script>
|
||||
import { GlDrawer } from '@gitlab/ui';
|
||||
import { MountingPortal } from 'portal-vue';
|
||||
import { union } from 'lodash';
|
||||
import SidebarDropdownWidget from 'ee_else_ce/sidebar/components/sidebar_dropdown_widget.vue';
|
||||
import activeBoardItemQuery from 'ee_else_ce/boards/graphql/client/active_board_item.query.graphql';
|
||||
import setActiveBoardItemMutation from 'ee_else_ce/boards/graphql/client/set_active_board_item.mutation.graphql';
|
||||
import { __, s__, sprintf } from '~/locale';
|
||||
import SidebarTimeTracker from '~/sidebar/components/time_tracking/time_tracker.vue';
|
||||
import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue';
|
||||
import { INCIDENT } from '~/boards/constants';
|
||||
import { INCIDENT, ListType } from '~/boards/constants';
|
||||
import { TYPE_ISSUE, WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
|
||||
import SidebarAssigneesWidget from '~/sidebar/components/assignees/sidebar_assignees_widget.vue';
|
||||
import SidebarConfidentialityWidget from '~/sidebar/components/confidential/sidebar_confidentiality_widget.vue';
|
||||
|
|
@ -17,9 +18,10 @@ import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sideb
|
|||
import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue';
|
||||
import SidebarLabelsWidget from '~/sidebar/components/labels/labels_select_widget/labels_select_root.vue';
|
||||
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { setError, updateListWeightCache } from '../graphql/cache_updates';
|
||||
import { setError, updateListWeightCache, identifyAffectedLists } from '../graphql/cache_updates';
|
||||
|
||||
export default {
|
||||
ListType,
|
||||
components: {
|
||||
GlDrawer,
|
||||
BoardSidebarTitle,
|
||||
|
|
@ -77,6 +79,22 @@ export default {
|
|||
},
|
||||
},
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
backlogListId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
closedListId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
affectedListTypes: [],
|
||||
updatedAttributeIds: [],
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
activeBoardCard: {
|
||||
query: activeBoardItemQuery,
|
||||
|
|
@ -156,21 +174,87 @@ export default {
|
|||
this.iterationFeatureAvailable && !this.isIncidentSidebar && this.activeBoardIssuable.id
|
||||
);
|
||||
},
|
||||
apolloClient() {
|
||||
return this.$apollo.provider.clients.defaultClient;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleClose() {
|
||||
this.$apollo.mutate({
|
||||
async handleClose() {
|
||||
const item = this.activeBoardCard;
|
||||
|
||||
await this.$apollo.mutate({
|
||||
mutation: setActiveBoardItemMutation,
|
||||
variables: {
|
||||
boardItem: null,
|
||||
listId: null,
|
||||
},
|
||||
});
|
||||
|
||||
if (item.listId !== this.closedListId) {
|
||||
await this.refetchAffectedLists(item);
|
||||
}
|
||||
this.affectedListTypes = [];
|
||||
this.updatedAttributeIds = [];
|
||||
},
|
||||
updateListTotalWeight({ weight }) {
|
||||
const { cache } = this.$apollo.provider.clients.defaultClient;
|
||||
const { cache } = this.apolloClient;
|
||||
updateListWeightCache({ weight, listId: this.activeBoardCard.listId, cache });
|
||||
},
|
||||
updateAffectedLists({ listType, attribute }) {
|
||||
if (!this.affectedListTypes.includes(listType)) {
|
||||
this.affectedListTypes.push(listType);
|
||||
}
|
||||
|
||||
if (Array.isArray(attribute)) {
|
||||
this.updatedAttributeIds = union(
|
||||
this.updatedAttributeIds,
|
||||
attribute.map(({ id }) => id),
|
||||
);
|
||||
} else {
|
||||
const attr = attribute.issuableSetAttribute.issuable.attribute;
|
||||
if (attr) {
|
||||
this.updatedAttributeIds.push(attr.id);
|
||||
}
|
||||
}
|
||||
},
|
||||
refetchAffectedLists(item) {
|
||||
if (!this.affectedListTypes.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const affectedLists = identifyAffectedLists({
|
||||
client: this.apolloClient,
|
||||
item,
|
||||
issuableType: this.issuableType,
|
||||
affectedListTypes: this.affectedListTypes,
|
||||
updatedAttributeIds: this.updatedAttributeIds,
|
||||
});
|
||||
|
||||
if (this.backlogListId && !affectedLists.includes(this.backlogListId)) {
|
||||
affectedLists.push(this.backlogListId);
|
||||
}
|
||||
|
||||
this.apolloClient.refetchQueries({
|
||||
updateCache(cache) {
|
||||
affectedLists.forEach((listId) => {
|
||||
cache.evict({
|
||||
id: cache.identify({
|
||||
__typename: 'BoardList',
|
||||
id: listId,
|
||||
}),
|
||||
fieldName: 'issues',
|
||||
});
|
||||
cache.evict({
|
||||
id: cache.identify({
|
||||
__typename: 'BoardList',
|
||||
id: listId,
|
||||
}),
|
||||
fieldName: 'issuesCount',
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -205,6 +289,12 @@ export default {
|
|||
:initial-assignees="activeBoardIssuable.assignees"
|
||||
:allow-multiple-assignees="multipleAssigneesFeatureAvailable"
|
||||
:editable="canUpdate"
|
||||
@assignees-updated="
|
||||
updateAffectedLists({
|
||||
listType: $options.ListType.assignee,
|
||||
attribute: $event.assignees,
|
||||
})
|
||||
"
|
||||
/>
|
||||
<sidebar-dropdown-widget
|
||||
v-if="showEpicSidebarDropdownWidget"
|
||||
|
|
@ -229,6 +319,9 @@ export default {
|
|||
:issuable-type="issuableType"
|
||||
:issue-id="activeBoardIssuable.id"
|
||||
data-testid="sidebar-milestones"
|
||||
@attribute-updated="
|
||||
updateAffectedLists({ listType: $options.ListType.milestone, attribute: $event })
|
||||
"
|
||||
/>
|
||||
<sidebar-iteration-widget
|
||||
v-if="showIterationSidebarDropdownWidget"
|
||||
|
|
@ -240,6 +333,9 @@ export default {
|
|||
:issuable-type="issuableType"
|
||||
class="gl-mt-5"
|
||||
data-testid="iteration-edit"
|
||||
@iteration-updated="
|
||||
updateAffectedLists({ listType: $options.ListType.iteration, attribute: $event })
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<sidebar-time-tracker
|
||||
|
|
@ -271,6 +367,9 @@ export default {
|
|||
workspace-type="project"
|
||||
:issuable-type="issuableType"
|
||||
:label-create-type="labelType"
|
||||
@updateSelectedLabels="
|
||||
updateAffectedLists({ listType: $options.ListType.label, attribute: $event.labels })
|
||||
"
|
||||
>
|
||||
{{ __('None') }}
|
||||
</sidebar-labels-widget>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import produce from 'immer';
|
||||
import { toNumber } from 'lodash';
|
||||
import { toNumber, uniq } from 'lodash';
|
||||
import * as Sentry from '~/sentry/sentry_browser_wrapper';
|
||||
import { defaultClient } from '~/graphql_shared/issuable_client';
|
||||
import listQuery from 'ee_else_ce/boards/graphql/board_lists_deferred.query.graphql';
|
||||
import { listsDeferredQuery } from 'ee_else_ce/boards/constants';
|
||||
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
|
||||
import { TYPE_ISSUE } from '~/issues/constants';
|
||||
|
||||
import setErrorMutation from './client/set_error.mutation.graphql';
|
||||
|
||||
|
|
@ -166,3 +168,48 @@ export function setError({ message, error, captureError = true }) {
|
|||
Sentry.captureException(error);
|
||||
}
|
||||
}
|
||||
|
||||
export function identifyAffectedLists({
|
||||
client,
|
||||
item,
|
||||
issuableType,
|
||||
affectedListTypes,
|
||||
updatedAttributeIds,
|
||||
}) {
|
||||
const allCache = client.cache.extract();
|
||||
const listIdsToRefetch = [];
|
||||
const type = capitalizeFirstCharacter(issuableType);
|
||||
const typename = issuableType === TYPE_ISSUE ? 'BoardList' : 'EpicList';
|
||||
|
||||
Object.values(allCache).forEach((value) => {
|
||||
const issuablesField = Object.keys(value).find((key) => key.includes(`${issuableType}s:`));
|
||||
const issuables = value[issuablesField]?.nodes ?? [];
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
if (value.__typename === typename) {
|
||||
// We identify the id of the attribute that was updated. In Apollo Cache, entries are stored in the following format:
|
||||
// UserCore:gid://gitlab/UserCore/1 (<type>:<global id>). We extract the id from the __ref field.
|
||||
const attributeId =
|
||||
value.assignee?.__ref.match(/UserCore:(.*)/)[1] ||
|
||||
value.label?.__ref.match(/Label:(.*)/)[1] ||
|
||||
value.milestone?.__ref.match(/Milestone:(.*)/)[1] ||
|
||||
value.iteration?.__ref.match(/Iteration:(.*)/)[1];
|
||||
|
||||
// If the item is in the list, and lists of this type are affected, we need to refetch the list
|
||||
if (issuables.length > 0) {
|
||||
const issueExistsInList = issuables.some((i) => i.__ref === `${type}:${item.id}`);
|
||||
if (issueExistsInList && affectedListTypes.includes(value.listType)) {
|
||||
listIdsToRefetch.push(value.id);
|
||||
}
|
||||
}
|
||||
// If the item is not in the list, but the list has the attribute from affected attributes list
|
||||
// we need to refetch the list
|
||||
if (updatedAttributeIds.includes(attributeId)) {
|
||||
listIdsToRefetch.push(value.id);
|
||||
}
|
||||
}
|
||||
/* eslint-enable no-underscore-dangle */
|
||||
});
|
||||
|
||||
return uniq(listIdsToRefetch);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ export default {
|
|||
<template>
|
||||
<li :class="{ 'js-toggle-container': collapsible }" class="commit">
|
||||
<div
|
||||
class="d-block d-sm-flex flex-row-reverse justify-content-between align-items-start flex-lg-row-reverse"
|
||||
class="gl-block sm:gl-flex flex-row-reverse justify-content-between align-items-start flex-lg-row-reverse"
|
||||
>
|
||||
<div
|
||||
class="commit-actions flex-row gl-hidden sm:gl-flex gl-align-items-center gl-flex-wrap justify-content-end"
|
||||
|
|
@ -142,7 +142,9 @@ export default {
|
|||
class="commit-row-message item-title"
|
||||
></a>
|
||||
|
||||
<span class="commit-row-message d-block d-sm-none">· {{ commit.short_id }}</span>
|
||||
<span class="commit-row-message !gl-block sm:!gl-hidden"
|
||||
>· {{ commit.short_id }}</span
|
||||
>
|
||||
|
||||
<gl-button
|
||||
v-if="commit.description_html && collapsible"
|
||||
|
|
@ -172,7 +174,7 @@ export default {
|
|||
<pre
|
||||
v-if="commit.description_html"
|
||||
v-safe-html:[$options.safeHtmlConfig]="commitDescription"
|
||||
:class="{ 'js-toggle-content': collapsible, 'd-block': !collapsible }"
|
||||
:class="{ 'js-toggle-content': collapsible, '!gl-block': !collapsible }"
|
||||
class="commit-row-description gl-mb-3 gl-text-body gl-white-space-pre-wrap"
|
||||
></pre>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ export default {
|
|||
</gl-tab>
|
||||
</gl-tabs>
|
||||
|
||||
<!-- eslint-disable-next-line vue/no-undef-components -->
|
||||
<container
|
||||
:is-loading="isLoading"
|
||||
:environments="state.environments"
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ export default {
|
|||
/>
|
||||
<div
|
||||
v-if="showSuggestions"
|
||||
class="dropdown-menu d-block dropdown-menu-selectable dropdown-menu-full-width"
|
||||
class="dropdown-menu !gl-block dropdown-menu-selectable dropdown-menu-full-width"
|
||||
>
|
||||
<div class="dropdown-content">
|
||||
<ul v-if="results.length">
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<ul class="groups-list group-list-tree gl-display-flex gl-flex-direction-column gl-m-0">
|
||||
<!-- eslint-disable-next-line vue/no-undef-components -->
|
||||
<group-item
|
||||
v-for="(group, index) in groups"
|
||||
:key="index"
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- eslint-disable-next-line vue/no-undef-components -->
|
||||
<group-folder
|
||||
v-if="group.isOpen && hasChildren"
|
||||
:parent-group="group"
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div class="groups-list-tree-container" data-testid="groups-list-tree-container">
|
||||
<!-- eslint-disable-next-line vue/no-undef-components -->
|
||||
<group-folder :groups="groups" :action="action" />
|
||||
<pagination-links
|
||||
:change="change"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export default {
|
|||
</span>
|
||||
<span>
|
||||
<strong> {{ item.name }} </strong>
|
||||
<span class="ide-merge-request-project-path d-block mt-1">
|
||||
<span class="ide-merge-request-project-path gl-block mt-1">
|
||||
Updated <timeago :time="item.committedDate || ''" />
|
||||
</span>
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ export default {
|
|||
</span>
|
||||
<span>
|
||||
<strong> {{ item.title }} </strong>
|
||||
<span class="ide-merge-request-project-path d-block mt-1"> {{ pathWithID }} </span>
|
||||
<span class="ide-merge-request-project-path gl-block mt-1"> {{ pathWithID }} </span>
|
||||
</span>
|
||||
</a>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ export default {
|
|||
data-testid="assignee-link"
|
||||
>
|
||||
<span class="js-assignee-tooltip">
|
||||
<span class="bold d-block">{{ s__('Label|Assignee') }}</span> {{ assignee.name }}
|
||||
<span class="bold gl-block">{{ s__('Label|Assignee') }}</span> {{ assignee.name }}
|
||||
<span v-if="assignee.username" class="text-white-50">@{{ assignee.username }}</span>
|
||||
</span>
|
||||
</user-avatar-link>
|
||||
|
|
|
|||
|
|
@ -765,7 +765,7 @@ export default {
|
|||
"
|
||||
>
|
||||
<template #link="{ content }">
|
||||
<span class="d-block">
|
||||
<span class="gl-display-block">
|
||||
<gl-link :href="lfsObjectsRemovalHelpPath" target="_blank">
|
||||
{{ content }}
|
||||
</gl-link>
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ const bindEvents = () => {
|
|||
const selectedTemplate = DEFAULT_PROJECT_TEMPLATES[value];
|
||||
$selectedTemplateText.textContent = selectedTemplate.text;
|
||||
const clone = document.querySelector(selectedTemplate.icon).cloneNode(true);
|
||||
clone.classList.add('d-block');
|
||||
clone.classList.add('gl-block');
|
||||
|
||||
$selectedIcon.append(clone);
|
||||
|
||||
|
|
|
|||
|
|
@ -451,12 +451,14 @@ export default {
|
|||
</template>
|
||||
</gl-sprintf>
|
||||
|
||||
<!-- eslint-disable-next-line vue/no-undef-components -->
|
||||
<approval-rules-app
|
||||
:is-mr-edit="false"
|
||||
:is-branch-rules-edit="true"
|
||||
@submitted="$apollo.queries.project.refetch()"
|
||||
>
|
||||
<template #rules>
|
||||
<!-- eslint-disable-next-line vue/no-undef-components -->
|
||||
<project-rules :is-branch-rules-edit="true" />
|
||||
</template>
|
||||
</approval-rules-app>
|
||||
|
|
|
|||
|
|
@ -101,6 +101,9 @@ export default {
|
|||
update(data) {
|
||||
return data.workspace?.issuable;
|
||||
},
|
||||
skip() {
|
||||
return !this.iid;
|
||||
},
|
||||
result({ data }) {
|
||||
if (!data) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ export default {
|
|||
update(data) {
|
||||
return data.workspace?.issuable?.confidential || false;
|
||||
},
|
||||
skip() {
|
||||
return !this.iid;
|
||||
},
|
||||
result({ data }) {
|
||||
if (!data) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,9 @@ export default {
|
|||
iid: String(this.iid),
|
||||
};
|
||||
},
|
||||
skip() {
|
||||
return !this.iid;
|
||||
},
|
||||
update(data) {
|
||||
return data.workspace?.issuable || {};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ export default {
|
|||
return issuableLabelsQueries[this.issuableType].issuableQuery;
|
||||
},
|
||||
skip() {
|
||||
return !isDropdownVariantSidebar(this.variant);
|
||||
return !isDropdownVariantSidebar(this.variant) || !this.iid;
|
||||
},
|
||||
variables() {
|
||||
const queryVariables = {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ export default {
|
|||
update(data) {
|
||||
return data.workspace?.issuable?.participants.nodes || [];
|
||||
},
|
||||
skip() {
|
||||
return !this.iid;
|
||||
},
|
||||
error(error) {
|
||||
this.$emit('fetch-error', {
|
||||
message: this.$options.i18n.fetchingError,
|
||||
|
|
|
|||
|
|
@ -118,6 +118,9 @@ export default {
|
|||
this.hasCurrentAttribute = data?.workspace?.issuable.hasEpic;
|
||||
}
|
||||
},
|
||||
skip() {
|
||||
return !this.iid;
|
||||
},
|
||||
error(error) {
|
||||
createAlert({
|
||||
message: this.i18n.currentFetchError,
|
||||
|
|
|
|||
|
|
@ -75,6 +75,9 @@ export default {
|
|||
iid: String(this.iid),
|
||||
};
|
||||
},
|
||||
skip() {
|
||||
return !this.iid;
|
||||
},
|
||||
update(data) {
|
||||
return data.workspace?.issuable?.subscribed || false;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ export default {
|
|||
iid: String(this.issuableIid),
|
||||
};
|
||||
},
|
||||
skip() {
|
||||
return !this.issuableIid;
|
||||
},
|
||||
update(data) {
|
||||
return data.workspace?.issuable?.currentUserTodos.nodes[0]?.id;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ export default {
|
|||
return `${getCommitIconMap(this.file).icon}${suffix}`;
|
||||
},
|
||||
changedIconClass() {
|
||||
return `${this.changedIcon} float-left d-block`;
|
||||
return `${this.changedIcon} float-left gl-block`;
|
||||
},
|
||||
tooltipTitle() {
|
||||
if (!this.showTooltip) {
|
||||
|
|
|
|||
|
|
@ -33,5 +33,5 @@ export default {
|
|||
class="code-block rounded code"
|
||||
:class="$options.userColorScheme"
|
||||
:style="styleObject"
|
||||
><slot><code class="d-block">{{ code }}</code></slot></pre>
|
||||
><slot><code class="gl-block">{{ code }}</code></slot></pre>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ export default {
|
|||
issuableColor: {
|
||||
query: epicColorQuery,
|
||||
skip() {
|
||||
return !isDropdownVariantSidebar(this.variant);
|
||||
return !isDropdownVariantSidebar(this.variant) || !this.iid;
|
||||
},
|
||||
variables() {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ $command-palette-spacing: px-to-rem(14px);
|
|||
--super-sidebar-nav-item-current-bg: #{$t-gray-a-08};
|
||||
--super-sidebar-nav-item-icon-color: #{$gray-500};
|
||||
|
||||
--super-sidebar-hr-mix-blend-mode: normal;
|
||||
--super-sidebar-hr-mix-blend-mode: multiply;
|
||||
|
||||
.gl-dark & {
|
||||
--super-sidebar-border-color: #{$t-white-a-08};
|
||||
|
|
@ -61,6 +61,8 @@ $command-palette-spacing: px-to-rem(14px);
|
|||
--super-sidebar-nav-item-active-bg: #{$t-white-a-16};
|
||||
--super-sidebar-nav-item-current-bg: #{$t-white-a-08};
|
||||
--super-sidebar-nav-item-icon-color: #{$gray-600};
|
||||
|
||||
--super-sidebar-hr-mix-blend-mode: screen;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,8 +92,6 @@ $command-palette-spacing: px-to-rem(14px);
|
|||
--super-sidebar-user-bar-button-icon-color: #{$user-bar-button-icon-color};
|
||||
--super-sidebar-user-bar-button-icon-hover-color: #{$user-bar-button-icon-color};
|
||||
--super-sidebar-user-bar-button-icon-mix-blend-mode: screen;
|
||||
|
||||
--super-sidebar-hr-mix-blend-mode: multiply;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -240,6 +240,7 @@ module WikiActions
|
|||
# rubocop:disable Gitlab/ModuleWithInstanceVariables
|
||||
def history
|
||||
if page
|
||||
@commits_count = page.count_versions
|
||||
@commits = Kaminari.paginate_array(page.versions(page: params[:page].to_i), total_count: page.count_versions)
|
||||
.page(params[:page])
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
.form-group.gl-mt-3.gl-mb-6
|
||||
= render Pajamas::AvatarComponent.new(@group, size: 96, alt: '', class: 'gl-float-left gl-mr-5')
|
||||
= f.label :avatar, s_('Groups|Group avatar'), class: 'label-bold d-block'
|
||||
= f.label :avatar, s_('Groups|Group avatar'), class: 'label-bold gl-block'
|
||||
= render 'shared/choose_avatar_button', f: f
|
||||
- if @group.avatar?
|
||||
%hr
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
= render_if_exists 'projects/commits/project_namespace', show_project_name: show_project_name, project: project
|
||||
|
||||
- if commit.description?
|
||||
%pre{ class: ["commit-row-description gl-mb-3 gl-white-space-pre-wrap", (collapsible ? "js-toggle-content" : "d-block")] }
|
||||
%pre{ class: ["commit-row-description gl-mb-3 gl-white-space-pre-wrap", (collapsible ? "js-toggle-content" : "!gl-block")] }
|
||||
= preserve(markdown_field(commit, :description))
|
||||
|
||||
.commit-actions.flex-row
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#js-project-show-empty-page.project-page-layout
|
||||
.project-page-layout-content.gl-mt-5
|
||||
.project-buttons.gl-mb-5{ data: { testid: 'quick-actions-container' } }
|
||||
.project-clone-holder.d-block.d-sm-none
|
||||
.project-clone-holder.gl-block.sm:gl-hidden
|
||||
= render "shared/mobile_clone_panel"
|
||||
|
||||
.project-clone-holder.gl-hidden.sm:gl-flex.gl-justify-content-end.gl-w-full
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
.form-group.gl-mt-3.gl-mb-3
|
||||
= render Pajamas::AvatarComponent.new(@project, size: 96, alt: '', class: 'gl-float-left gl-mr-5')
|
||||
= f.label :avatar, _('Project avatar'), class: 'label-bold d-block'
|
||||
= f.label :avatar, _('Project avatar'), class: 'label-bold gl-block'
|
||||
= render 'shared/choose_avatar_button', f: f
|
||||
- if @project.avatar?
|
||||
%hr
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
- wiki_page_title @page, _('History')
|
||||
- add_page_specific_style 'page_bundles/wiki'
|
||||
|
||||
.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
|
||||
.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row.gl-border-b-0
|
||||
= wiki_sidebar_toggle_button
|
||||
|
||||
%h1.page-title.gl-font-size-h-display
|
||||
|
|
@ -12,28 +12,38 @@
|
|||
= _('History')
|
||||
|
||||
.prepend-top-default.gl-mb-3
|
||||
.table-holder{ data: { testid: 'wiki-history-table' } }
|
||||
%table.table.wiki-history
|
||||
%thead
|
||||
%tr
|
||||
%th= @page.template? ? s_('Wiki|Template version') : s_('Wiki|Page version')
|
||||
%th= _('Author')
|
||||
%th= _('Changes')
|
||||
%th= _('Last updated')
|
||||
%tbody
|
||||
- @commits.each do |commit|
|
||||
%tr
|
||||
%td
|
||||
= link_to wiki_page_path(@wiki, @page, version_id: commit.id) do
|
||||
= truncate_sha(commit.id)
|
||||
%td
|
||||
= commit.author_name
|
||||
%td
|
||||
.commit-content
|
||||
= link_to wiki_page_path(@wiki, @page, action: :diff, version_id: commit.id), { title: commit.message } do
|
||||
= commit.message
|
||||
%td
|
||||
= time_ago_with_tooltip(commit.authored_date)
|
||||
= render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card gl-mt-0 gl-mb-5' }, header_options: { class: 'gl-new-card-header gl-border-b-0' }, body_options: { class: 'gl-new-card-body gl-px-0' }) do |c|
|
||||
- c.with_header do
|
||||
.gl-new-card-title-wrapper.gl-flex-col
|
||||
%h3.gl-new-card-title
|
||||
= _('Versions')
|
||||
.gl-new-card-count
|
||||
= sprite_icon('history', css_class: 'gl-mr-2')
|
||||
= @commits_count
|
||||
- c.with_body do
|
||||
.table-holder{ data: { testid: 'wiki-history-table' } }
|
||||
%table.table.wiki-history{ class: '!gl-mb-0' }
|
||||
%thead
|
||||
%tr
|
||||
%th= _('Version')
|
||||
%th= _('Author')
|
||||
%th= _('Diff')
|
||||
%th= _('Last updated')
|
||||
%tbody
|
||||
- @commits.each_with_index do |commit, i|
|
||||
%tr
|
||||
%td
|
||||
= link_to wiki_page_path(@wiki, @page, version_id: commit.id) do
|
||||
v#{@commits_count - i}
|
||||
%td
|
||||
= commit.author_name
|
||||
%td
|
||||
.commit-content
|
||||
= link_to wiki_page_path(@wiki, @page, action: :diff, version_id: commit.id), { title: commit.message } do
|
||||
= commit.message
|
||||
%td
|
||||
= time_ago_with_tooltip(commit.authored_date)
|
||||
|
||||
= paginate @commits, theme: 'gitlab'
|
||||
|
||||
= render 'shared/wikis/sidebar'
|
||||
|
|
|
|||
|
|
@ -436,6 +436,17 @@ To determine if there are any differences:
|
|||
Select the branch that matches your GitLab version. For example, the file for GitLab 16.2: <https://gitlab.com/gitlab-org/gitlab/-/blob/16-2-stable-ee/db/structure.sql>.
|
||||
1. Compare `/tmp/structure.sql` with the `db/structure.sql` file for your version.
|
||||
|
||||
## Check the database for schema inconsistencies
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/390719) in GitLab 15.11.
|
||||
|
||||
This Rake task checks the database schema for any inconsistencies
|
||||
and prints them in the terminal.
|
||||
|
||||
```shell
|
||||
gitlab-rake gitlab:db:schema_checker:run
|
||||
```
|
||||
|
||||
## Import common metrics
|
||||
|
||||
Sometimes you may need to re-import the common metrics that power the Metrics dashboards.
|
||||
|
|
|
|||
|
|
@ -60,14 +60,14 @@ Example response:
|
|||
"project_id": 7,
|
||||
"package_name_pattern": "@flightjs/flight-package-0",
|
||||
"package_type": "npm",
|
||||
"push_protected_up_to_access_level": "maintainer"
|
||||
"minimum_access_level_for_push": "maintainer"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"project_id": 7,
|
||||
"package_name_pattern": "@flightjs/flight-package-1",
|
||||
"package_type": "npm",
|
||||
"push_protected_up_to_access_level": "maintainer"
|
||||
"minimum_access_level_for_push": "maintainer"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
stage: Create
|
||||
group: Editor Extensions
|
||||
description: Visual Studio Code, JetBrains, Neovim, GitLab CLI.
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
description: "Extend the features of GitLab to Visual Studio Code, JetBrains IDEs, Visual Studio, and Neovim."
|
||||
---
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module API
|
|||
expose :project_id, documentation: { type: 'integer', example: 1 }
|
||||
expose :package_name_pattern, documentation: { type: 'string', example: 'flightjs/flight' }
|
||||
expose :package_type, documentation: { type: 'string', example: 'npm' }
|
||||
expose :push_protected_up_to_access_level, documentation: { type: 'string', example: 'maintainer' }
|
||||
expose :minimum_access_level_for_push, documentation: { type: 'string', example: 'maintainer' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -82,7 +82,8 @@ module Gitlab
|
|||
raise exception if should_raise_for_dev?
|
||||
end
|
||||
|
||||
# This should be used when you only want to track the exception.
|
||||
# This should be used when you want to track the exception and not raise
|
||||
# with the default trackers (Sentry and Logger).
|
||||
#
|
||||
# If the exception implements the method `sentry_extra_data` and that method
|
||||
# returns a Hash, then the return value of that method will be merged into
|
||||
|
|
@ -93,7 +94,7 @@ module Gitlab
|
|||
end
|
||||
|
||||
# This should be used when you only want to log the exception,
|
||||
# but not send it to Sentry.
|
||||
# but not send it to Sentry or raise.
|
||||
#
|
||||
# If the exception implements the method `sentry_extra_data` and that method
|
||||
# returns a Hash, then the return value of that method will be merged into
|
||||
|
|
|
|||
|
|
@ -18722,6 +18722,9 @@ msgstr ""
|
|||
msgid "Didn't receive unlock instructions?"
|
||||
msgstr ""
|
||||
|
||||
msgid "Diff"
|
||||
msgstr ""
|
||||
|
||||
msgid "Diff files surpassing this limit will be presented as 'too large' and won't be expandable."
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -57715,6 +57718,9 @@ msgstr ""
|
|||
msgid "VersionCheck|You are currently on version %{currentVersion}! We strongly recommend upgrading your GitLab installation to one of the following versions immediately: %{latestStableVersions}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Versions"
|
||||
msgstr ""
|
||||
|
||||
msgid "View File Metadata"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -59255,18 +59261,12 @@ msgstr ""
|
|||
msgid "Wiki|Page history"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wiki|Page version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wiki|Pages"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wiki|Template history"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wiki|Template version"
|
||||
msgstr ""
|
||||
|
||||
msgid "Wiki|Templates"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
"@gitlab/cluster-client": "^2.2.0",
|
||||
"@gitlab/favicon-overlay": "2.0.0",
|
||||
"@gitlab/fonts": "^1.3.0",
|
||||
"@gitlab/ui": "80.16.1",
|
||||
"@gitlab/ui": "80.19.0",
|
||||
"@gitlab/svgs": "3.101.0",
|
||||
"@gitlab/web-ide": "^0.0.1-dev-20240531032328",
|
||||
"@mattiasbuelens/web-streams-adapter": "^0.1.0",
|
||||
|
|
@ -290,7 +290,7 @@
|
|||
"swagger-cli": "^4.0.4",
|
||||
"tailwindcss": "^3.4.1",
|
||||
"timezone-mock": "^1.0.8",
|
||||
"vite": "^5.2.12",
|
||||
"vite": "^5.2.13",
|
||||
"vite-plugin-ruby": "^5.0.0",
|
||||
"vue-loader-vue3": "npm:vue-loader@17.4.2",
|
||||
"vue-test-utils-compat": "0.0.14",
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@ export const mismatchAllowList = [
|
|||
'.border-l\\!',
|
||||
'.border-r\\!',
|
||||
'.border-t\\!',
|
||||
// Tailwindy transparent border utils now leverage design tokens, the mismatches are expected.
|
||||
'.border-transparent',
|
||||
'.border-t-transparent',
|
||||
'.border-r-transparent',
|
||||
'.border-b-transparent',
|
||||
'.border-l-transparent',
|
||||
// Tailwind's line-clamp utils don't set `white-space: normal`, while our custom utils did.
|
||||
// We have added `gl-whitespace-normal` wherever line-clamp utils were being used, so these
|
||||
// mismatches can be ignored.
|
||||
|
|
|
|||
|
|
@ -14,10 +14,16 @@ RSpec.describe 'Project issue boards sidebar labels', :js, feature_category: :po
|
|||
let_it_be(:stretch) { create(:label, project: project, name: 'Stretch') }
|
||||
let_it_be(:issue1) { create(:labeled_issue, project: project, labels: [development], relative_position: 2) }
|
||||
let_it_be(:issue2) { create(:labeled_issue, project: project, labels: [development, stretch], relative_position: 1) }
|
||||
let_it_be(:issue3) { create(:issue, project: project) }
|
||||
let_it_be(:board) { create(:board, project: project) }
|
||||
let_it_be(:list) { create(:list, board: board, label: development, position: 0) }
|
||||
let_it_be(:list1) { create(:list, board: board, label: development, position: 0) }
|
||||
let_it_be(:list2) { create(:list, board: board, label: bug, position: 1) }
|
||||
|
||||
let(:card) { find('.board:nth-child(2)').first('.board-card') }
|
||||
let(:backlog_list) { find('.board:nth-child(1)') }
|
||||
let(:development_list) { find('.board:nth-child(2)') }
|
||||
let(:bug_list) { find('.board:nth-child(3)') }
|
||||
let(:card) { development_list.first('.board-card') }
|
||||
let(:backlog_card) { backlog_list.first('.board-card') }
|
||||
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
|
|
@ -65,9 +71,20 @@ RSpec.describe 'Project issue boards sidebar labels', :js, feature_category: :po
|
|||
end
|
||||
end
|
||||
|
||||
click_button 'Close drawer'
|
||||
|
||||
wait_for_requests
|
||||
|
||||
# 'Development' label does not show since the card is in a 'Development' list label
|
||||
expect(card).to have_selector('.gl-label', count: 2)
|
||||
expect(card).to have_content(bug.title)
|
||||
|
||||
# Card is duplicated in the 'Bug' list
|
||||
page.within(bug_list) do
|
||||
expect(page).to have_selector('.board-card', count: 1)
|
||||
expect(page).to have_content(issue2.title)
|
||||
expect(find('.board-card')).to have_content(development.title)
|
||||
end
|
||||
end
|
||||
|
||||
it 'adds a multiple labels' do
|
||||
|
|
@ -99,6 +116,69 @@ RSpec.describe 'Project issue boards sidebar labels', :js, feature_category: :po
|
|||
expect(card).to have_content(regression.title)
|
||||
end
|
||||
|
||||
it 'removes a label and moves card to backlog' do
|
||||
click_card(card)
|
||||
|
||||
page.within('.labels') do
|
||||
click_button 'Edit'
|
||||
|
||||
wait_for_requests
|
||||
|
||||
click_button development.title
|
||||
|
||||
click_button 'Close'
|
||||
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
click_button 'Close drawer'
|
||||
|
||||
wait_for_requests
|
||||
|
||||
# Card is moved to the 'Backlog' list
|
||||
page.within(backlog_list) do
|
||||
expect(page).to have_selector('.board-card', count: 2)
|
||||
expect(page).to have_content(issue2.title)
|
||||
end
|
||||
|
||||
# Card is moved away from the 'Development' list
|
||||
page.within(development_list) do
|
||||
expect(page).to have_selector('.board-card', count: 1)
|
||||
expect(page).not_to have_content(issue2.title)
|
||||
end
|
||||
end
|
||||
|
||||
it 'adds a label to backlog card and moves the card to the list' do
|
||||
click_card(backlog_card)
|
||||
|
||||
page.within('.labels') do
|
||||
click_button 'Edit'
|
||||
|
||||
wait_for_requests
|
||||
|
||||
click_on development.title
|
||||
|
||||
click_button 'Close'
|
||||
|
||||
wait_for_requests
|
||||
end
|
||||
|
||||
click_button 'Close drawer'
|
||||
|
||||
wait_for_requests
|
||||
|
||||
# Card is removed from backlog
|
||||
page.within(backlog_list) do
|
||||
expect(page).to have_selector('.board-card', count: 0)
|
||||
end
|
||||
|
||||
# Card is shown in the 'Development' list
|
||||
page.within(development_list) do
|
||||
expect(page).to have_selector('.board-card', count: 3)
|
||||
expect(page).to have_content(issue3.title)
|
||||
end
|
||||
end
|
||||
|
||||
it 'removes a label' do
|
||||
click_card(card)
|
||||
|
||||
|
|
@ -139,7 +219,7 @@ RSpec.describe 'Project issue boards sidebar labels', :js, feature_category: :po
|
|||
|
||||
expect(page).to have_button 'test label'
|
||||
end
|
||||
expect(page).to have_selector('.board', count: 3)
|
||||
expect(page).to have_selector('.board', count: 4)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ describe('Code Block', () => {
|
|||
class="code code-block rounded"
|
||||
>
|
||||
<code
|
||||
class="d-block"
|
||||
class="gl-block"
|
||||
/>
|
||||
</pre>
|
||||
`);
|
||||
|
|
@ -47,7 +47,7 @@ describe('Code Block', () => {
|
|||
class="code code-block rounded"
|
||||
>
|
||||
<code
|
||||
class="d-block"
|
||||
class="gl-block"
|
||||
>
|
||||
test-code
|
||||
</code>
|
||||
|
|
@ -64,7 +64,7 @@ describe('Code Block', () => {
|
|||
style="max-height: 200px; overflow-y: auto;"
|
||||
>
|
||||
<code
|
||||
class="d-block"
|
||||
class="gl-block"
|
||||
>
|
||||
test-code
|
||||
</code>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ RSpec.describe API::Entities::Projects::Packages::Protection::Rule, feature_cate
|
|||
:project_id,
|
||||
:package_name_pattern,
|
||||
:package_type,
|
||||
:push_protected_up_to_access_level
|
||||
:minimum_access_level_for_push
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ RSpec.describe Banzai::Pipeline::PlainMarkdownPipeline, feature_category: :team_
|
|||
end
|
||||
|
||||
it 'does not have a polynomial regex' do
|
||||
markdown = "x \\#\n\n#{'mliteralcmliteral-' * 1550000}mliteral"
|
||||
markdown = "x \\#\n\n#{'mliteralcmliteral-' * 450000}mliteral"
|
||||
|
||||
expect do
|
||||
Timeout.timeout(2.seconds) { described_class.to_html(markdown, project: project) }
|
||||
|
|
|
|||
16
yarn.lock
16
yarn.lock
|
|
@ -1331,10 +1331,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.101.0.tgz#a8769490eecd03b8cc2403f5b7faab34a4ad0d82"
|
||||
integrity sha512-X/3oLr969A9dzVaTD2JfG6EmxadEQwCPXcfn1A6Y+AAI0PLkBgjDXUz0yo1tXJOF6nqOmYpBiUM6uOon3i5N4A==
|
||||
|
||||
"@gitlab/ui@80.16.1":
|
||||
version "80.16.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-80.16.1.tgz#87ed3cf6dd6a1da123422dfa339734440ad35d1f"
|
||||
integrity sha512-j7yYTvdIXQsznIKmrIwX7G3e67b3s2qt4KbIR+fq78Yko+9FO38t4bceVZo33cpHu26Sx0wqbjq3xAVnE9D/ug==
|
||||
"@gitlab/ui@80.19.0":
|
||||
version "80.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-80.19.0.tgz#b6e6018d27939a7ac2451b6a41cf49071977aa95"
|
||||
integrity sha512-aswSSLDkHzjvWdHDKZH5ZPZYiX821+fZ2yPLoN+0OYyA75XzAr5daaV2os4y6PLPtWJHiHF3nWbZSF80wMF68A==
|
||||
dependencies:
|
||||
"@floating-ui/dom" "1.4.3"
|
||||
bootstrap-vue "2.23.1"
|
||||
|
|
@ -14156,10 +14156,10 @@ vite-plugin-ruby@^5.0.0:
|
|||
debug "^4.3.4"
|
||||
fast-glob "^3.3.2"
|
||||
|
||||
vite@^5.2.12:
|
||||
version "5.2.12"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.12.tgz#3536c93c58ba18edea4915a2ac573e6537409d97"
|
||||
integrity sha512-/gC8GxzxMK5ntBwb48pR32GGhENnjtY30G4A0jemunsBkiEZFw60s8InGpN8gkhHEkjnRK1aSAxeQgwvFhUHAA==
|
||||
vite@^5.2.13:
|
||||
version "5.2.13"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.13.tgz#945ababcbe3d837ae2479c29f661cd20bc5e1a80"
|
||||
integrity sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==
|
||||
dependencies:
|
||||
esbuild "^0.20.1"
|
||||
postcss "^8.4.38"
|
||||
|
|
|
|||
Loading…
Reference in New Issue