aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionSchemaHeaders.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/CollectionSchemaHeaders.tsx')
-rw-r--r--src/client/views/collections/CollectionSchemaHeaders.tsx153
1 files changed, 95 insertions, 58 deletions
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<HeaderProps> {
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 (
<div className="collectionSchemaView-header" >
@@ -67,7 +67,7 @@ export class CollectionSchemaAddColumnHeader extends React.Component<AddColumnHe
// }
render() {
- let addButton = <button onClick={() => console.log("add clicked")}><FontAwesomeIcon icon="plus" size="sm" /></button>;
+ let addButton = <button><FontAwesomeIcon icon="plus" size="sm" /></button>;
return (
<div className="collectionSchemaView-header-addColumn" >
{/* {this._creatingColumn ? <></> : */}
@@ -76,6 +76,7 @@ export class CollectionSchemaAddColumnHeader extends React.Component<AddColumnHe
possibleKeys={this.props.possibleKeys}
existingKeys={this.props.existingKeys}
keyType={ColumnType.Any}
+ typeConst={true}
menuButtonContent={addButton}
addNew={true}
onSelect={this.props.onSelect}
@@ -120,68 +121,74 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
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 (
+ <div className="collectionSchema-headerMenu-group">
+ <label>Column type:</label>
+ <div className="columnMenu-types">
+ <button title="Any" className={this.props.keyType === ColumnType.Any ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.Any)}>
+ <FontAwesomeIcon icon={"align-justify"} size="sm" />
+ </button>
+ <button title="Number" className={this.props.keyType === ColumnType.Number ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.Number)}>
+ <FontAwesomeIcon icon={"hashtag"} size="sm" />
+ </button>
+ <button title="String" className={this.props.keyType === ColumnType.String ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.String)}>
+ <FontAwesomeIcon icon={"font"} size="sm" />
+ </button>
+ <button title="Boolean" className={this.props.keyType === ColumnType.Boolean ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.Boolean)}>
+ <FontAwesomeIcon icon={"toggle-on"} size="sm" />
+ </button>
+ <button title="Checkbox" className={this.props.keyType === ColumnType.Checkbox ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.Checkbox)}>
+ <FontAwesomeIcon icon={"check-square"} size="sm" />
+ </button>
+ </div>
+ </div>
+ );
+ }
- if (this._isOpen) {
- if (this.props.onlyShowOptions) {
- return (
- <div className="collectionSchema-header-menuOptions">
- <KeysDropdown
- keyValue={this.props.keyValue}
- possibleKeys={this.props.possibleKeys}
- existingKeys={this.props.existingKeys}
- canAddNew={true}
- addNew={this.props.addNew}
- onSelect={this.props.onSelect}
- />
- </div>
- );
- } else {
- return (
- <div className="collectionSchema-header-menuOptions">
- <KeysDropdown
- keyValue={this.props.keyValue}
- possibleKeys={this.props.possibleKeys}
- existingKeys={this.props.existingKeys}
- canAddNew={true}
- addNew={this.props.addNew}
- onSelect={this.props.onSelect}
- />
- {!this.props.typeConst ?
- <KeysDropdown
- keyValue={keyTypeStr}
- possibleKeys={colTypes}
- existingKeys={[]}
- canAddNew={false}
- addNew={false}
- onSelect={this.setColumnType}
- />
- : null}
+ renderContent = () => {
+ return (
+ <div className="collectionSchema-header-menuOptions">
+ <label>Key:</label>
+ <div className="collectionSchema-headerMenu-group">
+ <KeysDropdown
+ keyValue={this.props.keyValue}
+ possibleKeys={this.props.possibleKeys}
+ existingKeys={this.props.existingKeys}
+ canAddNew={true}
+ addNew={this.props.addNew}
+ onSelect={this.props.onSelect}
+ />
+ </div>
+ {this.props.onlyShowOptions ? <></> :
+ <>
+ {this.renderTypes()}
+ <div className="collectionSchema-headerMenu-group">
<button onClick={() => this.props.deleteColumn(this.props.keyValue)}>Delete Column</button>
</div>
- );
- }
- }
+ </>
+ }
+ </div>
+ );
}
render() {
return (
- // <Flyout anchorPoint={anchorPoints.TOP} content={<div style={{ color: "black" }}>{this.renderContent()}</div>}>
- // <div onClick={() => { this.props.setIsEditing(true); console.log("clicked anchor"); }}>{this.props.menuButton}</div>
- // </ Flyout >
<div className="collectionSchema-header-menu">
- <div className="collectionSchema-header-toggler" onClick={() => this.toggleIsOpen()}>{this.props.menuButtonContent}</div>
- {this.renderContent()}
+ <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderContent()}>
+ <div className="collectionSchema-header-toggler" onClick={() => { this.props.setIsEditing(true); }}>{this.props.menuButtonContent}</div>
+ </ Flyout >
</div>
);
}
}
+{/* // <div className="collectionSchema-header-menu">
+ // <div className="collectionSchema-header-toggler" onClick={() => this.toggleIsOpen()}>{this.props.menuButtonContent}</div>
+ // {this.renderContent()}
+ // </div> */}
+
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<KeysDropdownProps> {
@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<KeysDropdownProps> {
// 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(<div key={""} className="key-option"
- onClick={() => { this.onSelect(this._searchTerm); this.setSearchTerm(""); }}>Create "{this._searchTerm}" key</div>);
+ onClick={() => { this.onSelect(this._searchTerm); this.setSearchTerm(""); }}>
+ Create "{this._searchTerm}" key</div>);
}
return options;
@@ -231,9 +268,9 @@ class KeysDropdown extends React.Component<KeysDropdownProps> {
render() {
return (
<div className="keys-dropdown">
- <input type="text" value={this._searchTerm} placeholder="Search for or create a new key"
- onChange={e => this.onChange(e.target.value)} ></input>
- <div className="keys-options-wrapper">
+ <input className="keys-search" type="text" value={this._searchTerm} placeholder="Search for or create a new key"
+ onChange={e => this.onChange(e.target.value)} onFocus={this.onFocus} onBlur={this.onBlur}></input>
+ <div className="keys-options-wrapper" onPointerEnter={this.onPointerEnter} onPointerOut={this.onPointerOut}>
{this.renderOptions()}
</div>
</div >