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:
Diffstat (limited to 'app/assets/javascripts/ci/runner/components/runner_bulk_delete.vue')
-rw-r--r--app/assets/javascripts/ci/runner/components/runner_bulk_delete.vue199
1 files changed, 199 insertions, 0 deletions
diff --git a/app/assets/javascripts/ci/runner/components/runner_bulk_delete.vue b/app/assets/javascripts/ci/runner/components/runner_bulk_delete.vue
new file mode 100644
index 00000000000..1ec3f8da7c3
--- /dev/null
+++ b/app/assets/javascripts/ci/runner/components/runner_bulk_delete.vue
@@ -0,0 +1,199 @@
+<script>
+import { GlButton, GlModalDirective, GlModal, GlSprintf } from '@gitlab/ui';
+import { createAlert } from '~/flash';
+import { __, s__, n__, sprintf } from '~/locale';
+import checkedRunnerIdsQuery from '../graphql/list/checked_runner_ids.query.graphql';
+import BulkRunnerDelete from '../graphql/list/bulk_runner_delete.mutation.graphql';
+import { RUNNER_TYPENAME } from '../constants';
+
+export default {
+ components: {
+ GlButton,
+ GlModal,
+ GlSprintf,
+ },
+ directives: {
+ GlModal: GlModalDirective,
+ },
+ inject: ['localMutations'],
+ props: {
+ runners: {
+ type: Array,
+ default: () => [],
+ required: false,
+ },
+ },
+ data() {
+ return {
+ isDeleting: false,
+ checkedRunnerIds: [],
+ };
+ },
+ apollo: {
+ checkedRunnerIds: {
+ query: checkedRunnerIdsQuery,
+ },
+ },
+ computed: {
+ currentCheckedRunnerIds() {
+ return this.runners
+ .map(({ id }) => id)
+ .filter((id) => this.checkedRunnerIds.indexOf(id) >= 0);
+ },
+ checkedCount() {
+ return this.currentCheckedRunnerIds.length || 0;
+ },
+ bannerMessage() {
+ return sprintf(
+ n__(
+ 'Runners|%{strongStart}%{count}%{strongEnd} runner selected',
+ 'Runners|%{strongStart}%{count}%{strongEnd} runners selected',
+ this.checkedCount,
+ ),
+ {
+ count: this.checkedCount,
+ },
+ );
+ },
+ modalTitle() {
+ return n__('Runners|Delete %d runner', 'Runners|Delete %d runners', this.checkedCount);
+ },
+ modalActionPrimary() {
+ return {
+ text: n__(
+ 'Runners|Permanently delete %d runner',
+ 'Runners|Permanently delete %d runners',
+ this.checkedCount,
+ ),
+ attributes: {
+ loading: this.isDeleting,
+ variant: 'danger',
+ },
+ };
+ },
+ modalActionCancel() {
+ return {
+ text: __('Cancel'),
+ attributes: {
+ loading: this.isDeleting,
+ },
+ };
+ },
+ modalMessage() {
+ return sprintf(
+ n__(
+ 'Runners|%{strongStart}%{count}%{strongEnd} runner will be permanently deleted and no longer available for projects or groups in the instance. Are you sure you want to continue?',
+ 'Runners|%{strongStart}%{count}%{strongEnd} runners will be permanently deleted and no longer available for projects or groups in the instance. Are you sure you want to continue?',
+ this.checkedCount,
+ ),
+ { count: this.checkedCount },
+ );
+ },
+ },
+ methods: {
+ toastConfirmationMessage(deletedCount) {
+ return n__(
+ 'Runners|%d selected runner deleted',
+ 'Runners|%d selected runners deleted',
+ deletedCount,
+ );
+ },
+ onClearChecked() {
+ this.localMutations.clearChecked();
+ },
+ async onConfirmDelete(e) {
+ this.isDeleting = true;
+ e.preventDefault(); // don't close modal until deletion is complete
+
+ try {
+ await this.$apollo.mutate({
+ mutation: BulkRunnerDelete,
+ variables: {
+ input: {
+ ids: this.currentCheckedRunnerIds,
+ },
+ },
+ update: (cache, { data }) => {
+ const { errors, deletedIds } = data.bulkRunnerDelete;
+
+ if (errors?.length) {
+ createAlert({
+ message: s__(
+ 'Runners|An error occurred while deleting. Some runners may not have been deleted.',
+ ),
+ captureError: true,
+ error: new Error(errors.join(' ')),
+ });
+ }
+
+ if (deletedIds?.length) {
+ this.$emit('deleted', {
+ message: this.toastConfirmationMessage(deletedIds.length),
+ });
+
+ // Remove deleted runners from the cache
+ deletedIds.forEach((id) => {
+ const cacheId = cache.identify({ __typename: RUNNER_TYPENAME, id });
+ cache.evict({ id: cacheId });
+ });
+ cache.gc();
+ }
+ },
+ });
+ } catch (error) {
+ this.onError(error);
+ } finally {
+ this.isDeleting = false;
+ this.$refs.modal.hide();
+ }
+ },
+ onError(error) {
+ createAlert({
+ message: s__(
+ 'Runners|Something went wrong while deleting. Please refresh the page to try again.',
+ ),
+ captureError: true,
+ error,
+ });
+ },
+ },
+ BULK_DELETE_MODAL_ID: 'bulk-delete-modal',
+};
+</script>
+
+<template>
+ <div v-if="checkedCount" class="gl-my-4 gl-p-4 gl-border-1 gl-border-solid gl-border-gray-100">
+ <div class="gl-display-flex gl-align-items-center">
+ <div>
+ <gl-sprintf :message="bannerMessage">
+ <template #strong="{ content }">
+ <strong>{{ content }}</strong>
+ </template>
+ </gl-sprintf>
+ </div>
+ <div class="gl-ml-auto">
+ <gl-button variant="default" @click="onClearChecked">{{
+ s__('Runners|Clear selection')
+ }}</gl-button>
+ <gl-button v-gl-modal="$options.BULK_DELETE_MODAL_ID" variant="danger">{{
+ s__('Runners|Delete selected')
+ }}</gl-button>
+ </div>
+ </div>
+ <gl-modal
+ ref="modal"
+ size="sm"
+ :modal-id="$options.BULK_DELETE_MODAL_ID"
+ :title="modalTitle"
+ :action-primary="modalActionPrimary"
+ :action-cancel="modalActionCancel"
+ @primary="onConfirmDelete"
+ >
+ <gl-sprintf :message="modalMessage">
+ <template #strong="{ content }">
+ <strong>{{ content }}</strong>
+ </template>
+ </gl-sprintf>
+ </gl-modal>
+ </div>
+</template>