Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track and remove nested hidden fields #5805

Merged
merged 24 commits into from
Apr 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0b0d58a
Accept and track `dottedKey` instead of `handle` for nested field han…
jesseleite Apr 8, 2022
2893ac5
Pass `dottedKey` using `errorKey` (for now, wip).
jesseleite Apr 8, 2022
c49eca9
Omit hidden values and nested values using dotted keys.
jesseleite Apr 8, 2022
22b9843
Handle hidden fields within bard json values.
jesseleite Apr 8, 2022
5d32ec6
Add field conditions value `Omitter.js` helper class.
jesseleite Apr 11, 2022
570f13b
Track JSON-submitting fields.
jesseleite Apr 11, 2022
8dc9608
Configure Bard fields as JSON-submitting (temporarily using error key…
jesseleite Apr 11, 2022
31bfee1
Remove old filtering logic in favour of more robust `Omitter.js` impl…
jesseleite Apr 11, 2022
318db14
Fix non-existent key issues when deleting bard sets, etc.
jesseleite Apr 12, 2022
06251c0
Ensure it properly handles null values vs undefined/missing values.
jesseleite Apr 12, 2022
ee77a46
Make it a bit more forgiving.
jesseleite Apr 12, 2022
dd641ed
But this should only store unique field keys anyway.
jesseleite Apr 12, 2022
497c1bf
Move ‘filled’ logic from `Field` to `Fields`.
jesseleite Apr 12, 2022
672f417
Ensure `validatableValues()` gets called recursively.
jesseleite Apr 12, 2022
037e154
Pass tests again (should add tests for recursive fields next though).
jesseleite Apr 12, 2022
450bd30
Apply fixes from StyleCI
StyleCIBot Apr 12, 2022
b6aa19d
Fix inconsistency between Grid and Replicator/Bard validation attribu…
jesseleite Apr 13, 2022
c881d95
Pass same grid values as rest of payload to pass test again.
jesseleite Apr 13, 2022
5b7daef
Remove `validateValues()` requirement for when using `preProcessValid…
jesseleite Apr 13, 2022
2a35108
Rename `error-key` stuff to `field-path`, since we’re using for more …
jesseleite Apr 13, 2022
9a0705c
Apply fixes from StyleCI
StyleCIBot Apr 13, 2022
4423f5c
Fix `$filled` array check when no values are filled.
jesseleite Apr 14, 2022
6ec2a95
Add test coverage for recursive `preProcessValidatables()` handling.
jesseleite Apr 14, 2022
ce19146
Elaborate on why we json strings in bard
jasonvarga Apr 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions resources/js/components/data-list/HasHiddenFields.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import HiddenValuesOmitter from '../field-conditions/Omitter.js';

export default {

computed: {
Expand All @@ -6,10 +8,17 @@ export default {
return this.$store.state.publish[this.publishContainer].hiddenFields;
},

jsonSubmittingFields() {
return this.$store.state.publish[this.publishContainer].jsonSubmittingFields;
},

visibleValues() {
return _.omit(this.values, (_, handle) => {
return this.hiddenFields[handle];
});
let hiddenFields = _.chain(this.hiddenFields)
.pick(hidden => hidden)
.keys()
.value();

return new HiddenValuesOmitter(this.values, this.jsonSubmittingFields).omit(hiddenFields);
},

}
Expand Down
91 changes: 91 additions & 0 deletions resources/js/components/field-conditions/Omitter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { clone } from '../../bootstrap/globals.js'

export default class {
constructor(values, jsonFields) {
this.values = clone(values);

this.jsonFields = clone(jsonFields || [])
.filter((field, index) => jsonFields.indexOf(field) === index)
.sort();
}

omit(hiddenKeys) {
this.jsonDecode()
.omitHiddenFields(hiddenKeys)
.jsonEncode();

return this.values;
}

jsonDecode() {
this.jsonFields.forEach(dottedKey => {
this.jsonDecodeValue(dottedKey);
});

return this;
}

omitHiddenFields(hiddenKeys) {
hiddenKeys.forEach(dottedKey => {
this.forgetValue(dottedKey);
});

return this;
}

jsonEncode() {
clone(this.jsonFields).reverse().forEach(dottedKey => {
this.jsonEncodeValue(dottedKey);
});

return this;
}

dottedKeyToJsPath(dottedKey) {
return dottedKey.replace(/\.*(\d+)\./g, '[$1].');
}

missingValue(dottedKey) {
var properties = Array.isArray(dottedKey) ? dottedKey : dottedKey.split('.');
var value = properties.reduce((prev, curr) => prev && prev[curr], clone(this.values));

return value === undefined;
}

jsonDecodeValue(dottedKey) {
if (this.missingValue(dottedKey)) return;

let values = clone(this.values);
let jsPath = this.dottedKeyToJsPath(dottedKey);
let fieldValue = eval('values.' + jsPath);
let decodedFieldValue = JSON.parse(fieldValue);

eval('values.' + jsPath + ' = decodedFieldValue');

this.values = values;
}

jsonEncodeValue(dottedKey) {
if (this.missingValue(dottedKey)) return;

let values = clone(this.values);
let jsPath = this.dottedKeyToJsPath(dottedKey);
let fieldValue = eval('values.' + jsPath);
let encodedFieldValue = JSON.stringify(fieldValue);

eval('values.' + jsPath + ' = encodedFieldValue');

this.values = values;
}

forgetValue(dottedKey) {
if (this.missingValue(dottedKey)) return;

let values = clone(this.values);
let jsPath = this.dottedKeyToJsPath(dottedKey);

eval('delete values.' + jsPath);

this.values = values;
}
}
4 changes: 2 additions & 2 deletions resources/js/components/field-conditions/ValidatorMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ export default {
},

methods: {
showField(field) {
showField(field, dottedKey) {
let passes = new Validator(field, this.values, this.$store, this.storeName).passesConditions();

this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
handle: field.handle,
dottedKey: dottedKey || field.handle,
hidden: ! passes,
});

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/Fieldtype.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default {
default: false
},
namePrefix: String,
errorKeyPrefix: String,
fieldPathPrefix: String,
},

methods: {
Expand Down
11 changes: 9 additions & 2 deletions resources/js/components/fieldtypes/bard/BardFieldtype.vue
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export default {
if (! this.storeState) return [];

return Object.values(this.setIndexes).filter((setIndex) => {
const prefix = `${this.errorKeyPrefix || this.handle}.${setIndex}.`;
const prefix = `${this.fieldPathPrefix || this.handle}.${setIndex}.`;

return Object.keys(this.storeState.errors).some(key => key.startsWith(prefix));
})
Expand Down Expand Up @@ -286,6 +286,8 @@ export default {
this.$nextTick(() => this.mounted = true);

this.pageHeader = document.querySelector('.global-header');

this.$store.commit(`publish/${this.storeName}/setFieldSubmitsJson`, this.fieldPathPrefix || this.handle);
},

beforeDestroy() {
Expand All @@ -297,7 +299,12 @@ export default {
json(json) {
if (!this.mounted) return;

// Use a json string otherwise Laravel's TrimStrings middleware will remove spaces where we need them.
// Prosemirror's JSON will include spaces between tags.
// For example (this is not the actual json)...
// "<p>One <b>two</b> three</p>" becomes ['OneSPACE', '<b>two</b>', 'SPACEthree']
// But, Laravel's TrimStrings middleware would remove them.
// Those spaces need to be there, otherwise it would be rendered as <p>One<b>two</b>three</p>
// To combat this, we submit the JSON string instead of an object.
this.updateDebounced(JSON.stringify(json));
},

Expand Down
10 changes: 5 additions & 5 deletions resources/js/components/fieldtypes/bard/Set.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@
<div class="replicator-set-body" v-if="!collapsed && index !== undefined">
<set-field
v-for="field in fields"
v-show="showField(field)"
v-show="showField(field, fieldPath(field))"
:key="field.handle"
:field="field"
:value="values[field.handle]"
:meta="meta[field.handle]"
:parent-name="parentName"
:set-index="index"
:error-key="errorKey(field)"
:field-path="fieldPath(field)"
:read-only="isReadOnly"
@updated="updated(field.handle, $event)"
@meta-updated="metaUpdated(field.handle, $event)"
Expand Down Expand Up @@ -191,10 +191,10 @@ export default {
this.options.bard.expandSet(this.node.attrs.id);
},

errorKey(field) {
let prefix = this.options.bard.errorKeyPrefix || this.options.bard.handle;
fieldPath(field) {
let prefix = this.options.bard.fieldPathPrefix || this.options.bard.handle;
return `${prefix}.${this.index}.attrs.values.${field.handle}`;
}
},

}
}
Expand Down
4 changes: 2 additions & 2 deletions resources/js/components/fieldtypes/grid/Cell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
:meta="meta"
:handle="field.handle"
:name-prefix="namePrefix"
:error-key-prefix="errorKey"
:field-path-prefix="fieldPath"
:read-only="grid.isReadOnly"
@input="$emit('updated', $event)"
@meta-updated="$emit('meta-updated', $event)"
Expand Down Expand Up @@ -59,7 +59,7 @@ export default {
type: Array,
required: true
},
errorKey: {
fieldPath: {
type: String,
required: true
}
Expand Down
4 changes: 2 additions & 2 deletions resources/js/components/fieldtypes/grid/Grid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export default {

reactiveProvide: {
name: 'grid',
include: ['config', 'isReorderable', 'isReadOnly', 'handle', 'errorKeyPrefix']
include: ['config', 'isReorderable', 'isReadOnly', 'handle', 'fieldPathPrefix']
},

watch: {
Expand Down Expand Up @@ -169,7 +169,7 @@ export default {

removed(index) {
if (! confirm(__('Are you sure?'))) return;

this.update([
...this.value.slice(0, index),
...this.value.slice(index + 1)
Expand Down
15 changes: 8 additions & 7 deletions resources/js/components/fieldtypes/grid/Row.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<td class="drag-handle" :class="sortableHandleClass" v-if="grid.isReorderable"></td>
<grid-cell
v-for="(field, i) in fields"
:show-inner="showField(field)"
:show-inner="showField(field, fieldPath(field.handle))"
:key="field.handle"
:field="field"
:value="values[field.handle]"
Expand All @@ -13,7 +13,7 @@
:row-index="index"
:grid-name="name"
:errors="errors(field.handle)"
:error-key="errorKey(field.handle)"
:field-path="fieldPath(field.handle)"
@updated="updated(field.handle, $event)"
@meta-updated="metaUpdated(field.handle, $event)"
@focus="$emit('focus')"
Expand Down Expand Up @@ -67,7 +67,7 @@ export default {
type: String,
required: true
},
errorKeyPrefix: {
fieldPathPrefix: {
type: String
},
canDelete: {
Expand Down Expand Up @@ -108,15 +108,16 @@ export default {
this.$emit('meta-updated', meta);
},

errorKey(handle) {
return `${this.errorKeyPrefix}.${this.index}.${handle}`;
fieldPath(handle) {
return `${this.fieldPathPrefix}.${this.index}.${handle}`;
},

errors(handle) {
const state = this.$store.state.publish[this.storeName];
if (! state) return [];
return state.errors[this.errorKey(handle)] || [];
}
return state.errors[this.fieldPath(handle)] || [];
},

}

}
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/grid/Stacked.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
:values="row"
:meta="meta[row._id]"
:name="name"
:error-key-prefix="errorKeyPrefix"
:field-path-prefix="fieldPathPrefix"
:can-delete="canDeleteRows"
:can-add-rows="canAddRows"
@updated="(row, value) => $emit('updated', row, value)"
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/grid/StackedRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
:parent-name="name"
:set-index="index"
:errors="errors(field.handle)"
:error-key-prefix="errorKey(field.handle)"
:field-path-prefix="fieldPath(field.handle)"
class="p-2"
:read-only="grid.isReadOnly"
@updated="updated(field.handle, $event)"
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/grid/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
:values="row"
:meta="meta[row._id]"
:name="name"
:error-key-prefix="errorKeyPrefix"
:field-path-prefix="fieldPathPrefix"
:can-delete="canDeleteRows"
:can-add-rows="canAddRows"
@updated="(row, value) => $emit('updated', row, value)"
Expand Down
4 changes: 2 additions & 2 deletions resources/js/components/fieldtypes/grid/View.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export default {
return `${this.name}-drag-handle`;
},

errorKeyPrefix() {
return this.grid.errorKeyPrefix || this.grid.handle;
fieldPathPrefix() {
return this.grid.fieldPathPrefix || this.grid.handle;
}

},
Expand Down
8 changes: 4 additions & 4 deletions resources/js/components/fieldtypes/replicator/Field.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
:value="value"
:handle="field.handle"
:name-prefix="namePrefix"
:error-key-prefix="errorKey"
:field-path-prefix="fieldPath"
:has-error="hasError || hasNestedError"
:read-only="isReadOnly"
@input="$emit('updated', $event)"
Expand Down Expand Up @@ -65,7 +65,7 @@ export default {
type: Number,
required: true
},
errorKey: {
fieldPath: {
type: String
},
readOnly: Boolean,
Expand Down Expand Up @@ -98,15 +98,15 @@ export default {
},

errors() {
return this.storeState.errors[this.errorKey] || [];
return this.storeState.errors[this.fieldPath] || [];
},

hasError() {
return this.errors.length > 0;
},

hasNestedError() {
const prefix = `${this.errorKey}.`;
const prefix = `${this.fieldPath}.`;

return Object.keys(this.storeState.errors).some(handle => handle.startsWith(prefix));
},
Expand Down
6 changes: 3 additions & 3 deletions resources/js/components/fieldtypes/replicator/Replicator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
:sortable-handle-class="sortableHandleClass"
:is-read-only="isReadOnly"
:collapsed="collapsed.includes(set._id)"
:error-key-prefix="errorKeyPrefix || handle"
:field-path-prefix="fieldPathPrefix || handle"
:has-error="setHasError(index)"
:previews="previews[set._id]"
@collapsed="collapseSet(set._id)"
Expand Down Expand Up @@ -90,7 +90,7 @@ export default {
},

computed: {

previews() {
return this.meta.previews;
},
Expand Down Expand Up @@ -204,7 +204,7 @@ export default {
},

setHasError(index) {
const prefix = `${this.errorKeyPrefix || this.handle}.${index}.`;
const prefix = `${this.fieldPathPrefix || this.handle}.${index}.`;

return Object.keys(this.storeState.errors ?? []).some(handle => handle.startsWith(prefix));
},
Expand Down
Loading