diff options
author | bobzel <zzzman@gmail.com> | 2024-09-17 22:11:22 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2024-09-17 22:11:22 -0400 |
commit | 4e0ea65c08ff07429cb32f3907268206c80889fa (patch) | |
tree | feb04e318ba52bb41b22f3cb6f94f4b21c35b5a3 /src/client/views/FilterPanel.tsx | |
parent | 31321f6def982305ea89cdfe5a873b942060eb84 (diff) |
linted cardView files after merge.
Diffstat (limited to 'src/client/views/FilterPanel.tsx')
-rw-r--r-- | src/client/views/FilterPanel.tsx | 352 |
1 files changed, 176 insertions, 176 deletions
diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index 8133a4d0d..3795a4a6d 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -1,4 +1,3 @@ -/* 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'; @@ -24,14 +23,186 @@ 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 { IconProp } from '@fortawesome/fontawesome-svg-core'; +interface HotKeyButtonProps { + hotKey: string; + selected?: Doc; +} + +/** + * 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 state = useLocalObservable(() => ({ + isActive: false, + isEditing: false, + myHotKey: hotKey, + + toggleActive() { + this.isActive = !this.isActive; + }, + deactivate() { + this.isActive = false; + }, + startEditing() { + this.isEditing = true; + }, + stopEditing() { + this.isEditing = false; + }, + setHotKey(newHotKey: string) { + this.myHotKey = newHotKey; + }, + })); + + const panelRef = useRef<HTMLDivElement>(null); + const inputRef = useRef<HTMLInputElement>(null); + + const handleClick = () => { + state.toggleActive(); + }; + + 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 + */ + const myHotKeyDoc = () => { + const hotKeyDocs = DocListCast(filter.data); + return hotKeyDocs.filter(k => StrCast(k.title) === hotKey)[0]; + }; + + /** + * Removes a hotkey from list + */ + const removeHotKey = () => { + Doc.RemoveDocFromList(filter, 'data', myHotKeyDoc()); + }; + + /** + * 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`; + }, ''); + + /** + * Deselects if the user clicks outside the button + * @param event + */ + const handleClickOutside = (event: MouseEvent) => { + if (panelRef.current && !panelRef.current.contains(event.target as Node)) { + state.deactivate(); + if (state.isEditing) { + state.stopEditing(); + + updateFromInput(); + } + } + }; + + useEffect(() => { + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, []); + + const iconOpts = ['star', 'heart', 'bolt', 'satellite', 'palette', 'robot', 'lightbulb', 'highlighter', 'book', 'chalkboard'] as IconProp[]; + + /** + * 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.toString(); + myHotKeyDoc().icon = icon.toString(); + }, '')} + className="icon-panel-button"> + <FontAwesomeIcon icon={icon} color={SnappingManager.userColor} /> + </button> + )); + + /** + * Actually renders the buttons + */ + + return ( + <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" + onClick={(e: React.MouseEvent) => { + e.stopPropagation(); + handleClick(); + }}> + <FontAwesomeIcon icon={Doc.UserDoc()[hotKey] as IconProp} size="2xl" color={SnappingManager.userColor} /> + </button> + </Tooltip> + {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)} + onBlur={() => { + state.stopEditing(); + updateFromInput(); + }} + onKeyDown={e => { + if (e.key === 'Enter') { + state.stopEditing(); + updateFromInput(); + } + }} + className="hotkey-title-input" + /> + ) : ( + <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 IconProp} color={SnappingManager.userColor} /> + </button> + </div> + ); +}); interface filterProps { Document: Doc; } @observer export class FilterPanel extends ObservableReactComponent<filterProps> { - @observable _selectedFacetHeaders = new Set<string>(); + // eslint-disable-next-line no-use-before-define public static Instance: FilterPanel; constructor(props: filterProps) { @@ -40,6 +211,7 @@ export class FilterPanel extends ObservableReactComponent<filterProps> { FilterPanel.Instance = this; } + @observable _selectedFacetHeaders = new Set<string>(); /** * @returns the relevant doc according to the value of FilterBox._filterScope i.e. either the Current Dashboard or the Current Collection */ @@ -263,8 +435,8 @@ export class FilterPanel extends ObservableReactComponent<filterProps> { 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>}> + const buttons = hotKeys.map(hotKey => ( + <Tooltip key={hotKey} title={<div className="dash-tooltip">Click to customize this hotkey's icon</div>}> <HotKeyIconButton hotKey={hotKey} selected={selected} /> </Tooltip> )); @@ -457,175 +629,3 @@ export class FilterPanel extends ObservableReactComponent<filterProps> { return undefined; } } - -interface HotKeyButtonProps { - hotKey: string; - selected?: Doc; -} - -/** - * 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 state = useLocalObservable(() => ({ - isActive: false, - isEditing: false, - myHotKey: hotKey, - - toggleActive() { - this.isActive = !this.isActive; - }, - deactivate() { - this.isActive = false; - }, - startEditing() { - this.isEditing = true; - }, - stopEditing() { - this.isEditing = false; - }, - setHotKey(newHotKey: string) { - this.myHotKey = newHotKey; - }, - })); - - const panelRef = useRef<HTMLDivElement>(null); - const inputRef = useRef<HTMLInputElement>(null); - - const handleClick = () => { - state.toggleActive(); - }; - - 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 - */ - const myHotKeyDoc = () => { - const hotKeyDocs = DocListCast(filter.data); - return hotKeyDocs.filter(k => StrCast(k.title) === hotKey)[0]; - }; - - /** - * Removes a hotkey from list - */ - const removeHotKey = () => { - Doc.RemoveDocFromList(filter, 'data', myHotKeyDoc()); - }; - - /** - * Deselects if the user clicks outside the button - * @param event - */ - const handleClickOutside = (event: MouseEvent) => { - if (panelRef.current && !panelRef.current.contains(event.target as Node)) { - state.deactivate(); - if (state.isEditing) { - state.stopEditing(); - - updateFromInput(); - } - } - }; - - /** - * 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`; - }, ''); - - useEffect(() => { - document.addEventListener('mousedown', handleClickOutside); - return () => { - document.removeEventListener('mousedown', handleClickOutside); - }; - }, []); - - 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> - )); - - /** - * Actually renders the buttons - */ - - return ( - <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" - onClick={(e: React.MouseEvent) => { - e.stopPropagation(); - handleClick(); - }}> - <FontAwesomeIcon icon={Doc.UserDoc()[hotKey] as any} size="2xl" color={SnappingManager.userColor} /> - </button> - </Tooltip> - {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)} - onBlur={() => { - state.stopEditing(); - updateFromInput(); - }} - onKeyDown={e => { - if (e.key === 'Enter') { - state.stopEditing(); - updateFromInput(); - } - }} - className="hotkey-title-input" - /> - ) : ( - <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> - </div> - ); -}); |