summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/feature_flags/components/configure_feature_flags_modal.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/feature_flags/components/configure_feature_flags_modal.vue')
-rw-r--r--app/assets/javascripts/feature_flags/components/configure_feature_flags_modal.vue254
1 files changed, 254 insertions, 0 deletions
diff --git a/app/assets/javascripts/feature_flags/components/configure_feature_flags_modal.vue b/app/assets/javascripts/feature_flags/components/configure_feature_flags_modal.vue
new file mode 100644
index 00000000000..b652cb329d7
--- /dev/null
+++ b/app/assets/javascripts/feature_flags/components/configure_feature_flags_modal.vue
@@ -0,0 +1,254 @@
+<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>