diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-04 12:09:00 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-04 12:09:00 +0000 |
commit | 88a0824944720b6edaaef56376713541b9a02118 (patch) | |
tree | f5fcc4f9755f249779cda9a8f02902d734af6e7e /app/assets/javascripts/registry | |
parent | 7d19df2d34a9803d9f077c16315ba919b7ae2aa2 (diff) | |
download | gitlab-ce-88a0824944720b6edaaef56376713541b9a02118.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/registry')
3 files changed, 248 insertions, 257 deletions
diff --git a/app/assets/javascripts/registry/settings/components/settings_form.vue b/app/assets/javascripts/registry/settings/components/settings_form.vue index ad2fdb4fd40..cab3c7fff85 100644 --- a/app/assets/javascripts/registry/settings/components/settings_form.vue +++ b/app/assets/javascripts/registry/settings/components/settings_form.vue @@ -1,16 +1,20 @@ <script> import { mapActions, mapState, mapGetters } from 'vuex'; +import { GlCard, GlButton, GlLoadingIcon } from '@gitlab/ui'; import Tracking from '~/tracking'; import { UPDATE_SETTINGS_ERROR_MESSAGE, UPDATE_SETTINGS_SUCCESS_MESSAGE, } from '../../shared/constants'; import { mapComputed } from '~/vuex_shared/bindings'; -import ExpirationPolicyForm from '../../shared/components/expiration_policy_form.vue'; +import ExpirationPolicyFields from '../../shared/components/expiration_policy_fields.vue'; export default { components: { - ExpirationPolicyForm, + GlCard, + GlButton, + GlLoadingIcon, + ExpirationPolicyFields, }, mixins: [Tracking.mixin()], labelsConfig: { @@ -22,12 +26,19 @@ export default { tracking: { label: 'docker_container_retention_and_expiration_policies', }, + formIsValid: true, }; }, computed: { ...mapState(['formOptions', 'isLoading']), ...mapGetters({ isEdited: 'getIsEdited' }), ...mapComputed([{ key: 'settings', getter: 'getSettings' }], 'updateSettings'), + isSubmitButtonDisabled() { + return !this.formIsValid || this.isLoading; + }, + isCancelButtonDisabled() { + return !this.isEdited || this.isLoading; + }, }, methods: { ...mapActions(['resetSettings', 'saveSettings']), @@ -46,12 +57,42 @@ export default { </script> <template> - <expiration-policy-form - v-model="settings" - :form-options="formOptions" - :is-loading="isLoading" - :disable-cancel-button="!isEdited" - @submit="submit" - @reset="reset" - /> + <form ref="form-element" @submit.prevent="submit" @reset.prevent="reset"> + <gl-card> + <template #header> + {{ s__('ContainerRegistry|Tag expiration policy') }} + </template> + <template #default> + <expiration-policy-fields + v-model="settings" + :form-options="formOptions" + :is-loading="isLoading" + @validated="formIsValid = true" + @invalidated="formIsValid = false" + /> + </template> + <template #footer> + <div class="d-flex justify-content-end"> + <gl-button + ref="cancel-button" + type="reset" + class="mr-2 d-block" + :disabled="isCancelButtonDisabled" + > + {{ __('Cancel') }} + </gl-button> + <gl-button + ref="save-button" + type="submit" + :disabled="isSubmitButtonDisabled" + variant="success" + class="d-flex justify-content-center align-items-center js-no-auto-disable" + > + {{ __('Save expiration policy') }} + <gl-loading-icon v-if="isLoading" class="ml-2" /> + </gl-button> + </div> + </template> + </gl-card> + </form> </template> diff --git a/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue b/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue new file mode 100644 index 00000000000..84d1c5ccc6a --- /dev/null +++ b/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue @@ -0,0 +1,197 @@ +<script> +import { uniqueId } from 'lodash'; +import { GlFormGroup, GlToggle, GlFormSelect, GlFormTextarea } from '@gitlab/ui'; +import { s__, __, sprintf } from '~/locale'; +import { NAME_REGEX_LENGTH } from '../constants'; +import { mapComputedToEvent } from '../utils'; + +export default { + components: { + GlFormGroup, + GlToggle, + GlFormSelect, + GlFormTextarea, + }, + props: { + formOptions: { + type: Object, + required: false, + default: () => ({}), + }, + isLoading: { + type: Boolean, + required: false, + default: false, + }, + value: { + type: Object, + required: false, + default: () => ({}), + }, + labelCols: { + type: [Number, String], + required: false, + default: 3, + }, + labelAlign: { + type: String, + required: false, + default: 'right', + }, + }, + nameRegexPlaceholder: '.*', + selectList: [ + { + name: 'expiration-policy-interval', + label: s__('ContainerRegistry|Expiration interval:'), + model: 'older_than', + optionKey: 'olderThan', + }, + { + name: 'expiration-policy-schedule', + label: s__('ContainerRegistry|Expiration schedule:'), + model: 'cadence', + optionKey: 'cadence', + }, + { + name: 'expiration-policy-latest', + label: s__('ContainerRegistry|Number of tags to retain:'), + model: 'keep_n', + optionKey: 'keepN', + }, + ], + data() { + return { + uniqueId: uniqueId(), + }; + }, + computed: { + ...mapComputedToEvent(['enabled', 'cadence', 'older_than', 'keep_n', 'name_regex'], 'value'), + policyEnabledText() { + return this.enabled ? __('enabled') : __('disabled'); + }, + toggleDescriptionText() { + return sprintf( + s__('ContainerRegistry|Docker tag expiration policy is %{toggleStatus}'), + { + toggleStatus: `<strong>${this.policyEnabledText}</strong>`, + }, + false, + ); + }, + regexHelpText() { + return sprintf( + s__( + 'ContainerRegistry|Wildcards such as %{codeStart}*-stable%{codeEnd} or %{codeStart}production/*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}', + ), + { + codeStart: '<code>', + codeEnd: '</code>', + }, + false, + ); + }, + nameRegexState() { + return this.name_regex ? this.name_regex.length <= NAME_REGEX_LENGTH : null; + }, + fieldsValidity() { + return this.nameRegexState !== false; + }, + isFormElementDisabled() { + return !this.enabled || this.isLoading; + }, + }, + watch: { + fieldsValidity: { + immediate: true, + handler(valid) { + if (valid) { + this.$emit('validated'); + } else { + this.$emit('invalidated'); + } + }, + }, + }, + methods: { + idGenerator(id) { + return `${id}_${this.uniqueId}`; + }, + updateModel(value, key) { + this[key] = value; + }, + }, +}; +</script> + +<template> + <div ref="form-elements" class="lh-2"> + <gl-form-group + :id="idGenerator('expiration-policy-toggle-group')" + :label-cols="labelCols" + :label-align="labelAlign" + :label-for="idGenerator('expiration-policy-toggle')" + :label="s__('ContainerRegistry|Expiration policy:')" + > + <div class="d-flex align-items-start"> + <gl-toggle + :id="idGenerator('expiration-policy-toggle')" + v-model="enabled" + :disabled="isLoading" + /> + <span class="mb-2 ml-1 lh-2" v-html="toggleDescriptionText"></span> + </div> + </gl-form-group> + + <gl-form-group + v-for="select in $options.selectList" + :id="idGenerator(`${select.name}-group`)" + :key="select.name" + :label-cols="labelCols" + :label-align="labelAlign" + :label-for="idGenerator(select.name)" + :label="select.label" + > + <gl-form-select + :id="idGenerator(select.name)" + :value="value[select.model]" + :disabled="isFormElementDisabled" + @input="updateModel($event, select.model)" + > + <option + v-for="option in formOptions[select.optionKey]" + :key="option.key" + :value="option.key" + > + {{ option.label }} + </option> + </gl-form-select> + </gl-form-group> + + <gl-form-group + :id="idGenerator('expiration-policy-name-matching-group')" + :label-cols="labelCols" + :label-align="labelAlign" + :label-for="idGenerator('expiration-policy-name-matching')" + :label=" + s__('ContainerRegistry|Docker tags with names matching this regex pattern will expire:') + " + :state="nameRegexState" + :invalid-feedback=" + s__('ContainerRegistry|The value of this input should be less than 255 characters') + " + > + <gl-form-textarea + :id="idGenerator('expiration-policy-name-matching')" + v-model="name_regex" + :placeholder="$options.nameRegexPlaceholder" + :state="nameRegexState" + :disabled="isFormElementDisabled" + trim + /> + <template #description> + <span ref="regex-description" v-html="regexHelpText"></span> + </template> + </gl-form-group> + </div> +</template> diff --git a/app/assets/javascripts/registry/shared/components/expiration_policy_form.vue b/app/assets/javascripts/registry/shared/components/expiration_policy_form.vue deleted file mode 100644 index c044add3759..00000000000 --- a/app/assets/javascripts/registry/shared/components/expiration_policy_form.vue +++ /dev/null @@ -1,247 +0,0 @@ -<script> -import { uniqueId } from 'lodash'; -import { - GlFormGroup, - GlToggle, - GlFormSelect, - GlFormTextarea, - GlButton, - GlCard, - GlLoadingIcon, -} from '@gitlab/ui'; -import { s__, __, sprintf } from '~/locale'; -import { NAME_REGEX_LENGTH } from '../constants'; -import { mapComputedToEvent } from '../utils'; - -export default { - components: { - GlFormGroup, - GlToggle, - GlFormSelect, - GlFormTextarea, - GlButton, - GlCard, - GlLoadingIcon, - }, - props: { - formOptions: { - type: Object, - required: false, - default: () => ({}), - }, - isLoading: { - type: Boolean, - required: false, - default: false, - }, - value: { - type: Object, - required: false, - default: () => ({}), - }, - labelCols: { - type: [Number, String], - required: false, - default: 3, - }, - labelAlign: { - type: String, - required: false, - default: 'right', - }, - disableCancelButton: { - type: Boolean, - required: false, - default: false, - }, - }, - nameRegexPlaceholder: '.*', - data() { - return { - uniqueId: uniqueId(), - }; - }, - computed: { - ...mapComputedToEvent(['enabled', 'cadence', 'older_than', 'keep_n', 'name_regex'], 'value'), - policyEnabledText() { - return this.enabled ? __('enabled') : __('disabled'); - }, - toggleDescriptionText() { - return sprintf( - s__('ContainerRegistry|Docker tag expiration policy is %{toggleStatus}'), - { - toggleStatus: `<strong>${this.policyEnabledText}</strong>`, - }, - false, - ); - }, - regexHelpText() { - return sprintf( - s__( - 'ContainerRegistry|Wildcards such as %{codeStart}*-stable%{codeEnd} or %{codeStart}production/*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}', - ), - { - codeStart: '<code>', - codeEnd: '</code>', - }, - false, - ); - }, - nameRegexState() { - return this.name_regex ? this.name_regex.length <= NAME_REGEX_LENGTH : null; - }, - formIsInvalid() { - return this.nameRegexState === false; - }, - isFormElementDisabled() { - return !this.enabled || this.isLoading; - }, - isSubmitButtonDisabled() { - return this.formIsInvalid || this.isLoading; - }, - isCancelButtonDisabled() { - return this.disableCancelButton || this.isLoading; - }, - }, - methods: { - idGenerator(id) { - return `${id}_${this.uniqueId}`; - }, - }, -}; -</script> - -<template> - <form - ref="form-element" - class="lh-2" - @submit.prevent="$emit('submit')" - @reset.prevent="$emit('reset')" - > - <gl-card> - <template #header> - {{ s__('ContainerRegistry|Tag expiration policy') }} - </template> - <template> - <gl-form-group - :id="idGenerator('expiration-policy-toggle-group')" - :label-cols="labelCols" - :label-align="labelAlign" - :label-for="idGenerator('expiration-policy-toggle')" - :label="s__('ContainerRegistry|Expiration policy:')" - > - <div class="d-flex align-items-start"> - <gl-toggle - :id="idGenerator('expiration-policy-toggle')" - v-model="enabled" - :disabled="isLoading" - /> - <span class="mb-2 ml-1 lh-2" v-html="toggleDescriptionText"></span> - </div> - </gl-form-group> - - <gl-form-group - :id="idGenerator('expiration-policy-interval-group')" - :label-cols="labelCols" - :label-align="labelAlign" - :label-for="idGenerator('expiration-policy-interval')" - :label="s__('ContainerRegistry|Expiration interval:')" - > - <gl-form-select - :id="idGenerator('expiration-policy-interval')" - v-model="older_than" - :disabled="isFormElementDisabled" - > - <option v-for="option in formOptions.olderThan" :key="option.key" :value="option.key"> - {{ option.label }} - </option> - </gl-form-select> - </gl-form-group> - - <gl-form-group - :id="idGenerator('expiration-policy-schedule-group')" - :label-cols="labelCols" - :label-align="labelAlign" - :label-for="idGenerator('expiration-policy-schedule')" - :label="s__('ContainerRegistry|Expiration schedule:')" - > - <gl-form-select - :id="idGenerator('expiration-policy-schedule')" - v-model="cadence" - :disabled="isFormElementDisabled" - > - <option v-for="option in formOptions.cadence" :key="option.key" :value="option.key"> - {{ option.label }} - </option> - </gl-form-select> - </gl-form-group> - - <gl-form-group - :id="idGenerator('expiration-policy-latest-group')" - :label-cols="labelCols" - :label-align="labelAlign" - :label-for="idGenerator('expiration-policy-latest')" - :label="s__('ContainerRegistry|Number of tags to retain:')" - > - <gl-form-select - :id="idGenerator('expiration-policy-latest')" - v-model="keep_n" - :disabled="isFormElementDisabled" - > - <option v-for="option in formOptions.keepN" :key="option.key" :value="option.key"> - {{ option.label }} - </option> - </gl-form-select> - </gl-form-group> - - <gl-form-group - :id="idGenerator('expiration-policy-name-matching-group')" - :label-cols="labelCols" - :label-align="labelAlign" - :label-for="idGenerator('expiration-policy-name-matching')" - :label=" - s__('ContainerRegistry|Docker tags with names matching this regex pattern will expire:') - " - :state="nameRegexState" - :invalid-feedback=" - s__('ContainerRegistry|The value of this input should be less than 255 characters') - " - > - <gl-form-textarea - :id="idGenerator('expiration-policy-name-matching')" - v-model="name_regex" - :placeholder="$options.nameRegexPlaceholder" - :state="nameRegexState" - :disabled="isFormElementDisabled" - trim - /> - <template #description> - <span ref="regex-description" v-html="regexHelpText"></span> - </template> - </gl-form-group> - </template> - <template #footer> - <div class="d-flex justify-content-end"> - <gl-button - ref="cancel-button" - type="reset" - class="mr-2 d-block" - :disabled="isCancelButtonDisabled" - > - {{ __('Cancel') }} - </gl-button> - <gl-button - ref="save-button" - type="submit" - :disabled="isSubmitButtonDisabled" - variant="success" - class="d-flex justify-content-center align-items-center js-no-auto-disable" - > - {{ __('Save expiration policy') }} - <gl-loading-icon v-if="isLoading" class="ml-2" /> - </gl-button> - </div> - </template> - </gl-card> - </form> -</template> |