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-01-24 21:11:44 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-01-24 21:11:44 +0300
commitfd247970cfe1e98276c780fbdcca026b7960e42a (patch)
treeab7963eb9b30fd73283c526cb6ae4ca1ef61c06f /app/assets/javascripts/vue_shared/components/entity_select
parentdf9890e9a702e2f12bbc8f022b916ca72820a292 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/entity_select')
-rw-r--r--app/assets/javascripts/vue_shared/components/entity_select/constants.js16
-rw-r--r--app/assets/javascripts/vue_shared/components/entity_select/group_select.vue15
-rw-r--r--app/assets/javascripts/vue_shared/components/entity_select/init_project_selects.js34
-rw-r--r--app/assets/javascripts/vue_shared/components/entity_select/project_select.vue113
4 files changed, 169 insertions, 9 deletions
diff --git a/app/assets/javascripts/vue_shared/components/entity_select/constants.js b/app/assets/javascripts/vue_shared/components/entity_select/constants.js
index a48bba3be8c..0fb5a2d5534 100644
--- a/app/assets/javascripts/vue_shared/components/entity_select/constants.js
+++ b/app/assets/javascripts/vue_shared/components/entity_select/constants.js
@@ -1,8 +1,16 @@
-import { __ } from '~/locale';
+import { __, s__ } from '~/locale';
-export const TOGGLE_TEXT = __('Search for a group');
-export const HEADER_TEXT = __('Select a group');
export const RESET_LABEL = __('Reset');
+export const QUERY_TOO_SHORT_MESSAGE = __('Enter at least three characters to search.');
+
+// Groups
+export const GROUP_TOGGLE_TEXT = __('Search for a group');
+export const GROUP_HEADER_TEXT = __('Select a group');
export const FETCH_GROUPS_ERROR = __('Unable to fetch groups. Reload the page to try again.');
export const FETCH_GROUP_ERROR = __('Unable to fetch group. Reload the page to try again.');
-export const QUERY_TOO_SHORT_MESSAGE = __('Enter at least three characters to search.');
+
+// Projects
+export const PROJECT_TOGGLE_TEXT = s__('ProjectSelect|Search for project');
+export const PROJECT_HEADER_TEXT = s__('ProjectSelect|Select a project');
+export const FETCH_PROJECTS_ERROR = __('Unable to fetch projects. Reload the page to try again.');
+export const FETCH_PROJECT_ERROR = __('Unable to fetch project. Reload the page to try again.');
diff --git a/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue b/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue
index a5fc438e932..ff137d764ee 100644
--- a/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue
+++ b/app/assets/javascripts/vue_shared/components/entity_select/group_select.vue
@@ -5,7 +5,12 @@ import axios from '~/lib/utils/axios_utils';
import { normalizeHeaders, parseIntPagination } from '~/lib/utils/common_utils';
import Api, { DEFAULT_PER_PAGE } from '~/api';
import { groupsPath } from './utils';
-import { TOGGLE_TEXT, HEADER_TEXT, FETCH_GROUPS_ERROR, FETCH_GROUP_ERROR } from './constants';
+import {
+ GROUP_TOGGLE_TEXT,
+ GROUP_HEADER_TEXT,
+ FETCH_GROUPS_ERROR,
+ FETCH_GROUP_ERROR,
+} from './constants';
import EntitySelect from './entity_select.vue';
export default {
@@ -58,7 +63,7 @@ export default {
let groups = [];
let totalPages = 0;
try {
- const { data, headers } = await axios.get(
+ const { data = [], headers } = await axios.get(
Api.buildUrl(groupsPath(this.groupsFilter, this.parentGroupID)),
{
params: {
@@ -68,7 +73,7 @@ export default {
},
},
);
- groups = (data.length ? data : data.results || []).map((group) => ({
+ groups = data.map((group) => ({
...group,
text: group.full_name,
value: String(group.id),
@@ -99,8 +104,8 @@ export default {
},
},
i18n: {
- toggleText: TOGGLE_TEXT,
- selectGroup: HEADER_TEXT,
+ toggleText: GROUP_TOGGLE_TEXT,
+ selectGroup: GROUP_HEADER_TEXT,
},
};
</script>
diff --git a/app/assets/javascripts/vue_shared/components/entity_select/init_project_selects.js b/app/assets/javascripts/vue_shared/components/entity_select/init_project_selects.js
new file mode 100644
index 00000000000..eee90b0f4f7
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/entity_select/init_project_selects.js
@@ -0,0 +1,34 @@
+import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import ProjectSelect from './project_select.vue';
+
+const SELECTOR = '.js-vue-project-select';
+
+export const initProjectSelects = () => {
+ if (process.env.NODE_ENV !== 'production' && document.querySelector(SELECTOR) === null) {
+ // eslint-disable-next-line no-console
+ console.warn(`Attempted to initialize ProjectSelect but '${SELECTOR}' not found in the page`);
+ }
+
+ document.querySelectorAll(SELECTOR).forEach((el) => {
+ const { label, inputName, inputId, groupId, selected: initialSelection } = el.dataset;
+ const clearable = parseBoolean(el.dataset.clearable);
+
+ return new Vue({
+ el,
+ name: 'ProjectSelectRoot',
+ render(createElement) {
+ return createElement(ProjectSelect, {
+ props: {
+ label,
+ inputName,
+ inputId,
+ groupId,
+ initialSelection,
+ clearable,
+ },
+ });
+ },
+ });
+ });
+};
diff --git a/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue b/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue
new file mode 100644
index 00000000000..c71fb713f1c
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/entity_select/project_select.vue
@@ -0,0 +1,113 @@
+<script>
+import { GlAlert } from '@gitlab/ui';
+import * as Sentry from '@sentry/browser';
+import Api from '~/api';
+import {
+ PROJECT_TOGGLE_TEXT,
+ PROJECT_HEADER_TEXT,
+ FETCH_PROJECTS_ERROR,
+ FETCH_PROJECT_ERROR,
+} from './constants';
+import EntitySelector from './entity_select.vue';
+
+export default {
+ components: {
+ GlAlert,
+ EntitySelector,
+ },
+ props: {
+ label: {
+ type: String,
+ required: true,
+ },
+ inputName: {
+ type: String,
+ required: true,
+ },
+ inputId: {
+ type: String,
+ required: true,
+ },
+ groupId: {
+ type: String,
+ required: true,
+ },
+ initialSelection: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ clearable: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ data() {
+ return {
+ errorMessage: '',
+ };
+ },
+ methods: {
+ async fetchProjects(searchString = '') {
+ let projects = [];
+ try {
+ const { data = [] } = await Api.groupProjects(this.groupId, searchString, {
+ with_shared: true,
+ include_subgroups: false,
+ order_by: 'similarity',
+ simple: true,
+ });
+ projects = data.map((item) => ({
+ text: item.name_with_namespace || item.name,
+ value: String(item.id),
+ }));
+ } catch (error) {
+ this.handleError({ message: FETCH_PROJECTS_ERROR, error });
+ }
+ return { items: projects, totalPages: 1 };
+ },
+ async fetchProjectName(projectId) {
+ let projectName = '';
+ try {
+ const { data: project } = await Api.project(projectId);
+ projectName = project.name_with_namespace;
+ } catch (error) {
+ this.handleError({ message: FETCH_PROJECT_ERROR, error });
+ }
+ return projectName;
+ },
+ handleError({ message, error }) {
+ Sentry.captureException(error);
+ this.errorMessage = message;
+ },
+ dismissError() {
+ this.errorMessage = '';
+ },
+ },
+ i18n: {
+ searchForProject: PROJECT_TOGGLE_TEXT,
+ selectProject: PROJECT_HEADER_TEXT,
+ },
+};
+</script>
+
+<template>
+ <entity-selector
+ :label="label"
+ :input-name="inputName"
+ :input-id="inputId"
+ :initial-selection="initialSelection"
+ :clearable="clearable"
+ :header-text="$options.i18n.selectProject"
+ :default-toggle-text="$options.i18n.searchForProject"
+ :fetch-items="fetchProjects"
+ :fetch-initial-selection-text="fetchProjectName"
+ >
+ <template #error>
+ <gl-alert v-if="errorMessage" class="gl-mb-3" variant="danger" @dismiss="dismissError">{{
+ errorMessage
+ }}</gl-alert>
+ </template>
+ </entity-selector>
+</template>