diff options
Diffstat (limited to 'app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue')
-rw-r--r-- | app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue | 133 |
1 files changed, 119 insertions, 14 deletions
diff --git a/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue b/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue index 217442e6131..12c0409629f 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_integrations_list.vue @@ -1,8 +1,24 @@ <script> -import { GlTable, GlIcon, GlTooltipDirective } from '@gitlab/ui'; +import { + GlButtonGroup, + GlButton, + GlIcon, + GlLoadingIcon, + GlModal, + GlModalDirective, + GlTable, + GlTooltipDirective, + GlSprintf, +} from '@gitlab/ui'; import { s__, __ } from '~/locale'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import Tracking from '~/tracking'; -import { trackAlertIntergrationsViewsOptions } from '../constants'; +import { + trackAlertIntegrationsViewsOptions, + integrationToDeleteDefault, + typeSet, +} from '../constants'; +import getCurrentIntegrationQuery from '../graphql/queries/get_current_integration.query.graphql'; export const i18n = { title: s__('AlertsIntegrations|Current integrations'), @@ -24,23 +40,36 @@ const bodyTrClass = export default { i18n, + typeSet, components: { - GlTable, + GlButtonGroup, + GlButton, GlIcon, + GlLoadingIcon, + GlModal, + GlTable, + GlSprintf, }, directives: { GlTooltip: GlTooltipDirective, + GlModal: GlModalDirective, }, + mixins: [glFeatureFlagsMixin()], props: { integrations: { type: Array, required: false, default: () => [], }, + loading: { + type: Boolean, + required: false, + default: false, + }, }, fields: [ { - key: 'activated', + key: 'active', label: __('Status'), }, { @@ -51,22 +80,56 @@ export default { key: 'type', label: __('Type'), }, + { + key: 'actions', + thClass: `gl-text-center`, + tdClass: `gl-text-center`, + label: __('Actions'), + }, ], - computed: { - tbodyTrClass() { - return { - [bodyTrClass]: this.integrations.length, - }; + apollo: { + currentIntegration: { + query: getCurrentIntegrationQuery, }, }, + data() { + return { + integrationToDelete: integrationToDeleteDefault, + currentIntegration: null, + }; + }, mounted() { - this.trackPageViews(); + const callback = entries => { + const isVisible = entries.some(entry => entry.isIntersecting); + + if (isVisible) { + this.trackPageViews(); + this.observer.disconnect(); + } + }; + + this.observer = new IntersectionObserver(callback); + this.observer.observe(this.$el); }, methods: { + tbodyTrClass(item) { + return { + [bodyTrClass]: this.integrations.length, + 'gl-bg-blue-50': (item !== null && item.id) === this.currentIntegration?.id, + }; + }, trackPageViews() { - const { category, action } = trackAlertIntergrationsViewsOptions; + const { category, action } = trackAlertIntegrationsViewsOptions; Tracking.event(category, action); }, + setIntegrationToDelete({ name, id }) { + this.integrationToDelete.id = id; + this.integrationToDelete.name = name; + }, + deleteIntegration() { + this.$emit('delete-integration', { id: this.integrationToDelete.id }); + this.integrationToDelete = { ...integrationToDeleteDefault }; + }, }, }; </script> @@ -75,15 +138,16 @@ export default { <div class="incident-management-list"> <h5 class="gl-font-lg">{{ $options.i18n.title }}</h5> <gl-table - :empty-text="$options.i18n.emptyState" + class="integration-list" :items="integrations" :fields="$options.fields" + :busy="loading" stacked="md" :tbody-tr-class="tbodyTrClass" show-empty > - <template #cell(activated)="{ item }"> - <span v-if="item.activated" data-testid="integration-activated-status"> + <template #cell(active)="{ item }"> + <span v-if="item.active" data-testid="integration-activated-status"> <gl-icon v-gl-tooltip name="check-circle-filled" @@ -104,6 +168,47 @@ export default { {{ $options.i18n.status.disabled.name }} </span> </template> + + <template #cell(actions)="{ item }"> + <gl-button-group v-if="glFeatures.httpIntegrationsList" class="gl-ml-3"> + <gl-button icon="pencil" @click="$emit('edit-integration', { id: item.id })" /> + <gl-button + v-gl-modal.deleteIntegration + :disabled="item.type === $options.typeSet.prometheus" + icon="remove" + @click="setIntegrationToDelete(item)" + /> + </gl-button-group> + </template> + + <template #table-busy> + <gl-loading-icon size="lg" color="dark" class="mt-3" /> + </template> + + <template #empty> + <div + class="gl-border-t-solid gl-border-b-solid gl-border-1 gl-border gl-border-gray-100 mt-n3 gl-px-5" + > + <p class="gl-text-gray-400 gl-py-3 gl-my-3">{{ $options.i18n.emptyState }}</p> + </div> + </template> </gl-table> + <gl-modal + modal-id="deleteIntegration" + :title="s__('AlertSettings|Delete integration')" + :ok-title="s__('AlertSettings|Delete integration')" + ok-variant="danger" + @ok="deleteIntegration" + > + <gl-sprintf + :message=" + s__( + 'AlertsIntegrations|You have opted to delete the %{integrationName} integration. Do you want to proceed? It means you will no longer receive alerts from this endpoint in your alert list, and this action cannot be undone.', + ) + " + > + <template #integrationName>{{ integrationToDelete.name }}</template> + </gl-sprintf> + </gl-modal> </div> </template> |