UNPKG

@blinkk/selective-edit

Version:
200 lines 7.15 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Fields = void 0; const preview_1 = require("../utility/preview"); const lit_html_1 = require("lit-html"); const mixins_1 = require("../mixins"); const data_1 = require("../mixins/data"); const deepObject_1 = require("../utility/deepObject"); const uuid_1 = require("../mixins/uuid"); const lodash_merge_1 = __importDefault(require("lodash.merge")); const repeat_js_1 = require("lit-html/directives/repeat.js"); /** * Fields control the display of a list of fields in the editor. */ class Fields extends (0, uuid_1.UuidMixin)((0, data_1.DataMixin)(mixins_1.Base)) { constructor(types, config, globalConfig) { super(); this.types = types; this.config = config; this.globalConfig = globalConfig; this.isLocked = false; this.fields = []; // Create the fields based on the config. for (const fieldConfig of this.config.fields || []) { this.addField(fieldConfig); } } addField(fieldConfig) { fieldConfig.parentKey = this.config.parentKey; fieldConfig.isGuessed = this.config.isGuessed; const newField = this.types.fields.newFromKey(fieldConfig.type, this.types, fieldConfig, this.globalConfig); if (!newField) { console.error(`Unable to add field for unknown field type: ${fieldConfig.type}.`); return; } this.fields.push(newField); } get allowSimple() { return !this.config.previewField && !this.config.previewFields; } /** * When there is no value, guess based on the known information about * the fields. */ guessDefaultValue() { // When there are multiple fields, default is an object. if (this.fields.length > 1) { return {}; } return ''; } /** * Checks if the value is clean (unchanged) from the original value. */ get isClean() { for (const field of this.fields) { if (!field.isClean) { return false; } } return true; } /** * Checks if the fields are simple and can be simplified in the display. */ get isSimple() { // Cannot be simple if there are more than one field. if (this.fields.length > 1) { return false; } // Allow the field to mark it as complex. for (const field of this.fields) { if (!field.isSimple) { return false; } } return true; } /** * Checks all the fields to find out if there are invalid fields. */ get isValid() { for (const field of this.fields) { if (!field.isValid) { return false; } } return true; } /** * Certain cases require the field to be locked while updating to prevent bad * data mixing. This allows for manually locking the fields. */ lock() { this.isLocked = true; // Lock all the fields to prevent them from being updated. for (const field of this.fields) { field.lock(); } } get previewFields() { return (0, preview_1.combinePreviewKeys)(this.config.previewFields, this.config.previewField); } reset() { this.fields = []; } /** * Template for determining how to render the fields. * * @param editor Selective editor used to render the template. * @param data Data provided to render the template. */ template(editor, data) { if (!this.fields.length) { return (0, lit_html_1.html) ``; } if (this.isSimple) { return (0, lit_html_1.html) ` ${this.updateOriginal(editor, data)} ${this.fields[0].template(editor, data)}`; } return (0, lit_html_1.html) `<div class="selective__fields"> ${this.updateOriginal(editor, data)} ${(0, repeat_js_1.repeat)(this.fields, (field) => field.uuid, (field) => (0, lit_html_1.html) ` ${field.template(editor, data)} `)} </div>`; } /** * Template for how to render a preview. * * @param editor Selective editor used to render the template. * @param data Data provided to render the template. */ templatePreviewValue( // eslint-disable-next-line @typescript-eslint/no-unused-vars editor, // eslint-disable-next-line @typescript-eslint/no-unused-vars data, index) { const defaultValue = 'Untitled item'; const previewValue = (0, preview_1.findOrGuessPreviewValue)(this.value, this.previewFields, defaultValue); return (0, preview_1.templatePreviewValue)(previewValue, this.config.previewType ? this.config.previewType : preview_1.PreviewTypes.Text, defaultValue, index); } /** * Certain cases require the field to be locked while updating to prevent bad * data mixing. This allows for manually unlocking the fields. */ unlock() { this.isLocked = false; // Lock all the fields to prevent them from being updated. for (const field of this.fields) { field.unlock(); } } /** * The data is not known to the fields until the rendering is done. * * Updated the original value from the data provided during rendering. * This gives a base set of values for clean checks and validation to use. * * @param editor Selective editor used to render the template. * @param data Data provided to render the template. * @param deep Update in fields as well, such as when the field is not visible. */ updateOriginal(editor, data, deep = false) { // Manual locking prevents the original value overwriting the value // in special cases when it should not. if (this.isLocked) { return; } this.originalValue = data; if (deep) { // Update all the fields since they may not get rendered. // Ex: a collapsed list would not get the update. for (const field of this.fields) { field.updateOriginal(editor, data); } } } /** * Returns the value from all of the fields in a single object. */ get value() { if (!this.fields.length) { return null; } if (this.allowSimple && this.isSimple && !this.fields[0].key) { return this.fields[0].value; } // Merging with the original value after setting values causes // issues where blank arrays are replaced by the original arrays. const value = new deepObject_1.DeepObject((0, lodash_merge_1.default)({}, this?.originalValue?.obj)); for (const field of this.fields) { value.set(field.key, field.value); } return value.obj; } } exports.Fields = Fields; //# sourceMappingURL=fields.js.map