🎨 Apply local style vars for embeded form elements, and adds in-code docs

This commit is contained in:
Alicia Sykes 2021-10-18 22:47:32 +01:00
parent 8a4f4373c1
commit 1ed55b42c6
1 changed files with 99 additions and 55 deletions

View File

@ -8,12 +8,16 @@
@closed="modalClosed" @closed="modalClosed"
> >
<div class="edit-item-inner"> <div class="edit-item-inner">
<!-- Title and Item ID -->
<h3 class="title">Edit Item</h3> <h3 class="title">Edit Item</h3>
<p class="sub-title">Editing {{item.title}} (ID: {{itemId}})</p> <p class="sub-title">Editing {{item.title}} (ID: {{itemId}})</p>
<!-- If no elements added to form, show info message -->
<p class="warning-note" v-if="formData.length === 0"> <p class="warning-note" v-if="formData.length === 0">
No data configured yet. Click an attribute in the list below to add the field to the form. No data configured yet. Click an attribute in the list below to add the field to the form.
</p> </p>
<!-- For each data attribute, render the correct type of input field -->
<div class="row" v-for="(row, index) in formData" :key="row.name"> <div class="row" v-for="(row, index) in formData" :key="row.name">
<!-- Text box, for text/ number/ raw input elements -->
<Input <Input
v-if="row.type === 'text' || row.type === 'number'" v-if="row.type === 'text' || row.type === 'number'"
v-model="formData[index].value" v-model="formData[index].value"
@ -22,6 +26,7 @@
:type="row.type" :type="row.type"
layout="horizontal" layout="horizontal"
/> />
<!-- Radio button, used for True or False input -->
<Radio <Radio
v-else-if="row.type === 'boolean'" v-else-if="row.type === 'boolean'"
v-model="formData[index].value" v-model="formData[index].value"
@ -30,6 +35,7 @@
:options="['true', 'false']" :options="['true', 'false']"
:initialOption="boolToStr(formData[index].value)" :initialOption="boolToStr(formData[index].value)"
/> />
<!-- Select/ dropdown for enum multiple-choice input -->
<Select <Select
v-else-if="row.type === 'select'" v-else-if="row.type === 'select'"
v-model="formData[index].value" v-model="formData[index].value"
@ -37,12 +43,15 @@
:description="row.description" :description="row.description"
:initialOption="formData[index].value" :initialOption="formData[index].value"
:label="row.name" :label="row.name"
class="edit-item-select"
/> />
<!-- Warning note, for any other data types, that aren't yet supported -->
<div v-else> <div v-else>
{{ row.name }} cannot currently be edited through the UI. {{ row.name }} cannot currently be edited through the UI.
</div> </div>
<BinIcon @click="() => removeField(row.name)" /> <BinIcon @click="() => removeField(row.name)" />
</div> </div>
<!-- Show Add chips, for adding more data elements to the form -->
<div class="add-more-inputs" v-if="additionalFormData.length > 0"> <div class="add-more-inputs" v-if="additionalFormData.length > 0">
<h4>More Fields</h4> <h4>More Fields</h4>
<div class="more-fields"> <div class="more-fields">
@ -55,7 +64,8 @@
</span> </span>
</div> </div>
</div> </div>
<Button :click="saveItem">Save</Button> <!-- Save to state button -->
<Button class="edit-item-save-btn" :click="saveItem">Save</Button>
</div> </div>
</modal> </modal>
</template> </template>
@ -128,11 +138,62 @@ export default {
}); });
return formData; return formData;
}, },
/* Convert boolean to string */
boolToStr(bool) { boolToStr(bool) {
if (bool) return 'true'; if (bool) return 'true';
if (bool === false) return 'false'; if (bool === false) return 'false';
return undefined; return undefined;
}, },
/* Adds field from extras list to main form, then removes from extras list */
appendNewField(fieldId) {
Object.keys(this.schema).forEach((property) => {
if (property === fieldId) {
this.formData.push(this.makeRowData(property));
}
});
this.additionalFormData.forEach((elem, index) => {
if (elem.name === fieldId) {
this.additionalFormData.splice(index, 1);
}
});
},
/* On Remove Field click, removes field from main form, and adds to chip list */
removeField(fieldId) {
this.formData.forEach((elem, index) => {
if (elem.name === fieldId) {
this.formData.splice(index, 1);
this.additionalFormData.push(elem);
}
});
},
/* Use schema to determine type of form element to render, for a given attribute */
getInputType(schemaItem) {
const definedType = schemaItem.type;
if (definedType === 'text') {
return 'text';
} else if (definedType === 'number') {
return 'number';
} else if (definedType === 'boolean') {
return 'boolean';
} else if (schemaItem.enum) {
return 'select';
}
return 'text';
},
/* Saves the updated item to VueX Store */
saveItem() {
// Convert form data back into section.item data structure
const structured = {};
this.formData.forEach((row) => { structured[row.name] = row.value; });
// Some attributes need a little extra formatting
const newItem = this.formatBeforeSave(structured);
// Update the data store, with new item data
this.$store.commit(StoreKeys.UPDATE_ITEM, { newItem, itemId: this.itemId });
// If we're not already in edit mode, enable it now
this.$store.commit(StoreKeys.SET_EDIT_MODE, true);
// Close edit menu
this.$emit('closeEditMenu');
},
/* Some fields require a bit of extra processing before they're saved */ /* Some fields require a bit of extra processing before they're saved */
formatBeforeSave(item) { formatBeforeSave(item) {
const newItem = item; const newItem = item;
@ -150,57 +211,6 @@ export default {
if (newItem.statusCheck) newItem.statusCheck = strToBool(newItem.statusCheck); if (newItem.statusCheck) newItem.statusCheck = strToBool(newItem.statusCheck);
return newItem; return newItem;
}, },
/* Saves the updated item to VueX Store */
saveItem() {
// Convert form data back into section.item data structure
const structured = {};
this.formData.forEach((row) => { structured[row.name] = row.value; });
// Some attributes need a little extra formatting
const newItem = this.formatBeforeSave(structured);
// Update the data store, with new item data
this.$store.commit(StoreKeys.UPDATE_ITEM, { newItem, itemId: this.itemId });
// If we're not already in edit mode, enable it now
this.$store.commit(StoreKeys.SET_EDIT_MODE, true);
// Close edit menu
this.$emit('closeEditMenu');
},
/* Adds filed from extras list to main form, then removes from extras list */
appendNewField(fieldId) {
Object.keys(this.schema).forEach((property) => {
if (property === fieldId) {
this.formData.push(this.makeRowData(property));
}
});
this.additionalFormData.forEach((elem, index) => {
if (elem.name === fieldId) {
this.additionalFormData.splice(index, 1);
}
});
},
/* Removes filed from main form, adds back into extras list */
removeField(fieldId) {
this.formData.forEach((elem, index) => {
if (elem.name === fieldId) {
this.formData.splice(index, 1);
this.additionalFormData.push(elem);
}
});
},
/* For a given attribute, determine type from schema */
getInputType(schemaItem) {
const definedType = schemaItem.type;
// console.log(definedType);
if (definedType === 'text') {
return 'text';
} else if (definedType === 'number') {
return 'number';
} else if (definedType === 'boolean') {
return 'boolean';
} else if (schemaItem.enum) {
return 'select';
}
return 'text';
},
/* Clean up work, triggered when modal closed */ /* Clean up work, triggered when modal closed */
modalClosed() { modalClosed() {
this.$store.commit(StoreKeys.SET_MODAL_OPEN, false); this.$store.commit(StoreKeys.SET_MODAL_OPEN, false);
@ -276,13 +286,47 @@ export default {
} }
} }
/* Override form input colors, to use local CSS variables */ /* Override form element colors, with local CSS variables */
.input-container input.input-field, div.input-container input.input-field,
.radio-container div.radio-wrapper, .radio-container div.radio-wrapper,
.form-dropdown div.vs__dropdown-toggle { .form-dropdown div.vs__dropdown-toggle {
color: var(--interactive-editor-color); color: var(--interactive-editor-color);
background: var(--interactive-editor-background);
border-color: var(--interactive-editor-color); border-color: var(--interactive-editor-color);
background: var(--interactive-editor-background);
}
button.edit-item-save-btn {
color: var(--interactive-editor-color);
border-color: var(--interactive-editor-color);
background: var(--interactive-editor-background);
&:hover {
color: var(--interactive-editor-background);
border-color: var(--interactive-editor-color);
background: var(--interactive-editor-color);
}
}
svg {
path { fill: var(--interactive-editor-color); }
background: var(--interactive-editor-background);
&:hover, &.selected {
path { fill: var(--interactive-editor-background); }
background: var(--interactive-editor-color);
}
}
.edit-item-select .v-select {
input.vs__search { color: var(--interactive-editor-color); }
div.vs__dropdown-toggle {
border-color: var(--interactive-editor-color);
background: var(--interactive-editor-background);
span.vs__selected { color: var(--interactive-editor-color); }
.vs__actions svg {
background: var(--interactive-editor-background);
path { fill: var(--interactive-editor-color); }
&:hover {
background: var(--interactive-editor-color);
path { fill: var(--interactive-editor-background); }
}
}
}
} }
} }
</style> </style>