diff --git a/ee/app/assets/javascripts/security_configuration/components/security_attributes/attribute_drawer.vue b/ee/app/assets/javascripts/security_configuration/components/security_attributes/attribute_drawer.vue
index c6925d30a87c9eab80b51bad0d998152e37a7ab6..b1776ec98fe3827642891cbf2d45be8fe687e05c 100644
--- a/ee/app/assets/javascripts/security_configuration/components/security_attributes/attribute_drawer.vue
+++ b/ee/app/assets/javascripts/security_configuration/components/security_attributes/attribute_drawer.vue
@@ -18,8 +18,8 @@ export default {
i18n: {
addAttributeTitle: s__('SecurityAttributes|Add security attribute'),
editAttributeTitle: s__('SecurityAttributes|Edit security attribute'),
- updateAttributeButton: s__('SecurityAttributes|Update attribute'),
- createAttributeButton: s__('SecurityAttributes|Add attribute'),
+ updateAttributeButton: s__('SecurityAttributes|Apply changes'),
+ createAttributeButton: s__('SecurityAttributes|Apply changes'),
cancelButton: s__('SecurityAttributes|Cancel'),
deleteButton: s__('SecurityAttributes|Delete'),
},
@@ -111,7 +111,7 @@ export default {
defaultCategory,
},
},
+ data() {
+ return {
+ formErrors: {
+ name: null,
+ multipleSelection: null,
+ attributes: null,
+ },
+ hasUnsavedChanges: false,
+ };
+ },
computed: {
isNew() {
return !this.category?.id;
@@ -68,14 +78,30 @@ export default {
areAttributesEditable() {
return this.category?.canEditAttributes || this.isNew;
},
- categoryName() {
- return this.category?.name;
+ attributes() {
+ return this.securityAttributes.filter(
+ (attribute) => attribute.categoryId === this.category.id,
+ );
},
- categoryDescription() {
- return this.category?.description;
+ },
+ methods: {
+ isFormValid() {
+ this.formErrors.name = this.category.name.trim() === '' ? __('Name is required') : null;
+ this.formErrors.multipleSelection =
+ this.category.multipleSelection === null ? __('Selection type is required') : null;
+ this.formErrors.attributes =
+ this.attributes.length === 0 ? __('At least one attribute is required') : null;
+ return (
+ !this.formErrors.name && !this.formErrors.multipleSelection && !this.formErrors.attributes
+ );
},
- attributes() {
- return this.category?.id ? this.securityAttributes : [];
+ handleSave() {
+ if (!this.isFormValid()) return;
+ this.$emit('updateCategory', this.category);
+ this.hasUnsavedChanges = false;
+ },
+ handleUnsavedChange() {
+ this.hasUnsavedChanges = true;
},
},
attributesTableFields: [
@@ -141,15 +167,32 @@ export default {
{{ s__('SecurityAttributes|Category details') }}
{{ s__('SecurityAttributes|View category settings and associated attributes.') }}
-
-
- {{ categoryName }}
+
+
+ {{ category.name }}
-
- {{ categoryDescription }}
+
+ {{ category.description }}
-
+
{{ s__('SecurityAttributes|Selection type') }}
-
+
{{ s__('SecurityAttributes|Single selection') }}
@@ -186,6 +229,8 @@ export default {
{{ __('Attributes') }}
@@ -221,10 +266,15 @@ export default {
-
-
+
+
{{ s__('SecurityAttributes|Save changes') }}
+ {{ __('Unsaved changes') }}
+ {{ __('All changes saved') }}
diff --git a/ee/app/assets/javascripts/security_configuration/components/security_attributes/category_list.vue b/ee/app/assets/javascripts/security_configuration/components/security_attributes/category_list.vue
index d4fe985cf9b230b8123889de93a37a9d7173a6c2..473ba39a037563aa3c143751bb00c36d566bd8d3 100644
--- a/ee/app/assets/javascripts/security_configuration/components/security_attributes/category_list.vue
+++ b/ee/app/assets/javascripts/security_configuration/components/security_attributes/category_list.vue
@@ -27,7 +27,7 @@ export default {
category="primary"
variant="confirm"
size="small"
- @click="$emit('selectCategory', {})"
+ @click="$emit('createCategory')"
>{{ s__('SecurityAttributes|Create category') }}
@@ -47,7 +47,7 @@ export default {
{{ category.description }}
- {{ category.attributeCount }}
+ {{ category.attributeCount }}
diff --git a/ee/app/assets/javascripts/security_configuration/components/security_attributes/configure_attributes.vue b/ee/app/assets/javascripts/security_configuration/components/security_attributes/configure_attributes.vue
index 787c842068c9b701e1c27db86ffc17f6b26668dc..4e6c2fc252bb530170e38c29821314da2080f012 100644
--- a/ee/app/assets/javascripts/security_configuration/components/security_attributes/configure_attributes.vue
+++ b/ee/app/assets/javascripts/security_configuration/components/security_attributes/configure_attributes.vue
@@ -1,4 +1,6 @@