gitlab-org--gitlab-foss/app/assets/javascripts/feature_flags/components/configure_feature_flags_mod...

255 lines
6.7 KiB
Vue
Raw Normal View History

<script>
import {
GlFormGroup,
GlFormInput,
GlModal,
GlTooltipDirective,
GlLoadingIcon,
GlSprintf,
GlLink,
GlIcon,
} from '@gitlab/ui';
import { s__, __ } from '~/locale';
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
import Callout from '~/vue_shared/components/callout.vue';
export default {
cancelActionLabel: __('Close'),
modalTitle: s__('FeatureFlags|Configure feature flags'),
apiUrlLabelText: s__('FeatureFlags|API URL'),
apiUrlCopyText: __('Copy URL'),
instanceIdLabelText: s__('FeatureFlags|Instance ID'),
instanceIdCopyText: __('Copy ID'),
instanceIdRegenerateError: __('Unable to generate new instance ID'),
instanceIdRegenerateText: __(
'Regenerating the instance ID can break integration depending on the client you are using.',
),
instanceIdRegenerateActionLabel: __('Regenerate instance ID'),
components: {
GlFormGroup,
GlFormInput,
GlModal,
ModalCopyButton,
GlIcon,
Callout,
GlLoadingIcon,
GlSprintf,
GlLink,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
helpClientLibrariesPath: {
type: String,
required: true,
},
helpClientExamplePath: {
type: String,
required: true,
},
apiUrl: {
type: String,
required: true,
},
instanceId: {
type: String,
required: true,
},
modalId: {
type: String,
required: false,
default: 'configure-feature-flags',
},
isRotating: {
type: Boolean,
required: true,
},
hasRotateError: {
type: Boolean,
required: true,
},
canUserRotateToken: {
type: Boolean,
required: true,
},
},
inject: ['projectName', 'featureFlagsHelpPagePath'],
data() {
return {
enteredProjectName: '',
};
},
computed: {
cancelActionProps() {
return {
text: this.$options.cancelActionLabel,
};
},
canRegenerateInstanceId() {
return this.canUserRotateToken && this.enteredProjectName === this.projectName;
},
regenerateInstanceIdActionProps() {
return this.canUserRotateToken
? {
text: this.$options.instanceIdRegenerateActionLabel,
attributes: [
{
category: 'secondary',
disabled: !this.canRegenerateInstanceId,
loading: this.isRotating,
variant: 'danger',
},
],
}
: null;
},
},
methods: {
clearState() {
this.enteredProjectName = '';
},
rotateToken() {
this.$emit('token');
this.clearState();
},
},
};
</script>
<template>
<gl-modal
:modal-id="modalId"
:action-cancel="cancelActionProps"
:action-primary="regenerateInstanceIdActionProps"
@canceled="clearState"
@hide="clearState"
@primary.prevent="rotateToken"
>
<template #modal-title>
{{ $options.modalTitle }}
</template>
<p>
<gl-sprintf
:message="
s__(
'FeatureFlags|Install a %{docsLinkAnchoredStart}compatible client library%{docsLinkAnchoredEnd} and specify the API URL, application name, and instance ID during the configuration setup. %{docsLinkStart}More Information%{docsLinkEnd}',
)
"
>
<template #docsLinkAnchored="{ content }">
<gl-link :href="helpClientLibrariesPath" target="_blank" data-testid="help-client-link">
{{ content }}
</gl-link>
</template>
<template #docsLink="{ content }">
<gl-link :href="featureFlagsHelpPagePath" target="_blank" data-testid="help-link">{{
content
}}</gl-link>
</template>
</gl-sprintf>
</p>
<callout category="warning">
<gl-sprintf
:message="
s__(
'FeatureFlags|Set the Unleash client application name to the name of the environment your application runs in. This value is used to match environment scopes. See the %{linkStart}example client configuration%{linkEnd}.',
)
"
>
<template #link="{ content }">
<gl-link :href="helpClientExamplePath" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</callout>
<div class="form-group">
<label for="api_url" class="label-bold">{{ $options.apiUrlLabelText }}</label>
<div class="input-group">
<input
id="api_url"
:value="apiUrl"
readonly
class="form-control"
type="text"
name="api_url"
/>
<span class="input-group-append">
<modal-copy-button
:text="apiUrl"
:title="$options.apiUrlCopyText"
:modal-id="modalId"
class="input-group-text"
/>
</span>
</div>
</div>
<div class="form-group">
<label for="instance_id" class="label-bold">{{ $options.instanceIdLabelText }}</label>
<div class="input-group">
<input
id="instance_id"
:value="instanceId"
class="form-control"
type="text"
name="instance_id"
readonly
:disabled="isRotating"
/>
<gl-loading-icon
v-if="isRotating"
class="position-absolute align-self-center instance-id-loading-icon"
/>
<div class="input-group-append">
<modal-copy-button
:text="instanceId"
:title="$options.instanceIdCopyText"
:modal-id="modalId"
:disabled="isRotating"
class="input-group-text"
/>
</div>
</div>
</div>
<div
v-if="hasRotateError"
class="text-danger d-flex align-items-center font-weight-normal mb-2"
>
<gl-icon name="warning" class="mr-1" />
<span>{{ $options.instanceIdRegenerateError }}</span>
</div>
<callout
v-if="canUserRotateToken"
category="danger"
:message="$options.instanceIdRegenerateText"
/>
<p v-if="canUserRotateToken" data-testid="prevent-accident-text">
<gl-sprintf
:message="
s__(
'FeatureFlags|To prevent accidental actions we ask you to confirm your intention. Please type %{projectName} to proceed or close this modal to cancel.',
)
"
>
<template #projectName>
<span class="gl-font-weight-bold gl-text-red-500">{{ projectName }}</span>
</template>
</gl-sprintf>
</p>
<gl-form-group>
<gl-form-input
v-if="canUserRotateToken"
id="project_name_verification"
v-model="enteredProjectName"
name="project_name"
type="text"
:disabled="isRotating"
/>
</gl-form-group>
</gl-modal>
</template>