From 939e18624af4252551f38c43335ee8ef0acd144c Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 21 Apr 2024 19:03:49 -0400 Subject: more lint cleanup --- .../views/nodes/CollectionFreeFormDocumentView.tsx | 44 +- src/client/views/nodes/ComparisonBox.tsx | 17 +- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 115 ++-- .../nodes/DataVizBox/components/Histogram.tsx | 230 ++++---- .../nodes/DataVizBox/components/LineChart.tsx | 107 ++-- .../views/nodes/DataVizBox/components/TableBox.tsx | 80 +-- src/client/views/nodes/DocumentContentsView.tsx | 33 +- src/client/views/nodes/DocumentLinksButton.tsx | 34 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/FieldView.tsx | 10 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 60 +- src/client/views/nodes/ImageBox.tsx | 7 +- src/client/views/nodes/KeyValuePair.tsx | 13 +- src/client/views/nodes/LabelBox.tsx | 25 +- src/client/views/nodes/LinkAnchorBox.tsx | 6 +- src/client/views/nodes/MapBox/MapBox.tsx | 25 +- .../views/nodes/MapboxMapBox/MapboxContainer.tsx | 31 +- src/client/views/nodes/PDFBox.tsx | 100 ++-- .../views/nodes/RecordingBox/RecordingBox.tsx | 37 +- src/client/views/nodes/ScreenshotBox.tsx | 29 +- src/client/views/nodes/VideoBox.tsx | 103 ++-- src/client/views/nodes/WebBox.tsx | 153 +++-- .../views/nodes/formattedText/DashFieldView.tsx | 310 +++++----- .../nodes/formattedText/FormattedTextBox.scss | 3 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 +- .../formattedText/ProsemirrorExampleTransfer.ts | 51 +- .../views/nodes/formattedText/RichTextMenu.tsx | 226 +++----- .../views/nodes/formattedText/RichTextRules.ts | 2 +- src/client/views/nodes/formattedText/marks_rts.ts | 30 +- src/client/views/nodes/formattedText/nodes_rts.ts | 14 +- src/client/views/nodes/trails/PresBox.tsx | 635 +++++++++++++-------- src/client/views/nodes/trails/PresElementBox.tsx | 96 ++-- 32 files changed, 1479 insertions(+), 1151 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 958d63267..6a86af6a7 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -97,7 +97,9 @@ export class CollectionFreeFormDocumentView extends DocComponent (this.Document[TransitionTimer] = this.Transition = undefined)), + action(() => { + this.Document[TransitionTimer] = this.Transition = undefined; + }), num ); } @@ -105,7 +107,11 @@ export class CollectionFreeFormDocumentView extends DocComponent>) { super.componentDidUpdate(prevProps); - this.WrapperKeys.forEach(action(keys => ((this as any)[keys.upper] = (this.props as any)[keys.lower]))); + this.WrapperKeys.forEach( + action(keys => { + (this as any)[keys.upper] = (this.props as any)[keys.lower]; + }) + ); } CollectionFreeFormView = this.props.CollectionFreeFormView; // needed for type checking @@ -121,6 +127,7 @@ export class CollectionFreeFormDocumentView extends DocComponent { - p[val.key] = Cast(doc[`${val.key}_indexed`], listSpec('number'), fillIn ? [NumCast(doc[val.key], val.val)] : []).reduce((p, v, i) => ((i <= Math.round(time) && v !== undefined) || p === undefined ? v : p), undefined as any as number); + p[val.key] = Cast(doc[`${val.key}_indexed`], listSpec('number'), fillIn ? [NumCast(doc[val.key], val.val)] : []).reduce( + (prev, v, i) => ((i <= Math.round(time) && v !== undefined) || prev === undefined ? v : prev), + undefined as any as number + ); return p; }, {} as { [val: string]: Opt } @@ -139,7 +149,7 @@ export class CollectionFreeFormDocumentView extends DocComponent { - p[val] = Cast(doc[`${val}_indexed`], listSpec('string'), [StrCast(doc[val])]).reduce((p, v, i) => ((i <= Math.round(time) && v !== undefined) || p === undefined ? v : p), undefined as any as string); + p[val] = Cast(doc[`${val}_indexed`], listSpec('string'), [StrCast(doc[val])]).reduce((prev, v, i) => ((i <= Math.round(time) && v !== undefined) || prev === undefined ? v : prev), undefined as any as string); return p; }, {} as { [val: string]: Opt } @@ -179,15 +189,21 @@ export class CollectionFreeFormDocumentView extends DocComponent { if (doc.appearFrame === undefined) doc.appearFrame = currTimecode; - if (!doc['opacity_indexed']) { + if (!doc.opacity_indexed) { // opacity is unlike other fields because it's value should not be undefined before it appears to enable it to fade-in - doc['opacity_indexed'] = new List(numberRange(currTimecode + 1).map(t => (!doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1))); + doc.opacity_indexed = new List(numberRange(currTimecode + 1).map(t => (!doc.z && makeAppear && t < NumCast(doc.appearFrame) ? 0 : 1))); } - CollectionFreeFormDocumentView.animFields.forEach(val => (doc[val.key] = ComputedField.MakeInterpolatedNumber(val.key, 'activeFrame', doc, currTimecode, val.val))); - CollectionFreeFormDocumentView.animStringFields.forEach(val => (doc[val] = ComputedField.MakeInterpolatedString(val, 'activeFrame', doc, currTimecode))); - CollectionFreeFormDocumentView.animDataFields(doc).forEach(val => (doc[val] = ComputedField.MakeInterpolatedDataField(val, 'activeFrame', doc, currTimecode))); + CollectionFreeFormDocumentView.animFields.forEach(val => { + doc[val.key] = ComputedField.MakeInterpolatedNumber(val.key, 'activeFrame', doc, currTimecode, val.val); + }); + CollectionFreeFormDocumentView.animStringFields.forEach(val => { + doc[val] = ComputedField.MakeInterpolatedString(val, 'activeFrame', doc, currTimecode); + }); + CollectionFreeFormDocumentView.animDataFields(doc).forEach(val => { + doc[val] = ComputedField.MakeInterpolatedDataField(val, 'activeFrame', doc, currTimecode); + }); const targetDoc = doc; // data fields, like rtf 'text' exist on the data doc, so - //doc !== targetDoc && (targetDoc.embedContainer = doc.embedContainer); // the computed fields don't see the layout doc -- need to copy the embedContainer to the data doc (HACK!!!) and set the activeFrame on the data doc (HACK!!!) + // doc !== targetDoc && (targetDoc.embedContainer = doc.embedContainer); // the computed fields don't see the layout doc -- need to copy the embedContainer to the data doc (HACK!!!) and set the activeFrame on the data doc (HACK!!!) targetDoc.activeFrame = ComputedField.MakeFunction('this.embedContainer?._currentFrame||0'); targetDoc.dataTransition = 'inherit'; }); @@ -202,16 +218,14 @@ export class CollectionFreeFormDocumentView extends DocComponent SelectionManager.SelectView(DocumentManager.Instance.getDocumentView(topDoc, containerDocView), false), 0); } @@ -259,6 +273,7 @@ export class CollectionFreeFormDocumentView extends DocComponent ) : ( val.lower)).omit} // prettier-ignore DataTransition={this.DataTransition} LocalRotation={this.localRotation} @@ -274,6 +289,7 @@ export class CollectionFreeFormDocumentView extends DocComponent() e, this.onPointerMove, emptyFunction, - action((e, doubleTap) => { + action((moveEv, doubleTap) => { if (doubleTap) { this._isAnyChildContentActive = true; if (!this.dataDoc[this.fieldKey + '_1'] && !this.dataDoc[this.fieldKey]) this.dataDoc[this.fieldKey + '_1'] = DocUtils.copyDragFactory(Doc.UserDoc().emptyNote as Doc); @@ -140,14 +140,14 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() setupMoveUpEvents( this, e, - e => { + moveEv => { const de = new DragManager.DocumentDragData([DocCast(this.dataDoc[which])], dropActionType.move); de.moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean): boolean => { this.clearDoc(which); return addDocument(doc); }; de.canEmbed = true; - DragManager.StartDocumentDrag([this._closeRef.current!], de, e.clientX, e.clientY); + DragManager.StartDocumentDrag([this._closeRef.current!], de, moveEv.clientX, moveEv.clientY); return true; }, emptyFunction, @@ -158,10 +158,10 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() if (property === StyleProp.PointerEvents) return 'none'; return this._props.styleProvider?.(doc, props, property); }; - moveDoc1 = (doc: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true); - moveDoc2 = (doc: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true); - remDoc1 = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true); - remDoc2 = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_2'), true); + moveDoc1 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (docs instanceof Doc ? [docs] : docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_1'), true); + moveDoc2 = (docs: Doc | Doc[], targetCol: Doc | undefined, addDoc: any) => (docs instanceof Doc ? [docs] : docs).reduce((res, doc: Doc) => res && this.moveDoc(doc, addDoc, this.fieldKey + '_2'), true); + remDoc1 = (docs: Doc | Doc[]) => (docs instanceof Doc ? [docs] : docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_1'), true); + remDoc2 = (docs: Doc | Doc[]) => (docs instanceof Doc ? [docs] : docs).reduce((res, doc) => res && this.remDoc(doc, this.fieldKey + '_2'), true); /** * Tests for whether a comparison box slot (ie, before or after) has renderable text content @@ -196,7 +196,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent() _closeRef = React.createRef(); render() { - trace(); const clearButton = (which: string) => (
() im setupMoveUpEvents( this, e, - action(e => { + action(moveEv => { MarqueeAnnotator.clearAnnotations(this._savedAnnotations); - this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]); + this._marqueeref.current?.onInitiateSelection([moveEv.clientX, moveEv.clientY]); return true; }), returnFalse, @@ -95,7 +95,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im // all CSV records in the dataset (that aren't an empty row) @computed.struct get records() { - var records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href); + const records = DataVizBox.dataset.get(CsvCast(this.dataDoc[this.fieldKey]).url.href); return records?.filter(record => Object.keys(record).some(key => record[key])) ?? []; } @@ -110,11 +110,15 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im @computed.struct get axes() { return StrListCast(this.layoutDoc._dataViz_axes); } - selectAxes = (axes: string[]) => (this.layoutDoc._dataViz_axes = new List(axes)); + selectAxes = (axes: string[]) => { + this.layoutDoc._dataViz_axes = new List(axes); + }; @computed.struct get titleCol() { return StrCast(this.layoutDoc._dataViz_titleCol); } - selectTitleCol = (titleCol: string) => (this.layoutDoc._dataViz_titleCol = titleCol); + selectTitleCol = (titleCol: string) => { + this.layoutDoc._dataViz_titleCol = titleCol; + }; @action // pinned / linked anchor doc includes selected rows, graph titles, and graph colors restoreView = (data: Doc) => { @@ -124,7 +128,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im this.layoutDoc.dataViz_histogram_barColors = Field.Copy(data.dataViz_histogram_barColors); this.layoutDoc.dataViz_histogram_defaultColor = data.dataViz_histogram_defaultColor; this.layoutDoc.dataViz_pie_sliceColors = Field.Copy(data.dataViz_pie_sliceColors); - Object.keys(this.layoutDoc).map(key => { + Object.keys(this.layoutDoc).forEach(key => { if (key.startsWith('dataViz_histogram_title') || key.startsWith('dataViz_lineChart_title') || key.startsWith('dataViz_pieChart_title')) { this.layoutDoc['_' + key] = data[key]; } @@ -150,7 +154,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im annotationOn: this.Document, // when we clear selection -> we should have it so chartBox getAnchor returns undefined // this is for when we want the whole doc (so when the chartBox getAnchor returns without a marker) - /*put in some options*/ + /* put in some options */ }); anchor.config_dataViz = this.dataVizView; anchor.config_dataVizAxes = this.axes.length ? new List(this.axes) : undefined; @@ -158,24 +162,21 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im anchor.dataViz_histogram_barColors = Field.Copy(this.layoutDoc.dataViz_histogram_barColors); anchor.dataViz_histogram_defaultColor = this.layoutDoc.dataViz_histogram_defaultColor; anchor.dataViz_pie_sliceColors = Field.Copy(this.layoutDoc.dataViz_pie_sliceColors); - Object.keys(this.layoutDoc).map(key => { + Object.keys(this.layoutDoc).forEach(key => { if (key.startsWith('dataViz_histogram_title') || key.startsWith('dataViz_lineChart_title') || key.startsWith('dataViz_pieChart_title')) { anchor[key] = this.layoutDoc[key]; } }); this.addDocument(anchor); - //addAsAnnotation && this.addDocument(anchor); + // addAsAnnotation && this.addDocument(anchor); return anchor; }; createNoteAnnotation = () => { - const createFunc = undoable( - action(() => { - const note = this._sidebarRef.current?.anchorMenuClick(this.getAnchor(false), ['latitude', 'longitude', '-linkedTo']); - }), - 'create note annotation' - ); + const createFunc = undoable(() => { + this._sidebarRef.current?.anchorMenuClick(this.getAnchor(false), ['latitude', 'longitude', '-linkedTo']); + }, 'create note annotation'); if (!this.layoutDoc.layout_showSidebar) { this.toggleSidebar(); setTimeout(createFunc); @@ -192,7 +193,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth); }; @computed get SidebarShown() { - return this.layoutDoc._layout_showSidebar ? true : false; + return !!this.layoutDoc._layout_showSidebar; } @computed get sidebarHandle() { return ( @@ -206,7 +207,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK, }} onPointerDown={this.sidebarBtnDown}> - +
); } @@ -218,7 +219,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im setupMoveUpEvents( this, e, - (e, down, delta) => + (moveEv, down, delta) => runInAction(() => { const localDelta = this._props .ScreenToLocalTransform() @@ -246,7 +247,9 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im options.didMove = true; this.toggleSidebar(); } - return new Promise>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv))); + return new Promise>(res => { + DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)); + }); }; @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); @@ -266,32 +269,31 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im if (!DataVizBox.dataset.has(CsvCast(this.dataDoc[this.fieldKey]).url.href)) this.fetchData(); this._disposers.datavis = reaction( () => { - if (this.layoutDoc.dataViz_schemaLive == undefined) this.layoutDoc.dataViz_schemaLive = true; + if (this.layoutDoc.dataViz_schemaLive === undefined) this.layoutDoc.dataViz_schemaLive = true; const getFrom = DocCast(this.layoutDoc.dataViz_asSchema); - const keys = Cast(getFrom?.schema_columnKeys, listSpec('string'))?.filter(key => key != 'text'); - if (!keys) return; - const children = DocListCast(getFrom[Doc.LayoutFieldKey(getFrom)]); - var current: { [key: string]: string }[] = []; + const keys = StrListCast(getFrom?.schema_columnKeys).filter(key => key !== 'text'); + const children = DocListCast(getFrom?.[Doc.LayoutFieldKey(getFrom)]); + const current: { [key: string]: string }[] = []; children .filter(child => child) .forEach(child => { const row: { [key: string]: string } = {}; keys.forEach(key => { - var cell = child[key]; - if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, ''); + let cell = child[key]; + if (cell && (cell as string)) cell = cell.toString().replace(/,/g, ''); row[key] = StrCast(cell); }); current.push(row); }); if (!this.layoutDoc._dataViz_schemaOG) { // makes a copy of the original table for the "live" toggle - let csvRows = []; + const csvRows = []; csvRows.push(keys.join(',')); for (let i = 0; i < children.length - 1; i++) { - let eachRow = []; + const eachRow = []; for (let j = 0; j < keys.length; j++) { - var cell = children[i][keys[j]]; - if (cell && (cell as string)) cell = cell.toString().replace(/\,/g, ''); + let cell = children[i][keys[j]]; + if (cell && (cell as string)) cell = cell.toString().replace(/,/g, ''); eachRow.push(cell); } csvRows.push(eachRow); @@ -305,19 +307,19 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im } const ogDoc = this.layoutDoc._dataViz_schemaOG as Doc; const ogHref = CsvCast(ogDoc[this.fieldKey]) ? CsvCast(ogDoc[this.fieldKey]).url.href : undefined; - const href = CsvCast(this.Document[this.fieldKey]).url.href; + const { href } = CsvCast(this.Document[this.fieldKey]).url; if (ogHref && !DataVizBox.datasetSchemaOG.has(href)) { // sets original dataset to the var const lastRow = current.pop(); DataVizBox.datasetSchemaOG.set(href, current); current.push(lastRow!); - fetch('/csvData?uri=' + ogHref).then(res => res.json().then(action(res => !res.errno && DataVizBox.datasetSchemaOG.set(href, res)))); + fetch('/csvData?uri=' + ogHref).then(res => res.json().then(action(jsonRes => !jsonRes.errno && DataVizBox.datasetSchemaOG.set(href, jsonRes)))); } return current; }, current => { if (current) { - const href = CsvCast(this.Document[this.fieldKey]).url.href; + const { href } = CsvCast(this.Document[this.fieldKey]).url; if (this.layoutDoc.dataViz_schemaLive) DataVizBox.dataset.set(href, current); else DataVizBox.dataset.set(href, DataVizBox.datasetSchemaOG.get(href)!); } @@ -329,8 +331,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im fetchData = () => { if (!this.Document.dataViz_asSchema) { DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, []); // assign temporary dataset as a lock to prevent duplicate server requests - fetch('/csvData?uri=' + this.dataUrl?.url.href) // - .then(res => res.json().then(action(res => !res.errno && DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, res)))); + fetch('/csvData?uri=' + (this.dataUrl?.url.href ?? '')) // + .then(res => res.json().then(action(jsonRes => !jsonRes.errno && DataVizBox.dataset.set(CsvCast(this.dataDoc[this.fieldKey]).url.href, jsonRes)))); } }; @@ -343,7 +345,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im records: this.records, axes: this.axes, titleCol: this.titleCol, - //width: this.SidebarShown? this._props.PanelWidth()*.9/1.2: this._props.PanelWidth() * 0.9, + // width: this.SidebarShown? this._props.PanelWidth()*.9/1.2: this._props.PanelWidth() * 0.9, height: (this._props.PanelHeight() / scale - 32) /* height of 'change view' button */ * 0.9, width: ((this._props.PanelWidth() - this.sidebarWidth()) / scale) * 0.9, margin: { top: 10, right: 25, bottom: 75, left: 45 }, @@ -351,11 +353,13 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im if (!this.records.length) return 'no data/visualization'; switch (this.dataVizView) { case DataVizView.TABLE: return ; - case DataVizView.LINECHART: return (this._vizRenderer = r ?? undefined)} vizBox={this} />; - case DataVizView.HISTOGRAM: return (this._vizRenderer = r ?? undefined)} />; - case DataVizView.PIECHART: return (this._vizRenderer = r ?? undefined)} + case DataVizView.LINECHART: return {this._vizRenderer = r ?? undefined;}} vizBox={this} />; + case DataVizView.HISTOGRAM: return {this._vizRenderer = r ?? undefined;}} />; + case DataVizView.PIECHART: return {this._vizRenderer = r ?? undefined;}} margin={{ top: 10, right: 15, bottom: 15, left: 15 }} />; + default: } // prettier-ignore + return null; } @action @@ -367,10 +371,13 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im this._marqueeing = [e.clientX, e.clientY]; const target = e.target as any; if (e.target && (target.className.includes('endOfContent') || (target.parentElement.className !== 'textLayer' && target.parentElement.parentElement?.className !== 'textLayer'))) { + /* empty */ } else { // if textLayer is hit, then we select text instead of using a marquee so clear out the marquee. setTimeout( - action(() => (this._marqueeing = undefined)), + action(() => { + this._marqueeing = undefined; + }), 100 ); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it. @@ -405,9 +412,21 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im render() { const scale = this._props.NativeDimScaling?.() || 1; + const toggleBtn = (name: string, type: DataVizView) => ( + { + this.layoutDoc._dataViz = type; + }} + toggleStatus={this.layoutDoc._dataViz === type} + /> + ); return !this.records.length ? ( // displays how to get data into the DataVizBox if its empty -
To create a DataViz box, either import / drag a CSV file into your canvas or copy a data table and use the command 'ctrl + p' to bring the data table to your canvas.
+
To create a DataViz box, either import / drag a CSV file into your canvas or copy a data table and use the command (ctrl + p) to bring the data table to your canvas.
) : (
() im onWheel={e => e.stopPropagation()} ref={this._mainCont}>
- (this.layoutDoc._dataViz = DataVizView.TABLE)} toggleStatus={this.layoutDoc._dataViz === DataVizView.TABLE} /> - (this.layoutDoc._dataViz = DataVizView.LINECHART)} toggleStatus={this.layoutDoc._dataViz === DataVizView.LINECHART} /> - (this.layoutDoc._dataViz = DataVizView.HISTOGRAM)} toggleStatus={this.layoutDoc._dataViz === DataVizView.HISTOGRAM} /> - (this.layoutDoc._dataViz = DataVizView.PIECHART)} toggleStatus={this.layoutDoc._dataViz == -DataVizView.PIECHART} /> + {toggleBtn(' TABLE ', DataVizView.TABLE)} + {toggleBtn('LINECHART', DataVizView.LINECHART)} + {toggleBtn('HISTOGRAM', DataVizView.HISTOGRAM)} + {toggleBtn('PIE CHART', DataVizView.PIECHART)}
{this.layoutDoc && this.layoutDoc.dataViz_asSchema ? ( -
+
Display Live Updates to Canvas
@@ -445,7 +464,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() im Document={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} - usePanelWidth={true} + usePanelWidth showSidebar={this.SidebarShown} nativeWidth={NumCast(this.layoutDoc._nativeWidth)} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx index 58cacef76..f0ffdbdcf 100644 --- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx +++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx @@ -64,14 +64,13 @@ export class Histogram extends ObservableReactComponent { @computed get _histogramData() { if (this._props.axes.length < 1) return []; if (this._props.axes.length < 2) { - var ax0 = this._props.axes[0]; + const ax0 = this._props.axes[0]; if (!/[A-Za-z-:]/.test(this._props.records[0][ax0])) { this.numericalXData = true; } return this._tableData.map(record => ({ [ax0]: record[this._props.axes[0]] })); } - var ax0 = this._props.axes[0]; - var ax1 = this._props.axes[1]; + const [ax0, ax1] = this._props.axes; if (!/[A-Za-z-:]/.test(this._props.records[0][ax0])) { this.numericalXData = true; } @@ -82,11 +81,11 @@ export class Histogram extends ObservableReactComponent { } @computed get defaultGraphTitle() { - var ax0 = this._props.axes[0]; - var ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined; + const [ax0, ax1] = this._props.axes; if (this._props.axes.length < 2 || !ax1 || !/\d/.test(this._props.records[0][ax1]) || !this.numericalYData) { return ax0 + ' Histogram'; - } else return ax0 + ' by ' + ax1 + ' Histogram'; + } + return ax0 + ' by ' + ax1 + ' Histogram'; } @computed get parentViz() { @@ -112,8 +111,7 @@ export class Histogram extends ObservableReactComponent { ); } - @action - restoreView = (data: Doc) => {}; + restoreView = () => {}; // create a document anchor that stores whatever is needed to reconstruct the viewing state (selection,zoom,etc) getAnchor = (pinProps?: PinProps) => { const anchor = Docs.Create.ConfigDocument({ @@ -133,36 +131,36 @@ export class Histogram extends ObservableReactComponent { // cleans data by converting numerical data to numbers and taking out empty cells data = (dataSet: any) => { - var validData = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || isNaN(d[key]))); + const validData = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || isNaN(d[key]))); const field = dataSet[0] ? Object.keys(dataSet[0])[0] : undefined; return !field ? [] : validData.map((d: { [x: string]: any }) => !this.numericalXData // ? d[field] - : +d[field!].replace(/\$/g, '').replace(/\%/g, '').replace(/\ { - var sameAsCurrent: boolean; - var barCounter = -1; + let sameAsCurrent: boolean; + let barCounter = -1; const selected = svg.selectAll('.histogram-bar').filter((d: any) => { barCounter++; // uses the order of bars and width of each bar to find which one the pointer is over if (barCounter * eachRectWidth <= pointerX && pointerX <= (barCounter + 1) * eachRectWidth) { - var showSelected = this.numericalYData - ? this._histogramData.filter((data: { [x: string]: any }) => StrCast(data[xAxisTitle]).replace(/\$/g, '').replace(/\%/g, '').replace(/\ data[xAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\ StrCast(data[xAxisTitle]).replace(/$/g, '').replace(/%/g, '').replace(/ data[xAxisTitle].replace(/$/g, '').replace(/%/g, '').replace(/ { const xAxisTitle = Object.keys(dataSet[0])[0]; const yAxisTitle = this.numericalYData ? Object.keys(dataSet[0])[1] : 'frequency'; const uniqueArr: unknown[] = [...new Set(data)]; - var numBins = this.numericalXData && Number.isInteger(data[0]) ? this.rangeVals.xMax! - this.rangeVals.xMin! : uniqueArr.length; - var translateXAxis = !this.numericalXData || numBins < this.maxBins ? width / (numBins + 1) / 2 : 0; + let numBins = this.numericalXData && Number.isInteger(data[0]) ? this.rangeVals.xMax! - this.rangeVals.xMin! : uniqueArr.length; + let translateXAxis = !this.numericalXData || numBins < this.maxBins ? width / (numBins + 1) / 2 : 0; if (numBins > this.maxBins) numBins = this.maxBins; const startingPoint = this.numericalXData ? this.rangeVals.xMin! : 0; const endingPoint = this.numericalXData ? this.rangeVals.xMax! : numBins; // converts data into Objects - var histDataSet = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || isNaN(d[key]))); + let histDataSet = dataSet.filter((d: { [x: string]: unknown }) => !Object.keys(dataSet[0]).some(key => !d[key] || isNaN(d[key]))); if (!this.numericalXData) { - var histStringDataSet: { [x: string]: unknown }[] = []; + const histStringDataSet: { [x: string]: unknown }[] = []; if (this.numericalYData) { for (let i = 0; i < dataSet.length; i++) { histStringDataSet.push({ [yAxisTitle]: dataSet[i][yAxisTitle], [xAxisTitle]: dataSet[i][xAxisTitle] }); @@ -204,15 +202,15 @@ export class Histogram extends ObservableReactComponent { histStringDataSet.push({ [yAxisTitle]: 0, [xAxisTitle]: uniqueArr[i] }); } for (let i = 0; i < data.length; i++) { - let barData = histStringDataSet.filter(each => each[xAxisTitle] == data[i]); - histStringDataSet.filter(each => each[xAxisTitle] == data[i])[0][yAxisTitle] = Number(barData[0][yAxisTitle]) + 1; + const barData = histStringDataSet.filter(each => each[xAxisTitle] === data[i]); + histStringDataSet.filter(each => each[xAxisTitle] === data[i])[0][yAxisTitle] = Number(barData[0][yAxisTitle]) + 1; } } histDataSet = histStringDataSet; } // initial graph and binning data for histogram - var svg = (this._histogramSvg = d3 + const svg = (this._histogramSvg = d3 .select(this._histogramRef.current) .append('svg') .attr('class', 'graph') @@ -220,23 +218,21 @@ export class Histogram extends ObservableReactComponent { .attr('height', height + this._props.margin.top + this._props.margin.bottom) .append('g') .attr('transform', 'translate(' + this._props.margin.left + ',' + this._props.margin.top + ')')); - var x = d3 + let x = d3 .scaleLinear() .domain(this.numericalXData ? [startingPoint!, endingPoint!] : [0, numBins]) .range([0, width]); - var histogram = d3 + const histogram = d3 .histogram() - .value(function (d) { - return d; - }) + .value(d => d) .domain([startingPoint!, endingPoint!]) .thresholds(x.ticks(numBins)); - var bins = histogram(data); - var eachRectWidth = width / bins.length; - var graphStartingPoint = bins[0].x1 && bins[1] ? bins[0].x1! - (bins[1].x1! - bins[1].x0!) : 0; + const bins = histogram(data); + let eachRectWidth = width / bins.length; + const graphStartingPoint = bins[0].x1 && bins[1] ? bins[0].x1! - (bins[1].x1! - bins[1].x0!) : 0; bins[0].x0 = graphStartingPoint; x = x.domain([graphStartingPoint, endingPoint]).range([0, Number.isInteger(this.rangeVals.xMin!) ? width - eachRectWidth : width]); - var xAxis; + let xAxis; // more calculations based on bins // x-axis @@ -245,9 +241,9 @@ export class Histogram extends ObservableReactComponent { // uniqueArr.sort() histDataSet.sort(); for (let i = 0; i < data.length; i++) { - var index = 0; + let index = 0; for (let j = 0; j < uniqueArr.length; j++) { - if (uniqueArr[j] == data[i]) { + if (uniqueArr[j] === data[i]) { index = j; } } @@ -255,7 +251,9 @@ export class Histogram extends ObservableReactComponent { } bins.pop(); eachRectWidth = width / bins.length; - bins.forEach(d => (d.x0 = d.x0!)); + bins.forEach(d => { + d.x0 = d.x0!; + }); xAxis = d3 .axisBottom(x) .ticks(bins.length > 1 ? bins.length - 1 : 1) @@ -265,12 +263,12 @@ export class Histogram extends ObservableReactComponent { x.domain([0, bins.length - 1]); translateXAxis = eachRectWidth / 2; } else { - var allSame = true; - for (var i = 0; i < bins.length; i++) { + let allSame = true; + for (let i = 0; i < bins.length; i++) { if (bins[i] && bins[i][0]) { - var compare = bins[i][0]; + const compare = bins[i][0]; for (let j = 1; j < bins[i].length; j++) { - if (bins[i][j] != compare) allSame = false; + if (bins[i][j] !== compare) allSame = false; } } } @@ -279,8 +277,8 @@ export class Histogram extends ObservableReactComponent { eachRectWidth = width / bins.length; } else { eachRectWidth = width / (bins.length + 1); - var tickDiff = bins.length >= 2 ? bins[bins.length - 2].x1! - bins[bins.length - 2].x0! : 0; - var curDomain = x.domain(); + const tickDiff = bins.length >= 2 ? bins[bins.length - 2].x1! - bins[bins.length - 2].x0! : 0; + const curDomain = x.domain(); x.domain([curDomain[0], curDomain[0] + tickDiff * bins.length]); } @@ -288,16 +286,13 @@ export class Histogram extends ObservableReactComponent { x.range([0, width - eachRectWidth]); } // y-axis - const maxFrequency = this.numericalYData - ? d3.max(histDataSet, function (d: any) { - return d[yAxisTitle] ? Number(d[yAxisTitle]!.replace(/\$/g, '').replace(/\%/g, '').replace(/\ (d[yAxisTitle] ? Number(d[yAxisTitle]!.replace(/\$/g, '') + .replace(/%/g, '').replace(/ d.length); // prettier-ignore + const y = d3.scaleLinear().range([height, 0]); y.domain([0, +maxFrequency!]); - var yAxis = d3.axisLeft(y).ticks(maxFrequency!); + const yAxis = d3.axisLeft(y).ticks(maxFrequency!); if (this.numericalYData) { const yScale = scaleCreatorNumerical(0, Number(maxFrequency), height, 0); yAxisCreator(svg.append('g'), width, yScale); @@ -312,18 +307,17 @@ export class Histogram extends ObservableReactComponent { const onPointClick = action((e: any) => this.highlightSelectedBar(true, svg, eachRectWidth, d3.pointer(e)[0], xAxisTitle, yAxisTitle, histDataSet)); const onHover = action((e: any) => { this.highlightSelectedBar(false, svg, eachRectWidth, d3.pointer(e)[0], xAxisTitle, yAxisTitle, histDataSet); + // eslint-disable-next-line no-use-before-define updateHighlights(); }); - const mouseOut = action((e: any) => { + const mouseOut = action(() => { this.hoverOverData = undefined; + // eslint-disable-next-line no-use-before-define updateHighlights(); }); const updateHighlights = () => { - const hoverOverBar = this.hoverOverData; - const selectedData = this.selectedData; - svg.selectAll('rect').attr('class', function (d: any) { - return (hoverOverBar && hoverOverBar[0] == d[0]) || (selectedData && selectedData[0] == d[0]) ? 'histogram-bar hover' : 'histogram-bar'; - }); + const { hoverOverData: hoverOverBar, selectedData } = this; + svg.selectAll('rect').attr('class', (d: any) => ((hoverOverBar && hoverOverBar[0] === d[0]) || (selectedData && selectedData[0] === d[0]) ? 'histogram-bar hover' : 'histogram-bar')); }; svg.on('click', onPointClick).on('mouseover', onHover).on('mouseout', mouseOut); @@ -333,7 +327,7 @@ export class Histogram extends ObservableReactComponent { .style('text-anchor', 'middle') .text(xAxisTitle); svg.append('text') - .attr('transform', 'rotate(-90)' + ' ' + 'translate( 0, ' + -10 + ')') + .attr('transform', 'rotate(-90) translate( 0, ' + -10 + ')') .attr('x', -(height / 2)) .attr('y', -20) .style('text-anchor', 'middle') @@ -341,7 +335,7 @@ export class Histogram extends ObservableReactComponent { d3.format('.0f'); // draw bars - var selected = this.selectedData; + const selected = this.selectedData; svg.selectAll('rect') .data(bins) .enter() @@ -349,49 +343,34 @@ export class Histogram extends ObservableReactComponent { .attr( 'transform', this.numericalYData - ? function (d) { - const eachData = histDataSet.filter((data: { [x: string]: number }) => { - return data[xAxisTitle] == d[0]; - }); - const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\ { + const eachData = histDataSet.filter((hData: { [x: string]: number }) => hData[xAxisTitle] === d[0]); + const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/%/g, '').replace(/ 'translate(' + x(d.x0!) + ',' + y(d.length) + ')' ) .attr( 'height', this.numericalYData - ? function (d) { - const eachData = histDataSet.filter((data: { [x: string]: number }) => { - return data[xAxisTitle] == d[0]; - }); - const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/\%/g, '').replace(/\ { + const eachData = histDataSet.filter((hData: { [x: string]: number }) => hData[xAxisTitle] === d[0]); + const length = eachData.length ? eachData[0][yAxisTitle].replace(/\$/g, '').replace(/%/g, '').replace(/ height - y(d.length) ) .attr('width', eachRectWidth) - .attr( - 'class', - selected - ? function (d) { - return selected && selected[0] === d[0] ? 'histogram-bar hover' : 'histogram-bar'; - } - : function (d) { - return 'histogram-bar'; - } - ) + .attr('class', selected ? d => (selected && selected[0] === d[0] ? 'histogram-bar hover' : 'histogram-bar') : () => 'histogram-bar') .attr('fill', d => { - var barColor; + let barColor; const barColors = StrListCast(this._props.layoutDoc.dataViz_histogram_barColors).map(each => each.split('::')); barColors.forEach(each => { - if (d[0] && d[0].toString() && each[0] == d[0].toString()) barColor = each[1]; + // eslint-disable-next-line prefer-destructuring + if (d[0] && d[0].toString() && each[0] === d[0].toString()) barColor = each[1]; else { const range = StrCast(each[0]).split(' to '); + // eslint-disable-next-line prefer-destructuring if (Number(range[0]) <= d[0] && d[0] <= Number(range[1])) barColor = each[1]; } }); @@ -401,7 +380,7 @@ export class Histogram extends ObservableReactComponent { @action changeSelectedColor = (color: string) => { this.curBarSelected.attr('fill', color); - const barName = StrCast(this._currSelected[this._props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\ each.split('::')[0] === barName && barColors.splice(barColors.indexOf(each), 1)); @@ -410,22 +389,24 @@ export class Histogram extends ObservableReactComponent { @action eraseSelectedColor = () => { this.curBarSelected.attr('fill', this._props.layoutDoc.dataViz_histogram_defaultColor); - const barName = StrCast(this._currSelected[this._props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\ each.split('::')[0] === barName && barColors.splice(barColors.indexOf(each), 1)); }; updateBarColors = () => { - var svg = this._histogramSvg; + const svg = this._histogramSvg; if (svg) svg.selectAll('rect').attr('fill', (d: any) => { - var barColor; + let barColor; const barColors = StrListCast(this._props.layoutDoc.dataViz_histogram_barColors).map(each => each.split('::')); barColors.forEach(each => { - if (d[0] && d[0].toString() && each[0] == d[0].toString()) barColor = each[1]; + // eslint-disable-next-line prefer-destructuring + if (d[0] && d[0].toString() && each[0] === d[0].toString()) barColor = each[1]; else { const range = StrCast(each[0]).split(' to '); + // eslint-disable-next-line prefer-destructuring if (Number(range[0]) <= d[0] && d[0] <= Number(range[1])) barColor = each[1]; } }); @@ -436,38 +417,41 @@ export class Histogram extends ObservableReactComponent { render() { this.updateBarColors(); this._histogramData; - var curSelectedBarName = ''; - var titleAccessor: any = 'dataViz_histogram_title'; - if (this._props.axes.length == 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1]; - else if (this._props.axes.length > 0) titleAccessor = titleAccessor + this._props.axes[0]; + let curSelectedBarName = ''; + let titleAccessor: any = 'dataViz_histogram_title'; + if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1]; + else if (this._props.axes.length > 0) titleAccessor += this._props.axes[0]; if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle; if (!this._props.layoutDoc.dataViz_histogram_defaultColor) this._props.layoutDoc.dataViz_histogram_defaultColor = '#69b3a2'; if (!this._props.layoutDoc.dataViz_histogram_barColors) this._props.layoutDoc.dataViz_histogram_barColors = new List(); - var selected = 'none'; + let selected = 'none'; if (this._currSelected) { - curSelectedBarName = StrCast(this._currSelected![this._props.axes[0]].replace(/\$/g, '').replace(/\%/g, '').replace(/\ + Object.keys(this._currSelected).forEach(key => { key // ? (selected += key + ': ' + this._currSelected[key] + ', ') - : '' - ); + : ''; + }); selected = selected.substring(0, selected.length - 2) + ' }'; - if (this._props.titleCol != '' && (!this._currSelected['frequency'] || this._currSelected['frequency'] < 10)) { + if (this._props.titleCol !== '' && (!this._currSelected.frequency || this._currSelected.frequency < 10)) { selected += '\n' + this._props.titleCol + ': '; this._tableData.forEach(each => { - if (this._currSelected[this._props.axes[0]] == each[this._props.axes[0]]) { + if (this._currSelected[this._props.axes[0]] === each[this._props.axes[0]]) { if (this._props.axes[1]) { - if (this._currSelected[this._props.axes[1]] == each[this._props.axes[1]]) selected += each[this._props.titleCol] + ', '; + if (this._currSelected[this._props.axes[1]] === each[this._props.axes[1]]) selected += each[this._props.titleCol] + ', '; } else selected += each[this._props.titleCol] + ', '; } }); selected = selected.slice(0, -1).slice(0, -1); } } - var selectedBarColor; - var barColors = StrListCast(this._props.layoutDoc.histogramBarColors).map(each => each.split('::')); - barColors.forEach(each => each[0] === curSelectedBarName && (selectedBarColor = each[1])); + let selectedBarColor; + const barColors = StrListCast(this._props.layoutDoc.histogramBarColors).map(each => each.split('::')); + barColors.forEach(each => { + // eslint-disable-next-line prefer-destructuring + each[0] === curSelectedBarName && (selectedBarColor = each[1]); + }); if (this._histogramData.length > 0 || !this.parentViz) { return this._props.axes.length >= 1 ? ( @@ -476,45 +460,51 @@ export class Histogram extends ObservableReactComponent { (this._props.layoutDoc[titleAccessor] = val as string)), + action(val => { + this._props.layoutDoc[titleAccessor] = val as string; + }), 'Change Graph Title' )} - color={'black'} + color="black" size={Size.LARGE} fillWidth />     } selectedColor={StrCast(this._props.layoutDoc.dataViz_histogram_defaultColor)} - setFinalColor={undoable(color => (this._props.layoutDoc.dataViz_histogram_defaultColor = color), 'Change Default Bar Color')} - setSelectedColor={undoable(color => (this._props.layoutDoc.dataViz_histogram_defaultColor = color), 'Change Default Bar Color')} + setFinalColor={undoable(color => { + this._props.layoutDoc.dataViz_histogram_defaultColor = color; + }, 'Change Default Bar Color')} + setSelectedColor={undoable(color => { + this._props.layoutDoc.dataViz_histogram_defaultColor = color; + }, 'Change Default Bar Color')} size={Size.XSMALL} />
- {selected != 'none' ? ( -
+ {selected !== 'none' ? ( +
Selected: {selected}     } - selectedColor={selectedBarColor ? selectedBarColor : this.curBarSelected.attr('fill')} + selectedColor={selectedBarColor || this.curBarSelected.attr('fill')} setFinalColor={undoable(color => this.changeSelectedColor(color), 'Change Selected Bar Color')} setSelectedColor={undoable(color => this.changeSelectedColor(color), 'Change Selected Bar Color')} size={Size.XSMALL} />   } + icon={} size={Size.XSMALL} - color={'black'} + color="black" type={Type.SEC} - tooltip={'Revert to the default bar color'} + tooltip="Revert to the default bar color" onClick={undoable( action(() => this.eraseSelectedColor()), 'Change Selected Bar Color' @@ -524,7 +514,7 @@ export class Histogram extends ObservableReactComponent { ) : null}
) : ( - {'first use table view to select a column to graph'} + first use table view to select a column to graph ); } // when it is a brushed table and the incoming table doesn't have any rows selected diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index c667a15de..8105adf1e 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -3,7 +3,7 @@ import * as d3 from 'd3'; import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { Doc, DocListCast, NumListCast, StrListCast } from '../../../../../fields/Doc'; +import { Doc, DocListCast, NumListCast } from '../../../../../fields/Doc'; import { List } from '../../../../../fields/List'; import { listSpec } from '../../../../../fields/Schema'; import { Cast, DocCast, StrCast } from '../../../../../fields/Types'; @@ -63,7 +63,6 @@ export class LineChart extends ObservableReactComponent { return !this.parentViz ? this._props.records : this._tableDataIds.map(rowId => this._props.records[rowId]); } @computed get _lineChartData() { - var guids = StrListCast(this._props.layoutDoc.dataViz_rowIds); if (this._props.axes.length <= 1) return []; return this._tableData.map(record => ({ x: Number(record[this._props.axes[0]]), y: Number(record[this._props.axes[1]]) })).sort((a, b) => (a.x < b.x ? -1 : 1)); } @@ -103,7 +102,7 @@ export class LineChart extends ObservableReactComponent { ); this._disposers.annos = reaction( () => DocListCast(this._props.dataDoc[this._props.fieldKey + '_annotations']), - annotations => { + (/* annotations */) => { // modify how d3 renders so that anything in this annotations list would be potentially highlighted in some way // could be blue colored to make it look like anchor // this.drawAnnotations() @@ -176,7 +175,7 @@ export class LineChart extends ObservableReactComponent { getAnchor = (pinProps?: PinProps) => { const anchor = Docs.Create.ConfigDocument({ // - title: 'line doc selection' + this._currSelected?.x, + title: 'line doc selection' + (this._currSelected?.x ?? ''), }); PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document); anchor.config_dataVizSelection = this._currSelected ? new List([this._currSelected.x, this._currSelected.y]) : undefined; @@ -192,11 +191,12 @@ export class LineChart extends ObservableReactComponent { } @computed get defaultGraphTitle() { - var ax0 = this._props.axes[0]; - var ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined; + const ax0 = this._props.axes[0]; + const ax1 = this._props.axes.length > 1 ? this._props.axes[1] : undefined; if (this._props.axes.length < 2 || !/\d/.test(this._props.records[0][ax0]) || !ax1) { return ax0 + ' Line Chart'; - } else return ax1 + ' by ' + ax0 + ' Line Chart'; + } + return ax1 + ' by ' + ax0 + ' Line Chart'; } setupTooltip() { @@ -216,9 +216,11 @@ export class LineChart extends ObservableReactComponent { @action setCurrSelected(x?: number, y?: number) { // TODO: nda - get rid of svg element in the list? - if (this._currSelected && this._currSelected.x == x && this._currSelected.y == y) this._currSelected = undefined; + if (this._currSelected && this._currSelected.x === x && this._currSelected.y === y) this._currSelected = undefined; else this._currSelected = x !== undefined && y !== undefined ? { x, y } : undefined; - this._props.records.forEach(record => record[this._props.axes[0]] === x && record[this._props.axes[1]] === y && (record.selected = true)); + this._props.records.forEach(record => { + record[this._props.axes[0]] === x && record[this._props.axes[1]] === y && (record.selected = true); + }); } drawDataPoints(data: DataPoint[], idx: number, xScale: d3.ScaleLinear, yScale: d3.ScaleLinear) { @@ -242,13 +244,13 @@ export class LineChart extends ObservableReactComponent { d3.select(this._lineChartRef.current).select('svg').remove(); d3.select(this._lineChartRef.current).select('.tooltip').remove(); - var { xMin, xMax, yMin, yMax } = rangeVals; + let { xMin, xMax, yMin, yMax } = rangeVals; if (xMin === undefined || xMax === undefined || yMin === undefined || yMax === undefined) { return; } // adding svg - const margin = this._props.margin; + const { margin } = this._props; const svg = (this._lineChartSvg = d3 .select(this._lineChartRef.current) .append('svg') @@ -258,15 +260,15 @@ export class LineChart extends ObservableReactComponent { .append('g') .attr('transform', `translate(${margin.left}, ${margin.top})`)); - var validSecondData; + let validSecondData; if (this._props.axes.length > 2) { // for when there are 2 lines on the chart - var next = this._tableData.map(record => ({ x: Number(record[this._props.axes[0]]), y: Number(record[this._props.axes[2]]) })).sort((a, b) => (a.x < b.x ? -1 : 1)); + const next = this._tableData.map(record => ({ x: Number(record[this._props.axes[0]]), y: Number(record[this._props.axes[2]]) })).sort((a, b) => (a.x < b.x ? -1 : 1)); validSecondData = next.filter(d => { if (!d.x || isNaN(d.x) || !d.y || isNaN(d.y)) return false; return true; }); - var secondDataRange = minMaxRange([validSecondData]); + const secondDataRange = minMaxRange([validSecondData]); if (secondDataRange.xMax! > xMax) xMax = secondDataRange.xMax; if (secondDataRange.yMax! > yMax) yMax = secondDataRange.yMax; if (secondDataRange.xMin! < xMin) xMin = secondDataRange.xMin; @@ -290,45 +292,31 @@ export class LineChart extends ObservableReactComponent { svg.append('path').attr('stroke', 'red'); // legend - var color = d3.scaleOrdinal().range(['black', 'blue']).domain([this._props.axes[1], this._props.axes[2]]); + const color: any = d3.scaleOrdinal().range(['black', 'blue']).domain([this._props.axes[1], this._props.axes[2]]); svg.selectAll('mydots') .data([this._props.axes[1], this._props.axes[2]]) .enter() .append('circle') .attr('cx', 5) - .attr('cy', function (d, i) { - return -30 + i * 15; - }) + .attr('cy', (d, i) => -30 + i * 15) .attr('r', 7) - .style('fill', function (d) { - return color(d); - }); + .style('fill', d => color(d)); svg.selectAll('mylabels') .data([this._props.axes[1], this._props.axes[2]]) .enter() .append('text') .attr('x', 25) - .attr('y', function (d, i) { - return -30 + i * 15; - }) - .style('fill', function (d) { - return color(d); - }) - .text(function (d) { - return d; - }) + .attr('y', (d, i) => -30 + i * 15) + .style('fill', d => color(d)) + .text(d => d) .attr('text-anchor', 'left') .style('alignment-baseline', 'middle'); } // get valid data points const data = dataSet[0]; - var validData = data.filter(d => { - Object.keys(data[0]).map(key => { - if (!d[key] || isNaN(d[key])) return false; - }); - return true; - }); + const keys = Object.keys(data[0]); + const validData = data.filter(d => !keys.some(key => isNaN(d[key]))); // draw the plot line drawLine(svg.append('path'), validData, lineGen, false); @@ -355,7 +343,7 @@ export class LineChart extends ObservableReactComponent { const x0 = bisect(data, xScale.invert(xPos - 5)); // shift x by -5 so that you can reach points on the left-side axis const d0 = data[x0]; // find .circle-d1 with data-x = d0.x and data-y = d0.y - const selected = svg.selectAll('.datapoint').filter((d: any) => d['data-x'] === d0.x && d['data-y'] === d0.y); + svg.selectAll('.datapoint').filter((d: any) => d['data-x'] === d0.x && d['data-y'] === d0.y); this.setCurrSelected(d0.x, d0.y); this.updateTooltip(higlightFocusPt, xScale, d0, yScale, tooltip); }); @@ -378,7 +366,7 @@ export class LineChart extends ObservableReactComponent { .style('text-anchor', 'middle') .text(this._props.axes[0]); svg.append('text') - .attr('transform', 'rotate(-90)' + ' ' + 'translate( 0, ' + -10 + ')') + .attr('transform', 'rotate(-90) translate(0, -10)') .attr('x', -(height / 2)) .attr('y', -30) .attr('height', 20) @@ -404,57 +392,60 @@ export class LineChart extends ObservableReactComponent { } render() { - var titleAccessor: any = 'dataViz_lineChart_title'; - if (this._props.axes.length == 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1]; - else if (this._props.axes.length > 0) titleAccessor = titleAccessor + this._props.axes[0]; + let titleAccessor: any = 'dataViz_lineChart_title'; + if (this._props.axes.length === 2) titleAccessor = titleAccessor + this._props.axes[0] + '-' + this._props.axes[1]; + else if (this._props.axes.length > 0) titleAccessor += this._props.axes[0]; if (!this._props.layoutDoc[titleAccessor]) this._props.layoutDoc[titleAccessor] = this.defaultGraphTitle; const selectedPt = this._currSelected ? `{ ${this._props.axes[0]}: ${this._currSelected.x} ${this._props.axes[1]}: ${this._currSelected.y} }` : 'none'; - var selectedTitle = ''; + let selectedTitle = ''; if (this._currSelected && this._props.titleCol) { selectedTitle += '\n' + this._props.titleCol + ': '; this._tableData.forEach(each => { - var mapThisEntry = false; - if (this._currSelected.x == each[this._props.axes[0]] && this._currSelected.y == each[this._props.axes[1]]) mapThisEntry = true; - else if (this._currSelected.y == each[this._props.axes[0]] && this._currSelected.x == each[this._props.axes[1]]) mapThisEntry = true; + let mapThisEntry = false; + if (this._currSelected.x === each[this._props.axes[0]] && this._currSelected.y === each[this._props.axes[1]]) mapThisEntry = true; + else if (this._currSelected.y === each[this._props.axes[0]] && this._currSelected.x === each[this._props.axes[1]]) mapThisEntry = true; if (mapThisEntry) selectedTitle += each[this._props.titleCol] + ', '; }); selectedTitle = selectedTitle.slice(0, -1).slice(0, -1); } - if (this._lineChartData.length > 0 || !this.parentViz || this.parentViz.length == 0) { + if (this._lineChartData.length > 0 || !this.parentViz || this.parentViz.length === 0) { return this._props.axes.length >= 2 && /\d/.test(this._props.records[0][this._props.axes[0]]) && /\d/.test(this._props.records[0][this._props.axes[1]]) ? (
(this._props.layoutDoc[titleAccessor] = val as string)), + action(val => { + this._props.layoutDoc[titleAccessor] = val as string; + }), 'Change Graph Title' )} - color={'black'} + color="black" size={Size.LARGE} fillWidth />
- {selectedPt != 'none' ? ( -
+ {selectedPt !== 'none' ? ( +
{`Selected: ${selectedPt}`} {`${selectedTitle}`} + }} + />
) : null}
) : ( - {'first use table view to select two numerical axes to plot'} - ); - } else - return ( - // when it is a brushed table and the incoming table doesn't have any rows selected -
Selected rows of data from the incoming DataVizBox to display.
+ first use table view to select two numerical axes to plot ); + } + return ( + // when it is a brushed table and the incoming table doesn't have any rows selected +
Selected rows of data from the incoming DataVizBox to display.
+ ); } } diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index 15959c61d..55c221046 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -1,3 +1,5 @@ +/* eslint-disable jsx-a11y/no-noninteractive-tabindex */ +/* eslint-disable jsx-a11y/no-static-element-interactions */ import { Button, Type } from 'browndash-components'; import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; @@ -13,7 +15,9 @@ import { ObservableReactComponent } from '../../../ObservableReactComponent'; import { DocumentView } from '../../DocumentView'; import { DataVizView } from '../DataVizBox'; import './Chart.scss'; + const { DATA_VIZ_TABLE_ROW_HEIGHT } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore + interface TableBoxProps { Document: Doc; layoutDoc: Doc; @@ -71,7 +75,7 @@ export class TableBox extends ObservableReactComponent { } @computed get columns() { - return this._tableData.length ? Array.from(Object.keys(this._tableData[0])).filter(header => header != '' && header != undefined) : []; + return this._tableData.length ? Array.from(Object.keys(this._tableData[0])).filter(header => header !== '' && header !== undefined) : []; } // updates the 'dataViz_selectedRows' and 'dataViz_highlightedRows' fields to no longer include rows that aren't in the table @@ -108,13 +112,11 @@ export class TableBox extends ObservableReactComponent { if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1); else highlited?.push(rowId); if (!selected?.includes(rowId)) selected?.push(rowId); - } else { + } else if (selected?.includes(rowId)) { // selecting a row - if (selected?.includes(rowId)) { - if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1); - selected.splice(selected.indexOf(rowId), 1); - } else selected?.push(rowId); - } + if (highlited?.includes(rowId)) highlited.splice(highlited.indexOf(rowId), 1); + selected.splice(selected.indexOf(rowId), 1); + } else selected?.push(rowId); e.stopPropagation(); }; @@ -124,7 +126,7 @@ export class TableBox extends ObservableReactComponent { setupMoveUpEvents( {}, e, - e => { + moveEv => { // dragging off a column to create a brushed DataVizBox const sourceAnchorCreator = () => this._props.docView?.()!.Document!; const targetCreator = (annotationOn: Doc | undefined) => { @@ -138,13 +140,13 @@ export class TableBox extends ObservableReactComponent { embedding.pieSliceColors = Field.Copy(this._props.layoutDoc.pieSliceColors); return embedding; }; - if (this._props.docView?.() && !ClientUtils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) { - DragManager.StartAnchorAnnoDrag(e.target instanceof HTMLElement ? [e.target] : [], new DragManager.AnchorAnnoDragData(this._props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, { - dragComplete: e => { - if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) { - e.linkDocument.link_displayLine = true; - e.linkDocument.link_matchEmbeddings = true; - e.linkDocument.link_displayArrow = true; + if (this._props.docView?.() && !ClientUtils.isClick(moveEv.clientX, moveEv.clientY, downX, downY, Date.now())) { + DragManager.StartAnchorAnnoDrag(moveEv.target instanceof HTMLElement ? [moveEv.target] : [], new DragManager.AnchorAnnoDragData(this._props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, { + dragComplete: completeEv => { + if (!completeEv.aborted && completeEv.annoDragData && completeEv.annoDragData.linkSourceDoc && completeEv.annoDragData.dropDocument && completeEv.linkDocument) { + completeEv.linkDocument.link_displayLine = true; + completeEv.linkDocument.link_matchEmbeddings = true; + completeEv.linkDocument.link_displayArrow = true; // e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this._props.Document; // e.annoDragData.linkSourceDoc.followLinkZoom = false; } @@ -155,9 +157,9 @@ export class TableBox extends ObservableReactComponent { return false; }, emptyFunction, - action(e => { - if (e.shiftKey) { - if (this._props.titleCol == col) this._props.titleCol = ''; + action(clickEv => { + if (clickEv.shiftKey) { + if (this._props.titleCol === col) this._props.titleCol = ''; else this._props.titleCol = col; this._props.selectTitleCol(this._props.titleCol); } else { @@ -185,8 +187,22 @@ export class TableBox extends ObservableReactComponent { } }}>
-
{ ? 'darkgreen' : this._props.axes.length > 2 && this._props.axes.lastElement() === col ? 'darkred' - : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] == col) + : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] === col) ? 'darkblue' : undefined, background: @@ -233,7 +249,7 @@ export class TableBox extends ObservableReactComponent { ? '#E3fbdb' : this._props.axes.length > 2 && this._props.axes.lastElement() === col ? '#Fbdbdb' - : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] == col) + : this._props.axes.lastElement() === col || (this._props.axes.length > 2 && this._props.axes[1] === col) ? '#c6ebf7' : undefined, // blue: #ADD8E6 @@ -260,11 +276,11 @@ export class TableBox extends ObservableReactComponent { background: NumListCast(this._props.layoutDoc.dataViz_highlitedRows).includes(rowId) ? 'lightYellow' : NumListCast(this._props.layoutDoc.dataViz_selectedRows).includes(rowId) ? 'lightgrey' : '', }}> {this.columns.map(col => { - var colSelected = false; - if (this._props.axes.length > 2) colSelected = this._props.axes[0] == col || this._props.axes[1] == col || this._props.axes[2] == col; - else if (this._props.axes.length > 1) colSelected = this._props.axes[0] == col || this._props.axes[1] == col; - else if (this._props.axes.length > 0) colSelected = this._props.axes[0] == col; - if (this._props.titleCol == col) colSelected = true; + let colSelected = false; + if (this._props.axes.length > 2) colSelected = this._props.axes[0] === col || this._props.axes[1] === col || this._props.axes[2] === col; + else if (this._props.axes.length > 1) colSelected = this._props.axes[0] === col || this._props.axes[1] === col; + else if (this._props.axes.length > 0) colSelected = this._props.axes[0] === col; + if (this._props.titleCol === col) colSelected = true; return (
{this._props.records[rowId][col]}
@@ -279,10 +295,10 @@ export class TableBox extends ObservableReactComponent {
); - } else - return ( - // when it is a brushed table and the incoming table doesn't have any rows selected -
Selected rows of data from the incoming DataVizBox to display.
- ); + } + return ( + // when it is a brushed table and the incoming table doesn't have any rows selected +
Selected rows of data from the incoming DataVizBox to display.
+ ); } } diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 518158a7f..832e18b68 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/require-default-props */ import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -18,7 +19,7 @@ import { CollectionView } from '../collections/CollectionView'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { CollectionSchemaView } from '../collections/collectionSchema/CollectionSchemaView'; import { SchemaRowBox } from '../collections/collectionSchema/SchemaRowBox'; -import { PresElementBox } from '../nodes/trails/PresElementBox'; +import { PresElementBox } from './trails/PresElementBox'; import { SearchBox } from '../search/SearchBox'; import { DashWebRTCVideo } from '../webcam/DashWebRTCVideo'; import { AudioBox } from './AudioBox'; @@ -71,8 +72,8 @@ interface HTMLtagProps { children?: JSX.Element[]; } -//" {this.title}" -//" {this.title}" +// " // @@ -85,7 +86,7 @@ interface HTMLtagProps { // " @observer export class HTMLtag extends React.Component { - click = (e: React.MouseEvent) => { + click = () => { const clickScript = (this.props as any).onClick as Opt; clickScript?.script.run({ this: this.props.Document, self: this.props.Document, scale: this.props.scaling }); }; @@ -96,11 +97,10 @@ export class HTMLtag extends React.Component { render() { const style: { [key: string]: any } = {}; const divKeys = OmitKeys(this.props, ['children', 'dragStarting', 'dragEnding', 'htmltag', 'scaling', 'Document', 'key', 'onInput', 'onClick', '__proto__']).omit; - const replacer = (match: any, expr: string, offset: any, string: any) => { + const replacer = (match: any, expr: string) => // bcz: this executes a script to convert a property expression string: { script } into a value - return (ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: 'number' })?.script.run({ self: this.props.Document, this: this.props.Document, scale: this.props.scaling }).result as string) || ''; - }; - Object.keys(divKeys).map((prop: string) => { + (ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: 'number' })?.script.run({ self: this.props.Document, this: this.props.Document, scale: this.props.scaling }).result as string) || ''; + Object.keys(divKeys).forEach((prop: string) => { const p = (this.props as any)[prop] as string; style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer); }); @@ -158,7 +158,7 @@ export class DocumentContentsView extends ObservableReactComponent{content}< as in {this.title} - const replacer = (match: any, prefix: string, expr: string, postfix: string, offset: any, string: any) => { - return prefix + ((ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ this: this._props.Document }).result as string) || '') + postfix; - }; + const replacer = (match: any, prefix: string, expr: string, postfix: string) => prefix + ((ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ this: this._props.Document }).result as string) || '') + postfix; layoutFrame = layoutFrame.replace(/(>[^{]*)[^=]\{([^.'][^<}]+)\}([^}]*<)/g, replacer); // replace HTML with corresponding HTML tag as in: becomes - const replacer2 = (match: any, p1: string, offset: any, string: any) => { - return ` ` with as in: becomes - const replacer3 = (match: any, p1: string, offset: any, string: any) => { - return ` ` { console.log('DocumentContentsView:' + test, bindings, layoutFrame); }} diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index d378082f8..a029b3761 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -1,3 +1,5 @@ +/* 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 { action, computed, makeObservable, observable, runInAction } from 'mobx'; @@ -26,20 +28,22 @@ interface DocumentLinksButtonProps { AlwaysOn?: boolean; InMenu?: boolean; OnHover?: boolean; - StartLink?: boolean; //whether the link HAS been started (i.e. now needs to be completed) + StartLink?: boolean; // whether the link HAS been started (i.e. now needs to be completed) ShowCount?: boolean; scaling?: () => number; // how uch doc is scaled so that link buttons can invert it hideCount?: () => boolean; } export class DocButtonState { - @observable public StartLink: Doc | undefined = undefined; //origin's Doc, if defined + @observable public StartLink: Doc | undefined = undefined; // origin's Doc, if defined @observable public StartLinkView: DocumentView | undefined = undefined; @observable public AnnotationId: string | undefined = undefined; @observable public AnnotationUri: string | undefined = undefined; @observable public LinkEditorDocView: DocumentView | undefined = undefined; + // eslint-disable-next-line no-use-before-define public static _instance: DocButtonState | undefined; public static get Instance() { + // eslint-disable-next-line no-return-assign return DocButtonState._instance ?? (DocButtonState._instance = new DocButtonState()); } constructor() { @@ -50,7 +54,7 @@ export class DocButtonState { export class DocumentLinksButton extends ObservableReactComponent { private _linkButton = React.createRef(); public static get StartLink() { return DocButtonState.Instance.StartLink; } // prettier-ignore - public static set StartLink(value) { runInAction(() => (DocButtonState.Instance.StartLink = value)); } // prettier-ignore + public static set StartLink(value) { runInAction(() => {DocButtonState.Instance.StartLink = value}); } // prettier-ignore @observable public static StartLinkView: DocumentView | undefined = undefined; @observable public static AnnotationId: string | undefined = undefined; @observable public static AnnotationUri: string | undefined = undefined; @@ -93,7 +97,9 @@ export class DocumentLinksButton extends ObservableReactComponent (DocButtonState.Instance.LinkEditorDocView = this._props.View)) + action(() => { + DocButtonState.Instance.LinkEditorDocView = this._props.View; + }) ); }; @@ -105,7 +111,7 @@ export class DocumentLinksButton extends ObservableReactComponent { if (doubleTap && this._props.InMenu && this._props.StartLink) { - //action(() => Doc.BrushDoc(this._props.View.Document)); + // action(() => Doc.BrushDoc(this._props.View.Document)); if (DocumentLinksButton.StartLink === this._props.View.Document) { DocumentLinksButton.StartLink = undefined; DocumentLinksButton.StartLinkView = undefined; @@ -119,7 +125,7 @@ export class DocumentLinksButton extends ObservableReactComponent { + onLinkClick = (): void => { if (this._props.InMenu && this._props.StartLink) { DocumentLinksButton.AnnotationId = undefined; DocumentLinksButton.AnnotationUri = undefined; @@ -127,7 +133,7 @@ export class DocumentLinksButton extends ObservableReactComponent (TaskCompletionBox.taskCompleted = false)), + action(() => { + TaskCompletionBox.taskCompleted = false; + }), 2500 ); } @@ -243,13 +253,13 @@ export class DocumentLinksButton extends ObservableReactComponent - {this._props.StartLink ? ( //if link has been started from current node, then set behavior of link button to deactivate linking when clicked again + {this._props.StartLink ? ( // if link has been started from current node, then set behavior of link button to deactivate linking when clicked again
) : null} - {!this._props.StartLink && DocumentLinksButton.StartLink !== this._props.View.Document ? ( //if the origin node is not this node -
+ {!this._props.StartLink && DocumentLinksButton.StartLink !== this._props.View.Document ? ( // if the origin node is not this node +
) : null} @@ -263,7 +273,7 @@ export class DocumentLinksButton extends ObservableReactComponent boolean = returnFalse; + public static addDocTabFunc: (doc: Doc | Doc[], location: OpenWhere) => boolean = returnFalse; private _disposers: { [name: string]: IReactionDisposer } = {}; private _doubleClickTimeout: NodeJS.Timeout | undefined; diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 14454ff61..5c91d5aca 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -1,3 +1,5 @@ +/* eslint-disable react/no-unused-prop-types */ +/* eslint-disable react/require-default-props */ import { computed } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; @@ -31,6 +33,7 @@ export interface FocusViewOptions { easeFunc?: 'linear' | 'ease'; // transition method for scrolling } export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt; +// eslint-disable-next-line no-use-before-define export type StyleProviderFuncType = (doc: Opt, props: Opt, property: string) => any; // // these properties get assigned through the render() method of the DocumentView when it creates this node. @@ -73,13 +76,14 @@ export interface FieldViewSharedProps { onPointerDownScript?: () => ScriptField; onPointerUpScript?: () => ScriptField; onBrowseClickScript?: () => ScriptField | undefined; + // eslint-disable-next-line no-use-before-define onKey?: (e: React.KeyboardEvent, fieldProps: FieldViewProps) => boolean | undefined; layout_fitWidth?: (doc: Doc) => boolean | undefined; searchFilterDocs: () => Doc[]; layout_showTitle?: () => string; whenChildContentsActiveChanged: (isActive: boolean) => void; rootSelected?: () => boolean; // whether the root of a template has been selected - addDocTab: (doc: Doc, where: OpenWhere) => boolean; + addDocTab: (doc: Doc | Doc[], where: OpenWhere) => boolean; filterAddDocument?: (doc: Doc[]) => boolean; // allows a document that renders a Collection view to filter or modify any documents added to the collection (see PresBox for an example) addDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean; removeDocument?: (doc: Doc | Doc[], annotationKey?: string) => boolean; @@ -120,7 +124,7 @@ export interface FieldViewProps extends FieldViewSharedProps { @observer export class FieldView extends React.Component { public static LayoutString(fieldType: { name: string }, fieldStr: string) { - return `<${fieldType.name} {...props} fieldKey={'${fieldStr}'}/>`; //e.g., "" + return `<${fieldType.name} {...props} fieldKey={'${fieldStr}'}/>`; // e.g., "" } @computed get fieldval() { return this.props.Document[this.props.fieldKey]; @@ -135,6 +139,6 @@ export class FieldView extends React.Component { if (field instanceof List) return
{field.map(f => Field.toString(f)).join(', ')}
; if (field instanceof WebField) return

{Field.toString(field.url.href)}

; if (!(field instanceof Promise)) return

{Field.toString(field)}

; - return

{'Waiting for server...'}

; + return

Waiting for server...

; } } diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 70fc63115..79738c452 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -1,13 +1,14 @@ +/* eslint-disable react/jsx-props-no-spreading */ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Button, ColorPicker, Dropdown, DropdownType, EditableText, IconButton, IListItemProps, MultiToggle, NumberDropdown, NumberDropdownType, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components'; +import { Button, ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, MultiToggle, NumberDropdown, NumberDropdownType, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; +import { ClientUtils, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils'; import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc'; import { BoolCast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; -import { emptyFunction, Utils } from '../../../../Utils'; -import { ClientUtils, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils'; +import { emptyFunction } from '../../../../Utils'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; import { SelectionManager } from '../../../util/SelectionManager'; import { SettingsManager } from '../../../util/SettingsManager'; @@ -34,7 +35,7 @@ export enum ButtonType { NumberSliderButton = 'numSliderBtn', NumberDropdownButton = 'numDropdownBtn', NumberInlineButton = 'numInlineBtn', - EditableText = 'editableText', + EditText = 'editableText', } export interface ButtonProps extends FieldViewProps { @@ -83,7 +84,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { if (iconFalse) { icon = StrCast(this.dataDoc[this.fieldKey ?? 'iconFalse'] ?? this.dataDoc.icon, 'user') as any; if (icon) return ; - else return null; + return null; } icon = StrCast(this.dataDoc[this.fieldKey ?? 'icon'] ?? this.dataDoc.icon, 'user') as any; return !icon ? null : icon === 'pres-trail' ? TrailsIcon(color) : ; @@ -109,7 +110,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { * - Color button * - Dropdown list * - Number button - **/ + * */ _batch: UndoManager.Batch | undefined = undefined; /** @@ -118,17 +119,12 @@ export class FontIconBox extends ViewBoxBaseComponent() { @computed get numberDropdown() { let type: NumberDropdownType; switch (this.type) { - case ButtonType.NumberDropdownButton: - type = 'dropdown'; - break; - case ButtonType.NumberInlineButton: - type = 'input'; - break; + case ButtonType.NumberDropdownButton: type = 'dropdown'; break; + case ButtonType.NumberInlineButton: type = 'input'; break; case ButtonType.NumberSliderButton: - default: - type = 'slider'; + default: type = 'slider'; break; - } + } // prettier-ignore const numScript = (value?: number) => ScriptCast(this.Document.script).script.run({ this: this.Document, self: this.Document, value, _readOnly_: value === undefined }); const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); // Script for checking the outcome of the toggle @@ -155,12 +151,10 @@ export class FontIconBox extends ViewBoxBaseComponent() { setupMoveUpEvents( this, e, - (e: PointerEvent) => { - return ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, self: this.Document, value: { doc: value, e } }).result; - }, + () => ScriptCast(this.Document.onDragScript)?.script.run({ this: this.Document, self: this.Document, value: { doc: value, e } }).result, emptyFunction, emptyFunction - ); + ); // prettier-ignore return false; }; @@ -189,7 +183,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { } return ( } + icon={} text={text} type={Type.TERT} color={SettingsManager.userColor} @@ -275,8 +269,8 @@ export class FontIconBox extends ViewBoxBaseComponent() { // Determine the type of toggle button const tooltip: string = StrCast(this.Document.toolTip); - const script = ScriptCast(this.Document.onClick); - const toggleStatus = script ? script.script.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result : false; + // const script = ScriptCast(this.Document.onClick); + // const toggleStatus = script ? script.script.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result : false; // Colors const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); const items = DocListCast(this.dataDoc.data); @@ -313,7 +307,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { const toggleStatus = script?.script.run({ this: this.Document, self: this.Document, value: undefined, _readOnly_: true }).result ?? false; // Colors const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); - const backgroundColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor); + // const backgroundColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor); return ( () { toggleStatus={toggleStatus} text={buttonText} color={color} - //background={SettingsManager.userBackgroundColor} + // background={SettingsManager.userBackgroundColor} icon={this.Icon(color)!} label={this.label} onPointerDown={e => @@ -332,10 +326,10 @@ export class FontIconBox extends ViewBoxBaseComponent() { e, returnTrue, emptyFunction, - action((e, doubleTap) => { + action((clickEv, doubleTap) => { (!doubleTap || !double) && script?.script.run({ this: this.Document, self: this.Document, value: !toggleStatus, _readOnly_: false }); doubleTap && double?.script.run({ this: this.Document, self: this.Document, value: !toggleStatus, _readOnly_: false }); - this._hackToRecompute = this._hackToRecompute + 1; + this._hackToRecompute += 1; }) ) } @@ -348,27 +342,22 @@ export class FontIconBox extends ViewBoxBaseComponent() { */ @computed get defaultButton() { const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); - const backgroundColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor); const tooltip: string = StrCast(this.Document.toolTip); return ; } @computed get editableText() { - // Script for running the toggle const script = ScriptCast(this.Document.script); - // Function to run the script const checkResult = script?.script.run({ this: this.Document, self: this.Document, value: '', _readOnly_: true }).result; - const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ this: this.Document, self: this.Document, value, _readOnly_: false }).result; - - return {}} />; + const setValue = (value: string): boolean => script?.script.run({ this: this.Document, self: this.Document, value, _readOnly_: false }).result; return (
- +
- script?.script.run({ this: this.Document, self: this.Document, value: '', _readOnly_: true }).result} SetValue={setValue} oneLine={true} contents={checkResult} /> + script?.script.run({ this: this.Document, self: this.Document, value: '', _readOnly_: true }).result} SetValue={setValue} oneLine contents={checkResult} />
); @@ -384,7 +373,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { case ButtonType.NumberDropdownButton: case ButtonType.NumberInlineButton: case ButtonType.NumberSliderButton: return this.numberDropdown; - case ButtonType.EditableText: return this.editableText; + case ButtonType.EditText: return this.editableText; case ButtonType.DropdownList: return this.dropdownListButton; case ButtonType.ColorButton: return this.colorButton; case ButtonType.MultiToggleButton: return this.multiToggleButton; @@ -395,6 +384,7 @@ export class FontIconBox extends ViewBoxBaseComponent() { background={SettingsManager.userBackgroundColor} text={StrCast(this.dataDoc.buttonText)}/>; case ButtonType.MenuButton: return ; + default: } return this.defaultButton; }; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 231300a65..90b4a6740 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -22,7 +22,7 @@ import { Networking } from '../../Network'; import { DocumentManager } from '../../util/DocumentManager'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; -import { ContextMenu } from '../../views/ContextMenu'; +import { ContextMenu } from '../ContextMenu'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { ContextMenuProps } from '../ContextMenuItem'; import { PinProps, ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; @@ -428,9 +428,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl setupMoveUpEvents( this, e, - action(e => { + action(moveEv => { MarqueeAnnotator.clearAnnotations(this._savedAnnotations); - this._marqueeref.current?.onInitiateSelection([e.clientX, e.clientY]); + this._marqueeref.current?.onInitiateSelection([moveEv.clientX, moveEv.clientY]); return true; }), returnFalse, @@ -476,6 +476,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() impl }}> { render() { // let fieldKey = Object.keys(props.Document).indexOf(props.fieldKey) !== -1 ? props.fieldKey : "(" + props.fieldKey + ")"; let protoCount = 0; - let doc = this._props.doc; + let { doc } = this._props; while (doc) { if (Object.keys(doc).includes(this._props.keyName)) { break; @@ -77,10 +78,18 @@ export class KeyValuePair extends ObservableReactComponent { const hover = { transition: '0.3s ease opacity', opacity: this.isPointerOver || this.isChecked ? 1 : 0 }; return ( - (this.isPointerOver = true))} onPointerLeave={action(() => (this.isPointerOver = false))}> + { + this.isPointerOver = true; + })} + onPointerLeave={action(() => { + this.isPointerOver = false; + })}>
); } @@ -605,7 +607,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent this._bingMap.current.entities.remove(this.map_docToPinMap.get(pin)); this.map_docToPinMap.delete(pin); const newpin = new this.MicrosoftMaps.Pushpin(new this.MicrosoftMaps.Location(pin.latitude, pin.longitude), color ? { color } : {}); - this.MicrosoftMaps.Events.addHandler(newpin, 'click', (e: any) => this.pushpinClicked(pin)); + this.MicrosoftMaps.Events.addHandler(newpin, 'click', () => this.pushpinClicked(pin)); this._bingMap.current.entities.push(newpin); this.map_docToPinMap.set(pin, newpin); }; @@ -637,7 +639,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent () => this.allAnnotations.map(doc => doc[Highlight]), () => { const allConfigPins = this.allAnnotations.map(doc => ({ doc, pushpin: DocCast(doc.mapPin) })).filter(pair => pair.pushpin); - allConfigPins.forEach(({ doc, pushpin }) => { + allConfigPins.forEach(({ pushpin }) => { if (!pushpin[Highlight] && this.map_pinHighlighted.get(pushpin)) { this.recolorPin(pushpin); this.map_pinHighlighted.delete(pushpin); @@ -736,7 +738,6 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent return null; } - const renderAnnotations = (childFilters?: () => string[]) => null; return (
e.button === 0 && !e.ctrlKey && e.stopPropagation(); }} style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}> -
{renderAnnotations(this.transparentFilter)}
- {renderAnnotations(this.opaqueFilter)} - {SnappingManager.IsDragging ? null : renderAnnotations()} -
typeof newText === 'string' && this.searchbarOnEdit(newText)} - onEnter={e => this.bingSearch()} + onEnter={() => this.bingSearch()} placeholder={this.bingSearchBarContents || 'enter city/zip/...'} textAlign="center" /> @@ -792,7 +789,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent ? null : this.allAnnotations .filter(anno => !anno.layout_unrendered) - .map((pushpin, i) => ( + .map(pushpin => ( () implem const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200; !this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (nh / nw)); if (this.pdfUrl) { - if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) runInAction(() => (this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href))); - else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action((pdf: any) => (this._pdf = pdf))); + if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) + runInAction(() => { + this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href); + }); + else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) + PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then( + action((pdf: any) => { + this._pdf = pdf; + }) + ); } } @@ -86,7 +96,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem if (oldDiv instanceof HTMLCanvasElement) { const canvas = oldDiv; const img = document.createElement('img'); // create a Image Element - img.src = canvas.toDataURL(); //image sourcez + img.src = canvas.toDataURL(); // image sourcez img.style.width = canvas.style.width; img.style.height = canvas.style.height; const newCan = newDiv as HTMLCanvasElement; @@ -97,7 +107,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem }; crop = (region: Doc | undefined, addCrop?: boolean) => { - if (!region) return; + if (!region) return undefined; const cropping = Doc.MakeCopy(region, true); const regionData = region[DocData]; regionData.lockedPosition = true; @@ -112,11 +122,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem this.replaceCanvases(docViewContent, newDiv); const htmlString = this._pdfViewer?._mainCont.current && new XMLSerializer().serializeToString(newDiv); - const anchx = NumCast(cropping.x); - const anchy = NumCast(cropping.y); + // const anchx = NumCast(cropping.x); + // const anchy = NumCast(cropping.y); const anchw = NumCast(cropping._width) * (this._props.NativeDimScaling?.() || 1); const anchh = NumCast(cropping._height) * (this._props.NativeDimScaling?.() || 1); - const viewScale = 1; + // const viewScale = 1; cropping.title = 'crop: ' + this.Document.title; cropping.x = NumCast(this.Document.x) + NumCast(this.layoutDoc._width); cropping.y = NumCast(this.Document.y); @@ -157,7 +167,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem ) ); }) - .catch(function (error: any) { + .catch((error: any) => { console.error('oops, something went wrong!', error); }); @@ -245,7 +255,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem } const docAnchor = () => Docs.Create.ConfigDocument({ - title: StrCast(this.Document.title + '@' + NumCast(this.layoutDoc._layout_scrollTop)?.toFixed(0)), + title: StrCast(this.Document.title + '@' + (NumCast(this.layoutDoc._layout_scrollTop) ?? 0).toFixed(0)), annotationOn: this.Document, }); const visibleAnchor = this._pdfViewer?._getAnchor?.(this._pdfViewer.savedAnnotations(), true); @@ -288,7 +298,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem this.Document._layout_curPage = Math.min(NumCast(this.dataDoc[this._props.fieldKey + '_numPages']), (NumCast(this.Document._layout_curPage) || 1) + 1); return true; }; - public gotoPage = (p: number) => (this.Document._layout_curPage = p); + public gotoPage = (p: number) => { + this.Document._layout_curPage = p; + }; @undoBatch onKeyDown = action((e: KeyboardEvent) => { @@ -300,6 +312,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem case 'PageUp': processed = this.backPage(); break; + default: } if (processed) { e.stopImmediatePropagation(); @@ -315,7 +328,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem this._initialScrollTarget = undefined; } }; - searchStringChanged = (e: React.ChangeEvent) => (this._searchString = e.currentTarget.value); + searchStringChanged = (e: React.ChangeEvent) => { + this._searchString = e.currentTarget.value; + }; // adding external documents; to sidebar key // if (doc.Geolocation) this.addDocument(doc, this.fieldkey+"_annotation") @@ -371,11 +386,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem settingsPanel() { const pageBtns = ( <> - - ); @@ -388,7 +403,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem onPointerDown={e => e.stopPropagation()} style={{ display: this._props.isContentActive() ? 'flex' : 'none' }}>
e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}> - - -
@@ -443,14 +463,16 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem return PDFBox.sidebarResizerWidth + nativeDiff * (this._props.NativeDimScaling?.() || 1); }; @undoBatch - toggleSidebarType = () => (this.dataDoc[this.SidebarKey + '_type_collection'] = this.dataDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform ? CollectionViewType.Stacking : CollectionViewType.Freeform); - specificContextMenu = (e: React.MouseEvent): void => { + toggleSidebarType = () => { + this.dataDoc[this.SidebarKey + '_type_collection'] = this.dataDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform ? CollectionViewType.Stacking : CollectionViewType.Freeform; + }; + specificContextMenu = (): void => { const cm = ContextMenu.Instance; const options = cm.findByDescription('Options...'); const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : []; !Doc.noviceMode && optionItems.push({ description: 'Toggle Sidebar Type', event: this.toggleSidebarType, icon: 'expand-arrows-alt' }); !Doc.noviceMode && optionItems.push({ description: 'update icon', event: () => this.pdfUrl && this.updateIcon(), icon: 'expand-arrows-alt' }); - //optionItems.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" }); + // optionItems.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" }); !options && ContextMenu.Instance.addItem({ description: 'Options...', subitems: optionItems, icon: 'asterisk' }); const help = cm.findByDescription('Help...'); const helpItems: ContextMenuProps[] = help && 'subitems' in help ? help.subitems : []; @@ -472,7 +494,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; @observable _showSidebar = false; @computed get SidebarShown() { - return this._showSidebar || this.layoutDoc._show_sidebar ? true : false; + return !!(this._showSidebar || this.layoutDoc._show_sidebar); } @computed get sidebarHandle() { return ( @@ -486,7 +508,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK, }} onPointerDown={e => this.sidebarBtnDown(e, true)}> - +
); } @@ -517,6 +539,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem return ComponentTag === CollectionStackingView ? ( () implem ) : (
setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.DocumentView?.()!, false), true)}> () implem yPadding={0} viewField={this.SidebarKey} isAnnotationOverlay={false} - originTopLeft={true} + originTopLeft isAnyChildContentActive={this.isAnyChildContentActive} select={emptyFunction} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} @@ -551,7 +575,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem addDocument={this.sidebarAddDocument} ScreenToLocalTransform={this.sidebarScreenToLocal} renderDepth={this._props.renderDepth + 1} - noSidebar={true} + noSidebar fieldKey={this.SidebarKey} />
@@ -585,6 +609,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() implem top: 0, }}> () implem const pdfView = !this._pdf ? null : this.renderPdfView; const href = this.pdfUrl?.url.href; if (!pdfView && href) { - if (PDFBox.pdfcache.get(href)) setTimeout(action(() => (this._pdf = PDFBox.pdfcache.get(href)))); + if (PDFBox.pdfcache.get(href)) + setTimeout( + action(() => { + this._pdf = PDFBox.pdfcache.get(href); + }) + ); else { if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise); - PDFBox.pdfpromise.get(href)?.then(action((pdf: any) => PDFBox.pdfcache.set(href, (this._pdf = pdf)))); + PDFBox.pdfpromise.get(href)?.then( + action((pdf: any) => { + PDFBox.pdfcache.set(href, (this._pdf = pdf)); + }) + ); } } return pdfView ?? this.renderTitleBox; diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx index 40199cce1..7d123d90c 100644 --- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx +++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx @@ -47,7 +47,9 @@ export class RecordingBox extends ViewBoxBaseComponent() { @observable videoDuration: number | undefined = undefined; @action - setVideoDuration = (duration: number) => (this.videoDuration = duration); + setVideoDuration = (duration: number) => { + this.videoDuration = duration; + }; @action setResult = (info: Upload.AccessPathInfo, presentation?: Presentation) => { @@ -69,15 +71,15 @@ export class RecordingBox extends ViewBoxBaseComponent() { public static WorkspaceStopRecording() { const remDoc = RecordingBox.screengrabber?.Document; if (remDoc) { - //if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening + // if recordingbox is true; when we press the stop button. changed vals temporarily to see if changes happening RecordingBox.screengrabber?.Pause?.(); setTimeout(() => { RecordingBox.screengrabber?.Finish?.(); - remDoc.overlayX = 70; //was 100 + remDoc.overlayX = 70; // was 100 remDoc.overlayY = 590; RecordingBox.screengrabber = undefined; }, 100); - //could break if recording takes too long to turn into videobox. If so, either increase time on setTimeout below or find diff place to do this + // could break if recording takes too long to turn into videobox. If so, either increase time on setTimeout below or find diff place to do this setTimeout(() => Doc.RemFromMyOverlay(remDoc), 1000); Doc.UserDoc().workspaceRecordingState = mediaState.Paused; Doc.AddDocToList(Doc.UserDoc(), 'workspaceRecordings', remDoc); @@ -103,10 +105,10 @@ export class RecordingBox extends ViewBoxBaseComponent() { _width: 205, _height: 115, }); - screengrabber.overlayX = 70; //was -400 - screengrabber.overlayY = 590; //was 0 + screengrabber.overlayX = 70; // was -400 + screengrabber.overlayY = 590; // was 0 screengrabber[DocData][Doc.LayoutFieldKey(screengrabber) + '_trackScreen'] = true; - Doc.AddToMyOverlay(screengrabber); //just adds doc to overlay + Doc.AddToMyOverlay(screengrabber); // just adds doc to overlay DocumentManager.Instance.AddViewRenderedCb(screengrabber, docView => { RecordingBox.screengrabber = docView.ComponentView as RecordingBox; RecordingBox.screengrabber.Record?.(); @@ -137,7 +139,7 @@ export class RecordingBox extends ViewBoxBaseComponent() { */ @undoBatch public static addRecToWorkspace(value: RecordingBox) { - let ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); + const ffView = Array.from(DocumentManager.Instance.DocumentViews).find(view => view.ComponentView instanceof CollectionFreeFormView); (ffView?.ComponentView as CollectionFreeFormView)._props.addDocument?.(value.Document); Doc.RemoveDocFromList(Doc.UserDoc(), 'workspaceRecordings', value.Document); Doc.RemFromMyOverlay(value.Document); @@ -204,51 +206,66 @@ export class RecordingBox extends ViewBoxBaseComponent() {
); } + // eslint-disable-next-line no-use-before-define static screengrabber: RecordingBox | undefined; } +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function stopWorkspaceRecording() { RecordingBox.WorkspaceStopRecording(); }); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function stopWorkspaceReplaying(value: Doc) { RecordingBox.stopWorkspaceReplaying(value); }); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function removeWorkspaceReplaying(value: Doc) { RecordingBox.removeWorkspaceReplaying(value); }); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function getCurrentRecording() { return Doc.UserDoc().currentRecording; }); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function getWorkspaceRecordings() { return new List(['Record Workspace', `Record Webcam`, ...DocListCast(Doc.UserDoc().workspaceRecordings)]); }); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function isWorkspaceRecording() { return Doc.UserDoc().workspaceRecordingState === mediaState.Recording; }); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function isWorkspaceReplaying() { return Doc.UserDoc().workspaceReplayingState; }); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function replayWorkspace(value: Doc | string, _readOnly_: boolean) { if (_readOnly_) return DocCast(Doc.UserDoc().currentRecording) ?? 'Record Workspace'; if (typeof value === 'string') RecordingBox.WorkspaceStartRecording(value); else RecordingBox.replayWorkspace(value); + return undefined; }); -ScriptingGlobals.add(function pauseWorkspaceReplaying(value: Doc, _readOnly_: boolean) { +// eslint-disable-next-line prefer-arrow-callback +ScriptingGlobals.add(function pauseWorkspaceReplaying(value: Doc) { RecordingBox.pauseWorkspaceReplaying(value); }); -ScriptingGlobals.add(function resumeWorkspaceReplaying(value: Doc, _readOnly_: boolean) { +// eslint-disable-next-line prefer-arrow-callback +ScriptingGlobals.add(function resumeWorkspaceReplaying(value: Doc) { RecordingBox.resumeWorkspaceReplaying(value); }); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function startRecordingDrag(value: { doc: Doc | string; e: React.PointerEvent }) { if (DocCast(value.doc)) { DragManager.StartDocumentDrag([value.e.target as HTMLElement], new DragManager.DocumentDragData([DocCast(value.doc)], dropActionType.embed), value.e.clientX, value.e.clientY); value.e.preventDefault(); return true; } + return undefined; }); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function renderDropdown() { if (!Doc.UserDoc().workspaceRecordings || DocListCast(Doc.UserDoc().workspaceRecordings).length === 0) { return true; diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index e29e47514..882f6ba9e 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/media-has-caption */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import * as React from 'react'; // import { Canvas } from '@react-three/fiber'; @@ -163,7 +164,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent() ind !== -1 && DocUtils.ActiveRecordings.splice(ind, 1); } - specificContextMenu = (e: React.MouseEvent): void => { + specificContextMenu = (): void => { const subitems = [{ description: 'Screen Capture', event: this.toggleRecording, icon: 'expand-arrows-alt' as any }]; ContextMenu.Instance.addItem({ description: 'Options...', subitems, icon: 'video' }); }; @@ -171,7 +172,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent() @computed get content() { return (