]> BookStack Code Mirror - bookstack/blobdiff - resources/js/wysiwyg/ui/defaults/forms/tables.ts
Search: Added exact/filter/tag term negation support
[bookstack] / resources / js / wysiwyg / ui / defaults / forms / tables.ts
index a045ba55d61f7176c64d3931fb9e82da288537ce..5a41c85b3dabbb8d7b479b43b9d96a568d8f3a1b 100644 (file)
@@ -5,12 +5,104 @@ import {
     EditorSelectFormFieldDefinition
 } from "../../framework/forms";
 import {EditorUiContext} from "../../framework/core";
-import {setEditorContentFromHtml} from "../../../actions";
+import {CustomTableCellNode} from "../../../nodes/custom-table-cell";
+import {EditorFormModal} from "../../framework/modals";
+import {$getSelection, ElementFormatType} from "lexical";
+import {
+    $forEachTableCell, $getCellPaddingForTable,
+    $getTableCellColumnWidth,
+    $getTableCellsFromSelection, $getTableFromSelection,
+    $getTableRowsFromSelection,
+    $setTableCellColumnWidth
+} from "../../../utils/tables";
+import {formatSizeValue} from "../../../utils/dom";
+import {CustomTableRowNode} from "../../../nodes/custom-table-row";
+import {CustomTableNode} from "../../../nodes/custom-table";
+
+const borderStyleInput: EditorSelectFormFieldDefinition = {
+    label: 'Border style',
+    name: 'border_style',
+    type: 'select',
+    valuesByLabel: {
+        'Select...': '',
+        "Solid": 'solid',
+        "Dotted": 'dotted',
+        "Dashed": 'dashed',
+        "Double": 'double',
+        "Groove": 'groove',
+        "Ridge": 'ridge',
+        "Inset": 'inset',
+        "Outset": 'outset',
+        "None": 'none',
+        "Hidden": 'hidden',
+    }
+};
+
+const borderColorInput: EditorFormFieldDefinition = {
+    label: 'Border color',
+    name: 'border_color',
+    type: 'text',
+};
+
+const backgroundColorInput: EditorFormFieldDefinition = {
+    label: 'Background color',
+    name: 'background_color',
+    type: 'text',
+};
+
+const alignmentInput: EditorSelectFormFieldDefinition = {
+    label: 'Alignment',
+    name: 'align',
+    type: 'select',
+    valuesByLabel: {
+        'None': '',
+        'Left': 'left',
+        'Center': 'center',
+        'Right': 'right',
+    }
+};
+
+export function $showCellPropertiesForm(cell: CustomTableCellNode, context: EditorUiContext): EditorFormModal {
+    const styles = cell.getStyles();
+    const modalForm = context.manager.createModal('cell_properties');
+    modalForm.show({
+        width: $getTableCellColumnWidth(context.editor, cell),
+        height: styles.get('height') || '',
+        type: cell.getTag(),
+        h_align: cell.getFormatType(),
+        v_align: styles.get('vertical-align') || '',
+        border_width: styles.get('border-width') || '',
+        border_style: styles.get('border-style') || '',
+        border_color: styles.get('border-color') || '',
+        background_color: styles.get('background-color') || '',
+    });
+    return modalForm;
+}
 
 export const cellProperties: EditorFormDefinition = {
     submitText: 'Save',
     async action(formData, context: EditorUiContext) {
-        setEditorContentFromHtml(context.editor, formData.get('source')?.toString() || '');
+        context.editor.update(() => {
+            const cells = $getTableCellsFromSelection($getSelection());
+            for (const cell of cells) {
+                const width = formData.get('width')?.toString() || '';
+
+                $setTableCellColumnWidth(cell, width);
+                cell.updateTag(formData.get('type')?.toString() || '');
+                cell.setFormat((formData.get('h_align')?.toString() || '') as ElementFormatType);
+
+                const styles = cell.getStyles();
+                styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
+                styles.set('vertical-align', formData.get('v_align')?.toString() || '');
+                styles.set('border-width', formatSizeValue(formData.get('border_width')?.toString() || ''));
+                styles.set('border-style', formData.get('border_style')?.toString() || '');
+                styles.set('border-color', formData.get('border_color')?.toString() || '');
+                styles.set('background-color', formData.get('background_color')?.toString() || '');
+
+                cell.setStyles(styles);
+            }
+        });
+
         return true;
     },
     fields: [
@@ -18,37 +110,31 @@ export const cellProperties: EditorFormDefinition = {
             build() {
                 const generalFields: EditorFormFieldDefinition[] = [
                     {
-                        label: 'Width',
+                        label: 'Width', // Colgroup width
                         name: 'width',
                         type: 'text',
                     },
                     {
-                        label: 'Height',
+                        label: 'Height', // inline-style: height
                         name: 'height',
                         type: 'text',
                     },
                     {
-                        label: 'Cell type',
+                        label: 'Cell type', // element
                         name: 'type',
                         type: 'select',
                         valuesByLabel: {
-                            'Cell': 'cell',
-                            'Header cell': 'header',
+                            'Cell': 'td',
+                            'Header cell': 'th',
                         }
                     } as EditorSelectFormFieldDefinition,
                     {
+                        ...alignmentInput, // class: 'align-right/left/center'
                         label: 'Horizontal align',
                         name: 'h_align',
-                        type: 'select',
-                        valuesByLabel: {
-                            'None': '',
-                            'Left': 'left',
-                            'Center': 'center',
-                            'Right': 'right',
-                        }
-                    } as EditorSelectFormFieldDefinition,
+                    },
                     {
-                        label: 'Vertical align',
+                        label: 'Vertical align', // inline-style: vertical-align
                         name: 'v_align',
                         type: 'select',
                         valuesByLabel: {
@@ -62,38 +148,168 @@ export const cellProperties: EditorFormDefinition = {
 
                 const advancedFields: EditorFormFieldDefinition[] = [
                     {
-                        label: 'Border width',
+                        label: 'Border width', // inline-style: border-width
                         name: 'border_width',
                         type: 'text',
                     },
+                    borderStyleInput, // inline-style: border-style
+                    borderColorInput, // inline-style: border-color
+                    backgroundColorInput, // inline-style: background-color
+                ];
+
+                return new EditorFormTabs([
                     {
-                        label: 'Border style',
-                        name: 'border_style',
-                        type: 'select',
-                        valuesByLabel: {
-                            'Select...': '',
-                            "Solid": 'solid',
-                            "Dotted": 'dotted',
-                            "Dashed": 'dashed',
-                            "Double": 'double',
-                            "Groove": 'groove',
-                            "Ridge": 'ridge',
-                            "Inset": 'inset',
-                            "Outset": 'outset',
-                            "None": 'none',
-                            "Hidden": 'hidden',
-                        }
-                    } as EditorSelectFormFieldDefinition,
+                        label: 'General',
+                        contents: generalFields,
+                    },
                     {
-                        label: 'Border color',
-                        name: 'border_color',
+                        label: 'Advanced',
+                        contents: advancedFields,
+                    }
+                ])
+            }
+        },
+    ],
+};
+
+export function $showRowPropertiesForm(row: CustomTableRowNode, context: EditorUiContext): EditorFormModal {
+    const styles = row.getStyles();
+    const modalForm = context.manager.createModal('row_properties');
+    modalForm.show({
+        height: styles.get('height') || '',
+        border_style: styles.get('border-style') || '',
+        border_color: styles.get('border-color') || '',
+        background_color: styles.get('background-color') || '',
+    });
+    return modalForm;
+}
+
+export const rowProperties: EditorFormDefinition = {
+    submitText: 'Save',
+    async action(formData, context: EditorUiContext) {
+        context.editor.update(() => {
+            const rows = $getTableRowsFromSelection($getSelection());
+            for (const row of rows) {
+                const styles = row.getStyles();
+                styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
+                styles.set('border-style', formData.get('border_style')?.toString() || '');
+                styles.set('border-color', formData.get('border_color')?.toString() || '');
+                styles.set('background-color', formData.get('background_color')?.toString() || '');
+                row.setStyles(styles);
+            }
+        });
+        return true;
+    },
+    fields: [
+        // Removed fields:
+        // Removed 'Row Type' as we don't currently support thead/tfoot elements
+        //  TinyMCE would move rows up/down into these parents when set
+        // Removed 'Alignment' since this was broken in our editor (applied alignment class to whole parent table)
+        {
+            label: 'Height', // style on tr: height
+            name: 'height',
+            type: 'text',
+        },
+        borderStyleInput, // style on tr: height
+        borderColorInput, // style on tr: height
+        backgroundColorInput, // style on tr: height
+    ],
+};
+
+export function $showTablePropertiesForm(table: CustomTableNode, context: EditorUiContext): EditorFormModal {
+    const styles = table.getStyles();
+    const modalForm = context.manager.createModal('table_properties');
+    modalForm.show({
+        width: styles.get('width') || '',
+        height: styles.get('height') || '',
+        cell_spacing: styles.get('cell-spacing') || '',
+        cell_padding: $getCellPaddingForTable(table),
+        border_width: styles.get('border-width') || '',
+        border_style: styles.get('border-style') || '',
+        border_color: styles.get('border-color') || '',
+        background_color: styles.get('background-color') || '',
+        // caption: '', TODO
+        align: table.getFormatType(),
+    });
+    return modalForm;
+}
+
+export const tableProperties: EditorFormDefinition = {
+    submitText: 'Save',
+    async action(formData, context: EditorUiContext) {
+        context.editor.update(() => {
+            const table = $getTableFromSelection($getSelection());
+            if (!table) {
+                return;
+            }
+
+            const styles = table.getStyles();
+            styles.set('width', formatSizeValue(formData.get('width')?.toString() || ''));
+            styles.set('height', formatSizeValue(formData.get('height')?.toString() || ''));
+            styles.set('cell-spacing', formatSizeValue(formData.get('cell_spacing')?.toString() || ''));
+            styles.set('border-width', formatSizeValue(formData.get('border_width')?.toString() || ''));
+            styles.set('border-style', formData.get('border_style')?.toString() || '');
+            styles.set('border-color', formData.get('border_color')?.toString() || '');
+            styles.set('background-color', formData.get('background_color')?.toString() || '');
+            table.setStyles(styles);
+
+            table.setFormat(formData.get('align') as ElementFormatType);
+
+            const cellPadding = (formData.get('cell_padding')?.toString() || '');
+            if (cellPadding) {
+                const cellPaddingFormatted = formatSizeValue(cellPadding);
+                $forEachTableCell(table, (cell: CustomTableCellNode) => {
+                    const styles = cell.getStyles();
+                    styles.set('padding', cellPaddingFormatted);
+                    cell.setStyles(styles);
+                });
+            }
+
+            // TODO - cell caption
+        });
+        return true;
+    },
+    fields: [
+        {
+            build() {
+                const generalFields: EditorFormFieldDefinition[] = [
+                    {
+                        label: 'Width', // Style - width
+                        name: 'width',
+                        type: 'text',
+                    },
+                    {
+                        label: 'Height', // Style - height
+                        name: 'height',
+                        type: 'text',
+                    },
+                    {
+                        label: 'Cell spacing', // Style - border-spacing
+                        name: 'cell_spacing',
                         type: 'text',
                     },
                     {
-                        label: 'Background color',
-                        name: 'background_color',
+                        label: 'Cell padding', // Style - padding on child cells?
+                        name: 'cell_padding',
                         type: 'text',
                     },
+                    {
+                        label: 'Border width', // Style - border-width
+                        name: 'border_width',
+                        type: 'text',
+                    },
+                    {
+                        label: 'caption', // Caption element
+                        name: 'caption',
+                        type: 'text', // TODO -
+                    },
+                    alignmentInput, // alignment class
+                ];
+
+                const advancedFields: EditorFormFieldDefinition[] = [
+                    borderStyleInput, // Style - border-style
+                    borderColorInput, // Style - border-color
+                    backgroundColorInput, // Style - background-color
                 ];
 
                 return new EditorFormTabs([