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, 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, faToggleOn); export interface HeaderProps { keyValue: string; possibleKeys: string[]; existingKeys: string[]; keyType: ColumnType; typeConst: boolean; onSelect: (oldKey: string, newKey: string, addnew: boolean) => void; setIsEditing: (isEditing: boolean) => void; deleteColumn: (column: string) => void; setColumnType: (key: string, type: ColumnType) => void; } 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"; return (
{this.props.keyValue}
} addNew={false} onSelect={this.props.onSelect} setIsEditing={this.props.setIsEditing} deleteColumn={this.props.deleteColumn} onlyShowOptions={false} setColumnType={this.props.setColumnType} /> ); } } export interface AddColumnHeaderProps { possibleKeys: string[]; existingKeys: string[]; onSelect: (oldKey: string, newKey: string, addnew: boolean) => void; setIsEditing: (isEditing: boolean) => void; } @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 ? <> : */}
); } } export interface ColumnMenuProps { keyValue: string; possibleKeys: string[]; existingKeys: string[]; keyType: ColumnType; typeConst: boolean; menuButtonContent: JSX.Element; addNew: boolean; onSelect: (oldKey: string, newKey: string, addnew: boolean) => void; setIsEditing: (isEditing: boolean) => void; deleteColumn: (column: string) => void; onlyShowOptions: boolean; setColumnType: (key: string, type: ColumnType) => void; } @observer export class CollectionSchemaColumnMenu extends React.Component { @observable private _isOpen: boolean = false; @action toggleIsOpen = (): void => { this._isOpen = !this._isOpen; this.props.setIsEditing(this._isOpen); } setColumnType = (oldKey: string, newKey: string, addnew: boolean) => { let typeStr = newKey as keyof typeof ColumnType; let type = ColumnType[typeStr]; this.props.setColumnType(this.props.keyValue, type); } renderTypes = () => { if (this.props.typeConst) return <>; return (
); } renderContent = () => { return (
{this.props.onlyShowOptions ? <> : <> {this.renderTypes()}
}
); } render() { return (
{ this.props.setIsEditing(true); }}>{this.props.menuButtonContent}
); } } {/* //
//
this.toggleIsOpen()}>{this.props.menuButtonContent}
// {this.renderContent()} //
*/} interface KeysDropdownProps { keyValue: string; possibleKeys: string[]; existingKeys: string[]; 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; let options = keyOptions.map(key => { return
{ this.onSelect(key); this.setSearchTerm(""); }}>{key}
; }); // 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
); } return options; } render() { return (
this.onChange(e.target.value)} onFocus={this.onFocus} onBlur={this.onBlur}>
{this.renderOptions()}
); } }