debian-mirror-gitlab/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue
2022-04-04 11:22:00 +05:30

194 lines
6 KiB
Vue

<script>
import createFlash from '~/flash';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import { visitUrl } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import MRWidgetService from '../../services/mr_widget_service';
import {
MANUAL_DEPLOY,
FAILED,
SUCCESS,
STOPPING,
DEPLOYING,
REDEPLOYING,
ACT_BUTTON_ICONS,
} from './constants';
import DeploymentActionButton from './deployment_action_button.vue';
import DeploymentViewButton from './deployment_view_button.vue';
export default {
name: 'DeploymentActions',
btnIcons: ACT_BUTTON_ICONS,
components: {
DeploymentActionButton,
DeploymentViewButton,
},
mixins: [glFeatureFlagsMixin()],
props: {
computedDeploymentStatus: {
type: String,
required: true,
},
deployment: {
type: Object,
required: true,
},
},
data() {
return {
actionInProgress: null,
constants: {
STOPPING,
DEPLOYING,
REDEPLOYING,
},
};
},
computed: {
appButtonText() {
return {
text: this.isCurrent ? s__('Review App|View app') : s__('Review App|View latest app'),
tooltip: this.isCurrent
? ''
: __('View the latest successful deployment to this environment'),
};
},
canBeManuallyDeployed() {
return this.computedDeploymentStatus === MANUAL_DEPLOY && Boolean(this.playPath);
},
canBeManuallyRedeployed() {
return this.computedDeploymentStatus === FAILED && Boolean(this.redeployPath);
},
hasExternalUrls() {
return Boolean(this.deployment.external_url && this.deployment.external_url_formatted);
},
isCurrent() {
return this.computedDeploymentStatus === SUCCESS;
},
playPath() {
return this.deployment.details?.playable_build?.play_path;
},
redeployPath() {
return this.deployment.details?.playable_build?.retry_path;
},
stopUrl() {
return this.deployment.stop_url;
},
},
actionsConfiguration: {
[STOPPING]: {
actionName: STOPPING,
buttonText: s__('MrDeploymentActions|Stop environment'),
buttonVariant: 'danger',
busyText: __('This environment is being deployed'),
confirmMessage: __('Are you sure you want to stop this environment?'),
errorMessage: __('Something went wrong while stopping this environment. Please try again.'),
},
[DEPLOYING]: {
actionName: DEPLOYING,
buttonText: s__('MrDeploymentActions|Deploy'),
buttonVariant: 'confirm',
busyText: __('This environment is being deployed'),
confirmMessage: __('Are you sure you want to deploy this environment?'),
errorMessage: __('Something went wrong while deploying this environment. Please try again.'),
},
[REDEPLOYING]: {
actionName: REDEPLOYING,
buttonText: s__('MrDeploymentActions|Re-deploy'),
buttonVariant: 'confirm',
busyText: __('This environment is being re-deployed'),
confirmMessage: __('Are you sure you want to re-deploy this environment?'),
errorMessage: __('Something went wrong while deploying this environment. Please try again.'),
},
},
methods: {
async executeAction(
endpoint,
{
actionName,
buttonText: primaryBtnText,
buttonVariant: primaryBtnVariant,
confirmMessage,
errorMessage,
},
) {
const isConfirmed = await confirmAction(confirmMessage, {
primaryBtnVariant,
primaryBtnText,
});
if (isConfirmed) {
this.actionInProgress = actionName;
MRWidgetService.executeInlineAction(endpoint)
.then((resp) => {
const redirectUrl = resp?.data?.redirect_url;
if (redirectUrl) {
visitUrl(redirectUrl);
}
})
.catch(() => {
createFlash({
message: errorMessage,
});
})
.finally(() => {
this.actionInProgress = null;
});
}
},
stopEnvironment() {
this.executeAction(this.stopUrl, this.$options.actionsConfiguration[STOPPING]);
},
deployManually() {
this.executeAction(this.playPath, this.$options.actionsConfiguration[DEPLOYING]);
},
redeploy() {
this.executeAction(this.redeployPath, this.$options.actionsConfiguration[REDEPLOYING]);
},
},
};
</script>
<template>
<div class="gl-display-inline-flex">
<deployment-action-button
v-if="canBeManuallyDeployed"
:action-in-progress="actionInProgress"
:actions-configuration="$options.actionsConfiguration[constants.DEPLOYING]"
:computed-deployment-status="computedDeploymentStatus"
:icon="$options.btnIcons.play"
container-classes="js-manual-deploy-action"
@click="deployManually"
>
<span>{{ $options.actionsConfiguration[constants.DEPLOYING].buttonText }}</span>
</deployment-action-button>
<deployment-action-button
v-if="canBeManuallyRedeployed"
:action-in-progress="actionInProgress"
:actions-configuration="$options.actionsConfiguration[constants.REDEPLOYING]"
:computed-deployment-status="computedDeploymentStatus"
:icon="$options.btnIcons.repeat"
container-classes="js-manual-redeploy-action"
@click="redeploy"
>
<span>{{ $options.actionsConfiguration[constants.REDEPLOYING].buttonText }}</span>
</deployment-action-button>
<deployment-view-button
v-if="hasExternalUrls"
:app-button-text="appButtonText"
:deployment="deployment"
/>
<deployment-action-button
v-if="stopUrl"
:action-in-progress="actionInProgress"
:computed-deployment-status="computedDeploymentStatus"
:actions-configuration="$options.actionsConfiguration[constants.STOPPING]"
:button-title="$options.actionsConfiguration[constants.STOPPING].buttonText"
:icon="$options.btnIcons.stop"
container-classes="js-stop-env"
@click="stopEnvironment"
/>
</div>
</template>