aboutsummaryrefslogtreecommitdiff
path: root/src/client/views
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views')
-rw-r--r--src/client/views/DocumentButtonBar.tsx51
-rw-r--r--src/client/views/FilterPanel.tsx352
-rw-r--r--src/client/views/StyleProvider.tsx10
-rw-r--r--src/client/views/nodes/FieldView.tsx4
4 files changed, 201 insertions, 216 deletions
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index ccde1de80..87dd5f45a 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -298,16 +298,12 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
key={icon.toString()}
size="sm"
icon={icon}
- onClick={e => {
- if (name === 'tags'){
- (targetDoc && (targetDoc[DocData].showIconTags = !targetDoc[DocData].showIconTags))
+ onClick={() => {
+ if (name === 'tags') {
+ targetDoc && (targetDoc[DocData].showIconTags = !targetDoc[DocData].showIconTags);
} else {
- (targetDoc && (targetDoc[DocData].showLabels = !targetDoc[DocData].showLabels))
+ targetDoc && (targetDoc[DocData].showLabels = !targetDoc[DocData].showLabels);
}
-
-
-
-
}}
/>
</div>
@@ -315,31 +311,24 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
);
};
-
-
-
return !targetDoc ? null : (
- <div className='documentButtonBar-icon'>
- <div className="documentButtonBar-pinTypes" style = {{width: '40px'}}>
- {metaBtn('tags', 'star')}
- {metaBtn("keywords", 'id-card')}
- </div>
-
- <Tooltip title={<div className="dash-keyword-button">Open keyword menu</div>}>
- <div
- className="documentButtonBar-icon"
- style={{ color: 'white' }}
- onClick={() => {
- // targetDoc[DocData].showIconTags = !targetDoc[DocData].showIconTags;
- }}
- >
-
-
- <FontAwesomeIcon className="documentdecorations-icon" icon="tag" />
+ <div className="documentButtonBar-icon">
+ <div className="documentButtonBar-pinTypes" style={{ width: '40px' }}>
+ {metaBtn('tags', 'star')}
+ {metaBtn('keywords', 'id-card')}
</div>
- </Tooltip>
- </div>
+ <Tooltip title={<div className="dash-keyword-button">Open keyword menu</div>}>
+ <div
+ className="documentButtonBar-icon"
+ style={{ color: 'white' }}
+ onClick={() => {
+ // targetDoc[DocData].showIconTags = !targetDoc[DocData].showIconTags;
+ }}>
+ <FontAwesomeIcon className="documentdecorations-icon" icon="tag" />
+ </div>
+ </Tooltip>
+ </div>
);
}
@@ -519,4 +508,4 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
</div>
);
}
-} \ No newline at end of file
+}
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&apos;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&apos;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>
- );
-});
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 13fef101a..eb434db40 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -326,7 +326,6 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
type={Type.TERT}
dropdownType={DropdownType.CLICK}
fillWidth
- // eslint-disable-next-line react/no-unstable-nested-components
iconProvider={() => <div className='styleProvider-filterShift'><FaFilter/></div>}
closeOnSelect
setSelectedVal={((dvValue: unknown) => {
@@ -366,12 +365,9 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps &
</Tooltip>
);
};
- const tags = () => props?.DocumentView?.() ? <TagsView Views={[props.DocumentView()]}/> : null;
-
- const iconTags = () => {
- if (doc && doc![DocData].showIconTags)
- {return (<IconTagBox doc= {doc}></IconTagBox>)}
- }
+ const tags = () => docView?.() ? <TagsView Views={[docView?.()]}/> : null;
+ const iconTags = () => doc?.[DocData].showIconTags ? <IconTagBox doc= {doc}/> : null;
+
return (
<>
{paint()}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index c269c7bcb..683edba16 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable react/no-unused-prop-types */
-/* eslint-disable react/require-default-props */
import { Property } from 'csstype';
import { computed } from 'mobx';
import { observer } from 'mobx-react';
@@ -21,6 +19,7 @@ export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt<number>
// eslint-disable-next-line no-use-before-define
export type StyleProviderFuncType = (
doc: Opt<Doc>,
+ // eslint-disable-next-line no-use-before-define
props: Opt<FieldViewProps>,
property: string
) =>
@@ -65,6 +64,7 @@ export interface FieldViewSharedProps {
containerViewPath?: () => DocumentView[];
fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document
isGroupActive?: () => string | undefined; // is this document part of a group that is active
+ // eslint-disable-next-line no-use-before-define
setContentViewBox?: (view: ViewBoxInterface<FieldViewProps>) => void; // called by rendered field's viewBox so that DocumentView can make direct calls to the viewBox
PanelWidth: () => number;
PanelHeight: () => number;