From e566ec7cf02cd88e32980dd0268d2b3f21d4f6ff Mon Sep 17 00:00:00 2001 From: Tobias Klika Date: Thu, 23 Dec 2021 13:47:34 +0100 Subject: [PATCH] remove legacy stuff + allow custom components for editor-fields --- .../form-error-view.vue | 0 zero.Backoffice.UI/app/components/index.ts | 22 +- .../{forms => }/components/ui-check-list.vue | 0 .../{forms => }/components/ui-colorpicker.vue | 2 +- .../{forms => }/components/ui-datepicker.vue | 4 +- .../{forms => components}/ui-form-header.vue | 0 .../app/{forms => components}/ui-form.vue | 7 +- .../{forms => }/components/ui-property.vue | 0 .../components/ui-rte/rte.config.ts | 0 .../components/ui-rte/rte.extensions.ts | 0 .../components/ui-rte/rte.menubar.ts | 0 .../{forms => }/components/ui-rte/ui-rte.vue | 4 +- .../app/{forms => }/components/ui-search.vue | 0 .../app/{forms => }/components/ui-select.vue | 0 .../app/{forms => }/components/ui-toggle.vue | 0 zero.Backoffice.UI/app/core/zeroRuntime.ts | 11 - .../{legacy/fields => _fields}/alias.vue | 0 .../{legacy/fields => _fields}/checklist.vue | 0 .../fields => _fields}/colorpicker.vue | 0 .../fields => _fields}/countrypicker.vue | 0 .../fields => _fields}/culturepicker.vue | 0 .../{legacy/fields => _fields}/currency.vue | 0 .../{legacy/fields => _fields}/datepicker.vue | 0 .../fields => _fields}/daterangepicker.vue | 0 .../{legacy/fields => _fields}/iconPicker.vue | 0 .../{legacy/fields => _fields}/inputlist.vue | 0 .../{legacy/fields => _fields}/link.vue | 0 .../{legacy/fields => _fields}/linkpicker.vue | 0 .../fields => _fields}/mailtemplatepicker.vue | 0 .../{legacy/fields => _fields}/media.vue | 0 .../{legacy/fields => _fields}/modules.vue | 0 .../{legacy/fields => _fields}/nested.vue | 0 .../{legacy/fields => _fields}/pagepicker.vue | 0 .../fields => _fields}/password-hash.vue | 0 .../{legacy/fields => _fields}/password.vue | 0 .../{legacy/fields => _fields}/select.vue | 0 .../fields => _fields}/spacepicker.vue | 0 .../{legacy/fields => _fields}/tags.vue | 0 .../{legacy/fields => _fields}/video.vue | 0 zero.Backoffice.UI/app/editor/_new/editor.ts | 36 -- .../app/editor/_new/editorField.ts | 109 ---- .../app/editor/_new/editortypes.d.ts | 89 --- .../app/editor/_new/fields.d.ts | 34 - .../app/editor/_new/fields/text.vue | 32 - zero.Backoffice.UI/app/editor/_new/plugin.ts | 11 - zero.Backoffice.UI/app/editor/_new/types.ts | 120 ---- zero.Backoffice.UI/app/editor/compile.ts | 2 +- zero.Backoffice.UI/app/editor/editor-field.ts | 21 +- .../app/editor/editor-types.d.ts | 22 +- zero.Backoffice.UI/app/editor/editor.ts | 4 +- .../app/editor/legacy/blueprint/property.vue | 323 --------- .../app/editor/legacy/blueprint/settings.vue | 224 ------- .../app/editor/legacy/editor-field-props.ts | 15 - .../app/editor/legacy/editor-field.ts | 611 ------------------ .../app/editor/legacy/editor.ts | 360 ----------- .../app/editor/legacy/fields/static/line.vue | 11 - zero.Backoffice.UI/app/editor/legacy/index.ts | 5 - .../app/editor/legacy/register.ts | 12 - .../app/forms/components/index.ts | 19 - zero.Backoffice.UI/app/forms/index.ts | 7 - zero.Backoffice.UI/app/forms/register.ts | 19 - .../modules/media/pages/detail/metadata.vue | 28 +- .../app/modules/media/schemas/editor.ts | 19 +- zero.Backoffice.UI/app/schemas/list/list.ts | 4 +- zero.Backoffice.UI/app/schemas/schemas.d.ts | 11 - zero.Backoffice.UI/app/ui/app-navigation.vue | 1 - 66 files changed, 79 insertions(+), 2120 deletions(-) rename zero.Backoffice.UI/{app/forms => _notimplemented}/form-error-view.vue (100%) rename zero.Backoffice.UI/app/{forms => }/components/ui-check-list.vue (100%) rename zero.Backoffice.UI/app/{forms => }/components/ui-colorpicker.vue (97%) rename zero.Backoffice.UI/app/{forms => }/components/ui-datepicker.vue (96%) rename zero.Backoffice.UI/app/{forms => components}/ui-form-header.vue (100%) rename zero.Backoffice.UI/app/{forms => components}/ui-form.vue (98%) rename zero.Backoffice.UI/app/{forms => }/components/ui-property.vue (100%) rename zero.Backoffice.UI/app/{forms => }/components/ui-rte/rte.config.ts (100%) rename zero.Backoffice.UI/app/{forms => }/components/ui-rte/rte.extensions.ts (100%) rename zero.Backoffice.UI/app/{forms => }/components/ui-rte/rte.menubar.ts (100%) rename zero.Backoffice.UI/app/{forms => }/components/ui-rte/ui-rte.vue (98%) rename zero.Backoffice.UI/app/{forms => }/components/ui-search.vue (100%) rename zero.Backoffice.UI/app/{forms => }/components/ui-select.vue (100%) rename zero.Backoffice.UI/app/{forms => }/components/ui-toggle.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/alias.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/checklist.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/colorpicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/countrypicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/culturepicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/currency.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/datepicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/daterangepicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/iconPicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/inputlist.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/link.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/linkpicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/mailtemplatepicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/media.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/modules.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/nested.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/pagepicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/password-hash.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/password.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/select.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/spacepicker.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/tags.vue (100%) rename zero.Backoffice.UI/app/editor/{legacy/fields => _fields}/video.vue (100%) delete mode 100644 zero.Backoffice.UI/app/editor/_new/editor.ts delete mode 100644 zero.Backoffice.UI/app/editor/_new/editorField.ts delete mode 100644 zero.Backoffice.UI/app/editor/_new/editortypes.d.ts delete mode 100644 zero.Backoffice.UI/app/editor/_new/fields.d.ts delete mode 100644 zero.Backoffice.UI/app/editor/_new/fields/text.vue delete mode 100644 zero.Backoffice.UI/app/editor/_new/plugin.ts delete mode 100644 zero.Backoffice.UI/app/editor/_new/types.ts delete mode 100644 zero.Backoffice.UI/app/editor/legacy/blueprint/property.vue delete mode 100644 zero.Backoffice.UI/app/editor/legacy/blueprint/settings.vue delete mode 100644 zero.Backoffice.UI/app/editor/legacy/editor-field-props.ts delete mode 100644 zero.Backoffice.UI/app/editor/legacy/editor-field.ts delete mode 100644 zero.Backoffice.UI/app/editor/legacy/editor.ts delete mode 100644 zero.Backoffice.UI/app/editor/legacy/fields/static/line.vue delete mode 100644 zero.Backoffice.UI/app/editor/legacy/index.ts delete mode 100644 zero.Backoffice.UI/app/editor/legacy/register.ts delete mode 100644 zero.Backoffice.UI/app/forms/components/index.ts delete mode 100644 zero.Backoffice.UI/app/forms/index.ts delete mode 100644 zero.Backoffice.UI/app/forms/register.ts diff --git a/zero.Backoffice.UI/app/forms/form-error-view.vue b/zero.Backoffice.UI/_notimplemented/form-error-view.vue similarity index 100% rename from zero.Backoffice.UI/app/forms/form-error-view.vue rename to zero.Backoffice.UI/_notimplemented/form-error-view.vue diff --git a/zero.Backoffice.UI/app/components/index.ts b/zero.Backoffice.UI/app/components/index.ts index 4d6bb3a5..32c7b114 100644 --- a/zero.Backoffice.UI/app/components/index.ts +++ b/zero.Backoffice.UI/app/components/index.ts @@ -27,6 +27,16 @@ import uiPick from './ui-pick.vue'; import uiDatagrid from './ui-datagrid.vue'; import uiProgress from './ui-progress.vue'; import uiDate from './ui-date.vue'; +import uiRte from './ui-rte/ui-rte.vue'; +import uiCheckList from './ui-check-list.vue'; +import uiSearch from './ui-search.vue'; +import uiToggle from './ui-toggle.vue'; +import uiProperty from './ui-property.vue'; +import uiColorpicker from './ui-colorpicker.vue'; +import uiDatepicker from './ui-datepicker.vue'; +import uiSelect from './ui-select.vue'; +import uiForm from './ui-form.vue'; +import uiFormHeader from './ui-form-header.vue'; export { uiIcon, @@ -57,5 +67,15 @@ export { uiPick, uiDatagrid, uiProgress, - uiDate + uiDate, + uiRte, + uiCheckList, + uiSearch, + uiToggle, + uiProperty, + uiColorpicker, + uiDatepicker, + uiSelect, + uiForm, + uiFormHeader }; \ No newline at end of file diff --git a/zero.Backoffice.UI/app/forms/components/ui-check-list.vue b/zero.Backoffice.UI/app/components/ui-check-list.vue similarity index 100% rename from zero.Backoffice.UI/app/forms/components/ui-check-list.vue rename to zero.Backoffice.UI/app/components/ui-check-list.vue diff --git a/zero.Backoffice.UI/app/forms/components/ui-colorpicker.vue b/zero.Backoffice.UI/app/components/ui-colorpicker.vue similarity index 97% rename from zero.Backoffice.UI/app/forms/components/ui-colorpicker.vue rename to zero.Backoffice.UI/app/components/ui-colorpicker.vue index 978ac86e..686b2ebe 100644 --- a/zero.Backoffice.UI/app/forms/components/ui-colorpicker.vue +++ b/zero.Backoffice.UI/app/components/ui-colorpicker.vue @@ -10,7 +10,7 @@ \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/_new/plugin.ts b/zero.Backoffice.UI/app/editor/_new/plugin.ts deleted file mode 100644 index 2d6f1374..00000000 --- a/zero.Backoffice.UI/app/editor/_new/plugin.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineAsyncComponent } from 'vue'; -import { ZeroPlugin, ZeroPluginOptions } from '../../core'; - -export default { - name: "zero.editor", - - install(app: ZeroPluginOptions) - { - app.fieldType('text', defineAsyncComponent(() => import('./fields/text.vue'))); - } -} as ZeroPlugin; \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/_new/types.ts b/zero.Backoffice.UI/app/editor/_new/types.ts deleted file mode 100644 index 2b5438ec..00000000 --- a/zero.Backoffice.UI/app/editor/_new/types.ts +++ /dev/null @@ -1,120 +0,0 @@ - -import { Component, ComponentPropsOptions } from 'vue'; -import { proxy, fieldTypes } from '../editorFieldProxy'; -import TestCmp from './_testcmp.vue'; - -export interface ZeroEditor -{ - -} - - -export interface ZeroFieldType -{ - component: Promise; - options: any; -} - - - - -//const testField = { -// component: () => import('./_testcmp.vue'), -// options: { -// maxLength: { -// type: Number, -// default: null -// }, -// placeholder: { -// type: [String, Function], -// default: null -// } -// } - -//} as ZeroFieldType; - - -export class ZeroEditorCanvasBase -{ - field(path: string, component: Component): ZeroEditorField - { - return new ZeroEditorField(path, component); - } -} - - -export class ZeroEditorCanvasBaseWithFieldset extends ZeroEditorCanvasBase -{ - fieldset(): ZeroEditorCanvasBase - { - return new ZeroEditorCanvasBase(); - } -} - - -export class ZeroEditorCanvas extends ZeroEditorCanvasBaseWithFieldset -{ - tab(alias: string, name: string): ZeroEditorTab - { - return new ZeroEditorTab(alias, name); - } -} - - -export class ZeroEditorTab extends ZeroEditorCanvasBaseWithFieldset -{ - alias: string; - name: string; - - constructor(alias: string, name: string) - { - super(); - this.alias = alias; - this.name = name; - } -} - - -export declare type BooleanExpression = (model: TModel, value: TField) => boolean; - - -export class ZeroEditorField -{ - path: string; - component: Component; - - constructor(path: string, component: Component) - { - this.path = path; - this.component = component; - } - - when(condition: BooleanExpression): ZeroEditorField - { - return this; - } - - required(required: boolean | BooleanExpression): ZeroEditorField - { - return this; - } - - configure(opts: ComponentPropsOptions) - { - - } -} - - -export function test() -{ - fieldTypes.text = (maxLength?: number, placeholder?: string | Function) => console.log(`text() called with maxLength: ${maxLength}, placeholder: ${placeholder}`); - - proxy.text(17, 'Enter your text...'); - - //var editor = new ZeroEditorCanvas(); - - //editor.field('hi', TestCmp) - - //console.info(TestCmp.); -} \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/compile.ts b/zero.Backoffice.UI/app/editor/compile.ts index 5ba0adea..1c9fa376 100644 --- a/zero.Backoffice.UI/app/editor/compile.ts +++ b/zero.Backoffice.UI/app/editor/compile.ts @@ -59,7 +59,7 @@ export interface ZeroCompiledEditorField export function compileField(zero: Zero, editor: ZeroEditor, field: ZeroEditorField): ZeroCompiledEditorField | undefined { - const component = zero.getFieldTypeComponent(field.fieldType); + const component = field.customComponent || zero.getFieldTypeComponent(field.fieldType); if (!component) { diff --git a/zero.Backoffice.UI/app/editor/editor-field.ts b/zero.Backoffice.UI/app/editor/editor-field.ts index b3408979..e790754b 100644 --- a/zero.Backoffice.UI/app/editor/editor-field.ts +++ b/zero.Backoffice.UI/app/editor/editor-field.ts @@ -1,6 +1,6 @@ -import { ZeroEditorField } from "zero/schemas"; +import { Component } from "vue"; +import { ZeroEditorField } from "zero/schemas"; import { extendObject } from '../utils/objects'; -import { ZeroFieldType } from "./_new/types"; export declare type BooleanExpression = (model: any, value: any) => boolean; @@ -10,14 +10,16 @@ export const createFieldProxy = (field: ZeroEditorFieldImpl) => new Proxy(field, { // handle internals if (prop in target) - { - return target[prop]; // @tsignore + { + // @ts-ignore + return target[prop]; } // handle dynamic fields + extensions - return (args) => + return (args: any) => { - target.custom(prop, args); + target.fieldType = prop; + target.options = args; return target; }; } @@ -29,8 +31,9 @@ export class ZeroEditorFieldImpl implements ZeroEditorField { path: string; configuration: ZeroEditorFieldConfiguration; - fieldType: string; + fieldType: string | symbol; options?: any; + customComponent?: Component; constructor(path: string, config?: ZeroEditorFieldConfiguration) { @@ -87,9 +90,9 @@ export class ZeroEditorFieldImpl implements ZeroEditorField * @param {Component} component - The component to render (can be an async component too) * @param {T} [options] = Custom options to pass to this editor */ - custom(fieldType: string, options?: T): ZeroEditorField + component(component: Component, options?: any): ZeroEditorField { - this.fieldType = fieldType; + this.customComponent = component; this.options = options; return this; } diff --git a/zero.Backoffice.UI/app/editor/editor-types.d.ts b/zero.Backoffice.UI/app/editor/editor-types.d.ts index 8d90ad1a..9d704d3e 100644 --- a/zero.Backoffice.UI/app/editor/editor-types.d.ts +++ b/zero.Backoffice.UI/app/editor/editor-types.d.ts @@ -1,3 +1,4 @@ +import { Component } from "vue"; import { ZeroEditorFieldConfiguration } from "./editor-field"; declare module 'zero/schemas' @@ -33,13 +34,18 @@ declare module 'zero/schemas' /** * Type of the field which has to be registered in the zero runtime */ - fieldType: string; + fieldType: string | symbol; /** * Custom options which are passed to the component */ options?: any; + /** + * Set a custom render component for this field + */ + customComponent?: Component; + /** * Set this field as optional * @param {function|boolean} [condition] - Optionally only require this field when a condition is fulfilled or reset the required state with true/false @@ -69,18 +75,6 @@ declare module 'zero/schemas' * @param {Component} component - The component to render (can be an async component too) * @param {T} [options] = Custom options to pass to this editor */ - custom(component: Component, options?: T): ZeroEditorField; - - /** - * Set this field as required - * @param {function|boolean} [condition] - Optionally only require this field when a condition is fulfilled or reset the required state with true/false - */ - //text(options?: TextFieldOptions): EditorField; - - ///** - // * Set this field as required - // * @param {function|boolean} [condition] - Optionally only require this field when a condition is fulfilled or reset the required state with true/false - // */ - //number(options?: NumberFieldOptions): EditorField; + component(component: Component, options?: any): ZeroEditorField; } } \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/editor.ts b/zero.Backoffice.UI/app/editor/editor.ts index c9801868..08f3c9a9 100644 --- a/zero.Backoffice.UI/app/editor/editor.ts +++ b/zero.Backoffice.UI/app/editor/editor.ts @@ -1,7 +1,7 @@ -import { ZeroEditorField } from "zero/schemas"; +import { ZeroEditorField, ZeroSchema } from "zero/schemas"; import { ZeroEditorCanvas } from "./editor-canvas"; -export class ZeroEditor extends ZeroEditorCanvas +export class ZeroEditor extends ZeroEditorCanvas implements ZeroSchema { alias: string; diff --git a/zero.Backoffice.UI/app/editor/legacy/blueprint/property.vue b/zero.Backoffice.UI/app/editor/legacy/blueprint/property.vue deleted file mode 100644 index bb956763..00000000 --- a/zero.Backoffice.UI/app/editor/legacy/blueprint/property.vue +++ /dev/null @@ -1,323 +0,0 @@ - - - - - - - - - - - - diff --git a/zero.Backoffice.UI/app/editor/legacy/blueprint/settings.vue b/zero.Backoffice.UI/app/editor/legacy/blueprint/settings.vue deleted file mode 100644 index 17af9b90..00000000 --- a/zero.Backoffice.UI/app/editor/legacy/blueprint/settings.vue +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/legacy/editor-field-props.ts b/zero.Backoffice.UI/app/editor/legacy/editor-field-props.ts deleted file mode 100644 index f7c4098b..00000000 --- a/zero.Backoffice.UI/app/editor/legacy/editor-field-props.ts +++ /dev/null @@ -1,15 +0,0 @@ - -export interface EditorFieldMeta -{ - canEdit: boolean; -} - - -export interface EditorFieldProps -{ - value: T; - model: any; - meta: EditorFieldMeta; - disabled: boolean; - system: boolean; -} \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/legacy/editor-field.ts b/zero.Backoffice.UI/app/editor/legacy/editor-field.ts deleted file mode 100644 index 2a387575..00000000 --- a/zero.Backoffice.UI/app/editor/legacy/editor-field.ts +++ /dev/null @@ -1,611 +0,0 @@ - -class EditorField -{ - path = null; - - options = { - label: null, - hideLabel: false, - description: null, - helpText: null, - condition: null, - disabled: false, - tab: null, - allTabs: false, - vertical: true, - coreDatabase: false, - fieldset: null, - fieldsetColumns: null, - class: '', - onChange: null - }; - - _preview = { - icon: 'fth-filter', - preview: x => x, - hasValue: x => !!x - }; - - _component = null; - _componentOptions = {}; - _required = false; - _isReadOnly = false; - - constructor(path, options) - { - this.path = path; - this.options = { ...this.options, ...options }; - } - - - get component() - { - return this._component; - } - - get componentOptions() - { - return this._componentOptions; - } - - get isRequired() - { - return this._required; - } - - get previewOptions() - { - return this._preview; - } - - - /** - * Set another editor field as the base for this editor (copies properties) - * @param {EditorField} field - Base editor field - * @returns {EditorField} - */ - setBase(field) - { - this.path = field.path; - this.options = { ...field.options }; - this._preview = { ...field.previewOptions }; - this._component = field.component; - this._componentOptions = field.componentOptions; - this._required = field.isRequired; - return this; - } - - - /** - * - */ - _setComponent(component, options?) - { - this._component = component; - this._componentOptions = options || {}; - return this; - } - - - /** - * Sets the column count for this field, only available within a an editor fieldset - * @param {number} columnCount - Column count between 1 and 12 - * @returns {EditorField} - */ - cols(columnCount) - { - this.options.fieldsetColumns = columnCount < 1 ? 1 : (columnCount > 12 ? 12 : columnCount); - return this; - } - - - /** - * Whether the input is below the headline or next to it - * @param {boolean} isVertical - * @returns {EditorField} - */ - vertical(isVertical) - { - this.options.vertical = isVertical; - return this; - } - - - /** - * Set this field to disabled - */ - disabled() - { - this.options.disabled = true; - return this; - } - - - /** - * Set this field as required - * @param {function|boolean} [condition] - Optionally only require this field when a condition is fulfilled or reset the required state with true/false - */ - required(condition) - { - if (typeof condition === 'function') - { - this._required = condition; - } - else if (typeof condition === 'boolean') - { - this._required = condition; - } - else - { - this._required = true; - } - return this; - } - - - /** - * Conditionally render this field (this is an alternative method to the field options 'condition') - * @param {function} condition - function which returns a boolean and gets passed the current model - */ - when(condition) - { - this.options.condition = condition; - return this; - } - - - /** - * The expression argument is called when the value of the field changes - * @param {function} expression - function which is called - */ - onChange(expression) - { - this.options.onChange = expression; - return this; - } - - - /** - * Create a preview for this field - * This is only used in list filters, ... - * @param {object} options - Custom options - * @param {string} options.icon - Custom icon - * @param {string|function} options.preview - Render the preview when this filter has been filled out - * @param {boolean} options.hasValue - Determine if the filter has a value or not - * @returns {EditorField} - */ - preview(options) - { - this._preview = { ...this.preview, ...options }; - return this; - } - - - - - - - - - - - - /** - * Render a custom component - * @param {object} component - The custom vue component - * @param {object} [options] - Custom options - * @returns {EditorField} - */ - custom(component, options) - { - return this._setComponent(component, { ...options }); - } - - - /** - * Render a text input field - * @param {number} [maxLength] - Maximum length of the input - * @param {string|function} [placeholder] - Placeholder text (can be a translation) or function - * @returns {EditorField} - */ - text(maxLength, placeholder) - { - return this._setComponent(() => import('./fields/text.vue'), { maxLength, placeholder }); - } - - - /** - * Render a password input field - * @param {number} [maxLength] - Maximum length of the input - * @param {string|function} [placeholder] - Placeholder text (can be a translation) or function - * @returns {EditorField} - */ - password(maxLength, placeholder) - { - return this._setComponent(() => import('./fields/password.vue'), { maxLength, placeholder }); - } - - - /** - * Render a password hash field - * @param {number} [maxLength] - Maximum length of the password - * @returns {EditorField} - */ - passwordHash(maxLength) - { - return this._setComponent(() => import('./fields/password-hash.vue'), { maxLength }); - } - - - /** - * Render a currency input field - * @param {string|function} [placeholder] - Placeholder text (can be a translation) or function - * @returns {EditorField} - */ - currency(placeholder) - { - return this._setComponent(() => import('./fields/currency.vue'), { placeholder }); - } - - - /** - * Render a number input field - * @param {number} [maxLength] - Maximum length of the input - * @param {string|function} [placeholder] - Placeholder text (can be a translation) or function - * @returns {EditorField} - */ - number(maxLength, placeholder) - { - return this._setComponent(() => import('./fields/number.vue'), { maxLength, placeholder }); - } - - - /** - * Render a rich-text editor field - * @param {object} [options] - Custom options - * @param {number} [options.maxLength=null] - Maximum characters - * @param {string} [options.placeholder=null] - Placeholder text (can be a translation) or function - * @param {function} [options.setup=value] - Called on RTE setup - * @returns {EditorField} - */ - rte(options) - { - return this._setComponent(() => import('./fields/rte.vue'), { ...options }); - } - - - /** - * @typedef {object} EditorSelectItem - * @param {object} key - Key/Id of the item - * @param {string} value - Label/Value of the item (can be a translation) - */ - - /** - * Render a select dropdown with the specified items - * @param {EditorSelectItem[]|function} items - Set items to pick from - * @param {object} [options] - Custom options - * @param {number} [options.emptyOption=false] - Adds an empty option so the field can be blank - * @returns {EditorField} - */ - select(items, options) - { - return this._setComponent(() => import('./fields/select.vue'), { items, ...options }); - } - - - /** - * Render a text area - * @param {number} [maxLength] - Maximum length of the input - * @returns {EditorField} - */ - textarea(maxLength) - { - return this._setComponent(() => import('./fields/textarea.vue'), { maxLength }); - } - - - /** - * Render a toggle - * @param {boolean} [negative] - Toggle with a negative color / red background - * @param {object} [options] - Custom options - * @param {number} [options.negative=false] - Display the toggle in red when set to TRUE - * @param {number} [options.onContent=null] - Text next to toggle when it is set to TRUE - * @param {number} [options.offContent=null] - Text next to toggle when it is set to FALSE - * @returns {EditorField} - */ - toggle(options) - { - this.options.vertical = false; - return this._setComponent(() => import('./fields/toggle.vue'), { ...options }); - } - - - /** - * Renders the field value - * @param {function} [render] - Render the output based on the given function - * @returns {EditorField} - */ - output(render) - { - this._isReadOnly = true; - return this._setComponent(() => import('./fields/output.vue'), { render }); - } - - - /** - * Renders an input which generates an alias for a given name or an alternative custom alias - * @param {string} [namePath] - Optional path to the name value which is used to auto-generate the alias - * @returns {EditorField} - */ - alias(namePath) - { - return this._setComponent(() => import('./fields/alias.vue'), { namePath }); - } - - - /** - * Renders an input which generates an alias for a given name or an alternative custom alias - * @param {EditorSelectItem[]|function} items - Set items to choose from, either via an array or a promise which returns such array - * @param {object} [options] - Custom options - * @param {number} [options.limit=100] - Maximum items to be checked - * @param {boolean} [options.reverse=false] - Reverse the checklist behaviour, so all items are checked by default and unchecking them adds them to the result list - * @param {string} [options.labelKey=value] - Object key to get the label - * @param {string} [options.idKey=key] - Object key to get the id - * @returns {EditorField} - */ - checkList(items, options) - { - return this._setComponent(() => import('./fields/checklist.vue'), { items, ...options }); - } - - - /** - * Renders a HEX color picker - * @returns {EditorField} - */ - colorPicker() - { - return this._setComponent(() => import('./fields/colorpicker.vue')); - } - - - /** - * Renders a country picker - * @param {number} [limit=1] - Maximum items to be selected - * @returns {EditorField} - */ - countryPicker(limit) - { - return this._setComponent(() => import('./fields/countrypicker.vue'), { limit }); - } - - - /** - * Renders a space picker - * @param {number} [limit=1] - Maximum items to be selected - * @returns {EditorField} - */ - spacePicker(limit) - { - return this._setComponent(() => import('./fields/spacepicker.vue'), { limit }); - } - - - /** - * Renders a culture picker - * @returns {EditorField} - */ - culturePicker() - { - return this._setComponent(() => import('./fields/culturepicker.vue')); - } - - - /** - * Renders a mail template picker - * @param {number} [limit=1] - Maximum items to be selected - * @returns {EditorField} - */ - mailTemplatePicker(limit) - { - return this._setComponent(() => import('./fields/mailtemplatepicker.vue'), { limit }); - } - - - /** - * Renders a date picker - * @param {object} [options] - Custom options - * @param {string} [options.format] - Format the date output - * @param {boolean} [options.time=false] - Allow time input - * @param {string|Date} [options.maxDate] - Maximum selectable date - * @param {string|Date} [options.minDate] - Minimum selectable date - * @param {string} [options.amPm] - Render time as AM/PM - * @returns {EditorField} - */ - datePicker(options) - { - return this._setComponent(() => import('./fields/datepicker.vue'), { ...options }); - } - - - /** - * Renders a date range picker - * @param {object} [options] - Custom options - * @param {string} [options.format] - Format the date output - * @param {boolean} [options.time=false] - Allow time input - * @param {string|Date} [options.maxDate] - Maximum selectable date - * @param {string|Date} [options.minDate] - Minimum selectable date - * @param {string} [options.fromLabel] - Label next to the "from" date input - * @param {string} [options.toLabel] - Label next to the "to" date input - * @param {string} [options.amPm] - Render time as AM/PM - * @param {string} [options.inline] - Don't render the range picker on an overlay - * @returns {EditorField} - */ - dateRangePicker(options) - { - return this._setComponent(() => import('./fields/daterangepicker.vue'), { ...options }); - } - - - /** - * Pick an icon from the specified icon collection - * @param {string} [iconSetAlias] - Custom icon set alias (defined in ZeroOptions.Icons) - * @returns {EditorField} - */ - iconPicker(iconSetAlias) - { - return this._setComponent(() => import('./fields/iconPicker.vue'), { set: iconSetAlias }); - } - - - /** - * Renders a page picker - * @param {object} [options] - Custom options - * @param {number} [options.limit=1] - Limit of selection - * @returns {EditorField} - */ - pagePicker(options) - { - return this._setComponent(() => import('./fields/pagepicker.vue'), { ...options }); - } - - - /** - * Render a link picker - * @param {object} [options] - Custom options - * @param {number} [options.limit=1] - Limit of selection - * @param {boolean} [options.title=true] - Allow input of custom link title - * @param {boolean} [options.target=true] - Allow selection of the link target - * @param {boolean} [options.label=false] - Allow input of a custom label for button generation - * @param {boolean} [options.suffix=false] - Allow input of custom link URL suffix (query or hash) - * @param {string[]} [options.areas] - Limit link areas to the specified values (built-in are zero.pages, zero.media and zero.url) - * @returns {EditorField} - */ - linkPicker(options) - { - return this._setComponent(() => import('./fields/linkpicker.vue'), { ...options }); - } - - - /** - * Create a list of strings - * @param {number} [limit=10] - Limit the inputs - * @param {number} [maxItemLength=200] - Maximum length for an item input - * @param {string} [addLabel] - Label for the add button - * @returns {EditorField} - */ - inputList(limit, maxItemLength, addLabel) - { - return this._setComponent(() => import('./fields/inputlist.vue'), { limit, maxItemLength, addLabel }); - } - - - /** - * Append tags to an entity - * @param {number} [limit=10] - Limit the tags - * @param {number} [maxItemLength=200] - Maximum length for a tag - * @returns {EditorField} - */ - tags(limit, maxItemLength) - { - return this._setComponent(() => import('./fields/tags.vue'), { limit, maxItemLength }); - } - - - /** - * Pick a language - * @returns {EditorField} - */ - languagePicker() - { - return this._setComponent(() => import('./fields/language.vue')); - } - - - /** - * Display a module renderer which allows you to select from defined modules - * @param {string[]} [tags] - Only allow selection of modules which match defined tags - * @returns {EditorField} - */ - modules(tags) - { - return this._setComponent(() => import('./fields/modules.vue'), { tags }); - } - - - /** - * Display a module renderer which allows you to select from defined modules - * @param {Editor} [editor] - Use the specified editor for each item - * @param {object} [options] - Custom options - * @param {number} [options.limit=100] - Limit the creation of items - * @param {string} [options.title] - Headline in the editor overlay - * @param {string} [options.addLabel] - Label for the add button - * @param {function} [options.itemLabel] - Function which generates the label for the current item - * @param {function} [options.itemDescription] - Function which generates the description for the current item - * @param {string|function} [options.itemIcon] - Static icon or function which generates the icon for the current item - * @param {object} [options.template] - Template which is used when adding an item - * @param {object} [options.width=820] - Width of the overlay panel - * @returns {EditorField} - */ - nested(editor, options) - { - return this._setComponent(() => import('./fields/nested.vue'), { editor, ...options }); - } - - - /** - * Render a select as a button group - * @param {EditorSelectItem[]} items - Set items to choose from - * @returns {EditorField} - */ - state(items) - { - return this._setComponent(() => import('./fields/state.vue'), { items }); - } - - - /** - * Render a media upload + picker - * @param {object} [options] - Custom options - * @param {number} [options.limit=1] - Limit the media select count - * @param {boolean} [options.disallowSelect=false] - Disallow the selection (only upload) of media items - * @param {boolean} [options.disallowUpload=false] - Disallow upload (only selection) of media items - * @param {string[]} [options.fileExtensions] - Allow upload + selection only for the specified file extensions - * @param {number} [options.maxFileSize=10] - Maximum allowed file size for uploads in Mibibytes - * @returns {EditorField} - */ - media(options) - { - return this._setComponent(() => import('./fields/media.vue'), { ...options }); - } - - - /** - * Render a media upload + picker - * @param {object} [options] - Custom options - * @param {number} [options.limit=1] - Limit the media select count - * @param {boolean} [options.disallowSelect=false] - Disallow the selection (only upload) of media items - * @param {boolean} [options.disallowUpload=false] - Disallow upload (only selection) of media items - * @param {string[]} [options.fileExtensions] - Allow upload + selection only for the specified file extensions - * @param {number} [options.maxFileSize=10] - Maximum allowed file size for uploads in Mibibytes - * @returns {EditorField} - */ - image(options) - { - return this._setComponent(() => import('./fields/media.vue'), { ...options, fileExtensions: ['.jpg', '.jpeg', '.png', '.webp', '.svg'] }); - } - - - /** - * Render a video (YouTube/vimeo) picker - * @param {number} [limit=1] - Limit the videos - * @returns {EditorField} - */ - video(limit) - { - return this._setComponent(() => import('./fields/video.vue'), { limit }); - } -} - - -export default EditorField; \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/legacy/editor.ts b/zero.Backoffice.UI/app/editor/legacy/editor.ts deleted file mode 100644 index d1fcf0f3..00000000 --- a/zero.Backoffice.UI/app/editor/legacy/editor.ts +++ /dev/null @@ -1,360 +0,0 @@ - -import { generateId } from '../utils/numbers'; -import EditorField from './editor-field'; - -class Editor -{ - _alias; - _prefix; - - _preview = { - icon: null, - template: null, - hideLabel: false - }; - - /** - * Overrides the string generation for the label - */ - templateLabel = field => this._prefix + field; - /** - * Overrides the string generation for the description - */ - templateDescription = field => this._prefix + field + '_text'; - - tabs = []; - fields = []; - - blueprintAlias?: string; - - options = { - disabled: false, - display: 'tabs', - coreDatabase: false - }; - - - constructor(prefix) - { - this._alias = null; - this._prefix = prefix || ''; - } - - - get alias() - { - return this._alias; - } - - get previewOptions() - { - return this._preview; - } - - - /** - * A tab within an editor - * @typedef {object} EditorTab - * @param {string} alias - Alias for the tab - * @param {string} name - Name of the tab (can be a translation) - * @param {number|function} [count] - Output a count indicator - * @param {boolean|function} [disabled] - Conditionally disable the tab and its content - */ - - /** - * Add a new tab to the editor or returns the tab in case it was already added - * @param {string} alias - Alias for the tab - * @param {string} name - Name of the tab (can be a translation) - * @param {number|function} [count] - Output a count indicator - * @param {boolean|function} [disabled] - Conditionally disable the tab and its content - * @param {string} [classes] - Append HTML class to the generated tab - * @param {object} [component] - Render a custom vue component instead of editor fields - * @returns {EditorTab} - */ - tab(alias, name, count, disabled, classes, component) - { - if (typeof disabled !== 'undefined' && disabled != null && typeof disabled !== 'boolean' && typeof disabled !== 'function') - { - console.warn(`[zero] editor.tab: the disabled property has to be of type [boolean, function, undefined]`); - return; - } - - if (typeof count !== 'undefined' && count != null && typeof count !== 'number' && typeof count !== 'function') - { - console.warn(`[zero] editor.tab: the count property has to be of type [number, function, undefined]`); - return; - } - - let tab = this.tabs.find(x => x.alias === alias); - - if (!tab) - { - tab = this._createTab(alias, name, disabled, count, classes, component); - this.tabs.push(tab); - } - - return tab; - } - - - /** - * Add a new field to the editor or returns the field in case it was already added - * @param {string} path - Model path - * @param {object} [options] - Custom options - * @param {string} [options.label] - A custom label for this field (otherwise it's generated via `onLabelCreate`) - * @param {string} [options.hideLabel] - Hide the field label and make the content full-width - * @param {string} [options.description] - A custom description for this field (otherwise it's generated via `onDescriptionCreate`) - * @param {string} [options.helpText] - Display a help text below the field - * @param {boolean|function} [options.condition] - Conditionally hide the field - * @param {boolean|function} [options.disabled=false] - Conditionally disable the field - * @param {boolean} [options.coreDatabase] - Operate on the core database for this field (default is set by Editor.options.coreDatabase) - * @param {string|object} [options.tab] - Add this field to a tab (by passing the alias or the tab instance) - * @param {boolean} [options.allTabs] - Add this field to all defined tabs (could be an information property for instance) - * @param {string} [options.classes] - Append HTML class to the generated property - * @returns {EditorField} - */ - field(path, options) - { - options = options || {}; - - //let field = this.fields.find(x => x.path === path); - // TODO we need another method to retrieve existing fields - // but we can't do it this way anymore as sometimes a field is defined multiple times with a condition - - if (this.tabs.length < 1) - { - this.tab('content', '@ui.tab_content', x => 0, x => false, null, null); - } - - //if (!field) - //{ - if (typeof options.coreDatabase === 'undefined') - { - options.coreDatabase = this.options.coreDatabase; - } - if (!options.tab) - { - options.tab = 'content'; - } - let field = new EditorField(path, options); - this.fields.push(field); - //} - //else - //{ - // field.options = { ...field.options, ...options }; - //} - - return field; - } - - - /** - * Add a new fieldset to the editor or returns the tab in case it was already added - * A fieldset combines properties in a row (side-by-side) - * @param {function} [configure] - Configures the fieldset - */ - fieldset(configure) - { - let set = this._createFieldset(); - configure(set); - } - - - /** - * Adds an info tab to the editor which outputs data for ZeroEntity. - * This won't work as expected for other entities as they probably do not have required properties defined. - * @returns {EditorTab} - */ - infoTab() - { - return this.tab('infos', '@ui.tab_infos', x => 0, false, 'is-blank', () => import('./editor-infos.vue')); - } - - - /** - * Conditionally disable this editor - * @param {function|boolean} [condition] - Optionally only disable this editor when a condition is fulfilled or reset the required state with true/false - */ - disabled(condition) - { - this.options.disabled = condition; - return this; - } - - - /** - * Get fields for the specified tab - * @param {string|EditorTab} [tab] - Pass the tab or its alias - * @returns {EditorField[]} - */ - getFields(tab) - { - const alias = typeof tab === 'undefined' ? null : (typeof tab === 'string' ? tab : tab.alias); - return this.fields.filter(x => !alias || x.options.allTabs ? true : x.options.tab === alias);; - } - - - /** - * Get fields grouped in fieldsets for the specified tab - * @param {string|EditorTab} [tab] - Pass the tab or its alias - * @returns {EditorField[]} - */ - getFieldsets(tab) - { - let fields = this.getFields(tab); - let currentFieldset = "__undefined"; - let fieldsets = []; - - fields.forEach(field => - { - if (field.options.fieldset != currentFieldset || !field.options.fieldset) - { - currentFieldset = field.options.fieldset; - fieldsets.push({ - fields: [], - cols: [] - }); - } - - fieldsets[fieldsets.length - 1].fields.push(field); - fieldsets[fieldsets.length - 1].cols.push(field.options.fieldsetColumns); - }); - - fieldsets.forEach(fieldset => - { - fieldset.count = fieldset.fields.length; - let reserved = fieldset.cols.reduce((acc, x) => acc + (x || 0), 0); - let rest = reserved < 1 ? 12 : (12 - reserved) % 12; - let columnsToFill = fieldset.cols.filter(x => !x).length; - let perColumn = Math.floor(rest / columnsToFill); - - fieldset.fields.forEach(field => - { - if (!field.options.fieldsetColumns) - { - field.options.fieldsetColumns = perColumn; - } - }); - }); - - return fieldsets; - } - - - /** - * Removes a field by path name - * @param {string} path - Model path - */ - removeField(path) - { - const field = this.fields.find(x => x.path === path); - - if (field != null) - { - const index = this.fields.indexOf(field); - this.fields.splice(index, 1); - } - } - - - /** - * Removes a tab from the editor - * @param {EditorTab|string} tab - The tab to remove - */ - removeTab(tab) - { - const alias = typeof tab === 'object' ? tab.alias : tab; - const foundTab = this.tabs.find(x => x.alias === alias); - - if (foundTab != null) - { - const index = this.tabs.indexOf(foundTab); - this.tabs.splice(index, 1); - - this.fields.filter(x => x.tab === alias).forEach(field => this.removeField(field.path)); - } - } - - - /** - * Set another editor as the base for this editor (copies fields and tabs) - * @param {Editor} editor - Base editor - * @returns {Editor} - */ - setBase(editor) - { - this.fields = editor.fields.map(x => new EditorField(x.path).setBase(x)); - this.tabs = editor.tabs.map(x => this._createTab(x.alias, x.name, x.disabled, x.count, x.component)); - this._preview = { ...editor.previewOptions }; - return this; - } - - - /** - * Create a preview for this editor - * This is primarly used for module previews - * @param {string|object} template - A vue template string (`model` is passed as property for the module content) or a custom vue component - * @param {object} [options] - Custom options - * @param {number} [options.icon] - Custom icon - * @param {number} [options.hideLabel=false] - Whether to hide the displayed module-type label in the preview - * @returns {Editor} - */ - preview(template, options) - { - this._preview = { ...this._preview, template, ...options }; - return this; - } - - - /** - * Create a new tab instance - * @returns {EditorTab} - */ - _createTab(alias, name, disabled, count, classes, component) - { - return { - alias, - name, - disabled, - count, - class: classes, - component, - field: (path, options) => - { - options = options || {}; - options.tab = alias; - return this.field(path, options); - }, - fieldset: configure => - { - let set = this._createFieldset(alias); - configure(set); - }, - removeField: path => this.removeField(path) - }; - } - - - /** - * Create a new fieldset - */ - _createFieldset(tab) - { - let id = generateId(); - - return { - id, - field: (path, options) => - { - options = options || {}; - options.fieldset = id; - options.tab = tab; - return this.field(path, options); - }, - removeField: path => this.removeField(path) - }; - } - -}; - -export default Editor; \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/legacy/fields/static/line.vue b/zero.Backoffice.UI/app/editor/legacy/fields/static/line.vue deleted file mode 100644 index f39baecd..00000000 --- a/zero.Backoffice.UI/app/editor/legacy/fields/static/line.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/legacy/index.ts b/zero.Backoffice.UI/app/editor/legacy/index.ts deleted file mode 100644 index baf77b54..00000000 --- a/zero.Backoffice.UI/app/editor/legacy/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import uiEditor from './editor.vue'; - -export { - uiEditor -}; \ No newline at end of file diff --git a/zero.Backoffice.UI/app/editor/legacy/register.ts b/zero.Backoffice.UI/app/editor/legacy/register.ts deleted file mode 100644 index 736b39d6..00000000 --- a/zero.Backoffice.UI/app/editor/legacy/register.ts +++ /dev/null @@ -1,12 +0,0 @@ - -import { App } from 'vue'; -import * as components from './index'; - -export default function (app: App) -{ - for (var key in components) - { - let component = components[key]; - app.component(key, component.default || component); - } -}; \ No newline at end of file diff --git a/zero.Backoffice.UI/app/forms/components/index.ts b/zero.Backoffice.UI/app/forms/components/index.ts deleted file mode 100644 index f77d10c8..00000000 --- a/zero.Backoffice.UI/app/forms/components/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import uiRte from './ui-rte/ui-rte.vue'; -import uiCheckList from './ui-check-list.vue'; -import uiSearch from './ui-search.vue'; -import uiToggle from './ui-toggle.vue'; -import uiProperty from './ui-property.vue'; -import uiColorpicker from './ui-colorpicker.vue'; -import uiDatepicker from './ui-datepicker.vue'; -import uiSelect from './ui-select.vue'; - -export { - uiRte, - uiCheckList, - uiSearch, - uiToggle, - uiProperty, - uiColorpicker, - uiDatepicker, - uiSelect -}; \ No newline at end of file diff --git a/zero.Backoffice.UI/app/forms/index.ts b/zero.Backoffice.UI/app/forms/index.ts deleted file mode 100644 index c4390d0a..00000000 --- a/zero.Backoffice.UI/app/forms/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import uiForm from './ui-form.vue'; -import uiFormHeader from './ui-form-header.vue'; - -export { - uiForm, - uiFormHeader -}; \ No newline at end of file diff --git a/zero.Backoffice.UI/app/forms/register.ts b/zero.Backoffice.UI/app/forms/register.ts deleted file mode 100644 index 1c15ed6f..00000000 --- a/zero.Backoffice.UI/app/forms/register.ts +++ /dev/null @@ -1,19 +0,0 @@ - -import { App } from 'vue'; -import * as partials from './components/index'; -import * as components from './index'; - -export default function (app: App) -{ - for (var key in partials) - { - let component = partials[key]; - app.component(key, component.default || component); - } - - for (var key in components) - { - let component = components[key]; - app.component(key, component.default || component); - } -}; \ No newline at end of file diff --git a/zero.Backoffice.UI/app/modules/media/pages/detail/metadata.vue b/zero.Backoffice.UI/app/modules/media/pages/detail/metadata.vue index dba99d30..7b22b761 100644 --- a/zero.Backoffice.UI/app/modules/media/pages/detail/metadata.vue +++ b/zero.Backoffice.UI/app/modules/media/pages/detail/metadata.vue @@ -1,26 +1,26 @@