Fixed ui errors to do with ck-editor
This commit is contained in:
parent
49bac1091a
commit
9565b80fb1
@ -5,7 +5,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mailTemplate-editor {
|
.mailTemplate-editor {
|
||||||
width: calc(100% - ($gridGap + $mailtemplateNameListWidth));
|
//width: calc(100% - ($gridGap + $mailtemplateNameListWidth));
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
@ -17,7 +18,7 @@
|
|||||||
.ck-main-container {
|
.ck-main-container {
|
||||||
// --ckeditor5-preview-height: 700px;
|
// --ckeditor5-preview-height: 700px;
|
||||||
font-family: "Lato";
|
font-family: "Lato";
|
||||||
width: fit-content;
|
width: 100%;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
|
||||||
@ -35,6 +36,7 @@
|
|||||||
font-family: "Lato";
|
font-family: "Lato";
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
color: var(--bs-body-color);
|
||||||
|
|
||||||
.table table {
|
.table table {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -42,8 +44,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.editor-container__editor-wrapper {
|
.editor-container__editor-wrapper {
|
||||||
display: flex;
|
width: 100%;
|
||||||
width: fit-content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-container_document-editor {
|
.editor-container_document-editor {
|
||||||
@ -96,12 +97,12 @@
|
|||||||
//min-width: calc(100vw - ($leftMenuWidth + ($frameWorkAreaPadding * 2)));
|
//min-width: calc(100vw - ($leftMenuWidth + ($frameWorkAreaPadding * 2)));
|
||||||
//max-width: calc(100vw - ($leftMenuWidth + ($frameWorkAreaPadding * 2)));
|
//max-width: calc(100vw - ($leftMenuWidth + ($frameWorkAreaPadding * 2)));
|
||||||
|
|
||||||
min-width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
|
||||||
|
|
||||||
// min-width: calc(210mm + 2px);
|
// min-width: calc(210mm + 2px);
|
||||||
// max-width: calc(210mm + 2px);
|
// max-width: calc(210mm + 2px);
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
|
|
||||||
// padding: 20mm 12mm;
|
// padding: 20mm 12mm;
|
||||||
border: 1px hsl(0, 0%, 82.7%) solid;
|
border: 1px hsl(0, 0%, 82.7%) solid;
|
||||||
//background: hsl(0, 0%, 100%);
|
//background: hsl(0, 0%, 100%);
|
||||||
|
|||||||
@ -11,6 +11,7 @@ export interface SelectProps {
|
|||||||
value: unknown;
|
value: unknown;
|
||||||
options?: Option[];
|
options?: Option[];
|
||||||
includeBlankFirstEntry?: boolean;
|
includeBlankFirstEntry?: boolean;
|
||||||
|
multiple?: boolean;
|
||||||
onChange?: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
onChange?: (e: React.ChangeEvent<HTMLSelectElement>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,6 +21,24 @@ function GenerateValue(value: unknown) {
|
|||||||
return value as string | number | readonly string[] | undefined;
|
return value as string | number | readonly string[] | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function NormalizeSelectValue(value: unknown, isMultiple: boolean) {
|
||||||
|
const actualValue = GenerateValue(value);
|
||||||
|
|
||||||
|
if (!isMultiple) {
|
||||||
|
return actualValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(actualValue)) {
|
||||||
|
return actualValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actualValue === undefined || actualValue === null || actualValue === "") {
|
||||||
|
return [] as readonly string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [actualValue] as readonly (string | number)[];
|
||||||
|
}
|
||||||
|
|
||||||
export default function Select({
|
export default function Select({
|
||||||
includeLabel,
|
includeLabel,
|
||||||
name,
|
name,
|
||||||
@ -28,11 +47,13 @@ export default function Select({
|
|||||||
value,
|
value,
|
||||||
options,
|
options,
|
||||||
includeBlankFirstEntry,
|
includeBlankFirstEntry,
|
||||||
|
multiple,
|
||||||
onChange,
|
onChange,
|
||||||
...rest
|
...rest
|
||||||
}: SelectProps) {
|
}: SelectProps) {
|
||||||
const { t } = useTranslation<typeof Namespaces.Common>();
|
const { t } = useTranslation<typeof Namespaces.Common>();
|
||||||
const actualValue = GenerateValue(value);
|
const isMultiple = multiple ?? options === undefined;
|
||||||
|
const actualValue = NormalizeSelectValue(value, isMultiple);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
@ -41,7 +62,7 @@ export default function Select({
|
|||||||
)}
|
)}
|
||||||
{!options && (
|
{!options && (
|
||||||
<select
|
<select
|
||||||
multiple
|
multiple={isMultiple}
|
||||||
{...rest}
|
{...rest}
|
||||||
id={name}
|
id={name}
|
||||||
value={actualValue}
|
value={actualValue}
|
||||||
@ -54,6 +75,7 @@ export default function Select({
|
|||||||
)}
|
)}
|
||||||
{options && (
|
{options && (
|
||||||
<select
|
<select
|
||||||
|
multiple={isMultiple}
|
||||||
{...rest}
|
{...rest}
|
||||||
id={name}
|
id={name}
|
||||||
value={actualValue}
|
value={actualValue}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect, useRef } from 'react';
|
import { useState, useEffect, useRef } from "react";
|
||||||
import { CKEditor } from '@ckeditor/ckeditor5-react';
|
import { CKEditor } from "@ckeditor/ckeditor5-react";
|
||||||
import Field from './plugins/field/field';
|
import Field from "./plugins/field/field";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
DecoupledEditor,
|
DecoupledEditor,
|
||||||
@ -66,10 +66,10 @@ import {
|
|||||||
TextTransformation,
|
TextTransformation,
|
||||||
TodoList,
|
TodoList,
|
||||||
Underline,
|
Underline,
|
||||||
Undo
|
Undo,
|
||||||
} from 'ckeditor5';
|
} from "ckeditor5";
|
||||||
|
|
||||||
import 'ckeditor5/ckeditor5.css';
|
import "ckeditor5/ckeditor5.css";
|
||||||
|
|
||||||
// export interface TextEditorProps {
|
// export interface TextEditorProps {
|
||||||
// className : String;
|
// className : String;
|
||||||
@ -93,34 +93,34 @@ export default function TextEditor( props ) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
let toobarItems = [
|
let toobarItems = [
|
||||||
'undo',
|
"undo",
|
||||||
'redo',
|
"redo",
|
||||||
'|',
|
"|",
|
||||||
'heading',
|
"heading",
|
||||||
'|',
|
"|",
|
||||||
'fontSize',
|
"fontSize",
|
||||||
'fontFamily',
|
"fontFamily",
|
||||||
'fontColor',
|
"fontColor",
|
||||||
'fontBackgroundColor',
|
"fontBackgroundColor",
|
||||||
'|',
|
"|",
|
||||||
'bold',
|
"bold",
|
||||||
'italic',
|
"italic",
|
||||||
'underline',
|
"underline",
|
||||||
'|',
|
"|",
|
||||||
'link',
|
"link",
|
||||||
'insertImage',
|
"insertImage",
|
||||||
'insertTable',
|
"insertTable",
|
||||||
'highlight',
|
"highlight",
|
||||||
'blockQuote',
|
"blockQuote",
|
||||||
'codeBlock',
|
"codeBlock",
|
||||||
'|',
|
"|",
|
||||||
'alignment',
|
"alignment",
|
||||||
'|',
|
"|",
|
||||||
'bulletedList',
|
"bulletedList",
|
||||||
'numberedList',
|
"numberedList",
|
||||||
'todoList',
|
"todoList",
|
||||||
'outdent',
|
"outdent",
|
||||||
'indent',
|
"indent",
|
||||||
];
|
];
|
||||||
|
|
||||||
let plugins = [
|
let plugins = [
|
||||||
@ -186,109 +186,123 @@ export default function TextEditor( props ) {
|
|||||||
TextTransformation,
|
TextTransformation,
|
||||||
TodoList,
|
TodoList,
|
||||||
Underline,
|
Underline,
|
||||||
Undo
|
Undo,
|
||||||
];
|
];
|
||||||
|
|
||||||
let customfields = []
|
let customfields = [];
|
||||||
|
|
||||||
if (props.customFields && props.customFields.length > 0) {
|
if (props.customFields && props.customFields.length > 0) {
|
||||||
toobarItems.push( '|' );
|
toobarItems.push("|");
|
||||||
toobarItems.push( 'Field' );
|
toobarItems.push("Field");
|
||||||
plugins.push(Field);
|
plugins.push(Field);
|
||||||
customfields = props.customFields;
|
customfields = props.customFields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const licenseKey = window.__RUNTIME_CONFIG__?.CKEDITOR_LICENSE_KEY || "GPL";
|
||||||
|
|
||||||
const editorConfig = {
|
const editorConfig = {
|
||||||
|
licenseKey: licenseKey,
|
||||||
toolbar: {
|
toolbar: {
|
||||||
items: toobarItems,
|
items: toobarItems,
|
||||||
shouldNotGroupWhenFull: false
|
shouldNotGroupWhenFull: false,
|
||||||
},
|
},
|
||||||
plugins: plugins,
|
plugins: plugins,
|
||||||
balloonToolbar: ['bold', 'italic', '|', 'link', 'insertImage', '|', 'bulletedList', 'numberedList'],
|
balloonToolbar: [
|
||||||
|
"bold",
|
||||||
|
"italic",
|
||||||
|
"|",
|
||||||
|
"link",
|
||||||
|
"insertImage",
|
||||||
|
"|",
|
||||||
|
"bulletedList",
|
||||||
|
"numberedList",
|
||||||
|
"|",
|
||||||
|
"field",
|
||||||
|
],
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
supportAllValues: true
|
supportAllValues: true,
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
options: [10, 12, 14, 'default', 18, 20, 22],
|
options: [10, 12, 14, "default", 18, 20, 22],
|
||||||
supportAllValues: true
|
supportAllValues: true,
|
||||||
},
|
},
|
||||||
heading: {
|
heading: {
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
model: 'paragraph',
|
model: "paragraph",
|
||||||
title: 'Paragraph',
|
title: "Paragraph",
|
||||||
class: 'ck-heading_paragraph'
|
class: "ck-heading_paragraph",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: 'heading1',
|
model: "heading1",
|
||||||
view: 'h1',
|
view: "h1",
|
||||||
title: 'Heading 1',
|
title: "Heading 1",
|
||||||
class: 'ck-heading_heading1'
|
class: "ck-heading_heading1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: 'heading2',
|
model: "heading2",
|
||||||
view: 'h2',
|
view: "h2",
|
||||||
title: 'Heading 2',
|
title: "Heading 2",
|
||||||
class: 'ck-heading_heading2'
|
class: "ck-heading_heading2",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: 'heading3',
|
model: "heading3",
|
||||||
view: 'h3',
|
view: "h3",
|
||||||
title: 'Heading 3',
|
title: "Heading 3",
|
||||||
class: 'ck-heading_heading3'
|
class: "ck-heading_heading3",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: 'heading4',
|
model: "heading4",
|
||||||
view: 'h4',
|
view: "h4",
|
||||||
title: 'Heading 4',
|
title: "Heading 4",
|
||||||
class: 'ck-heading_heading4'
|
class: "ck-heading_heading4",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: 'heading5',
|
model: "heading5",
|
||||||
view: 'h5',
|
view: "h5",
|
||||||
title: 'Heading 5',
|
title: "Heading 5",
|
||||||
class: 'ck-heading_heading5'
|
class: "ck-heading_heading5",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
model: 'heading6',
|
model: "heading6",
|
||||||
view: 'h6',
|
view: "h6",
|
||||||
title: 'Heading 6',
|
title: "Heading 6",
|
||||||
class: 'ck-heading_heading6'
|
class: "ck-heading_heading6",
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
image: {
|
image: {
|
||||||
toolbar: [
|
toolbar: [
|
||||||
'toggleImageCaption',
|
"toggleImageCaption",
|
||||||
'imageTextAlternative',
|
"imageTextAlternative",
|
||||||
'|',
|
"|",
|
||||||
'imageStyle:inline',
|
"imageStyle:inline",
|
||||||
'imageStyle:wrapText',
|
"imageStyle:wrapText",
|
||||||
'imageStyle:breakText',
|
"imageStyle:breakText",
|
||||||
'|',
|
"|",
|
||||||
'resizeImage'
|
"resizeImage",
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
//initialData: props.data,
|
//initialData: props.data,
|
||||||
link: {
|
link: {
|
||||||
addTargetToExternalLinks: true,
|
addTargetToExternalLinks: true,
|
||||||
defaultProtocol: 'https://',
|
defaultProtocol: "https://",
|
||||||
decorators: {
|
decorators: {
|
||||||
toggleDownloadable: {
|
toggleDownloadable: {
|
||||||
mode: 'manual',
|
mode: "manual",
|
||||||
label: 'Downloadable',
|
label: "Downloadable",
|
||||||
attributes: {
|
attributes: {
|
||||||
download: 'file'
|
download: "file",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
properties: {
|
properties: {
|
||||||
styles: true,
|
styles: true,
|
||||||
startIndex: true,
|
startIndex: true,
|
||||||
reversed: true
|
reversed: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
// mention: {
|
// mention: {
|
||||||
// feeds: [
|
// feeds: [
|
||||||
@ -301,39 +315,66 @@ export default function TextEditor( props ) {
|
|||||||
// ]
|
// ]
|
||||||
// },
|
// },
|
||||||
menuBar: {
|
menuBar: {
|
||||||
isVisible: true
|
isVisible: true,
|
||||||
},
|
},
|
||||||
placeholder: 'Type or paste your content here!',
|
placeholder: "Type or paste your content here!",
|
||||||
table: {
|
table: {
|
||||||
contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties']
|
contentToolbar: [
|
||||||
|
"tableColumn",
|
||||||
|
"tableRow",
|
||||||
|
"mergeTableCells",
|
||||||
|
"tableProperties",
|
||||||
|
"tableCellProperties",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
fieldConfig: {
|
fieldConfig: {
|
||||||
fields : customfields
|
fields: customfields,
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const editorClasses = "editor-container__editor " + props.className;
|
const editorClasses = props.className || "";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
|
||||||
<div className="ck-main-container">
|
|
||||||
<div className="editor-container editor-container_document-editor" ref={editorContainerRef}>
|
|
||||||
<div className="editor-container__menu-bar" ref={editorMenuBarRef}></div>
|
|
||||||
<div className="editor-container__toolbar" ref={editorToolbarRef}></div>
|
|
||||||
<div className="editor-container__editor-wrapper">
|
|
||||||
<div className={editorClasses}>
|
<div className={editorClasses}>
|
||||||
|
<div className="ck-main-container">
|
||||||
|
<div
|
||||||
|
className="editor-container editor-container_document-editor"
|
||||||
|
ref={editorContainerRef}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="editor-container__menu-bar"
|
||||||
|
ref={editorMenuBarRef}
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
className="editor-container__toolbar"
|
||||||
|
ref={editorToolbarRef}
|
||||||
|
></div>
|
||||||
|
<div className="editor-container__editor-wrapper">
|
||||||
|
<div className="editor-container__editor">
|
||||||
<div ref={editorRef}>
|
<div ref={editorRef}>
|
||||||
{isLayoutReady && (
|
{isLayoutReady && (
|
||||||
<CKEditor
|
<CKEditor
|
||||||
onReady={editor => {
|
onReady={(editor) => {
|
||||||
Array.from(editorToolbarRef.current?.children).forEach(child => child.remove());
|
Array.from(editorToolbarRef.current?.children).forEach(
|
||||||
Array.from(editorMenuBarRef.current?.children).forEach(child => child.remove());
|
(child) => child.remove(),
|
||||||
editorToolbarRef.current.appendChild(editor.ui.view.toolbar.element);
|
);
|
||||||
editorMenuBarRef.current.appendChild(editor.ui.view.menuBarView.element);
|
Array.from(editorMenuBarRef.current?.children).forEach(
|
||||||
|
(child) => child.remove(),
|
||||||
|
);
|
||||||
|
editorToolbarRef.current.appendChild(
|
||||||
|
editor.ui.view.toolbar.element,
|
||||||
|
);
|
||||||
|
editorMenuBarRef.current.appendChild(
|
||||||
|
editor.ui.view.menuBarView?.element,
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
onAfterDestroy={() => {
|
onAfterDestroy={() => {
|
||||||
Array.from(editorToolbarRef.current.children).forEach(child => child.remove());
|
Array.from(editorToolbarRef.current.children).forEach(
|
||||||
Array.from(editorMenuBarRef.current.children).forEach(child => child.remove());
|
(child) => child.remove(),
|
||||||
|
);
|
||||||
|
Array.from(editorMenuBarRef.current.children).forEach(
|
||||||
|
(child) => child.remove(),
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
editor={DecoupledEditor}
|
editor={DecoupledEditor}
|
||||||
config={editorConfig}
|
config={editorConfig}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Plugin } from 'ckeditor5';
|
import { Plugin } from "ckeditor5";
|
||||||
import FieldEditing from './fieldediting';
|
import FieldEditing from "./fieldediting";
|
||||||
import FieldUI from './fieldui';
|
import FieldUI from "./fieldui";
|
||||||
|
|
||||||
export default class Field extends Plugin {
|
export default class Field extends Plugin {
|
||||||
static get requires() {
|
static get requires() {
|
||||||
|
|||||||
@ -1,15 +1,21 @@
|
|||||||
import { Plugin, Collection, addListToDropdown, createDropdown, ViewModel } from 'ckeditor5';
|
import {
|
||||||
import './styles.css';
|
Plugin,
|
||||||
|
Collection,
|
||||||
|
addListToDropdown,
|
||||||
|
createDropdown,
|
||||||
|
ViewModel,
|
||||||
|
} from "ckeditor5";
|
||||||
|
import "./styles.css";
|
||||||
|
|
||||||
export default class FieldUI extends Plugin {
|
export default class FieldUI extends Plugin {
|
||||||
init() {
|
init() {
|
||||||
const editor = this.editor;
|
const editor = this.editor;
|
||||||
const t = editor.t;
|
const t = editor.t;
|
||||||
const fields = editor.config.get( 'fieldConfig' ).fields;
|
const fields = editor.config.get("fieldConfig").fields;
|
||||||
|
|
||||||
// The "field" dropdown must be registered among the UI components of the editor
|
// The "field" dropdown must be registered among the UI components of the editor
|
||||||
// to be displayed in the toolbar.
|
// to be displayed in the toolbar.
|
||||||
editor.ui.componentFactory.add( 'field', locale => {
|
editor.ui.componentFactory.add("field", (locale) => {
|
||||||
const dropdownView = createDropdown(locale);
|
const dropdownView = createDropdown(locale);
|
||||||
|
|
||||||
// Populate the list in the dropdown with items.
|
// Populate the list in the dropdown with items.
|
||||||
@ -18,44 +24,38 @@ import './styles.css';
|
|||||||
dropdownView.buttonView.set({
|
dropdownView.buttonView.set({
|
||||||
// The t() function helps localize the editor. All strings enclosed in t() can be
|
// The t() function helps localize the editor. All strings enclosed in t() can be
|
||||||
// translated and change when the language of the editor changes.
|
// translated and change when the language of the editor changes.
|
||||||
label: t( 'Insert Field' ),
|
label: t("Insert Field"),
|
||||||
tooltip: true,
|
tooltip: true,
|
||||||
withText: true
|
withText: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Disable the field button when the command is disabled.
|
// Disable the field button when the command is disabled.
|
||||||
const command = editor.commands.get( 'field' );
|
const command = editor.commands.get("field");
|
||||||
dropdownView.bind( 'isEnabled' ).to( command );
|
dropdownView.bind("isEnabled").to(command);
|
||||||
|
|
||||||
// Execute the command when the dropdown item is clicked (executed).
|
// Execute the command when the dropdown item is clicked (executed).
|
||||||
this.listenTo( dropdownView, 'execute', evt => {
|
this.listenTo(dropdownView, "execute", (evt) => {
|
||||||
editor.execute( 'field', { value: evt.source.commandParam } );
|
editor.execute("field", { value: evt.source.commandParam });
|
||||||
editor.editing.view.focus();
|
editor.editing.view.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
return dropdownView;
|
return dropdownView;
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.ui.extendMenuBar( {
|
|
||||||
item: 'field',
|
|
||||||
position: 'after:bold'
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDropdownItemsDefinitions(fields) {
|
function getDropdownItemsDefinitions(fields) {
|
||||||
const itemDefinitions = new Collection();
|
const itemDefinitions = new Collection();
|
||||||
|
|
||||||
if (fields !== undefined)
|
if (fields !== undefined) {
|
||||||
{
|
|
||||||
for (const field of fields) {
|
for (const field of fields) {
|
||||||
const definition = {
|
const definition = {
|
||||||
type: 'button',
|
type: "button",
|
||||||
model: new ViewModel({
|
model: new ViewModel({
|
||||||
commandParam: field,
|
commandParam: field,
|
||||||
label: field.name,
|
label: field.name,
|
||||||
withText: true
|
withText: true,
|
||||||
} )
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add the item definition to the collection.
|
// Add the item definition to the collection.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user