Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-08-12 00:08:47 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-12 00:08:47 +0300
commit23790cda2b4145294d71591515acfe892d4c99a7 (patch)
tree0efc35c3f6ae5830953f09929e77569e9082104b /app/assets
parent413b7041032d2bf34d95cdc1d2375dbf2dbf4163 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/organizations/groups_and_projects/graphql/queries/projects.query.graphql1
-rw-r--r--app/assets/javascripts/organizations/groups_and_projects/utils.js6
-rw-r--r--app/assets/javascripts/projects/components/shared/delete_modal.vue8
-rw-r--r--app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue41
-rw-r--r--app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js8
-rw-r--r--app/assets/javascripts/vue_shared/components/projects_list/constants.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/projects_list/projects_list.vue1
-rw-r--r--app/assets/javascripts/vue_shared/components/projects_list/projects_list_item.vue303
8 files changed, 240 insertions, 130 deletions
diff --git a/app/assets/javascripts/organizations/groups_and_projects/graphql/queries/projects.query.graphql b/app/assets/javascripts/organizations/groups_and_projects/graphql/queries/projects.query.graphql
index b4cb8c607d4..2a7971e1106 100644
--- a/app/assets/javascripts/organizations/groups_and_projects/graphql/queries/projects.query.graphql
+++ b/app/assets/javascripts/organizations/groups_and_projects/graphql/queries/projects.query.graphql
@@ -15,6 +15,7 @@ query getOrganizationProjects {
descriptionHtml
issuesAccessLevel
forkingAccessLevel
+ isForked
accessLevel {
integerValue
}
diff --git a/app/assets/javascripts/organizations/groups_and_projects/utils.js b/app/assets/javascripts/organizations/groups_and_projects/utils.js
index cbfa120503d..d2a4e05e806 100644
--- a/app/assets/javascripts/organizations/groups_and_projects/utils.js
+++ b/app/assets/javascripts/organizations/groups_and_projects/utils.js
@@ -1,7 +1,8 @@
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { ACTION_EDIT, ACTION_DELETE } from '~/vue_shared/components/projects_list/constants';
export const formatProjects = (projects) =>
- projects.map(({ id, nameWithNamespace, accessLevel, ...project }) => ({
+ projects.map(({ id, nameWithNamespace, accessLevel, webUrl, ...project }) => ({
...project,
id: getIdFromGraphQLId(id),
name: nameWithNamespace,
@@ -10,6 +11,9 @@ export const formatProjects = (projects) =>
accessLevel: accessLevel.integerValue,
},
},
+ webUrl,
+ editPath: `${webUrl}/edit`,
+ actions: [ACTION_EDIT, ACTION_DELETE],
}));
export const formatGroups = (groups) =>
diff --git a/app/assets/javascripts/projects/components/shared/delete_modal.vue b/app/assets/javascripts/projects/components/shared/delete_modal.vue
index aded11ca92c..d15f51692e7 100644
--- a/app/assets/javascripts/projects/components/shared/delete_modal.vue
+++ b/app/assets/javascripts/projects/components/shared/delete_modal.vue
@@ -37,22 +37,22 @@ export default {
required: true,
},
issuesCount: {
- type: Number,
+ type: [Number, String],
required: false,
default: null,
},
mergeRequestsCount: {
- type: Number,
+ type: [Number, String],
required: false,
default: null,
},
forksCount: {
- type: Number,
+ type: [Number, String],
required: false,
default: null,
},
starsCount: {
- type: Number,
+ type: [Number, String],
required: false,
default: null,
},
diff --git a/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue b/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue
index b8e7e9e15db..a02a33992b5 100644
--- a/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue
+++ b/app/assets/javascripts/projects/settings/components/shared_runners_toggle.vue
@@ -1,5 +1,5 @@
<script>
-import { GlAlert, GlToggle } from '@gitlab/ui';
+import { GlAlert, GlLink, GlToggle, GlSprintf } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
import { __, s__ } from '~/locale';
import { CC_VALIDATION_REQUIRED_ERROR } from '../constants';
@@ -15,7 +15,9 @@ export default {
},
components: {
GlAlert,
+ GlLink,
GlToggle,
+ GlSprintf,
CcValidationRequiredAlert: () =>
import('ee_component/billings/components/cc_validation_required_alert.vue'),
},
@@ -36,6 +38,16 @@ export default {
type: String,
required: true,
},
+ groupName: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ groupSettingsPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
},
data() {
return {
@@ -57,6 +69,9 @@ export default {
!this.ccAlertDismissed
);
},
+ isGroupSettingsAvailable() {
+ return this.groupSettingsPath && this.groupName;
+ },
},
methods: {
creditCardValidated() {
@@ -103,16 +118,6 @@ export default {
{{ errorMessage }}
</gl-alert>
- <gl-alert
- v-if="isDisabledAndUnoverridable"
- data-testid="unoverridable-alert"
- variant="warning"
- :dismissible="false"
- class="gl-mb-5"
- >
- {{ s__('Runners|Shared runners are disabled in the group settings') }}
- </gl-alert>
-
<gl-toggle
ref="sharedRunnersToggle"
:disabled="isDisabledAndUnoverridable"
@@ -121,7 +126,19 @@ export default {
:value="isSharedRunnerEnabled"
data-testid="toggle-shared-runners"
@change="toggleSharedRunners"
- />
+ >
+ <template v-if="isDisabledAndUnoverridable" #help>
+ {{ s__('Runners|Shared runners are disabled in the group settings.') }}
+ <gl-sprintf
+ v-if="isGroupSettingsAvailable"
+ :message="s__('Runners|Go to %{groupLink} to enable them.')"
+ >
+ <template #groupLink>
+ <gl-link :href="groupSettingsPath">{{ groupName }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </template>
+ </gl-toggle>
</section>
</div>
</template>
diff --git a/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js b/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js
index 54120b3525d..ace5fd5c6e4 100644
--- a/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js
+++ b/app/assets/javascripts/projects/settings/mount_shared_runners_toggle.js
@@ -9,10 +9,15 @@ export default (containerId = 'toggle-shared-runners-form') => {
}
const {
+ // required
isDisabledAndUnoverridable,
isEnabled,
updatePath,
isCreditCardValidationRequired,
+
+ // optional
+ groupName,
+ groupSettingsPath,
} = containerEl.dataset;
return new Vue({
@@ -24,6 +29,9 @@ export default (containerId = 'toggle-shared-runners-form') => {
isEnabled: parseBoolean(isEnabled),
isCreditCardValidationRequired: parseBoolean(isCreditCardValidationRequired),
updatePath,
+
+ groupName,
+ groupSettingsPath,
},
});
},
diff --git a/app/assets/javascripts/vue_shared/components/projects_list/constants.js b/app/assets/javascripts/vue_shared/components/projects_list/constants.js
new file mode 100644
index 00000000000..aa0b1418a06
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/projects_list/constants.js
@@ -0,0 +1,2 @@
+export const ACTION_EDIT = 'edit';
+export const ACTION_DELETE = 'delete';
diff --git a/app/assets/javascripts/vue_shared/components/projects_list/projects_list.vue b/app/assets/javascripts/vue_shared/components/projects_list/projects_list.vue
index cb8220a0407..3a4da54c84c 100644
--- a/app/assets/javascripts/vue_shared/components/projects_list/projects_list.vue
+++ b/app/assets/javascripts/vue_shared/components/projects_list/projects_list.vue
@@ -46,6 +46,7 @@ export default {
:key="project.id"
:project="project"
:show-project-icon="showProjectIcon"
+ @delete="$emit('delete', $event)"
/>
</ul>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/projects_list/projects_list_item.vue b/app/assets/javascripts/vue_shared/components/projects_list/projects_list_item.vue
index d919f76e684..9fc4571b0dc 100644
--- a/app/assets/javascripts/vue_shared/components/projects_list/projects_list_item.vue
+++ b/app/assets/javascripts/vue_shared/components/projects_list/projects_list_item.vue
@@ -7,6 +7,7 @@ import {
GlTooltipDirective,
GlPopover,
GlSprintf,
+ GlDisclosureDropdown,
} from '@gitlab/ui';
import uniqueId from 'lodash/uniqueId';
@@ -19,6 +20,8 @@ import { numberToMetricPrefix } from '~/lib/utils/number_utils';
import { truncate } from '~/lib/utils/text_utility';
import SafeHtml from '~/vue_shared/directives/safe_html';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import DeleteModal from '~/projects/components/shared/delete_modal.vue';
+import { ACTION_EDIT, ACTION_DELETE } from './constants';
const MAX_TOPICS_TO_SHOW = 3;
const MAX_TOPIC_TITLE_LENGTH = 15;
@@ -33,6 +36,7 @@ export default {
topicsPopoverTargetText: __('+ %{count} more'),
moreTopics: __('More topics'),
updated: __('Updated'),
+ actions: __('Actions'),
},
avatarSize: { default: 32, md: 48 },
safeHtmlConfig: {
@@ -47,6 +51,8 @@ export default {
GlPopover,
GlSprintf,
TimeAgoTooltip,
+ GlDisclosureDropdown,
+ DeleteModal,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -73,6 +79,9 @@ export default {
* };
* descriptionHtml: string;
* updatedAt: string;
+ * isForked: boolean;
+ * actions?: ('edit' | 'delete')[];
+ * editPath?: string;
* }
*/
project: {
@@ -88,6 +97,7 @@ export default {
data() {
return {
topicsPopoverTarget: uniqueId('project-topics-popover-'),
+ isDeleteModalVisible: false,
};
},
computed: {
@@ -136,9 +146,50 @@ export default {
popoverTopics() {
return this.project.topics.slice(MAX_TOPICS_TO_SHOW);
},
+ starCount() {
+ return numberToMetricPrefix(this.project.starCount);
+ },
+ forksCount() {
+ if (!this.isForkingEnabled) {
+ return null;
+ }
+
+ return numberToMetricPrefix(this.project.forksCount);
+ },
+ openIssuesCount() {
+ if (!this.isIssuesEnabled) {
+ return null;
+ }
+
+ return numberToMetricPrefix(this.project.openIssuesCount);
+ },
+ actionsDropdownItems() {
+ return [
+ {
+ id: ACTION_EDIT,
+ text: __('Edit'),
+ href: this.project.editPath,
+ },
+ {
+ id: ACTION_DELETE,
+ text: __('Delete'),
+ extraAttrs: {
+ class: 'gl-text-red-500!',
+ },
+ action: () => {
+ this.isDeleteModalVisible = true;
+ },
+ },
+ ].filter(({ id }) => this.project.actions?.includes(id));
+ },
+ hasActions() {
+ return this.actionsDropdownItems.length;
+ },
+ hasDeleteAction() {
+ return this.actionsDropdownItems.find((action) => action.id === ACTION_DELETE);
+ },
},
methods: {
- numberToMetricPrefix,
topicPath(topic) {
return `/explore/projects/topics/${encodeURIComponent(topic)}`;
},
@@ -158,128 +209,154 @@ export default {
</script>
<template>
- <li class="projects-list-item gl-py-5 gl-md-display-flex gl-align-items-center gl-border-b">
- <div class="gl-display-flex gl-flex-grow-1">
- <gl-icon
- v-if="showProjectIcon"
- class="gl-mr-3 gl-mt-3 gl-md-mt-5 gl-flex-shrink-0 gl-text-secondary"
- name="project"
- />
- <gl-avatar-labeled
- :entity-id="project.id"
- :entity-name="project.name"
- :label="project.name"
- :label-link="project.webUrl"
- shape="rect"
- :size="$options.avatarSize"
- >
- <template #meta>
- <div class="gl-px-2">
- <div class="gl-mx-n2 gl-display-flex gl-align-items-center gl-flex-wrap">
- <div class="gl-px-2">
- <gl-icon
- v-if="visibility"
- v-gl-tooltip="visibilityTooltip"
- :name="visibilityIcon"
- class="gl-text-secondary"
- />
- </div>
- <div class="gl-px-2">
- <user-access-role-badge v-if="shouldShowAccessLevel">{{
- accessLevelLabel
- }}</user-access-role-badge>
+ <li class="projects-list-item gl-py-5 gl-border-b gl-display-flex gl-align-items-flex-start">
+ <div class="gl-md-display-flex gl-align-items-center gl-flex-grow-1">
+ <div class="gl-display-flex gl-flex-grow-1">
+ <gl-icon
+ v-if="showProjectIcon"
+ class="gl-mr-3 gl-mt-3 gl-md-mt-5 gl-flex-shrink-0 gl-text-secondary"
+ name="project"
+ />
+ <gl-avatar-labeled
+ :entity-id="project.id"
+ :entity-name="project.name"
+ :label="project.name"
+ :label-link="project.webUrl"
+ shape="rect"
+ :size="$options.avatarSize"
+ >
+ <template #meta>
+ <div class="gl-px-2">
+ <div class="gl-mx-n2 gl-display-flex gl-align-items-center gl-flex-wrap">
+ <div class="gl-px-2">
+ <gl-icon
+ v-if="visibility"
+ v-gl-tooltip="visibilityTooltip"
+ :name="visibilityIcon"
+ class="gl-text-secondary"
+ />
+ </div>
+ <div class="gl-px-2">
+ <user-access-role-badge v-if="shouldShowAccessLevel">{{
+ accessLevelLabel
+ }}</user-access-role-badge>
+ </div>
</div>
</div>
- </div>
- </template>
- <div
- v-if="project.descriptionHtml"
- v-safe-html:[$options.safeHtmlConfig]="project.descriptionHtml"
- class="gl-font-sm gl-overflow-hidden gl-line-height-20 description md"
- data-testid="project-description"
- ></div>
- <div v-if="hasTopics" class="gl-mt-3" data-testid="project-topics">
+ </template>
<div
- class="gl-w-full gl-display-inline-flex gl-flex-wrap gl-font-base gl-font-weight-normal gl-align-items-center gl-mx-n2 gl-my-n2"
- >
- <span class="gl-p-2 gl-text-secondary">{{ $options.i18n.topics }}:</span>
- <div v-for="topic in visibleTopics" :key="topic" class="gl-p-2">
- <gl-badge v-gl-tooltip="topicTooltipTitle(topic)" :href="topicPath(topic)">
- {{ topicTitle(topic) }}
- </gl-badge>
- </div>
- <template v-if="popoverTopics.length">
- <div
- :id="topicsPopoverTarget"
- class="gl-p-2 gl-text-secondary"
- role="button"
- tabindex="0"
- >
- <gl-sprintf :message="$options.i18n.topicsPopoverTargetText">
- <template #count>{{ popoverTopics.length }}</template>
- </gl-sprintf>
+ v-if="project.descriptionHtml"
+ v-safe-html:[$options.safeHtmlConfig]="project.descriptionHtml"
+ class="gl-font-sm gl-overflow-hidden gl-line-height-20 description md"
+ data-testid="project-description"
+ ></div>
+ <div v-if="hasTopics" class="gl-mt-3" data-testid="project-topics">
+ <div
+ class="gl-w-full gl-display-inline-flex gl-flex-wrap gl-font-base gl-font-weight-normal gl-align-items-center gl-mx-n2 gl-my-n2"
+ >
+ <span class="gl-p-2 gl-text-secondary">{{ $options.i18n.topics }}:</span>
+ <div v-for="topic in visibleTopics" :key="topic" class="gl-p-2">
+ <gl-badge v-gl-tooltip="topicTooltipTitle(topic)" :href="topicPath(topic)">
+ {{ topicTitle(topic) }}
+ </gl-badge>
</div>
- <gl-popover :target="topicsPopoverTarget" :title="$options.i18n.moreTopics">
- <div class="gl-font-base gl-font-weight-normal gl-mx-n2 gl-my-n2">
- <div
- v-for="topic in popoverTopics"
- :key="topic"
- class="gl-p-2 gl-display-inline-block"
- >
- <gl-badge v-gl-tooltip="topicTooltipTitle(topic)" :href="topicPath(topic)">
- {{ topicTitle(topic) }}
- </gl-badge>
- </div>
+ <template v-if="popoverTopics.length">
+ <div
+ :id="topicsPopoverTarget"
+ class="gl-p-2 gl-text-secondary"
+ role="button"
+ tabindex="0"
+ >
+ <gl-sprintf :message="$options.i18n.topicsPopoverTargetText">
+ <template #count>{{ popoverTopics.length }}</template>
+ </gl-sprintf>
</div>
- </gl-popover>
- </template>
+ <gl-popover :target="topicsPopoverTarget" :title="$options.i18n.moreTopics">
+ <div class="gl-font-base gl-font-weight-normal gl-mx-n2 gl-my-n2">
+ <div
+ v-for="topic in popoverTopics"
+ :key="topic"
+ class="gl-p-2 gl-display-inline-block"
+ >
+ <gl-badge v-gl-tooltip="topicTooltipTitle(topic)" :href="topicPath(topic)">
+ {{ topicTitle(topic) }}
+ </gl-badge>
+ </div>
+ </div>
+ </gl-popover>
+ </template>
+ </div>
</div>
- </div>
- </gl-avatar-labeled>
- </div>
- <div
- class="gl-md-display-flex gl-flex-direction-column gl-align-items-flex-end gl-flex-shrink-0 gl-mt-3 gl-md-pl-0 gl-md-mt-0"
- :class="showProjectIcon ? 'gl-pl-11' : 'gl-pl-8'"
- >
- <div class="gl-display-flex gl-align-items-center gl-gap-x-3">
- <gl-badge v-if="project.archived" variant="warning">{{ $options.i18n.archived }}</gl-badge>
- <gl-link
- v-gl-tooltip="$options.i18n.stars"
- :href="starsHref"
- :aria-label="$options.i18n.stars"
- class="gl-text-secondary"
- >
- <gl-icon name="star-o" />
- <span>{{ numberToMetricPrefix(project.starCount) }}</span>
- </gl-link>
- <gl-link
- v-if="isForkingEnabled"
- v-gl-tooltip="$options.i18n.forks"
- :href="forksHref"
- :aria-label="$options.i18n.forks"
- class="gl-text-secondary"
- >
- <gl-icon name="fork" />
- <span>{{ numberToMetricPrefix(project.forksCount) }}</span>
- </gl-link>
- <gl-link
- v-if="isIssuesEnabled"
- v-gl-tooltip="$options.i18n.issues"
- :href="issuesHref"
- :aria-label="$options.i18n.issues"
- class="gl-text-secondary"
- >
- <gl-icon name="issues" />
- <span>{{ numberToMetricPrefix(project.openIssuesCount) }}</span>
- </gl-link>
+ </gl-avatar-labeled>
</div>
<div
- v-if="project.updatedAt"
- class="gl-font-sm gl-white-space-nowrap gl-text-secondary gl-mt-3"
+ class="gl-md-display-flex gl-flex-direction-column gl-align-items-flex-end gl-flex-shrink-0 gl-mt-3 gl-md-pl-0 gl-md-mt-0"
+ :class="showProjectIcon ? 'gl-pl-11' : 'gl-pl-8'"
>
- <span>{{ $options.i18n.updated }}</span>
- <time-ago-tooltip :time="project.updatedAt" />
+ <div class="gl-display-flex gl-align-items-center gl-gap-x-3">
+ <gl-badge v-if="project.archived" variant="warning">{{
+ $options.i18n.archived
+ }}</gl-badge>
+ <gl-link
+ v-gl-tooltip="$options.i18n.stars"
+ :href="starsHref"
+ :aria-label="$options.i18n.stars"
+ class="gl-text-secondary"
+ >
+ <gl-icon name="star-o" />
+ <span>{{ starCount }}</span>
+ </gl-link>
+ <gl-link
+ v-if="isForkingEnabled"
+ v-gl-tooltip="$options.i18n.forks"
+ :href="forksHref"
+ :aria-label="$options.i18n.forks"
+ class="gl-text-secondary"
+ >
+ <gl-icon name="fork" />
+ <span>{{ forksCount }}</span>
+ </gl-link>
+ <gl-link
+ v-if="isIssuesEnabled"
+ v-gl-tooltip="$options.i18n.issues"
+ :href="issuesHref"
+ :aria-label="$options.i18n.issues"
+ class="gl-text-secondary"
+ >
+ <gl-icon name="issues" />
+ <span>{{ openIssuesCount }}</span>
+ </gl-link>
+ </div>
+ <div
+ v-if="project.updatedAt"
+ class="gl-font-sm gl-white-space-nowrap gl-text-secondary gl-mt-3"
+ >
+ <span>{{ $options.i18n.updated }}</span>
+ <time-ago-tooltip :time="project.updatedAt" />
+ </div>
</div>
</div>
+ <gl-disclosure-dropdown
+ v-if="hasActions"
+ class="gl-ml-3 gl-md-align-self-center"
+ :items="actionsDropdownItems"
+ icon="ellipsis_v"
+ no-caret
+ :toggle-text="$options.i18n.actions"
+ text-sr-only
+ placement="right"
+ category="tertiary"
+ />
+
+ <delete-modal
+ v-if="hasDeleteAction"
+ v-model="isDeleteModalVisible"
+ :confirm-phrase="project.name"
+ :is-fork="project.isForked"
+ :issues-count="openIssuesCount"
+ :forks-count="forksCount"
+ :stars-count="starCount"
+ @primary="$emit('delete', project)"
+ />
</li>
</template>