diff options
author | Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> | 2021-07-12 13:45:49 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-12 13:45:49 -0400 |
commit | 34404caeb6b159e9ad040d8213849a9eb6f908aa (patch) | |
tree | 75dd8cb1829d7879ecdf7eaccf0473a8a647954c | |
parent | 0443cb9267d808513e181e3130d69dde8e73018e (diff) |
Revert "Schema view En-Hua — added ability to type strings in without quotes, as well as formatting reflecting nested containers"
-rw-r--r-- | .idea/.gitignore | 3 | ||||
-rw-r--r-- | .idea/Dash-Web.iml | 9 | ||||
-rw-r--r-- | .idea/modules.xml | 8 | ||||
-rw-r--r-- | .idea/vcs.xml | 6 | ||||
-rw-r--r-- | src/client/util/SelectionManager.ts | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaCells.tsx (renamed from src/client/views/collections/schemaView/CollectionSchemaCells.tsx) | 112 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaHeaders.tsx (renamed from src/client/views/collections/schemaView/CollectionSchemaHeaders.tsx) | 16 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaMovableTableHOC.tsx (renamed from src/client/views/collections/schemaView/CollectionSchemaMovableRow.tsx) | 141 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.scss (renamed from src/client/views/collections/schemaView/CollectionSchemaView.scss) | 97 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx (renamed from src/client/views/collections/schemaView/CollectionSchemaView.tsx) | 38 | ||||
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/SchemaTable.tsx (renamed from src/client/views/collections/schemaView/SchemaTable.tsx) | 50 | ||||
-rw-r--r-- | src/client/views/collections/schemaView/CollectionSchemaMovableColumn.tsx | 128 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.tsx | 4 | ||||
-rw-r--r-- | src/fields/SchemaHeaderField.ts | 2 |
16 files changed, 304 insertions, 316 deletions
diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d33521a..000000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/Dash-Web.iml b/.idea/Dash-Web.iml deleted file mode 100644 index d6ebd4805..000000000 --- a/.idea/Dash-Web.iml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<module type="JAVA_MODULE" version="4"> - <component name="NewModuleRootManager" inherit-compiler-output="true"> - <exclude-output /> - <content url="file://$MODULE_DIR$" /> - <orderEntry type="inheritedJdk" /> - <orderEntry type="sourceFolder" forTests="false" /> - </component> -</module>
\ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 35c51c015..000000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="ProjectModuleManager"> - <modules> - <module fileurl="file://$PROJECT_DIR$/.idea/Dash-Web.iml" filepath="$PROJECT_DIR$/.idea/Dash-Web.iml" /> - </modules> - </component> -</project>
\ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddfb..000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project version="4"> - <component name="VcsDirectoryMappings"> - <mapping directory="" vcs="Git" /> - </component> -</project>
\ No newline at end of file diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index a624d5b7c..ca5ef75d2 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -1,7 +1,7 @@ import { action, observable, ObservableMap } from "mobx"; import { computedFn } from "mobx-utils"; import { Doc, Opt } from "../../fields/Doc"; -import { CollectionSchemaView } from "../views/collections/schemaView/CollectionSchemaView"; +import { CollectionSchemaView } from "../views/collections/CollectionSchemaView"; import { CollectionViewType } from "../views/collections/CollectionView"; import { DocumentView } from "../views/nodes/DocumentView"; diff --git a/src/client/views/collections/schemaView/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index f75179cea..2e6186680 100644 --- a/src/client/views/collections/schemaView/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -6,34 +6,33 @@ import DatePicker from "react-datepicker"; import "react-datepicker/dist/react-datepicker.css"; import { CellInfo } from "react-table"; import "react-table/react-table.css"; -import { DateField } from "../../../../fields/DateField"; -import { Doc, DocListCast, Field, Opt } from "../../../../fields/Doc"; -import { Id } from "../../../../fields/FieldSymbols"; -import { List } from "../../../../fields/List"; -import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; -import { ComputedField } from "../../../../fields/ScriptField"; -import { BoolCast, Cast, DateCast, FieldValue, NumCast, StrCast } from "../../../../fields/Types"; -import { ImageField } from "../../../../fields/URLField"; -import { Utils, emptyFunction } from "../../../../Utils"; -import { Docs } from "../../../documents/Documents"; -import { DocumentType } from "../../../documents/DocumentTypes"; -import { DocumentManager } from "../../../util/DocumentManager"; -import { DragManager } from "../../../util/DragManager"; -import { KeyCodes } from "../../../util/KeyCodes"; -import { CompileScript } from "../../../util/Scripting"; -import { SearchUtil } from "../../../util/SearchUtil"; -import { SnappingManager } from "../../../util/SnappingManager"; -import { undoBatch } from "../../../util/UndoManager"; -import '../../../views/DocumentDecorations.scss'; -import { EditableView } from "../../EditableView"; -import { MAX_ROW_HEIGHT } from '../../globalCssVariables.scss'; -import { DocumentIconContainer } from "../../nodes/DocumentIcon"; -import { OverlayView } from "../../OverlayView"; +import { DateField } from "../../../fields/DateField"; +import { Doc, DocListCast, Field, Opt } from "../../../fields/Doc"; +import { Id } from "../../../fields/FieldSymbols"; +import { List } from "../../../fields/List"; +import { SchemaHeaderField } from "../../../fields/SchemaHeaderField"; +import { ComputedField } from "../../../fields/ScriptField"; +import { BoolCast, Cast, DateCast, FieldValue, NumCast, StrCast } from "../../../fields/Types"; +import { ImageField } from "../../../fields/URLField"; +import { Utils, emptyFunction } from "../../../Utils"; +import { Docs } from "../../documents/Documents"; +import { DocumentType } from "../../documents/DocumentTypes"; +import { DocumentManager } from "../../util/DocumentManager"; +import { DragManager } from "../../util/DragManager"; +import { KeyCodes } from "../../util/KeyCodes"; +import { CompileScript } from "../../util/Scripting"; +import { SearchUtil } from "../../util/SearchUtil"; +import { SnappingManager } from "../../util/SnappingManager"; +import { undoBatch } from "../../util/UndoManager"; +import '../DocumentDecorations.scss'; +import { EditableView } from "../EditableView"; +import { MAX_ROW_HEIGHT } from '../globalCssVariables.scss'; +import { DocumentIconContainer } from "../nodes/DocumentIcon"; +import { OverlayView } from "../OverlayView"; import "./CollectionSchemaView.scss"; -import { CollectionView } from "../CollectionView"; +import { CollectionView } from "./CollectionView"; const path = require('path'); -// intialize cell properties export interface CellProps { row: number; col: number; @@ -237,69 +236,14 @@ export class CollectionSchemaCell extends React.Component<CellProps> { Field.IsField(cfield) ? Field.toScriptString(cfield) : ""; }} SetValue={action((value: string) => { - // sets what is displayed after the user makes an input let retVal = false; if (value.startsWith(":=") || value.startsWith("=:=")) { - // decides how to compute a value when given either of the above strings const script = value.substring(value.startsWith("=:=") ? 3 : 2); retVal = this.props.setComputed(script, value.startsWith(":=") ? this._rowDataDoc : this._rowDoc, this.renderFieldKey, this.props.row, this.props.col); } else { - // check if the input is a number - let inputIsNum = true; - for (let s of value) { - if (isNaN(parseInt(s)) && !(s == ".") && !(s == ",")) { - inputIsNum = false; - } - } - // check if the input is a boolean - let inputIsBool: boolean = value == "false" || value == "true"; - // what to do in the case - if (!inputIsNum && !inputIsBool && !value.startsWith("=")) { - // if it's not a number, it's a string, and should be processed as such - // strips the string of quotes when it is edited to prevent quotes form being added to the text automatically - // after each edit - let valueSansQuotes = value; - if (this._isEditing) { - const vsqLength = valueSansQuotes.length; - // get rid of outer quotes - valueSansQuotes = valueSansQuotes.substring(value.startsWith("\"") ? 1 : 0, - valueSansQuotes.charAt(vsqLength - 1) == "\"" ? vsqLength - 1 : vsqLength); - } - let inputAsString = '"'; - // escape any quotes in the string - for (const i of valueSansQuotes) { - if (i == '"') { - inputAsString += '\\"'; - } else { - inputAsString += i; - } - } - // add a closing quote - inputAsString += '"'; - //two options here: we can strip off outer quotes or we can figure out what's going on with the script - const script = CompileScript(inputAsString, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - const changeMade = inputAsString.length !== value.length || inputAsString.length - 2 !== value.length - script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run)); - // handle numbers and expressions - } else if (inputIsNum || value.startsWith("=")) { - //TODO: make accept numbers - const inputscript = value.substring(value.startsWith("=") ? 1 : 0); - // if commas are not stripped, the parser only considers the numbers after the last comma - let inputSansCommas = ""; - for (let s of inputscript) { - if (!(s == ",")) { - inputSansCommas += s; - } - } - const script = CompileScript(inputSansCommas, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - const changeMade = value.length !== value.length || value.length - 2 !== value.length - script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run)); - // handle booleans - } else if (inputIsBool) { - const script = CompileScript(value, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); - const changeMade = value.length !== value.length || value.length - 2 !== value.length - script.compiled && (retVal = this.applyToDoc(changeMade ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run)); - } + const inputscript = value.substring(value.startsWith("=") ? 1 : 0); + const script = CompileScript(inputscript, { requiredType: type, typecheck: false, editable: true, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } }); + script.compiled && (retVal = this.applyToDoc(inputscript.length !== value.length ? this._rowDoc : this._rowDataDoc, this.props.row, this.props.col, script.run)); } if (retVal) { this._isEditing = false; // need to set this here. otherwise, the assignment of the field will invalidate & cause render() to be called with the wrong value for 'editing' @@ -374,7 +318,7 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell { const script = CompileScript(value, { addReturn: true, - typecheck: true, + typecheck: false, transformer: DocumentIconContainer.getTransformer() }); diff --git a/src/client/views/collections/schemaView/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index b2115b22e..3b52e6408 100644 --- a/src/client/views/collections/schemaView/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -3,16 +3,16 @@ import { IconProp, library } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; -import { Doc, DocListCast, Opt } from "../../../../fields/Doc"; -import { listSpec } from "../../../../fields/Schema"; -import { PastelSchemaPalette, SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; -import { ScriptField } from "../../../../fields/ScriptField"; -import { Cast, StrCast } from "../../../../fields/Types"; -import { undoBatch } from "../../../util/UndoManager"; -import { SearchBox } from "../../search/SearchBox"; +import { Doc, DocListCast, Opt } from "../../../fields/Doc"; +import { listSpec } from "../../../fields/Schema"; +import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField"; +import { ScriptField } from "../../../fields/ScriptField"; +import { Cast, StrCast } from "../../../fields/Types"; +import { undoBatch } from "../../util/UndoManager"; +import { SearchBox } from "../search/SearchBox"; import { ColumnType } from "./CollectionSchemaView"; import "./CollectionSchemaView.scss"; -import { CollectionView } from "../CollectionView"; +import { CollectionView } from "./CollectionView"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; diff --git a/src/client/views/collections/schemaView/CollectionSchemaMovableRow.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index f48906ba5..881246bd4 100644 --- a/src/client/views/collections/schemaView/CollectionSchemaMovableRow.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -2,17 +2,131 @@ import React = require("react"); import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action } from "mobx"; import { ReactTableDefaults, RowInfo, TableCellRenderer } from "react-table"; -import { Doc } from "../../../../fields/Doc"; -import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; -import { Cast, FieldValue, StrCast } from "../../../../fields/Types"; -import { DocumentManager } from "../../../util/DocumentManager"; -import { DragManager, dropActionType, SetupDrag } from "../../../util/DragManager"; -import { SnappingManager } from "../../../util/SnappingManager"; -import { Transform } from "../../../util/Transform"; -import { undoBatch } from "../../../util/UndoManager"; -import { ContextMenu } from "../../ContextMenu"; +import { Doc } from "../../../fields/Doc"; +import { SchemaHeaderField } from "../../../fields/SchemaHeaderField"; +import { Cast, FieldValue, StrCast } from "../../../fields/Types"; +import { DocumentManager } from "../../util/DocumentManager"; +import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager"; +import { SnappingManager } from "../../util/SnappingManager"; +import { Transform } from "../../util/Transform"; +import { undoBatch } from "../../util/UndoManager"; +import { ContextMenu } from "../ContextMenu"; import "./CollectionSchemaView.scss"; +export interface MovableColumnProps { + columnRenderer: TableCellRenderer; + columnValue: SchemaHeaderField; + allColumns: SchemaHeaderField[]; + reorderColumns: (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columns: SchemaHeaderField[]) => void; + ScreenToLocalTransform: () => Transform; +} +export class MovableColumn extends React.Component<MovableColumnProps> { + private _header?: React.RefObject<HTMLDivElement> = React.createRef(); + private _colDropDisposer?: DragManager.DragDropDisposer; + private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 }; + private _sensitivity: number = 16; + private _dragRef: React.RefObject<HTMLDivElement> = React.createRef(); + + onPointerEnter = (e: React.PointerEvent): void => { + if (e.buttons === 1 && SnappingManager.GetIsDragging()) { + this._header!.current!.className = "collectionSchema-col-wrapper"; + document.addEventListener("pointermove", this.onDragMove, true); + } + } + onPointerLeave = (e: React.PointerEvent): void => { + this._header!.current!.className = "collectionSchema-col-wrapper"; + document.removeEventListener("pointermove", this.onDragMove, true); + !e.buttons && document.removeEventListener("pointermove", this.onPointerMove); + } + onDragMove = (e: PointerEvent): void => { + const x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); + const rect = this._header!.current!.getBoundingClientRect(); + const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); + const before = x[0] < bounds[0]; + this._header!.current!.className = "collectionSchema-col-wrapper"; + if (before) this._header!.current!.className += " col-before"; + if (!before) this._header!.current!.className += " col-after"; + e.stopPropagation(); + } + + createColDropTarget = (ele: HTMLDivElement) => { + this._colDropDisposer?.(); + if (ele) { + this._colDropDisposer = DragManager.MakeDropTarget(ele, this.colDrop.bind(this)); + } + } + + colDrop = (e: Event, de: DragManager.DropEvent) => { + document.removeEventListener("pointermove", this.onDragMove, true); + const x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y); + const rect = this._header!.current!.getBoundingClientRect(); + const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); + const before = x[0] < bounds[0]; + const colDragData = de.complete.columnDragData; + if (colDragData) { + e.stopPropagation(); + this.props.reorderColumns(colDragData.colKey, this.props.columnValue, before, this.props.allColumns); + return true; + } + return false; + } + + onPointerMove = (e: PointerEvent) => { + const onRowMove = (e: PointerEvent) => { + e.stopPropagation(); + e.preventDefault(); + + document.removeEventListener("pointermove", onRowMove); + document.removeEventListener('pointerup', onRowUp); + const dragData = new DragManager.ColumnDragData(this.props.columnValue); + DragManager.StartColumnDrag(this._dragRef.current!, dragData, e.x, e.y); + }; + const onRowUp = (): void => { + document.removeEventListener("pointermove", onRowMove); + document.removeEventListener('pointerup', onRowUp); + }; + if (e.buttons === 1) { + const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y); + if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) { + document.removeEventListener("pointermove", this.onPointerMove); + e.stopPropagation(); + + document.addEventListener("pointermove", onRowMove); + document.addEventListener("pointerup", onRowUp); + } + } + } + + onPointerUp = (e: React.PointerEvent) => { + document.removeEventListener("pointermove", this.onPointerMove); + } + + @action + onPointerDown = (e: React.PointerEvent, ref: React.RefObject<HTMLDivElement>) => { + this._dragRef = ref; + const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX, e.clientY); + if (!(e.target as any)?.tagName.includes("INPUT")) { + this._startDragPosition = { x: dx, y: dy }; + document.addEventListener("pointermove", this.onPointerMove); + } + } + + + render() { + const reference = React.createRef<HTMLDivElement>(); + + return ( + <div className="collectionSchema-col" ref={this.createColDropTarget}> + <div className="collectionSchema-col-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> + <div className="col-dragger" ref={reference} onPointerDown={e => this.onPointerDown(e, reference)} onPointerUp={this.onPointerUp}> + {this.props.columnRenderer} + </div> + </div> + </div> + ); + } +} + export interface MovableRowProps { rowInfo: RowInfo; ScreenToLocalTransform: () => Transform; @@ -29,20 +143,16 @@ export class MovableRow extends React.Component<MovableRowProps> { private _header?: React.RefObject<HTMLDivElement> = React.createRef(); private _rowDropDisposer?: DragManager.DragDropDisposer; - // Event listeners are only necessary when the user is hovering over the table - // Create one when the mouse starts hovering... onPointerEnter = (e: React.PointerEvent): void => { if (e.buttons === 1 && SnappingManager.GetIsDragging()) { this._header!.current!.className = "collectionSchema-row-wrapper"; document.addEventListener("pointermove", this.onDragMove, true); } } - // ... and delete it when the mouse leaves onPointerLeave = (e: React.PointerEvent): void => { this._header!.current!.className = "collectionSchema-row-wrapper"; document.removeEventListener("pointermove", this.onDragMove, true); } - // The method for the event listener, reorders columns when dragged to their new locations. onDragMove = (e: PointerEvent): void => { const x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); const rect = this._header!.current!.getBoundingClientRect(); @@ -57,14 +167,14 @@ export class MovableRow extends React.Component<MovableRowProps> { this._rowDropDisposer?.(); } - // + createRowDropTarget = (ele: HTMLDivElement) => { this._rowDropDisposer?.(); if (ele) { this._rowDropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this)); } } - // Controls what hppens when a row is dragged and dropped + rowDrop = (e: Event, de: DragManager.DropEvent) => { this.onPointerLeave(e as any); const rowDoc = FieldValue(Cast(this.props.rowInfo.original, Doc)); @@ -91,6 +201,7 @@ export class MovableRow extends React.Component<MovableRowProps> { } onRowContextMenu = (e: React.MouseEvent): void => { + e.preventDefault(); const description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row"; ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original), icon: "file-pdf" }); } diff --git a/src/client/views/collections/schemaView/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index b57fee0e4..2bdd280ec 100644 --- a/src/client/views/collections/schemaView/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -1,4 +1,5 @@ -@import "../../globalCssVariables"; +@import "../globalCssVariables"; + .collectionSchemaView-container { border-width: $COLLECTION_BORDER_WIDTH; border-color: $intermediate-color; @@ -15,13 +16,17 @@ justify-content: space-between; flex-wrap: nowrap; touch-action: none; + div { touch-action: none; } + + .collectionSchemaView-tableContainer { width: 100%; height: 100%; } + .collectionSchemaView-dividerDragger { position: relative; height: 100%; @@ -32,6 +37,7 @@ background: gray; cursor: col-resize; } + // .documentView-node:first-child { // background: $light-color; // } @@ -54,13 +60,17 @@ flex-wrap: nowrap; touch-action: none; padding: 2px; + div { touch-action: none; } + + .collectionSchemaView-tableContainer { width: 100%; height: 100%; } + .collectionSchemaView-dividerDragger { position: relative; height: 100%; @@ -71,6 +81,7 @@ background: gray; cursor: col-resize; } + // .documentView-node:first-child { // background: $light-color; // } @@ -82,6 +93,7 @@ box-sizing: border-box; border: none !important; float: none !important; + .rt-table { height: 100%; display: -webkit-inline-box; @@ -91,10 +103,12 @@ .rt-noData { display: none; } + .rt-thead { width: 100%; z-index: 100; overflow-y: visible; + &.-header { font-size: 12px; height: 30px; @@ -102,10 +116,12 @@ z-index: 100; overflow-y: visible; } + .rt-resizable-header-content { height: 100%; overflow: visible; } + .rt-th { padding: 0; border: solid lightgray; @@ -113,31 +129,38 @@ border-bottom: 2px solid lightgray; } } + .rt-th { font-size: 13px; text-align: center; + &:last-child { overflow: visible; } } + .rt-tbody { width: 100%; direction: rtl; overflow: visible; + .rt-td { border-right: 1px solid rgba(0, 0, 0, 0.2); } } + .rt-tr-group { direction: ltr; flex: 0 1 auto; min-height: 30px; border: 0 !important; } + .rt-tr { width: 100%; min-height: 30px; } + .rt-td { padding: 0; font-size: 13px; @@ -145,15 +168,18 @@ white-space: nowrap; display: flex; align-items: center; + .imageBox-cont { position: relative; max-height: 100%; } + .imageBox-cont img { object-fit: contain; max-width: 100%; height: 100%; } + .videoBox-cont { object-fit: contain; width: auto; @@ -165,16 +191,20 @@ align-items: center; height: inherit; } + .rt-resizer { width: 8px; right: -4px; } + .rt-resizable-header { padding: 0; height: 30px; } + .rt-resizable-header:last-child { overflow: visible; + .rt-resizer { width: 5px !important; } @@ -191,6 +221,7 @@ height: 100%; } + .collectionSchema-header-menu { height: auto; z-index: 100; @@ -200,6 +231,7 @@ position: fixed; background: white; border: black 1px solid; + .collectionSchema-header-toggler { z-index: 100; width: 100%; @@ -207,6 +239,7 @@ padding: 4px; letter-spacing: 2px; text-transform: uppercase; + svg { margin-right: 4px; } @@ -231,51 +264,62 @@ button.add-column { color: black; width: 180px; text-align: left; + .collectionSchema-headerMenu-group { padding: 7px 0; border-bottom: 1px solid lightgray; cursor: pointer; + &:first-child { padding-top: 0; } + &:last-child { border: none; text-align: center; padding: 12px 0 0 0; } } + label { color: $main-accent; font-weight: normal; letter-spacing: 2px; text-transform: uppercase; } + input { color: black; width: 100%; } + .columnMenu-option { cursor: pointer; padding: 3px; background-color: white; transition: background-color 0.2s; + &:hover { background-color: $light-color-secondary; } + &.active { font-weight: bold; border: 2px solid $light-color-secondary; } + svg { color: gray; margin-right: 5px; width: 10px; } } + .keys-dropdown { position: relative; //width: 100%; background-color: white; + input { border: 2px solid $light-color-secondary; padding: 3px; @@ -283,10 +327,12 @@ button.add-column { font-weight: bold; letter-spacing: "2px"; text-transform: "uppercase"; + &:focus { font-weight: normal; } } + .keys-options-wrapper { width: 100%; max-height: 150px; @@ -295,28 +341,34 @@ button.add-column { top: 28px; box-shadow: 0 10px 16px rgba(0, 0, 0, 0.1); background-color: white; + .key-option { background-color: white; border: 1px solid lightgray; padding: 2px 3px; + &:not(:first-child) { border-top: 0; } + &:hover { background-color: $light-color-secondary; } } } } + .columnMenu-colors { display: flex; justify-content: space-between; flex-wrap: wrap; + .columnMenu-colorPicker { cursor: pointer; width: 20px; height: 20px; border-radius: 10px; + &.active { border: 2px solid white; box-shadow: 0 0 0 2px lightgray; @@ -328,14 +380,17 @@ button.add-column { .collectionSchema-row { height: 100%; background-color: white; + &.row-focused .rt-td { background-color: #bfffc0; //$light-color-secondary; } + &.row-wrapped { .rt-td { white-space: normal; } } + .row-dragger { display: flex; justify-content: space-around; @@ -348,6 +403,7 @@ button.add-column { color: lightgray; background-color: white; transition: color 0.1s ease; + .row-option { // padding: 5px; cursor: pointer; @@ -357,21 +413,27 @@ button.add-column { flex-direction: column; justify-content: center; z-index: 2; + &:hover { color: gray; } } } + .collectionSchema-row-wrapper { + &.row-above { border-top: 1px solid red; } + &.row-below { border-bottom: 1px solid red; } + &.row-inside { border: 1px solid red; } + .row-dragging { background-color: blue; } @@ -388,12 +450,16 @@ button.add-column { padding: 4px; text-align: left; padding-left: 19px; + position: relative; + &:focus { outline: none; } + &.editing { padding: 0; + input { outline: 0; border: none; @@ -404,36 +470,50 @@ button.add-column { min-height: 26px; } } + &.focused { + &.inactive { border: none; } } + p { width: 100%; height: 100%; } + &:hover .collectionSchemaView-cellContents-docExpander { display: block; } + + .collectionSchemaView-cellContents-document { display: inline-block; } + .collectionSchemaView-cellContents-docButton { float: right; width: "15px"; height: "15px"; } + .collectionSchemaView-dropdownWrapper { + border: grey; border-style: solid; border-width: 1px; height: 30px; + .collectionSchemaView-dropdownButton { + //display: inline-block; float: left; height: 100%; + + } + .collectionSchemaView-dropdownText { display: inline-block; //float: right; @@ -443,11 +523,14 @@ button.add-column { justify-content: "center"; align-items: "center"; } + } + .collectionSchemaView-dropdownContainer { position: absolute; border: 1px solid rgba(0, 0, 0, 0.04); box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14); + .collectionSchemaView-dropdownOption:hover { background-color: rgba(0, 0, 0, 0.14); cursor: pointer; @@ -463,6 +546,7 @@ button.add-column { top: 0; right: 0; background-color: lightgray; + } .doc-drag-over { @@ -479,6 +563,7 @@ button.add-column { justify-content: flex-end; padding: 0 10px; border-bottom: 2px solid gray; + .collectionSchemaView-toolbar-item { display: flex; flex-direction: column; @@ -501,24 +586,27 @@ button.add-column { .rt-td.rt-expandable { overflow: visible; position: relative; - height: 100%; + height:100%; z-index: 1; } - .reactTable-sub { background-color: rgb(252, 252, 252); width: 100%; + .rt-thead { display: none; } + .row-dragger { background-color: rgb(252, 252, 252); } + .rt-table { background-color: rgb(252, 252, 252); } + .collectionSchemaView-table { - width: 100%; + width: 100%; border: solid 1px; overflow: visible; padding: 0px; @@ -533,6 +621,7 @@ button.add-column { width: 20; height: auto; left: 55; + svg { position: absolute; top: 50%; diff --git a/src/client/views/collections/schemaView/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index ef28f75c8..b33c437a9 100644 --- a/src/client/views/collections/schemaView/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -5,27 +5,27 @@ import { observer } from "mobx-react"; import Measure from "react-measure"; import { Resize } from "react-table"; import "react-table/react-table.css"; -import { Doc, Opt } from "../../../../fields/Doc"; -import { List } from "../../../../fields/List"; -import { listSpec } from "../../../../fields/Schema"; -import { PastelSchemaPalette, SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; -import { Cast, NumCast } from "../../../../fields/Types"; -import { TraceMobx } from "../../../../fields/util"; -import { emptyFunction, emptyPath, returnFalse, setupMoveUpEvents, returnEmptyDoclist, returnTrue } from "../../../../Utils"; -import { SelectionManager } from "../../../util/SelectionManager"; -import { SnappingManager } from "../../../util/SnappingManager"; -import { Transform } from "../../../util/Transform"; -import { undoBatch } from "../../../util/UndoManager"; -import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../globalCssVariables.scss'; -import { ContextMenu } from "../../ContextMenu"; -import { ContextMenuProps } from "../../ContextMenuItem"; -import '../../../views/DocumentDecorations.scss'; -import { DocumentView } from "../../nodes/DocumentView"; -import { DefaultStyleProvider } from "../../StyleProvider"; +import { Doc, Opt } from "../../../fields/Doc"; +import { List } from "../../../fields/List"; +import { listSpec } from "../../../fields/Schema"; +import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField"; +import { Cast, NumCast } from "../../../fields/Types"; +import { TraceMobx } from "../../../fields/util"; +import { emptyFunction, emptyPath, returnFalse, setupMoveUpEvents, returnEmptyDoclist, returnTrue } from "../../../Utils"; +import { SelectionManager } from "../../util/SelectionManager"; +import { SnappingManager } from "../../util/SnappingManager"; +import { Transform } from "../../util/Transform"; +import { undoBatch } from "../../util/UndoManager"; +import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/globalCssVariables.scss'; +import { ContextMenu } from "../ContextMenu"; +import { ContextMenuProps } from "../ContextMenuItem"; +import '../DocumentDecorations.scss'; +import { DocumentView } from "../nodes/DocumentView"; +import { DefaultStyleProvider } from "../StyleProvider"; import "./CollectionSchemaView.scss"; -import { CollectionSubView } from "../CollectionSubView"; +import { CollectionSubView } from "./CollectionSubView"; import { SchemaTable } from "./SchemaTable"; -import { DocUtils } from "../../../documents/Documents"; +import { DocUtils } from "../../documents/Documents"; // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 export enum ColumnType { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index e5b1721f9..fb60265e3 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -29,7 +29,7 @@ import CollectionMapView from './CollectionMapView'; import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { CollectionPileView } from './CollectionPileView'; -import { CollectionSchemaView } from "./schemaView/CollectionSchemaView"; +import { CollectionSchemaView } from "./CollectionSchemaView"; import { CollectionStackingView } from './CollectionStackingView'; import { SubCollectionViewProps } from './CollectionSubView'; import { CollectionTimeView } from './CollectionTimeView'; diff --git a/src/client/views/collections/schemaView/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx index 0d5c9e077..0c69ee030 100644 --- a/src/client/views/collections/schemaView/SchemaTable.tsx +++ b/src/client/views/collections/SchemaTable.tsx @@ -5,33 +5,32 @@ import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import ReactTable, { CellInfo, Column, ComponentPropsGetterR, Resize, SortingRule } from "react-table"; import "react-table/react-table.css"; -import { DateField } from "../../../../fields/DateField"; -import { AclPrivate, AclReadonly, DataSym, Doc, DocListCast, Field, Opt } from "../../../../fields/Doc"; -import { Id } from "../../../../fields/FieldSymbols"; -import { List } from "../../../../fields/List"; -import { listSpec } from "../../../../fields/Schema"; -import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; -import { ComputedField } from "../../../../fields/ScriptField"; -import { Cast, FieldValue, NumCast, StrCast } from "../../../../fields/Types"; -import { ImageField } from "../../../../fields/URLField"; -import { GetEffectiveAcl } from "../../../../fields/util"; -import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from "../../../../Utils"; -import { Docs, DocumentOptions, DocUtils } from "../../../documents/Documents"; -import { DocumentType } from "../../../documents/DocumentTypes"; -import { CompileScript, Transformer, ts } from "../../../util/Scripting"; -import { Transform } from "../../../util/Transform"; -import { undoBatch } from "../../../util/UndoManager"; -import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../globalCssVariables.scss'; -import { ContextMenu } from "../../ContextMenu"; -import '../../../views/DocumentDecorations.scss'; -import { DocumentView } from "../../nodes/DocumentView"; -import { DefaultStyleProvider } from "../../StyleProvider"; +import { DateField } from "../../../fields/DateField"; +import { AclPrivate, AclReadonly, DataSym, Doc, DocListCast, Field, Opt } from "../../../fields/Doc"; +import { Id } from "../../../fields/FieldSymbols"; +import { List } from "../../../fields/List"; +import { listSpec } from "../../../fields/Schema"; +import { SchemaHeaderField } from "../../../fields/SchemaHeaderField"; +import { ComputedField } from "../../../fields/ScriptField"; +import { Cast, FieldValue, NumCast, StrCast } from "../../../fields/Types"; +import { ImageField } from "../../../fields/URLField"; +import { GetEffectiveAcl } from "../../../fields/util"; +import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from "../../../Utils"; +import { Docs, DocumentOptions, DocUtils } from "../../documents/Documents"; +import { DocumentType } from "../../documents/DocumentTypes"; +import { CompileScript, Transformer, ts } from "../../util/Scripting"; +import { Transform } from "../../util/Transform"; +import { undoBatch } from "../../util/UndoManager"; +import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/globalCssVariables.scss'; +import { ContextMenu } from "../ContextMenu"; +import '../DocumentDecorations.scss'; +import { DocumentView } from "../nodes/DocumentView"; +import { DefaultStyleProvider } from "../StyleProvider"; import { CellProps, CollectionSchemaButtons, CollectionSchemaCell, CollectionSchemaCheckboxCell, CollectionSchemaDateCell, CollectionSchemaDocCell, CollectionSchemaImageCell, CollectionSchemaListCell, CollectionSchemaNumberCell, CollectionSchemaStringCell } from "./CollectionSchemaCells"; import { CollectionSchemaAddColumnHeader, KeysDropdown } from "./CollectionSchemaHeaders"; -import { MovableColumn } from "./CollectionSchemaMovableColumn"; -import { MovableRow } from "./CollectionSchemaMovableRow"; +import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC"; import "./CollectionSchemaView.scss"; -import { CollectionView } from "../CollectionView"; +import { CollectionView } from "./CollectionView"; enum ColumnType { @@ -458,9 +457,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> { expanded={expanded} resized={this.resized} onResizedChange={this.props.onResizedChange} - // if it has a child, render another table with the children SubComponent={!hasCollectionChild ? undefined : row => (row.original.type !== DocumentType.COL) ? (null) : - <div style={{ paddingLeft: 57 + "px" }} className="reactTable-sub"><SchemaTable {...this.props} Document={row.original} dataDoc={undefined} childDocs={undefined} /></div>} + <div className="reactTable-sub"><SchemaTable {...this.props} Document={row.original} dataDoc={undefined} childDocs={undefined} /></div>} />; } diff --git a/src/client/views/collections/schemaView/CollectionSchemaMovableColumn.tsx b/src/client/views/collections/schemaView/CollectionSchemaMovableColumn.tsx deleted file mode 100644 index 456c38c68..000000000 --- a/src/client/views/collections/schemaView/CollectionSchemaMovableColumn.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import React = require("react"); -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action } from "mobx"; -import { ReactTableDefaults, RowInfo, TableCellRenderer } from "react-table"; -import { Doc } from "../../../../fields/Doc"; -import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; -import { Cast, FieldValue, StrCast } from "../../../../fields/Types"; -import { DocumentManager } from "../../../util/DocumentManager"; -import { DragManager, dropActionType, SetupDrag } from "../../../util/DragManager"; -import { SnappingManager } from "../../../util/SnappingManager"; -import { Transform } from "../../../util/Transform"; -import { undoBatch } from "../../../util/UndoManager"; -import { ContextMenu } from "../../ContextMenu"; -import "./CollectionSchemaView.scss"; - -export interface MovableColumnProps { - columnRenderer: TableCellRenderer; - columnValue: SchemaHeaderField; - allColumns: SchemaHeaderField[]; - reorderColumns: (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columns: SchemaHeaderField[]) => void; - ScreenToLocalTransform: () => Transform; -} -export class MovableColumn extends React.Component<MovableColumnProps> { - private _header?: React.RefObject<HTMLDivElement> = React.createRef(); - private _colDropDisposer?: DragManager.DragDropDisposer; - private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 }; - private _sensitivity: number = 16; - private _dragRef: React.RefObject<HTMLDivElement> = React.createRef(); - - onPointerEnter = (e: React.PointerEvent): void => { - if (e.buttons === 1 && SnappingManager.GetIsDragging()) { - this._header!.current!.className = "collectionSchema-col-wrapper"; - document.addEventListener("pointermove", this.onDragMove, true); - } - } - onPointerLeave = (e: React.PointerEvent): void => { - this._header!.current!.className = "collectionSchema-col-wrapper"; - document.removeEventListener("pointermove", this.onDragMove, true); - !e.buttons && document.removeEventListener("pointermove", this.onPointerMove); - } - onDragMove = (e: PointerEvent): void => { - const x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); - const rect = this._header!.current!.getBoundingClientRect(); - const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); - const before = x[0] < bounds[0]; - this._header!.current!.className = "collectionSchema-col-wrapper"; - if (before) this._header!.current!.className += " col-before"; - if (!before) this._header!.current!.className += " col-after"; - e.stopPropagation(); - } - - createColDropTarget = (ele: HTMLDivElement) => { - this._colDropDisposer?.(); - if (ele) { - this._colDropDisposer = DragManager.MakeDropTarget(ele, this.colDrop.bind(this)); - } - } - - colDrop = (e: Event, de: DragManager.DropEvent) => { - document.removeEventListener("pointermove", this.onDragMove, true); - const x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y); - const rect = this._header!.current!.getBoundingClientRect(); - const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); - const before = x[0] < bounds[0]; - const colDragData = de.complete.columnDragData; - if (colDragData) { - e.stopPropagation(); - this.props.reorderColumns(colDragData.colKey, this.props.columnValue, before, this.props.allColumns); - return true; - } - return false; - } - - onPointerMove = (e: PointerEvent) => { - const onRowMove = (e: PointerEvent) => { - e.stopPropagation(); - e.preventDefault(); - - document.removeEventListener("pointermove", onRowMove); - document.removeEventListener('pointerup', onRowUp); - const dragData = new DragManager.ColumnDragData(this.props.columnValue); - DragManager.StartColumnDrag(this._dragRef.current!, dragData, e.x, e.y); - }; - const onRowUp = (): void => { - document.removeEventListener("pointermove", onRowMove); - document.removeEventListener('pointerup', onRowUp); - }; - if (e.buttons === 1) { - const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y); - if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) { - document.removeEventListener("pointermove", this.onPointerMove); - e.stopPropagation(); - - document.addEventListener("pointermove", onRowMove); - document.addEventListener("pointerup", onRowUp); - } - } - } - - onPointerUp = (e: React.PointerEvent) => { - document.removeEventListener("pointermove", this.onPointerMove); - } - - @action - onPointerDown = (e: React.PointerEvent, ref: React.RefObject<HTMLDivElement>) => { - this._dragRef = ref; - const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX, e.clientY); - if (!(e.target as any)?.tagName.includes("INPUT")) { - this._startDragPosition = { x: dx, y: dy }; - document.addEventListener("pointermove", this.onPointerMove); - } - } - - - render() { - const reference = React.createRef<HTMLDivElement>(); - - return ( - <div className="collectionSchema-col" ref={this.createColDropTarget}> - <div className="collectionSchema-col-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}> - <div className="col-dragger" ref={reference} onPointerDown={e => this.onPointerDown(e, reference)} onPointerUp={this.onPointerUp}> - {this.props.columnRenderer} - </div> - </div> - </div> - ); - } -} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index ecf4c0901..f0a54e4ac 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -8,7 +8,7 @@ import { emptyPath, OmitKeys, Without } from "../../../Utils"; import { DirectoryImportBox } from "../../util/Import & Export/DirectoryImportBox"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; -import { CollectionSchemaView } from "../collections/schemaView/CollectionSchemaView"; +import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView } from "../collections/CollectionView"; import { InkingStroke } from "../InkingStroke"; import { PresElementBox } from "../presentationview/PresElementBox"; diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index a671c955d..5c168d8a9 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -18,7 +18,7 @@ import { SetupDrag } from '../../util/DragManager'; import { SearchUtil } from '../../util/SearchUtil'; import { Transform } from '../../util/Transform'; import { CollectionDockingView } from "../collections/CollectionDockingView"; -import { CollectionSchemaView, ColumnType } from "../collections/schemaView/CollectionSchemaView"; +import { CollectionSchemaView, ColumnType } from "../collections/CollectionSchemaView"; import { CollectionViewType } from '../collections/CollectionView'; import { ViewBoxBaseComponent } from "../DocComponent"; import { FieldView, FieldViewProps } from '../nodes/FieldView'; @@ -119,7 +119,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc getFinalQuery(query: string): string { //alters the query so it looks in the correct fields - //if this is true, then not all of the field boxes are checked + //if this is true, th`en not all of the field boxes are checked //TODO: data const initialfilters = Cast(this.props.Document._docFilters, listSpec("string"), []); diff --git a/src/fields/SchemaHeaderField.ts b/src/fields/SchemaHeaderField.ts index 74cf934f2..88de3a19f 100644 --- a/src/fields/SchemaHeaderField.ts +++ b/src/fields/SchemaHeaderField.ts @@ -3,7 +3,7 @@ import { serializable, primitive } from "serializr"; import { ObjectField } from "./ObjectField"; import { Copy, ToScriptString, ToString, OnUpdate } from "./FieldSymbols"; import { scriptingGlobal } from "../client/util/Scripting"; -import { ColumnType } from "../client/views/collections/schemaView/CollectionSchemaView"; +import { ColumnType } from "../client/views/collections/CollectionSchemaView"; export const PastelSchemaPalette = new Map<string, string>([ // ["pink1", "#FFB4E8"], |