aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections')
-rw-r--r--src/client/views/collections/CollectionCalendarView.tsx4
-rw-r--r--src/client/views/collections/CollectionCardDeckView.tsx13
-rw-r--r--src/client/views/collections/CollectionCarousel3DView.tsx11
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx19
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx73
-rw-r--r--src/client/views/collections/CollectionMasonryViewFieldRow.tsx20
-rw-r--r--src/client/views/collections/CollectionMenu.tsx75
-rw-r--r--src/client/views/collections/CollectionNoteTakingView.tsx29
-rw-r--r--src/client/views/collections/CollectionNoteTakingViewColumn.tsx15
-rw-r--r--src/client/views/collections/CollectionPileView.tsx10
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx27
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx41
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx11
-rw-r--r--src/client/views/collections/CollectionSubView.tsx25
-rw-r--r--src/client/views/collections/CollectionTimeView.tsx8
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx56
-rw-r--r--src/client/views/collections/CollectionView.tsx12
-rw-r--r--src/client/views/collections/TabDocView.tsx55
-rw-r--r--src/client/views/collections/TreeView.tsx108
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx12
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx20
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx177
-rw-r--r--src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx39
-rw-r--r--src/client/views/collections/collectionGrid/CollectionGridView.tsx6
-rw-r--r--src/client/views/collections/collectionLinear/CollectionLinearView.tsx9
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss69
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx109
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss49
-rw-r--r--src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx39
-rw-r--r--src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx2
-rw-r--r--src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx2
-rw-r--r--src/client/views/collections/collectionSchema/CollectionSchemaView.tsx58
-rw-r--r--src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx4
-rw-r--r--src/client/views/collections/collectionSchema/SchemaRowBox.tsx4
-rw-r--r--src/client/views/collections/collectionSchema/SchemaTableCell.tsx32
36 files changed, 615 insertions, 632 deletions
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx
index a08a7c7c1..9eb16917b 100644
--- a/src/client/views/collections/CollectionCalendarView.tsx
+++ b/src/client/views/collections/CollectionCalendarView.tsx
@@ -6,11 +6,11 @@ import { dateRangeStrToDates, returnTrue } from '../../../ClientUtils';
import { Doc, DocListCast } from '../../../fields/Doc';
import { StrCast } from '../../../fields/Types';
import { CollectionStackingView } from './CollectionStackingView';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
@observer
export class CollectionCalendarView extends CollectionSubView() {
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
index de46180e6..28a769896 100644
--- a/src/client/views/collections/CollectionCardDeckView.tsx
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -18,7 +18,7 @@ import { StyleProp } from '../StyleProp';
import { DocumentView } from '../nodes/DocumentView';
import { GPTPopup, GPTPopupMode } from '../pdf/GPTPopup/GPTPopup';
import './CollectionCardDeckView.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
enum cardSortings {
Time = 'time',
@@ -68,7 +68,7 @@ export class CollectionCardView extends CollectionSubView() {
}
};
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -86,11 +86,11 @@ export class CollectionCardView extends CollectionSubView() {
}
@computed get cardSort_customField() {
- return StrCast(this.Document.cardSort_customField) as any as 'chat' | 'star' | 'idea' | 'like';
+ return StrCast(this.Document.cardSort_customField) as 'chat' | 'star' | 'idea' | 'like';
}
@computed get cardSort() {
- return StrCast(this.Document.cardSort) as any as cardSortings;
+ return StrCast(this.Document.cardSort) as cardSortings;
}
/**
* how much to scale down the contents of the view so that everything will fit
@@ -428,7 +428,6 @@ export class CollectionCardView extends CollectionSubView() {
return (
<div className="card-button-container" style={{ width: `${totalWidth}px` }}>
{numberRange(amButtons).map(i => (
- // eslint-disable-next-line jsx-a11y/control-has-associated-label
<button
key={i}
type="button"
@@ -496,8 +495,8 @@ export class CollectionCardView extends CollectionSubView() {
className="collectionCardView-outer"
ref={this.createDashEventsTarget}
style={{
- background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor),
- color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color),
+ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
+ color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string,
}}>
<div
className="card-wrapper"
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index 27c85533f..c799eb3c8 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
@@ -15,8 +13,9 @@ import { StyleProp } from '../StyleProp';
import { DocumentView } from '../nodes/DocumentView';
import { FocusViewOptions } from '../nodes/FocusViewOptions';
import './CollectionCarousel3DView.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
+// eslint-disable-next-line @typescript-eslint/no-var-requires
const { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } = require('../global/globalCssVariables.module.scss');
@observer
@@ -24,7 +23,7 @@ export class CollectionCarousel3DView extends CollectionSubView() {
@computed get scrollSpeed() {
return this.layoutDoc._autoScrollSpeed ? NumCast(this.layoutDoc._autoScrollSpeed) : 1000; // default scroll speed
}
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -180,8 +179,8 @@ export class CollectionCarousel3DView extends CollectionSubView() {
className="collectionCarousel3DView-outer"
ref={this.createDashEventsTarget}
style={{
- background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor),
- color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color),
+ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
+ color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string,
}}>
<div className="carousel-wrapper" style={{ transform: `translateX(${this.translateX}px)` }}>
{this.content}
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index 2adad68e0..4bec2d963 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable react/jsx-props-no-spreading */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { computed, makeObservable } from 'mobx';
@@ -12,13 +10,12 @@ import { DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { DocumentType } from '../../documents/DocumentTypes';
import { DragManager } from '../../util/DragManager';
import { ContextMenu } from '../ContextMenu';
-import { ContextMenuProps } from '../ContextMenuItem';
import { StyleProp } from '../StyleProp';
import { DocumentView } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import './CollectionCarouselView.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
enum cardMode {
PRACTICE = 'practice',
@@ -35,7 +32,7 @@ export class CollectionCarouselView extends CollectionSubView() {
get practiceField() { return this.fieldKey + "_practice"; } // prettier-ignore
get starField() { return this.fieldKey + "_star"; } // prettier-ignore
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -124,7 +121,7 @@ export class CollectionCarouselView extends CollectionSubView() {
this.advance(e);
};
- captionStyleProvider = (doc: Doc | undefined, captionProps: Opt<FieldViewProps>, property: string): any => {
+ captionStyleProvider = (doc: Doc | undefined, captionProps: Opt<FieldViewProps>, property: string) => {
// first look for properties on the document in the carousel, then fallback to properties on the container
const childValue = doc?.['caption_' + property] ? this._props.styleProvider?.(doc, captionProps, property) : undefined;
return childValue ?? this._props.styleProvider?.(this.layoutDoc, captionProps, property);
@@ -137,7 +134,7 @@ export class CollectionCarouselView extends CollectionSubView() {
const cm = ContextMenu.Instance;
const revealOptions = cm.findByDescription('Filter Flashcards');
- const revealItems: ContextMenuProps[] = revealOptions && 'subitems' in revealOptions ? revealOptions.subitems : [];
+ const revealItems = revealOptions?.subitems ?? [];
revealItems.push({description: 'All', event: () => {this.layoutDoc.filterOp = undefined;}, icon: 'layer-group',}); // prettier-ignore
revealItems.push({description: 'Star', event: () => {this.layoutDoc.filterOp = cardMode.STAR;}, icon: 'star',}); // prettier-ignore
revealItems.push({description: 'Practice Mode', event: () => {this.layoutDoc.filterOp = cardMode.PRACTICE;}, icon: 'check',}); // prettier-ignore
@@ -161,7 +158,7 @@ export class CollectionCarouselView extends CollectionSubView() {
onDoubleClickScript={this.onContentDoubleClick}
onClickScript={this.onContentClick}
isDocumentActive={this._props.childDocumentsActive?.() ? this._props.isDocumentActive : this._props.isContentActive}
- isContentActive={this._props.childContentsActive ?? this._props.isContentActive() === false ? returnFalse : emptyFunction}
+ isContentActive={(this._props.childContentsActive ?? this._props.isContentActive() === false) ? returnFalse : emptyFunction}
hideCaptions={!!carouselShowsCaptions} // hide captions if the carousel is configured to show the captions
renderDepth={this._props.renderDepth + 1}
LayoutTemplate={this._props.childLayoutTemplate}
@@ -177,7 +174,7 @@ export class CollectionCarouselView extends CollectionSubView() {
key="caption"
onWheel={StopEvent}
style={{
- borderRadius: this._props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding),
+ borderRadius: this._props.styleProvider?.(this.layoutDoc, captionProps, StyleProp.BorderRounding) as string,
marginRight: this.marginX,
marginLeft: this.marginX,
width: `calc(100% - ${this.marginX * 2}px)`,
@@ -218,8 +215,8 @@ export class CollectionCarouselView extends CollectionSubView() {
ref={this.createDashEventsTarget}
onContextMenu={this.specificMenu}
style={{
- background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor),
- color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color),
+ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
+ color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string,
}}>
{this.content}
{/* Displays a message to the user to add more flashcards if they are in practice mode and no flashcards are there. */}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 73179a266..e0aa79c7b 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -2,12 +2,14 @@ import { action, IReactionDisposer, makeObservable, observable, reaction } from
import { observer } from 'mobx-react';
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
+import ResizeObserver from 'resize-observer-polyfill';
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivHeight, DivWidth, incrementTitleCopy, returnTrue, UpdateIcon } from '../../../ClientUtils';
import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
import { AclAdmin, AclEdit, DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
+import { FieldType } from '../../../fields/ObjectField';
import { ImageCast, NumCast, StrCast } from '../../../fields/Types';
import { ImageField } from '../../../fields/URLField';
import { GetEffectiveAcl, inheritParentAcls, SetPropSetterCb } from '../../../fields/util';
@@ -28,19 +30,17 @@ import { OverlayView } from '../OverlayView';
import { ScriptingRepl } from '../ScriptingRepl';
import { UndoStack } from '../UndoStack';
import './CollectionDockingView.scss';
-import { CollectionSubView } from './CollectionSubView';
-
-const _global = (window /* browser */ || global) /* node */ as any;
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
@observer
export class CollectionDockingView extends CollectionSubView() {
- static tabClass: JSX.Element | null = null;
+ static tabClass: unknown = null;
/**
* Initialize by assigning the add split method to DocumentView and by
* configuring golden layout to render its documents using the specified React component
* @param ele - typically would be set to TabDocView
*/
- public static Init(ele: any) {
+ public static Init(ele: unknown) {
this.tabClass = ele;
DocumentView.addSplit = CollectionDockingView.AddSplit;
}
@@ -53,20 +53,22 @@ export class CollectionDockingView extends CollectionSubView() {
private _flush: UndoManager.Batch | undefined;
private _unmounting = false;
private _ignoreStateChange = '';
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ private _goldenLayout: any = null;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
public tabMap: Set<any> = new Set();
public get HasFullScreen() {
return this._goldenLayout._maximisedItem !== null;
}
- private _goldenLayout: any = null;
- static _highlightStyleSheet: any = addStyleSheet();
+ static _highlightStyleSheet = addStyleSheet();
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
if (this._props.renderDepth < 0) CollectionDockingView.Instance = this;
// Why is this here?
- (window as any).React = React;
- (window as any).ReactDOM = ReactDOM;
+ (window as unknown as { React: unknown }).React = React;
+ (window as unknown as { ReactDOM: unknown }).ReactDOM = ReactDOM;
DragManager.StartWindowDrag = this.StartOtherDrag;
this.Document.myTrails; // this is equivalent to having a prefetchProxy for myTrails which is needed for the My Trails button in the UI which assumes that Doc.ActiveDashboard.myTrails is legit...
}
@@ -88,10 +90,11 @@ export class CollectionDockingView extends CollectionSubView() {
};
tabItemDropped = () => DragManager.CompleteWindowDrag?.(false);
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
tabDragStart = (proxy: any, finishDrag?: (aborted: boolean) => void) => {
this._flush = this._flush ?? UndoManager.StartBatch('tab move');
- const dashDoc = proxy?._contentItem?.tab?.DashDoc as Doc;
- dashDoc && (DragManager.DocDragData = new DragManager.DocumentDragData([proxy._contentItem.tab.DashDoc]));
+ //const dashDoc = proxy?._contentItem?.tab?.DashDoc as Doc;
+ //dashDoc && (DragManager.DocDragData = new DragManager.DocumentDragData([proxy._contentItem.tab.DashDoc]));
DragManager.CompleteWindowDrag = (aborted: boolean) => {
if (aborted) {
proxy._dragListener.AbortDrag();
@@ -129,12 +132,13 @@ export class CollectionDockingView extends CollectionSubView() {
}
@undoBatch
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
public static ReplaceTab(document: Doc, mods: OpenWhereMod, stack: any, panelName: string, addToSplit?: boolean, keyValue?: boolean): boolean {
const instance = CollectionDockingView.Instance;
if (!instance) return false;
const newConfig = DashboardView.makeDocumentConfig(document, panelName, undefined, keyValue);
if (!panelName && stack) {
- const activeContentItemIndex = stack.contentItems.findIndex((item: any) => item.config === stack._activeContentItem.config);
+ const activeContentItemIndex = stack.contentItems.findIndex((item: { config: unknown }) => item.config === stack._activeContentItem.config);
const newContentItem = stack.layoutManager.createContentItem(newConfig, instance._goldenLayout);
stack.addChild(newContentItem.contentItems[0], undefined);
stack.contentItems[activeContentItemIndex].remove();
@@ -154,6 +158,7 @@ export class CollectionDockingView extends CollectionSubView() {
}
@undoBatch
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
public static ToggleSplit(doc: Doc, location: OpenWhereMod, stack?: any, panelName?: string, keyValue?: boolean) {
return Array.from(CollectionDockingView.Instance?.tabMap.keys() ?? []).findIndex(tab => tab.DashDoc === doc) !== -1 ? CollectionDockingView.CloseSplit(doc) : CollectionDockingView.AddSplit(doc, location, stack, panelName, keyValue);
}
@@ -162,6 +167,7 @@ export class CollectionDockingView extends CollectionSubView() {
// Creates a split on any side of the docking view based on the passed input pullSide and then adds the Document to the requested side
//
@action
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
public static AddSplit(document: Doc, pullSide: OpenWhereMod, stack?: any, panelName?: string, keyValue?: boolean) {
if (document?._type_collection === CollectionViewType.Docking && !keyValue) return DashboardView.openDashboard(document);
if (!CollectionDockingView.Instance) return false;
@@ -320,7 +326,7 @@ export class CollectionDockingView extends CollectionSubView() {
* @param target
* @param title
*/
- titleChanged = (target: any, value: any) => {
+ titleChanged = (target: Doc, value: FieldType) => {
const title = Field.toString(value);
if (title.startsWith('@') && !title.substring(1).match(/[()[\]@]/) && title.length > 1) {
const embedding = DocListCast(target.proto_embeddings).lastElement();
@@ -339,7 +345,7 @@ export class CollectionDockingView extends CollectionSubView() {
() => DocumentView.LightboxDoc(),
doc => setTimeout(() => !doc && this.onResize())
);
- new _global.ResizeObserver(this.onResize).observe(this._containerRef.current);
+ new ResizeObserver(this.onResize).observe(this._containerRef.current);
this._reactionDisposer = reaction(
() => StrCast(this.Document.dockingConfig),
config => {
@@ -428,7 +434,7 @@ export class CollectionDockingView extends CollectionSubView() {
@action
onPointerDown = (e: React.PointerEvent): void => {
let hitFlyout = false;
- for (let par = e.target as any; !hitFlyout && par; par = par.parentElement) {
+ for (let par = e.target as HTMLElement | null; !hitFlyout && par; par = par.parentElement) {
hitFlyout = par.className === 'dockingViewButtonSelector';
}
if (!hitFlyout) {
@@ -513,6 +519,7 @@ export class CollectionDockingView extends CollectionSubView() {
return changesMade;
};
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
tabDestroyed = (tab: any) => {
this._flush = this._flush ?? UndoManager.StartBatch('tab movement');
const dashDoc = tab.DashDoc;
@@ -530,18 +537,21 @@ export class CollectionDockingView extends CollectionSubView() {
const { fieldKey } = CollectionDockingView.Instance.props;
Doc.RemoveDocFromList(dview, fieldKey, dashDoc);
this.tabMap.delete(tab);
- tab._disposers && Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
+ tab._disposers && Object.values(tab._disposers).forEach(disposer => (disposer as () => void)());
this.stateChanged();
}
};
- tabCreated = (tab: any) => {
+ tabCreated = (tab: { contentItem: { element: HTMLElement[] } }) => {
this.tabMap.add(tab);
- tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content)
+ // InitTab is added to the tab's HTMLElement in TabDocView
+ const tabdocviewContent = tab.contentItem.element[0]?.firstChild?.firstChild as unknown as { InitTab?: (tab: object) => void };
+ tabdocviewContent?.InitTab?.(tab); // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content)
};
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
stackCreated = (stackIn: any) => {
const stack = stackIn.header ? stackIn : stackIn.origin;
- stack.header?.element.on('mousedown', (e: any) => {
+ stack.header?.element.on('mousedown', (e: MouseEvent) => {
const dashboard = Doc.ActiveDashboard;
if (dashboard && e.target === stack.header?.element[0] && e.button === 2) {
dashboard.pane_count = NumCast(dashboard.pane_count) + 1;
@@ -594,7 +604,7 @@ export class CollectionDockingView extends CollectionSubView() {
})
);
- stack.element.click((e: any) => {
+ stack.element.click((e: { originalEvent: MouseEvent }) => {
if (stack.contentItems.length === 0 && Array.from(document.elementsFromPoint(e.originalEvent.x, e.originalEvent.y)).some(ele => ele?.className === 'empty-tabs-message')) {
addNewDoc();
}
@@ -632,7 +642,7 @@ export class CollectionDockingView extends CollectionSubView() {
ScriptingGlobals.add(
// eslint-disable-next-line prefer-arrow-callback
- function openInLightbox(doc: any) {
+ function openInLightbox(doc: Doc) {
CollectionDockingView.Instance?._props.addDocTab(doc, OpenWhere.lightboxAlways);
},
'opens up document in a lightbox',
@@ -640,33 +650,22 @@ ScriptingGlobals.add(
);
ScriptingGlobals.add(
// eslint-disable-next-line prefer-arrow-callback
- function openDoc(doc: any, where: OpenWhere) {
+ function openDoc(doc: Doc | string, where: OpenWhere) {
switch (where) {
case OpenWhere.addRight:
- return CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
+ return doc instanceof Doc && CollectionDockingView.AddSplit(doc, OpenWhereMod.right);
case OpenWhere.overlay:
default:
- // prettier-ignore
switch (doc) {
case '<ScriptingRepl />': return OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: 'Scripting REPL' });
case "<UndoStack />": return OverlayView.Instance.addWindow(<UndoStack />, { x: 300, y: 100, width: 200, height: 200, title: 'Undo stack' });
- default:
- }
- Doc.AddToMyOverlay(doc);
- return true;
+ default: return doc instanceof Doc && Doc.AddToMyOverlay(doc);
+ } // prettier-ignore
}
},
'opens up document in location specified',
'(doc: any)'
);
-ScriptingGlobals.add(
- // eslint-disable-next-line prefer-arrow-callback
- function openRepl() {
- return 'openRepl';
- },
- 'opens up document in screen overlay layer',
- '(doc: any)'
-);
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(async function snapshotDashboard() {
const batch = UndoManager.StartBatch('snapshot');
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 9a6f1e2eb..710c00841 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -1,6 +1,3 @@
-/* eslint-disable jsx-a11y/control-has-associated-label */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
@@ -16,7 +13,7 @@ import { DragManager } from '../../util/DragManager';
import { CompileScript } from '../../util/Scripting';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
-import { undoBatch } from '../../util/UndoManager';
+import { undoBatch, undoable } from '../../util/UndoManager';
import { EditableView } from '../EditableView';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
@@ -37,13 +34,13 @@ interface CMVFieldRowProps {
createDropTarget: (ele: HTMLDivElement) => void;
screenToLocalTransform: () => Transform;
setDocHeight: (key: string, thisHeight: number) => void;
- refList: any[];
+ refList: Element[];
showHandle: boolean;
}
@observer
export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVFieldRowProps> {
- constructor(props: any) {
+ constructor(props: CMVFieldRowProps) {
super(props);
makeObservable(this);
}
@@ -73,7 +70,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
private _dropDisposer?: DragManager.DragDropDisposer;
private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
private _contRef: React.RefObject<HTMLDivElement> = React.createRef();
- private _ele: any;
+ private _ele: HTMLDivElement | null = null;
createRowDropRef = (ele: HTMLDivElement | null) => {
this._dropDisposer?.();
@@ -118,7 +115,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
return false;
});
- getValue = (value: string): any => {
+ getValue = (value: string) => {
const parsed = parseInt(value);
if (!isNaN(parsed)) return parsed;
if (value.toLowerCase().indexOf('true') > -1) return true;
@@ -173,7 +170,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
return docs ? !!docs.splice(0, 0, newDoc) : this._props.parent._props.addDocument?.(newDoc) || false; // should really extend addDocument to specify insertion point (at beginning of list)
};
- deleteRow = undoBatch(
+ deleteRow = undoable(
action(() => {
this._createEmbeddingSelected = false;
const key = this._props.pivotField;
@@ -182,11 +179,12 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent<CMVF
const index = this._props.parent.colHeaderData.indexOf(this._props.headingObject);
this._props.parent.colHeaderData.splice(index, 1);
}
- })
+ }),
+ 'delete row'
);
@action
- collapseSection = (e: any) => {
+ collapseSection = (e: PointerEvent) => {
this._createEmbeddingSelected = false;
this.toggleVisibility();
e.stopPropagation();
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 3eb3008c4..dab1298d5 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -1,7 +1,3 @@
-/* eslint-disable jsx-a11y/label-has-associated-control */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable react/no-unused-class-component-methods */
/* eslint-disable react/sort-comp */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -10,20 +6,20 @@ import { Toggle, ToggleType, Type } from 'browndash-components';
import { Lambda, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { ClientUtils, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
+import { ClientUtils, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../ClientUtils';
import { emptyFunction } from '../../../Utils';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { Doc, DocListCast, Opt, returnEmptyDoclist } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
import { RichTextField } from '../../../fields/RichTextField';
-import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, NumCast, StrCast } from '../../../fields/Types';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { DragManager } from '../../util/DragManager';
import { dropActionType } from '../../util/DropActionTypes';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
-import { undoBatch } from '../../util/UndoManager';
+import { undoBatch, undoable } from '../../util/UndoManager';
import { AntimodeMenu } from '../AntimodeMenu';
import { EditableView } from '../EditableView';
import { DefaultStyleProvider, returnEmptyDocViewList } from '../StyleProvider';
@@ -47,7 +43,7 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
private _docBtnRef = React.createRef<HTMLDivElement>();
- constructor(props: any) {
+ constructor(props: CollectionMenuProps) {
super(props);
makeObservable(this);
CollectionMenu.Instance = this;
@@ -185,7 +181,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
params: ['target', 'source'],
title: 'item view',
script: 'this.target.childLayoutTemplate = getDocTemplate(this.source?.[0])',
- immediate: undoBatch((source: Doc[]) => {
+ immediate: undoable((source: Doc[]) => {
let formatStr = source.length && Cast(source[0].text, RichTextField, null)?.Text;
try {
formatStr && JSON.parse(formatStr);
@@ -200,25 +196,25 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
Doc.SetInPlace(this.target, 'childLayoutString', undefined, true);
Doc.SetInPlace(this.target, 'childLayoutTemplate', undefined, true);
}
- }),
+ }, ''),
initialize: emptyFunction,
};
_narrativeCommand = {
params: ['target', 'source'],
title: 'child click view',
script: 'this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])',
- immediate: undoBatch((source: Doc[]) => {
+ immediate: undoable((source: Doc[]) => {
source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]));
- }),
+ }, 'narrative command'),
initialize: emptyFunction,
};
_contentCommand = {
params: ['target', 'source'],
title: 'set content',
script: 'getProto(this.target).data = copyField(this.source);',
- immediate: undoBatch((source: Doc[]) => {
+ immediate: undoable((source: Doc[]) => {
this.target[DocData].data = new List<Doc>(source);
- }),
+ }, ''),
initialize: emptyFunction,
};
_onClickCommand = {
@@ -229,19 +225,19 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
getProto(this.proxy[0]).target = this.target.target;
getProto(this.proxy[0]).source = copyField(this.target.source);
}}`,
- immediate: undoBatch(() => {}),
+ immediate: undoable(() => {}, ''),
initialize: emptyFunction,
};
_viewCommand = {
params: ['target'],
title: 'bookmark view',
script: "this.target._freeform_panX = this.target_freeform_panX; this.target._freeform_panY = this['target-freeform_panY']; this.target._freeform_scale = this['target_freeform_scale']; gotoFrame(this.target, this['target-currentFrame']);",
- immediate: undoBatch(() => {
+ immediate: undoable(() => {
this.target._freeform_panX = 0;
this.target._freeform_panY = 0;
this.target._freeform_scale = 1;
this.target._currentFrame = this.target._currentFrame === undefined ? undefined : 0;
- }),
+ }, ''),
initialize: (button: Doc) => {
button['target-panX'] = this.target._freeform_panX;
button['target-panY'] = this.target._freeform_panY;
@@ -253,18 +249,18 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
params: ['target'],
title: 'fit content',
script: 'this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox;',
- immediate: undoBatch(() => {
+ immediate: undoable(() => {
this.target._freeform_fitContentsToBox = !this.target._freeform_fitContentsToBox;
- }),
+ }, ''),
initialize: emptyFunction,
};
_fitContentCommand = {
params: ['target'],
title: 'toggle clusters',
script: 'this.target._freeform_useClusters = !this.target._freeform_useClusters;',
- immediate: undoBatch(() => {
+ immediate: undoable(() => {
this.target._freeform_useClusters = !this.target._freeform_useClusters;
- }),
+ }, ''),
initialize: emptyFunction,
};
_saveFilterCommand = {
@@ -272,15 +268,15 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
title: 'save filter',
script: `this.target._childFilters = compareLists(this.target_childFilters,this.target._childFilters) ? undefined : copyField(this.target_childFilters);
this.target._searchFilterDocs = compareLists(this.target_searchFilterDocs,this.target._searchFilterDocs) ? undefined: copyField(this.target_searchFilterDocs);`,
- immediate: undoBatch(() => {
+ immediate: undoable(() => {
this.target._childFilters = undefined;
this.target._searchFilterDocs = undefined;
- }),
+ }, ''),
initialize: (button: Doc) => {
const activeDash = Doc.ActiveDashboard;
if (activeDash) {
- button.target_childFilters = (Doc.MySearcher._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher._childFilters || activeDash._childFilters) as any as ObjectField) : undefined;
- button.target_searchFilterDocs = activeDash._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(activeDash._searchFilterDocs as any as ObjectField) : undefined;
+ button.target_childFilters = (Doc.MySearcher._childFilters || activeDash._childFilters) instanceof ObjectField ? ObjectField.MakeCopy((Doc.MySearcher._childFilters || activeDash._childFilters) as ObjectField) : undefined;
+ button.target_searchFilterDocs = activeDash._searchFilterDocs instanceof ObjectField ? ObjectField.MakeCopy(activeDash._searchFilterDocs) : undefined;
}
},
};
@@ -338,15 +334,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
this._currentKey = this._currentKey || (this._buttonizableCommands?.length ? this._buttonizableCommands[0]?.title : '');
});
- @undoBatch
- viewChanged = (e: React.ChangeEvent) => {
- const target = this.document !== Doc.MyLeftSidebarPanel ? this.document : DocCast(this.document.proto);
- target._type_collection = (e.target as any).selectedOptions[0].value;
- };
-
- commandChanged = (e: React.ChangeEvent) => {
+ commandChanged = (e: React.ChangeEvent<HTMLSelectElement>) => {
runInAction(() => {
- this._currentKey = (e.target as any).selectedOptions[0].value;
+ this._currentKey = e.target.selectedOptions[0].value;
});
};
@@ -485,7 +475,7 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi
};
@action
- onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
+ onKeyChange = (e: React.FormEvent<Element>, { newValue }: { newValue: string }) => {
this._currentKey = newValue;
};
@@ -538,7 +528,6 @@ export class CollectionNoteTakingViewChrome extends React.Component<CollectionVi
autosuggestProps: {
inputProps: {
value: this._currentKey,
- // @ts-ignore
onChange: this.onKeyChange,
},
getSuggestionValue: this.getSuggestionValue,
@@ -605,9 +594,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
*/
onNumColsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.currentTarget.valueAsNumber > 0)
- undoBatch(() => {
+ undoable(() => {
this.document.gridNumCols = e.currentTarget.valueAsNumber;
- })();
+ }, '')();
};
/**
@@ -636,9 +625,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
onIncrementButtonClick = () => {
this.clicked = true;
this.entered && (this.document.gridNumCols as number)--;
- undoBatch(() => {
+ undoable(() => {
this.document.gridNumCols = this.numCols + 1;
- })();
+ }, '')();
this.entered = false;
};
@@ -649,9 +638,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
this.clicked = true;
if (this.numCols > 1 && !this.decrementLimitReached) {
this.entered && (this.document.gridNumCols as number)++;
- undoBatch(() => {
+ undoable(() => {
this.document.gridNumCols = this.numCols - 1;
- })();
+ }, '')();
if (this.numCols === 1) this.decrementLimitReached = true;
}
this.entered = false;
@@ -733,7 +722,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewMenu
onChange={this.changeCompactType}
value={StrCast(this.document.gridStartCompaction, StrCast(this.document.gridCompaction))}>
{['vertical', 'horizontal', 'none'].map(type => (
- <option className="collectionGridViewChrome-viewOption" onPointerDown={stopPropagation} value={type}>
+ <option key={type} className="collectionGridViewChrome-viewOption" onPointerDown={stopPropagation} value={type}>
{this.resize ? type[0].toUpperCase() + type.substring(1) : 'Compact: ' + type}
</option>
))}
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 16c474996..e1f0a3e41 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -30,9 +30,8 @@ import { StyleProp } from '../StyleProp';
import './CollectionNoteTakingView.scss';
import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider';
-import { CollectionSubView } from './CollectionSubView';
-
-const _global = (window /* browser */ || global) /* node */ as any;
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
+import { Property } from 'csstype';
/**
* CollectionNoteTakingView is a column-based view for displaying documents. In this view, the user can (1)
@@ -52,9 +51,9 @@ export class CollectionNoteTakingView extends CollectionSubView() {
public DividerWidth = 16;
@observable docsDraggedRowCol: number[] = [];
@observable _scroll = 0;
- @observable _refList: any[] = [];
+ @observable _refList: HTMLElement[] = [];
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -78,7 +77,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
return colHeaderData ?? ([] as SchemaHeaderField[]);
}
@computed get headerMargin() {
- return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin);
+ return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin) as number;
}
@computed get xMargin() {
return NumCast(this.layoutDoc._xMargin, 5);
@@ -216,7 +215,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
// let's dive in and get the actual document we want to drag/move around
focusDocument = (doc: Doc, options: FocusViewOptions) => {
Doc.BrushDoc(doc);
- const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]);
+ const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find(node => node.id === doc[Id]);
if (found) {
const { top } = found.getBoundingClientRect();
const localTop = this.ScreenToLocalBoxXf().transformPoint(0, top);
@@ -295,7 +294,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
addDocument={this._props.addDocument}
moveDocument={this._props.moveDocument}
removeDocument={this._props.removeDocument}
- contentPointerEvents={StrCast(this.layoutDoc.childContentPointerEvents) as any}
+ contentPointerEvents={StrCast(this.layoutDoc.childContentPointerEvents) as Property.PointerEvents}
whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
addDocTab={this._props.addDocTab}
pinToPres={this._props.pinToPres}
@@ -313,14 +312,14 @@ export class CollectionNoteTakingView extends CollectionSubView() {
// how to get the width of a document. Currently returns the width of the column (minus margins)
// if a note doc. Otherwise, returns the normal width (for graphs, images, etc...)
- getDocWidth(d: Doc) {
+ getDocWidth = (d: Doc) => {
const heading = !d[this.notetakingCategoryField] ? 'unset' : Field.toString(d[this.notetakingCategoryField] as FieldType);
const existingHeader = this.colHeaderData.find(sh => sh.heading === heading);
const existingWidth = this.layoutDoc._notetaking_columns_autoSize ? 1 / (this.colHeaderData.length ?? 1) : existingHeader?.width ? existingHeader.width : 0;
const maxWidth = existingWidth > 0 ? existingWidth * this.availableWidth : this.maxColWidth;
const width = d.layout_fitWidth ? maxWidth : NumCast(d._width);
return Math.min(maxWidth - CollectionNoteTakingViewColumn.ColumnMargin, width < maxWidth ? width : maxWidth);
- }
+ };
// how to get the height of a document. Nothing special here.
getDocHeight(d?: Doc) {
@@ -364,7 +363,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
// onPointerMove is used to preview where a document will drop in a column once a drag is complete.
@action
onPointerMove = (force: boolean, ex: number, ey: number) => {
- if (this.childDocList?.includes(DragManager.DocDragData?.draggedDocuments?.lastElement() as any) || force || SnappingManager.CanEmbed) {
+ const dragDoc = DragManager.DraggedDocs?.lastElement();
+ if ((dragDoc && this.childDocList?.includes(dragDoc)) || force || SnappingManager.CanEmbed) {
// get the current docs for the column based on the mouse's x coordinate
const xCoord = this.ScreenToLocalBoxXf().transformPoint(ex, ey)[0] - 2 * this.gridGap;
const colDocs = this.getDocsFromXCoord(xCoord);
@@ -500,7 +500,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
super.onExternalDrop(
e,
{},
- undoBatch(
+ undoable(
action(docus => {
this.onPointerMove(true, e.clientX, e.clientY);
docus?.map((doc: Doc) => this.addDocument(doc));
@@ -513,7 +513,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
docs.splice(targInd, 0, newDoc);
}
this.removeDocDragHighlight();
- })
+ }),
+ 'drop into note view'
)
);
};
@@ -673,7 +674,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
return this.isContentActive() === false ? 'none' : undefined;
}
- observer = new _global.ResizeObserver(() => this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight))));
+ observer = new ResizeObserver(() => this._props.setHeight?.(this.headerMargin + Math.max(...this._refList.map(DivHeight))));
render() {
TraceMobx();
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index 44ab1968d..8c6a6b551 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable jsx-a11y/control-has-associated-label */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
@@ -16,7 +15,7 @@ import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
import { undoBatch, undoable } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
-import { EditableView } from '../EditableView';
+import { EditableProps, EditableView } from '../EditableView';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import './CollectionNoteTakingView.scss';
@@ -24,7 +23,7 @@ import './CollectionNoteTakingView.scss';
interface CSVFieldColumnProps {
Document: Doc;
TemplateDataDocument: Opt<Doc>;
- backgroundColor?: (() => string) | undefined;
+ backgroundColor?: () => string | undefined;
docList: Doc[];
heading: string;
pivotField: string;
@@ -35,15 +34,15 @@ interface CSVFieldColumnProps {
yMargin: number;
numGroupColumns: number;
gridGap: number;
- headings: () => object[];
+ headings: () => [SchemaHeaderField, Doc[]][];
select: (ctrlPressed: boolean) => void;
isContentActive: () => boolean | undefined;
renderChildren: (docs: Doc[]) => JSX.Element[];
addDocument: (doc: Doc | Doc[]) => boolean;
createDropTarget: (ele: HTMLDivElement) => void;
screenToLocalTransform: () => Transform;
- refList: any[];
- editableViewProps: () => any;
+ refList: HTMLElement[];
+ editableViewProps: () => EditableProps;
resizeColumns: (headers: SchemaHeaderField[]) => boolean;
maxColWidth: number;
dividerWidth: number;
@@ -103,7 +102,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
return true;
};
- getValue = (value: string): any => {
+ getValue = (value: string) => {
const parsed = parseInt(value);
if (!isNaN(parsed)) return parsed;
if (value.toLowerCase().indexOf('true') > -1) return true;
@@ -272,7 +271,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSV
style={{
width: this.columnWidth,
background: this._hover && SnappingManager.IsDragging ? '#b4b4b4' : 'inherit',
- marginLeft: this._props.headings().findIndex((h: any) => h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Document.xMargin) : 0,
+ marginLeft: this._props.headings().findIndex(h => h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Document.xMargin) : 0,
}}>
<div className="collectionNoteTakingViewFieldColumn" key={this._heading} ref={this.createColumnDropRef}>
{this.innards}
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index 5b3f625db..eea128803 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -1,10 +1,8 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { action, computed, IReactionDisposer, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils';
-import { Doc, DocListCast } from '../../../fields/Doc';
+import { Doc, DocListCast, FieldResult } from '../../../fields/Doc';
import { ScriptField } from '../../../fields/ScriptField';
import { NumCast, StrCast, toList } from '../../../fields/Types';
import { emptyFunction } from '../../../Utils';
@@ -15,15 +13,15 @@ import { OpenWhere } from '../nodes/OpenWhere';
import { computePassLayout, computeStarburstLayout } from './collectionFreeForm';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
import './CollectionPileView.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
import { DocumentView } from '../nodes/DocumentView';
@observer
export class CollectionPileView extends CollectionSubView() {
- _originalChrome: any = '';
+ _originalChrome: FieldResult = '';
_disposers: { [name: string]: IReactionDisposer } = {};
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index fac885300..486c826b6 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -1,14 +1,11 @@
/* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable jsx-a11y/alt-text */
/* eslint-disable no-use-before-define */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import * as React from 'react';
-import { returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnTrue, returnZero, setupMoveUpEvents, smoothScrollHorizontal, StopEvent } from '../../../ClientUtils';
-import { Doc, Opt } from '../../../fields/Doc';
+import { returnEmptyFilter, returnFalse, returnNone, returnTrue, returnZero, setupMoveUpEvents, smoothScrollHorizontal, StopEvent } from '../../../ClientUtils';
+import { Doc, Opt, returnEmptyDoclist } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
@@ -34,7 +31,7 @@ import { LabelBox } from '../nodes/LabelBox';
import { OpenWhere } from '../nodes/OpenWhere';
import { ObservableReactComponent } from '../ObservableReactComponent';
import './CollectionStackedTimeline.scss';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
export type CollectionStackedTimelineProps = {
Play: () => void;
@@ -72,7 +69,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
);
this.SelectingRegions.clear();
}
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps & CollectionStackedTimelineProps) {
super(props);
makeObservable(this);
}
@@ -182,7 +179,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
});
anchorStart = (anchor: Doc) => NumCast(anchor._timecodeToShow, NumCast(anchor[this._props.startTag]));
- anchorEnd = (anchor: Doc, val: any = null) => NumCast(anchor._timecodeToHide, NumCast(anchor[this._props.endTag], val) ?? null);
+ anchorEnd = (anchor: Doc, val?: number) => NumCast(anchor._timecodeToHide, NumCast(anchor[this._props.endTag], val) ?? null);
// converts screen pixel offset to time
// prettier-ignore
@@ -192,13 +189,13 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
@computed get rangeClick() {
// prettier-ignore
return ScriptField.MakeFunction('stackedTimeline.clickAnchor(this, clientX)',
- { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: this as any }
+ { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: 'string' /* should be CollectionStackedTimeline */ }
)!;
}
@computed get rangePlay() {
// prettier-ignore
return ScriptField.MakeFunction('stackedTimeline.playOnClick(this, clientX)',
- { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: this as any })!;
+ { stackedTimeline: 'any', clientX: 'number' }, { stackedTimeline: 'string' /* should be CollectionStackedTimeline */})!;
}
rangeClickScript = () => this.rangeClick;
rangePlayScript = () => this.rangePlay;
@@ -426,7 +423,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
const anchor =
docAnchor ??
Docs.Create.LabelDocument({
- title: ComputedField.MakeFunction(`this["${endTag}"] ? "#" + formatToTime(this["${startTag}"]) + "-" + formatToTime(this["${endTag}"]) : "#" + formatToTime(this["${startTag}"])`) as any,
+ title: ComputedField.MakeFunction(`this["${endTag}"] ? "#" + formatToTime(this["${startTag}"]) + "-" + formatToTime(this["${endTag}"]) : "#" + formatToTime(this["${startTag}"])`) as unknown as string, // title can take a function or a string
_label_minFontSize: 12,
_label_maxFontSize: 24,
_dragOnlyWithinContainer: true,
@@ -777,8 +774,8 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
@action
onAnchorDown = (e: React.PointerEvent, anchor: Doc, left: boolean): void => {
const newTime = (timeDownEv: PointerEvent) => {
- const rect = (timeDownEv.target as any).getBoundingClientRect();
- return this._props.toTimeline(timeDownEv.clientX - rect.x, rect.width);
+ const rect = (timeDownEv.target as HTMLElement).getBoundingClientRect?.();
+ return !rect ? 0 : this._props.toTimeline(timeDownEv.clientX - rect.x, rect.width);
};
const changeAnchor = (time: number | undefined) => {
const timelineOnly = Cast(anchor[this._props.startTag], 'number', null) !== undefined;
@@ -850,7 +847,7 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
styleProvider={this._props.styleProvider}
renderDepth={this._props.renderDepth + 1}
LayoutTemplate={undefined}
- LayoutTemplateString={LabelBox.LayoutStringWithTitle('data', this.computeTitle())}
+ LayoutTemplateString={LabelBox.LayoutString('data')}
isDocumentActive={this._props.isDocumentActive}
PanelWidth={width}
PanelHeight={height}
@@ -892,7 +889,7 @@ class StackedTimelineAnchor extends ObservableReactComponent<StackedTimelineAnch
}
}
// eslint-disable-next-line prefer-arrow-callback
-ScriptingGlobals.add(function formatToTime(time: number): any {
+ScriptingGlobals.add(function formatToTime(time: number): string {
return formatTime(time);
});
// eslint-disable-next-line prefer-arrow-callback
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 56d2a6c9c..3f8aee792 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -1,11 +1,10 @@
/* eslint-disable react/jsx-props-no-spreading */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-// eslint-disable-next-line import/no-extraneous-dependencies
import * as CSS from 'csstype';
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { ClientUtils, DivHeight, returnEmptyDoclist, returnNone, returnZero, setupMoveUpEvents, smoothScroll } from '../../../ClientUtils';
+import { ClientUtils, DivHeight, returnNone, returnZero, setupMoveUpEvents, smoothScroll } from '../../../ClientUtils';
import { Doc, Opt } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
@@ -31,12 +30,11 @@ import { DocumentView } from '../nodes/DocumentView';
import { FieldViewProps } from '../nodes/FieldView';
import { FocusViewOptions } from '../nodes/FocusViewOptions';
import { StyleProp } from '../StyleProp';
+import { returnEmptyDocViewList } from '../StyleProvider';
import { CollectionMasonryViewFieldRow } from './CollectionMasonryViewFieldRow';
import './CollectionStackingView.scss';
import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn';
-import { CollectionSubView } from './CollectionSubView';
-
-const _global = (window /* browser */ || global) /* node */ as any;
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
export type collectionStackingViewProps = {
sortFunc?: (a: Doc, b: Doc) => number;
@@ -57,8 +55,9 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
_docXfs: { height: () => number; width: () => number; stackedDocTransform: () => Transform }[] = [];
// Doesn't look like this field is being used anywhere. Obsolete?
_columnStart: number = 0;
+ _oldWheel: HTMLElement | null = null;
- @observable _refList: any[] = [];
+ @observable _refList: HTMLElement[] = [];
// map of node headers to their heights. Used in Masonry
@observable _heightMap = new Map<string, number>();
// Assuming that this is the current css cursor style
@@ -85,7 +84,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
}
// how much margin we give the header
@computed get headerMargin() {
- return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin);
+ return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin) as number;
}
@computed get xMargin() {
return NumCast(this.layoutDoc._xMargin, Math.max(3, 0.05 * this._props.PanelWidth()));
@@ -118,7 +117,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
return this._props.PanelWidth() - this.gridGap;
}
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
if (this.colHeaderData === undefined) {
@@ -260,7 +259,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
focusDocument = (doc: Doc, options: FocusViewOptions) => {
Doc.BrushDoc(doc);
- const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]);
+ const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find(node => node.id === doc[Id]);
if (found) {
const { top } = found.getBoundingClientRect();
const localTop = this.ScreenToLocalBoxXf().transformPoint(0, top);
@@ -321,7 +320,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
const dataDoc = doc.isTemplateDoc || doc.isTemplateForField ? this._props.TemplateDataDocument : undefined;
const height = () => this.getDocHeight(doc);
const panelHeight = () => (this.isStackingView ? height() : Math.min(height(), this._props.PanelHeight()));
- const panelWidth = () => (this.isStackingView ? width() : this.columnWidth);
+ const panelWidth = () => this.columnWidth;
const stackedDocTransform = () => this.getDocTransform(doc);
this._docXfs.push({ stackedDocTransform, width, height });
return count > this._renderCount ? null : (
@@ -344,7 +343,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
LayoutTemplateString={this._props.childLayoutString}
NativeWidth={this._props.childIgnoreNativeSize ? returnZero : this._props.childLayoutFitWidth?.(doc) || (this.childFitWidth(doc) && !Doc.NativeWidth(doc)) ? width : undefined} // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
NativeHeight={this._props.childIgnoreNativeSize ? returnZero : this._props.childLayoutFitWidth?.(doc) || (this.childFitWidth(doc) && !Doc.NativeHeight(doc)) ? height : undefined}
- dontCenter={this._props.childIgnoreNativeSize ? 'xy' : (StrCast(this.layoutDoc.layout_dontCenter) as any)}
+ dontCenter={this._props.childIgnoreNativeSize ? 'xy' : (StrCast(this.layoutDoc.layout_dontCenter) as 'x' | 'y' | 'xy')}
dontRegisterView={BoolCast(this.layoutDoc.childDontRegisterViews, this._props.dontRegisterView)} // used to be true if DataDoc existed, but template textboxes won't layout_autoHeight resize if dontRegisterView is set, but they need to.
rootSelected={this.rootSelected}
showTitle={this._props.childlayout_showTitle}
@@ -363,7 +362,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
addDocument={this._props.addDocument}
moveDocument={this._props.moveDocument}
removeDocument={this._props.removeDocument}
- contentPointerEvents={StrCast(this.layoutDoc.childContentPointerEvents) as any}
+ contentPointerEvents={StrCast(this.layoutDoc.childContentPointerEvents) as CSS.Property.PointerEvents | undefined}
whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
addDocTab={this._props.addDocTab}
pinToPres={this._props.pinToPres}
@@ -374,9 +373,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
getDocTransform(doc: Doc) {
const dref = this.docRefs.get(doc);
this._scroll; // must be referenced for document decorations to update when the text box container is scrolled
- const { translateX, translateY } = ClientUtils.GetScreenTransform(dref?.ContentDiv);
- // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform. so we have to subtract that off
- return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(this.ScreenToLocalBoxXf().Scale);
+ const { translateX, translateY, scale } = ClientUtils.GetScreenTransform(dref?.ContentDiv);
+ return new Transform(-translateX + (dref?.centeringX || 0) * scale,
+ -translateY + (dref?.centeringY || 0) * scale, 1)
+ .scale(1 / scale); // prettier-ignore
}
getDocWidth(d?: Doc) {
if (!d) return 0;
@@ -623,7 +623,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
if (!e.isPropagationStopped()) {
const cm = ContextMenu.Instance;
const options = cm.findByDescription('Options...');
- const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : [];
+ const optionItems: ContextMenuProps[] = options?.subitems ?? [];
optionItems.push({ description: `${this.layoutDoc._columnsFill ? 'Variable Size' : 'Autosize'} Column`, event: () => { this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill; }, icon: 'plus' }); // prettier-ignore
optionItems.push({ description: `${this.layoutDoc._layout_autoHeight ? 'Variable Height' : 'Auto Height'}`, event: () => { this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight; }, icon: 'plus' }); // prettier-ignore
optionItems.push({ description: 'Clear All', event: () => { this.dataDoc[this.fieldKey ?? 'data'] = new List([]); } , icon: 'times' }); // prettier-ignore
@@ -663,7 +663,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
renderDepth={this._props.renderDepth}
focus={emptyFunction}
styleProvider={this._props.styleProvider}
- containerViewPath={returnEmptyDoclist}
+ containerViewPath={returnEmptyDocViewList}
whenChildContentsActiveChanged={emptyFunction}
childFilters={this._props.childFilters}
childFiltersByRanges={this._props.childFiltersByRanges}
@@ -688,10 +688,9 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
return this._props.isContentActive() === false ? 'none' : undefined;
}
- observer = new _global.ResizeObserver(() => this._props.setHeight?.(this.headerMargin + (this.isStackingView ? Math.max(...this._refList.map(DivHeight)) : this._refList.reduce((p, r) => p + DivHeight(r), 0))));
+ observer = new ResizeObserver(() => this._props.setHeight?.(this.headerMargin + (this.isStackingView ? Math.max(...this._refList.map(DivHeight)) : this._refList.reduce((p, r) => p + DivHeight(r), 0))));
onPassiveWheel = (e: WheelEvent) => e.stopPropagation();
- _oldWheel: any;
render() {
TraceMobx();
const editableViewProps = {
@@ -722,8 +721,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
}}
style={{
overflowY: this.isContentActive() ? 'auto' : 'hidden',
- background: this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor),
- pointerEvents: (this._props.pointerEvents?.() as any) ?? this.backgroundEvents,
+ background: this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) as string,
+ pointerEvents: this._props.pointerEvents?.() ?? this.backgroundEvents,
}}
onScroll={action(e => {
this._scroll = e.currentTarget.scrollTop;
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index e2ad5b31d..5ae08e535 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -1,6 +1,3 @@
-/* eslint-disable jsx-a11y/control-has-associated-label */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
@@ -51,7 +48,7 @@ interface CSVFieldColumnProps {
addDocument: (doc: Doc | Doc[]) => boolean;
createDropTarget: (ele: HTMLDivElement) => void;
screenToLocalTransform: () => Transform;
- refList: any[];
+ refList: HTMLElement[];
}
@observer
@@ -64,7 +61,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
@observable _heading = '';
@observable _color = '';
- constructor(props: any) {
+ constructor(props: CSVFieldColumnProps) {
super(props);
makeObservable(this);
this._heading = this._props.headingObject ? this._props.headingObject.heading : this._props.heading;
@@ -118,7 +115,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
this._props.pivotField && drop.docs?.forEach(d => Doc.SetInPlace(d, this._props.pivotField, drop.val, false));
return true;
});
- getValue = (value: string): any => {
+ getValue = (value: string) => {
const parsed = parseInt(value);
if (!isNaN(parsed)) return parsed;
if (value.toLowerCase().indexOf('true') > -1) return true;
@@ -212,7 +209,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
<div className="colorOptions">
{colors.map(col => {
const palette = PastelSchemaPalette.get(col);
- return <div className={'colorPicker' + (selected === palette ? ' active' : '')} style={{ backgroundColor: palette }} onClick={() => this.changeColumnColor(palette!)} />;
+ return <div key={col} className={'colorPicker' + (selected === palette ? ' active' : '')} style={{ backgroundColor: palette }} onClick={() => this.changeColumnColor(palette!)} />;
})}
</div>
</div>
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 26528b2b3..a6768ab35 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -22,7 +22,7 @@ import { DragManager } from '../../util/DragManager';
import { dropActionType } from '../../util/DropActionTypes';
import { ImageUtils } from '../../util/Import & Export/ImageUtils';
import { SnappingManager } from '../../util/SnappingManager';
-import { UndoManager, undoBatch } from '../../util/UndoManager';
+import { UndoManager } from '../../util/UndoManager';
import { ViewBoxBaseComponent } from '../DocComponent';
import { FieldViewProps } from '../nodes/FieldView';
import { DocumentView } from '../nodes/DocumentView';
@@ -67,7 +67,7 @@ export function CollectionSubView<X>() {
private gestureDisposer?: GestureUtils.GestureEventDisposer;
protected _mainCont?: HTMLDivElement;
- constructor(props: any) {
+ constructor(props: X & SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -227,7 +227,6 @@ export function CollectionSubView<X>() {
}
}
- @undoBatch
// eslint-disable-next-line @typescript-eslint/no-unused-vars
protected onGesture(e: Event, ge: GestureUtils.GestureEvent) {}
@@ -294,7 +293,6 @@ export function CollectionSubView<X>() {
return false;
}
- @undoBatch
protected async onExternalDrop(e: React.DragEvent, options: DocumentOptions, completed?: (docs: Doc[]) => void) {
if (e.ctrlKey) {
e.stopPropagation(); // bcz: this is a hack to stop propagation when dropping an image on a text document with shift+ctrl
@@ -386,7 +384,7 @@ export function CollectionSubView<X>() {
addDocument(htmlDoc);
if (srcWeb) {
const iframe = DocumentView.Selected()[0].ContentDiv?.getElementsByTagName('iframe')?.[0];
- const focusNode = iframe?.contentDocument?.getSelection()?.focusNode as any;
+ const focusNode = iframe?.contentDocument?.getSelection()?.focusNode;
if (focusNode) {
const anchor = srcWeb?.ComponentView?.getAnchor?.(true);
anchor && DocUtils.MakeLink(htmlDoc, anchor, {});
@@ -465,23 +463,6 @@ export function CollectionSubView<X>() {
if (item.kind === 'file') {
const file = item.getAsFile();
file?.type && files.push(file);
-
- file?.type === 'application/json' &&
- ClientUtils.readUploadedFileAsText(file).then(result => {
- const json = JSON.parse(result as string);
- addDocument(
- Docs.Create.TreeDocument(
- json['rectangular-puzzle'].crossword.clues[0].clue.map((c: any) => {
- const label = Docs.Create.LabelDocument({ title: c['#text'], _width: 120, _height: 20 });
- const proto = Doc.GetProto(label);
- proto._width = 120;
- proto._height = 20;
- return proto;
- }),
- { _width: 150, _height: 600, title: 'across', backgroundColor: 'white', _createDocOnCR: true }
- )
- );
- });
}
}
this.slowLoadDocuments(files, options, generatedDocuments, text, completed, addDocument).then(batch.end);
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index 0369e4a2a..8a24db330 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -18,7 +16,7 @@ import { ContextMenuProps } from '../ContextMenuItem';
import { FieldsDropdown } from '../FieldsDropdown';
import { PinDocView } from '../PinFuncs';
import { DocumentView } from '../nodes/DocumentView';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
import './CollectionTimeView.scss';
import { ViewDefBounds, computePivotLayout, computeTimelineLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
@@ -32,7 +30,7 @@ export class CollectionTimeView extends CollectionSubView() {
@observable _viewDefDivClick: Opt<ScriptField> = undefined;
@observable _focusPivotField: Opt<string> = undefined;
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -51,7 +49,7 @@ export class CollectionTimeView extends CollectionSubView() {
getAnchor = (addAsAnnotation: boolean) => {
const anchor = Docs.Create.ConfigDocument({
- title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as any,
+ title: ComputedField.MakeFunction(`"${this.pivotField}"])`) as unknown as string, // title can take a functiono or a string
annotationOn: this.Document,
});
PinDocView(anchor, { pinData: { type_collection: true, pivot: true, filters: true } }, this.Document);
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index c39df2c76..a60cd98ac 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,10 +1,9 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { DivHeight, returnAll, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnNone, returnOne, returnTrue, returnZero } from '../../../ClientUtils';
-import { Doc, DocListCast, Opt, StrListCast } from '../../../fields/Doc';
+import ResizeObserver from 'resize-observer-polyfill';
+import { DivHeight, returnAll, returnEmptyFilter, returnFalse, returnNone, returnOne, returnTrue, returnZero } from '../../../ClientUtils';
+import { Doc, DocListCast, Opt, returnEmptyDoclist, StrListCast } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { listSpec } from '../../../fields/Schema';
@@ -19,21 +18,20 @@ import { dropActionType } from '../../util/DropActionTypes';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
-import { undoBatch, UndoManager } from '../../util/UndoManager';
+import { undoable, undoBatch, UndoManager } from '../../util/UndoManager';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { EditableView } from '../EditableView';
import { DocumentView } from '../nodes/DocumentView';
import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
import { StyleProp } from '../StyleProp';
+import { returnEmptyDocViewList } from '../StyleProvider';
import { CollectionFreeFormView } from './collectionFreeForm';
-import { CollectionSubView } from './CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
import './CollectionTreeView.scss';
import { TreeViewType } from './CollectionTreeViewType';
import { TreeView } from './TreeView';
-const _global = (window /* browser */ || global) /* node */ as any;
-
export type collectionTreeViewProps = {
treeViewExpandedView?: 'fields' | 'layout' | 'links' | 'data';
treeViewOpen?: boolean;
@@ -52,14 +50,13 @@ export type collectionTreeViewProps = {
export class CollectionTreeView extends CollectionSubView<Partial<collectionTreeViewProps>>() {
public static AddTreeFunc = 'addTreeFolder(this.embedContainer)';
private _treedropDisposer?: DragManager.DragDropDisposer;
- private _mainEle?: HTMLDivElement;
private _titleRef?: HTMLDivElement | HTMLInputElement | null;
private _disposers: { [name: string]: IReactionDisposer } = {};
private _isDisposing = false; // notes that instance is in process of being disposed
- private refList: Set<any> = new Set(); // list of tree view items to monitor for height changes
- private observer: any; // observer for monitoring tree view items.
+ private refList: Set<HTMLElement> = new Set(); // list of tree view items to monitor for height changes
+ private observer: ResizeObserver | undefined; // observer for monitoring tree view items.
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps & collectionTreeViewProps) {
super(props);
makeObservable(this);
}
@@ -83,8 +80,6 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
@observable _titleHeight = 0; // height of the title bar
- MainEle = () => this._mainEle;
-
// these should stay in synch with counterparts in DocComponent.ts ViewBoxAnnotatableComponent
@observable _isAnyChildContentActive = false;
whenChildContentsActiveChanged = action((isActive: boolean) => {
@@ -116,14 +111,14 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
!this._props.dontRegisterView && this._props.setHeight?.(bodyHeight + titleHeight);
}
};
- unobserveHeight = (ref: any) => {
+ unobserveHeight = (ref: HTMLElement) => {
this.refList.delete(ref);
this.layoutDoc.layout_autoHeight && this.computeHeight();
};
- observeHeight = (ref: any) => {
+ observeHeight = (ref: HTMLElement) => {
if (ref) {
this.refList.add(ref);
- this.observer = new _global.ResizeObserver(() => {
+ this.observer = new ResizeObserver(() => {
if (this.layoutDoc.layout_autoHeight && ref && this.refList.size && !SnappingManager.IsDragging) {
this.computeHeight();
}
@@ -134,7 +129,6 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
};
protected createTreeDropTarget = (ele: HTMLDivElement) => {
this._treedropDisposer?.();
- this._mainEle = ele;
if (ele) this._treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.Document, this.onInternalPreDrop.bind(this));
};
@@ -220,7 +214,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
ContextMenu.Instance.addItem({ description: 'Options...', subitems: layoutItems, icon: 'eye' });
if (!Doc.noviceMode) {
const existingOnClick = ContextMenu.Instance.findByDescription('OnClick...');
- const onClicks: ContextMenuProps[] = existingOnClick && 'subitems' in existingOnClick ? existingOnClick.subitems : [];
+ const onClicks: ContextMenuProps[] = existingOnClick?.subitems ?? [];
onClicks.push({ description: 'Edit onChecked Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.Document, undefined, 'onCheckedClick'), 'edit onCheckedClick'), icon: 'edit' });
!existingOnClick && ContextMenu.Instance.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
}
@@ -233,16 +227,16 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
get editableTitle() {
return (
<EditableView
- contents={this.dataDoc.title}
+ contents={StrCast(this.dataDoc.title)}
display="block"
maxHeight={72}
height="auto"
GetValue={() => StrCast(this.dataDoc.title)}
- SetValue={undoBatch((value: string, shift: boolean, enter: boolean) => {
+ SetValue={undoable((value: string, shift: boolean, enter: boolean) => {
if (enter && this.Document.treeView_Type === TreeViewType.outline) this.makeTextCollection(this.treeChildren);
this.dataDoc.title = value;
return true;
- })}
+ }, 'set doc title')}
/>
);
}
@@ -289,7 +283,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
@observable _renderCount = 1;
@computed get treeViewElements() {
TraceMobx();
- const dragAction = StrCast(this.Document.childDragAction) as any as dropActionType;
+ const dragAction = StrCast(this.Document.childDragAction) as dropActionType;
const treeAddDoc = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => this.addDoc(doc, relativeTo, before);
const moveDoc = (d: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => this._props.moveDocument?.(d, target, addDoc) || false;
if (this._renderCount < this.treeChildren.length)
@@ -337,9 +331,11 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
return this.dataDoc === null ? null : (
<div
className="collectionTreeView-titleBar"
- ref={action((r: any) => {
- (this._titleRef = r) && (this._titleHeight = r.getBoundingClientRect().height * this.ScreenToLocalBoxXf().Scale);
- })}
+ ref={r =>
+ runInAction(() => {
+ (this._titleRef = r) && (this._titleHeight = r.getBoundingClientRect().height * this.ScreenToLocalBoxXf().Scale);
+ })
+ }
key={this.Document[Id]}
style={!this.outlineMode ? { marginLeft: this.marginX(), paddingTop: this.marginTop() } : {}}>
{this.outlineMode ? this.documentTitle : this.editableTitle}
@@ -374,7 +370,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
renderDepth={this._props.renderDepth + 1}
focus={emptyFunction}
styleProvider={this._props.styleProvider}
- containerViewPath={returnEmptyDoclist}
+ containerViewPath={returnEmptyDocViewList}
whenChildContentsActiveChanged={emptyFunction}
childFilters={this._props.childFilters}
childFiltersByRanges={this._props.childFiltersByRanges}
@@ -414,8 +410,8 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
@observable _headerHeight = 0;
@computed get content() {
- const background = () => this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor);
- const color = () => this._props.styleProvider?.(this.Document, this._props, StyleProp.Color);
+ const background = () => this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) as string;
+ const color = () => this._props.styleProvider?.(this.Document, this._props, StyleProp.Color) as string;
const pointerEvents = () => (this._props.isContentActive() === false ? 'none' : undefined);
const titleBar = this._props.treeViewHideTitle || this.Document.treeView_HideTitle ? null : this.titleBar;
return (
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index a750b731a..66c4896c0 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -49,7 +49,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
private reactionDisposer: IReactionDisposer | undefined;
@observable _isContentActive: boolean | undefined = undefined;
- constructor(props: any) {
+ constructor(props: CollectionViewProps) {
super(props);
makeObservable(this);
this._annotationKeySuffix = returnEmptyString;
@@ -73,7 +73,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
}
get collectionViewType(): CollectionViewType | undefined {
- const viewField = StrCast(this.layoutDoc._type_collection) as any as CollectionViewType;
+ const viewField = StrCast(this.layoutDoc._type_collection) as CollectionViewType;
if (CollectionView._safeMode) {
switch (viewField) {
case CollectionViewType.Freeform:
@@ -133,7 +133,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
];
const existingVm = ContextMenu.Instance.findByDescription(category);
- const catItems = existingVm && 'subitems' in existingVm ? existingVm.subitems : [];
+ const catItems = existingVm?.subitems ?? [];
catItems.push({ description: 'Add a Perspective...', addDivider: true, noexpand: true, subitems: subItems, icon: 'eye' });
!existingVm && ContextMenu.Instance.addItem({ description: category, subitems: catItems, icon: 'eye' });
}
@@ -152,7 +152,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
});
const options = cm.findByDescription('Options...');
- const optionItems = options && 'subitems' in options ? options.subitems : [];
+ const optionItems = options?.subitems ?? [];
!Doc.noviceMode ? optionItems.splice(0, 0, { description: `${this.Document.forceActive ? 'Select' : 'Force'} Contents Active`, event: () => {this.Document.forceActive = !this.Document.forceActive}, icon: 'project-diagram' }) : null; // prettier-ignore
if (this.Document.childLayout instanceof Doc) {
optionItems.push({ description: 'View Child Layout', event: () => this._props.addDocTab(this.Document.childLayout as Doc, OpenWhere.addRight), icon: 'project-diagram' });
@@ -166,7 +166,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
if (!Doc.noviceMode && !this.Document.annotationOn && !this._props.hideClickBehaviors) {
const existingOnClick = cm.findByDescription('OnClick...');
- const onClicks = existingOnClick && 'subitems' in existingOnClick ? existingOnClick.subitems : [];
+ const onClicks = existingOnClick?.subitems ?? [];
const funcs = [
{ key: 'onChildClick', name: 'On Child Clicked' },
{ key: 'onChildDoubleClick', name: 'On Child Double Clicked' },
@@ -196,7 +196,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<CollectionViewPr
if (!Doc.noviceMode) {
const more = cm.findByDescription('More...');
- const moreItems = more && 'subitems' in more ? more.subitems : [];
+ const moreItems = more?.subitems ?? [];
moreItems.push({ description: 'Export Image Hierarchy', icon: 'columns', event: () => ImageUtils.ExportHierarchyToFileSystem(this.Document) });
!more && cm.addItem({ description: 'More...', subitems: moreItems, icon: 'hand-point-right' });
}
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 46f61290e..31b6be927 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -6,15 +6,16 @@ import { IReactionDisposer, ObservableSet, action, computed, makeObservable, obs
import { observer } from 'mobx-react';
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
-import { ClientUtils, DashColor, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils';
+import ResizeObserver from 'resize-observer-polyfill';
+import { ClientUtils, DashColor, lightOrDark, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils';
import { emptyFunction } from '../../../Utils';
-import { Doc, Opt } from '../../../fields/Doc';
+import { Doc, Opt, returnEmptyDoclist } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
import { FieldId } from '../../../fields/RefField';
import { ComputedField } from '../../../fields/ScriptField';
-import { Cast, DocCast, NumCast, StrCast, toList } from '../../../fields/Types';
+import { Cast, NumCast, StrCast, toList } from '../../../fields/Types';
import { DocServer } from '../../DocServer';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
@@ -41,8 +42,6 @@ import { CollectionView } from './CollectionView';
import './TabDocView.scss';
import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
-const _global = (window /* browser */ || global) /* node */ as any;
-
interface TabMinimapViewProps {
document: Doc;
tabView: () => DocumentView | undefined;
@@ -67,7 +66,7 @@ class TabMiniThumb extends React.Component<TabMiniThumbProps> {
}
@observer
export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps> {
- static miniStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
+ static miniStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => {
if (doc) {
switch (property.split(':')[0]) {
case StyleProp.PointerEvents: return 'none';
@@ -158,8 +157,8 @@ export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps
addDocTab={this._props.addDocTab}
// eslint-disable-next-line no-use-before-define
pinToPres={TabDocView.PinDoc}
- childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
- childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
+ childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyFilter}
+ childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyFilter}
searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
fitContentsToBox={returnTrue}
xPadding={this.xPadding}
@@ -183,6 +182,7 @@ export class TabMinimapView extends ObservableReactComponent<TabMinimapViewProps
interface TabDocViewProps {
documentId: FieldId;
keyValue?: boolean;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
glContainer: any;
}
@observer
@@ -274,7 +274,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
}
static Activate = (tabDoc: Doc) => {
- const tab = Array.from(CollectionDockingView.Instance?.tabMap!).find(findTab => findTab.DashDoc === tabDoc && !findTab.contentItem.config.props.keyValue);
+ const tab = Array.from(CollectionDockingView.Instance?.tabMap ?? []).find(findTab => findTab.DashDoc === tabDoc && !findTab.contentItem.config.props.keyValue);
tab?.header.parent.setActiveContentItem(tab.contentItem); // glr: Panning does not work when this is set - (this line is for trying to make a tab that is not topmost become topmost)
return tab !== undefined;
};
@@ -286,7 +286,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
// }
// return undefined;
// }
- constructor(props: any) {
+ constructor(props: TabDocViewProps) {
super(props);
makeObservable(this);
DocumentView.activateTabView = TabDocView.Activate;
@@ -327,10 +327,12 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
get view() {
return this._view;
}
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
_lastTab: any;
_lastView: DocumentView | undefined;
@action
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
init = (tab: any, doc: Opt<Doc>) => {
if (tab.contentItem === tab.header.parent.getActiveContentItem()) this._activated = true;
if (tab.DashDoc !== doc && doc && tab.contentItem?.config.type !== 'stack') {
@@ -357,10 +359,11 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
titleEle.size = StrCast(doc.title).length + 3;
titleEle.value = doc.title;
titleEle.onkeydown = (e: KeyboardEvent) => e.stopPropagation();
- titleEle.onchange = (e: any) => {
+ titleEle.onchange = (e: InputEvent) => {
undoable(() => {
- titleEle.size = e.currentTarget.value.length + 3;
- doc[DocData].title = e.currentTarget.value;
+ const target = e.currentTarget as unknown as { value: string };
+ titleEle.size = target?.value.length + 3;
+ doc[DocData].title = target?.value ?? '';
}, 'edit tab title')();
};
@@ -399,9 +402,10 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
tab._disposers.color = reaction(
() => ({ variant: SnappingManager.userVariantColor, degree: Doc.GetBrushStatus(doc), highlight: DefaultStyleProvider(this._document, undefined, StyleProp.Highlighting) }),
({ variant, degree, highlight }) => {
- const color = highlight?.highlightIndex === Doc.DocBrushStatus.highlighted ? highlight.highlightColor : degree ? ['transparent', variant, variant, 'orange'][degree] : variant;
+ const { highlightIndex, highlightColor } = (highlight as { highlightIndex: number; highlightColor: string }) ?? { highlightIndex: undefined, highlightColor: undefined };
+ const color = highlightIndex === Doc.DocBrushStatus.highlighted ? highlightColor : degree ? ['transparent', variant, variant, 'orange'][degree] : variant;
- const textColor = color === variant ? SnappingManager.userColor ?? '' : lightOrDark(color);
+ const textColor = color === variant ? (SnappingManager.userColor ?? '') : lightOrDark(color);
titleEle.style.color = textColor;
iconWrap.style.color = textColor;
closeWrap.style.color = textColor;
@@ -448,8 +452,8 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
};
// select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected
- titleEle.onpointerdown = action((e: any) => {
- if (e.target.className !== 'lm_iconWrap') {
+ titleEle.onpointerdown = action((e: PointerEvent) => {
+ if ((e.target as HTMLElement)?.className !== 'lm_iconWrap') {
if (this.view) DocumentView.SelectView(this.view, false);
else this._activated = true;
if (Date.now() - titleEle.lastClick < 1000) titleEle.select();
@@ -481,7 +485,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
tab.closeElement
.off('click') // unbind the current click handler
.click(() => {
- Object.values(tab._disposers).forEach((disposer: any) => disposer?.());
+ Object.values(tab._disposers).forEach(disposer => (disposer as () => void)());
DocumentView.DeselectAll();
UndoManager.RunInBatch(() => tab.contentItem.remove(), 'delete tab');
});
@@ -489,8 +493,8 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
};
componentDidMount() {
- new _global.ResizeObserver(
- action((entries: any) => {
+ new ResizeObserver(
+ action(entries => {
// eslint-disable-next-line no-restricted-syntax
for (const entry of entries) {
this._panelWidth = entry.contentRect.width;
@@ -523,6 +527,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
public static DontSelectOnActivate = 'dontSelectOnActivate';
@action.bound
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
private onActiveContentItemChanged(contentItem: any) {
if (!contentItem || (this.stack === contentItem.parent && ((contentItem?.tab === this.tab && !this._isActive) || (contentItem?.tab !== this.tab && this._isActive)))) {
this._activated = this._isActive = !contentItem || contentItem?.tab === this.tab;
@@ -612,8 +617,8 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
PanelWidth={this.PanelWidth}
PanelHeight={this.PanelHeight}
styleProvider={DefaultStyleProvider}
- childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
- childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
+ childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyFilter}
+ childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyFilter}
searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
addDocument={undefined}
removeDocument={this.remDocTab}
@@ -623,7 +628,7 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
dontCenter="y"
whenChildContentsActiveChanged={this.whenChildContentActiveChanges}
focus={this.focusFunc}
- containerViewPath={returnEmptyDoclist}
+ containerViewPath={returnEmptyDocViewList}
pinToPres={TabDocView.PinDoc}
/>
{this.disableMinimap() ? null : <TabMinimapView key="minimap" addDocTab={this.addDocTab} PanelHeight={this.PanelHeight} PanelWidth={this.PanelWidth} background={this.miniMapColor} document={this._document} tabView={this.tabView} />}
@@ -649,13 +654,13 @@ export class TabDocView extends ObservableReactComponent<TabDocViewProps> {
this._view && DocumentView.removeView(this._view);
}
this._lastTab = this.tab;
- (this._mainCont as any).InitTab = (tab: any) => this.init(tab, this._document);
+ (this._mainCont as { InitTab?: (tab: object) => void }).InitTab = (tab: object) => this.init(tab, this._document);
DocServer.GetRefField(this._props.documentId).then(
action(doc => {
doc instanceof Doc && (this._document = doc) && this.tab && this.init(this.tab, this._document);
})
);
- new _global.ResizeObserver(action(() => this._forceInvalidateScreenToLocal++)).observe(ref);
+ ref && new ResizeObserver(action(() => this._forceInvalidateScreenToLocal++)).observe(ref);
}
}}>
{this.docView}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index b82421e6b..b10a521ca 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -1,15 +1,12 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { IconButton, Size } from 'browndash-components';
-import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { ClientUtils, lightOrDark, return18, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils';
+import { ClientUtils, lightOrDark, return18, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, returnZero, setupMoveUpEvents, simulateMouseClick } from '../../../ClientUtils';
import { emptyFunction } from '../../../Utils';
-import { Doc, DocListCast, Field, FieldResult, FieldType, Opt, StrListCast } from '../../../fields/Doc';
+import { Doc, DocListCast, Field, FieldType, Opt, StrListCast, returnEmptyDoclist } from '../../../fields/Doc';
import { DocData } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { List } from '../../../fields/List';
@@ -41,14 +38,15 @@ import { CollectionView } from './CollectionView';
import { TreeSort } from './TreeSort';
import './TreeView.scss';
+// eslint-disable-next-line @typescript-eslint/no-var-requires
const { TREE_BULLET_WIDTH } = require('../global/globalCssVariables.module.scss'); // prettier-ignore
export interface TreeViewProps {
treeView: CollectionTreeView;
// eslint-disable-next-line no-use-before-define
parentTreeView: TreeView | CollectionTreeView | undefined;
- observeHeight: (ref: any) => void;
- unobserveHeight: (ref: any) => void;
+ observeHeight: (ref: HTMLDivElement) => void;
+ unobserveHeight: (ref: HTMLDivElement) => void;
prevSibling?: Doc;
Document: Doc;
dataDoc?: Doc;
@@ -188,7 +186,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
moving: boolean = false;
@undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
if (this.Document !== target && addDoc !== returnFalse) {
- const canAdd1 = (this._props.parentTreeView as any).dropping || !(ComputedField.WithoutComputed(() => FieldValue(this._props.parentTreeView?.Document.data)) instanceof ComputedField);
+ const canAdd1 = (this._props.parentTreeView as TreeView).dropping || !(ComputedField.WithoutComputed(() => FieldValue(this._props.parentTreeView?.Document.data)) instanceof ComputedField);
// bcz: this should all be running in a Temp undo batch instead of hackily testing for returnFalse
if (canAdd1 && this._props.removeDoc?.(doc) === true) {
@@ -251,7 +249,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
return [];
}
- const runningChildren: FieldResult[] = [];
+ const runningChildren: Doc[] = [];
childList.forEach(child => {
if (child.runProcess && TreeView.GetRunningChildren.get(child)) {
if (child.runProcess) {
@@ -263,7 +261,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
return runningChildren;
};
- static GetRunningChildren = new Map<Doc, any>();
+ static GetRunningChildren = new Map<Doc, () => Doc[]>();
static ToggleChildrenRun = new Map<Doc, () => void>();
constructor(props: TreeViewProps) {
super(props);
@@ -285,7 +283,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
TreeView.GetRunningChildren.set(this.Document, () => this.getRunningChildren(this.childDocs));
}
- _treeEle: any;
+ _treeEle: HTMLDivElement | null = null;
protected createTreeDropTarget = (ele: HTMLDivElement) => {
this._treedropDisposer?.();
ele && ((this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this), this.Document, this.preTreeDrop.bind(this))), this.Document);
@@ -469,14 +467,12 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
return false;
}
- refTransform = (ref: HTMLDivElement | undefined | null) => {
+ refTransform = (ref: HTMLElement | undefined | null) => {
if (!ref) return this.ScreenToLocalTransform();
- const { translateX, translateY } = ClientUtils.GetScreenTransform(ref);
- const outerXf = ClientUtils.GetScreenTransform(this.treeView.MainEle());
- const offset = this.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
- return this.ScreenToLocalTransform().translate(offset[0], offset[1]);
+ const { translateX, translateY, scale } = ClientUtils.GetScreenTransform(ref);
+ return new Transform(-translateX, -translateY, 1).scale(1 / scale);
};
- docTransform = () => this.refTransform(this._dref?.ContentRef?.current);
+ docTransform = () => this.refTransform(this._dref?.ContentDiv);
getTransform = () => this.refTransform(this._tref.current);
embeddedPanelWidth = () => this._props.panelWidth() / (this.treeView._props.NativeDimScaling?.() || 1);
embeddedPanelHeight = () => {
@@ -526,7 +522,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
return toList(docs).reduce((flg, iDoc) => flg && innerAdd(iDoc), true as boolean);
};
contentElement = TreeView.GetChildElements(
- toList(contents as any),
+ contents instanceof Doc ? [contents] : DocListCast(contents),
this.treeView,
this,
doc,
@@ -574,9 +570,11 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
rows.push(
<div style={{ display: 'flex', overflow: 'auto' }} key={key}>
<span
- ref={action((r: any) => {
- if (r) leftOffset.width = r.getBoundingClientRect().width;
- })}
+ ref={r =>
+ runInAction(() => {
+ if (r) leftOffset.width = r.getBoundingClientRect().width;
+ })
+ }
style={{ fontWeight: 'bold' }}>
{key + ':'}
&nbsp;
@@ -610,7 +608,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
return rows;
}
- _renderTimer: any;
+ _renderTimer: NodeJS.Timeout | undefined;
@observable _renderCount = 1;
@computed get renderContent() {
TraceMobx();
@@ -756,7 +754,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
}
get onCheckedClick() {
- return this.Document.type === DocumentType.COL ? undefined : this._props.onCheckedClick?.() ?? ScriptCast(this.Document.onCheckedClick);
+ return this.Document.type === DocumentType.COL ? undefined : (this._props.onCheckedClick?.() ?? ScriptCast(this.Document.onCheckedClick));
}
@action
@@ -779,9 +777,9 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
@computed get renderBullet() {
TraceMobx();
- const iconType = this.treeView._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':treeOpen' : !this.childDocs.length ? ':empty' : '')) || 'question';
+ const iconType = (this.treeView._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':treeOpen' : !this.childDocs.length ? ':empty' : '')) as string) || 'question';
const color = SettingsManager.userColor;
- const checked = this.onCheckedClick ? this.Document.treeView_Checked ?? 'unchecked' : undefined;
+ const checked = this.onCheckedClick ? (this.Document.treeView_Checked ?? 'unchecked') : undefined;
return (
<div
className={`bullet${this.treeView.outlineMode ? '-outline' : ''}`}
@@ -791,7 +789,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
style={
this.treeView.outlineMode
? {
- opacity: this.titleStyleProvider?.(this.Document, this.treeView._props, StyleProp.Opacity),
+ opacity: this.titleStyleProvider?.(this.Document, this.treeView._props, StyleProp.Opacity) as number,
}
: {
pointerEvents: this._props.isContentActive() ? 'all' : undefined,
@@ -831,7 +829,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
@action
expandNextviewType = () => {
if (this.treeViewOpen && !this.Document.isFolder && !this.treeView.outlineMode && !this.Document.treeView_ExpandedViewLock) {
- const next = (modes: any[]) => modes[(modes.indexOf(StrCast(this.treeViewExpandedView)) + 1) % modes.length];
+ const next = (modes: string[]) => modes[(modes.indexOf(StrCast(this.treeViewExpandedView)) + 1) % modes.length];
this.Document.treeView_ExpandedView = next(this.validExpandViewTypes);
}
this.treeViewOpen = true;
@@ -899,13 +897,13 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
onChildDoubleClick = () => ScriptCast(this.treeView.Document.treeView_ChildDoubleClick, !this.treeView.outlineMode ? this._openScript?.() : null);
refocus = () => this.treeView._props.focus(this.treeView.Document, {});
- ignoreEvent = (e: any) => {
+ ignoreEvent = (e: React.MouseEvent) => {
if (this._props.isContentActive(true)) {
e.stopPropagation();
e.preventDefault();
}
};
- titleStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
+ titleStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
if (!doc || doc !== this.Document) return this._props?.treeView?._props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView
const { treeView } = this;
@@ -925,7 +923,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
style={{
// just render a title for a tree view label (identified by treeViewDoc being set in 'props')
maxWidth: props?.PanelWidth() || undefined,
- background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor),
+ background: props?.styleProvider?.(doc, props, StyleProp.BackgroundColor) as string,
outline: SnappingManager.IsDragging ? undefined: `solid ${highlightColor} ${highlightIndex}px`,
paddingLeft: NumCast(treeView.Document.childXPadding, NumCast(treeView._props.childXPadding, Doc.IsComicStyle(doc)?20:0)),
paddingRight: NumCast(treeView.Document.childXPadding, NumCast(treeView._props.childXPadding, Doc.IsComicStyle(doc)?20:0)),
@@ -940,7 +938,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
}
return treeView._props.styleProvider?.(doc, props, property);
};
- embeddedStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
+ embeddedStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
if (property.startsWith(StyleProp.Decorations)) return null;
return this._props?.treeView?._props.styleProvider?.(doc, props, property); // properties are inherited from the CollectionTreeView, not the hierarchical parent in the treeView
};
@@ -992,28 +990,30 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
this._editTitle = e;
})}
GetValue={() => StrCast(this.Document.title)}
- OnTab={undoBatch((shift?: boolean) => {
+ OnTab={undoable((shift?: boolean) => {
if (!shift) this._props.indentDocument?.(true);
else this._props.outdentDocument?.(true);
- })}
- OnEmpty={undoBatch(() => this.treeView.outlineMode && this._props.removeDoc?.(this.Document))}
+ }, 'create new tree Doc')}
+ OnEmpty={undoable(() => this.treeView.outlineMode && this._props.removeDoc?.(this.Document), 'remove tree doc')}
OnFillDown={() => this.treeView.fileSysMode && this.makeFolder()}
- SetValue={undoBatch((value: string, shiftKey: boolean, enterKey: boolean) => {
+ SetValue={undoable((value: string, shiftKey: boolean, enterKey: boolean) => {
Doc.SetInPlace(this.Document, 'title', value, false);
- this.treeView.outlineMode && enterKey && this.makeTextCollection();
- })}
+ return this.treeView.outlineMode && enterKey && this.makeTextCollection();
+ }, 'set tree doc title')}
/>
) : (
<DocumentView
key="title"
- ref={action((r: any) => {
- this._docRef = r || undefined;
- if (this._docRef && TreeView._editTitleOnLoad?.id === this.Document[Id] && TreeView._editTitleOnLoad.parent === this._props.parentTreeView) {
- this._docRef.select(false);
- this.setEditTitle(this._docRef);
- TreeView._editTitleOnLoad = undefined;
- }
- })}
+ ref={r =>
+ runInAction(() => {
+ this._docRef = r || undefined;
+ if (this._docRef && TreeView._editTitleOnLoad?.id === this.Document[Id] && TreeView._editTitleOnLoad.parent === this._props.parentTreeView) {
+ this._docRef.select(false);
+ this.setEditTitle(this._docRef);
+ TreeView._editTitleOnLoad = undefined;
+ }
+ })
+ }
Document={this.Document}
fitWidth={returnTrue}
scriptContext={this}
@@ -1070,9 +1070,11 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
</div>
<div
className="treeView-rightButtons"
- ref={action((r: any) => {
- r && (this.headerEleWidth = r.getBoundingClientRect().width);
- })}>
+ ref={r =>
+ runInAction(() => {
+ r && (this.headerEleWidth = r.getBoundingClientRect().width);
+ })
+ }>
{this.titleButtons}
</div>
</>
@@ -1092,7 +1094,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
this,
e,
() => {
- (this._dref ?? this._docRef)?.startDragging(e.clientX, e.clientY, '' as any);
+ (this._dref ?? this._docRef)?.startDragging(e.clientX, e.clientY, undefined);
return true;
},
returnFalse,
@@ -1181,7 +1183,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
@computed get renderBorder() {
const sorting = StrCast(this.Document.treeView_SortCriterion, TreeSort.WhenAdded);
- const sortings = (this._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewSortings) ?? {}) as { [key: string]: { color: string; label: string } };
+ const sortings = (this._props.styleProvider?.(this.Document, this.treeView._props, StyleProp.TreeViewSortings) ?? {}) as { [key: string]: { color: string; icon: JSX.Element } };
return (
<div className={`treeView-border${this.treeView.outlineMode ? TreeViewType.outline : ''}`} style={{ borderColor: sortings[sorting]?.color }}>
{!this.treeViewOpen ? null : this.renderContent}
@@ -1274,8 +1276,8 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
firstLevel: boolean,
whenChildContentsActiveChanged: (isActive: boolean) => void,
dontRegisterView: boolean | undefined,
- observerHeight: (ref: any) => void,
- unobserveHeight: (ref: any) => void,
+ observerHeight: (ref: HTMLElement) => void,
+ unobserveHeight: (ref: HTMLElement) => void,
contextMenuItems: { script: ScriptField; filter: ScriptField; label: string; icon: string }[],
// TODO: [AL] add these
AddToMap?: (treeViewDoc: Doc, index: number[]) => void,
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
index fc39cafaa..c17371151 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
@@ -12,7 +12,7 @@ import './CollectionFreeFormView.scss';
* returns a truthy value
*/
// eslint-disable-next-line no-use-before-define
-export type infoArc = [() => any, (res?: any) => infoState];
+export type infoArc = [() => unknown, (res?: unknown) => infoState];
export const StateMessage = Symbol('StateMessage');
export const StateMessageGIF = Symbol('StateMessageGIF');
@@ -20,9 +20,9 @@ export const StateEntryFunc = Symbol('StateEntryFunc');
export class infoState {
[StateMessage]: string = '';
[StateMessageGIF]?: string = '';
- [StateEntryFunc]?: () => any;
+ [StateEntryFunc]?: () => unknown;
[key: string]: infoArc;
- constructor(message: string, arcs: { [key: string]: infoArc }, messageGif?: string, entryFunc?: () => any) {
+ constructor(message: string, arcs: { [key: string]: infoArc }, messageGif?: string, entryFunc?: () => unknown) {
this[StateMessage] = message;
Object.assign(this, arcs);
this[StateMessageGIF] = messageGif;
@@ -44,7 +44,7 @@ export function InfoState(
msg: string, //
arcs: { [key: string]: infoArc },
gif?: string,
- entryFunc?: () => any
+ entryFunc?: () => unknown
) {
// eslint-disable-next-line new-cap
return new infoState(msg, arcs, gif, entryFunc);
@@ -52,7 +52,7 @@ export function InfoState(
export interface CollectionFreeFormInfoStateProps {
infoState: infoState;
- next: (state: infoState) => any;
+ next: (state: infoState) => unknown;
close: () => void;
}
@@ -61,7 +61,7 @@ export class CollectionFreeFormInfoState extends ObservableReactComponent<Collec
_disposers: IReactionDisposer[] = [];
@observable _expanded = false;
- constructor(props: any) {
+ constructor(props: CollectionFreeFormInfoStateProps) {
super(props);
makeObservable(this);
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index de51cc73c..79aad0ef2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -9,7 +9,7 @@ import { aggregateBounds } from '../../../../Utils';
export interface ViewDefBounds {
type: string;
- payload: any;
+ payload: unknown;
x: number;
y: number;
z?: number;
@@ -72,11 +72,15 @@ function toLabel(target: FieldResult<FieldType>) {
*/
function getTextWidth(text: string, font: string): number {
// re-use canvas object for better performance
- const canvas = (getTextWidth as any).canvas || ((getTextWidth as any).canvas = document.createElement('canvas'));
+ const selfStoreHack = getTextWidth as unknown as { canvas: Element };
+ const canvas = (selfStoreHack.canvas = (selfStoreHack.canvas as unknown as HTMLCanvasElement) ?? document.createElement('canvas'));
const context = canvas.getContext('2d');
- context.font = font;
- const metrics = context.measureText(text);
- return metrics.width;
+ if (context) {
+ context.font = font;
+ const metrics = context.measureText(text);
+ return metrics.width;
+ }
+ return 0;
}
interface PivotColumn {
@@ -131,13 +135,13 @@ export function computeStarburstLayout(poolData: Map<string, PoolData>, pivotDoc
return normalizeResults(burstDiam, 12, docMap, poolData, viewDefsToJSX, [], 0, [divider]);
}
-export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) {
+export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: unknown) {
const docMap = new Map<string, PoolData>();
const fieldKey = 'data';
const pivotColumnGroups = new Map<FieldResult<FieldType>, PivotColumn>();
let nonNumbers = 0;
- const pivotFieldKey = toLabel(engineProps?.pivotField ?? pivotDoc._pivotField) || 'author';
+ const pivotFieldKey = toLabel((engineProps as { pivotField?: string })?.pivotField ?? pivotDoc._pivotField) || 'author';
childPairs.forEach(pair => {
const listValue = Cast(pair.layout[pivotFieldKey], listSpec('string'), null);
@@ -265,7 +269,7 @@ export function computePivotLayout(poolData: Map<string, PoolData>, pivotDoc: Do
y: -maxColHeight + pivotAxisWidth,
width: pivotAxisWidth * numCols * expander,
height: maxColHeight,
- payload: pivotColumnGroups.get(key)!.filters,
+ payload: pivotColumnGroups.get(key)?.filters,
}));
groupNames.push(...dividers);
// eslint-disable-next-line no-use-before-define
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
index e543b4008..bc9dd022c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
@@ -54,8 +54,8 @@ export class CollectionFreeFormPannableContents extends ObservableReactComponent
<div
className={'collectionfreeformview' + (this._props.viewDefDivClick ? '-viewDef' : '-none')}
onScroll={e => {
- const target = e.target as any;
- if (getComputedStyle(target)?.overflow === 'visible') {
+ const { target } = e;
+ if (target instanceof Element && getComputedStyle(target)?.overflow === 'visible') {
target.scrollTop = target.scrollLeft = 0; // if collection is visible, scrolling messes things up since there are no scroll bars
}
}}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index b6e1fca77..c4cf8dee7 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,15 +1,14 @@
/* eslint-disable react/jsx-props-no-spreading */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
import { Bezier } from 'bezier-js';
import { Colors } from 'browndash-components';
+import { Property } from 'csstype';
import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { computedFn } from 'mobx-utils';
import * as React from 'react';
import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils';
import { DateField } from '../../../../fields/DateField';
-import { ActiveEraserWidth, ActiveInkWidth, Doc, DocListCast, Field, FieldType, Opt, SetActiveInkColor, SetActiveInkWidth } from '../../../../fields/Doc';
+import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc';
import { DocData, Height, Width } from '../../../../fields/DocSymbols';
import { Id } from '../../../../fields/FieldSymbols';
import { InkData, InkField, InkTool, Segment } from '../../../../fields/InkField';
@@ -32,20 +31,20 @@ import { CompileScript } from '../../../util/Scripting';
import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
import { freeformScrollMode, SnappingManager } from '../../../util/SnappingManager';
import { Transform } from '../../../util/Transform';
-import { undoable, undoBatch, UndoManager } from '../../../util/UndoManager';
+import { undoable, UndoManager } from '../../../util/UndoManager';
import { Timeline } from '../../animationtimeline/Timeline';
import { ContextMenu } from '../../ContextMenu';
import { InkingStroke } from '../../InkingStroke';
import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView';
import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp';
-import { DocumentView } from '../../nodes/DocumentView';
+import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveEraserWidth, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, DocumentView, SetActiveInkColor, SetActiveInkWidth } from '../../nodes/DocumentView';
import { FieldViewProps } from '../../nodes/FieldView';
import { FocusViewOptions } from '../../nodes/FocusViewOptions';
import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
import { OpenWhere, OpenWhereMod } from '../../nodes/OpenWhere';
import { PinDocView, PinProps } from '../../PinFuncs';
import { StyleProp } from '../../StyleProp';
-import { CollectionSubView } from '../CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
import { TreeViewType } from '../CollectionTreeViewType';
import { CollectionFreeFormBackgroundGrid } from './CollectionFreeFormBackgroundGrid';
import { CollectionFreeFormClusters } from './CollectionFreeFormClusters';
@@ -70,7 +69,7 @@ export interface collectionFreeformViewProps {
childPointerEvents?: () => string | undefined;
viewField?: string;
noOverlay?: boolean; // used to suppress docs in the overlay (z) layer (ie, for minimap since overlay doesn't scale)
- engineProps?: any;
+ engineProps?: unknown;
getScrollHeight?: () => number | undefined;
}
@@ -82,13 +81,15 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
public unprocessedDocs: Doc[] = [];
public static collectionsWithUnprocessedInk = new Set<CollectionFreeFormView>();
public static from(dv?: DocumentView): CollectionFreeFormView | undefined {
- const parent = CollectionFreeFormDocumentView.from(dv)?._props.parent;
+ const parent = CollectionFreeFormDocumentView.from(dv)?._props.reactParent;
return parent instanceof CollectionFreeFormView ? parent : undefined;
}
private _clusters = new CollectionFreeFormClusters(this);
- private _oldWheel: any;
- private _panZoomTransitionTimer: any;
+ private _oldWheel: HTMLDivElement | null = null;
+ private _panZoomTransitionTimer: NodeJS.Timeout | undefined = undefined;
+ private _brushtimer: NodeJS.Timeout | undefined = undefined;
+ private _brushtimer1: NodeJS.Timeout | undefined = undefined;
private _lastX: number = 0;
private _lastY: number = 0;
private _downX: number = 0;
@@ -97,8 +98,6 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
private _disposers: { [name: string]: IReactionDisposer } = {};
private _renderCutoffData = observable.map<string, boolean>();
private _batch: UndoManager.Batch | undefined = undefined;
- private _brushtimer: any;
- private _brushtimer1: any;
private _keyTimer: NodeJS.Timeout | undefined; // timer for turning off transition flag when key frame change has completed. Need to clear this if you do a second navigation before first finishes, or else first timer can go off during second naviation.
private _presEaseFunc: string = 'ease';
@@ -122,14 +121,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@observable _marqueeViewRef = React.createRef<MarqueeView>();
@observable _brushedView: { width: number; height: number; panX: number; panY: number } | undefined = undefined; // highlighted region of freeform canvas used by presentations to indicate a region
@observable GroupChildDrag: boolean = false; // child document view being dragged. needed to update drop areas of groups when a group item is dragged.
- @observable _childPointerEvents: 'none' | 'all' | 'visiblepainted' | undefined = undefined;
+ @observable _childPointerEvents: Property.PointerEvents | undefined = undefined;
@observable _lightboxDoc: Opt<Doc> = undefined;
@observable _paintedId = 'id' + Utils.GenerateGuid().replace(/-/g, '');
@observable _keyframeEditing = false;
@observable _eraserX: number = 0;
@observable _eraserY: number = 0;
@observable _showEraserCircle: boolean = false; // to determine whether the radius eraser should show
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -139,12 +138,12 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
@computed get childPointerEvents() {
return SnappingManager.IsResizing
? 'none'
- : this._props.childPointerEvents?.() ??
+ : (this._props.childPointerEvents?.() ??
(this._props.viewDefDivClick || //
(this.layoutEngine === computePassLayout.name && !this._props.isSelected()) ||
this.isContentActive() === false
? 'none'
- : this._props.pointerEvents?.());
+ : this._props.pointerEvents?.()));
}
@computed get contentViews() {
const viewsMask = this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z && ele.inkMask !== -1 && ele.inkMask !== undefined).map(ele => ele.ele);
@@ -184,7 +183,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
.transform(this.panZoomXf);
}
@computed get backgroundColor() {
- return this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor);
+ return this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor) as string;
}
@computed get fitWidth() {
return this._props.fitWidth?.(this.Document) ?? this.layoutDoc.layout_fitWidth;
@@ -356,7 +355,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
* @param options
* @returns
*/
- focus = (anchor: Doc, options: FocusViewOptions): any => {
+ focus = (anchor: Doc, options: FocusViewOptions) => {
if (anchor.isGroup && !options.docTransform && options.contextPath?.length) {
// don't focus on group if there's a context path because we're about to focus on a group item
// which will override any group focus. (If we allowed the group to focus, it would mark didMove even if there were no net movement)
@@ -373,14 +372,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
const xfToCollection = options?.docTransform ?? Transform.Identity();
const savedState = { panX: NumCast(this.Document[this.panXFieldKey]), panY: NumCast(this.Document[this.panYFieldKey]), scale: options?.willZoomCentered ? this.Document[this.scaleFieldKey] : undefined };
const cantTransform = this.fitContentsToBox || ((this.Document.isGroup || this.layoutDoc._lockedTransform) && !DocumentView.LightboxDoc());
- const { panX, panY, scale } = cantTransform || (!options.willPan && !options.willZoomCentered) ? savedState : this.calculatePanIntoView(anchor, xfToCollection, options?.willZoomCentered ? options?.zoomScale ?? 0.75 : undefined);
+ const { panX, panY, scale } = cantTransform || (!options.willPan && !options.willZoomCentered) ? savedState : this.calculatePanIntoView(anchor, xfToCollection, options?.willZoomCentered ? (options?.zoomScale ?? 0.75) : undefined);
// focus on the document in the collection
const didMove = !cantTransform && !anchor.z && (panX !== savedState.panX || panY !== savedState.panY || scale !== savedState.scale);
if (didMove) options.didMove = true;
// glr: freeform transform speed can be set by adjusting presentation_transition field - needs a way of knowing when presentation is not active...
if (didMove) {
- const focusTime = options?.instant ? 0 : options.zoomTime ?? 500;
+ const focusTime = options?.instant ? 0 : (options.zoomTime ?? 500);
(options.zoomScale ?? options.willZoomCentered) && scale && (this.Document[this.scaleFieldKey] = scale);
this.setPan(panX, panY, focusTime); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
return focusTime;
@@ -442,8 +441,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return true;
}
- @undoBatch
- internalAnchorAnnoDrop(e: Event, de: DragManager.DropEvent, annoDragData: DragManager.AnchorAnnoDragData) {
+ internalAnchorAnnoDrop = undoable((e: Event, de: DragManager.DropEvent, annoDragData: DragManager.AnchorAnnoDragData) => {
const dropCreator = annoDragData.dropDocCreator;
const [xp, yp] = this.screenToFreeformContentsXf.transformPoint(de.x, de.y);
annoDragData.dropDocCreator = (annotationOn: Doc | undefined) => {
@@ -456,10 +454,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return dropDoc || this.Document;
};
return true;
- }
+ }, 'anchor drop');
- @undoBatch
- internalLinkDrop(e: Event, de: DragManager.DropEvent, linkDragData: DragManager.LinkDragData) {
+ internalLinkDrop = undoable((e: Event, de: DragManager.DropEvent, linkDragData: DragManager.LinkDragData) => {
if (this.DocumentView?.() && linkDragData.linkDragView.containerViewPath?.().includes(this.DocumentView())) {
const [x, y] = this.screenToFreeformContentsXf.transformPoint(de.x, de.y);
// do nothing if link is dropped into any freeform view parent of dragged document
@@ -475,9 +472,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return added;
}
return false;
- }
+ }, 'link drop');
- onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
+ onInternalDrop = (e: Event, de: DragManager.DropEvent): boolean => {
if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de, de.complete.annoDragData);
if (de.complete.linkDragData) return this.internalLinkDrop(e, de, de.complete.linkDragData);
if (de.complete.docDragData?.droppedDocuments.length) return this.internalDocDrop(e, de, de.complete.docDragData);
@@ -523,8 +520,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
};
- @undoBatch
- onGesture = (e: Event, ge: GestureUtils.GestureEvent) => {
+ onGesture = undoable((e: Event, ge: GestureUtils.GestureEvent) => {
switch (ge.gesture) {
case Gestures.Text:
if (ge.text) {
@@ -550,7 +546,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
_width: B.width + inkWidth,
_height: B.height + inkWidth,
stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore
- inkWidth
+ inkWidth,
+ ActiveInkColor(),
+ ActiveInkBezierApprox(),
+ ActiveFillColor(),
+ ActiveArrowStart(),
+ ActiveArrowEnd(),
+ ActiveDash(),
+ ActiveIsInkMask()
);
if (Doc.ActiveTool === InkTool.Write) {
this.unprocessedDocs.push(inkDoc);
@@ -560,7 +563,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
e.stopPropagation();
}
}
- };
+ }, 'gesture');
@action
onEraserUp = (): void => {
this._deleteList.lastElement()?._props.removeDocument?.(this._deleteList.map(ink => ink.Document));
@@ -634,7 +637,14 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
_width: B.width + inkWidth,
_height: B.height + inkWidth,
stroke_showLabel: BoolCast(Doc.UserDoc().activeInkHideTextLabels)}, // prettier-ignore
- inkWidth
+ inkWidth,
+ ActiveInkColor(),
+ ActiveInkBezierApprox(),
+ ActiveFillColor(),
+ ActiveArrowStart(),
+ ActiveArrowEnd(),
+ ActiveDash(),
+ ActiveIsInkMask()
);
});
newStrokes && this.addDocument?.(newStrokes);
@@ -684,8 +694,8 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return false;
};
- forceStrokeGesture = (e: PointerEvent, gesture: Gestures, points: InkData, text?: any) => {
- this.onGesture(e, new GestureUtils.GestureEvent(gesture, points, InkField.getBounds(points), text));
+ forceStrokeGesture = (e: PointerEvent, gesture: Gestures, points: InkData) => {
+ this.onGesture(e, new GestureUtils.GestureEvent(gesture, points, InkField.getBounds(points)));
};
onPointerMove = (e: PointerEvent) => {
@@ -1163,6 +1173,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
// for some reason bezier.js doesn't handle the case of intersecting a linear curve, so we wrap the intersection
// call in a test for linearity
bintersects = (curve: Bezier, otherCurve: Bezier) => {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((curve as any)._linear) {
// bezier.js doesn't intersect properly if the curve is actually a line -- so get intersect other curve against this line, then figure out the t coordinates of the intersection on this line
const intersections = otherCurve.lineIntersects({ p1: curve.points[0], p2: curve.points[3] });
@@ -1172,6 +1183,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return intT ? [intT] : [];
}
}
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
if ((otherCurve as any)._linear) {
return curve.lineIntersects({ p1: otherCurve.points[0], p2: otherCurve.points[3] });
}
@@ -1463,17 +1475,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
return ret;
};
childPointerEventsFunc = () => this._childPointerEvents;
- childContentsActive = () => (this._props.childContentsActive ?? this.isContentActive() === false ? returnFalse : emptyFunction)();
+ childContentsActive = () => ((this._props.childContentsActive ?? this.isContentActive() === false) ? returnFalse : emptyFunction)();
getChildDocView(entry: PoolData) {
const childLayout = entry.pair.layout;
const childData = entry.pair.data;
return (
<CollectionFreeFormDocumentView
- // eslint-disable-next-line react/jsx-props-no-spreading
- {...OmitKeys(entry, ['replica', 'pair']).omit}
+ // eslint-disable-next-line react/jsx-props-no-spreading, @typescript-eslint/no-explicit-any
+ {...(OmitKeys(entry, ['replica', 'pair']).omit as any)}
key={childLayout[Id] + (entry.replica || '')}
Document={childLayout}
- parent={this}
+ reactParent={this}
containerViewPath={this.DocumentView?.().docViewPath}
styleProvider={this._clusters.styleProvider}
TemplateDataDocument={childData}
@@ -1588,7 +1600,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
};
}
- onViewDefDivClick = (e: React.MouseEvent, payload: any) => {
+ onViewDefDivClick = (e: React.MouseEvent, payload: unknown) => {
(this._props.viewDefDivClick || ScriptCast(this.Document.onViewDefDivClick))?.script.run({ this: this.Document, payload });
e.stopPropagation();
};
@@ -1622,7 +1634,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
ele: (
<div
className="collectionFreeform-customDiv"
- title={viewDef.payload?.join(' ')}
+ title={StrListCast(viewDef.payload as string).join(' ')}
key={'div' + x + y + z + viewDef.payload}
onClick={e => this.onViewDefDivClick(e, viewDef)}
style={{ width, height, backgroundColor: color, transform }}
@@ -1639,11 +1651,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
* since rendering a large collection of documents can be slow, at startup, docs are rendered in batches.
* each doc's render() method will call the cutoff provider which will let the doc know if it should render itself yet, or wait
*/
- renderCutoffProvider = computedFn((doc: Doc) => (this.Document.isTemplateDoc ? false : !this._renderCutoffData.get(doc[Id] + '')));
+ renderCutoffProvider = computedFn((doc: Doc) => (this.Document.isTemplateDoc || this.Document.isTemplateForField ? false : !this._renderCutoffData.get(doc[Id] + '')));
doEngineLayout(
poolData: Map<string, PoolData>,
- engine: (poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: any) => ViewDefResult[]
+ engine: (poolData: Map<string, PoolData>, pivotDoc: Doc, childPairs: { layout: Doc; data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: ViewDefBounds[]) => ViewDefResult[], engineProps: unknown) => ViewDefResult[]
) {
return engine(poolData, this.Document, this.childLayoutPairs, [this._props.PanelWidth(), this._props.PanelHeight()], this.viewDefsToJSX, this._props.engineProps);
}
@@ -1673,7 +1685,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
.forEach(entry =>
elements.push({
ele: this.getChildDocView(entry[1]),
- bounds: (entry[1].opacity === 0 ? { ...entry[1], width: 0, height: 0 } : { ...entry[1] }) as any,
+ bounds: entry[1].opacity === 0 ? { payload: undefined, type: '', ...entry[1], width: 0, height: 0 } : { payload: undefined, type: '', ...entry[1] },
inkMask: BoolCast(entry[1].pair.layout.stroke_isInkMask) ? NumCast(entry[1].pair.layout.opacity, 1) : -1,
})
);
@@ -1756,7 +1768,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._disposers.pointerevents = reaction(
() => this.childPointerEvents,
pointerevents => {
- this._childPointerEvents = pointerevents as any;
+ this._childPointerEvents = pointerevents as Property.PointerEvents | undefined;
},
{ fireImmediately: true }
);
@@ -1795,24 +1807,27 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
Object.values(this._disposers).forEach(disposer => disposer?.());
}
- updateIcon = () =>
- UpdateIcon(
- this.layoutDoc[Id] + '-icon' + new Date().getTime(),
- this.DocumentView?.().ContentDiv!,
- NumCast(this.layoutDoc._width),
- NumCast(this.layoutDoc._height),
- this._props.PanelWidth(),
- this._props.PanelHeight(),
- 0,
- 1,
- false,
- '',
- (iconFile, nativeWidth, nativeHeight) => {
- this.dataDoc.icon = new ImageField(iconFile);
- this.dataDoc.icon_nativeWidth = nativeWidth;
- this.dataDoc.icon_nativeHeight = nativeHeight;
- }
- );
+ updateIcon = () => {
+ const contentDiv = this.DocumentView?.().ContentDiv;
+ contentDiv &&
+ UpdateIcon(
+ this.layoutDoc[Id] + '-icon' + new Date().getTime(),
+ contentDiv,
+ NumCast(this.layoutDoc._width),
+ NumCast(this.layoutDoc._height),
+ this._props.PanelWidth(),
+ this._props.PanelHeight(),
+ 0,
+ 1,
+ false,
+ '',
+ (iconFile, nativeWidth, nativeHeight) => {
+ this.dataDoc.icon = new ImageField(iconFile);
+ this.dataDoc.icon_nativeWidth = nativeWidth;
+ this.dataDoc.icon_nativeHeight = nativeHeight;
+ }
+ );
+ };
@action
onCursorMove = (e: React.PointerEvent) => {
@@ -1831,8 +1846,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this._showEraserCircle = true;
};
- @undoBatch
- promoteCollection = () => {
+ promoteCollection = undoable(() => {
const childDocs = this.childDocs.slice();
childDocs.forEach(docIn => {
const doc = docIn;
@@ -1841,10 +1855,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
doc.y = scr?.[1];
});
this._props.addDocTab(childDocs, OpenWhere.inParentFromScreen);
- };
+ }, 'promote collection');
- @undoBatch
- layoutDocsInGrid = () => {
+ layoutDocsInGrid = undoable(() => {
const docs = this.childLayoutPairs.map(pair => pair.layout);
const width = Math.max(...docs.map(doc => NumCast(doc._width))) + 20;
const height = Math.max(...docs.map(doc => NumCast(doc._height))) + 20;
@@ -1854,40 +1867,37 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
doc.x = NumCast(this.Document[this.panXFieldKey]) + (i % dim) * width - (width * dim) / 2;
doc.y = NumCast(this.Document[this.panYFieldKey]) + Math.floor(i / dim) * height - (height * dim) / 2;
});
- };
+ }, 'layout docs in grid');
- @undoBatch
- toggleNativeDimensions = () => Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight);
+ toggleNativeDimensions = undoable(() => Doc.toggleNativeDimensions(this.layoutDoc, 1, this.nativeWidth, this.nativeHeight), 'toggle native dimensions');
///
/// resetView restores a freeform collection to unit scale and centered at (0,0) UNLESS
/// the view is a group, in which case this does nothing (since Groups calculate their own scale and center)
///
- @undoBatch
- resetView = () => {
+ resetView = undoable(() => {
this.layoutDoc[this.panXFieldKey] = NumCast(this.dataDoc[this.panXFieldKey + '_reset']);
this.layoutDoc[this.panYFieldKey] = NumCast(this.dataDoc[this.panYFieldKey + '_reset']);
this.layoutDoc[this.scaleFieldKey] = NumCast(this.dataDoc[this.scaleFieldKey + '_reset'], 1);
- };
+ }, 'reset view');
///
/// resetView restores a freeform collection to unit scale and centered at (0,0) UNLESS
/// the view is a group, in which case this does nothing (since Groups calculate their own scale and center)
///
- @undoBatch
- toggleResetView = () => {
+ toggleResetView = undoable(() => {
this.dataDoc[this.autoResetFieldKey] = !this.dataDoc[this.autoResetFieldKey];
if (this.dataDoc[this.autoResetFieldKey]) {
this.dataDoc[this.panXFieldKey + '_reset'] = this.layoutDoc[this.panXFieldKey];
this.dataDoc[this.panYFieldKey + '_reset'] = this.layoutDoc[this.panYFieldKey];
this.dataDoc[this.scaleFieldKey + '_reset'] = this.layoutDoc[this.scaleFieldKey];
}
- };
+ }, 'toggle reset view');
onContextMenu = () => {
if (this._props.isAnnotationOverlay || !ContextMenu.Instance) return;
const appearance = ContextMenu.Instance.findByDescription('Appearance...');
- const appearanceItems = appearance && 'subitems' in appearance ? appearance.subitems : [];
+ const appearanceItems = appearance?.subitems ?? [];
!this.Document.isGroup && appearanceItems.push({ description: 'Reset View', event: this.resetView, icon: 'compress-arrows-alt' });
!this.Document.isGroup && appearanceItems.push({ description: 'Toggle Auto Reset View', event: this.toggleResetView, icon: 'compress-arrows-alt' });
if (this._props.setContentViewBox === emptyFunction) {
@@ -1914,7 +1924,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
!appearance && ContextMenu.Instance.addItem({ description: 'Appearance...', subitems: appearanceItems, icon: 'eye' });
const options = ContextMenu.Instance.findByDescription('Options...');
- const optionItems = options && 'subitems' in options ? options.subitems : [];
+ const optionItems = options?.subitems ?? [];
!this._props.isAnnotationOverlay &&
!Doc.noviceMode &&
optionItems.push({
@@ -1938,12 +1948,11 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
}
!options && ContextMenu.Instance.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' });
const mores = ContextMenu.Instance.findByDescription('More...');
- const moreItems = mores && 'subitems' in mores ? mores.subitems : [];
+ const moreItems = mores?.subitems ?? [];
!mores && ContextMenu.Instance.addItem({ description: 'More...', subitems: moreItems, icon: 'eye' });
};
- @undoBatch
- transcribeStrokes = () => {
+ transcribeStrokes = undoable(() => {
if (this.Document.isGroup && this.Document.transcription) {
const text = StrCast(this.Document.transcription);
const lines = text.split('\n');
@@ -1951,7 +1960,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
this.addDocument(Docs.Create.TextDocument(text, { title: lines[0], x: NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc._width) + 20, y: NumCast(this.layoutDoc.y), _width: 200, _height: height }));
}
- };
+ }, 'transcribe strokes');
@action
dragEnding = () => {
@@ -1993,7 +2002,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
incrementalRender = action(() => {
if (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.())) {
const layoutUnrendered = this.childDocs.filter(doc => !this._renderCutoffData.get(doc[Id]));
- const loadIncrement = this.Document.isTemplateDoc ? Number.MAX_VALUE : 5;
+ const loadIncrement = this.Document.isTemplateDoc || this.Document.isTemplateForField ? Number.MAX_VALUE : 5;
for (let i = 0; i < Math.min(layoutUnrendered.length, loadIncrement); i++) {
this._renderCutoffData.set(layoutUnrendered[i][Id] + '', true);
}
@@ -2117,7 +2126,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
onDragOver={e => e.preventDefault()}
onContextMenu={this.onContextMenu}
style={{
- pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : (this._props.pointerEvents?.() as any),
+ pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : this._props.pointerEvents?.(),
textAlign: this.isAnnotationOverlay ? 'initial' : undefined,
transform: `scale(${this.nativeDimScaling})`,
width: `${100 / this.nativeDimScaling}%`,
diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
index 1d3f88df1..50b91e8fe 100644
--- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
+++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx
@@ -1,26 +1,27 @@
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { IconButton, Size } from 'browndash-components';
+import * as faceapi from 'face-api.js';
+import { FaceMatcher } from 'face-api.js';
+import 'ldrs/ring';
+import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import React from 'react';
-import { Docs } from '../../../documents/Documents';
-import { DocumentType } from '../../../documents/DocumentTypes';
-import { ViewBoxBaseComponent } from '../../DocComponent';
-import { FieldView, FieldViewProps } from '../../nodes/FieldView';
-import 'ldrs/ring';
-import { SnappingManager } from '../../../util/SnappingManager';
-import { action, computed, makeObservable, observable, reaction } from 'mobx';
-import { Doc, DocListCast, NumListCast } from '../../../../fields/Doc';
+import { Utils } from '../../../../Utils';
+import { Doc, DocListCast } from '../../../../fields/Doc';
import { DocData } from '../../../../fields/DocSymbols';
+import { Id } from '../../../../fields/FieldSymbols';
+import { List } from '../../../../fields/List';
import { ImageCast, StrCast } from '../../../../fields/Types';
+import { DocumentType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
+import { DragManager } from '../../../util/DragManager';
+import { SnappingManager } from '../../../util/SnappingManager';
+import { ViewBoxBaseComponent } from '../../DocComponent';
import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { DocumentView } from '../../nodes/DocumentView';
+import { FieldView, FieldViewProps } from '../../nodes/FieldView';
import './FaceCollectionBox.scss';
-import { IconButton, Size } from 'browndash-components';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { MarqueeOptionsMenu } from './MarqueeOptionsMenu';
-import { List } from '../../../../fields/List';
-import { DocumentView } from '../../nodes/DocumentView';
-import { Utils } from '../../../../Utils';
-import { DragManager } from '../../../util/DragManager';
-import * as faceapi from 'face-api.js';
-import { FaceMatcher } from 'face-api.js';
interface FaceDocumentProps {
faceDoc: Doc;
@@ -36,7 +37,7 @@ export class FaceDocumentItem extends ObservableReactComponent<FaceDocumentProps
private _dropDisposer?: DragManager.DragDropDisposer;
private _inputRef = React.createRef<HTMLInputElement>();
- constructor(props: any) {
+ constructor(props: FaceDocumentProps) {
super(props);
makeObservable(this);
this.ref = React.createRef();
@@ -194,7 +195,7 @@ export class FaceCollectionBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}
- constructor(props: any) {
+ constructor(props: FieldViewProps) {
super(props);
makeObservable(this);
FaceCollectionBox.Instance = this;
@@ -204,7 +205,7 @@ export class FaceCollectionBox extends ViewBoxBaseComponent<FieldViewProps>() {
return (
<div className="searchBox-container" style={{ pointerEvents: 'all', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}>
{this.currentDocs.map(doc => {
- return <FaceDocumentItem faceDoc={doc} />;
+ return <FaceDocumentItem key={doc[Id]} faceDoc={doc} />;
})}
</div>
);
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index 2d9191dd7..61bd0241c 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -13,7 +13,7 @@ import { undoBatch } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { ContextMenuProps } from '../../ContextMenuItem';
import { DocumentView } from '../../nodes/DocumentView';
-import { CollectionSubView } from '../CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
import './CollectionGridView.scss';
import Grid, { Layout } from './Grid';
@@ -26,7 +26,7 @@ export class CollectionGridView extends CollectionSubView() {
@observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll
private dropLocation: object = {}; // sets the drop location for external drops
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -200,7 +200,7 @@ export class CollectionGridView extends CollectionSubView() {
whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
onClickScript={this.onChildClickHandler}
renderDepth={this._props.renderDepth + 1}
- dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy'
+ dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as 'x' | 'y' | 'xy'}
/>
);
}
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index eac0dc0e1..ceae43c04 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -1,8 +1,7 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { Toggle, ToggleType, Type } from 'browndash-components';
+import { Property } from 'csstype';
import { IReactionDisposer, action, makeObservable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
@@ -22,7 +21,7 @@ import { UndoStack } from '../../UndoStack';
import { DocumentLinksButton } from '../../nodes/DocumentLinksButton';
import { DocumentView } from '../../nodes/DocumentView';
import { LinkDescriptionPopup } from '../../nodes/LinkDescriptionPopup';
-import { CollectionSubView } from '../CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
import './CollectionLinearView.scss';
/**
@@ -39,7 +38,7 @@ export class CollectionLinearView extends CollectionSubView() {
private _widthDisposer?: IReactionDisposer;
private _selectedDisposer?: IReactionDisposer;
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -239,7 +238,7 @@ export class CollectionLinearView extends CollectionSubView() {
className="collectionLinearView-content"
style={{
height: this.dimension(),
- flexDirection: flexDir as any,
+ flexDirection: flexDir as Property.FlexDirection,
gap: flexGap,
}}>
{this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
index f983fd815..06d78c39e 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss
@@ -1,43 +1,50 @@
-.collectionMulticolumnView_contents {
- display: flex;
- //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template)
- width: 100%;
+.collectionMulticolumnView_drop {
height: 100%;
+ top: 0;
+ left: 0;
+ position: absolute;
- .document-wrapper {
+ .collectionMulticolumnView_contents {
display: flex;
- flex-direction: column;
+ //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template)
width: 100%;
- align-items: center;
- position: relative;
- > .iconButton-container {
- top: 0;
- left: 0;
- position: absolute;
- }
-
- .contentFittingDocumentView {
- margin: auto;
- }
+ height: 100%;
- .label-wrapper {
+ .document-wrapper {
display: flex;
- flex-direction: row;
- justify-content: center;
- height: 20px;
+ flex-direction: column;
+ width: 100%;
+ align-items: center;
+ position: relative;
+ > .iconButton-container {
+ top: 0;
+ left: 0;
+ position: absolute;
+ }
+
+ .contentFittingDocumentView {
+ margin: auto;
+ }
+
+ .label-wrapper {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ height: 20px;
+ }
}
- }
- .multiColumnResizer {
- cursor: ew-resize;
- transition: 0.5s opacity ease;
- display: flex;
- flex-direction: column;
+ .multiColumnResizer {
+ cursor: ew-resize;
+ transition: 0.5s opacity ease;
+ display: flex;
+ flex-direction: column;
- .multiColumnResizer-hdl {
- width: 100%;
- height: 100%;
- transition: 0.5s background-color ease;
+ .multiColumnResizer-hdl {
+ width: 100%;
+ height: 100%;
+ transition: 0.5s background-color ease;
+ }
}
}
}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index b8509a005..d67e10c0b 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -1,5 +1,3 @@
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { Button, IconButton } from 'browndash-components';
@@ -12,13 +10,14 @@ import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types
import { DragManager } from '../../../util/DragManager';
import { SettingsManager } from '../../../util/SettingsManager';
import { Transform } from '../../../util/Transform';
-import { undoBatch, undoable } from '../../../util/UndoManager';
+import { undoable } from '../../../util/UndoManager';
import { DocumentView } from '../../nodes/DocumentView';
-import { CollectionSubView } from '../CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
import './CollectionMulticolumnView.scss';
import ResizeBar from './MulticolumnResizer';
import WidthLabel from './MulticolumnWidthLabel';
import { dropActionType } from '../../../util/DropActionTypes';
+import { SnappingManager } from '../../../util/SnappingManager';
interface WidthSpecifier {
magnitude: number;
@@ -42,7 +41,7 @@ const resizerWidth = 8;
export class CollectionMulticolumnView extends CollectionSubView() {
@observable _startIndex = 0;
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -198,30 +197,28 @@ export class CollectionMulticolumnView extends CollectionSubView() {
* documents before the target.
*/
private lookupIndividualTransform = (layout: Doc) => {
- const { columnUnitLength } = this;
- if (columnUnitLength === undefined) {
+ if (this.columnUnitLength === undefined) {
return Transform.Identity(); // we're still waiting on promises to resolve
}
let offset = 0;
// eslint-disable-next-line no-restricted-syntax
for (const { layout: candidate } of this.childLayoutPairs) {
if (candidate === layout) {
- return this.ScreenToLocalBoxXf().translate(0, -offset / (this._props.NativeDimScaling?.() || 1));
+ return this.ScreenToLocalBoxXf().translate(-offset / (this._props.NativeDimScaling?.() || 1), 0);
}
offset += this.lookupPixels(candidate) + resizerWidth;
}
return Transform.Identity();
};
- @undoBatch
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
let dropInd = -1;
- if (de.complete.docDragData && this._mainCont) {
+ if (de.complete.docDragData && this._contRef.current) {
let curInd = -1;
de.complete.docDragData?.droppedDocuments.forEach(d => {
curInd = this.childDocs.indexOf(d);
});
- Array.from(this._mainCont.children).forEach((child, index) => {
+ Array.from(this._contRef.current.children).forEach((child, index) => {
const brect = child.getBoundingClientRect();
if (brect.x < de.x && brect.x + brect.width > de.x) {
if (curInd !== -1 && curInd === Math.floor(index / 2)) {
@@ -305,7 +302,7 @@ export class CollectionMulticolumnView extends CollectionSubView() {
whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
addDocTab={this._props.addDocTab}
pinToPres={this._props.pinToPres}
- dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy'
+ dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as 'x' | 'y' | 'xy'}
/>
);
};
@@ -319,11 +316,11 @@ export class CollectionMulticolumnView extends CollectionSubView() {
this.childLayouts.forEach((layout, i) => {
collector.push(
// eslint-disable-next-line react/no-array-index-key
- <Tooltip title={'Tab: ' + StrCast(layout.title)} key={'wrapper' + i}>
+ <Tooltip title={'Doc: ' + StrCast(layout.title)} key={'wrapper' + i}>
<div className="document-wrapper" style={{ flexDirection: 'column', width: this.lookupPixels(layout) }}>
{this.getDisplayDoc(layout)}
{this.layoutDoc._chromeHidden ? null : (
- <Button tooltip="Remove document from header bar" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(() => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} />
+ <Button tooltip="Remove document" icon={<FontAwesomeIcon icon="times" size="lg" />} onClick={undoable(() => this._props.removeDocument?.(layout), 'close doc')} color={SettingsManager.userColor} />
)}
<WidthLabel layout={layout} collectionDoc={this.Document} />
</div>
@@ -345,49 +342,53 @@ export class CollectionMulticolumnView extends CollectionSubView() {
return collector;
}
+ _contRef = React.createRef<HTMLDivElement>();
render() {
return (
- <div
- className="collectionMulticolumnView_contents"
- ref={this.createDashEventsTarget}
- style={{
- width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`,
- height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`,
- marginLeft: NumCast(this.Document._xMargin),
- marginRight: NumCast(this.Document._xMargin),
- marginTop: NumCast(this.Document._yMargin),
- marginBottom: NumCast(this.Document._yMargin),
- }}>
- {this.contents}
- {!this._startIndex ? null : (
- <Tooltip title="scroll back">
- <div
- style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }}
- onClick={action(() => {
- this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
- })}>
- <Button
- tooltip="Scroll back"
- icon={<FontAwesomeIcon icon="chevron-left" size="lg" />}
+ <div className="collectionMulticolumnView_drop" ref={this.createDashEventsTarget}>
+ <div
+ className="collectionMulticolumnView_contents"
+ ref={this._contRef}
+ style={{
+ pointerEvents: this._props.isContentActive() && SnappingManager.IsDragging ? 'all' : this._props.pointerEvents?.(),
+ width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`,
+ height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`,
+ marginLeft: NumCast(this.Document._xMargin),
+ marginRight: NumCast(this.Document._xMargin),
+ marginTop: NumCast(this.Document._yMargin),
+ marginBottom: NumCast(this.Document._yMargin),
+ }}>
+ {this.contents}
+ {!this._startIndex ? null : (
+ <Tooltip title="scroll back">
+ <div
+ style={{ position: 'absolute', bottom: 0, left: 0, background: SettingsManager.userVariantColor }}
+ onClick={action(() => {
+ this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
+ })}>
+ <Button
+ tooltip="Scroll back"
+ icon={<FontAwesomeIcon icon="chevron-left" size="lg" />}
+ onClick={action(() => {
+ this._startIndex = Math.max(0, this._startIndex - this.maxShown);
+ })}
+ color={SettingsManager.userColor}
+ />
+ </div>
+ </Tooltip>
+ )}
+ {this._startIndex > this.childLayoutPairs.length - 1 || !this.maxShown ? null : (
+ <Tooltip title="scroll forward">
+ <div
+ style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }}
onClick={action(() => {
- this._startIndex = Math.max(0, this._startIndex - this.maxShown);
- })}
- color={SettingsManager.userColor}
- />
- </div>
- </Tooltip>
- )}
- {this._startIndex > this.childLayoutPairs.length - 1 || !this.maxShown ? null : (
- <Tooltip title="scroll forward">
- <div
- style={{ position: 'absolute', bottom: 0, right: 0, background: SettingsManager.userVariantColor }}
- onClick={action(() => {
- this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
- })}>
- <IconButton icon={<FaChevronRight />} color={SettingsManager.userColor} />
- </div>
- </Tooltip>
- )}
+ this._startIndex = Math.min(this.childLayoutPairs.length - 1, this._startIndex + this.maxShown);
+ })}>
+ <IconButton icon={<FaChevronRight />} color={SettingsManager.userColor} />
+ </div>
+ </Tooltip>
+ )}
+ </div>
</div>
);
}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
index f44eacb2a..0d49fabaa 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss
@@ -1,34 +1,41 @@
-.collectionMultirowView_contents {
- display: flex;
- //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template)
- width: 100%;
+.collectionMultirowView_drop {
height: 100%;
- flex-direction: column;
+ top: 0;
+ left: 0;
+ position: absolute;
- .document-wrapper {
+ .collectionMultirowView_contents {
display: flex;
- flex-direction: row;
+ //overflow: hidden; // bcz: turned of to allow highlighting to appear when there is no border (e.g, for a component of the slide template)
+ width: 100%;
height: 100%;
- align-items: center;
+ flex-direction: column;
- .label-wrapper {
+ .document-wrapper {
display: flex;
flex-direction: row;
- justify-content: center;
- height: 20px;
+ height: 100%;
+ align-items: center;
+
+ .label-wrapper {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ height: 20px;
+ }
}
- }
- .multiRowResizer {
- cursor: ns-resize;
- transition: 0.5s opacity ease;
- display: flex;
- flex-direction: row;
+ .multiRowResizer {
+ cursor: ns-resize;
+ transition: 0.5s opacity ease;
+ display: flex;
+ flex-direction: row;
- .multiRowResizer-hdl {
- width: 100%;
- height: 100%;
- transition: 0.5s background-color ease;
+ .multiRowResizer-hdl {
+ width: 100%;
+ height: 100%;
+ transition: 0.5s background-color ease;
+ }
}
}
}
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 3fe3d5343..bda8e91ac 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -6,9 +6,8 @@ import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types
import { DragManager } from '../../../util/DragManager';
import { dropActionType } from '../../../util/DropActionTypes';
import { Transform } from '../../../util/Transform';
-import { undoBatch } from '../../../util/UndoManager';
import { DocumentView } from '../../nodes/DocumentView';
-import { CollectionSubView } from '../CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
import './CollectionMultirowView.scss';
import HeightLabel from './MultirowHeightLabel';
import ResizeBar from './MultirowResizer';
@@ -33,7 +32,7 @@ const resizerHeight = 8;
@observer
export class CollectionMultirowView extends CollectionSubView() {
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -193,15 +192,14 @@ export class CollectionMultirowView extends CollectionSubView() {
return Transform.Identity(); // type coersion, this case should never be hit
};
- @undoBatch
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
let dropInd = -1;
- if (de.complete.docDragData && this._mainCont) {
+ if (de.complete.docDragData && this._contRef.current) {
let curInd = -1;
de.complete.docDragData?.droppedDocuments.forEach(d => {
curInd = this.childDocs.indexOf(d);
});
- Array.from(this._mainCont.children).forEach((child, index) => {
+ Array.from(this._contRef.current.children).forEach((child, index) => {
const brect = child.getBoundingClientRect();
if (brect.y < de.y && brect.y + brect.height > de.y) {
if (curInd !== -1 && curInd === Math.floor(index / 2)) {
@@ -284,7 +282,7 @@ export class CollectionMultirowView extends CollectionSubView() {
whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
addDocTab={this._props.addDocTab}
pinToPres={this._props.pinToPres}
- dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as any} // 'y', 'x', 'xy'
+ dontCenter={StrCast(this.layoutDoc.layout_dontCenter) as 'y' | 'x' | 'xy'}
/>
);
};
@@ -318,20 +316,23 @@ export class CollectionMultirowView extends CollectionSubView() {
return collector;
}
+ _contRef = React.createRef<HTMLDivElement>();
render() {
return (
- <div
- className="collectionMultirowView_contents"
- style={{
- width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`,
- height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`,
- marginLeft: NumCast(this.Document._xMargin),
- marginRight: NumCast(this.Document._xMargin),
- marginTop: NumCast(this.Document._yMargin),
- marginBottom: NumCast(this.Document._yMargin),
- }}
- ref={this.createDashEventsTarget}>
- {this.contents}
+ <div className="collectionMultirowView_drop" ref={this.createDashEventsTarget}>
+ <div
+ ref={this._contRef}
+ className="collectionMultirowView_contents"
+ style={{
+ width: `calc(100% - ${2 * NumCast(this.Document._xMargin)}px)`,
+ height: `calc(100% - ${2 * NumCast(this.Document._yMargin)}px)`,
+ marginLeft: NumCast(this.Document._xMargin),
+ marginRight: NumCast(this.Document._xMargin),
+ marginTop: NumCast(this.Document._yMargin),
+ marginBottom: NumCast(this.Document._yMargin),
+ }}>
+ {this.contents}
+ </div>
</div>
);
}
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
index 931e2c5e0..10a6fa2e9 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
@@ -68,7 +68,7 @@ export default class ResizeBar extends React.Component<ResizerProps> {
style={{
pointerEvents: this.props.isContentActive?.() ? 'all' : 'none',
width: this.props.width,
- backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor),
+ backgroundColor: !this.props.isContentActive?.() ? '' : (this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor) as string),
}}>
<div className="multiColumnResizer-hdl" onPointerDown={e => this.registerResizing(e)} />
</div>
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
index cff0a8b4c..918365700 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
@@ -66,7 +66,7 @@ export default class ResizeBar extends React.Component<ResizerProps> {
style={{
pointerEvents: this.props.isContentActive?.() ? 'all' : 'none',
height: this.props.height,
- backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor),
+ backgroundColor: !this.props.isContentActive?.() ? '' : this.props.styleProvider?.(undefined, undefined, StyleProp.WidgetColor) as string,
}}>
<div className="multiRowResizer-hdl" onPointerDown={e => this.registerResizing(e)} />
</div>
diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
index 7c2cfd15f..8b0639b3b 100644
--- a/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
+++ b/src/client/views/collections/collectionSchema/CollectionSchemaView.tsx
@@ -4,7 +4,7 @@ import { Popup, PopupTrigger, Type } from 'browndash-components';
import { ObservableMap, action, computed, makeObservable, observable, observe, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { returnEmptyDoclist, returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../ClientUtils';
+import { returnEmptyString, returnFalse, returnIgnore, returnNever, returnTrue, setupMoveUpEvents, smoothScroll } from '../../../../ClientUtils';
import { emptyFunction } from '../../../../Utils';
import { Doc, DocListCast, Field, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
import { DocData } from '../../../../fields/DocSymbols';
@@ -22,16 +22,17 @@ import { ContextMenu } from '../../ContextMenu';
import { EditableView } from '../../EditableView';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { StyleProp } from '../../StyleProp';
-import { DefaultStyleProvider } from '../../StyleProvider';
+import { DefaultStyleProvider, returnEmptyDocViewList } from '../../StyleProvider';
import { Colors } from '../../global/globalEnums';
import { DocumentView } from '../../nodes/DocumentView';
import { FieldViewProps } from '../../nodes/FieldView';
import { FocusViewOptions } from '../../nodes/FocusViewOptions';
-import { CollectionSubView } from '../CollectionSubView';
+import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView';
import './CollectionSchemaView.scss';
import { SchemaColumnHeader } from './SchemaColumnHeader';
import { SchemaRowBox } from './SchemaRowBox';
+// eslint-disable-next-line @typescript-eslint/no-var-requires
const { SCHEMA_NEW_NODE_HEIGHT } = require('../../global/globalCssVariables.module.scss'); // prettier-ignore
export const FInfotoColType: { [key: string]: ColumnType } = {
@@ -48,14 +49,14 @@ const defaultColumnKeys: string[] = ['title', 'type', 'author', 'author_date', '
@observer
export class CollectionSchemaView extends CollectionSubView() {
- private _keysDisposer: any;
+ private _keysDisposer?: () => void;
private _previewRef: HTMLDivElement | null = null;
private _makeNewColumn: boolean = false;
private _documentOptions: DocumentOptions = new DocumentOptions();
private _tableContentRef: HTMLDivElement | null = null;
private _menuTarget = React.createRef<HTMLDivElement>();
- constructor(props: any) {
+ constructor(props: SubCollectionViewProps) {
super(props);
makeObservable(this);
}
@@ -75,7 +76,7 @@ export class CollectionSchemaView extends CollectionSubView() {
@observable _columnMenuIndex: number | undefined = undefined;
@observable _newFieldWarning: string = '';
@observable _makeNewField: boolean = false;
- @observable _newFieldDefault: any = 0;
+ @observable _newFieldDefault: boolean | number | string | undefined = 0;
@observable _newFieldType: ColumnType = ColumnType.Number;
@observable _menuValue: string = '';
@observable _filterColumnIndex: number | undefined = undefined;
@@ -160,11 +161,11 @@ export class CollectionSchemaView extends CollectionSubView() {
Object.entries(this._documentOptions).forEach((pair: [string, FInfo]) => this.fieldInfos.set(pair[0], pair[1]));
this._keysDisposer = observe(
this.dataDoc[this.fieldKey ?? 'data'] as List<Doc>,
- (change: any) => {
+ change => {
switch (change.type) {
case 'splice':
// prettier-ignore
- (change as any).added.forEach((doc: Doc) => // for each document added
+ change.added.filter(doc => doc instanceof Doc).map(doc => doc as Doc).forEach((doc: Doc) => // for each document added
Doc.GetAllPrototypes(doc.value as Doc).forEach(proto => // for all of its prototypes (and itself)
Object.keys(proto).forEach(action(key => // check if any of its keys are new, and add them
!this.fieldInfos.get(key) && this.fieldInfos.set(key, new FInfo("-no description-", key === 'author'))))));
@@ -269,7 +270,7 @@ export class CollectionSchemaView extends CollectionSubView() {
addRow = (doc: Doc | Doc[]) => this.addDocument(doc);
@undoBatch
- changeColumnKey = (index: number, newKey: string, defaultVal?: any) => {
+ changeColumnKey = (index: number, newKey: string, defaultVal?: string | number | boolean) => {
if (!this.documentKeys.includes(newKey)) {
this.addNewKey(newKey, defaultVal);
}
@@ -280,7 +281,7 @@ export class CollectionSchemaView extends CollectionSubView() {
};
@undoBatch
- addColumn = (key: string, defaultVal?: any) => {
+ addColumn = (key: string, defaultVal?: string | number | boolean) => {
if (!this.documentKeys.includes(key)) {
this.addNewKey(key, defaultVal);
}
@@ -297,7 +298,7 @@ export class CollectionSchemaView extends CollectionSubView() {
};
@action
- addNewKey = (key: string, defaultVal: any) =>
+ addNewKey = (key: string, defaultVal?: string | number | boolean) =>
this.childDocs.forEach(doc => {
doc[DocData][key] = defaultVal;
});
@@ -316,7 +317,7 @@ export class CollectionSchemaView extends CollectionSubView() {
};
@action
- startResize = (e: any, index: number) => {
+ startResize = (e: React.PointerEvent, index: number) => {
this._displayColumnWidths = this.storedColumnWidths;
setupMoveUpEvents(this, e, moveEv => this.resizeColumn(moveEv, index), this.finishResize, emptyFunction);
};
@@ -603,7 +604,7 @@ export class CollectionSchemaView extends CollectionSubView() {
};
scrollToDoc = (doc: Doc, options: FocusViewOptions) => {
- const found = this._tableContentRef && Array.from(this._tableContentRef.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]);
+ const found = this._tableContentRef && Array.from(this._tableContentRef.getElementsByClassName('documentView-node')).find(node => node.id === doc[Id]);
if (found) {
const rect = found.getBoundingClientRect();
const localRect = this.ScreenToLocalBoxXf().transformBounds(rect.left, rect.top, rect.width, rect.height);
@@ -624,9 +625,9 @@ export class CollectionSchemaView extends CollectionSubView() {
type="number"
name=""
id=""
- value={this._newFieldDefault ?? 0}
+ value={Number(this._newFieldDefault ?? 0)}
onPointerDown={e => e.stopPropagation()}
- onChange={action((e: any) => {
+ onChange={action(e => {
this._newFieldDefault = e.target.value;
})}
/>
@@ -636,11 +637,9 @@ export class CollectionSchemaView extends CollectionSubView() {
<>
<input
type="checkbox"
- name=""
- id=""
- value={this._newFieldDefault}
+ value={this._newFieldDefault?.toString()}
onPointerDown={e => e.stopPropagation()}
- onChange={action((e: any) => {
+ onChange={action(e => {
this._newFieldDefault = e.target.checked;
})}
/>
@@ -653,9 +652,9 @@ export class CollectionSchemaView extends CollectionSubView() {
type="text"
name=""
id=""
- value={this._newFieldDefault ?? ''}
+ value={this._newFieldDefault?.toString() ?? ''}
onPointerDown={e => e.stopPropagation()}
- onChange={action((e: any) => {
+ onChange={action(e => {
this._newFieldDefault = e.target.value;
})}
/>
@@ -682,7 +681,7 @@ export class CollectionSchemaView extends CollectionSubView() {
};
@action
- setKey = (key: string, defaultVal?: any) => {
+ setKey = (key: string, defaultVal?: string | number | boolean) => {
if (this._makeNewColumn) {
this.addColumn(key, defaultVal);
} else {
@@ -855,16 +854,16 @@ export class CollectionSchemaView extends CollectionSubView() {
onKeysPassiveWheel = (e: WheelEvent) => {
// if scrollTop is 0, then don't let wheel trigger scroll on any container (which it would since onScroll won't be triggered on this)
- if (!this._oldKeysWheel.scrollTop && e.deltaY <= 0) e.preventDefault();
+ if (!this._oldKeysWheel?.scrollTop && e.deltaY <= 0) e.preventDefault();
e.stopPropagation();
};
- _oldKeysWheel: any;
+ _oldKeysWheel: HTMLDivElement | null = null;
@computed get keysDropdown() {
return (
<div className="schema-key-search">
<div
className="schema-column-menu-button"
- onPointerDown={action((e: any) => {
+ onPointerDown={action(e => {
e.stopPropagation();
this._makeNewField = true;
})}>
@@ -879,6 +878,7 @@ export class CollectionSchemaView extends CollectionSubView() {
}}>
{this._menuKeys.map(key => (
<div
+ key={key}
className="schema-search-result"
onPointerDown={e => {
e.stopPropagation();
@@ -961,7 +961,7 @@ export class CollectionSchemaView extends CollectionSubView() {
{this.renderFilterOptions}
<div
className="schema-column-menu-button"
- onPointerDown={action((e: any) => {
+ onPointerDown={action(e => {
e.stopPropagation();
this.closeFilterMenu();
})}>
@@ -1012,7 +1012,7 @@ export class CollectionSchemaView extends CollectionSubView() {
screenToLocal = () => this.ScreenToLocalBoxXf().translate(-this.tableWidth, 0);
previewWidthFunc = () => this.previewWidth;
onPassiveWheel = (e: WheelEvent) => e.stopPropagation();
- _oldWheel: any;
+ _oldWheel: HTMLDivElement | null = null;
render() {
return (
<div className="collectionSchemaView" ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} onDrop={this.onExternalDrop.bind(this)} onPointerMove={e => this.onPointerMove(e)}>
@@ -1111,7 +1111,7 @@ export class CollectionSchemaView extends CollectionSubView() {
childFiltersByRanges={this.childDocRangeFilters}
searchFilterDocs={this.searchFilterDocs}
styleProvider={DefaultStyleProvider}
- containerViewPath={returnEmptyDoclist}
+ containerViewPath={returnEmptyDocViewList}
moveDocument={this._props.moveDocument}
addDocument={this.addRow}
removeDocument={this._props.removeDocument}
@@ -1136,7 +1136,7 @@ interface CollectionSchemaViewDocProps {
@observer
class CollectionSchemaViewDoc extends ObservableReactComponent<CollectionSchemaViewDocProps> {
- constructor(props: any) {
+ constructor(props: CollectionSchemaViewDocProps) {
super(props);
makeObservable(this);
}
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index 6b5a34ec0..e0ed8d01e 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -18,8 +18,8 @@ export interface SchemaColumnHeaderProps {
setSort: (field: string | undefined, desc?: boolean) => void;
removeColumn: (index: number) => void;
rowHeight: () => number;
- resizeColumn: (e: any, index: number) => void;
- dragColumn: (e: any, index: number) => boolean;
+ resizeColumn: (e: React.PointerEvent, index: number) => void;
+ dragColumn: (e: PointerEvent, index: number) => boolean;
openContextMenu: (x: number, y: number, index: number) => void;
setColRef: (index: number, ref: HTMLDivElement) => void;
}
diff --git a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
index 760089ffb..a7e0e916b 100644
--- a/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaRowBox.tsx
@@ -58,8 +58,8 @@ export class SchemaRowBox extends ViewBoxBaseComponent<SchemaRowBoxProps>() {
selectCell = (doc: Doc, col: number, shift: boolean, ctrl: boolean) => this.schemaView?.selectCell(doc, col, shift, ctrl);
deselectCell = () => this.schemaView?.deselectAllCells();
selectedCells = () => this.schemaView?._selectedDocs;
- setColumnValues = (field: any, value: any) => this.schemaView?.setColumnValues(field, value) ?? false;
- setSelectedColumnValues = (field: any, value: any) => this.schemaView?.setSelectedColumnValues(field, value) ?? false;
+ setColumnValues = (field: string, value: string) => this.schemaView?.setColumnValues(field, value) ?? false;
+ setSelectedColumnValues = (field: string, value: string) => this.schemaView?.setSelectedColumnValues(field, value) ?? false;
columnWidth = computedFn((index: number) => () => this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth);
render() {
return (
diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
index 5874364e0..22506cac1 100644
--- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable jsx-a11y/alt-text */
/* eslint-disable react/jsx-props-no-spreading */
/* eslint-disable no-use-before-define */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -10,10 +9,10 @@ import * as React from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import Select from 'react-select';
-import { ClientUtils, StopEvent, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../../ClientUtils';
+import { ClientUtils, StopEvent, returnEmptyFilter, returnFalse, returnZero } from '../../../../ClientUtils';
import { emptyFunction } from '../../../../Utils';
import { DateField } from '../../../../fields/DateField';
-import { Doc, DocListCast, Field } from '../../../../fields/Doc';
+import { Doc, DocListCast, Field, returnEmptyDoclist } from '../../../../fields/Doc';
import { RichTextField } from '../../../../fields/RichTextField';
import { ColumnType } from '../../../../fields/SchemaHeaderField';
import { BoolCast, Cast, DateCast, DocCast, FieldValue, StrCast, toList } from '../../../../fields/Types';
@@ -22,7 +21,7 @@ import { FInfo, FInfoFieldType } from '../../../documents/Documents';
import { dropActionType } from '../../../util/DropActionTypes';
import { SnappingManager } from '../../../util/SnappingManager';
import { Transform } from '../../../util/Transform';
-import { undoBatch, undoable } from '../../../util/UndoManager';
+import { undoable } from '../../../util/UndoManager';
import { EditableView } from '../../EditableView';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { DefaultStyleProvider, returnEmptyDocViewList } from '../../StyleProvider';
@@ -138,7 +137,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
ref={r => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)}
oneLine={this._props.oneLine}
allowCRs={this._props.allowCRs}
- contents={undefined}
+ contents={''}
fieldContents={fieldProps}
editing={selectedCell(this._props) ? undefined : false}
GetValue={() => Field.toKeyValueString(fieldProps.Document, this._props.fieldKey, SnappingManager.MetaKey)}
@@ -209,7 +208,7 @@ export class SchemaTableCell extends ObservableReactComponent<SchemaTableCellPro
// mj: most of this is adapted from old schema code so I'm not sure what it does tbh
@observer
export class SchemaImageCell extends ObservableReactComponent<SchemaTableCellProps> {
- constructor(props: any) {
+ constructor(props: SchemaTableCellProps) {
super(props);
makeObservable(this);
}
@@ -276,7 +275,7 @@ export class SchemaImageCell extends ObservableReactComponent<SchemaTableCellPro
@observer
export class SchemaDateCell extends ObservableReactComponent<SchemaTableCellProps> {
- constructor(props: any) {
+ constructor(props: SchemaTableCellProps) {
super(props);
makeObservable(this);
}
@@ -324,7 +323,7 @@ export class SchemaDateCell extends ObservableReactComponent<SchemaTableCellProp
}
@observer
export class SchemaRTFCell extends ObservableReactComponent<SchemaTableCellProps> {
- constructor(props: any) {
+ constructor(props: SchemaTableCellProps) {
super(props);
makeObservable(this);
}
@@ -343,7 +342,7 @@ export class SchemaRTFCell extends ObservableReactComponent<SchemaTableCellProps
}
@observer
export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProps> {
- constructor(props: any) {
+ constructor(props: SchemaTableCellProps) {
super(props);
makeObservable(this);
}
@@ -356,18 +355,19 @@ export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProp
style={{ marginRight: 4 }}
type="checkbox"
checked={BoolCast(this._props.Document[this._props.fieldKey])}
- onChange={undoBatch((value: React.ChangeEvent<HTMLInputElement> | undefined) => {
- if ((value?.nativeEvent as any).shiftKey) {
+ onChange={undoable((value: React.ChangeEvent<HTMLInputElement> | undefined) => {
+ if ((value?.nativeEvent as MouseEvent | PointerEvent).shiftKey) {
this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? ''));
} else Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? ''));
- })}
+ }, 'set bool cell')}
/>
+
<EditableView
- contents={undefined}
+ contents=""
fieldContents={fieldProps}
editing={selectedCell(this._props) ? undefined : false}
GetValue={() => Field.toKeyValueString(this._props.Document, this._props.fieldKey)}
- SetValue={undoBatch((value: string, shiftDown?: boolean, enterKey?: boolean) => {
+ SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => {
if (shiftDown && enterKey) {
this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value);
this._props.finishEdit?.();
@@ -376,7 +376,7 @@ export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProp
const set = Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Document) ? true : undefined);
this._props.finishEdit?.();
return set;
- })}
+ }, 'set bool cell')}
/>
</div>
);
@@ -384,7 +384,7 @@ export class SchemaBoolCell extends ObservableReactComponent<SchemaTableCellProp
}
@observer
export class SchemaEnumerationCell extends ObservableReactComponent<SchemaTableCellProps> {
- constructor(props: any) {
+ constructor(props: SchemaTableCellProps) {
super(props);
makeObservable(this);
}