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') 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