From 6c7dc0f939635982ae619eb5831ff45063d7021e Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Wed, 17 Jul 2019 14:08:24 -0400 Subject: can add columns and delete columns through column header --- .../views/collections/CollectionSchemaView.scss | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 186e006f3..4ab38b9d9 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -187,6 +187,27 @@ .documentView-node:first-child { background: $light-color; } + + .ReactTable .rt-thead .rt-resizable-header:last-child { + overflow: visible; + } +} + +.collectionSchema-header-menuOptions { + position: absolute; + top: $MAX_ROW_HEIGHT; + left: 0; + z-index: 9999; + background-color: $light-color-secondary; + color: black; + border: 1px solid $main-accent; + width: 250px; + padding: 10px; + + input { + color: black; + width: 100%; + } } //options menu styling -- cgit v1.2.3-70-g09d2 From 928f217b51acd105b5366b57fbb0c043740f97a6 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Wed, 17 Jul 2019 20:47:54 -0400 Subject: column menu styling --- .../views/collections/CollectionSchemaCells.tsx | 46 ++- .../views/collections/CollectionSchemaHeaders.tsx | 153 +++++--- .../views/collections/CollectionSchemaView.scss | 413 +++++++-------------- .../views/collections/CollectionSchemaView.tsx | 32 +- 4 files changed, 272 insertions(+), 372 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 691c4f630..1bb661f88 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -81,6 +81,13 @@ export class CollectionSchemaCell extends React.Component { this.props.changeFocusedCellByIndex(this.props.row, this.props.col); } + applyToDoc = (doc: Doc, run: (args?: { [name: string]: any }) => any) => { + const res = run({ this: doc }); + if (!res.success) return false; + doc[this.props.rowProps.column.id as string] = res.result; + return true; + } + renderCellWithType(type: string | undefined) { let props: FieldViewProps = { Document: this.props.rowProps.original, @@ -105,12 +112,6 @@ export class CollectionSchemaCell extends React.Component { // (!this.props.CollectionView.props.isSelected() ? undefined : // SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); }; - let applyToDoc = (doc: Doc, run: (args?: { [name: string]: any }) => any) => { - const res = run({ this: doc }); - if (!res.success) return false; - doc[props.fieldKey] = res.result; - return true; - }; let field = props.Document[props.fieldKey]; let contents: any = "incorrect type"; @@ -141,7 +142,7 @@ export class CollectionSchemaCell extends React.Component { if (!script.compiled) { return false; } - return applyToDoc(props.Document, script.run); + return this.applyToDoc(props.Document, script.run); }} OnFillDown={async (value: string) => { let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } }); @@ -151,7 +152,7 @@ export class CollectionSchemaCell extends React.Component { const run = script.run; //TODO This should be able to be refactored to compile the script once const val = await DocListCastAsync(this.props.Document[this.props.fieldKey]); - val && val.forEach(doc => applyToDoc(doc, run)); + val && val.forEach(doc => this.applyToDoc(doc, run)); }} /> @@ -187,21 +188,13 @@ export class CollectionSchemaStringCell extends CollectionSchemaCell { @observer export class CollectionSchemaCheckboxCell extends CollectionSchemaCell { @observable private _isChecked: boolean = typeof this.props.rowProps.original[this.props.rowProps.column.id as string] === "boolean" ? BoolCast(this.props.rowProps.original[this.props.rowProps.column.id as string]) : false; - private _doc: Doc = this.props.rowProps.original; - - applyToDoc = (doc: Doc, run: (args?: { [name: string]: any }) => any) => { - const res = run({ this: doc }); - if (!res.success) return false; - doc[this.props.rowProps.column.id as string] = res.result; - return true; - } @action toggleChecked = (e: React.ChangeEvent) => { this._isChecked = e.target.checked; let script = CompileScript(e.target.checked.toString(), { requiredType: "boolean", addReturn: true, params: { this: Doc.name } }); if (script.compiled) { - this.applyToDoc(this._doc, script.run); + this.applyToDoc(this._document, script.run); } } @@ -213,10 +206,27 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell { }; return (
-
+
); } +} + +@observer +export class CollectionSchemaDocCell extends CollectionSchemaCell { + render() { + let reference = React.createRef(); + let onItemDown = (e: React.PointerEvent) => { + // (!this.props.CollectionView.props.isSelected() ? undefined : + // SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); + }; + return ( +
+
+
+
+ ); + } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index 3d45089a3..d6ebaf8d8 100644 --- a/src/client/views/collections/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -2,14 +2,14 @@ import React = require("react"); import { action, computed, observable, trace, untracked } from "mobx"; import { observer } from "mobx-react"; import "./CollectionSchemaView.scss"; -import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare } from '@fortawesome/free-solid-svg-icons'; +import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn } from '@fortawesome/free-solid-svg-icons'; import { library, IconProp } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Flyout, anchorPoints } from "../DocumentDecorations"; import { ColumnType } from "./CollectionSchemaView"; import { emptyFunction } from "../../../Utils"; -library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare); +library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn); export interface HeaderProps { keyValue: string; @@ -26,7 +26,7 @@ export interface HeaderProps { export class CollectionSchemaHeader extends React.Component { render() { let icon: IconProp = this.props.keyType === ColumnType.Number ? "hashtag" : this.props.keyType === ColumnType.String ? "font" : - this.props.keyType === ColumnType.Checkbox || this.props.keyType === ColumnType.Boolean ? "check-square" : "align-justify"; + this.props.keyType === ColumnType.Checkbox ? "check-square" : this.props.keyType === ColumnType.Boolean ? "toggle-on" : "align-justify"; return (
@@ -67,7 +67,7 @@ export class CollectionSchemaAddColumnHeader extends React.Component console.log("add clicked")}>; + let addButton = ; return (
{/* {this._creatingColumn ? <> : */} @@ -76,6 +76,7 @@ export class CollectionSchemaAddColumnHeader extends React.Component this.props.setColumnType(this.props.keyValue, type); } - renderContent = () => { - let keyTypeStr = ColumnType[this.props.keyType]; - let colTypes = []; - for (let type in ColumnType) { - if (!(parseInt(type, 10) >= 0)) colTypes.push(type); - } + renderTypes = () => { + if (this.props.typeConst) return <>; + return ( +
+ +
+ + + + + +
+
+ ); + } - if (this._isOpen) { - if (this.props.onlyShowOptions) { - return ( -
- -
- ); - } else { - return ( -
- - {!this.props.typeConst ? - - : null} + renderContent = () => { + return ( +
+ +
+ +
+ {this.props.onlyShowOptions ? <> : + <> + {this.renderTypes()} +
- ); - } - } + + } +
+ ); } render() { return ( - // {this.renderContent()}
}> - //
{ this.props.setIsEditing(true); console.log("clicked anchor"); }}>{this.props.menuButton}
- //
-
this.toggleIsOpen()}>{this.props.menuButtonContent}
- {this.renderContent()} + +
{ this.props.setIsEditing(true); }}>{this.props.menuButtonContent}
+
); } } +{/* //
+ //
this.toggleIsOpen()}>{this.props.menuButtonContent}
+ // {this.renderContent()} + //
*/} + interface KeysDropdownProps { keyValue: string; @@ -190,27 +197,56 @@ interface KeysDropdownProps { canAddNew: boolean; addNew: boolean; onSelect: (oldKey: string, newKey: string, addnew: boolean) => void; - } @observer class KeysDropdown extends React.Component { @observable private _key: string = this.props.keyValue; @observable private _searchTerm: string = ""; + @observable private _isOpen: boolean = false; + @observable private _canClose: boolean = true; @action setSearchTerm = (value: string): void => { this._searchTerm = value; }; @action setKey = (key: string): void => { this._key = key; }; + @action setIsOpen = (isOpen: boolean): void => {this._isOpen = isOpen;}; @action onSelect = (key: string): void => { this.props.onSelect(this._key, key, this.props.addNew); this.setKey(key); + this._isOpen = false; } onChange = (val: string): void => { this.setSearchTerm(val); } + @action + onFocus = (e: React.FocusEvent): void => { + this._isOpen = true; + } + + @action + onBlur = (e: React.FocusEvent): void => { + // const that = this; + if (this._canClose) this._isOpen = false; + // setTimeout(function() { // TODO: this might be too hacky lol + // that.setIsOpen(false); + // }, 100); + } + + @action + onPointerEnter = (e: React.PointerEvent): void => { + this._canClose = false; + } + + @action + onPointerOut = (e: React.PointerEvent): void => { + this._canClose = true; + } + renderOptions = (): JSX.Element[] | JSX.Element => { + if (!this._isOpen) return <>; + let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1); let exactFound = keyOptions.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1 || this.props.existingKeys.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1; @@ -222,7 +258,8 @@ class KeysDropdown extends React.Component { // if search term does not already exist as a group type, give option to create new group type if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) { options.push(
{ this.onSelect(this._searchTerm); this.setSearchTerm(""); }}>Create "{this._searchTerm}" key
); + onClick={() => { this.onSelect(this._searchTerm); this.setSearchTerm(""); }}> + Create "{this._searchTerm}" key
); } return options; @@ -231,9 +268,9 @@ class KeysDropdown extends React.Component { render() { return (
- this.onChange(e.target.value)} > -
+ this.onChange(e.target.value)} onFocus={this.onFocus} onBlur={this.onBlur}> +
{this.renderOptions()}
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 4ab38b9d9..4bc7a778c 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -1,7 +1,5 @@ @import "../globalCssVariables"; - - .collectionSchemaView-container { border-width: $COLLECTION_BORDER_WIDTH; border-color: $intermediate-color; @@ -13,15 +11,6 @@ height: 100%; overflow: hidden; - .collectionSchemaView-cellContents { - height: $MAX_ROW_HEIGHT; - - img { - width: auto; - max-height: $MAX_ROW_HEIGHT; - } - } - .collectionSchemaView-previewRegion { position: relative; background: $light-color; @@ -47,16 +36,6 @@ } } - .collectionSchemaView-previewHandle { - position: absolute; - height: 15px; - width: 15px; - z-index: 20; - right: 0; - top: 20px; - background: Black; - } - .collectionSchemaView-dividerDragger { position: relative; background: black; @@ -67,324 +46,198 @@ right: 0; top: 0; background: $main-accent; - } - - .collectionSchemaView-columnsHandle { - position: absolute; - height: 37px; - width: 20px; - z-index: 20; - left: 0; - bottom: 0; - background: $main-accent; - } - - .collectionSchemaView-colDividerDragger { - position: relative; - box-sizing: border-box; - border-top: 1px solid $intermediate-color; - border-bottom: 1px solid $intermediate-color; - float: top; - width: 100%; - } - - .collectionSchemaView-dividerDragger { - position: relative; box-sizing: border-box; border-left: 1px solid $intermediate-color; border-right: 1px solid $intermediate-color; - float: left; - height: 100%; } +} - .collectionSchemaView-tableContainer { - position: relative; - float: left; - height: 100%; - } +.ReactTable { + width: 100%; + height: 100%; + background: $light-color; + box-sizing: border-box; + border: none !important; - .ReactTable { - // position: absolute; // display: inline-block; - // overflow: auto; - width: 100%; + .rt-table { + overflow-y: auto; + overflow-x: auto; height: 100%; - background: $light-color; - box-sizing: border-box; - border: none !important; - - .rt-table { - overflow-y: auto; - overflow-x: auto; - height: 100%; - display: -webkit-inline-box; - direction: ltr; // direction:rtl; - // display:block; - } - - .rt-tbody { - //direction: ltr; - direction: rtl; - } + display: -webkit-inline-box; + direction: ltr; + } - .rt-tr-group { - direction: ltr; - max-height: $MAX_ROW_HEIGHT; + .rt-thead { + &.-header { + background: $intermediate-color; + color: $light-color; + font-size: 12px; + height: 30px; } - .rt-td { - border-width: 1px; - border-right-color: $intermediate-color; - - .imageBox-cont { - position: relative; - max-height: 100%; - } - - .imageBox-cont img { - object-fit: contain; - max-width: 100%; - height: 100%; - } + .rt-resizable-header { + padding: 0; + height: 30px; - .videoBox-cont { - object-fit: contain; - width: auto; - height: 100%; + &:last-child { + overflow: visible; } } - } - .ReactTable .rt-thead.-header { - background: $intermediate-color; - color: $light-color; - // text-transform: uppercase; - letter-spacing: 2px; - font-size: 12px; - height: 30px; - padding-top: 4px; + .rt-resizable-header-content { + height: 100%; + overflow: visible; + } } - .ReactTable .rt-th, - .ReactTable .rt-td { + .rt-th { max-height: $MAX_ROW_HEIGHT; padding: 3px 7px; font-size: 13px; text-align: center; } - .ReactTable .rt-tbody .rt-tr-group:last-child { - border-bottom: $intermediate-color; - border-bottom-style: solid; - border-bottom-width: 1; + .rt-tbody { + direction: rtl; } - .documentView-node-topmost { - text-align: left; - transform-origin: center top; - display: inline-block; - } + .rt-tr-group { + direction: ltr; + max-height: $MAX_ROW_HEIGHT; - .documentView-node:first-child { - background: $light-color; + &:last-child { + border-bottom: $intermediate-color; + border-bottom-style: solid; + border-bottom-width: 1; + } } - .ReactTable .rt-thead .rt-resizable-header:last-child { - overflow: visible; - } -} + .rt-td { + border-width: 1px; + border-right-color: $intermediate-color; + max-height: $MAX_ROW_HEIGHT; + padding: 3px 7px; + font-size: 13px; + text-align: center; -.collectionSchema-header-menuOptions { - position: absolute; - top: $MAX_ROW_HEIGHT; - left: 0; - z-index: 9999; - background-color: $light-color-secondary; - color: black; - border: 1px solid $main-accent; - width: 250px; - padding: 10px; + .imageBox-cont { + position: relative; + max-height: 100%; + } - input { - color: black; - width: 100%; + .imageBox-cont img { + object-fit: contain; + max-width: 100%; + height: 100%; + } + + .videoBox-cont { + object-fit: contain; + width: auto; + height: 100%; + } } } -//options menu styling -#schemaOptionsMenuBtn { - position: absolute; - height: 20px; - width: 20px; - border-radius: 50%; - z-index: 21; - right: 4px; - top: 4px; - pointer-events: auto; - background-color: black; +.documentView-node-topmost { + text-align: left; + transform-origin: center top; display: inline-block; - padding: 0px; - font-size: 100%; -} - -ul { - list-style-type: disc; } -#schema-options-header { - text-align: center; - padding: 0px; - margin: 0px; +.documentView-node:first-child { + background: $light-color; } -.schema-options-subHeader { - color: $intermediate-color; - margin-bottom: 5px; -} +.collectionSchemaView-header { + height: 100%; -#schemaOptionsMenuBtn:hover { - transform: scale(1.15); -} + .collectionSchema-header-menu { + height: 100%; -#preview-schema-checkbox-div { - margin-left: 20px; - font-size: 12px; -} + .collectionSchema-header-toggler { + width: 100%; + height: 100%; + padding: 4px; -#options-flyout-div { - text-align: left; - padding: 0px; - z-index: 100; - font-family: $sans-serif; - padding-left: 5px; + svg { + margin-right: 4px; + } + } + } } -#schema-col-checklist { - overflow: scroll; +.collectionSchema-header-menuOptions { + // position: absolute; + // top: 30px; + // left: 50%; + // transform: translateX(-50%); + // z-index: 9999; + // background-color: $light-color-secondary; + color: black; + // border: 1px solid $main-accent; + width: 175px; + // padding: 10px; text-align: left; - //background-color: $light-color-secondary; - line-height: 25px; - max-height: 175px; - font-family: $sans-serif; - font-size: 12px; -} - -.Resizer { - box-sizing: border-box; - background: #000; - opacity: 0.5; - z-index: 1; - background-clip: padding-box; - - &.horizontal { - height: 11px; - margin: -5px 0; - border-top: 5px solid rgba(255, 255, 255, 0); - border-bottom: 5px solid rgba(255, 255, 255, 0); - cursor: row-resize; - width: 100%; - - &:hover { - border-top: 5px solid rgba(0, 0, 0, 0.5); - border-bottom: 5px solid rgba(0, 0, 0, 0.5); - } + .collectionSchema-headerMenu-group { + margin-bottom: 10px; } - &.vertical { - width: 11px; - margin: 0 -5px; - border-left: 5px solid rgba(255, 255, 255, 0); - border-right: 5px solid rgba(255, 255, 255, 0); - cursor: col-resize; - - &:hover { - border-left: 5px solid rgba(0, 0, 0, 0.5); - border-right: 5px solid rgba(0, 0, 0, 0.5); - } + label { + color: $main-accent; + font-weight: normal; } - &:hover { - -webkit-transition: all 2s ease; - transition: all 2s ease; + input { + color: black; + width: 100%; } -} -.vertical { - section { - width: 100vh; - height: 100vh; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - } + .keys-dropdown { + position: relative; + max-width: 175px; - header { - padding: 1rem; - background: #eee; - } + // .keys-search { - footer { - padding: 1rem; - background: #eee; - } -} + // } -.horizontal { - section { - width: 100vh; - height: 100vh; - display: flex; - flex-direction: column; + .keys-options-wrapper { + width: 100%; + max-height: 150px; + overflow-y: scroll; + position: absolute; + top: 20px; + + .key-option { + background-color: $light-color; + border: 1px solid $light-color-secondary; + padding: 2px 3px; + + &:not(:last-child) { + border-top: 0; + } + + &:hover { + background-color: $light-color-secondary; + } + } + } } - header { - padding: 1rem; - background: #eee; - } + .columnMenu-types { + display: flex; + justify-content: space-between; - footer { - padding: 1rem; - background: #eee; + button { + border-radius: 20px; + } } } -.parent { - width: 100%; - height: 100%; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.header { - background: #aaa; - height: 3rem; - line-height: 3rem; -} - -.wrapper { - background: #ffa; - margin: 5rem; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; +#preview-schema-checkbox-div { + margin-left: 20px; + font-size: 12px; } .-even { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 3572fac55..3ef58bcaf 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -44,7 +44,7 @@ export enum ColumnType { Number, String, Boolean, - Doc, + // Doc, Checkbox } // this map should be used for keys that should have a const type of value @@ -54,21 +54,21 @@ const columnTypes: Map = new Map([ ["page", ColumnType.Number], ["curPage", ColumnType.Number], ["libraryBrush", ColumnType.Boolean], ["zIndex", ColumnType.Number] ]); -@observer -class KeyToggle extends React.Component<{ keyName: string, checked: boolean, toggle: (key: string) => void }> { - constructor(props: any) { - super(props); - } - - render() { - return ( -
- this.props.toggle(this.props.keyName)} /> - {this.props.keyName} -
- ); - } -} +// @observer +// class KeyToggle extends React.Component<{ keyName: string, checked: boolean, toggle: (key: string) => void }> { +// constructor(props: any) { +// super(props); +// } + +// render() { +// return ( +//
+// this.props.toggle(this.props.keyName)} /> +// {this.props.keyName} +//
+// ); +// } +// } @observer export class CollectionSchemaView extends CollectionSubView(doc => doc) { -- cgit v1.2.3-70-g09d2 From 28420a749a0e06ee105a2d8f1cc3c273469b83d7 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Thu, 18 Jul 2019 17:55:19 -0400 Subject: shema rows can be moved by dragging --- .../views/collections/CollectionSchemaCells.tsx | 12 +- .../views/collections/CollectionSchemaHeaders.tsx | 3 + .../CollectionSchemaMovableTableHOC.tsx | 261 +++++++++++++++++++++ .../views/collections/CollectionSchemaView.scss | 82 +++++-- .../views/collections/CollectionSchemaView.tsx | 183 +++++++++++---- 5 files changed, 476 insertions(+), 65 deletions(-) create mode 100644 src/client/views/collections/CollectionSchemaMovableTableHOC.tsx (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 1bb661f88..51e9016b7 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -109,8 +109,8 @@ export class CollectionSchemaCell extends React.Component { }; let reference = React.createRef(); let onItemDown = (e: React.PointerEvent) => { - // (!this.props.CollectionView.props.isSelected() ? undefined : - // SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); + (!this.props.CollectionView.props.isSelected() ? undefined : + SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); }; let field = props.Document[props.fieldKey]; @@ -201,8 +201,8 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell { render() { let reference = React.createRef(); let onItemDown = (e: React.PointerEvent) => { - // (!this.props.CollectionView.props.isSelected() ? undefined : - // SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); + (!this.props.CollectionView.props.isSelected() ? undefined : + SetupDrag(reference, () => this._document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); }; return (
@@ -219,8 +219,8 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell { render() { let reference = React.createRef(); let onItemDown = (e: React.PointerEvent) => { - // (!this.props.CollectionView.props.isSelected() ? undefined : - // SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); + (!this.props.CollectionView.props.isSelected() ? undefined : + SetupDrag(reference, () => this._document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); }; return (
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index d6ebaf8d8..c81cf1aef 100644 --- a/src/client/views/collections/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -177,7 +177,10 @@ export class CollectionSchemaColumnMenu extends React.Component return (
+ {/*
*/}
{ this.props.setIsEditing(true); }}>{this.props.menuButtonContent}
+ {/* {this._isOpen ? this.renderContent() : <>} */} + {/*
*/}
); diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx new file mode 100644 index 000000000..44a134d31 --- /dev/null +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -0,0 +1,261 @@ +import React = require("react"); +import { TableProps, ReactTableDefaults, Column, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0 } from "react-table"; +import { ComponentType, ComponentClass } from 'react'; +import { action } from "mobx"; +import "./CollectionSchemaView.scss"; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faBars } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Transform } from "../../util/Transform"; +import { Doc } from "../../../new_fields/Doc"; +import { DragManager, SetupDrag } from "../../util/DragManager"; +import { SelectionManager } from "../../util/SelectionManager"; +import { Cast, FieldValue } from "../../../new_fields/Types"; + +library.add(faBars); + +// export interface MovableSchemaProps { +// ScreenToLocalTransform: () => Transform; +// addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; +// moveDoc: DragManager.MoveFunction; +// columnsValues: string[]; +// columnsList: Column[]; +// setColumnsOrder: (columns: string[]) => void; +// numImmovableColumns?: number; +// } + +// export default function CollectionSchemaMovableHOC>(WrappedComponent: ComponentType): ComponentClass { +// return class CollectionSchemaMovableSchemaHOC extends React.Component { +// constructor(props: any) { +// super(props); +// } + +// reorderColumns(toMove: string, relativeTo: string, before: boolean, columnsValues: string[], setColumnsOrder: (columns: string[]) => void) { +// let columns = [...columnsValues]; +// let oldIndex = columns.indexOf(toMove); +// let relIndex = columns.indexOf(relativeTo); +// let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; + +// if (oldIndex === newIndex) return; + +// columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); +// setColumnsOrder(columns); +// } + +// createColumns(columnsValues: string[], columnsList: Column[], setColumnsOrder: (columnsValues: string[]) => void, ScreenToLocalTransform: () => Transform): Column[] { +// let immovableIndex = this.props.numImmovableColumns ? columnsList.length - this.props.numImmovableColumns! : columnsList.length; +// return columnsList.map((col, index) => { +// if (index >= immovableIndex) { +// return col; +// } else { +// return ({ ...col, Header: MovableColumn(col.Header, columnsValues[index], columnsValues, setColumnsOrder, this.reorderColumns, ScreenToLocalTransform) }); +// } +// }); +// } + +// render() { +// console.log("THIS IS THE RIGHT HOC"); +// const { ScreenToLocalTransform, addDoc, moveDoc, columnsValues, columnsList, setColumnsOrder, getTrProps, ...props } = this.props; +// return ( +// +// ); +// } + +// }; +// } +// //TrComponent={MovableRow(ScreenToLocalTransform, addDoc, moveDoc)} +// //columns={this.createColumns(columnsValues, columnsList, setColumnsOrder, ScreenToLocalTransform)} + +// export function MovableSchemaHOC>(WrappedComponent: ComponentType): ComponentClass { +// return class MovableSchemaHOC extends React.Component { +// constructor(props: any) { +// super(props); +// } + +// createColumns(columnsValues: string[], columnsList: Column[], setColumnsOrder: (columnsValues: string[]) => void, ScreenToLocalTransform: () => Transform): Column[] { +// let immovableIndex = this.props.numImmovableColumns ? columnsList.length - this.props.numImmovableColumns! : columnsList.length; +// return columnsList.map((col, index) => { +// if (index >= immovableIndex) { +// return col; +// } else { +// return ({ ...col, Header: MovableColumn(col.Header, columnsValues[index], columnsValues, setColumnsOrder, this.reorderColumns, ScreenToLocalTransform) }); +// } +// }); +// } + +// reorderColumns(toMove: string, relativeTo: string, before: boolean, columnsValues: string[], setColumnsOrder: (columns: string[]) => void) { +// let columns = [...columnsValues]; +// let oldIndex = columns.indexOf(toMove); +// let relIndex = columns.indexOf(relativeTo); +// let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; + +// if (oldIndex === newIndex) return; + +// columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); +// setColumnsOrder(columns); +// } + +// render() { +// const { ScreenToLocalTransform, addDoc, moveDoc, columnsValues, columnsList, setColumnsOrder, getTrProps, ...props } = this.props; +// return ( +// +// ); +// } +// }; +// } + + + + +export interface MovableColumnProps { + columnRenderer: TableCellRenderer; + columnValue: string; + allColumns: string[]; + reorderColumns: (toMove: string, relativeTo: string, before: boolean, columns: string[]) => void; + ScreenToLocalTransform: () => Transform; +} +export class MovableColumn extends React.Component { + // private _ref: React.RefObject = React.createRef(); + + onDragStart = (e: React.DragEvent, ref: React.RefObject): void => { + console.log("drag start"); + e.dataTransfer.setData("column", this.props.columnValue); + } + + onDragOver = (e: React.DragEvent,ref: React.RefObject): void => { + console.log("drag over"); + let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); + let rect = ref.current!.getBoundingClientRect(); + let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); + let before = x[0] < bounds[0]; + + ref.current!.className = "collectionSchema-column-header"; + if (before) ref.current!.className += " col-before"; + if (!before) ref.current!.className += " col-after"; + // e.stopPropagation(); + } + + onDragLeave = (e: React.DragEvent, ref: React.RefObject): void => { + console.log("drag leave"); + ref.current!.className = "collectionSchema-column-header"; + e.stopPropagation(); + } + + onDrop = (e: React.DragEvent,ref: React.RefObject): void => { + console.log("on drop"); + // TODO: get column being dropped and before/after + let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); + let rect = ref.current!.getBoundingClientRect(); + let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); + let before = x[0] < bounds[0]; + + this.props.reorderColumns(e.dataTransfer.getData("column"), this.props.columnValue, before, this.props.allColumns); + ref.current!.className = "collectionSchema-column-header"; + } + + render() { + let ref: React.RefObject = React.createRef(); + return ( +
console.log("pointer down")} onPointerEnter={() => console.log("pointer enter")} onPointerOut={() => console.log("pointer exit")} + onDragStart={e => this.onDragStart(e, ref)} onDragOver={e => this.onDragOver(e, ref)} onDragLeave={e => this.onDragLeave(e, ref)} onDrop={e => this.onDrop(e, ref)}> + {this.props.columnRenderer} +
+ ); + } +} + +// export function MovableColumn(columnRenderer: TableCellRenderer, columnValue: string, allColumns: string[], +// reorderColumns: (toMove: string, relativeTo: string, before: boolean, columns: string[]) => void, +// ScreenToLocalTransform: () => Transform) { +// return ; +// } + +export function MovableRow(ScreenToLocalTransform: () => Transform, addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean, moveDoc: DragManager.MoveFunction) { + return class MovableRow extends React.Component { + private _header?: React.RefObject = React.createRef(); + private _treedropDisposer?: DragManager.DragDropDisposer; + + onPointerEnter = (e: React.PointerEvent): void => { + if (e.buttons === 1 && SelectionManager.GetIsDragging()) { + this._header!.current!.className = "collectionSchema-row-wrapper"; + document.addEventListener("pointermove", this.onDragMove, true); + } + } + onPointerLeave = (e: React.PointerEvent): void => { + this._header!.current!.className = "collectionSchema-row-wrapper"; + document.removeEventListener("pointermove", this.onDragMove, true); + } + onDragMove = (e: PointerEvent): void => { + let x = ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); + let rect = this._header!.current!.getBoundingClientRect(); + let bounds = ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); + let before = x[1] < bounds[1]; + this._header!.current!.className = "collectionSchema-row-wrapper"; + if (before) this._header!.current!.className += " row-above"; + if (!before) this._header!.current!.className += " row-below"; + e.stopPropagation(); + } + + createTreeDropTarget = (ele: HTMLDivElement) => { + this._treedropDisposer && this._treedropDisposer(); + if (ele) { + this._treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.treeDrop.bind(this) } }); + } + } + + treeDrop = (e: Event, de: DragManager.DropEvent) => { + const { children = null, rowInfo } = this.props; + if (!rowInfo) return false; + + const { original } = rowInfo; + const rowDoc = FieldValue(Cast(original, Doc)); + if (!rowDoc) return false; + + let x = ScreenToLocalTransform().transformPoint(de.x, de.y); + let rect = this._header!.current!.getBoundingClientRect(); + let bounds = ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); + let before = x[1] < bounds[1]; + if (de.data instanceof DragManager.DocumentDragData) { + e.stopPropagation(); + if (de.data.draggedDocuments[0] === rowDoc) return true; + let addDocument = (doc: Doc) => addDoc(doc, rowDoc, before); + let movedDocs = de.data.draggedDocuments; //(de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments); + return (de.data.dropAction || de.data.userDropAction) ? + de.data.droppedDocuments.reduce((added: boolean, d) => addDoc(d, rowDoc, before) || added, false) + : (de.data.moveDocument) ? + movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false) + : de.data.droppedDocuments.reduce((added: boolean, d) => addDoc(d, rowDoc, before), false); + } + return false; + } + + render() { + const { children = null, rowInfo } = this.props; + if (!rowInfo) { + console.log("no rowinfo"); + return {children}; + } + + const { original } = rowInfo; + const doc = FieldValue(Cast(original, Doc)); + if (!doc) return <>; + + let reference = React.createRef(); + let onItemDown = SetupDrag(reference, () => doc, moveDoc); + + return ( +
+
+
+ + {children} + +
+
+
+ ); + } + }; +} + diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 4bc7a778c..fce1c8833 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -105,6 +105,14 @@ direction: ltr; max-height: $MAX_ROW_HEIGHT; + &:nth-child(even) { + background-color: $light-color; + } + + &:nth-child(odd) { + background-color: $light-color-secondary; + } + &:last-child { border-bottom: $intermediate-color; border-bottom-style: solid; @@ -112,6 +120,10 @@ } } + .rt-tr { + width: 100%; + } + .rt-td { border-width: 1px; border-right-color: $intermediate-color; @@ -149,6 +161,18 @@ background: $light-color; } +.collectionSchema-column-header { + height: 100%; + background-color: green; + + &.col-before { + border-left: 2px solid red; + } + &.col-after { + border-right: 2px solid red; + } +} + .collectionSchemaView-header { height: 100%; @@ -168,16 +192,8 @@ } .collectionSchema-header-menuOptions { - // position: absolute; - // top: 30px; - // left: 50%; - // transform: translateX(-50%); - // z-index: 9999; - // background-color: $light-color-secondary; color: black; - // border: 1px solid $main-accent; width: 175px; - // padding: 10px; text-align: left; .collectionSchema-headerMenu-group { @@ -235,15 +251,51 @@ } } -#preview-schema-checkbox-div { - margin-left: 20px; - font-size: 12px; +.collectionSchema-row { + height: $MAX_ROW_HEIGHT; + // display: flex; + + .row-dragger { + height: $MAX_ROW_HEIGHT; + } + + .collectionSchema-row-wrapper { + max-height: $MAX_ROW_HEIGHT; + // width: 100%; + // border: 1px solid lightgray; + + &.row-above { + border-top: 1px solid red; + } + &.row-below { + border-bottom: 1px solid red; + } + &.row-inside { + border: 1px solid red; + } + } } -.-even { - background: $light-color !important; + +.collectionSchemaView-cellWrapper { + // height: $MAX_ROW_HEIGHT; + // background-color: red; + height: 100%; + padding: 4px; + + &.focused { + // background-color: yellowgreen; + border: 2px solid yellowgreen; + + input { + outline: 0; + border: none; + background-color: yellow; + } + } } -.-odd { - background: $light-color-secondary !important; +#preview-schema-checkbox-div { + margin-left: 20px; + font-size: 12px; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 3ef58bcaf..4746e637b 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -4,7 +4,7 @@ import { faCog, faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, trace, untracked } from "mobx"; import { observer } from "mobx-react"; -import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults, TableCellRenderer } from "react-table"; +import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults, TableCellRenderer, Column } from "react-table"; import "react-table/react-table.css"; import { emptyFunction, returnFalse, returnZero, returnOne } from "../../../Utils"; import { Doc, DocListCast, DocListCastAsync, Field, FieldResult } from "../../../new_fields/Doc"; @@ -33,12 +33,14 @@ import { undoBatch } from "../../util/UndoManager"; import { timesSeries } from "async"; import { CollectionSchemaHeader, CollectionSchemaAddColumnHeader } from "./CollectionSchemaHeaders"; import { CellProps, CollectionSchemaCell, CollectionSchemaNumberCell, CollectionSchemaStringCell, CollectionSchemaBooleanCell, CollectionSchemaCheckboxCell } from "./CollectionSchemaCells"; - +import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC"; library.add(faCog); library.add(faPlus); // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 +// const MovableTable = CollectionSchemaMovableSchemaHOC(ReactTable); + export enum ColumnType { Any, Number, @@ -54,22 +56,6 @@ const columnTypes: Map = new Map([ ["page", ColumnType.Number], ["curPage", ColumnType.Number], ["libraryBrush", ColumnType.Boolean], ["zIndex", ColumnType.Number] ]); -// @observer -// class KeyToggle extends React.Component<{ keyName: string, checked: boolean, toggle: (key: string) => void }> { -// constructor(props: any) { -// super(props); -// } - -// render() { -// return ( -//
-// this.props.toggle(this.props.keyName)} /> -// {this.props.keyName} -//
-// ); -// } -// } - @observer export class CollectionSchemaView extends CollectionSubView(doc => doc) { private _mainCont?: HTMLDivElement; @@ -83,6 +69,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @observable _newKeyName: string = ""; @observable previewScript: string = ""; @observable _headerIsEditing: boolean = false; + @observable _cellIsEditing: boolean = false; + @observable _focusedCell: {row: number, col: number} = {row: 0, col: 0}; @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } @@ -90,10 +78,25 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get columns() { return Cast(this.props.Document.schemaColumns, listSpec("string"), []); } set columns(columns: string[]) { this.props.Document.schemaColumns = new List(columns); } @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } - @computed get tableColumns() { + @computed get tableColumns(): Column[] { let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1); let cols = this.columns.map(col => { + let focusedRow = this._focusedCell.row; + let focusedCol = this._focusedCell.col; + let isEditable = !this._headerIsEditing; + let header = ; + return { Header: doc) { deleteColumn={this.deleteColumn} setColumnType={this.setColumnType} />, + // Header: , accessor: (doc: Doc) => doc ? doc[col] : 0, id: col, Cell: (rowProps: CellInfo) => { let row = rowProps.index; let column = this.columns.indexOf(rowProps.column.id!); - // let isFocused = focusedRow === row && focusedCol === column; - let isFocused = false; + let isFocused = focusedRow === row && focusedCol === column; let props: CellProps = { row: row, col: column, rowProps: rowProps, isFocused: isFocused, - changeFocusedCellByDirection: action(emptyFunction),//this.changeFocusedCellByDirection, - changeFocusedCellByIndex: action(emptyFunction), //this.changeFocusedCellByIndex, + changeFocusedCellByDirection: this.changeFocusedCellByDirection, + changeFocusedCellByIndex: this.changeFocusedCellByIndex, CollectionView: this.props.CollectionView, ContainingCollection: this.props.ContainingCollectionView, Document: this.props.Document, fieldKey: this.props.fieldKey, renderDepth: this.props.renderDepth, addDocTab: this.props.addDocTab, moveDocument: this.props.moveDocument, - setIsEditing: action(emptyFunction), //this.setCellIsEditing, - isEditable: true //isEditable + setIsEditing: this.setCellIsEditing, + isEditable: isEditable }; let colType = this.getColumnType(col); - if (colType === ColumnType.Number) return - if (colType === ColumnType.String) return - if (colType === ColumnType.Boolean) return - if (colType === ColumnType.Checkbox) return - return + if (colType === ColumnType.Number) return ; + if (colType === ColumnType.String) return ; + if (colType === ColumnType.Boolean) return ; + if (colType === ColumnType.Checkbox) return ; + return ; } }; }) as {Header: TableCellRenderer, accessor: (doc: Doc) => FieldResult, id: string, Cell: (rowProps: CellInfo) => JSX.Element}[]; @@ -156,6 +159,19 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return cols; } + reorderColumns(toMove: string, relativeTo: string, before: boolean, columnsValues: string[]) { + let columns = [...columnsValues]; + let oldIndex = columns.indexOf(toMove); + let relIndex = columns.indexOf(relativeTo); + let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; + + if (oldIndex === newIndex) return; + + columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); + this.columns = columns; + } + + onHeaderDrag = (columnName: string) => { let schemaDoc = Cast(this.props.Document.schemaDoc, Doc); if (schemaDoc instanceof Doc) { @@ -170,12 +186,21 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return this.props.Document; } + componentDidMount() { + document.addEventListener("keydown", this.onKeyDown); + } + + componentWillUnmount() { + document.removeEventListener("keydown", this.onKeyDown); + } + private getTrProps: ComponentPropsGetterR = (state, rowInfo) => { const that = this; if (!rowInfo) { return {}; } return { + rowInfo, onClick: action((e: React.MouseEvent, handleOriginal: Function) => { that.props.select(e.ctrlKey); that._selectedIndex = rowInfo.index; @@ -195,27 +220,63 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { this._mainCont = ele; super.CreateDropTarget(ele); } + @action + changeFocusedCellByDirection = (direction: string): void => { + switch (direction) { + case "tab": + if (this._focusedCell.col + 1 === this.columns.length && this._focusedCell.row + 1 === this.childDocs.length) { + this._focusedCell = { row: 0, col: 0 }; + } else if (this._focusedCell.col + 1 === this.columns.length) { + this._focusedCell = { row: this._focusedCell.row + 1, col: 0 }; + } else { + this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col + 1 }; + } + break; + case "right": + this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col + 1 === this.columns.length ? this._focusedCell.col : this._focusedCell.col + 1 }; + break; + case "left": + this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col === 0 ? this._focusedCell.col : this._focusedCell.col - 1 }; + break; + case "up": + this._focusedCell = { row: this._focusedCell.row === 0 ? this._focusedCell.row : this._focusedCell.row - 1, col: this._focusedCell.col }; + break; + case "down": + this._focusedCell = { row: this._focusedCell.row + 1 === this.childDocs.length ? this._focusedCell.row : this._focusedCell.row + 1, col: this._focusedCell.col }; + break; + } + } @action - setHeaderIsEditing = (isEditing: boolean) => { - this._headerIsEditing = isEditing; + changeFocusedCellByIndex = (row: number, col: number): void => { + this._focusedCell = { row: row, col: col }; } @action - toggleKey = (key: string) => { - let list = Cast(this.props.Document.schemaColumns, listSpec("string")); - if (list === undefined) { - this.props.Document.schemaColumns = list = new List([key]); - } else { - const index = list.indexOf(key); - if (index === -1) { - list.push(key); - } else { - list.splice(index, 1); - } - } + setCellIsEditing = (isEditing: boolean): void => { + this._cellIsEditing = isEditing; } + @action + setHeaderIsEditing = (isEditing: boolean): void => { + this._headerIsEditing = isEditing; + } + + // @action + // toggleKey = (key: string) => { + // let list = Cast(this.props.Document.schemaColumns, listSpec("string")); + // if (list === undefined) { + // this.props.Document.schemaColumns = list = new List([key]); + // } else { + // const index = list.indexOf(key); + // if (index === -1) { + // list.push(key); + // } else { + // list.splice(index, 1); + // } + // } + // } + //toggles preview side-panel of schema @action toggleExpander = () => { @@ -262,6 +323,13 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { } } + onKeyDown = (e: KeyboardEvent): void => { + if (!this._cellIsEditing && !this._headerIsEditing) { + let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : ""; + this.changeFocusedCellByDirection(direction); + } + } + @action makeDB = async () => { let csv: string = this.columns.reduce((val, col) => val + col + ",", ""); @@ -410,7 +478,31 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get reactTable() { + let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before); + let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc); let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; + + // return this.columns = columns} + // numImmovableColumns={1} + // />; + + + // // let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; return doc) { // column={{ ...ReactTableDefaults.column, Cell: this.renderCell, }} getTrProps={this.getTrProps} sortable={false} + + TrComponent={MovableRow(this.props.ScreenToLocalTransform, addDoc, moveDoc)} />; } @@ -472,6 +566,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return (
this.onDrop(e, {})} onContextMenu={this.onContextMenu} ref={this.createTarget}> +
TESTER
{this.reactTable} {this.dividerDragger} {!this.previewWidth() ? (null) : this.previewPanel} -- cgit v1.2.3-70-g09d2 From 8a1be635352177ba05845851289d1a67b4060708 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Thu, 18 Jul 2019 19:24:58 -0400 Subject: schema cols can be moved by dragging --- src/client/util/DragManager.ts | 13 + .../CollectionSchemaMovableTableHOC.tsx | 346 +++++++++------------ .../views/collections/CollectionSchemaView.scss | 15 +- .../views/collections/CollectionSchemaView.tsx | 63 +--- 4 files changed, 175 insertions(+), 262 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 323908302..f9f6b05c0 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -288,6 +288,15 @@ export namespace DragManager { [id: string]: any; } + // for column dragging in schema view + export class ColumnDragData { + constructor(colKey: string) { + this.colKey = colKey; + } + colKey: string; + [id: string]: any; + } + export function StartLinkDrag(ele: HTMLElement, dragData: LinkDragData, downX: number, downY: number, options?: DragOptions) { StartDrag([ele], dragData, downX, downY, options); } @@ -296,6 +305,10 @@ export namespace DragManager { StartDrag([ele], dragData, downX, downY, options); } + export function StartColumnDrag(ele: HTMLElement, dragData: ColumnDragData, downX: number, downY: number, options?:DragOptions) { + StartDrag([ele], dragData, downX, downY, options); + } + export let AbortDrag: () => void = emptyFunction; function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: { [id: string]: any }) => void) { diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 44a134d31..3a61881a7 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -1,111 +1,12 @@ import React = require("react"); -import { TableProps, ReactTableDefaults, Column, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0 } from "react-table"; -import { ComponentType, ComponentClass } from 'react'; -import { action } from "mobx"; +import { ReactTableDefaults, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0 } from "react-table"; import "./CollectionSchemaView.scss"; -import { library } from '@fortawesome/fontawesome-svg-core'; -import { faBars } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Transform } from "../../util/Transform"; import { Doc } from "../../../new_fields/Doc"; import { DragManager, SetupDrag } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { Cast, FieldValue } from "../../../new_fields/Types"; -library.add(faBars); - -// export interface MovableSchemaProps { -// ScreenToLocalTransform: () => Transform; -// addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; -// moveDoc: DragManager.MoveFunction; -// columnsValues: string[]; -// columnsList: Column[]; -// setColumnsOrder: (columns: string[]) => void; -// numImmovableColumns?: number; -// } - -// export default function CollectionSchemaMovableHOC>(WrappedComponent: ComponentType): ComponentClass { -// return class CollectionSchemaMovableSchemaHOC extends React.Component { -// constructor(props: any) { -// super(props); -// } - -// reorderColumns(toMove: string, relativeTo: string, before: boolean, columnsValues: string[], setColumnsOrder: (columns: string[]) => void) { -// let columns = [...columnsValues]; -// let oldIndex = columns.indexOf(toMove); -// let relIndex = columns.indexOf(relativeTo); -// let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; - -// if (oldIndex === newIndex) return; - -// columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); -// setColumnsOrder(columns); -// } - -// createColumns(columnsValues: string[], columnsList: Column[], setColumnsOrder: (columnsValues: string[]) => void, ScreenToLocalTransform: () => Transform): Column[] { -// let immovableIndex = this.props.numImmovableColumns ? columnsList.length - this.props.numImmovableColumns! : columnsList.length; -// return columnsList.map((col, index) => { -// if (index >= immovableIndex) { -// return col; -// } else { -// return ({ ...col, Header: MovableColumn(col.Header, columnsValues[index], columnsValues, setColumnsOrder, this.reorderColumns, ScreenToLocalTransform) }); -// } -// }); -// } - -// render() { -// console.log("THIS IS THE RIGHT HOC"); -// const { ScreenToLocalTransform, addDoc, moveDoc, columnsValues, columnsList, setColumnsOrder, getTrProps, ...props } = this.props; -// return ( -// -// ); -// } - -// }; -// } -// //TrComponent={MovableRow(ScreenToLocalTransform, addDoc, moveDoc)} -// //columns={this.createColumns(columnsValues, columnsList, setColumnsOrder, ScreenToLocalTransform)} - -// export function MovableSchemaHOC>(WrappedComponent: ComponentType): ComponentClass { -// return class MovableSchemaHOC extends React.Component { -// constructor(props: any) { -// super(props); -// } - -// createColumns(columnsValues: string[], columnsList: Column[], setColumnsOrder: (columnsValues: string[]) => void, ScreenToLocalTransform: () => Transform): Column[] { -// let immovableIndex = this.props.numImmovableColumns ? columnsList.length - this.props.numImmovableColumns! : columnsList.length; -// return columnsList.map((col, index) => { -// if (index >= immovableIndex) { -// return col; -// } else { -// return ({ ...col, Header: MovableColumn(col.Header, columnsValues[index], columnsValues, setColumnsOrder, this.reorderColumns, ScreenToLocalTransform) }); -// } -// }); -// } - -// reorderColumns(toMove: string, relativeTo: string, before: boolean, columnsValues: string[], setColumnsOrder: (columns: string[]) => void) { -// let columns = [...columnsValues]; -// let oldIndex = columns.indexOf(toMove); -// let relIndex = columns.indexOf(relativeTo); -// let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; - -// if (oldIndex === newIndex) return; - -// columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); -// setColumnsOrder(columns); -// } - -// render() { -// const { ScreenToLocalTransform, addDoc, moveDoc, columnsValues, columnsList, setColumnsOrder, getTrProps, ...props } = this.props; -// return ( -// -// ); -// } -// }; -// } - - - export interface MovableColumnProps { columnRenderer: TableCellRenderer; @@ -115,147 +16,178 @@ export interface MovableColumnProps { ScreenToLocalTransform: () => Transform; } export class MovableColumn extends React.Component { - // private _ref: React.RefObject = React.createRef(); + private _header?: React.RefObject = React.createRef(); + private _colDropDisposer?: DragManager.DragDropDisposer; - onDragStart = (e: React.DragEvent, ref: React.RefObject): void => { - console.log("drag start"); - e.dataTransfer.setData("column", this.props.columnValue); + onPointerEnter = (e: React.PointerEvent): void => { + if (e.buttons === 1 && SelectionManager.GetIsDragging()) { + this._header!.current!.className = "collectionSchema-col-wrapper"; + document.addEventListener("pointermove", this.onDragMove, true); + } } - - onDragOver = (e: React.DragEvent,ref: React.RefObject): void => { - console.log("drag over"); + onPointerLeave = (e: React.PointerEvent): void => { + this._header!.current!.className = "collectionSchema-col-wrapper"; + document.removeEventListener("pointermove", this.onDragMove, true); + } + onDragMove = (e: PointerEvent): void => { let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); - let rect = ref.current!.getBoundingClientRect(); + let rect = this._header!.current!.getBoundingClientRect(); let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); let before = x[0] < bounds[0]; - - ref.current!.className = "collectionSchema-column-header"; - if (before) ref.current!.className += " col-before"; - if (!before) ref.current!.className += " col-after"; - // e.stopPropagation(); + 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(); } - onDragLeave = (e: React.DragEvent, ref: React.RefObject): void => { - console.log("drag leave"); - ref.current!.className = "collectionSchema-column-header"; - e.stopPropagation(); + createColDropTarget = (ele: HTMLDivElement) => { + this._colDropDisposer && this._colDropDisposer(); + if (ele) { + this._colDropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.colDrop.bind(this) } }); + } } - onDrop = (e: React.DragEvent,ref: React.RefObject): void => { - console.log("on drop"); - // TODO: get column being dropped and before/after - let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); - let rect = ref.current!.getBoundingClientRect(); + colDrop = (e: Event, de: DragManager.DropEvent) => { + document.removeEventListener("pointermove", this.onDragMove, true); + let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y); + let rect = this._header!.current!.getBoundingClientRect(); let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top); let before = x[0] < bounds[0]; + if (de.data instanceof DragManager.ColumnDragData) { + this.props.reorderColumns(de.data.colKey, this.props.columnValue, before, this.props.allColumns); + return true; + } + return false; + } - this.props.reorderColumns(e.dataTransfer.getData("column"), this.props.columnValue, before, this.props.allColumns); - ref.current!.className = "collectionSchema-column-header"; + setupDrag (ref: React.RefObject) { + let onRowMove = (e: PointerEvent) => { + e.stopPropagation(); + e.preventDefault(); + + document.removeEventListener("pointermove", onRowMove); + document.removeEventListener('pointerup', onRowUp); + let dragData = new DragManager.ColumnDragData(this.props.columnValue); + DragManager.StartColumnDrag(ref.current!, dragData, e.x, e.y); + }; + let onRowUp = (): void => { + document.removeEventListener("pointermove", onRowMove); + document.removeEventListener('pointerup', onRowUp); + }; + let onItemDown = (e: React.PointerEvent) => { + if (e.button === 0) { + e.stopPropagation(); + document.addEventListener("pointermove", onRowMove); + document.addEventListener("pointerup", onRowUp); + } + }; + return onItemDown; } + render() { - let ref: React.RefObject = React.createRef(); + let reference = React.createRef(); + let onItemDown = this.setupDrag(reference); + return ( -
console.log("pointer down")} onPointerEnter={() => console.log("pointer enter")} onPointerOut={() => console.log("pointer exit")} - onDragStart={e => this.onDragStart(e, ref)} onDragOver={e => this.onDragOver(e, ref)} onDragLeave={e => this.onDragLeave(e, ref)} onDrop={e => this.onDrop(e, ref)}> - {this.props.columnRenderer} +
+
+
+ {this.props.columnRenderer} +
+
); } } -// export function MovableColumn(columnRenderer: TableCellRenderer, columnValue: string, allColumns: string[], -// reorderColumns: (toMove: string, relativeTo: string, before: boolean, columns: string[]) => void, -// ScreenToLocalTransform: () => Transform) { -// return ; -// } +export interface MovableRowProps { + ScreenToLocalTransform: () => Transform; + addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; + moveDoc: DragManager.MoveFunction; +} -export function MovableRow(ScreenToLocalTransform: () => Transform, addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean, moveDoc: DragManager.MoveFunction) { - return class MovableRow extends React.Component { - private _header?: React.RefObject = React.createRef(); - private _treedropDisposer?: DragManager.DragDropDisposer; +export class MovableRow extends React.Component { + private _header?: React.RefObject = React.createRef(); + private _rowDropDisposer?: DragManager.DragDropDisposer; - onPointerEnter = (e: React.PointerEvent): void => { - if (e.buttons === 1 && SelectionManager.GetIsDragging()) { - this._header!.current!.className = "collectionSchema-row-wrapper"; - document.addEventListener("pointermove", this.onDragMove, true); - } - } - onPointerLeave = (e: React.PointerEvent): void => { - this._header!.current!.className = "collectionSchema-row-wrapper"; - document.removeEventListener("pointermove", this.onDragMove, true); - } - onDragMove = (e: PointerEvent): void => { - let x = ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); - let rect = this._header!.current!.getBoundingClientRect(); - let bounds = ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); - let before = x[1] < bounds[1]; + onPointerEnter = (e: React.PointerEvent): void => { + if (e.buttons === 1 && SelectionManager.GetIsDragging()) { this._header!.current!.className = "collectionSchema-row-wrapper"; - if (before) this._header!.current!.className += " row-above"; - if (!before) this._header!.current!.className += " row-below"; - e.stopPropagation(); + document.addEventListener("pointermove", this.onDragMove, true); } + } + onPointerLeave = (e: React.PointerEvent): void => { + this._header!.current!.className = "collectionSchema-row-wrapper"; + document.removeEventListener("pointermove", this.onDragMove, true); + } + onDragMove = (e: PointerEvent): void => { + let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); + let rect = this._header!.current!.getBoundingClientRect(); + let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); + let before = x[1] < bounds[1]; + this._header!.current!.className = "collectionSchema-row-wrapper"; + if (before) this._header!.current!.className += " row-above"; + if (!before) this._header!.current!.className += " row-below"; + e.stopPropagation(); + } - createTreeDropTarget = (ele: HTMLDivElement) => { - this._treedropDisposer && this._treedropDisposer(); - if (ele) { - this._treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.treeDrop.bind(this) } }); - } + createRowDropTarget = (ele: HTMLDivElement) => { + this._rowDropDisposer && this._rowDropDisposer(); + if (ele) { + this._rowDropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.rowDrop.bind(this) } }); } + } - treeDrop = (e: Event, de: DragManager.DropEvent) => { - const { children = null, rowInfo } = this.props; - if (!rowInfo) return false; + rowDrop = (e: Event, de: DragManager.DropEvent) => { + const { children = null, rowInfo } = this.props; + if (!rowInfo) return false; - const { original } = rowInfo; - const rowDoc = FieldValue(Cast(original, Doc)); - if (!rowDoc) return false; + const { original } = rowInfo; + const rowDoc = FieldValue(Cast(original, Doc)); + if (!rowDoc) return false; - let x = ScreenToLocalTransform().transformPoint(de.x, de.y); - let rect = this._header!.current!.getBoundingClientRect(); - let bounds = ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); - let before = x[1] < bounds[1]; - if (de.data instanceof DragManager.DocumentDragData) { - e.stopPropagation(); - if (de.data.draggedDocuments[0] === rowDoc) return true; - let addDocument = (doc: Doc) => addDoc(doc, rowDoc, before); - let movedDocs = de.data.draggedDocuments; //(de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments); - return (de.data.dropAction || de.data.userDropAction) ? - de.data.droppedDocuments.reduce((added: boolean, d) => addDoc(d, rowDoc, before) || added, false) - : (de.data.moveDocument) ? - movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false) - : de.data.droppedDocuments.reduce((added: boolean, d) => addDoc(d, rowDoc, before), false); - } - return false; + let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y); + let rect = this._header!.current!.getBoundingClientRect(); + let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2); + let before = x[1] < bounds[1]; + if (de.data instanceof DragManager.DocumentDragData) { + e.stopPropagation(); + if (de.data.draggedDocuments[0] === rowDoc) return true; + let addDocument = (doc: Doc) => this.props.addDoc(doc, rowDoc, before); + let movedDocs = de.data.draggedDocuments; //(de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments); + return (de.data.dropAction || de.data.userDropAction) ? + de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before) || added, false) + : (de.data.moveDocument) ? + movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false) + : de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false); } + return false; + } - render() { - const { children = null, rowInfo } = this.props; - if (!rowInfo) { - console.log("no rowinfo"); - return {children}; - } + render() { + const { children = null, rowInfo } = this.props; + if (!rowInfo) { + return {children}; + } - const { original } = rowInfo; - const doc = FieldValue(Cast(original, Doc)); - if (!doc) return <>; + const { original } = rowInfo; + const doc = FieldValue(Cast(original, Doc)); + if (!doc) return <>; - let reference = React.createRef(); - let onItemDown = SetupDrag(reference, () => doc, moveDoc); + let reference = React.createRef(); + let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc); - return ( -
-
-
- - {children} - -
+ return ( +
+
+
+ + {children} +
- ); - } - }; -} - +
+ ); + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index fce1c8833..15dec4e44 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -161,18 +161,21 @@ background: $light-color; } -.collectionSchema-column-header { +.collectionSchema-col{ height: 100%; background-color: green; - &.col-before { - border-left: 2px solid red; - } - &.col-after { - border-right: 2px solid red; + .collectionSchema-col-wrapper { + &.col-before { + border-left: 2px solid red; + } + &.col-after { + border-right: 2px solid red; + } } } + .collectionSchemaView-header { height: 100%; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 4746e637b..b9b299e13 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -62,7 +62,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { private _startPreviewWidth = 0; private DIVIDER_WIDTH = 4; - @observable _columns: Array = ["title", "data", "author"]; + // @observable _columns: Array = ["title", "data", "author"]; @observable _selectedIndex = 0; @observable _columnsPercentage = 0; @observable _keys: string[] = []; @@ -76,7 +76,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); } @computed get columns() { return Cast(this.props.Document.schemaColumns, listSpec("string"), []); } - set columns(columns: string[]) { this.props.Document.schemaColumns = new List(columns); } + set columns(columns: string[]) {this.props.Document.schemaColumns = new List(columns); } @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } @computed get tableColumns(): Column[] { let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1); @@ -98,18 +98,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { />; return { - Header: , - // Header: , + Header: , accessor: (doc: Doc) => doc ? doc[col] : 0, id: col, Cell: (rowProps: CellInfo) => { @@ -159,7 +148,12 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return cols; } - reorderColumns(toMove: string, relativeTo: string, before: boolean, columnsValues: string[]) { + @action + setColumns = (columns: string[]) => { + this.columns = columns; + } + + reorderColumns = (toMove: string, relativeTo: string, before: boolean, columnsValues: string[]) => { let columns = [...columnsValues]; let oldIndex = columns.indexOf(toMove); let relIndex = columns.indexOf(relativeTo); @@ -168,7 +162,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { if (oldIndex === newIndex) return; columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); - this.columns = columns; + this.setColumns(columns); } @@ -200,6 +194,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return {}; } return { + ScreenToLocalTransform: this.props.ScreenToLocalTransform, + addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before), + moveDoc: (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc), rowInfo, onClick: action((e: React.MouseEvent, handleOriginal: Function) => { that.props.select(e.ctrlKey); @@ -209,10 +206,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { handleOriginal(); } }), - style: { - background: rowInfo.index === this._selectedIndex ? "lightGray" : "white", - //color: rowInfo.index === this._selectedIndex ? "white" : "black" - } }; } @@ -401,7 +394,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { let newTypesDoc = new Doc(); newTypesDoc[key] = type; this.props.Document.schemaColumnTypes = newTypesDoc; - console.log("no typesDoc"); return; } else { typesDoc[key] = type; @@ -478,31 +470,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get reactTable() { - let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before); - let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc); let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; - - // return this.columns = columns} - // numImmovableColumns={1} - // />; - - - // // let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; return doc) { pageSize={this.childDocs.length} showPagination={false} columns={this.tableColumns} - // column={{ ...ReactTableDefaults.column, Cell: this.renderCell, }} getTrProps={this.getTrProps} sortable={false} - - TrComponent={MovableRow(this.props.ScreenToLocalTransform, addDoc, moveDoc)} + TrComponent={MovableRow} />; } @@ -566,7 +532,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return (
this.onDrop(e, {})} onContextMenu={this.onContextMenu} ref={this.createTarget}> -
TESTER
{this.reactTable} {this.dividerDragger} {!this.previewWidth() ? (null) : this.previewPanel} -- cgit v1.2.3-70-g09d2 From ae51e87874a714fdb46d4093fee513787b413ed8 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Fri, 19 Jul 2019 13:11:10 -0400 Subject: can sort columns by asc, desc --- src/client/views/EditableView.tsx | 12 +- .../views/collections/CollectionSchemaCells.tsx | 2 +- .../views/collections/CollectionSchemaHeaders.tsx | 90 ++++++--- .../views/collections/CollectionSchemaView.scss | 1 - .../views/collections/CollectionSchemaView.tsx | 204 ++++++++------------- 5 files changed, 159 insertions(+), 150 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 989fb1be9..42faedf9d 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -31,6 +31,7 @@ export interface EditableProps { oneLine?: boolean; editing?: boolean; onClick?: (e: React.MouseEvent) => boolean; + isEditingCallback?: (isEditing: boolean) => void; } /** @@ -47,6 +48,11 @@ export class EditableView extends React.Component { this._editing = this.props.editing ? true : false; } + @action + componentWillReceiveProps(nextProps: EditableProps) { + this._editing = nextProps.editing ? true : false; + } + @action onKeyDown = (e: React.KeyboardEvent) => { if (e.key === "Tab") { @@ -55,13 +61,16 @@ export class EditableView extends React.Component { if (!e.ctrlKey) { if (this.props.SetValue(e.currentTarget.value, e.shiftKey)) { this._editing = false; + this.props.isEditingCallback && this.props.isEditingCallback(false); } } else if (this.props.OnFillDown) { this.props.OnFillDown(e.currentTarget.value); this._editing = false; + this.props.isEditingCallback && this.props.isEditingCallback(false); } } else if (e.key === "Escape") { this._editing = false; + this.props.isEditingCallback && this.props.isEditingCallback(false); } } @@ -69,6 +78,7 @@ export class EditableView extends React.Component { onClick = (e: React.MouseEvent) => { if (!this.props.onClick || !this.props.onClick(e)) { this._editing = true; + this.props.isEditingCallback && this.props.isEditingCallback(true); } e.stopPropagation(); } @@ -85,7 +95,7 @@ export class EditableView extends React.Component { render() { if (this._editing) { return this._editing = false)} onPointerDown={this.stopPropagation} onClick={this.stopPropagation} onPointerUp={this.stopPropagation} + onBlur={action(() => {this._editing = false; this.props.isEditingCallback && this.props.isEditingCallback(false);})} onPointerDown={this.stopPropagation} onClick={this.stopPropagation} onPointerUp={this.stopPropagation} style={{ display: this.props.display, fontSize: this.props.fontSize }} />; } else { return ( diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 51e9016b7..5b40032eb 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -125,7 +125,7 @@ export class CollectionSchemaCell extends React.Component {
void; deleteColumn: (column: string) => void; setColumnType: (key: string, type: ColumnType) => void; + setColumnSort: (key: string, desc: boolean) => void; + removeColumnSort: (key: string) => void; } export class CollectionSchemaHeader extends React.Component { @@ -43,6 +45,8 @@ export class CollectionSchemaHeader extends React.Component { deleteColumn={this.props.deleteColumn} onlyShowOptions={false} setColumnType={this.props.setColumnType} + setColumnSort={this.props.setColumnSort} + removeColumnSort={this.props.removeColumnSort} />
); @@ -59,18 +63,10 @@ export interface AddColumnHeaderProps { @observer export class CollectionSchemaAddColumnHeader extends React.Component { - // @observable private _creatingColumn: boolean = false; - - // @action - // onClick = (e: React.MouseEvent): void => { - // this._creatingColumn = true; - // } - render() { let addButton = ; return (
- {/* {this._creatingColumn ? <> : */}
); @@ -105,12 +103,38 @@ export interface ColumnMenuProps { deleteColumn: (column: string) => void; onlyShowOptions: boolean; setColumnType: (key: string, type: ColumnType) => void; + setColumnSort: (key: string, desc: boolean) => void; + removeColumnSort: (key: string) => void; } @observer export class CollectionSchemaColumnMenu extends React.Component { @observable private _isOpen: boolean = false; + // @observable private _node : HTMLDivElement | null = null; + @observable private _node = React.createRef(); - @action toggleIsOpen = (): void => { + componentDidMount() { + document.addEventListener("pointerdown", this.onPointerDown); + console.log("did mount", this._node); + } + + componentWillUnmount() { + document.removeEventListener("pointerdown", this.onPointerDown); + } + + onPointerDown (e: PointerEvent) { + console.log("pointer down", this._node); + if (this._node ) { + // && this._node.contains(e.target as Node) + console.log("CLICKED INSNIDE"); + } else { + console.log("CLICKED OUTSIDE"); + // console.log(this._node); + // console.log(e.target as Node); + } + } + + @action + toggleIsOpen = (): void => { this._isOpen = !this._isOpen; this.props.setIsEditing(this._isOpen); } @@ -121,6 +145,14 @@ export class CollectionSchemaColumnMenu extends React.Component this.props.setColumnType(this.props.keyValue, type); } + // @action + // setNode = (node: HTMLDivElement): void => { + // if (node) { + // this._node = node; + // console.log("set node to ", this._node); + // } + // } + renderTypes = () => { if (this.props.typeConst) return <>; return ( @@ -147,6 +179,19 @@ export class CollectionSchemaColumnMenu extends React.Component ); } + renderSorting = () => { + return ( +
+ +
+
this.props.setColumnSort(this.props.keyValue, false)}>Sort ascending
+
this.props.setColumnSort(this.props.keyValue, true)}>Sort descending
+
this.props.removeColumnSort(this.props.keyValue)}>Clear sorting
+
+
+ ); + } + renderContent = () => { return (
@@ -159,11 +204,13 @@ export class CollectionSchemaColumnMenu extends React.Component canAddNew={true} addNew={this.props.addNew} onSelect={this.props.onSelect} + setIsEditing={this.props.setIsEditing} />
{this.props.onlyShowOptions ? <> : <> {this.renderTypes()} + {this.renderSorting()}
@@ -174,24 +221,17 @@ export class CollectionSchemaColumnMenu extends React.Component } render() { + console.log("render", this._node); return ( -
+
- {/*
*/} -
{ this.props.setIsEditing(true); }}>{this.props.menuButtonContent}
- {/* {this._isOpen ? this.renderContent() : <>} */} - {/*
*/} +
this.toggleIsOpen()}>{this.props.menuButtonContent}
); } } -{/* //
- //
this.toggleIsOpen()}>{this.props.menuButtonContent}
- // {this.renderContent()} - //
*/} - interface KeysDropdownProps { keyValue: string; @@ -200,6 +240,7 @@ interface KeysDropdownProps { canAddNew: boolean; addNew: boolean; onSelect: (oldKey: string, newKey: string, addnew: boolean) => void; + setIsEditing: (isEditing: boolean) => void; } @observer class KeysDropdown extends React.Component { @@ -217,6 +258,7 @@ class KeysDropdown extends React.Component { this.props.onSelect(this._key, key, this.props.addNew); this.setKey(key); this._isOpen = false; + this.props.setIsEditing(false); } onChange = (val: string): void => { @@ -226,15 +268,15 @@ class KeysDropdown extends React.Component { @action onFocus = (e: React.FocusEvent): void => { this._isOpen = true; + this.props.setIsEditing(true); } @action onBlur = (e: React.FocusEvent): void => { - // const that = this; - if (this._canClose) this._isOpen = false; - // setTimeout(function() { // TODO: this might be too hacky lol - // that.setIsOpen(false); - // }, 100); + if (this._canClose) { + this._isOpen = false; + this.props.setIsEditing(false); + } } @action diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 15dec4e44..4ae9628a9 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -163,7 +163,6 @@ .collectionSchema-col{ height: 100%; - background-color: green; .collectionSchema-col-wrapper { &.col-before { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index b9b299e13..10b1e895d 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -39,8 +39,6 @@ library.add(faCog); library.add(faPlus); // bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 -// const MovableTable = CollectionSchemaMovableSchemaHOC(ReactTable); - export enum ColumnType { Any, Number, @@ -62,7 +60,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { private _startPreviewWidth = 0; private DIVIDER_WIDTH = 4; - // @observable _columns: Array = ["title", "data", "author"]; @observable _selectedIndex = 0; @observable _columnsPercentage = 0; @observable _keys: string[] = []; @@ -71,6 +68,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @observable _headerIsEditing: boolean = false; @observable _cellIsEditing: boolean = false; @observable _focusedCell: {row: number, col: number} = {row: 0, col: 0}; + @observable _sortedColumns: Map = new Map(); @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } @@ -80,7 +78,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } @computed get tableColumns(): Column[] { let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1); - let cols = this.columns.map(col => { let focusedRow = this._focusedCell.row; let focusedCol = this._focusedCell.col; @@ -95,6 +92,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { setIsEditing={this.setHeaderIsEditing} deleteColumn={this.deleteColumn} setColumnType={this.setColumnType} + setColumnSort={this.setColumnSort} + removeColumnSort={this.removeColumnSort} />; return { @@ -148,37 +147,19 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return cols; } - @action - setColumns = (columns: string[]) => { - this.columns = columns; - } - - reorderColumns = (toMove: string, relativeTo: string, before: boolean, columnsValues: string[]) => { - let columns = [...columnsValues]; - let oldIndex = columns.indexOf(toMove); - let relIndex = columns.indexOf(relativeTo); - let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; - - if (oldIndex === newIndex) return; - - columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); - this.setColumns(columns); - } - - - onHeaderDrag = (columnName: string) => { - let schemaDoc = Cast(this.props.Document.schemaDoc, Doc); - if (schemaDoc instanceof Doc) { - let columnDocs = DocListCast(schemaDoc.data); - if (columnDocs) { - let ddoc = columnDocs.find(doc => doc.title === columnName); - if (ddoc) { - return ddoc; - } - } - } - return this.props.Document; - } + // onHeaderDrag = (columnName: string) => { + // let schemaDoc = Cast(this.props.Document.schemaDoc, Doc); + // if (schemaDoc instanceof Doc) { + // let columnDocs = DocListCast(schemaDoc.data); + // if (columnDocs) { + // let ddoc = columnDocs.find(doc => doc.title === columnName); + // if (ddoc) { + // return ddoc; + // } + // } + // } + // return this.props.Document; + // } componentDidMount() { document.addEventListener("keydown", this.onKeyDown); @@ -213,37 +194,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { this._mainCont = ele; super.CreateDropTarget(ele); } - @action - changeFocusedCellByDirection = (direction: string): void => { - switch (direction) { - case "tab": - if (this._focusedCell.col + 1 === this.columns.length && this._focusedCell.row + 1 === this.childDocs.length) { - this._focusedCell = { row: 0, col: 0 }; - } else if (this._focusedCell.col + 1 === this.columns.length) { - this._focusedCell = { row: this._focusedCell.row + 1, col: 0 }; - } else { - this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col + 1 }; - } - break; - case "right": - this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col + 1 === this.columns.length ? this._focusedCell.col : this._focusedCell.col + 1 }; - break; - case "left": - this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col === 0 ? this._focusedCell.col : this._focusedCell.col - 1 }; - break; - case "up": - this._focusedCell = { row: this._focusedCell.row === 0 ? this._focusedCell.row : this._focusedCell.row - 1, col: this._focusedCell.col }; - break; - case "down": - this._focusedCell = { row: this._focusedCell.row + 1 === this.childDocs.length ? this._focusedCell.row : this._focusedCell.row + 1, col: this._focusedCell.col }; - break; - } - } - - @action - changeFocusedCellByIndex = (row: number, col: number): void => { - this._focusedCell = { row: row, col: col }; - } @action setCellIsEditing = (isEditing: boolean): void => { @@ -255,21 +205,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { this._headerIsEditing = isEditing; } - // @action - // toggleKey = (key: string) => { - // let list = Cast(this.props.Document.schemaColumns, listSpec("string")); - // if (list === undefined) { - // this.props.Document.schemaColumns = list = new List([key]); - // } else { - // const index = list.indexOf(key); - // if (index === -1) { - // list.push(key); - // } else { - // list.splice(index, 1); - // } - // } - // } - //toggles preview side-panel of schema @action toggleExpander = () => { @@ -323,6 +258,38 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { } } + @action + changeFocusedCellByDirection = (direction: string): void => { + switch (direction) { + case "tab": + if (this._focusedCell.col + 1 === this.columns.length && this._focusedCell.row + 1 === this.childDocs.length) { + this._focusedCell = { row: 0, col: 0 }; + } else if (this._focusedCell.col + 1 === this.columns.length) { + this._focusedCell = { row: this._focusedCell.row + 1, col: 0 }; + } else { + this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col + 1 }; + } + break; + case "right": + this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col + 1 === this.columns.length ? this._focusedCell.col : this._focusedCell.col + 1 }; + break; + case "left": + this._focusedCell = { row: this._focusedCell.row, col: this._focusedCell.col === 0 ? this._focusedCell.col : this._focusedCell.col - 1 }; + break; + case "up": + this._focusedCell = { row: this._focusedCell.row === 0 ? this._focusedCell.row : this._focusedCell.row - 1, col: this._focusedCell.col }; + break; + case "down": + this._focusedCell = { row: this._focusedCell.row + 1 === this.childDocs.length ? this._focusedCell.row : this._focusedCell.row + 1, col: this._focusedCell.col }; + break; + } + } + + @action + changeFocusedCellByIndex = (row: number, col: number): void => { + this._focusedCell = { row: row, col: col }; + } + @action makeDB = async () => { let csv: string = this.columns.reduce((val, col) => val + col + ",", ""); @@ -400,10 +367,32 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { } } - // @action - // newKeyChange = (e: React.ChangeEvent) => { - // this._newKeyName = e.currentTarget.value; - // } + @action + setColumns = (columns: string[]) => { + this.columns = columns; + } + + reorderColumns = (toMove: string, relativeTo: string, before: boolean, columnsValues: string[]) => { + let columns = [...columnsValues]; + let oldIndex = columns.indexOf(toMove); + let relIndex = columns.indexOf(relativeTo); + let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex; + + if (oldIndex === newIndex) return; + + columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]); + this.setColumns(columns); + } + + @action + setColumnSort = (column: string, descending: boolean) => { + this._sortedColumns.set(column, {id: column, desc: descending}); + } + + @action + removeColumnSort = (column: string) => { + this._sortedColumns.delete(column); + } @computed get previewDocument(): Doc | undefined { @@ -430,44 +419,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return Array.from(Object.keys(keys)); } - // get documentKeysCheckList() { - // const docs = DocListCast(this.props.Document[this.props.fieldKey]); - // let keys: { [key: string]: boolean } = {}; - // // bcz: ugh. this is untracked since otherwise a large collection of documents will blast the server for all their fields. - // // then as each document's fields come back, we update the documents _proxies. Each time we do this, the whole schema will be - // // invalidated and re-rendered. This workaround will inquire all of the document fields before the options button is clicked. - // // then by the time the options button is clicked, all of the fields should be in place. If a new field is added while this menu - // // is displayed (unlikely) it won't show up until something else changes. - // //TODO Types - // untracked(() => docs.map(doc => Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false)))); - - // this.columns.forEach(key => keys[key] = true); - // return Array.from(Object.keys(keys)).map(item => - // ()); - // } - - // get tableOptionsPanel() { - // return !this.props.active() ? (null) : - // ( - //
Options
- //
- //
Preview Window
- //
Show Preview
- //
Displayed Columns
- //
    - // {this.documentKeysCheckList} - //
- // - // - //
- //
- // }> - // - // ); - // } - @computed get reactTable() { let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; @@ -481,6 +432,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { getTrProps={this.getTrProps} sortable={false} TrComponent={MovableRow} + sorted={Array.from(this._sortedColumns.values())} />; } @@ -614,7 +566,13 @@ export class CollectionSchemaPreview extends React.Component Show Preview
+ + let input = this.props.previewScript === undefined ? (null) :
; -- cgit v1.2.3-70-g09d2 From e1b11d49cc73ae9cfe85c5225537d681bbc976cc Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Fri, 19 Jul 2019 16:10:16 -0400 Subject: changed add col button to immediately add new column --- .../views/collections/CollectionSchemaCells.tsx | 4 +- .../views/collections/CollectionSchemaHeaders.tsx | 62 +++++++++++----------- .../views/collections/CollectionSchemaView.scss | 4 ++ .../views/collections/CollectionSchemaView.tsx | 40 ++++++++++---- 4 files changed, 67 insertions(+), 43 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 5b40032eb..0307bb83e 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -31,7 +31,7 @@ export interface CellProps { renderDepth: number; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; - isFocused: boolean; + isFocused: boolean; changeFocusedCellByDirection: (direction: string) => void; changeFocusedCellByIndex: (row: number, col: number) => void; setIsEditing: (isEditing: boolean) => void; @@ -229,4 +229,4 @@ export class CollectionSchemaDocCell extends CollectionSchemaCell {
); } -} \ No newline at end of file +} diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index 316b3f0ff..5f8037fbf 100644 --- a/src/client/views/collections/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -29,7 +29,7 @@ export interface HeaderProps { export class CollectionSchemaHeader extends React.Component { render() { let icon: IconProp = this.props.keyType === ColumnType.Number ? "hashtag" : this.props.keyType === ColumnType.String ? "font" : - this.props.keyType === ColumnType.Checkbox ? "check-square" : this.props.keyType === ColumnType.Boolean ? "toggle-on" : "align-justify"; + this.props.keyType === ColumnType.Boolean ? "check-square" : "align-justify"; return (
@@ -56,10 +56,11 @@ export class CollectionSchemaHeader extends React.Component { export interface AddColumnHeaderProps { - possibleKeys: string[]; - existingKeys: string[]; - onSelect: (oldKey: string, newKey: string, addnew: boolean) => void; - setIsEditing: (isEditing: boolean) => void; + // possibleKeys: string[]; + // existingKeys: string[]; + // onSelect: (oldKey: string, newKey: string, addnew: boolean) => void; + // setIsEditing: (isEditing: boolean) => void; + createColumn: () => void; } @observer @@ -67,24 +68,26 @@ export class CollectionSchemaAddColumnHeader extends React.Component; return ( -
- -
+ + //
+ // + //
); } } @@ -106,6 +109,7 @@ export interface ColumnMenuProps { setColumnType: (key: string, type: ColumnType) => void; setColumnSort: (key: string, desc: boolean) => void; removeColumnSort: (key: string) => void; + anchorPoint?: any; } @observer export class CollectionSchemaColumnMenu extends React.Component { @@ -116,7 +120,6 @@ export class CollectionSchemaColumnMenu extends React.Component componentDidMount() { document.addEventListener("pointerdown", this.detectClick); - console.log("did mount", this._node); } componentWillUnmount() { @@ -124,7 +127,6 @@ export class CollectionSchemaColumnMenu extends React.Component } detectClick = (e: PointerEvent): void => { - console.log("click", this); if (this._node && this._node.contains(e.target as Node)) { } else { this._isOpen = false; @@ -148,7 +150,6 @@ export class CollectionSchemaColumnMenu extends React.Component setNode = (node: HTMLDivElement): void => { if (node) { this._node = node; - console.log("set node to ", this._node); } } @@ -167,10 +168,10 @@ export class CollectionSchemaColumnMenu extends React.Component - - */} +
@@ -220,10 +221,9 @@ export class CollectionSchemaColumnMenu extends React.Component } render() { - console.log("render", this._node); return (
- +
this.toggleIsOpen()}>{this.props.menuButtonContent}
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 4ae9628a9..47947829e 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -95,6 +95,10 @@ padding: 3px 7px; font-size: 13px; text-align: center; + + &:last-child { + overflow: visible; + } } .rt-tbody { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index ffc9d7d09..02c1ec082 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -32,7 +32,7 @@ import { CollectionView } from "./CollectionView"; import { undoBatch } from "../../util/UndoManager"; import { timesSeries } from "async"; import { CollectionSchemaHeader, CollectionSchemaAddColumnHeader } from "./CollectionSchemaHeaders"; -import { CellProps, CollectionSchemaCell, CollectionSchemaNumberCell, CollectionSchemaStringCell, CollectionSchemaBooleanCell, CollectionSchemaCheckboxCell } from "./CollectionSchemaCells"; +import { CellProps, CollectionSchemaCell, CollectionSchemaNumberCell, CollectionSchemaStringCell, CollectionSchemaBooleanCell, CollectionSchemaCheckboxCell, CollectionSchemaDocCell } from "./CollectionSchemaCells"; import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC"; library.add(faCog); @@ -44,8 +44,8 @@ export enum ColumnType { Number, String, Boolean, - // Doc, - Checkbox + Doc, + // Checkbox } // this map should be used for keys that should have a const type of value const columnTypes: Map = new Map([ @@ -125,23 +125,28 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { let colType = this.getColumnType(col); if (colType === ColumnType.Number) return ; if (colType === ColumnType.String) return ; - if (colType === ColumnType.Boolean) return ; - if (colType === ColumnType.Checkbox) return ; + // if (colType === ColumnType.Boolean) return ; + // if (colType === ColumnType.Checkbox) return ; + if (colType === ColumnType.Boolean) return ; + if (colType === ColumnType.Doc) return ; return ; } }; - }) as {Header: TableCellRenderer, accessor: (doc: Doc) => FieldResult, id: string, Cell: (rowProps: CellInfo) => JSX.Element}[]; + }) as {Header: TableCellRenderer, accessor: (doc: Doc) => FieldResult, id: string, Cell: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean}[]; cols.push({ Header: , accessor: (doc: Doc) => 0, id: "add", Cell: (rowProps: CellInfo) => <>, + width: 45, + resizable: false }); return cols; @@ -311,6 +316,21 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { } } + @action + createColumn = () => { + let index = 0; + let found = this.columns.findIndex(col => col.toUpperCase() === "New field".toUpperCase()) > -1; + if (!found) { + this.columns.push("New field"); + return; + } + while (found) { + index ++; + found = this.columns.findIndex(col => col.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1; + } + this.columns.push("New field (" + index + ")"); + } + @action addColumn = () => { this.columns.push(this._newKeyName); -- cgit v1.2.3-70-g09d2 From 5da4de27c45e4f40c88b710be64f0129e9be7088 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Fri, 19 Jul 2019 16:21:19 -0400 Subject: focused cell styling + click editable view changes focuses on that cell --- src/client/views/EditableView.tsx | 2 +- .../views/collections/CollectionSchemaCells.tsx | 1 + .../views/collections/CollectionSchemaHeaders.tsx | 29 ---------------------- .../views/collections/CollectionSchemaView.scss | 7 +++++- 4 files changed, 8 insertions(+), 31 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 42faedf9d..9471ae98a 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -79,7 +79,7 @@ export class EditableView extends React.Component { if (!this.props.onClick || !this.props.onClick(e)) { this._editing = true; this.props.isEditingCallback && this.props.isEditingCallback(true); - } + } e.stopPropagation(); } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 0307bb83e..31a9baa11 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -74,6 +74,7 @@ export class CollectionSchemaCell extends React.Component { document.addEventListener("keydown", this.onKeyDown); this._isEditing = isEditing; this.props.setIsEditing(isEditing); + this.props.changeFocusedCellByIndex(this.props.row, this.props.col); } @action diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index 5f8037fbf..df078eca5 100644 --- a/src/client/views/collections/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -56,38 +56,14 @@ export class CollectionSchemaHeader extends React.Component { export interface AddColumnHeaderProps { - // possibleKeys: string[]; - // existingKeys: string[]; - // onSelect: (oldKey: string, newKey: string, addnew: boolean) => void; - // setIsEditing: (isEditing: boolean) => void; createColumn: () => void; } @observer export class CollectionSchemaAddColumnHeader extends React.Component { render() { - let addButton = ; return ( - //
- // - //
); } } @@ -115,8 +91,6 @@ export interface ColumnMenuProps { export class CollectionSchemaColumnMenu extends React.Component { @observable private _isOpen: boolean = false; @observable private _node : HTMLDivElement | null = null; - // @observable private _node = React.createRef(); - @observable private _test = "test"; componentDidMount() { document.addEventListener("pointerdown", this.detectClick); @@ -168,9 +142,6 @@ export class CollectionSchemaColumnMenu extends React.Component - {/* */} diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 47947829e..045994751 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -126,13 +126,14 @@ .rt-tr { width: 100%; + height: $MAX_ROW_HEIGHT; } .rt-td { border-width: 1px; border-right-color: $intermediate-color; max-height: $MAX_ROW_HEIGHT; - padding: 3px 7px; + padding: 0; font-size: 13px; text-align: center; @@ -289,6 +290,10 @@ height: 100%; padding: 4px; + &:focus { + outline: none; + } + &.focused { // background-color: yellowgreen; border: 2px solid yellowgreen; -- cgit v1.2.3-70-g09d2 From fa37c6f8e9947b7f536d7ff7372c9f1025a3926d Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Fri, 19 Jul 2019 17:02:17 -0400 Subject: merge --- .../views/collections/CollectionSchemaCells.tsx | 2 +- .../views/collections/CollectionSchemaView.scss | 1 + .../views/collections/CollectionSchemaView.tsx | 22 ++++++++++++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 31a9baa11..7c82ed720 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -42,7 +42,7 @@ export interface CellProps { export class CollectionSchemaCell extends React.Component { @observable protected _isEditing: boolean = false; protected _focusRef = React.createRef(); - protected _document = this.props.rowProps.original; + protected _document: Doc = this.props.rowProps.original; componentDidMount() { if (this._focusRef.current) { diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 045994751..2134362ce 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -108,6 +108,7 @@ .rt-tr-group { direction: ltr; max-height: $MAX_ROW_HEIGHT; + // for sub comp &:nth-child(even) { background-color: $light-color; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 02c1ec082..7c7309a4a 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -4,7 +4,7 @@ import { faCog, faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, trace, untracked } from "mobx"; import { observer } from "mobx-react"; -import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults, TableCellRenderer, Column } from "react-table"; +import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults, TableCellRenderer, Column, RowInfo } from "react-table"; import "react-table/react-table.css"; import { emptyFunction, returnFalse, returnZero, returnOne } from "../../../Utils"; import { Doc, DocListCast, DocListCastAsync, Field, FieldResult } from "../../../new_fields/Doc"; @@ -132,7 +132,20 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { return ; } }; - }) as {Header: TableCellRenderer, accessor: (doc: Doc) => FieldResult, id: string, Cell: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean}[]; + }) as {Header?: TableCellRenderer, accessor?: (doc: Doc) => FieldResult, id?: string, Cell?: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean, expander?: boolean, Expander?: (rowInfo: RowInfo) => JSX.Element | null}[]; + + cols.push({ + expander: true, + Header: "", + width: 45, + Expander: (rowInfo) => { + if (rowInfo.original.type === "collection") { + return
+
; + } else { + return null; + } + } + }); cols.push({ Header: doc) { resizable: false }); + // SubComponent={row => row.original.type === "collection" &&
SUB
} + return cols; } @@ -453,7 +468,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { sortable={false} TrComponent={MovableRow} sorted={Array.from(this._sortedColumns.values())} + SubComponent={row => row.original.type === "collection" &&
this is the sub component
} />; + + } @computed -- cgit v1.2.3-70-g09d2 From e81cf9407966612e25b944addbc8d2a08300d0bb Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Mon, 22 Jul 2019 11:38:55 -0400 Subject: editing + nav on schema only occur when that schemaview is selected --- .../views/collections/CollectionSchemaCells.tsx | 3 + .../views/collections/CollectionSchemaHeaders.tsx | 8 ++- .../views/collections/CollectionSchemaView.scss | 10 ++- .../views/collections/CollectionSchemaView.tsx | 80 ++++++++++++++-------- 4 files changed, 67 insertions(+), 34 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 91bd0453e..55185e30e 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -51,6 +51,9 @@ export class CollectionSchemaCell extends React.Component { if (this._focusRef.current) { if (this.props.isFocused) { this._focusRef.current.className += " focused"; + if (!this.props.isEditable) { + this._focusRef.current.className += " inactive"; + } } else { this._focusRef.current.className = "collectionSchemaView-cellWrapper"; } diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index df078eca5..3a57cd306 100644 --- a/src/client/views/collections/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -9,8 +9,9 @@ import { Flyout, anchorPoints } from "../DocumentDecorations"; import { ColumnType } from "./CollectionSchemaView"; import { emptyFunction } from "../../../Utils"; import { contains } from "typescript-collections/dist/lib/arrays"; +import { faFile } from "@fortawesome/free-regular-svg-icons"; -library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn); +library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faFile); export interface HeaderProps { keyValue: string; @@ -29,7 +30,7 @@ export interface HeaderProps { export class CollectionSchemaHeader extends React.Component { render() { let icon: IconProp = this.props.keyType === ColumnType.Number ? "hashtag" : this.props.keyType === ColumnType.String ? "font" : - this.props.keyType === ColumnType.Boolean ? "check-square" : "align-justify"; + this.props.keyType === ColumnType.Boolean ? "check-square" : this.props.keyType === ColumnType.Doc ? "file" : "align-justify"; return (
@@ -145,6 +146,9 @@ export class CollectionSchemaColumnMenu extends React.Component +
); diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 2134362ce..e511bc1bd 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -8,8 +8,9 @@ box-sizing: border-box; position: absolute; width: 100%; - height: 100%; - overflow: hidden; + height: calc(100% - 25px); + // overflow: hidden; + overflow-x: scroll; .collectionSchemaView-previewRegion { position: relative; @@ -304,6 +305,11 @@ border: none; background-color: yellow; } + + &.inactive { + // border: 2px solid rgba(255, 255, 0, 0.4); + border: none; + } } } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 7c7309a4a..ea09926d4 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -34,6 +34,7 @@ import { timesSeries } from "async"; import { CollectionSchemaHeader, CollectionSchemaAddColumnHeader } from "./CollectionSchemaHeaders"; import { CellProps, CollectionSchemaCell, CollectionSchemaNumberCell, CollectionSchemaStringCell, CollectionSchemaBooleanCell, CollectionSchemaCheckboxCell, CollectionSchemaDocCell } from "./CollectionSchemaCells"; import { MovableColumn, MovableRow } from "./CollectionSchemaMovableTableHOC"; +import { SelectionManager } from "../../util/SelectionManager"; library.add(faCog); library.add(faPlus); @@ -60,7 +61,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { private _startPreviewWidth = 0; private DIVIDER_WIDTH = 4; - @observable _selectedIndex = 0; + // @observable _selectedIndex = 0; @observable _columnsPercentage = 0; @observable _keys: string[] = []; @observable _newKeyName: string = ""; @@ -69,6 +70,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @observable _cellIsEditing: boolean = false; @observable _focusedCell: {row: number, col: number} = {row: 0, col: 0}; @observable _sortedColumns: Map = new Map(); + @observable private _node : HTMLDivElement | null = null; + // @observable _schemaIsFocused: boolean = @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } @@ -81,7 +84,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { let cols = this.columns.map(col => { let focusedRow = this._focusedCell.row; let focusedCol = this._focusedCell.col; - let isEditable = !this._headerIsEditing; + let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false; + let isEditable = !this._headerIsEditing && (isSelected);// || BoolCast(this.props.Document.libraryBrush)); + console.log(BoolCast(this.props.Document.libraryBrush), isSelected); + let header = doc) { if (colType === ColumnType.Boolean) return ; if (colType === ColumnType.Doc) return ; return ; - } + }, + minWidth: 200, }; - }) as {Header?: TableCellRenderer, accessor?: (doc: Doc) => FieldResult, id?: string, Cell?: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean, expander?: boolean, Expander?: (rowInfo: RowInfo) => JSX.Element | null}[]; - - cols.push({ - expander: true, - Header: "", - width: 45, - Expander: (rowInfo) => { - if (rowInfo.original.type === "collection") { - return
+
; - } else { - return null; - } - } - }); + }) as {Header?: TableCellRenderer, accessor?: (doc: Doc) => FieldResult, id?: string, Cell?: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean, expander?: boolean, Expander?: (rowInfo: RowInfo) => JSX.Element | null, minWidth?: number}[]; + + // cols.push({ + // expander: true, + // Header: "", + // width: 45, + // Expander: (rowInfo) => { + // if (rowInfo.original.type === "collection") { + // return
+
; + // } else { + // return null; + // } + // } + // }); cols.push({ Header: doc) { // } // } // } - // return this.props.Document; + // return this.props.Document; // } componentDidMount() { @@ -199,14 +206,14 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before), moveDoc: (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc), rowInfo, - onClick: action((e: React.MouseEvent, handleOriginal: Function) => { - that.props.select(e.ctrlKey); - that._selectedIndex = rowInfo.index; - - if (handleOriginal) { - handleOriginal(); - } - }), + // onClick: action((e: React.MouseEvent, handleOriginal: Function) => { + // that.props.select(e.ctrlKey); + // that._selectedIndex = rowInfo.index; + + // if (handleOriginal) { + // handleOriginal(); + // } + // }), }; } @@ -215,6 +222,14 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { super.CreateDropTarget(ele); } + // detectClick = (e: PointerEvent): void => { + // if (this._node && this._node.contains(e.target as Node)) { + // } else { + // this._isOpen = false; + // this.props.setIsEditing(false); + // } + // } + @action setCellIsEditing = (isEditing: boolean): void => { this._cellIsEditing = isEditing; @@ -272,7 +287,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { } onKeyDown = (e: KeyboardEvent): void => { - if (!this._cellIsEditing && !this._headerIsEditing) { + let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false; + if (!this._cellIsEditing && !this._headerIsEditing && isSelected) { let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : ""; this.changeFocusedCellByDirection(direction); } @@ -431,7 +447,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get previewDocument(): Doc | undefined { - const selected = this.childDocs.length > this._selectedIndex ? this.childDocs[this._selectedIndex] : undefined; + let selectedIndex = this._focusedCell.row; + console.log("preview", selectedIndex); + const selected = this.childDocs.length > selectedIndex ? this.childDocs[selectedIndex] : undefined; let pdc = selected ? (this.previewScript && this.previewScript !== "this" ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined; return pdc; } @@ -468,7 +486,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { sortable={false} TrComponent={MovableRow} sorted={Array.from(this._sortedColumns.values())} - SubComponent={row => row.original.type === "collection" &&
this is the sub component
} + // SubComponent={row => row.original.type === "collection" &&
this is the sub component
} />; @@ -529,14 +547,16 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { render() { return ( + <> + {this.schemaToolbar}
this.onDrop(e, {})} onContextMenu={this.onContextMenu} ref={this.createTarget}> - {this.schemaToolbar} {this.reactTable} {this.dividerDragger} {!this.previewWidth() ? (null) : this.previewPanel} {/* {this.tableOptionsPanel} */}
+ ); } } -- cgit v1.2.3-70-g09d2 From 8515b6957f075f8ae7e88243ab5a4c7cb8fff3b6 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Mon, 22 Jul 2019 14:49:57 -0400 Subject: removed fixed row height --- .../views/collections/CollectionSchemaCells.tsx | 103 +++++++++++---------- .../CollectionSchemaMovableTableHOC.tsx | 5 +- .../views/collections/CollectionSchemaView.scss | 67 +++++++++----- .../views/collections/CollectionSchemaView.tsx | 45 +++++---- 4 files changed, 126 insertions(+), 94 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 55185e30e..2dd3eeff4 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -20,6 +20,7 @@ import { CollectionView } from "./CollectionView"; import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../new_fields/Types"; import { Docs } from "../../documents/Documents"; import { DocumentContentsView } from "../nodes/DocumentContentsView"; +import { SelectionManager } from "../../util/SelectionManager"; export interface CellProps { @@ -118,6 +119,8 @@ export class CollectionSchemaCell extends React.Component { } renderCellWithType(type: string | undefined) { + let dragRef: React.RefObject = React.createRef(); + let props: FieldViewProps = { Document: this.props.rowProps.original, DataDoc: this.props.rowProps.original, @@ -136,10 +139,19 @@ export class CollectionSchemaCell extends React.Component { PanelWidth: returnZero, addDocTab: this.props.addDocTab, }; + let onItemDown = (e: React.PointerEvent) => { SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document, this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument, this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e); }; + let onPointerEnter = (e: React.PointerEvent): void => { + if (e.buttons === 1 && SelectionManager.GetIsDragging() && (type === "document" || type === undefined)) { + dragRef!.current!.className = "doc-drag-over"; + } + }; + let onPointerLeave = (e: React.PointerEvent): void => { + dragRef!.current!.className = ""; + }; let field = props.Document[props.fieldKey]; let contents: any = "incorrect type"; @@ -153,40 +165,42 @@ export class CollectionSchemaCell extends React.Component { } return ( -
-
- { - let field = props.Document[props.fieldKey]; - if (Field.IsField(field)) { - return Field.toScriptString(field); +
+
+
+ { + let field = props.Document[props.fieldKey]; + if (Field.IsField(field)) { + return Field.toScriptString(field); + } + return ""; } - return ""; - } - } - SetValue={(value: string) => { - let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } }); - if (!script.compiled) { - return false; } - return this.applyToDoc(props.Document, script.run); - }} - OnFillDown={async (value: string) => { - let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } }); - if (!script.compiled) { - return; - } - const run = script.run; - //TODO This should be able to be refactored to compile the script once - const val = await DocListCastAsync(this.props.Document[this.props.fieldKey]); - val && val.forEach(doc => this.applyToDoc(doc, run)); - }} /> -
+ SetValue={(value: string) => { + let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } }); + if (!script.compiled) { + return false; + } + return this.applyToDoc(props.Document, script.run); + }} + OnFillDown={async (value: string) => { + let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name } }); + if (!script.compiled) { + return; + } + const run = script.run; + //TODO This should be able to be refactored to compile the script once + const val = await DocListCastAsync(this.props.Document[this.props.fieldKey]); + val && val.forEach(doc => this.applyToDoc(doc, run)); + }} /> +
+
); } @@ -217,6 +231,13 @@ export class CollectionSchemaStringCell extends CollectionSchemaCell { } } +@observer +export class CollectionSchemaDocCell extends CollectionSchemaCell { + render() { + return this.renderCellWithType("document"); + } +} + @observer export class CollectionSchemaCheckboxCell extends CollectionSchemaCell { @observable private _isChecked: boolean = typeof this.props.rowProps.original[this.props.rowProps.column.id as string] === "boolean" ? BoolCast(this.props.rowProps.original[this.props.rowProps.column.id as string]) : false; @@ -245,21 +266,3 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell { ); } } - -@observer -export class CollectionSchemaDocCell extends CollectionSchemaCell { - render() { - return this.renderCellWithType("document"); - // let reference = React.createRef(); - // let onItemDown = (e: React.PointerEvent) => { - // // (!this.props.CollectionView.props.isSelected() ? undefined : - // // SetupDrag(reference, () => props.Document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e)); - // }; - // return ( - //
- //
- //
- //
- // ); - } -} diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 3a61881a7..8ed71d70f 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -105,6 +105,7 @@ export interface MovableRowProps { ScreenToLocalTransform: () => Transform; addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; moveDoc: DragManager.MoveFunction; + rowFocused: boolean; } export class MovableRow extends React.Component { @@ -178,8 +179,10 @@ export class MovableRow extends React.Component { let reference = React.createRef(); let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc); + console.log("row focused", this.props.rowFocused); + return ( -
+
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index e511bc1bd..ef93e381b 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -11,6 +11,7 @@ height: calc(100% - 25px); // overflow: hidden; overflow-x: scroll; + border: none; .collectionSchemaView-previewRegion { position: relative; @@ -70,10 +71,11 @@ .rt-thead { &.-header { - background: $intermediate-color; - color: $light-color; + // background: $intermediate-color; + // color: $light-color; font-size: 12px; height: 30px; + border: 1px solid $intermediate-color; } .rt-resizable-header { @@ -89,11 +91,14 @@ height: 100%; overflow: visible; } + + .rt-th { + padding: 0; + } } .rt-th { - max-height: $MAX_ROW_HEIGHT; - padding: 3px 7px; + // max-height: $MAX_ROW_HEIGHT; font-size: 13px; text-align: center; @@ -108,16 +113,17 @@ .rt-tr-group { direction: ltr; - max-height: $MAX_ROW_HEIGHT; + flex: 0 1 auto; + // max-height: $MAX_ROW_HEIGHT; // for sub comp - &:nth-child(even) { - background-color: $light-color; - } + // &:nth-child(even) { + // background-color: $light-color; + // } - &:nth-child(odd) { - background-color: $light-color-secondary; - } + // &:nth-child(odd) { + // background-color: $light-color-secondary; + // } &:last-child { border-bottom: $intermediate-color; @@ -128,13 +134,13 @@ .rt-tr { width: 100%; - height: $MAX_ROW_HEIGHT; + // height: $MAX_ROW_HEIGHT; } .rt-td { border-width: 1px; border-right-color: $intermediate-color; - max-height: $MAX_ROW_HEIGHT; + // max-height: $MAX_ROW_HEIGHT; padding: 0; font-size: 13px; text-align: center; @@ -184,6 +190,7 @@ .collectionSchemaView-header { height: 100%; + color: $intermediate-color; .collectionSchema-header-menu { height: 100%; @@ -223,10 +230,6 @@ position: relative; max-width: 175px; - // .keys-search { - - // } - .keys-options-wrapper { width: 100%; max-height: 150px; @@ -261,17 +264,18 @@ } .collectionSchema-row { - height: $MAX_ROW_HEIGHT; - // display: flex; + // height: $MAX_ROW_HEIGHT; + + &.row-focused { + background-color: $light-color-secondary; + } .row-dragger { - height: $MAX_ROW_HEIGHT; + // height: $MAX_ROW_HEIGHT; } .collectionSchema-row-wrapper { - max-height: $MAX_ROW_HEIGHT; - // width: 100%; - // border: 1px solid lightgray; + // max-height: $MAX_ROW_HEIGHT; &.row-above { border-top: 1px solid red; @@ -287,8 +291,6 @@ .collectionSchemaView-cellWrapper { - // height: $MAX_ROW_HEIGHT; - // background-color: red; height: 100%; padding: 4px; @@ -311,6 +313,21 @@ border: none; } } + + p { + width: 100%; + height: 100%; + word-wrap: break-word; + } +} + +.doc-drag-over { + background-color: red; +} + +.collectionSchemaView-toolbar { + display: flex; + justify-content: flex-end; } #preview-schema-checkbox-div { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index ea09926d4..a1251b028 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -81,6 +81,21 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } @computed get tableColumns(): Column[] { let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1); + let columns: Column[] = [ + { + expander: true, + Header: "", + width: 45, + Expander: (rowInfo) => { + if (rowInfo.original.type === "collection") { + return
+
; + } else { + return null; + } + } + } + ]; + let cols = this.columns.map(col => { let focusedRow = this._focusedCell.row; let focusedCol = this._focusedCell.col; @@ -139,22 +154,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { }, minWidth: 200, }; - }) as {Header?: TableCellRenderer, accessor?: (doc: Doc) => FieldResult, id?: string, Cell?: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean, expander?: boolean, Expander?: (rowInfo: RowInfo) => JSX.Element | null, minWidth?: number}[]; - - // cols.push({ - // expander: true, - // Header: "", - // width: 45, - // Expander: (rowInfo) => { - // if (rowInfo.original.type === "collection") { - // return
+
; - // } else { - // return null; - // } - // } - // }); - - cols.push({ + });// as {Header?: TableCellRenderer, accessor?: (doc: Doc) => FieldResult, id?: string, Cell?: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean, expander?: boolean, Expander?: (rowInfo: RowInfo) => JSX.Element | null, minWidth?: number}[]; + columns.push(...cols); + + columns.push({ Header: doc) { // SubComponent={row => row.original.type === "collection" &&
SUB
} - return cols; + return columns; } // onHeaderDrag = (columnName: string) => { @@ -201,11 +204,17 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { if (!rowInfo) { return {}; } + let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false; return { ScreenToLocalTransform: this.props.ScreenToLocalTransform, addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before), moveDoc: (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc), rowInfo, + rowFocused: !this._headerIsEditing && isSelected && rowInfo.index === this._focusedCell.row, + // style: { + // background: rowInfo.index === this._focusedCell.row ? "lightGray" : "white", + // //color: rowInfo.index === this._selectedIndex ? "white" : "black" + // } // onClick: action((e: React.MouseEvent, handleOriginal: Function) => { // that.props.select(e.ctrlKey); // that._selectedIndex = rowInfo.index; @@ -486,7 +495,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { sortable={false} TrComponent={MovableRow} sorted={Array.from(this._sortedColumns.values())} - // SubComponent={row => row.original.type === "collection" &&
this is the sub component
} + SubComponent={row => row.original.type === "collection" &&
this is the sub component
} />; -- cgit v1.2.3-70-g09d2 From d3edc59402efb5d8ada602305a95a7a3a7f0ba95 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Mon, 22 Jul 2019 17:08:46 -0400 Subject: can have expanded collection in schema --- .../CollectionSchemaMovableTableHOC.tsx | 2 - .../views/collections/CollectionSchemaView.scss | 9 ++- .../views/collections/CollectionSchemaView.tsx | 93 ++++++++++------------ 3 files changed, 51 insertions(+), 53 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 8ed71d70f..db60e657a 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -179,8 +179,6 @@ export class MovableRow extends React.Component { let reference = React.createRef(); let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc); - console.log("row focused", this.props.rowFocused); - return (
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index ef93e381b..4b20e8241 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -6,9 +6,9 @@ border-style: solid; border-radius: $border-radius; box-sizing: border-box; - position: absolute; + // position: absolute; width: 100%; - height: calc(100% - 25px); + // height: calc(100% - 25px); // overflow: hidden; overflow-x: scroll; border: none; @@ -333,4 +333,9 @@ #preview-schema-checkbox-div { margin-left: 20px; font-size: 12px; +} + +.sub { + padding: 20px; + background-color: red; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index a1251b028..25e90a25e 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -61,7 +61,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { private _startPreviewWidth = 0; private DIVIDER_WIDTH = 4; - // @observable _selectedIndex = 0; @observable _columnsPercentage = 0; @observable _keys: string[] = []; @observable _newKeyName: string = ""; @@ -70,8 +69,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @observable _cellIsEditing: boolean = false; @observable _focusedCell: {row: number, col: number} = {row: 0, col: 0}; @observable _sortedColumns: Map = new Map(); + @observable _openCollections: Array = []; @observable private _node : HTMLDivElement | null = null; - // @observable _schemaIsFocused: boolean = @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } @@ -81,27 +80,30 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } @computed get tableColumns(): Column[] { let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1); - let columns: Column[] = [ - { - expander: true, - Header: "", - width: 45, - Expander: (rowInfo) => { - if (rowInfo.original.type === "collection") { - return
+
; - } else { - return null; + let columns: Column[] = []; + + if (this.childDocs.reduce((found, doc) => found || doc.type === "collection", false)) { + columns.push( + { + expander: true, + Header: "", + width: 45, + Expander: (rowInfo) => { + if (rowInfo.original.type === "collection") { + if (rowInfo.isExpanded) return
this.onCloseCollection(rowInfo.original)}>-
; + if (!rowInfo.isExpanded) return
this.onExpandCollection(rowInfo.original)}>+
; + } else { + return null; + } + } } - } + ); } - ]; let cols = this.columns.map(col => { let focusedRow = this._focusedCell.row; let focusedCol = this._focusedCell.col; - let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false; - let isEditable = !this._headerIsEditing && (isSelected);// || BoolCast(this.props.Document.libraryBrush)); - console.log(BoolCast(this.props.Document.libraryBrush), isSelected); + let isEditable = !this._headerIsEditing && this.props.isSelected();// || BoolCast(this.props.Document.libraryBrush)); let header = doc) { let colType = this.getColumnType(col); if (colType === ColumnType.Number) return ; if (colType === ColumnType.String) return ; - // if (colType === ColumnType.Boolean) return ; - // if (colType === ColumnType.Checkbox) return ; if (colType === ColumnType.Boolean) return ; if (colType === ColumnType.Doc) return ; return ; }, minWidth: 200, }; - });// as {Header?: TableCellRenderer, accessor?: (doc: Doc) => FieldResult, id?: string, Cell?: (rowProps: CellInfo) => JSX.Element, width?: number, resizable?: boolean, expander?: boolean, Expander?: (rowInfo: RowInfo) => JSX.Element | null, minWidth?: number}[]; + }); columns.push(...cols); columns.push({ - Header: , + Header: , accessor: (doc: Doc) => 0, id: "add", Cell: (rowProps: CellInfo) => <>, width: 45, resizable: false }); - - // SubComponent={row => row.original.type === "collection" &&
SUB
} - return columns; } @@ -204,25 +195,12 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { if (!rowInfo) { return {}; } - let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false; return { ScreenToLocalTransform: this.props.ScreenToLocalTransform, addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before), moveDoc: (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc), rowInfo, - rowFocused: !this._headerIsEditing && isSelected && rowInfo.index === this._focusedCell.row, - // style: { - // background: rowInfo.index === this._focusedCell.row ? "lightGray" : "white", - // //color: rowInfo.index === this._selectedIndex ? "white" : "black" - // } - // onClick: action((e: React.MouseEvent, handleOriginal: Function) => { - // that.props.select(e.ctrlKey); - // that._selectedIndex = rowInfo.index; - - // if (handleOriginal) { - // handleOriginal(); - // } - // }), + rowFocused: !this._headerIsEditing && this.props.isSelected() && rowInfo.index === this._focusedCell.row, }; } @@ -239,6 +217,17 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { // } // } + @action + onExpandCollection = (collection: Doc): void => { + this._openCollections.push(collection); + } + + @action + onCloseCollection = (collection: Doc): void => { + let index = this._openCollections.findIndex(col => col === collection); + if (index > -1) this._openCollections.splice(index, 1); + } + @action setCellIsEditing = (isEditing: boolean): void => { this._cellIsEditing = isEditing; @@ -296,8 +285,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { } onKeyDown = (e: KeyboardEvent): void => { - let isSelected = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0].props.Document === this.props.Document : false; - if (!this._cellIsEditing && !this._headerIsEditing && isSelected) { + if (!this._cellIsEditing && !this._headerIsEditing && this.props.isSelected()) { let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : ""; this.changeFocusedCellByDirection(direction); } @@ -457,7 +445,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get previewDocument(): Doc | undefined { let selectedIndex = this._focusedCell.row; - console.log("preview", selectedIndex); const selected = this.childDocs.length > selectedIndex ? this.childDocs[selectedIndex] : undefined; let pdc = selected ? (this.previewScript && this.previewScript !== "this" ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined; return pdc; @@ -484,6 +471,11 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get reactTable() { let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; + let hasCollectionChild = this.childDocs.reduce((found, doc) => found || doc.type === "collection", false); + let expandedRowsList = this._openCollections.map(col => this.childDocs.findIndex(doc => doc === col).toString()); + let expanded = {}; + expandedRowsList.forEach(row => expanded[row] = true); + return doc) { getTrProps={this.getTrProps} sortable={false} TrComponent={MovableRow} - sorted={Array.from(this._sortedColumns.values())} - SubComponent={row => row.original.type === "collection" &&
this is the sub component
} + sorted={Array.from(this._sortedColumns.values())} + expanded={expanded} + SubComponent={hasCollectionChild ? row => row.original.type === "collection" && +
: undefined} + />; -- cgit v1.2.3-70-g09d2 From 40b7197fb9b4748a63845bb664fa9ab02ad6915a Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Tue, 23 Jul 2019 22:07:55 -0400 Subject: minor styling --- src/client/views/EditableView.tsx | 13 ++-- .../views/collections/CollectionSchemaHeaders.tsx | 38 +++++------ .../views/collections/CollectionSchemaView.scss | 29 ++++++-- .../views/collections/CollectionSchemaView.tsx | 79 +++++++++++----------- 4 files changed, 92 insertions(+), 67 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 5cbecf2c9..31e4557be 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -39,7 +39,7 @@ export interface EditableProps { oneLine?: boolean; editing?: boolean; onClick?: (e: React.MouseEvent) => boolean; - isEditingCallback?: (isEditing: boolean) => void; + isEditingCallback?: (isEditing: boolean) => void; } /** @@ -58,7 +58,12 @@ export class EditableView extends React.Component { @action componentWillReceiveProps(nextProps: EditableProps) { - this._editing = nextProps.editing ? true : false; + // this is done because when autosuggest is turned on, the suggestions are passed in as a prop, + // so when the suggestions are passed in, and no editing prop is passed in, it used to set it + // to false. this will no longer do so -syip + if (nextProps.editing && nextProps.editing !== this._editing) { + this._editing = nextProps.editing; + } } @action @@ -88,7 +93,7 @@ export class EditableView extends React.Component { if (!this.props.onClick || !this.props.onClick(e)) { this._editing = true; this.props.isEditingCallback && this.props.isEditingCallback(true); - } + } e.stopPropagation(); } @@ -119,7 +124,7 @@ export class EditableView extends React.Component { }} /> : {this._editing = false; this.props.isEditingCallback && this.props.isEditingCallback(false);})} onPointerDown={this.stopPropagation} onClick={this.stopPropagation} onPointerUp={this.stopPropagation} + onBlur={action(() => { this._editing = false; this.props.isEditingCallback && this.props.isEditingCallback(false); })} onPointerDown={this.stopPropagation} onClick={this.stopPropagation} onPointerUp={this.stopPropagation} style={{ display: this.props.display, fontSize: this.props.fontSize }} />; } else { if (this.props.autosuggestProps) this.props.autosuggestProps.resetValue(); diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index 3a57cd306..d1d0674c4 100644 --- a/src/client/views/collections/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -30,7 +30,7 @@ export interface HeaderProps { export class CollectionSchemaHeader extends React.Component { render() { let icon: IconProp = this.props.keyType === ColumnType.Number ? "hashtag" : this.props.keyType === ColumnType.String ? "font" : - this.props.keyType === ColumnType.Boolean ? "check-square" : this.props.keyType === ColumnType.Doc ? "file" : "align-justify"; + this.props.keyType === ColumnType.Boolean ? "check-square" : this.props.keyType === ColumnType.Doc ? "file" : "align-justify"; return (
@@ -64,7 +64,7 @@ export interface AddColumnHeaderProps { export class CollectionSchemaAddColumnHeader extends React.Component { render() { return ( - + ); } } @@ -91,7 +91,7 @@ export interface ColumnMenuProps { @observer export class CollectionSchemaColumnMenu extends React.Component { @observable private _isOpen: boolean = false; - @observable private _node : HTMLDivElement | null = null; + @observable private _node: HTMLDivElement | null = null; componentDidMount() { document.addEventListener("pointerdown", this.detectClick); @@ -109,7 +109,7 @@ export class CollectionSchemaColumnMenu extends React.Component } } - @action + @action toggleIsOpen = (): void => { this._isOpen = !this._isOpen; this.props.setIsEditing(this._isOpen); @@ -133,19 +133,19 @@ export class CollectionSchemaColumnMenu extends React.Component return (
-
+
+ + + + @@ -183,13 +183,13 @@ export class CollectionSchemaColumnMenu extends React.Component />
{this.props.onlyShowOptions ? <> : - <> - {this.renderTypes()} - {this.renderSorting()} -
- -
- + <> + {this.renderTypes()} + {this.renderSorting()} +
+ +
+ }
); @@ -225,7 +225,7 @@ class KeysDropdown extends React.Component { @action setSearchTerm = (value: string): void => { this._searchTerm = value; }; @action setKey = (key: string): void => { this._key = key; }; - @action setIsOpen = (isOpen: boolean): void => {this._isOpen = isOpen;}; + @action setIsOpen = (isOpen: boolean): void => { this._isOpen = isOpen; }; @action onSelect = (key: string): void => { @@ -253,7 +253,7 @@ class KeysDropdown extends React.Component { } } - @action + @action onPointerEnter = (e: React.PointerEvent): void => { this._canClose = false; } @@ -278,7 +278,7 @@ class KeysDropdown extends React.Component { if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) { options.push(
{ this.onSelect(this._searchTerm); this.setSearchTerm(""); }}> - Create "{this._searchTerm}" key
); + Create "{this._searchTerm}" key
); } return options; diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 4b20e8241..38d14c2de 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -57,7 +57,7 @@ .ReactTable { width: 100%; height: 100%; - background: $light-color; + background: white; box-sizing: border-box; border: none !important; @@ -76,6 +76,7 @@ font-size: 12px; height: 30px; border: 1px solid $intermediate-color; + box-shadow: none; } .rt-resizable-header { @@ -101,6 +102,7 @@ // max-height: $MAX_ROW_HEIGHT; font-size: 13px; text-align: center; + background-color: $light-color-secondary; &:last-child { overflow: visible; @@ -114,6 +116,7 @@ .rt-tr-group { direction: ltr; flex: 0 1 auto; + min-height: 30px; // max-height: $MAX_ROW_HEIGHT; // for sub comp @@ -134,6 +137,7 @@ .rt-tr { width: 100%; + min-height: 30px; // height: $MAX_ROW_HEIGHT; } @@ -144,6 +148,7 @@ padding: 0; font-size: 13px; text-align: center; + white-space: normal; .imageBox-cont { position: relative; @@ -190,7 +195,9 @@ .collectionSchemaView-header { height: 100%; - color: $intermediate-color; + color: gray; + letter-spacing: 2px; + text-transform: uppercase; .collectionSchema-header-menu { height: 100%; @@ -204,9 +211,18 @@ margin-right: 4px; } } + + div[class*="css"] { + width: 100%; + height: 100%; + } } } +button.add-column { + width: 28px; +} + .collectionSchema-header-menuOptions { color: black; width: 175px; @@ -265,6 +281,7 @@ .collectionSchema-row { // height: $MAX_ROW_HEIGHT; + height: 100%; &.row-focused { background-color: $light-color-secondary; @@ -317,7 +334,7 @@ p { width: 100%; height: 100%; - word-wrap: break-word; + // word-wrap: break-word; } } @@ -337,5 +354,9 @@ .sub { padding: 20px; - background-color: red; + background-color: $intermediate-color; +} + +.collectionSchemaView-expander { + height: 100%; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index febf95dc7..0e2d37a9e 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -1,6 +1,6 @@ import React = require("react"); import { library } from '@fortawesome/fontawesome-svg-core'; -import { faCog, faPlus } from '@fortawesome/free-solid-svg-icons'; +import { faCog, faPlus, faSortUp, faSortDown } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, observable, trace, untracked } from "mobx"; import { observer } from "mobx-react"; @@ -40,8 +40,7 @@ import { ImageBox } from "../nodes/ImageBox"; import { ComputedField } from "../../../new_fields/ScriptField"; -library.add(faCog); -library.add(faPlus); +library.add(faCog, faPlus, faSortUp, faSortDown); // 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 { @@ -67,7 +66,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @observable previewScript: string = ""; @observable previewDoc: Doc | undefined = this.childDocs.length ? this.childDocs[0] : undefined; - @observable private _node : HTMLDivElement | null = null; + @observable private _node: HTMLDivElement | null = null; @observable private _focusedTable: Doc = this.props.Document; @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @@ -192,7 +191,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @computed get schemaTable() { return ( - Transform; // CreateDropTarget: (ele: HTMLDivElement)=> void; // super createdriotarget active: () => boolean; - onDrop: (e: React.DragEvent, options: DocumentOptions, completed?: (() => void) | undefined)=> void; + onDrop: (e: React.DragEvent, options: DocumentOptions, completed?: (() => void) | undefined) => void; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; isSelected: () => boolean; isFocused: (document: Doc) => boolean; @@ -267,16 +266,16 @@ export class SchemaTable extends React.Component { @observable _headerIsEditing: boolean = false; @observable _cellIsEditing: boolean = false; - @observable _focusedCell: {row: number, col: number} = {row: 0, col: 0}; - @observable _sortedColumns: Map = new Map(); + @observable _focusedCell: { row: number, col: number } = { row: 0, col: 0 }; + @observable _sortedColumns: Map = new Map(); @observable _openCollections: Array = []; - @observable private _node : HTMLDivElement | null = null; + @observable private _node: HTMLDivElement | null = null; @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); } @computed get columns() { return Cast(this.props.Document.schemaColumns, listSpec("string"), []); } - set columns(columns: string[]) {this.props.Document.schemaColumns = new List(columns); } + set columns(columns: string[]) { this.props.Document.schemaColumns = new List(columns); } @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } @computed get tableColumns(): Column[] { let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1); @@ -294,8 +293,8 @@ export class SchemaTable extends React.Component { width: 45, Expander: (rowInfo) => { if (rowInfo.original.type === "collection") { - if (rowInfo.isExpanded) return
this.onCloseCollection(rowInfo.original)}>-
; - if (!rowInfo.isExpanded) return
this.onExpandCollection(rowInfo.original)}>+
; + if (rowInfo.isExpanded) return
this.onCloseCollection(rowInfo.original)}>
; + if (!rowInfo.isExpanded) return
this.onExpandCollection(rowInfo.original)}>
; } else { return null; } @@ -303,10 +302,10 @@ export class SchemaTable extends React.Component { } ); } - + let cols = this.columns.map(col => { - let header = { ContainingCollection: this.props.ContainingCollectionView, Document: this.props.Document, fieldKey: this.props.fieldKey, - renderDepth: this.props.renderDepth, + renderDepth: this.props.renderDepth, addDocTab: this.props.addDocTab, moveDocument: this.props.moveDocument, setIsEditing: this.setCellIsEditing, @@ -347,11 +346,11 @@ export class SchemaTable extends React.Component { }; let colType = this.getColumnType(col); - if (colType === ColumnType.Number) return ; - if (colType === ColumnType.String) return ; + if (colType === ColumnType.Number) return ; + if (colType === ColumnType.String) return ; if (colType === ColumnType.Boolean) return ; if (colType === ColumnType.Doc) return ; - return ; + return ; }, minWidth: 200, }; @@ -363,7 +362,7 @@ export class SchemaTable extends React.Component { accessor: (doc: Doc) => 0, id: "add", Cell: (rowProps: CellInfo) => <>, - width: 45, + width: 28, resizable: false }); return columns; @@ -397,7 +396,7 @@ export class SchemaTable extends React.Component { } tableMoveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => { - console.log("SCHEMA MOVE"); + console.log("SCHEMA MOVE"); this.props.moveDocument(d, target, addDoc); } @@ -410,7 +409,7 @@ export class SchemaTable extends React.Component { ScreenToLocalTransform: this.props.ScreenToLocalTransform, addDoc: this.tableAddDoc, moveDoc: this.tableMoveDoc, - rowInfo, + rowInfo, rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document) }; } @@ -505,7 +504,7 @@ export class SchemaTable extends React.Component { } @action - createColumn = () => { + createColumn = () => { let index = 0; let found = this.columns.findIndex(col => col.toUpperCase() === "New field".toUpperCase()) > -1; if (!found) { @@ -513,7 +512,7 @@ export class SchemaTable extends React.Component { return; } while (found) { - index ++; + index++; found = this.columns.findIndex(col => col.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1; } this.columns.push("New field (" + index + ")"); @@ -562,7 +561,7 @@ export class SchemaTable extends React.Component { if (!typesDoc) { let newTypesDoc = new Doc(); newTypesDoc[key] = type; - this.props.Document.schemaColumnTypes = newTypesDoc; + this.props.Document.schemaColumnTypes = newTypesDoc; return; } else { typesDoc[key] = type; @@ -588,13 +587,13 @@ export class SchemaTable extends React.Component { @action setColumnSort = (column: string, descending: boolean) => { - this._sortedColumns.set(column, {id: column, desc: descending}); + this._sortedColumns.set(column, { id: column, desc: descending }); } @action removeColumnSort = (column: string) => { this._sortedColumns.delete(column); - } + } get documentKeys() { const docs = DocListCast(this.props.Document[this.props.fieldKey]); @@ -619,27 +618,27 @@ export class SchemaTable extends React.Component { let expanded = {}; expandedRowsList.forEach(row => expanded[row] = true); - return { - if (row.original.type === "collection") { + if (row.original.type === "collection") { let childDocs = DocListCast(row.original[this.props.fieldKey]); - return
; + return
; } } - : undefined} - + : undefined} + />; } @@ -685,7 +684,7 @@ export class SchemaTable extends React.Component { interface CollectionSchemaPreviewProps { Document?: Doc; - DataDocument?: Doc; + DataDocument?: Doc; childDocs?: Doc[]; renderDepth: number; fitToBox?: boolean; @@ -762,7 +761,7 @@ export class CollectionSchemaPreview extends React.Component Date: Wed, 24 Jul 2019 12:28:17 -0400 Subject: can text wrap row via context menu --- .../CollectionSchemaMovableTableHOC.tsx | 34 +++++++++++++++------- .../views/collections/CollectionSchemaView.scss | 8 ++++- .../views/collections/CollectionSchemaView.tsx | 28 ++++++++++++++---- 3 files changed, 53 insertions(+), 17 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 6fc04849c..beae739ec 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -1,11 +1,12 @@ import React = require("react"); -import { ReactTableDefaults, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0 } from "react-table"; +import { ReactTableDefaults, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0, RowInfo } from "react-table"; import "./CollectionSchemaView.scss"; import { Transform } from "../../util/Transform"; import { Doc } from "../../../new_fields/Doc"; import { DragManager, SetupDrag } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { Cast, FieldValue, StrCast } from "../../../new_fields/Types"; +import { ContextMenu } from "../ContextMenu"; export interface MovableColumnProps { @@ -60,7 +61,7 @@ export class MovableColumn extends React.Component { return false; } - setupDrag (ref: React.RefObject) { + setupDrag(ref: React.RefObject) { let onRowMove = (e: PointerEvent) => { e.stopPropagation(); e.preventDefault(); @@ -102,10 +103,13 @@ export class MovableColumn extends React.Component { } export interface MovableRowProps { + rowInfo: RowInfo; ScreenToLocalTransform: () => Transform; addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; moveDoc: DragManager.MoveFunction; rowFocused: boolean; + textWrapRow: (doc: Doc) => void; + rowWrapped: boolean; } export class MovableRow extends React.Component { @@ -141,11 +145,10 @@ export class MovableRow extends React.Component { } rowDrop = (e: Event, de: DragManager.DropEvent) => { - const { children = null, rowInfo } = this.props; - if (!rowInfo) return false; + // const { children = null, rowInfo } = this.props; + // if (!rowInfo) return false; - const { original } = rowInfo; - const rowDoc = FieldValue(Cast(original, Doc)); + const rowDoc = FieldValue(Cast(this.props.rowInfo.original, Doc)); if (!rowDoc) return false; let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y); @@ -158,16 +161,23 @@ export class MovableRow extends React.Component { if (de.data.draggedDocuments[0] === rowDoc) return true; let addDocument = (doc: Doc) => this.props.addDoc(doc, rowDoc, before); let movedDocs = de.data.draggedDocuments; //(de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments); - return (de.data.dropAction || de.data.userDropAction) ? + return (de.data.dropAction || de.data.userDropAction) ? de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before) || added, false) : (de.data.moveDocument) ? - movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false) + movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false) // movedDocs.reduce((added: boolean, d) => this.props.moveDoc(d, rowDoc, addDocument) || added, false) : de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false); } return false; } + onRowContextMenu = (e: React.MouseEvent): void => { + // const { rowInfo } = this.props; + // const { textWrapRow, original } = rowInfo; + let description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row"; + ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original) }); + } + render() { const { children = null, rowInfo } = this.props; if (!rowInfo) { @@ -179,10 +189,14 @@ export class MovableRow extends React.Component { if (!doc) return <>; let reference = React.createRef(); - let onItemDown = SetupDrag(reference, () => doc); + let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc); + + let className = "collectionSchema-row"; + if (this.props.rowFocused) className += " row-focused"; + if (this.props.rowWrapped) className += " row-wrapped"; return ( -
+
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 38d14c2de..410790197 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -148,7 +148,7 @@ padding: 0; font-size: 13px; text-align: center; - white-space: normal; + // white-space: normal; .imageBox-cont { position: relative; @@ -287,6 +287,12 @@ button.add-column { background-color: $light-color-secondary; } + &.row-wrapped { + .rt-td { + white-space: normal; + } + } + .row-dragger { // height: $MAX_ROW_HEIGHT; } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 0e2d37a9e..62e4ceb54 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -53,6 +53,7 @@ export enum ColumnType { } // this map should be used for keys that should have a const type of value const columnTypes: Map = new Map([ + ["title", ColumnType.String], ["x", ColumnType.Number], ["y", ColumnType.Number], ["width", ColumnType.Number], ["height", ColumnType.Number], ["nativeWidth", ColumnType.Number], ["nativeHeight", ColumnType.Number], ["isPrototype", ColumnType.Boolean], ["page", ColumnType.Number], ["curPage", ColumnType.Number], ["libraryBrush", ColumnType.Boolean], ["zIndex", ColumnType.Number] @@ -268,7 +269,8 @@ export class SchemaTable extends React.Component { @observable _cellIsEditing: boolean = false; @observable _focusedCell: { row: number, col: number } = { row: 0, col: 0 }; @observable _sortedColumns: Map = new Map(); - @observable _openCollections: Array = []; + @observable _openCollections: Array = []; + @observable _textWrappedRows: Array = []; @observable private _node: HTMLDivElement | null = null; @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @@ -396,7 +398,7 @@ export class SchemaTable extends React.Component { } tableMoveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => { - console.log("SCHEMA MOVE"); + console.log("SCHEMA MOVE", StrCast(d.title), StrCast(target.title)); this.props.moveDocument(d, target, addDoc); } @@ -410,7 +412,9 @@ export class SchemaTable extends React.Component { addDoc: this.tableAddDoc, moveDoc: this.tableMoveDoc, rowInfo, - rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document) + rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document), + textWrapRow: this.textWrapRow, + rowWrapped: this._textWrappedRows.findIndex(id => rowInfo.original[Id] === id) > -1 }; } @@ -429,12 +433,12 @@ export class SchemaTable extends React.Component { @action onExpandCollection = (collection: Doc): void => { - this._openCollections.push(collection); + this._openCollections.push(collection[Id]); } @action onCloseCollection = (collection: Doc): void => { - let index = this._openCollections.findIndex(col => col === collection); + let index = this._openCollections.findIndex(col => col === collection[Id]); if (index > -1) this._openCollections.splice(index, 1); } @@ -610,13 +614,25 @@ export class SchemaTable extends React.Component { return Array.from(Object.keys(keys)); } + @action + textWrapRow = (doc: Doc): void => { + let index = this._textWrappedRows.findIndex(id => doc[Id] === id); + if (index > -1) { + this._textWrappedRows.splice(index, 1); + } else { + this._textWrappedRows.push(doc[Id]); + } + + } + @computed get reactTable() { let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; let hasCollectionChild = this.props.childDocs.reduce((found, doc) => found || doc.type === "collection", false); - let expandedRowsList = this._openCollections.map(col => this.props.childDocs.findIndex(doc => doc === col).toString()); + let expandedRowsList = this._openCollections.map(col => this.props.childDocs.findIndex(doc => doc[Id] === col).toString()); let expanded = {}; expandedRowsList.forEach(row => expanded[row] = true); + console.log(...[...this._textWrappedRows]); // TODO: get component to rerender on text wrap change without needign to console.log :(((( return Date: Wed, 24 Jul 2019 17:48:11 -0400 Subject: can move rows within expanded collection --- src/client/util/DragManager.ts | 4 +-- .../views/collections/CollectionSchemaCells.tsx | 42 ++++++++++++---------- .../CollectionSchemaMovableTableHOC.tsx | 18 +++++----- .../views/collections/CollectionSchemaView.scss | 24 ++++++------- .../views/collections/CollectionSchemaView.tsx | 17 +++++---- src/new_fields/Doc.ts | 9 ++++- 6 files changed, 64 insertions(+), 50 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index f9f6b05c0..0299b1d90 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -1,6 +1,6 @@ import { action, runInAction } from "mobx"; import { Doc } from "../../new_fields/Doc"; -import { Cast } from "../../new_fields/Types"; +import { Cast, StrCast } from "../../new_fields/Types"; import { URLField } from "../../new_fields/URLField"; import { emptyFunction } from "../../Utils"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; @@ -305,7 +305,7 @@ export namespace DragManager { StartDrag([ele], dragData, downX, downY, options); } - export function StartColumnDrag(ele: HTMLElement, dragData: ColumnDragData, downX: number, downY: number, options?:DragOptions) { + export function StartColumnDrag(ele: HTMLElement, dragData: ColumnDragData, downX: number, downY: number, options?: DragOptions) { StartDrag([ele], dragData, downX, downY, options); } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index abb2203a0..bc84da140 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -34,7 +34,7 @@ export interface CellProps { renderDepth: number; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => void; moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; - isFocused: boolean; + isFocused: boolean; changeFocusedCellByIndex: (row: number, col: number) => void; setIsEditing: (isEditing: boolean) => void; isEditable: boolean; @@ -42,22 +42,22 @@ export interface CellProps { @observer export class CollectionSchemaCell extends React.Component { - @observable protected _isEditing: boolean = false; + @observable protected _isEditing: boolean = this.props.isEditing ? true : false; protected _focusRef = React.createRef(); protected _document = this.props.rowProps.original; private _dropDisposer?: DragManager.DragDropDisposer; componentDidMount() { - if (this._focusRef.current) { - if (this.props.isFocused) { - this._focusRef.current.className += " focused"; - if (!this.props.isEditable) { - this._focusRef.current.className += " inactive"; - } - } else { - this._focusRef.current.className = "collectionSchemaView-cellWrapper"; - } - } + // if (this._focusRef.current) { + // if (this.props.isFocused) { + // this._focusRef.current.className += " focused"; + // if (!this.props.isEditable) { + // this._focusRef.current.className += " inactive"; + // } + // } else { + // this._focusRef.current.className = "collectionSchemaView-cellWrapper"; + // } + // } document.addEventListener("keydown", this.onKeyDown); @@ -69,6 +69,7 @@ export class CollectionSchemaCell extends React.Component { @action onKeyDown = (e: KeyboardEvent): void => { + console.log("CELL keydown"); if (this.props.isFocused && this.props.isEditable) { document.removeEventListener("keydown", this.onKeyDown); this._isEditing = true; @@ -139,10 +140,10 @@ export class CollectionSchemaCell extends React.Component { addDocTab: this.props.addDocTab, }; - let onItemDown = (e: React.PointerEvent) => { - SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document, - this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument, this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e); - }; + // let onItemDown = (e: React.PointerEvent) => { + // SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document, + // this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument, this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e); + // }; let onPointerEnter = (e: React.PointerEvent): void => { if (e.buttons === 1 && SelectionManager.GetIsDragging() && (type === "document" || type === undefined)) { dragRef!.current!.className = "doc-drag-over"; @@ -163,10 +164,15 @@ export class CollectionSchemaCell extends React.Component { contents = typeof field === "object" ? doc ? StrCast(doc.title) === "" ? "--" : StrCast(doc.title) : `--${typeof field}--` : `--${typeof field}--`; } + let className = "collectionSchemaView-cellWrapper"; + if (this._isEditing) className += " editing"; + if (this.props.isFocused && this.props.isEditable) className += " focused"; + if (this.props.isFocused && !this.props.isEditable) className += " inactive"; + return (
-
-
+
+
Transform; addDoc: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean; - moveDoc: DragManager.MoveFunction; + removeDoc: (doc: Doc) => boolean; rowFocused: boolean; textWrapRow: (doc: Doc) => void; rowWrapped: boolean; @@ -145,9 +146,6 @@ export class MovableRow extends React.Component { } rowDrop = (e: Event, de: DragManager.DropEvent) => { - // const { children = null, rowInfo } = this.props; - // if (!rowInfo) return false; - const rowDoc = FieldValue(Cast(this.props.rowInfo.original, Doc)); if (!rowDoc) return false; @@ -160,24 +158,26 @@ export class MovableRow extends React.Component { e.stopPropagation(); if (de.data.draggedDocuments[0] === rowDoc) return true; let addDocument = (doc: Doc) => this.props.addDoc(doc, rowDoc, before); - let movedDocs = de.data.draggedDocuments; //(de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments); + let movedDocs = de.data.draggedDocuments; return (de.data.dropAction || de.data.userDropAction) ? de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before) || added, false) : (de.data.moveDocument) ? movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false) - // movedDocs.reduce((added: boolean, d) => this.props.moveDoc(d, rowDoc, addDocument) || added, false) : de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false); } return false; } onRowContextMenu = (e: React.MouseEvent): void => { - // const { rowInfo } = this.props; - // const { textWrapRow, original } = rowInfo; let description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row"; ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original) }); } + @action + move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => { + return doc !== target && this.props.removeDoc(doc) && addDoc(doc); + } + render() { const { children = null, rowInfo } = this.props; if (!rowInfo) { @@ -189,7 +189,7 @@ export class MovableRow extends React.Component { if (!doc) return <>; let reference = React.createRef(); - let onItemDown = SetupDrag(reference, () => doc, this.props.moveDoc); + let onItemDown = SetupDrag(reference, () => doc, this.move); let className = "collectionSchema-row"; if (this.props.rowFocused) className += " row-focused"; diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 410790197..c2b0d8f42 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -148,7 +148,7 @@ padding: 0; font-size: 13px; text-align: center; - // white-space: normal; + white-space: normal; .imageBox-cont { position: relative; @@ -196,8 +196,6 @@ .collectionSchemaView-header { height: 100%; color: gray; - letter-spacing: 2px; - text-transform: uppercase; .collectionSchema-header-menu { height: 100%; @@ -206,16 +204,18 @@ width: 100%; height: 100%; padding: 4px; + letter-spacing: 2px; + text-transform: uppercase; svg { margin-right: 4px; } } - div[class*="css"] { - width: 100%; - height: 100%; - } + // div[class*="css"] { + // width: 100%; + // height: 100%; + // } } } @@ -287,12 +287,6 @@ button.add-column { background-color: $light-color-secondary; } - &.row-wrapped { - .rt-td { - white-space: normal; - } - } - .row-dragger { // height: $MAX_ROW_HEIGHT; } @@ -309,6 +303,10 @@ button.add-column { &.row-inside { border: 1px solid red; } + + .row-dragging { + background-color: blue; + } } } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 62e4ceb54..a7e435ac6 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -344,7 +344,7 @@ export class SchemaTable extends React.Component { addDocTab: this.props.addDocTab, moveDocument: this.props.moveDocument, setIsEditing: this.setCellIsEditing, - isEditable: isEditable + isEditable: isEditable, }; let colType = this.getColumnType(col); @@ -393,13 +393,16 @@ export class SchemaTable extends React.Component { } tableAddDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => { - console.log("table add doc"); return Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before); } - tableMoveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => { - console.log("SCHEMA MOVE", StrCast(d.title), StrCast(target.title)); - this.props.moveDocument(d, target, addDoc); + tableRemoveDoc = (document: Doc): boolean => { + let index = this.props.childDocs.findIndex(d => d === document); + if (index !== -1) { + this.props.childDocs.splice(index, 1); + return true; + } + return false; } private getTrProps: ComponentPropsGetterR = (state, rowInfo) => { @@ -410,7 +413,7 @@ export class SchemaTable extends React.Component { return { ScreenToLocalTransform: this.props.ScreenToLocalTransform, addDoc: this.tableAddDoc, - moveDoc: this.tableMoveDoc, + removeDoc: this.tableRemoveDoc, rowInfo, rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document), textWrapRow: this.textWrapRow, @@ -467,6 +470,7 @@ export class SchemaTable extends React.Component { } onKeyDown = (e: KeyboardEvent): void => { + console.log("schema keydown", !this._cellIsEditing, !this._headerIsEditing, this.props.isFocused(this.props.Document)); if (!this._cellIsEditing && !this._headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected()) { let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : ""; this.changeFocusedCellByDirection(direction); @@ -504,7 +508,6 @@ export class SchemaTable extends React.Component { changeFocusedCellByIndex = (row: number, col: number): void => { this._focusedCell = { row: row, col: col }; this.props.setFocused(this.props.Document); - // console.log("changed cell by index", StrCast(this.props.Document.title)); } @action diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 5ae0753d8..eba1d4f04 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -267,21 +267,28 @@ export namespace Doc { export function AddDocToList(target: Doc, key: string, doc: Doc, relativeTo?: Doc, before?: boolean, first?: boolean, allowDuplicates?: boolean) { if (target[key] === undefined) { + console.log("target key undefined"); Doc.GetProto(target)[key] = new List(); } let list = Cast(target[key], listSpec(Doc)); if (list) { + console.log("has list"); if (allowDuplicates !== true) { let pind = list.reduce((l, d, i) => d instanceof Doc && Doc.AreProtosEqual(d, doc) ? i : l, -1); if (pind !== -1) { list.splice(pind, 1); } } - if (first) list.splice(0, 0, doc); + if (first) { + console.log("is first"); + list.splice(0, 0, doc); + } else { + console.log("not first"); let ind = relativeTo ? list.indexOf(relativeTo) : -1; if (ind === -1) list.push(doc); else list.splice(before ? ind : ind + 1, 0, doc); + console.log("index", ind); } } return true; -- cgit v1.2.3-70-g09d2 From 779938dd613d81bfb773f14cd4e43362f0aa8b24 Mon Sep 17 00:00:00 2001 From: Fawn Date: Wed, 24 Jul 2019 22:08:31 -0400 Subject: minor schema stylign --- .../views/collections/CollectionSchemaCells.tsx | 20 +++------------ .../views/collections/CollectionSchemaView.scss | 29 ++++++++++++++++------ .../views/collections/CollectionSchemaView.tsx | 24 +++++++++++++++--- 3 files changed, 46 insertions(+), 27 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index bc84da140..d453fed47 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -42,23 +42,12 @@ export interface CellProps { @observer export class CollectionSchemaCell extends React.Component { - @observable protected _isEditing: boolean = this.props.isEditing ? true : false; + @observable protected _isEditing: boolean = false; protected _focusRef = React.createRef(); protected _document = this.props.rowProps.original; private _dropDisposer?: DragManager.DragDropDisposer; componentDidMount() { - // if (this._focusRef.current) { - // if (this.props.isFocused) { - // this._focusRef.current.className += " focused"; - // if (!this.props.isEditable) { - // this._focusRef.current.className += " inactive"; - // } - // } else { - // this._focusRef.current.className = "collectionSchemaView-cellWrapper"; - // } - // } - document.addEventListener("keydown", this.onKeyDown); } @@ -69,7 +58,6 @@ export class CollectionSchemaCell extends React.Component { @action onKeyDown = (e: KeyboardEvent): void => { - console.log("CELL keydown"); if (this.props.isFocused && this.props.isEditable) { document.removeEventListener("keydown", this.onKeyDown); this._isEditing = true; @@ -146,11 +134,11 @@ export class CollectionSchemaCell extends React.Component { // }; let onPointerEnter = (e: React.PointerEvent): void => { if (e.buttons === 1 && SelectionManager.GetIsDragging() && (type === "document" || type === undefined)) { - dragRef!.current!.className = "doc-drag-over"; + dragRef!.current!.className = "collectionSchemaView-cellContainer doc-drag-over"; } }; let onPointerLeave = (e: React.PointerEvent): void => { - dragRef!.current!.className = ""; + dragRef!.current!.className = "collectionSchemaView-cellContainer"; }; let field = props.Document[props.fieldKey]; @@ -170,7 +158,7 @@ export class CollectionSchemaCell extends React.Component { if (this.props.isFocused && !this.props.isEditable) className += " inactive"; return ( -
+
{ { expander: true, Header: "", - width: 45, + width: 30, Expander: (rowInfo) => { if (rowInfo.original.type === "collection") { if (rowInfo.isExpanded) return
this.onCloseCollection(rowInfo.original)}>
; @@ -421,6 +421,25 @@ export class SchemaTable extends React.Component { }; } + private getTdProps: ComponentPropsGetterR = (state, rowInfo, column, instance) => { + if (!rowInfo) return {}; + if (!column) return {}; + + let row = rowInfo.index; + let col = this.columns.indexOf(column.id); + // let col = column ? this.columns.indexOf(column!) : -1; + let isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document); + // let column = this.columns.indexOf(column.id!); + + console.log("td style", row, col, this._focusedCell.row, this._focusedCell.col); + + return { + style: { + border: !this._headerIsEditing && isFocused ? "2px solid black" : "1px solid #f1efeb" + } + }; + } + // private createTarget = (ele: HTMLDivElement) => { // this._mainCont = ele; // this.props.CreateDropTarget(ele); @@ -456,7 +475,6 @@ export class SchemaTable extends React.Component { } onPointerDown = (e: React.PointerEvent): void => { - // console.log("pointer down", StrCast(this.props.Document.title)); this.props.setFocused(this.props.Document); if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey) { if (this.props.isSelected()) e.stopPropagation(); @@ -470,7 +488,6 @@ export class SchemaTable extends React.Component { } onKeyDown = (e: KeyboardEvent): void => { - console.log("schema keydown", !this._cellIsEditing, !this._headerIsEditing, this.props.isFocused(this.props.Document)); if (!this._cellIsEditing && !this._headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected()) { let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : ""; this.changeFocusedCellByDirection(direction); @@ -645,6 +662,7 @@ export class SchemaTable extends React.Component { showPagination={false} columns={this.tableColumns} getTrProps={this.getTrProps} + getTdProps={this.getTdProps} sortable={false} TrComponent={MovableRow} sorted={Array.from(this._sortedColumns.values())} -- cgit v1.2.3-70-g09d2 From f8f3ee8df596758ca6f5f7e735fb1296a676f5b6 Mon Sep 17 00:00:00 2001 From: Fawn Date: Wed, 24 Jul 2019 22:31:45 -0400 Subject: merge --- .../views/collections/CollectionSchemaMovableTableHOC.tsx | 15 ++++++++++----- src/client/views/collections/CollectionSchemaView.scss | 9 +++++++++ src/client/views/collections/CollectionViewChromes.tsx | 6 +++--- 3 files changed, 22 insertions(+), 8 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 6d388bb40..290958cd0 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -8,7 +8,11 @@ import { SelectionManager } from "../../util/SelectionManager"; import { Cast, FieldValue, StrCast } from "../../../new_fields/Types"; import { ContextMenu } from "../ContextMenu"; import { action } from "mobx"; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faGripVertical } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +library.add(faGripVertical); export interface MovableColumnProps { columnRenderer: TableCellRenderer; @@ -198,11 +202,12 @@ export class MovableRow extends React.Component { return (
-
- - {children} - -
+ +
+ +
+ {children} +
); diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 3bc1bc060..22d8a5cb6 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -70,6 +70,9 @@ } .rt-thead { + width: calc(100% - 30px); + margin-left: 30px; + &.-header { // background: $intermediate-color; // color: $light-color; @@ -77,6 +80,8 @@ height: 30px; // border: 1px solid $intermediate-color; box-shadow: none; + // width: calc(100% - 30px); + // margin-right: -30px; } .rt-resizable-header { @@ -298,6 +303,10 @@ button.add-column { .row-dragger { // height: $MAX_ROW_HEIGHT; + width: 30px; + height: 100%; + padding: 10px; + color: gray; } .collectionSchema-row-wrapper { diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 52fee26bf..03676fe86 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -53,7 +53,7 @@ class CollectionViewBaseChrome extends React.ComponentMasonry View
- ) + ); } } @@ -147,6 +147,6 @@ export class CollectionStackingViewChrome extends React.Component
- ) + ); } -} \ No newline at end of file +} -- cgit v1.2.3-70-g09d2 From 2d62ca0060c9ef7d3932e8681deb09cc3acf6d48 Mon Sep 17 00:00:00 2001 From: Fawn Date: Thu, 25 Jul 2019 11:47:23 -0400 Subject: schema stylign --- .../CollectionSchemaMovableTableHOC.tsx | 10 +-- .../views/collections/CollectionSchemaView.scss | 82 +++++++++++++++++----- .../views/collections/CollectionSchemaView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 2 +- 4 files changed, 73 insertions(+), 23 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 290958cd0..70d6fbc7b 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -9,10 +9,10 @@ import { Cast, FieldValue, StrCast } from "../../../new_fields/Types"; import { ContextMenu } from "../ContextMenu"; import { action } from "mobx"; import { library } from '@fortawesome/fontawesome-svg-core'; -import { faGripVertical } from '@fortawesome/free-solid-svg-icons'; +import { faGripVertical, faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -library.add(faGripVertical); +library.add(faGripVertical, faTrash); export interface MovableColumnProps { columnRenderer: TableCellRenderer; @@ -198,13 +198,15 @@ export class MovableRow extends React.Component { let className = "collectionSchema-row"; if (this.props.rowFocused) className += " row-focused"; if (this.props.rowWrapped) className += " row-wrapped"; + // if (!this.props.rowWrapped) className += " row-unwrapped"; return (
-
- +
+
this.props.removeDoc(this.props.rowInfo.original)}>
+
{children} diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 22d8a5cb6..9ad52db4c 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -8,7 +8,7 @@ box-sizing: border-box; // position: absolute; width: 100%; - // height: calc(100% - 25px); + height: calc(100% - 50px); // overflow: hidden; overflow-x: scroll; border: none; @@ -55,7 +55,7 @@ } .ReactTable { - width: 100%; + width: 100% !important; height: 100%; background: white; box-sizing: border-box; @@ -70,8 +70,8 @@ } .rt-thead { - width: calc(100% - 30px); - margin-left: 30px; + width: calc(100% - 50px); + margin-left: 50px; &.-header { // background: $intermediate-color; @@ -118,6 +118,7 @@ .rt-tbody { direction: rtl; + overflow: visible; } .rt-tr-group { @@ -139,12 +140,12 @@ // background-color: $light-color-secondary; // } - &:first-child { - border-top: 1px solid $light-color-secondary !important; - } - &:last-child { - border-bottom: 1px solid $light-color-secondary !important; - } + // &:first-child { + // border-top: 1px solid $light-color-secondary !important; + // } + // &:last-child { + // border-bottom: 1px solid $light-color-secondary !important; + // } } .rt-tr { @@ -162,7 +163,8 @@ padding: 0; font-size: 13px; text-align: center; - white-space: normal; + + // white-space: normal; .imageBox-cont { position: relative; @@ -296,17 +298,46 @@ button.add-column { .collectionSchema-row { // height: $MAX_ROW_HEIGHT; height: 100%; + background-color: white; &.row-focused { - background-color: rgb(253, 191, 191);//$light-color-secondary; + background-color: rgb(255, 246, 246);//$light-color-secondary; + } + + &.row-wrapped { + white-space: normal; } .row-dragger { + display: flex; + justify-content: space-evenly; // height: $MAX_ROW_HEIGHT; - width: 30px; + flex: 50 0 auto; + width: 50px; + max-width: 50px; height: 100%; - padding: 10px; - color: gray; + min-height: 30px; + // padding: 5px 5px 5px 0; + color: lightgray; + background-color: white; + transition: color 0.1s ease; + + // &:hover { + // color: lightgray; + // } + + .row-option { + // padding: 5px; + cursor: pointer; + transition: color 0.1s ease; + display: flex; + flex-direction: column; + justify-content: center; + + &:hover { + color: gray; + } + } } .collectionSchema-row-wrapper { @@ -369,6 +400,7 @@ button.add-column { } .collectionSchemaView-toolbar { + height: 50px; display: flex; justify-content: flex-end; } @@ -379,8 +411,24 @@ button.add-column { } .sub { - padding: 20px; - background-color: $intermediate-color; + padding: 10px 30px; + // padding-left: 80px; + background-color: rgb(252, 252, 252); + width: calc(100% - 50px); + margin-left: 50px; + + .rt-table { + overflow-x: hidden; // todo; this shouldnt be like this :(( + overflow-y: visible; + } // TODO fix + + .row-dragger { + background-color: rgb(252, 252, 252); + } + + .rt-table { + background-color: rgb(252, 252, 252); + } } .collectionSchemaView-expander { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 87a4a0c6a..a8692ee95 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -435,7 +435,7 @@ export class SchemaTable extends React.Component { return { style: { - border: !this._headerIsEditing && isFocused ? "2px solid black" : "1px solid #f1efeb" + border: !this._headerIsEditing && isFocused ? "2px solid rgb(255, 160, 160)" : "1px solid #f1efeb" } }; } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 62d721868..df8a1ebc1 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -62,7 +62,7 @@ export class CollectionView extends React.Component { } else { return [ - (), + // (), this.SubViewHelper(type, renderProps) ]; } -- cgit v1.2.3-70-g09d2 From d583b473181c9e97b4626c302dc9a167fa64a17c Mon Sep 17 00:00:00 2001 From: Fawn Date: Thu, 25 Jul 2019 12:43:24 -0400 Subject: some preview stuff --- .../views/collections/CollectionSchemaView.scss | 32 ++++++++++++++++------ .../views/collections/CollectionSchemaView.tsx | 19 +++++++++---- 2 files changed, 37 insertions(+), 14 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 9ad52db4c..98ec971ef 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -40,22 +40,23 @@ .collectionSchemaView-dividerDragger { position: relative; - background: black; float: left; - height: 37px; + height: 100%; width: 20px; z-index: 20; right: 0; top: 0; - background: $main-accent; - box-sizing: border-box; - border-left: 1px solid $intermediate-color; - border-right: 1px solid $intermediate-color; + background: gray; + cursor: col-resize; + // background: $main-accent; + // box-sizing: border-box; + // border-left: 1px solid $intermediate-color; + // border-right: 1px solid $intermediate-color; } } .ReactTable { - width: 100% !important; + width: 100%; height: 100%; background: white; box-sizing: border-box; @@ -400,9 +401,16 @@ button.add-column { } .collectionSchemaView-toolbar { - height: 50px; + height: 30px; display: flex; justify-content: flex-end; + padding: 0 10px; + + .collectionSchemaView-toolbar-item { + display: flex; + flex-direction: column; + justify-content: center; + } } #preview-schema-checkbox-div { @@ -410,6 +418,10 @@ button.add-column { font-size: 12px; } +.collectionSchemaView-table { + width: calc(100% - 7px); +} + .sub { padding: 10px 30px; // padding-left: 80px; @@ -429,6 +441,10 @@ button.add-column { .rt-table { background-color: rgb(252, 252, 252); } + + .collectionSchemaView-table { + width: 100%; + } } .collectionSchemaView-expander { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index a8692ee95..ed2c88f19 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -66,7 +66,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { private DIVIDER_WIDTH = 4; @observable previewScript: string = ""; - @observable previewDoc: Doc | undefined = this.childDocs.length ? this.childDocs[0] : undefined; + @observable previewDoc: Doc | undefined = undefined; @observable private _node: HTMLDivElement | null = null; @observable private _focusedTable: Doc = this.props.Document; @@ -100,6 +100,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @action setPreviewDoc = (doc: Doc): void => { + console.log("set"); this.previewDoc = doc; } @@ -147,6 +148,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { get previewDocument(): Doc | undefined { let selected = this.previewDoc; let pdc = selected ? (this.previewScript && this.previewScript !== "this" ? FieldValue(Cast(selected[this.previewScript], Doc)) : selected) : undefined; + console.log("preview document", pdc); return pdc; } @@ -209,6 +211,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { isSelected={this.props.isSelected} isFocused={this.isFocused} setFocused={this.setFocused} + setPreviewDoc={this.setPreviewDoc} /> ); } @@ -217,7 +220,9 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { get schemaToolbar() { return (
-
Show Preview
+
+
Show Preview
+
); } @@ -258,6 +263,7 @@ export interface SchemaTableProps { isSelected: () => boolean; isFocused: (document: Doc) => boolean; setFocused: (document: Doc) => void; + setPreviewDoc: (document: Doc) => void; } @observer @@ -430,9 +436,6 @@ export class SchemaTable extends React.Component { // let col = column ? this.columns.indexOf(column!) : -1; let isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document); // let column = this.columns.indexOf(column.id!); - - console.log("td style", row, col, this._focusedCell.row, this._focusedCell.col); - return { style: { border: !this._headerIsEditing && isFocused ? "2px solid rgb(255, 160, 160)" : "1px solid #f1efeb" @@ -519,12 +522,16 @@ export class SchemaTable extends React.Component { this._focusedCell = { row: this._focusedCell.row + 1 === this.props.childDocs.length ? this._focusedCell.row : this._focusedCell.row + 1, col: this._focusedCell.col }; break; } + let doc = this.props.childDocs[this._focusedCell.row]; + this.props.setPreviewDoc(doc); } @action changeFocusedCellByIndex = (row: number, col: number): void => { this._focusedCell = { row: row, col: col }; this.props.setFocused(this.props.Document); + let doc = this.props.childDocs[this._focusedCell.row]; + this.props.setPreviewDoc(doc); } @action @@ -647,7 +654,7 @@ export class SchemaTable extends React.Component { @computed get reactTable() { - let previewWidth = this.previewWidth() + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; + let previewWidth = this.previewWidth(); // + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1; let hasCollectionChild = this.props.childDocs.reduce((found, doc) => found || doc.type === "collection", false); let expandedRowsList = this._openCollections.map(col => this.props.childDocs.findIndex(doc => doc[Id] === col).toString()); let expanded = {}; -- cgit v1.2.3-70-g09d2 From db560a8c43f77b9342e55a48dd96f695813b32ef Mon Sep 17 00:00:00 2001 From: yipstanley Date: Thu, 25 Jul 2019 12:53:09 -0400 Subject: oof a lot of stuff here --- .../views/collections/CollectionSchemaView.scss | 1 + .../views/collections/CollectionSchemaView.tsx | 2 + .../views/collections/CollectionStackingView.tsx | 5 +- .../views/collections/CollectionTreeView.scss | 27 ++- .../views/collections/CollectionTreeView.tsx | 2 + src/client/views/collections/CollectionView.tsx | 18 +- .../views/collections/CollectionViewChromes.scss | 258 +++++++++++---------- .../views/collections/CollectionViewChromes.tsx | 137 ++++++----- .../authentication/models/current_user_utils.ts | 4 + 9 files changed, 251 insertions(+), 203 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 186e006f3..1e6d1fe99 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -12,6 +12,7 @@ width: 100%; height: 100%; overflow: hidden; + transition: top 0.5s; .collectionSchemaView-cellContents { height: $MAX_ROW_HEIGHT; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 2cf50e551..bdcedea10 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -69,6 +69,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { @observable _newKeyName: string = ""; @observable previewScript: string = ""; + @computed get chromeCollapsed() { return this.props.chromeCollapsed; } @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); } @@ -390,6 +391,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { render() { return (
this.onDrop(e, {})} onContextMenu={this.onContextMenu} ref={this.createTarget}> {this.reactTable} {this.dividerDragger} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 31ec80d76..b5c0fb3d6 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -21,8 +21,6 @@ import { List } from "../../../new_fields/List"; import { EditableView } from "../EditableView"; import { CollectionViewProps } from "./CollectionBaseView"; -let valuesCreated = 1; - @observer export class CollectionStackingView extends CollectionSubView(doc => doc) { _masonryGridRef: HTMLDivElement | null = null; @@ -33,7 +31,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { _columnStart: number = 0; @observable private cursor: CursorProperty = "grab"; get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); } - get chromeCollapsed() { return this.props.chromeCollapsed; } + @computed get chromeCollapsed() { return this.props.chromeCollapsed; } @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); } @computed get yMargin() { return NumCast(this.props.Document.yMargin, 2 * this.gridGap); } @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); } @@ -84,7 +82,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { () => StrCast(this.props.Document.sectionFilter), () => { this.props.Document.sectionHeaders = new List(); - valuesCreated = 1; } ) } diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index 5205f4313..db3652ff6 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -31,6 +31,7 @@ margin-top: 4px; transform: scale(1.3, 1.3); } + .editableView-container { font-weight: bold; } @@ -43,18 +44,20 @@ display: inline; } - .editableView-input, .editableView-container-editing { + .editableView-input, + .editableView-container-editing { display: block; text-overflow: ellipsis; font-size: 24px; white-space: nowrap; } } + .collectionTreeView-keyHeader { font-style: italic; font-size: 8pt; margin-left: 3px; - display:none; + display: none; background: lightgray; } @@ -72,28 +75,31 @@ // width:100%;//width: max-content; } + .treeViewItem-openRight { display: none; } .treeViewItem-border { - display:inherit; + display: inherit; border-left: dashed 1px #00000042; } .treeViewItem-header:hover { .collectionTreeView-keyHeader { - display:inherit; + display: inherit; } + .treeViewItem-openRight { display: inline-block; - height:13px; - margin-top:2px; + height: 13px; + margin-top: 2px; margin-left: 5px; + // display: inline; svg { - display:block; - padding:0px; + display: block; + padding: 0px; margin: 0px; } } @@ -101,14 +107,17 @@ .treeViewItem-header { border: transparent 1px solid; - display:flex; + display: flex; } + .treeViewItem-header-above { border-top: black 1px solid; } + .treeViewItem-header-below { border-bottom: black 1px solid; } + .treeViewItem-header-inside { border: black 1px solid; } \ No newline at end of file diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index d05cc375e..cbf32c667 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -456,6 +456,8 @@ export class CollectionTreeView extends CollectionSubView(Document) { private treedropDisposer?: DragManager.DragDropDisposer; private _mainEle?: HTMLDivElement; + @computed get chromeCollapsed() { return this.props.chromeCollapsed; } + protected createTreeDropTarget = (ele: HTMLDivElement) => { this.treedropDisposer && this.treedropDisposer(); if (this._mainEle = ele) { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index e2f652908..1c6dd661d 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -18,7 +18,7 @@ import { CollectionTreeView } from "./CollectionTreeView"; import { StrCast, PromiseValue } from '../../../new_fields/Types'; import { DocumentType } from '../../documents/Documents'; import { CollectionStackingViewChrome, CollectionViewBaseChrome } from './CollectionViewChromes'; -import { observable } from 'mobx'; +import { observable, action, runInAction } from 'mobx'; export const COLLECTION_BORDER_WIDTH = 2; library.add(faTh); @@ -37,11 +37,20 @@ export class CollectionView extends React.Component { public static LayoutString(fieldStr: string = "data", fieldExt: string = "") { return FieldView.LayoutString(CollectionView, fieldStr, fieldExt); } + componentDidMount = () => { + // chrome status is one of disabled, collapsed, or visible. this determines initial state from document + let chromeStatus = this.props.Document.chromeStatus; + if (chromeStatus && (chromeStatus === "disabled" || chromeStatus === "collapsed")) { + runInAction(() => this._collapsed = true); + } + } + private SubViewHelper = (type: CollectionViewType, renderProps: CollectionRenderProps) => { let props = { ...this.props, ...renderProps }; switch (this.isAnnotationOverlay ? CollectionViewType.Freeform : type) { case CollectionViewType.Schema: return (); - case CollectionViewType.Docking: return (); + // currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip + case CollectionViewType.Docking: return (); case CollectionViewType.Tree: return (); case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (); } case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (); } @@ -52,12 +61,15 @@ export class CollectionView extends React.Component { return (null); } + @action private collapse = (value: boolean) => { this._collapsed = value; + this.props.Document.chromeStatus = value ? "collapsed" : "visible"; } private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => { - if (this.isAnnotationOverlay || this.props.Document === CurrentUserUtils.UserDocument.sidebar) { + // currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip + if (this.isAnnotationOverlay || this.props.Document.chromeStatus === "disabled" || type === CollectionViewType.Docking) { return [(null), this.SubViewHelper(type, renderProps)]; } else { diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss index d37228bde..0faca0607 100644 --- a/src/client/views/collections/CollectionViewChromes.scss +++ b/src/client/views/collections/CollectionViewChromes.scss @@ -1,167 +1,171 @@ @import "../globalCssVariables"; @import '~js-datepicker/dist/datepicker.min.css'; -.collectionViewChrome { - display: grid; - grid-template-columns: 1fr auto; - padding-bottom: 10px; - border-bottom: .5px solid lightgrey; - margin: 10px; +.collectionViewChrome-cont { position: relative; z-index: 9001; transition: top .5s; + background: rgb(238, 238, 238); + padding: 10px; - .collectionViewBaseChrome { - display: flex; + .collectionViewChrome { + display: grid; + grid-template-columns: 1fr auto; + padding-bottom: 10px; + border-bottom: .5px solid lightgrey; - .collectionViewBaseChrome-viewPicker { - font-size: 75%; - text-transform: uppercase; - letter-spacing: 2px; - background: rgb(238, 238, 238); - color: grey; - outline-color: black; - border: none; - padding: 12px 10px 11px 10px; - margin-left: 50px; - } - - .collectionViewBaseChrome-viewPicker:active { - outline-color: black; - } - - .collectionViewBaseChrome-collapse { - transition: all .5s; - position: absolute; - width: 40px; - } - - .collectionViewBaseChrome-viewSpecs { - margin-left: 10px; - display: grid; + .collectionViewBaseChrome { + display: flex; - .collectionViewBaseChrome-viewSpecsInput { - padding: 12px 10px 11px 10px; - border: 0px; - color: grey; - text-align: center; + .collectionViewBaseChrome-viewPicker { + font-size: 75%; text-transform: uppercase; letter-spacing: 2px; - outline-color: black; - font-size: 75%; background: rgb(238, 238, 238); - height: 100%; - width: 150px; + color: grey; + outline-color: black; + border: none; + padding: 12px 10px 11px 10px; + margin-left: 50px; + } + + .collectionViewBaseChrome-viewPicker:active { + outline-color: black; } - .collectionViewBaseChrome-viewSpecsMenu { - overflow: hidden; - transition: height .5s, display .5s; + .collectionViewBaseChrome-collapse { + transition: all .5s; position: absolute; - top: 60px; - z-index: 100; - display: flex; - flex-direction: column; - background: rgb(238, 238, 238); - box-shadow: grey 2px 2px 4px; + width: 40px; + } - .qs-datepicker { - left: unset; - right: 0; + .collectionViewBaseChrome-viewSpecs { + margin-left: 10px; + display: grid; + + .collectionViewBaseChrome-viewSpecsInput { + padding: 12px 10px 11px 10px; + border: 0px; + color: grey; + text-align: center; + text-transform: uppercase; + letter-spacing: 2px; + outline-color: black; + font-size: 75%; + background: rgb(238, 238, 238); + height: 100%; + width: 150px; } - .collectionViewBaseChrome-viewSpecsMenu-row { - display: grid; - grid-template-columns: 150px 200px 150px; - margin-top: 10px; - margin-right: 10px; - - .collectionViewBaseChrome-viewSpecsMenu-rowLeft, - .collectionViewBaseChrome-viewSpecsMenu-rowMiddle, - .collectionViewBaseChrome-viewSpecsMenu-rowRight { - font-size: 75%; - letter-spacing: 2px; - color: grey; - margin-left: 10px; - padding: 5px; - border: none; - outline-color: black; + .collectionViewBaseChrome-viewSpecsMenu { + overflow: hidden; + transition: height .5s, display .5s; + position: absolute; + top: 60px; + z-index: 100; + display: flex; + flex-direction: column; + background: rgb(238, 238, 238); + box-shadow: grey 2px 2px 4px; + + .qs-datepicker { + left: unset; + right: 0; } - } - .collectionViewBaseChrome-viewSpecsMenu-lastRow { - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: 10px; - margin: 10px; + .collectionViewBaseChrome-viewSpecsMenu-row { + display: grid; + grid-template-columns: 150px 200px 150px; + margin-top: 10px; + margin-right: 10px; + + .collectionViewBaseChrome-viewSpecsMenu-rowLeft, + .collectionViewBaseChrome-viewSpecsMenu-rowMiddle, + .collectionViewBaseChrome-viewSpecsMenu-rowRight { + font-size: 75%; + letter-spacing: 2px; + color: grey; + margin-left: 10px; + padding: 5px; + border: none; + outline-color: black; + } + } + + .collectionViewBaseChrome-viewSpecsMenu-lastRow { + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 10px; + margin: 10px; + } } } } - } - .collectionStackingViewChrome-cont { - display: flex; - justify-content: space-between; - } + .collectionStackingViewChrome-cont { + display: flex; + justify-content: space-between; + } - .collectionStackingViewChrome-sort { - display: flex; - align-items: center; - justify-content: space-between; + .collectionStackingViewChrome-sort { + display: flex; + align-items: center; + justify-content: space-between; - .collectionStackingViewChrome-sortIcon { - transition: transform .5s; - margin-left: 10px; + .collectionStackingViewChrome-sortIcon { + transition: transform .5s; + margin-left: 10px; + } } - } - - button:hover { - transform: scale(1); - } + button:hover { + transform: scale(1); + } - .collectionStackingViewChrome-sectionFilter-cont { - justify-self: right; - display: flex; - font-size: 75%; - text-transform: uppercase; - letter-spacing: 2px; - .collectionStackingViewChrome-sectionFilter-label { - vertical-align: center; - padding: 10px; - } + .collectionStackingViewChrome-sectionFilter-cont { + justify-self: right; + display: flex; + font-size: 75%; + text-transform: uppercase; + letter-spacing: 2px; - .collectionStackingViewChrome-sectionFilter { - color: white; - width: 100px; - text-align: center; - background: rgb(238, 238, 238); + .collectionStackingViewChrome-sectionFilter-label { + vertical-align: center; + padding: 10px; + } - .editable-view-input, - input, - .editableView-container-editing-oneLine, - .editableView-container-editing { - padding: 12px 10px 11px 10px; - border: 0px; - color: grey; + .collectionStackingViewChrome-sectionFilter { + color: white; + width: 100px; text-align: center; - text-transform: uppercase; - letter-spacing: 2px; - outline-color: black; - height: 100%; - } + background: rgb(238, 238, 238); - .react-autosuggest__container { - margin: 0; - color: grey; - padding: 0px; + .editable-view-input, + input, + .editableView-container-editing-oneLine, + .editableView-container-editing { + padding: 12px 10px 11px 10px; + border: 0px; + color: grey; + text-align: center; + text-transform: uppercase; + letter-spacing: 2px; + outline-color: black; + height: 100%; + } + + .react-autosuggest__container { + margin: 0; + color: grey; + padding: 0px; + } } } - } - .collectionStackingViewChrome-sectionFilter:hover { - cursor: text; + .collectionStackingViewChrome-sectionFilter:hover { + cursor: text; + } } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 24d13d5cb..4129781f7 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -47,6 +47,20 @@ export class CollectionViewBaseChrome extends React.Component { this._keyRestrictions.push([ runInAction(() => this._keyRestrictions[0][1] = value)} />, ""]); this._keyRestrictions.push([ runInAction(() => this._keyRestrictions[1][1] = value)} />, ""]); + + // chrome status is one of disabled, collapsed, or visible. this determines initial state from document + let chromeStatus = this.props.CollectionView.props.Document.chromeStatus; + if (chromeStatus) { + if (chromeStatus === "disabled") { + throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!"); + } + else if (chromeStatus === "collapsed") { + this._collapsed = true; + if (this.props.collapse) { + this.props.collapse(true); + } + } + } }); } @@ -130,11 +144,12 @@ export class CollectionViewBaseChrome extends React.Component { this._collapsed = !this._collapsed; - this.props.collapse(this._collapsed); + if (this.props.collapse) { + this.props.collapse(this._collapsed); + } } subChrome = () => { - switch (this.props.type) { case CollectionViewType.Stacking: return ( -
- - -
- -
- {this._keyRestrictions.map(i => i[0])} -
-
- CREATED WITHIN: -
- - +
+
+
+ + +
+ +
+ {this._keyRestrictions.map(i => i[0])} +
+
+ CREATED WITHIN:
-
-
+
+ - +
+ {this.subChrome()}
- {this.subChrome()}
) } diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 1c52a3f11..41eb1aa0c 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -50,6 +50,7 @@ export class CurrentUserUtils { if (doc.workspaces === undefined) { const workspaces = Docs.Create.TreeDocument([], { title: "Workspaces", height: 100 }); workspaces.excludeFromLibrary = true; + workspaces.chromeStatus = "disabled"; workspaces.workspaceLibrary = true; workspaces.boxShadow = "0 0"; doc.workspaces = workspaces; @@ -57,6 +58,7 @@ export class CurrentUserUtils { if (doc.recentlyClosed === undefined) { const recentlyClosed = Docs.Create.TreeDocument([], { title: "Recently Closed", height: 75 }); recentlyClosed.excludeFromLibrary = true; + recentlyClosed.chromeStatus = "disabled"; recentlyClosed.boxShadow = "0 0"; doc.recentlyClosed = recentlyClosed; } @@ -65,11 +67,13 @@ export class CurrentUserUtils { sidebar.excludeFromLibrary = true; sidebar.gridGap = 5; sidebar.xMargin = 5; + sidebar.chromeStatus = "disabled"; sidebar.yMargin = 5; Doc.GetProto(sidebar).backgroundColor = "#aca3a6"; sidebar.boxShadow = "1 1 3"; doc.sidebar = sidebar; } + doc.chromeStatus = "disabled"; StrCast(doc.title).indexOf("@") !== -1 && (doc.title = StrCast(doc.title).split("@")[0] + "'s Library"); } -- cgit v1.2.3-70-g09d2 From 1bedf9e23afe26a284ba4804672ad4f396402813 Mon Sep 17 00:00:00 2001 From: Fawn Date: Thu, 25 Jul 2019 19:44:40 -0400 Subject: merge --- src/client/views/collections/CollectionSchemaCells.tsx | 4 ++-- src/client/views/collections/CollectionSchemaView.scss | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index d453fed47..4a618a436 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -158,8 +158,8 @@ export class CollectionSchemaCell extends React.Component { if (this.props.isFocused && !this.props.isEditable) className += " inactive"; return ( -
-
+
+
Date: Sat, 27 Jul 2019 17:03:20 -0400 Subject: schema headers changed to schemaheaderfields, a bug with udpating the headers (in CollectionSchemaView>ChangeColumn) --- src/client/documents/Documents.ts | 13 +-- src/client/util/DragManager.ts | 5 +- src/client/views/MainView.tsx | 3 +- .../views/collections/CollectionSchemaCells.tsx | 30 +++++- .../views/collections/CollectionSchemaHeaders.tsx | 9 +- .../CollectionSchemaMovableTableHOC.tsx | 7 +- .../views/collections/CollectionSchemaView.scss | 15 +++ .../views/collections/CollectionSchemaView.tsx | 103 +++++++++++++-------- .../views/collections/CollectionStackingView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 3 +- src/client/views/nodes/LinkEditor.tsx | 3 +- src/client/views/nodes/LinkMenuGroup.tsx | 3 +- src/new_fields/SchemaHeaderField.ts | 55 +++++++++-- 13 files changed, 186 insertions(+), 65 deletions(-) (limited to 'src/client/views/collections/CollectionSchemaView.scss') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 76ac34d85..e6fe1b8b3 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -39,6 +39,7 @@ import { DocumentManager } from "../util/DocumentManager"; import DirectoryImportBox from "../util/Import & Export/DirectoryImportBox"; import { Scripting } from "../util/Scripting"; import { ButtonBox } from "../views/nodes/ButtonBox"; +import { SchemaHeaderField, RandomPastel } from "../../new_fields/SchemaHeaderField"; var requestImageSize = require('../util/request-image-size'); var path = require('path'); @@ -84,7 +85,7 @@ export interface DocumentOptions { curPage?: number; documentText?: string; borderRounding?: string; - schemaColumns?: List; + schemaColumns?: List; dockingConfig?: string; dbDoc?: Doc; // [key: string]: Opt; @@ -403,23 +404,23 @@ export namespace Docs { } export function FreeformDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Freeform }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Freeform }); } - export function SchemaDocument(schemaColumns: string[], documents: Array, options: DocumentOptions) { + export function SchemaDocument(schemaColumns: SchemaHeaderField[], documents: Array, options: DocumentOptions) { return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(schemaColumns), ...options, viewType: CollectionViewType.Schema }); } export function TreeDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Tree }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Tree }); } export function StackingDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Stacking }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Stacking }); } export function MasonryDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List(["title"]), ...options, viewType: CollectionViewType.Masonry }); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { schemaColumns: new List([new SchemaHeaderField("title")]), ...options, viewType: CollectionViewType.Masonry }); } export function ButtonDocument(options?: DocumentOptions) { diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 0299b1d90..47d3c313d 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -8,6 +8,7 @@ import * as globalCssVariables from "../views/globalCssVariables.scss"; import { DocumentManager } from "./DocumentManager"; import { LinkManager } from "./LinkManager"; import { SelectionManager } from "./SelectionManager"; +import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField"; export type dropActionType = "alias" | "copy" | undefined; export function SetupDrag( @@ -290,10 +291,10 @@ export namespace DragManager { // for column dragging in schema view export class ColumnDragData { - constructor(colKey: string) { + constructor(colKey: SchemaHeaderField) { this.colKey = colKey; } - colKey: string; + colKey: SchemaHeaderField; [id: string]: any; } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 0e04b5e7e..282db244e 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -39,6 +39,7 @@ import { PreviewCursor } from './PreviewCursor'; import { FilterBox } from './search/FilterBox'; import { CollectionTreeView } from './collections/CollectionTreeView'; import { ClientUtils } from '../util/ClientUtils'; +import { SchemaHeaderField, RandomPastel } from '../../new_fields/SchemaHeaderField'; @observer export class MainView extends React.Component { @@ -375,7 +376,7 @@ export class MainView extends React.Component { let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg"; // let addDockingNode = action(() => Docs.Create.StandardCollectionDockingDocument([{ doc: addColNode(), initialWidth: 200 }], { width: 200, height: 200, title: "a nested docking freeform collection" })); - let addSchemaNode = action(() => Docs.Create.SchemaDocument(["title"], [], { width: 200, height: 200, title: "a schema collection" })); + let addSchemaNode = action(() => Docs.Create.SchemaDocument([new SchemaHeaderField("title")], [], { width: 200, height: 200, title: "a schema collection" })); //let addTreeNode = action(() => Docs.TreeDocument([CurrentUserUtils.UserDocument], { width: 250, height: 400, title: "Library:" + CurrentUserUtils.email, dropAction: "alias" })); // let addTreeNode = action(() => Docs.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas", dropAction: "copy" })); let addColNode = action(() => Docs.Create.FreeformDocument([], { width: this.pwidth * .7, height: this.pheight, title: "a freeform collection" })); diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 4a618a436..c91f1017b 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -21,7 +21,12 @@ import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../new_field import { Docs } from "../../documents/Documents"; import { DocumentContentsView } from "../nodes/DocumentContentsView"; import { SelectionManager } from "../../util/SelectionManager"; +import { library } from '@fortawesome/fontawesome-svg-core'; +import { faExpand } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField"; +library.add(faExpand); export interface CellProps { row: number; @@ -38,6 +43,7 @@ export interface CellProps { changeFocusedCellByIndex: (row: number, col: number) => void; setIsEditing: (isEditing: boolean) => void; isEditable: boolean; + setPreviewDoc: (doc: Doc) => void; } @observer @@ -92,7 +98,7 @@ export class CollectionSchemaCell extends React.Component { this._document[fieldKey] = de.data.draggedDocuments[0]; } else { - let coll = Docs.Create.SchemaDocument(["title"], de.data.draggedDocuments, {}); + let coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title")], de.data.draggedDocuments, {}); this._document[fieldKey] = coll; } e.stopPropagation(); @@ -106,6 +112,18 @@ export class CollectionSchemaCell extends React.Component { } } + expandDoc = (e: React.PointerEvent) => { + let field = this.props.rowProps.original[this.props.rowProps.column.id as string]; + let doc = FieldValue(Cast(field, Doc)); + + console.log("Expanding doc", StrCast(doc!.title)); + this.props.setPreviewDoc(doc!); + + // this.props.changeFocusedCellByIndex(this.props.row, this.props.col); + + e.stopPropagation(); + } + renderCellWithType(type: string | undefined) { let dragRef: React.RefObject = React.createRef(); @@ -157,6 +175,15 @@ export class CollectionSchemaCell extends React.Component { if (this.props.isFocused && this.props.isEditable) className += " focused"; if (this.props.isFocused && !this.props.isEditable) className += " inactive"; + let doc = FieldValue(Cast(field, Doc)); + if (type === "document") console.log("doc", typeof field); + let fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc); + let docExpander = ( +
+ +
+ ); + return (
@@ -193,6 +220,7 @@ export class CollectionSchemaCell extends React.Component { val && val.forEach(doc => this.applyToDoc(doc, run)); }} />
+ {fieldIsDoc ? docExpander : null}
); diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx index d1d0674c4..9fc28eafa 100644 --- a/src/client/views/collections/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/CollectionSchemaHeaders.tsx @@ -10,11 +10,12 @@ import { ColumnType } from "./CollectionSchemaView"; import { emptyFunction } from "../../../Utils"; import { contains } from "typescript-collections/dist/lib/arrays"; import { faFile } from "@fortawesome/free-regular-svg-icons"; +import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faFile); export interface HeaderProps { - keyValue: string; + keyValue: SchemaHeaderField; possibleKeys: string[]; existingKeys: string[]; keyType: ColumnType; @@ -33,14 +34,14 @@ export class CollectionSchemaHeader extends React.Component { this.props.keyType === ColumnType.Boolean ? "check-square" : this.props.keyType === ColumnType.Doc ? "file" : "align-justify"; return ( -
+
{this.props.keyValue}
} + menuButtonContent={
{this.props.keyValue.heading}
} addNew={false} onSelect={this.props.onSelect} setIsEditing={this.props.setIsEditing} diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 0ddd56180..2349e42ca 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -12,14 +12,15 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faGripVertical, faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { DocumentManager } from "../../util/DocumentManager"; +import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; library.add(faGripVertical, faTrash); export interface MovableColumnProps { columnRenderer: TableCellRenderer; - columnValue: string; - allColumns: string[]; - reorderColumns: (toMove: string, relativeTo: string, before: boolean, columns: string[]) => void; + columnValue: SchemaHeaderField; + allColumns: SchemaHeaderField[]; + reorderColumns: (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columns: SchemaHeaderField[]) => void; ScreenToLocalTransform: () => Transform; } export class MovableColumn extends React.Component { diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 91c6e8b3c..e0de76247 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -379,6 +379,7 @@ button.add-column { .collectionSchemaView-cellWrapper { height: 100%; padding: 4px; + position: relative; &:focus { outline: none; @@ -405,6 +406,20 @@ button.add-column { height: 100%; // word-wrap: break-word; } + + &:hover .collectionSchemaView-cellContents-docExpander { + display: block; + } +} + +.collectionSchemaView-cellContents-docExpander { + height: 30px; + width: 30px; + display: none; + position: absolute; + top: 0; + right: 0; + background-color: lightgray; } .doc-drag-over { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index c6550560a..176872503 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -38,6 +38,7 @@ import { SelectionManager } from "../../util/SelectionManager"; import { DocumentManager } from "../../util/DocumentManager"; import { ImageBox } from "../nodes/ImageBox"; import { ComputedField } from "../../../new_fields/ScriptField"; +import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField"; library.add(faCog, faPlus, faSortUp, faSortDown); @@ -284,11 +285,13 @@ export class SchemaTable extends React.Component { @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); } @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; } @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); } - @computed get columns() { return Cast(this.props.Document.schemaColumns, listSpec("string"), []); } - set columns(columns: string[]) { this.props.Document.schemaColumns = new List(columns); } + @computed get columns() { + return Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField), []); + } + set columns(columns: SchemaHeaderField[]) { this.props.Document.schemaColumns = new List(columns); } @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); } @computed get tableColumns(): Column[] { - let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.toUpperCase() === key.toUpperCase()) === -1); + let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1); let columns: Column[] = []; let tableIsFocused = this.props.isFocused(this.props.Document); let focusedRow = this._focusedCell.row; @@ -321,9 +324,9 @@ export class SchemaTable extends React.Component { let header = c.heading)} keyType={this.getColumnType(col)} - typeConst={columnTypes.get(col) !== undefined} + typeConst={col.type !== undefined || columnTypes.get(col.heading) !== undefined} onSelect={this.changeColumns} setIsEditing={this.setHeaderIsEditing} deleteColumn={this.deleteColumn} @@ -334,16 +337,16 @@ export class SchemaTable extends React.Component { return { Header: , - accessor: (doc: Doc) => doc ? doc[col] : 0, - id: col, + accessor: (doc: Doc) => doc ? doc[col.heading] : 0, + id: col.heading, Cell: (rowProps: CellInfo) => { - let row = rowProps.index; - let column = this.columns.indexOf(rowProps.column.id!); - let isFocused = focusedRow === row && focusedCol === column && tableIsFocused; + let rowIndex = rowProps.index; + let columnIndex = this.columns.map(c => c.heading).indexOf(rowProps.column.id!); + let isFocused = focusedRow === rowIndex && focusedCol === columnIndex && tableIsFocused; let props: CellProps = { - row: row, - col: column, + row: rowIndex, + col: columnIndex, rowProps: rowProps, isFocused: isFocused, changeFocusedCellByIndex: this.changeFocusedCellByIndex, @@ -356,6 +359,7 @@ export class SchemaTable extends React.Component { moveDocument: this.props.moveDocument, setIsEditing: this.setCellIsEditing, isEditable: isEditable, + setPreviewDoc: this.props.setPreviewDoc }; let colType = this.getColumnType(col); @@ -394,6 +398,15 @@ export class SchemaTable extends React.Component { // } // return this.props.Document; // } + constructor(props: SchemaTableProps) { + super(props); + // convert old schema columns (list of strings) into new schema columns (list of schema header fields) + let oldSchemaColumns = Cast(this.props.Document.schemaColumns, listSpec("string"), []); + if (oldSchemaColumns && oldSchemaColumns.length) { + let newSchemaColumns = oldSchemaColumns.map(i => typeof i === "string" ? new SchemaHeaderField(i) : i); + this.props.Document.schemaColumns = new List(newSchemaColumns); + } + } componentDidMount() { document.addEventListener("keydown", this.onKeyDown); @@ -440,7 +453,7 @@ export class SchemaTable extends React.Component { let row = rowInfo.index; //@ts-ignore - let col = this.columns.indexOf(column!.id); + let col = this.columns.map(c => c.heading).indexOf(column!.id); // let col = column ? this.columns.indexOf(column!) : -1; let isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document); // let column = this.columns.indexOf(column.id!); @@ -502,6 +515,11 @@ export class SchemaTable extends React.Component { if (!this._cellIsEditing && !this._headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected()) { let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : ""; this.changeFocusedCellByDirection(direction); + + let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document; + let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []); + const pdoc = FieldValue(children[this._focusedCell.row]); + pdoc && this.props.setPreviewDoc(pdoc); } } @@ -532,8 +550,8 @@ export class SchemaTable extends React.Component { this._focusedCell = { row: this._focusedCell.row + 1 === children.length ? this._focusedCell.row : this._focusedCell.row + 1, col: this._focusedCell.col }; break; } - const pdoc = FieldValue(children[this._focusedCell.row]); - pdoc && this.props.setPreviewDoc(pdoc); + // const pdoc = FieldValue(children[this._focusedCell.row]); + // pdoc && this.props.setPreviewDoc(pdoc); } @action @@ -544,8 +562,8 @@ export class SchemaTable extends React.Component { this._focusedCell = { row: row, col: col }; this.props.setFocused(this.props.Document); - const fdoc = FieldValue(children[this._focusedCell.row]); - fdoc && this.props.setPreviewDoc(fdoc); + // const fdoc = FieldValue(children[this._focusedCell.row]); + // fdoc && this.props.setPreviewDoc(fdoc); } createRow = () => { @@ -561,25 +579,25 @@ export class SchemaTable extends React.Component { @action createColumn = () => { let index = 0; - let found = this.columns.findIndex(col => col.toUpperCase() === "New field".toUpperCase()) > -1; + let found = this.columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1; if (!found) { - this.columns.push("New field"); + this.columns.push(new SchemaHeaderField("New field")); return; } while (found) { index++; - found = this.columns.findIndex(col => col.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1; + found = this.columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1; } - this.columns.push("New field (" + index + ")"); + this.columns.push(new SchemaHeaderField("New field (" + index + ")")); } @action deleteColumn = (key: string) => { - let list = Cast(this.props.Document.schemaColumns, listSpec("string")); + let list = Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField)); if (list === undefined) { - this.props.Document.schemaColumns = list = new List([]); + this.props.Document.schemaColumns = list = new List([]); } else { - const index = list.indexOf(key); + const index = list.map(c => c.heading).indexOf(key); if (index > -1) { list.splice(index, 1); } @@ -588,26 +606,37 @@ export class SchemaTable extends React.Component { @action changeColumns = (oldKey: string, newKey: string, addNew: boolean) => { - let list = Cast(this.props.Document.schemaColumns, listSpec("string")); + let list = Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField)); if (list === undefined) { - this.props.Document.schemaColumns = list = new List([newKey]); + this.props.Document.schemaColumns = list = new List([new SchemaHeaderField(newKey)]); } else { if (addNew) { - this.columns.push(newKey); + this.columns.push(new SchemaHeaderField(newKey)); } else { - const index = list.indexOf(oldKey); + const index = list.map(c => c.heading).indexOf(oldKey); if (index > -1) { - list[index] = newKey; + list[index] = new SchemaHeaderField(newKey); } } } } - getColumnType = (key: string): ColumnType => { - if (columnTypes.get(key)) return columnTypes.get(key)!; + getColumnType = (column: SchemaHeaderField): ColumnType => { + // added functionality to convert old column type stuff to new column type stuff -syip + if (column.type && column.type !== 0) { + return column.type; + } + if (columnTypes.get(column.heading)) { + column.type = columnTypes.get(column.heading)!; + return columnTypes.get(column.heading)!; + } const typesDoc = FieldValue(Cast(this.props.Document.schemaColumnTypes, Doc)); - if (!typesDoc) return ColumnType.Any; - return NumCast(typesDoc[key]); + if (!typesDoc) { + column.type = ColumnType.Any; + return ColumnType.Any; + } + column.type = NumCast(typesDoc[column.heading]); + return NumCast(typesDoc[column.heading]); } setColumnType = (key: string, type: ColumnType): void => { @@ -624,11 +653,11 @@ export class SchemaTable extends React.Component { } @action - setColumns = (columns: string[]) => { + setColumns = (columns: SchemaHeaderField[]) => { this.columns = columns; } - reorderColumns = (toMove: string, relativeTo: string, before: boolean, columnsValues: string[]) => { + reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => { let columns = [...columnsValues]; let oldIndex = columns.indexOf(toMove); let relIndex = columns.indexOf(relativeTo); @@ -661,7 +690,7 @@ export class SchemaTable extends React.Component { //TODO Types untracked(() => docs.map(doc => Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false)))); - this.columns.forEach(key => keys[key] = true); + this.columns.forEach(key => keys[key.heading] = true); return Array.from(Object.keys(keys)); } @@ -727,7 +756,7 @@ export class SchemaTable extends React.Component { csv = csv.substr(0, csv.length - 1) + "\n"; let self = this; DocListCast(this.props.Document.data).map(doc => { - csv += self.columns.reduce((val, col) => val + (doc[col] ? doc[col]!.toString() : "0") + ",", ""); + csv += self.columns.reduce((val, col) => val + (doc[col.heading] ? doc[col.heading]!.toString() : "0") + ",", ""); csv = csv.substr(0, csv.length - 1) + "\n"; }); csv.substring(0, csv.length - 1); diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 7677f53c1..e897c5676 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -16,7 +16,7 @@ import { Transform } from "../../util/Transform"; import { CursorProperty } from "csstype"; import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn"; import { listSpec } from "../../../new_fields/Schema"; -import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; +import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField"; import { List } from "../../../new_fields/List"; import { EditableView } from "../EditableView"; import { CollectionViewProps } from "./CollectionBaseView"; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index b765517a2..2e54a9736 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -19,6 +19,7 @@ import { CollectionViewType } from "../CollectionBaseView"; import { CollectionFreeFormView } from "./CollectionFreeFormView"; import "./MarqueeView.scss"; import React = require("react"); +import { SchemaHeaderField, RandomPastel } from "../../../../new_fields/SchemaHeaderField"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -134,7 +135,7 @@ export class MarqueeView extends React.Component doc.width = 200; docList.push(doc); } - let newCol = Docs.Create.SchemaDocument([...(groupAttr ? ["_group"] : []), ...columns.filter(c => c)], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 }); + let newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 }); this.props.addDocument(newCol, false); } diff --git a/src/client/views/nodes/LinkEditor.tsx b/src/client/views/nodes/LinkEditor.tsx index afde85b69..0ea948c81 100644 --- a/src/client/views/nodes/LinkEditor.tsx +++ b/src/client/views/nodes/LinkEditor.tsx @@ -11,6 +11,7 @@ import { faArrowLeft, faEllipsisV, faTable, faTrash, faCog, faExchangeAlt, faTim import { library } from "@fortawesome/fontawesome-svg-core"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { SetupDrag } from "../../util/DragManager"; +import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField"; library.add(faArrowLeft, faEllipsisV, faTable, faTrash, faCog, faExchangeAlt, faTimes, faPlus); @@ -289,7 +290,7 @@ export class LinkGroupEditor extends React.Component { let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType); let index = keys.indexOf(""); if (index > -1) keys.splice(index, 1); - let cols = ["anchor1", "anchor2", ...[...keys]]; + let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c)); let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType); let createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" })); let ref = React.createRef(); diff --git a/src/client/views/nodes/LinkMenuGroup.tsx b/src/client/views/nodes/LinkMenuGroup.tsx index ae97bed2f..3637807ad 100644 --- a/src/client/views/nodes/LinkMenuGroup.tsx +++ b/src/client/views/nodes/LinkMenuGroup.tsx @@ -14,6 +14,7 @@ import { Docs } from "../../documents/Documents"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { UndoManager } from "../../util/UndoManager"; import { StrCast } from "../../../new_fields/Types"; +import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeaderField"; interface LinkMenuGroupProps { sourceDoc: Doc; @@ -70,7 +71,7 @@ export class LinkMenuGroup extends React.Component { let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType); let index = keys.indexOf(""); if (index > -1) keys.splice(index, 1); - let cols = ["anchor1", "anchor2", ...[...keys]]; + let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c)); let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType); let createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" })); let ref = React.createRef(); diff --git a/src/new_fields/SchemaHeaderField.ts b/src/new_fields/SchemaHeaderField.ts index 284de3023..a6df31e81 100644 --- a/src/new_fields/SchemaHeaderField.ts +++ b/src/new_fields/SchemaHeaderField.ts @@ -3,13 +3,42 @@ import { serializable, createSimpleSchema, primitive } from "serializr"; import { ObjectField } from "./ObjectField"; import { Copy, ToScriptString, OnUpdate } from "./FieldSymbols"; import { scriptingGlobal, Scripting } from "../client/util/Scripting"; +import { ColumnType } from "../client/views/collections/CollectionSchemaView"; export const PastelSchemaPalette = new Map([ - ["purple", "#f5b5fc"], - ["green", "#96F7D2"], - ["yellow", "#F0F696"], - ["red", "#FCB1B1"] -]) + ["pink1", "#FFB4E8"], + ["pink2", "#ff9cee"], + ["pink3", "#ffccf9"], + ["pink4", "#fcc2ff"], + ["pink5", "#f6a6ff"], + ["purple1", "#b28dff"], + ["purple2", "#c5a3ff"], + ["purple3", "#d5aaff"], + ["purple4", "#ecd4ff"], + ["purple5", "#fb34ff"], + ["purple6", "#dcd3ff"], + ["purple7", "#a79aff"], + ["purple8", "#b5b9ff"], + ["purple9", "#97a2ff"], + ["bluegreen1", "#afcbff"], + ["bluegreen2", "#aff8db"], + ["bluegreen3", "#c4faf8"], + ["bluegreen4", "#85e3ff"], + ["bluegreen5", "#ace7ff"], + ["bluegreen6", "#6eb5ff"], + ["bluegreen7", "#bffcc6"], + ["bluegreen8", "#dbffd6"], + ["yellow1", "#f3ffe3"], + ["yellow2", "#e7ffac"], + ["yellow3", "#ffffd1"], + ["yellow4", "#fff5ba"], + ["red1", "#ffc9de"], + ["red2", "#ffabab"], + ["red3", "#ffbebc"], + ["red4", "#ffcbc1"], +]); + +export const RandomPastel = () => Array.from(PastelSchemaPalette.values())[Math.floor(Math.random() * PastelSchemaPalette.size)]; @scriptingGlobal @Deserializable("schemaheader") @@ -17,12 +46,19 @@ export class SchemaHeaderField extends ObjectField { @serializable(primitive()) heading: string; color: string; + type: number; - constructor(heading: string = "", color: string = Array.from(PastelSchemaPalette.values())[Math.floor(Math.random() * 4)]) { + constructor(heading: string = "", color: string = RandomPastel(), type?: ColumnType) { super(); this.heading = heading; this.color = color; + if (type) { + this.type = type; + } + else { + this.type = 0; + } } setHeading(heading: string) { @@ -35,8 +71,13 @@ export class SchemaHeaderField extends ObjectField { this[OnUpdate](); } + setType(type: ColumnType) { + this.type = type; + this[OnUpdate](); + } + [Copy]() { - return new SchemaHeaderField(this.heading, this.color); + return new SchemaHeaderField(this.heading, this.color, this.type); } [ToScriptString]() { -- cgit v1.2.3-70-g09d2