From 3ae94183bf670c1acb27bbad7af9f42e6c375a0c Mon Sep 17 00:00:00 2001
From: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com>
Date: Fri, 8 Sep 2023 10:02:52 -0500
Subject: [PATCH] UI: Namespace validation update (#22820)
---
ui/app/models/namespace.js | 20 +++++++++------
ui/lib/core/addon/components/edit-form.js | 18 +++++++++++++
ui/lib/core/addon/components/form-field.hbs | 6 -----
.../components/form-save-buttons.hbs | 5 ++--
.../addon/components/form-save-buttons.js | 25 +++++++++----------
.../addon/templates/components/edit-form.hbs | 20 ++++++++++++---
6 files changed, 61 insertions(+), 33 deletions(-)
rename ui/lib/core/addon/{templates => }/components/form-save-buttons.hbs (77%)
diff --git a/ui/app/models/namespace.js b/ui/app/models/namespace.js
index 0cfc5949d8..5a2b2174b6 100644
--- a/ui/app/models/namespace.js
+++ b/ui/app/models/namespace.js
@@ -5,19 +5,23 @@
import Model, { attr } from '@ember-data/model';
import { withExpandedAttributes } from 'vault/decorators/model-expanded-attributes';
+import { withModelValidations } from 'vault/decorators/model-validations';
@withExpandedAttributes()
+@withModelValidations({
+ path: [
+ { type: 'presence', message: `Path can't be blank.` },
+ { type: 'endsInSlash', message: `Path can't end in forward slash '/'.` },
+ {
+ type: 'containsWhiteSpace',
+ message: "Path can't contain whitespace.",
+ },
+ ],
+})
export default class NamespaceModel extends Model {
- @attr('string', {
- validationAttr: 'pathIsValid',
- invalidMessage: 'You have entered and invalid path please only include letters, numbers, -, ., and _.',
- })
+ @attr('string')
path;
- get pathIsValid() {
- return this.path && this.path.match(/^[\w\d-.]+$/g);
- }
-
get fields() {
return ['path'].map((f) => this.allByKey[f]);
}
diff --git a/ui/lib/core/addon/components/edit-form.js b/ui/lib/core/addon/components/edit-form.js
index e71c09f7d8..12f8b8205d 100644
--- a/ui/lib/core/addon/components/edit-form.js
+++ b/ui/lib/core/addon/components/edit-form.js
@@ -15,6 +15,9 @@ export default Component.extend({
layout,
flashMessages: service(),
+ // internal validations
+ invalidFormAlert: '',
+ modelValidations: null,
// public API
model: null,
successMessage: 'Saved!',
@@ -38,10 +41,25 @@ export default Component.extend({
// is the case, set this value to true
callOnSaveAfterRender: false,
+ checkModelValidity(model) {
+ if (model.validate) {
+ const { isValid, state, invalidFormMessage } = model.validate();
+ this.set('modelValidations', state);
+ this.set('invalidFormAlert', invalidFormMessage);
+ return isValid;
+ }
+ // no validations on model; return true
+ return true;
+ },
+
save: task(
waitFor(function* (model, options = { method: 'save' }) {
const { method } = options;
const messageKey = method === 'save' ? 'successMessage' : 'deleteSuccessMessage';
+ if (method === 'save' && !this.checkModelValidity(model)) {
+ // if saving and model invalid, don't continue
+ return;
+ }
try {
yield model[method]();
} catch (err) {
diff --git a/ui/lib/core/addon/components/form-field.hbs b/ui/lib/core/addon/components/form-field.hbs
index 7c9e4b5af0..31be930f44 100644
--- a/ui/lib/core/addon/components/form-field.hbs
+++ b/ui/lib/core/addon/components/form-field.hbs
@@ -281,12 +281,6 @@
class="input {{if this.validationError 'has-error-border'}}"
maxLength={{@attr.options.characterLimit}}
/>
- {{! TODO: explore removing in favor of new model validations pattern since it is only used on the namespace model }}
- {{#if @attr.options.validationAttr}}
- {{#if (and (get @model this.valuePath) (not (get @model @attr.options.validationAttr)))}}
-