-
+
-import { GlButton, GlIcon, GlAvatar } from '@gitlab/ui';
-import { __ } from '~/locale';
+import { GlButton, GlIcon, GlAvatar, GlTooltipDirective } from '@gitlab/ui';
+import { sprintf, s__ } from '~/locale';
export default {
name: 'ExclusionsListItem',
@@ -9,13 +9,22 @@ export default {
GlAvatar,
GlIcon,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
props: {
exclusion: {
type: Object,
required: true,
},
},
- i18n: { remove: __('Remove') },
+ computed: {
+ deleteButtonLabel() {
+ return sprintf(s__('Integrations|Remove exclusion for %{name}'), {
+ name: this.exclusion.name,
+ });
+ },
+ },
};
@@ -37,8 +46,9 @@ export default {
$emit('remove')"
/>
diff --git a/app/assets/javascripts/lib/utils/regexp.js b/app/assets/javascripts/lib/utils/regexp.js
index da9bbf49e0e..240b871be18 100644
--- a/app/assets/javascripts/lib/utils/regexp.js
+++ b/app/assets/javascripts/lib/utils/regexp.js
@@ -9,3 +9,5 @@ export const unicodeLetters =
export const semverRegex =
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
+
+export const noSpacesRegex = /^\S+$/;
diff --git a/app/assets/javascripts/ml/model_registry/components/model_create.vue b/app/assets/javascripts/ml/model_registry/components/model_create.vue
index 91ecbf193b7..98ce51d3925 100644
--- a/app/assets/javascripts/ml/model_registry/components/model_create.vue
+++ b/app/assets/javascripts/ml/model_registry/components/model_create.vue
@@ -12,6 +12,7 @@ import {
import { __, s__ } from '~/locale';
import { visitUrl } from '~/lib/utils/url_utility';
import * as Sentry from '~/sentry/sentry_browser_wrapper';
+import { semverRegex, noSpacesRegex } from '~/lib/utils/regexp';
import { uploadModel } from '../services/upload_model';
import createModelVersionMutation from '../graphql/mutations/create_model_version.mutation.graphql';
import createModelMutation from '../graphql/mutations/create_model.mutation.graphql';
@@ -49,6 +50,36 @@ export default {
showImportArtifactZone() {
return this.version && this.name;
},
+ modelNameIsValid() {
+ return this.name && noSpacesRegex.test(this.name);
+ },
+ isSemver() {
+ return semverRegex.test(this.version);
+ },
+ isVersionValid() {
+ return !this.version || this.isSemver;
+ },
+ submitButtonDisabled() {
+ return !this.isVersionValid || !this.modelNameIsValid;
+ },
+ actionPrimary() {
+ return {
+ text: s__('MlModelRegistry|Create'),
+ attributes: { variant: 'confirm', disabled: this.submitButtonDisabled },
+ };
+ },
+ validVersionFeedback() {
+ if (this.isSemver) {
+ return this.$options.modal.versionValid;
+ }
+ return null;
+ },
+ modelNameDescription() {
+ return !this.name || this.modelNameIsValid ? this.$options.modal.nameDescription : '';
+ },
+ versionDescriptionText() {
+ return !this.version ? this.$options.modal.versionDescription : '';
+ },
},
methods: {
async createModel() {
@@ -138,29 +169,28 @@ export default {
i18n: {},
modal: {
id: MODEL_CREATION_MODAL_ID,
- actionPrimary: {
- text: __('Create'),
- attributes: { variant: 'confirm' },
- },
actionSecondary: {
text: __('Cancel'),
attributes: { variant: 'default' },
},
- nameDescription: s__(
- 'MlModelRegistry|Model name must not contain spaces or upper case letter.',
- ),
- namePlaceholder: s__('MlModelRegistry|For example my-model'),
- versionDescription: s__('MlModelRegistry|Leave empty to skip version creation.'),
- versionPlaceholder: s__('MlModelRegistry|For example 1.0.0. Must be a semantic version.'),
- descriptionPlaceholder: s__('MlModelRegistry|Enter a model description'),
+ nameDescriptionLabel: s__('MlModelRegistry|Must be unique. May not contain spaces.'),
+ nameDescription: s__('MlModelRegistry|Example: my-model'),
+ nameInvalid: s__('MlModelRegistry|May not contain spaces.'),
+ namePlaceholder: s__('MlModelRegistry|Enter a model name'),
+ versionDescription: s__('MlModelRegistry|Example: 1.0.0'),
+ versionPlaceholder: s__('MlModelRegistry|Enter a semantic version'),
+ nameDescriptionPlaceholder: s__('MlModelRegistry|Enter a model description'),
versionDescriptionTitle: s__('MlModelRegistry|Version description'),
- versionDescriptionPlaceholder: s__(
- 'MlModelRegistry|Enter a description for this version of the model.',
+ versionDescriptionLabel: s__(
+ 'MlModelRegistry|Must be a semantic version. Leave blank to skip version creation.',
),
+ versionValid: s__('MlModelRegistry|Version is a valid semantic version.'),
+ versionInvalid: s__('MlModelRegistry|Must be a semantic version. Example: 1.0.0'),
+ versionDescriptionPlaceholder: s__('MlModelRegistry|Enter a version description'),
buttonTitle: s__('MlModelRegistry|Create model'),
title: s__('MlModelRegistry|Create model, version & import artifacts'),
modelName: s__('MlModelRegistry|Model name'),
- modelDescription: __('Description'),
+ modelDescription: __('Model description'),
version: __('Version'),
uploadLabel: __('Upload artifacts'),
modelSuccessButVersionArtifactFailAlert: {
@@ -170,6 +200,7 @@ export default {
),
variant: 'warning',
},
+ optionalText: s__('MlModelRegistry|Optional'),
},
};
@@ -180,7 +211,7 @@ export default {
-
+
{{ errorMessage }}
+ >{{ errorMessage }}
+
diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/view/rule_drawer.vue b/app/assets/javascripts/projects/settings/branch_rules/components/view/rule_drawer.vue
index ff6bd85d9fb..ae0e9b356fd 100644
--- a/app/assets/javascripts/projects/settings/branch_rules/components/view/rule_drawer.vue
+++ b/app/assets/javascripts/projects/settings/branch_rules/components/view/rule_drawer.vue
@@ -176,17 +176,16 @@ export default {
diff --git a/app/assets/javascripts/projects/settings/repository/maintenance/redact_text.vue b/app/assets/javascripts/projects/settings/repository/maintenance/redact_text.vue
index 63af2770d44..f69ecc793c7 100644
--- a/app/assets/javascripts/projects/settings/repository/maintenance/redact_text.vue
+++ b/app/assets/javascripts/projects/settings/repository/maintenance/redact_text.vue
@@ -1,5 +1,6 @@