Skip to content

Commit

Permalink
Merge pull request learningequality#4714 from AllanOXDi/bulk_editting…
Browse files Browse the repository at this point in the history
…-fix

Fixed field is required' validation
  • Loading branch information
marcellamaki authored Sep 13, 2024
2 parents f029bd4 + b208530 commit cfff054
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 81 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@

<template>

<KModal
:title="title"
:submitText="$tr('saveAction')"
:submitDisabled="!canSave"
:cancelText="$tr('cancelAction')"
data-test="edit-booleanMap-modal"
@submit="handleSave"
Expand All @@ -11,6 +13,9 @@
<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 @@ -26,9 +31,6 @@
:inputHandler="(value) => { selectedValues = value }"
></slot>

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

</template>
Expand All @@ -45,6 +47,7 @@
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 @@ -94,13 +97,31 @@
};
},
computed: {
...mapGetters('contentNode', ['getContentNodes']),
...mapGetters('contentNode', ['getContentNodes', 'getContentNode']),
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 @@ -147,19 +168,16 @@
}
},
async handleSave() {
this.validate();
if (this.error) {
return;
}
await Promise.all(
this.nodes.map(node => {
this.nodes.map(async node => {
const fieldValue = {};
const currentNode = this.getContentNode(node.id);
Object.entries(this.selectedValues).forEach(([key, value]) => {
if (value.includes(node.id)) {
fieldValue[key] = true;
}
const existingValue = currentNode[this.field]?.[key] || false;
fieldValue[key] = existingValue || value.includes(node.id);
});
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,7 +16,6 @@ let generalActions;
const CheckboxValue = {
UNCHECKED: 'UNCHECKED',
CHECKED: 'CHECKED',
INDETERMINATE: 'INDETERMINATE',
};

const { translateMetadataString } = metadataTranslationMixin.methods;
Expand All @@ -31,11 +30,9 @@ const getOptionsValues = wrapper => {
const categories = {};
const checkboxes = wrapper.findAll('[data-test="option-checkbox"]');
checkboxes.wrappers.forEach(checkbox => {
const { label, checked, indeterminate } = checkbox.vm.$props || {};
const { label, checked } = checkbox.vm.$props || {};
let value;
if (indeterminate) {
value = CheckboxValue.INDETERMINATE;
} else if (checked) {
if (checked) {
value = CheckboxValue.CHECKED;
} else {
value = CheckboxValue.UNCHECKED;
Expand Down Expand Up @@ -182,26 +179,6 @@ 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="autocompleteOptions"
:items="categoriesList"
:searchInput.sync="categoryText"
:label="translateMetadataString('category')"
box
Expand Down Expand Up @@ -81,7 +81,6 @@
:label="option.text"
:style="treeItemStyle(option)"
:checked="isSelected(option.value)"
:indeterminate="isCheckboxIndeterminate(option.value)"
@change="onChange(option.value)"
/>
<p
Expand All @@ -102,8 +101,6 @@
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 @@ -155,28 +152,10 @@
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 @@ -216,9 +195,6 @@
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 @@ -282,15 +258,6 @@
});
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 @@ -301,7 +268,6 @@
},
$trs: {
noCategoryFoundText: 'Category not found',
mixedLabel: 'Mixed',
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
: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 @@ -188,12 +187,6 @@
}
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 @@ -216,4 +209,4 @@
pointer-events: none;
opacity: 0.5;
}
</style>
</style>

0 comments on commit cfff054

Please sign in to comment.