diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-19 12:08:42 +0300 |
commit | b76ae638462ab0f673e5915986070518dd3f9ad3 (patch) | |
tree | bdab0533383b52873be0ec0eb4d3c66598ff8b91 /app/assets/javascripts/integrations | |
parent | 434373eabe7b4be9593d18a585fb763f1e5f1a6f (diff) |
Add latest changes from gitlab-org/gitlab@14-2-stable-eev14.2.0-rc42
Diffstat (limited to 'app/assets/javascripts/integrations')
5 files changed, 177 insertions, 3 deletions
diff --git a/app/assets/javascripts/integrations/edit/components/dynamic_field.vue b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue index 3655f94f06f..1fd4083b920 100644 --- a/app/assets/javascripts/integrations/edit/components/dynamic_field.vue +++ b/app/assets/javascripts/integrations/edit/components/dynamic_field.vue @@ -1,6 +1,12 @@ <script> -/* eslint-disable vue/no-v-html */ -import { GlFormGroup, GlFormCheckbox, GlFormInput, GlFormSelect, GlFormTextarea } from '@gitlab/ui'; +import { + GlFormGroup, + GlFormCheckbox, + GlFormInput, + GlFormSelect, + GlFormTextarea, + GlSafeHtmlDirective as SafeHtml, +} from '@gitlab/ui'; import { capitalize, lowerCase, isEmpty } from 'lodash'; import { mapGetters } from 'vuex'; import eventHub from '../event_hub'; @@ -14,6 +20,9 @@ export default { GlFormSelect, GlFormTextarea, }, + directives: { + SafeHtml, + }, props: { choices: { type: Array, @@ -122,6 +131,9 @@ export default { this.validated = true; }, }, + helpHtmlConfig: { + ADD_ATTR: ['target'], // allow external links, can be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1427 is implemented + }, }; </script> @@ -133,7 +145,7 @@ export default { :state="valid" > <template #description> - <span v-html="help"></span> + <span v-safe-html:[$options.helpHtmlConfig]="help"></span> </template> <template v-if="isCheckbox"> diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue index 91f7c7dabf6..63f007170d0 100644 --- a/app/assets/javascripts/integrations/edit/components/integration_form.vue +++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue @@ -86,7 +86,9 @@ export default { }, }, helpHtmlConfig: { + ADD_ATTR: ['target'], // allow external links, can be removed after https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1427 is implemented ADD_TAGS: ['use'], // to support icon SVGs + FORBID_ATTR: [], // This is trusted input so we can override the default config to allow data-* attributes }, }; </script> diff --git a/app/assets/javascripts/integrations/overrides/api.js b/app/assets/javascripts/integrations/overrides/api.js new file mode 100644 index 00000000000..a379a864f9c --- /dev/null +++ b/app/assets/javascripts/integrations/overrides/api.js @@ -0,0 +1,10 @@ +import axios from '~/lib/utils/axios_utils'; + +export const fetchOverrides = (overridesPath, { page, perPage }) => { + return axios.get(overridesPath, { + params: { + page, + per_page: perPage, + }, + }); +}; diff --git a/app/assets/javascripts/integrations/overrides/components/integration_overrides.vue b/app/assets/javascripts/integrations/overrides/components/integration_overrides.vue new file mode 100644 index 00000000000..707ac946b98 --- /dev/null +++ b/app/assets/javascripts/integrations/overrides/components/integration_overrides.vue @@ -0,0 +1,127 @@ +<script> +import { GlLink, GlLoadingIcon, GlPagination, GlTable } from '@gitlab/ui'; + +import { DEFAULT_PER_PAGE } from '~/api'; +import createFlash from '~/flash'; +import { fetchOverrides } from '~/integrations/overrides/api'; +import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; +import { truncateNamespace } from '~/lib/utils/text_utility'; +import { __, s__ } from '~/locale'; +import ProjectAvatar from '~/vue_shared/components/project_avatar.vue'; + +export default { + name: 'IntegrationOverrides', + components: { + GlLink, + GlLoadingIcon, + GlPagination, + GlTable, + ProjectAvatar, + }, + props: { + overridesPath: { + type: String, + required: true, + }, + }, + fields: [ + { + key: 'name', + label: __('Project'), + }, + ], + data() { + return { + isLoading: true, + overrides: [], + page: 1, + totalItems: 0, + }; + }, + computed: { + showPagination() { + return this.totalItems > this.$options.DEFAULT_PER_PAGE && this.overrides.length > 0; + }, + }, + mounted() { + this.loadOverrides(); + }, + methods: { + loadOverrides(page = this.page) { + this.isLoading = true; + + fetchOverrides(this.overridesPath, { + page, + perPage: this.$options.DEFAULT_PER_PAGE, + }) + .then(({ data, headers }) => { + const { page: newPage, total } = parseIntPagination(normalizeHeaders(headers)); + this.page = newPage; + this.totalItems = total; + this.overrides = data; + }) + .catch((error) => { + createFlash({ + message: this.$options.i18n.defaultErrorMessage, + error, + captureError: true, + }); + }) + .finally(() => { + this.isLoading = false; + }); + }, + truncateNamespace, + }, + DEFAULT_PER_PAGE, + i18n: { + defaultErrorMessage: s__( + 'Integrations|An error occurred while loading projects using custom settings.', + ), + tableEmptyText: s__('Integrations|There are no projects using custom settings'), + }, +}; +</script> + +<template> + <div> + <gl-table + :items="overrides" + :fields="$options.fields" + :busy="isLoading" + show-empty + :empty-text="$options.i18n.tableEmptyText" + > + <template #cell(name)="{ item }"> + <gl-link + class="gl-display-inline-flex gl-align-items-center gl-hover-text-decoration-none gl-text-body!" + :href="item.full_path" + > + <project-avatar + class="gl-mr-3" + :project-avatar-url="item.avatar_url" + :project-name="item.name" + aria-hidden="true" + /> + {{ truncateNamespace(item.full_name) }} / + + <strong>{{ item.name }}</strong> + </gl-link> + </template> + + <template #table-busy> + <gl-loading-icon size="md" class="gl-my-2" /> + </template> + </gl-table> + <div class="gl-display-flex gl-justify-content-center gl-mt-5"> + <gl-pagination + v-if="showPagination" + :per-page="$options.DEFAULT_PER_PAGE" + :total-items="totalItems" + :value="page" + :disabled="isLoading" + @input="loadOverrides" + /> + </div> + </div> +</template> diff --git a/app/assets/javascripts/integrations/overrides/index.js b/app/assets/javascripts/integrations/overrides/index.js new file mode 100644 index 00000000000..0f03b23ba21 --- /dev/null +++ b/app/assets/javascripts/integrations/overrides/index.js @@ -0,0 +1,23 @@ +import Vue from 'vue'; +import IntegrationOverrides from './components/integration_overrides.vue'; + +export default () => { + const el = document.querySelector('.js-vue-integration-overrides'); + + if (!el) { + return null; + } + + const { overridesPath } = el.dataset; + + return new Vue({ + el, + render(createElement) { + return createElement(IntegrationOverrides, { + props: { + overridesPath, + }, + }); + }, + }); +}; |