diff options
Diffstat (limited to 'src/client/views/FilterPanel.tsx')
-rw-r--r-- | src/client/views/FilterPanel.tsx | 170 |
1 files changed, 78 insertions, 92 deletions
diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index f3f447e22..8133a4d0d 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -1,34 +1,29 @@ /* eslint-disable react/jsx-props-no-spreading */ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Tooltip } from '@mui/material'; import { action, computed, makeObservable, observable, ObservableMap } from 'mobx'; -import { observer } from 'mobx-react'; +import { observer, useLocalObservable } from 'mobx-react'; import * as React from 'react'; +import { useEffect, useRef } from 'react'; import { Handles, Rail, Slider, Ticks, Tracks } from 'react-compound-slider'; import { AiOutlineMinusSquare, AiOutlinePlusSquare } from 'react-icons/ai'; import { CiCircleRemove } from 'react-icons/ci'; import { Doc, DocListCast, Field, FieldType, LinkedTo, StrListCast } from '../../fields/Doc'; +import { DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { List } from '../../fields/List'; import { RichTextField } from '../../fields/RichTextField'; +import { DocCast, StrCast } from '../../fields/Types'; +import { Button, CurrentUserUtils } from '../util/CurrentUserUtils'; import { SearchUtil } from '../util/SearchUtil'; import { SnappingManager } from '../util/SnappingManager'; -import { undoable, undoBatch } from '../util/UndoManager'; +import { undoable } from '../util/UndoManager'; import { FieldsDropdown } from './FieldsDropdown'; import './FilterPanel.scss'; import { DocumentView } from './nodes/DocumentView'; +import { ButtonType } from './nodes/FontIconBox/FontIconBox'; import { Handle, Tick, TooltipRail, Track } from './nodes/SliderBox-components'; import { ObservableReactComponent } from './ObservableReactComponent'; -import { Button } from '../util/CurrentUserUtils'; -import { ButtonType } from './nodes/FontIconBox/FontIconBox'; -import { DocCast } from '../../fields/Types'; -import { CurrentUserUtils } from '../util/CurrentUserUtils'; -import { StrCast } from '../../fields/Types'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { DocData } from '../../fields/DocSymbols'; -import { Tooltip } from '@mui/material'; -import { useLocalObservable } from 'mobx-react'; -import { useRef } from 'react'; -import { useEffect } from 'react'; - interface filterProps { Document: Doc; @@ -37,8 +32,7 @@ interface filterProps { @observer export class FilterPanel extends ObservableReactComponent<filterProps> { @observable _selectedFacetHeaders = new Set<string>(); - public static Instance: FilterPanel; - + public static Instance: FilterPanel; constructor(props: filterProps) { super(props); @@ -227,7 +221,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> { }; /** - * Allows users to add a filter hotkey to the properties panel. Will also update the multitoggle at the top menu and the + * Allows users to add a filter hotkey to the properties panel. Will also update the multitoggle at the top menu and the * icontags tht are displayed on the documents themselves * @param hotKey tite of the new hotkey */ @@ -246,21 +240,20 @@ export class FilterPanel extends ObservableReactComponent<filterProps> { scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}' }, }; - const currHotKeys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles) + const currHotKeys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles); - Doc.UserDoc().myFilterHotKeyTitles = new List<string>(currHotKeys.concat(hotKey)) + Doc.UserDoc().myFilterHotKeyTitles = new List<string>(currHotKeys.concat(hotKey)); - Doc.UserDoc()[hotKey] = 'bolt' + Doc.UserDoc()[hotKey] = 'bolt'; const newBtn = CurrentUserUtils.setupContextMenuBtn(newKey, filter); newBtn.isSystem = newBtn[DocData].isSystem = undefined; - const subDocs = DocListCast(filter.data) - const opts = subDocs[subDocs.length-1] + const subDocs = DocListCast(filter.data); + const opts = subDocs[subDocs.length - 1]; Doc.AddDocToList(filter, 'data', newBtn, opts, true); - } + }; - /** * Renders the newly formed hotkey icon buttons * @returns the buttons to be rendered @@ -268,16 +261,16 @@ export class FilterPanel extends ObservableReactComponent<filterProps> { hotKeyButtons = () => { const selected = DocumentView.SelectedDocs().lastElement(); const hotKeys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles); - + // Selecting a button should make it so that the icon on the top filter panel becomes said icon const buttons = hotKeys.map((hotKey, i) => ( <Tooltip key={hotKey} title={<div className="dash-tooltip">Click to customize this hotkey's icon</div>}> - <HotKeyIconButton hotKey={hotKey} selected = {selected}/> + <HotKeyIconButton hotKey={hotKey} selected={selected} /> </Tooltip> )); - + return buttons; - } + }; // @observable iconPanelMap: Map<string, number> = new Map(); @@ -465,18 +458,16 @@ export class FilterPanel extends ObservableReactComponent<filterProps> { } } - - interface HotKeyButtonProps { hotKey: string; - selected?: Doc + selected?: Doc; } /** - * Renders the buttons that correspond to each icon tag in the properties view. Allows users to change the icon, - * title, and delete. + * Renders the buttons that correspond to each icon tag in the properties view. Allows users to change the icon, + * title, and delete. */ -const HotKeyIconButton: React.FC<HotKeyButtonProps> = observer(({ hotKey, selected}) => { +const HotKeyIconButton: React.FC<HotKeyButtonProps> = observer(({ hotKey, selected }) => { const state = useLocalObservable(() => ({ isActive: false, isEditing: false, @@ -496,7 +487,7 @@ const HotKeyIconButton: React.FC<HotKeyButtonProps> = observer(({ hotKey, select }, setHotKey(newHotKey: string) { this.myHotKey = newHotKey; - } + }, })); const panelRef = useRef<HTMLDivElement>(null); @@ -506,31 +497,29 @@ const HotKeyIconButton: React.FC<HotKeyButtonProps> = observer(({ hotKey, select state.toggleActive(); }; - const hotKeys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles) + const hotKeys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles); const buttons = DocCast(Doc.UserDoc().myContextMenuBtns); const filter = DocCast(buttons.Filter); /** * The doc of the button in the context menu that corresponds to the current hotkey - * @returns + * @returns */ const myHotKeyDoc = () => { - const hotKeyDocs = DocListCast(filter.data) - return hotKeyDocs.filter(k => StrCast(k.title) === hotKey)[0] - - } + const hotKeyDocs = DocListCast(filter.data); + return hotKeyDocs.filter(k => StrCast(k.title) === hotKey)[0]; + }; /** - * Removes a hotkey from list + * Removes a hotkey from list */ const removeHotKey = () => { Doc.RemoveDocFromList(filter, 'data', myHotKeyDoc()); - - } + }; /** * Deselects if the user clicks outside the button - * @param event + * @param event */ const handleClickOutside = (event: MouseEvent) => { if (panelRef.current && !panelRef.current.contains(event.target as Node)) { @@ -538,24 +527,23 @@ const HotKeyIconButton: React.FC<HotKeyButtonProps> = observer(({ hotKey, select if (state.isEditing) { state.stopEditing(); - updateFromInput() + updateFromInput(); } } }; /** - * Updates the list of hotkeys based on the users input. replaces the old title with the new one and then assigns this new + * Updates the list of hotkeys based on the users input. replaces the old title with the new one and then assigns this new * hotkey with the current icon */ - const updateFromInput = undoable (() => { - const myDoc = myHotKeyDoc() - Doc.UserDoc().myFilterHotKeyTitles = new List<string>(hotKeys.map(k => k === hotKey ? state.myHotKey : k)); - Doc.UserDoc()[state.myHotKey] = StrCast(Doc.UserDoc()[hotKey]) - Doc.UserDoc()[hotKey] = '' - myDoc.title = state.myHotKey - myDoc.toolTip = `Click to toggle the ${state.myHotKey}'s group's visibility` - }, '') - + const updateFromInput = undoable(() => { + const myDoc = myHotKeyDoc(); + Doc.UserDoc().myFilterHotKeyTitles = new List<string>(hotKeys.map(k => (k === hotKey ? state.myHotKey : k))); + Doc.UserDoc()[state.myHotKey] = StrCast(Doc.UserDoc()[hotKey]); + Doc.UserDoc()[hotKey] = ''; + myDoc.title = state.myHotKey; + myDoc.toolTip = `Click to toggle the ${state.myHotKey}'s group's visibility`; + }, ''); useEffect(() => { document.addEventListener('mousedown', handleClickOutside); @@ -564,18 +552,21 @@ const HotKeyIconButton: React.FC<HotKeyButtonProps> = observer(({ hotKey, select }; }, []); - const iconOpts = ['star', 'heart', 'bolt', 'satellite', 'palette', 'robot', 'lightbulb', 'highlighter', 'book', 'chalkboard' ]; + const iconOpts = ['star', 'heart', 'bolt', 'satellite', 'palette', 'robot', 'lightbulb', 'highlighter', 'book', 'chalkboard']; /** * Panel of icons the user can choose from to represent their tag */ const iconPanel = iconOpts.map((icon, i) => ( - <button key={i} onClick={undoable((e: React.MouseEvent) => { - e.stopPropagation; - Doc.UserDoc()[hotKey] = icon; - myHotKeyDoc().icon = icon - }, '')} className='icon-panel-button'> - <FontAwesomeIcon icon={icon as any} color = {SnappingManager.userColor}/> + <button + key={i} + onClick={undoable((e: React.MouseEvent) => { + e.stopPropagation; + Doc.UserDoc()[hotKey] = icon; + myHotKeyDoc().icon = icon; + }, '')} + className="icon-panel-button"> + <FontAwesomeIcon icon={icon as any} color={SnappingManager.userColor} /> </button> )); @@ -584,62 +575,57 @@ const HotKeyIconButton: React.FC<HotKeyButtonProps> = observer(({ hotKey, select */ return ( - <div className={`filterHotKey-button`} - onClick={(e) => { + <div + className={`filterHotKey-button`} + onClick={e => { e.stopPropagation(); state.startEditing(); setTimeout(() => inputRef.current?.focus(), 0); - }} - > + }}> <div className={`hotKey-icon-button ${state.isActive ? 'active' : ''}`} ref={panelRef}> <Tooltip title={<div className="dash-tooltip">Click to customize this hotkey's icon</div>}> <button type="button" - className='hotKey-icon' + className="hotKey-icon" onClick={(e: React.MouseEvent) => { - e.stopPropagation(); + e.stopPropagation(); handleClick(); - }} - > - <FontAwesomeIcon icon={Doc.UserDoc()[hotKey] as any} size="2xl" color={SnappingManager.userColor}/> + }}> + <FontAwesomeIcon icon={Doc.UserDoc()[hotKey] as any} size="2xl" color={SnappingManager.userColor} /> </button> </Tooltip> - {state.isActive && ( - <div className="icon-panel"> - {iconPanel} - </div> - )} + {state.isActive && <div className="icon-panel">{iconPanel}</div>} </div> {state.isEditing ? ( <input ref={inputRef} type="text" value={state.myHotKey.toUpperCase()} - onChange={(e) => state.setHotKey(e.target.value)} + onChange={e => state.setHotKey(e.target.value)} onBlur={() => { state.stopEditing(); - updateFromInput() + updateFromInput(); }} - onKeyDown={(e) => { + onKeyDown={e => { if (e.key === 'Enter') { state.stopEditing(); - updateFromInput() - + updateFromInput(); } }} - className='hotkey-title-input' + className="hotkey-title-input" /> ) : ( - <p className='hotkey-title'>{hotKey.toUpperCase()}</p> + <p className="hotkey-title">{hotKey.toUpperCase()}</p> )} - <button className='hotKey-close' onClick={(e: React.MouseEvent) => { - e.stopPropagation(); - Doc.UserDoc().myFilterHotKeyTitles = new List<string>(hotKeys.filter(k => k !== hotKey)); - removeHotKey() - - }}> - <FontAwesomeIcon icon={'x' as any} color={SnappingManager.userColor}/> + <button + className="hotKey-close" + onClick={(e: React.MouseEvent) => { + e.stopPropagation(); + Doc.UserDoc().myFilterHotKeyTitles = new List<string>(hotKeys.filter(k => k !== hotKey)); + removeHotKey(); + }}> + <FontAwesomeIcon icon={'x' as any} color={SnappingManager.userColor} /> </button> </div> ); -})
\ No newline at end of file +}); |