diff options
author | Enrique Alcántara <ealcantara@gitlab.com> | 2019-05-02 14:17:03 +0000 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2019-05-02 14:17:03 +0000 |
commit | bf229a6c632709ef7c69a7033eadfd74f5ddcc97 (patch) | |
tree | 876b70f0ddb0e111199a685dd53fb71adeba5552 /app/assets/javascripts/clusters/components | |
parent | d6aa8a0553e30ef2d0d303fc79515cd5cf3ba1b9 (diff) | |
download | gitlab-ce-bf229a6c632709ef7c69a7033eadfd74f5ddcc97.tar.gz |
Uninstall application confirm modal component
- Vue confirmation modal implementation
- CSS tweaks for modal default height
Diffstat (limited to 'app/assets/javascripts/clusters/components')
4 files changed, 184 insertions, 33 deletions
diff --git a/app/assets/javascripts/clusters/components/application_row.vue b/app/assets/javascripts/clusters/components/application_row.vue index a351916942e..5f7675bb432 100644 --- a/app/assets/javascripts/clusters/components/application_row.vue +++ b/app/assets/javascripts/clusters/components/application_row.vue @@ -1,12 +1,13 @@ <script> /* eslint-disable vue/require-default-prop */ -import { GlLink } from '@gitlab/ui'; +import { GlLink, GlModalDirective } from '@gitlab/ui'; import TimeagoTooltip from '../../vue_shared/components/time_ago_tooltip.vue'; import { s__, sprintf } from '../../locale'; import eventHub from '../event_hub'; import identicon from '../../vue_shared/components/identicon.vue'; import loadingButton from '../../vue_shared/components/loading_button.vue'; import UninstallApplicationButton from './uninstall_application_button.vue'; +import UninstallApplicationConfirmationModal from './uninstall_application_confirmation_modal.vue'; import { APPLICATION_STATUS } from '../constants'; @@ -17,6 +18,10 @@ export default { TimeagoTooltip, GlLink, UninstallApplicationButton, + UninstallApplicationConfirmationModal, + }, + directives: { + GlModalDirective, }, props: { id: { @@ -94,6 +99,16 @@ export default { required: false, default: false, }, + uninstallFailed: { + type: Boolean, + required: false, + default: false, + }, + uninstallSuccessful: { + type: Boolean, + required: false, + default: false, + }, updateAcknowledged: { type: Boolean, required: false, @@ -170,10 +185,21 @@ export default { manageButtonLabel() { return s__('ClusterIntegration|Manage'); }, + hasError() { + return this.installFailed || this.uninstallFailed; + }, generalErrorDescription() { - return sprintf(s__('ClusterIntegration|Something went wrong while installing %{title}'), { - title: this.title, - }); + let errorDescription; + + if (this.installFailed) { + errorDescription = s__('ClusterIntegration|Something went wrong while installing %{title}'); + } else if (this.uninstallFailed) { + errorDescription = s__( + 'ClusterIntegration|Something went wrong while uninstalling %{title}', + ); + } + + return sprintf(errorDescription, { title: this.title }); }, versionLabel() { if (this.updateFailed) { @@ -214,13 +240,23 @@ export default { // AND new upgrade is unavailable AND version information is present. return (this.updateSuccessful || this.updateFailed) && !this.upgradeAvailable && this.version; }, + uninstallSuccessDescription() { + return sprintf(s__('ClusterIntegration|%{title} uninstalled successfully.'), { + title: this.title, + }); + }, }, watch: { - updateSuccessful() { - if (this.updateSuccessful) { + updateSuccessful(updateSuccessful) { + if (updateSuccessful) { this.$toast.show(this.upgradeSuccessDescription); } }, + uninstallSuccessful(uninstallSuccessful) { + if (uninstallSuccessful) { + this.$toast.show(this.uninstallSuccessDescription); + } + }, }, methods: { installClicked() { @@ -235,6 +271,11 @@ export default { params: this.installApplicationRequestParams, }); }, + uninstallConfirmed() { + eventHub.$emit('uninstallApplication', { + id: this.id, + }); + }, }, }; </script> @@ -271,10 +312,7 @@ export default { <span v-else class="js-cluster-application-title">{{ title }}</span> </strong> <slot name="description"></slot> - <div - v-if="installFailed || isUnknownStatus" - class="cluster-application-error text-danger prepend-top-10" - > + <div v-if="hasError" class="cluster-application-error text-danger prepend-top-10"> <p class="js-cluster-application-general-error-message append-bottom-0"> {{ generalErrorDescription }} </p> @@ -325,9 +363,9 @@ export default { role="gridcell" > <div v-if="showManageButton" class="btn-group table-action-buttons"> - <a :href="manageLink" :class="{ disabled: disabled }" class="btn"> - {{ manageButtonLabel }} - </a> + <a :href="manageLink" :class="{ disabled: disabled }" class="btn">{{ + manageButtonLabel + }}</a> </div> <div class="btn-group table-action-buttons"> <loading-button @@ -340,8 +378,15 @@ export default { /> <uninstall-application-button v-if="displayUninstallButton" + v-gl-modal-directive="'uninstall-' + id" + :status="status" class="js-cluster-application-uninstall-button" /> + <uninstall-application-confirmation-modal + :application="id" + :application-title="title" + @confirm="uninstallConfirmed()" + /> </div> </div> </div> diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue index dfc2069f131..287bdbcf873 100644 --- a/app/assets/javascripts/clusters/components/applications.vue +++ b/app/assets/javascripts/clusters/components/applications.vue @@ -240,6 +240,9 @@ export default { :request-reason="applications.helm.requestReason" :installed="applications.helm.installed" :install-failed="applications.helm.installFailed" + :uninstallable="applications.helm.uninstallable" + :uninstall-successful="applications.helm.uninstallSuccessful" + :uninstall-failed="applications.helm.uninstallFailed" class="rounded-top" title-link="https://docs.helm.sh/" > @@ -269,6 +272,9 @@ export default { :request-reason="applications.ingress.requestReason" :installed="applications.ingress.installed" :install-failed="applications.ingress.installFailed" + :uninstallable="applications.ingress.uninstallable" + :uninstall-successful="applications.ingress.uninstallSuccessful" + :uninstall-failed="applications.ingress.uninstallFailed" :disabled="!helmInstalled" title-link="https://kubernetes.io/docs/concepts/services-networking/ingress/" > @@ -312,9 +318,9 @@ export default { generated endpoint in order to access your application after it has been deployed.`) }} - <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer"> - {{ __('More information') }} - </a> + <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">{{ + __('More information') + }}</a> </p> </div> @@ -324,9 +330,9 @@ export default { the process of being assigned. Please check your Kubernetes cluster or Quotas on Google Kubernetes Engine if it takes a long time.`) }} - <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer"> - {{ __('More information') }} - </a> + <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">{{ + __('More information') + }}</a> </p> </template> <template v-if="!ingressInstalled"> @@ -345,6 +351,9 @@ export default { :installed="applications.cert_manager.installed" :install-failed="applications.cert_manager.installFailed" :install-application-request-params="{ email: applications.cert_manager.email }" + :uninstallable="applications.cert_manager.uninstallable" + :uninstall-successful="applications.cert_manager.uninstallSuccessful" + :uninstall-failed="applications.cert_manager.uninstallFailed" :disabled="!helmInstalled" title-link="https://cert-manager.readthedocs.io/en/latest/#" > @@ -352,9 +361,9 @@ export default { <div slot="description"> <p v-html="certManagerDescription"></p> <div class="form-group"> - <label for="cert-manager-issuer-email"> - {{ s__('ClusterIntegration|Issuer Email') }} - </label> + <label for="cert-manager-issuer-email">{{ + s__('ClusterIntegration|Issuer Email') + }}</label> <div class="input-group"> <input v-model="applications.cert_manager.email" @@ -391,6 +400,9 @@ export default { :request-reason="applications.prometheus.requestReason" :installed="applications.prometheus.installed" :install-failed="applications.prometheus.installFailed" + :uninstallable="applications.prometheus.uninstallable" + :uninstall-successful="applications.prometheus.uninstallSuccessful" + :uninstall-failed="applications.prometheus.uninstallFailed" :disabled="!helmInstalled" title-link="https://prometheus.io/docs/introduction/overview/" > @@ -411,6 +423,9 @@ export default { :install-failed="applications.runner.installFailed" :update-successful="applications.runner.updateSuccessful" :update-failed="applications.runner.updateFailed" + :uninstallable="applications.runner.uninstallable" + :uninstall-successful="applications.runner.uninstallSuccessful" + :uninstall-failed="applications.runner.uninstallFailed" :disabled="!helmInstalled" title-link="https://docs.gitlab.com/runner/" > @@ -434,6 +449,9 @@ export default { :request-reason="applications.jupyter.requestReason" :installed="applications.jupyter.installed" :install-failed="applications.jupyter.installFailed" + :uninstallable="applications.jupyter.uninstallable" + :uninstall-successful="applications.jupyter.uninstallSuccessful" + :uninstall-failed="applications.jupyter.uninstallFailed" :install-application-request-params="{ hostname: applications.jupyter.hostname }" :disabled="!helmInstalled" title-link="https://jupyterhub.readthedocs.io/en/stable/" @@ -474,9 +492,9 @@ export default { s__(`ClusterIntegration|Replace this with your own hostname if you want. If you do so, point hostname to Ingress IP Address from above.`) }} - <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer"> - {{ __('More information') }} - </a> + <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">{{ + __('More information') + }}</a> </p> </div> </template> @@ -494,6 +512,9 @@ export default { :installed="applications.knative.installed" :install-failed="applications.knative.installFailed" :install-application-request-params="{ hostname: applications.knative.hostname }" + :uninstallable="applications.knative.uninstallable" + :uninstall-successful="applications.knative.uninstallSuccessful" + :uninstall-failed="applications.knative.uninstallFailed" :disabled="!helmInstalled" v-bind="applications.knative" title-link="https://github.com/knative/docs" @@ -505,9 +526,9 @@ export default { s__(`ClusterIntegration|You must have an RBAC-enabled cluster to install Knative.`) }} - <a :href="helpPath" target="_blank" rel="noopener noreferrer"> - {{ __('More information') }} - </a> + <a :href="helpPath" target="_blank" rel="noopener noreferrer">{{ + __('More information') + }}</a> </p> <br /> </span> @@ -572,9 +593,9 @@ export default { `ClusterIntegration|To access your application after deployment, point a wildcard DNS to the Knative Endpoint.`, ) }} - <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer"> - {{ __('More information') }} - </a> + <a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">{{ + __('More information') + }}</a> </p> <p diff --git a/app/assets/javascripts/clusters/components/uninstall_application_button.vue b/app/assets/javascripts/clusters/components/uninstall_application_button.vue index 30918d1d115..ef4bcbe14dd 100644 --- a/app/assets/javascripts/clusters/components/uninstall_application_button.vue +++ b/app/assets/javascripts/clusters/components/uninstall_application_button.vue @@ -1,14 +1,33 @@ <script> -// TODO: Implement loading button component import LoadingButton from '~/vue_shared/components/loading_button.vue'; +import { APPLICATION_STATUS } from '~/clusters/constants'; + +const { UPDATING, UNINSTALLING } = APPLICATION_STATUS; export default { components: { LoadingButton, }, + props: { + status: { + type: String, + required: true, + }, + }, + computed: { + disabled() { + return [UNINSTALLING, UPDATING].includes(this.status); + }, + loading() { + return this.status === UNINSTALLING; + }, + label() { + return this.loading ? this.__('Uninstalling') : this.__('Uninstall'); + }, + }, }; </script> <template> - <loading-button @click="$emit('click')" /> + <loading-button :label="label" :disabled="disabled" :loading="loading" /> </template> diff --git a/app/assets/javascripts/clusters/components/uninstall_application_confirmation_modal.vue b/app/assets/javascripts/clusters/components/uninstall_application_confirmation_modal.vue new file mode 100644 index 00000000000..80ba2f22198 --- /dev/null +++ b/app/assets/javascripts/clusters/components/uninstall_application_confirmation_modal.vue @@ -0,0 +1,66 @@ +<script> +import { GlModal } from '@gitlab/ui'; +import { sprintf, s__ } from '~/locale'; +import { INGRESS, CERT_MANAGER, PROMETHEUS, RUNNER, KNATIVE, JUPYTER } from '../constants'; + +const CUSTOM_APP_WARNING_TEXT = { + [INGRESS]: s__( + 'ClusterIntegration|The associated load balancer and IP will be deleted and cannot be restored.', + ), + [CERT_MANAGER]: s__( + 'ClusterIntegration|The associated certifcate will be deleted and cannot be restored.', + ), + [PROMETHEUS]: s__('ClusterIntegration|All data will be deleted and cannot be restored.'), + [RUNNER]: s__('ClusterIntegration|Any running pipelines will be canceled.'), + [KNATIVE]: s__('ClusterIntegration|The associated IP will be deleted and cannot be restored.'), + [JUPYTER]: '', +}; + +export default { + components: { + GlModal, + }, + props: { + application: { + type: String, + required: true, + }, + applicationTitle: { + type: String, + required: true, + }, + }, + computed: { + title() { + return sprintf(s__('ClusterIntegration|Uninstall %{appTitle}'), { + appTitle: this.applicationTitle, + }); + }, + warningText() { + return sprintf( + s__('ClusterIntegration|You are about to uninstall %{appTitle} from your cluster.'), + { + appTitle: this.applicationTitle, + }, + ); + }, + customAppWarningText() { + return CUSTOM_APP_WARNING_TEXT[this.application]; + }, + modalId() { + return `uninstall-${this.application}`; + }, + }, +}; +</script> +<template> + <gl-modal + ok-variant="danger" + cancel-variant="light" + :ok-title="title" + :modal-id="modalId" + :title="title" + @ok="$emit('confirm')" + >{{ warningText }} {{ customAppWarningText }}</gl-modal + > +</template> |