Skip to content

Commit

Permalink
Revert "Fixed field is required' validation"
Browse files Browse the repository at this point in the history
  • Loading branch information
AllanOXDi authored Sep 13, 2024
1 parent eeffb7c commit d1ffde7
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 35 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@

<template>

<KModal
:title="title"
:submitText="$tr('saveAction')"
:submitDisabled="!canSave"
:cancelText="$tr('cancelAction')"
data-test="edit-booleanMap-modal"
@submit="handleSave"
Expand All @@ -13,9 +11,6 @@
<p v-if="resourcesSelectedText.length > 0" data-test="resources-selected-message">
{{ resourcesSelectedText }}
</p>
<p v-if="hasMixedCategories" data-test="mixed-categories-message">
{{ hasMixedCategoriesMessage }}
</p>
<template v-if="isDescendantsUpdatable && isTopicSelected">
<KCheckbox
:checked="updateDescendants"
Expand All @@ -31,6 +26,9 @@
:inputHandler="(value) => { selectedValues = value }"
></slot>

<span v-if="error" class="red--text">
{{ error }}
</span>
</KModal>

</template>
Expand All @@ -47,7 +45,6 @@
import { mapGetters, mapActions } from 'vuex';
import { ContentKindsNames } from 'shared/leUtils/ContentKinds';
import { getInvalidText } from 'shared/utils/validation';
import commonStrings from 'shared/translator';
export default {
name: 'EditBooleanMapModal',
Expand Down Expand Up @@ -97,31 +94,13 @@
};
},
computed: {
...mapGetters('contentNode', ['getContentNodes', 'getContentNode']),
...mapGetters('contentNode', ['getContentNodes']),
nodes() {
return this.getContentNodes(this.nodeIds);
},
isTopicSelected() {
return this.nodes.some(node => node.kind === ContentKindsNames.TOPIC);
},
canSave() {
return Object.values(this.selectedValues).some(value => value.length > 0);
},
hasMixedCategories() {
const allSelectedCategories = new Set(Object.keys(this.selectedValues));
for (const categoryId of allSelectedCategories) {
const nodesWithThisCategory = this.selectedValues[categoryId].length;
if (nodesWithThisCategory < this.nodes.length) {
return true;
}
}
return false;
},
hasMixedCategoriesMessage() {
// eslint-disable-next-line kolibri/vue-no-undefined-string-uses
return commonStrings.$tr('addAdditionalCatgoriesDescription');
},
},
watch: {
selectedValues(newValue, oldValue) {
Expand Down Expand Up @@ -168,16 +147,19 @@
}
},
async handleSave() {
this.validate();
if (this.error) {
return;
}
await Promise.all(
this.nodes.map(async node => {
this.nodes.map(node => {
const fieldValue = {};
const currentNode = this.getContentNode(node.id);
Object.entries(this.selectedValues).forEach(([key, value]) => {
const existingValue = currentNode[this.field]?.[key] || false;
fieldValue[key] = existingValue || value.includes(node.id);
if (value.includes(node.id)) {
fieldValue[key] = true;
}
});
if (this.updateDescendants && node.kind === ContentKindsNames.TOPIC) {
return this.updateContentNodeDescendants({
id: node.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let generalActions;
const CheckboxValue = {
UNCHECKED: 'UNCHECKED',
CHECKED: 'CHECKED',
INDETERMINATE: 'INDETERMINATE',
};

const { translateMetadataString } = metadataTranslationMixin.methods;
Expand All @@ -30,9 +31,11 @@ const getOptionsValues = wrapper => {
const categories = {};
const checkboxes = wrapper.findAll('[data-test="option-checkbox"]');
checkboxes.wrappers.forEach(checkbox => {
const { label, checked } = checkbox.vm.$props || {};
const { label, checked, indeterminate } = checkbox.vm.$props || {};
let value;
if (checked) {
if (indeterminate) {
value = CheckboxValue.INDETERMINATE;
} else if (checked) {
value = CheckboxValue.CHECKED;
} else {
value = CheckboxValue.UNCHECKED;
Expand Down Expand Up @@ -179,6 +182,26 @@ describe('EditBooleanMapModal', () => {
expect(dailyLifeValue).toBe(CheckboxValue.CHECKED);
expect(foundationsValue).toBe(CheckboxValue.CHECKED);
});

test('checkbox option should be indeterminate if not all nodes have the same options set', () => {
nodes['node1'].categories = {
[Categories.DAILY_LIFE]: true,
[Categories.FOUNDATIONS]: true,
};
nodes['node2'].categories = {
[Categories.DAILY_LIFE]: true,
};

const wrapper = makeWrapper({ nodeIds: ['node1', 'node2'] });

const optionsValues = getOptionsValues(wrapper);
const {
[Categories.DAILY_LIFE]: dailyLifeValue,
[Categories.FOUNDATIONS]: foundationsValue,
} = optionsValues;
expect(dailyLifeValue).toBe(CheckboxValue.CHECKED);
expect(foundationsValue).toBe(CheckboxValue.INDETERMINATE);
});
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<template #default="{ attach, menuProps }">
<VAutocomplete
:value="autocompleteValues"
:items="categoriesList"
:items="autocompleteOptions"
:searchInput.sync="categoryText"
:label="translateMetadataString('category')"
box
Expand Down Expand Up @@ -81,6 +81,7 @@
:label="option.text"
:style="treeItemStyle(option)"
:checked="isSelected(option.value)"
:indeterminate="isCheckboxIndeterminate(option.value)"
@change="onChange(option.value)"
/>
<p
Expand All @@ -101,6 +102,8 @@
import DropdownWrapper from 'shared/views/form/DropdownWrapper';
import { constantsTranslationMixin, metadataTranslationMixin } from 'shared/mixins';
const MIXED = 'mixed';
export default {
name: 'CategoryOptions',
components: { DropdownWrapper },
Expand Down Expand Up @@ -152,10 +155,28 @@
this.$emit('input', value);
},
},
autocompleteOptions() {
const options = [...this.categoriesList];
if (this.expanded) {
// Just boolean maps can have indeterminate values
options.push({
value: MIXED,
text: this.$tr('mixedLabel'),
undeletable: true,
});
}
return options;
},
autocompleteValues() {
const selectedValues = Object.entries(this.selected)
.filter(entry => entry[1].length === this.nodeIds.length)
.map(([key]) => key);
if (
this.expanded &&
Object.values(this.selected).some(value => value.length < this.nodeIds.length)
) {
selectedValues.push(MIXED);
}
return selectedValues;
},
nested() {
Expand Down Expand Up @@ -195,6 +216,9 @@
this.selected = {};
},
tooltipText(optionId) {
if (optionId === MIXED) {
return this.$tr('mixedLabel');
}
const option = this.categoriesList.find(option => option.value === optionId);
if (!option) {
return '';
Expand Down Expand Up @@ -258,6 +282,15 @@
});
return nodeIds.size === this.nodeIds.length;
},
isCheckboxIndeterminate(optionId) {
if (this.selected[optionId] && this.selected[optionId].length < this.nodeIds.length) {
return true;
}
return (
Object.keys(this.selected).some(selectedValue => selectedValue.startsWith(optionId)) &&
!this.isSelected(optionId)
);
},
onChange(optionId) {
if (this.isSelected(optionId)) {
this.remove(optionId);
Expand All @@ -268,6 +301,7 @@
},
$trs: {
noCategoryFoundText: 'Category not found',
mixedLabel: 'Mixed',
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
:key="option.value"
:label="option.text"
:checked="isSelected(option.value)"
:indeterminate="isIndeterminate(option.value)"
data-test="option-checkbox"
@change="value => setOption(option.value, value)"
/>
Expand Down Expand Up @@ -187,6 +188,12 @@
}
return this.valueModel[value].length === this.availableItems.length;
},
isIndeterminate(value) {
if (!this.valueModel[value]) {
return false;
}
return this.valueModel[value].length < this.availableItems.length;
},
setOption(optionId, value) {
if (value) {
this.valueModel = {
Expand All @@ -209,4 +216,4 @@
pointer-events: none;
opacity: 0.5;
}
</style>
</style>

0 comments on commit d1ffde7

Please sign in to comment.