From 04669ffeb163688c7aefd7b5face7998252abdca Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 10 Mar 2025 18:02:07 -0400 Subject: removed label creation from text's anchor menu. removed label creation from pdfs. --- src/client/views/pdf/AnchorMenu.tsx | 53 +++---------------------------------- src/client/views/pdf/PDFViewer.tsx | 8 +++--- 2 files changed, 8 insertions(+), 53 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index 9aa8fe649..eaaeb8d97 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -1,24 +1,19 @@ import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from '@dash/components'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; +import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { ColorResult } from 'react-color'; -import ReactLoading from 'react-loading'; import { ClientUtils, returnFalse, setupMoveUpEvents } from '../../../ClientUtils'; import { emptyFunction, unimplementedFunction } from '../../../Utils'; import { Doc, Opt } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { SettingsManager } from '../../util/SettingsManager'; -import { undoBatch } from '../../util/UndoManager'; import { AntimodeMenu, AntimodeMenuProps } from '../AntimodeMenu'; import { LinkPopup } from '../linking/LinkPopup'; import { ComparisonBox } from '../nodes/ComparisonBox'; import { DocumentView } from '../nodes/DocumentView'; -import { DrawingOptions, SmartDrawHandler } from '../smartdraw/SmartDrawHandler'; import './AnchorMenu.scss'; import { GPTPopup } from './GPTPopup/GPTPopup'; -import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; @observer export class AnchorMenu extends AntimodeMenu { @@ -116,39 +111,6 @@ export class AnchorMenu extends AntimodeMenu { ); }; - /** - * Creates a GPT drawing based on selected text. - */ - gptDraw = (e: React.PointerEvent) => { - try { - SmartDrawHandler.Instance.AddDrawing = this.createDrawingAnnotation; - runInAction(() => (this._isLoading = true)); - SmartDrawHandler.Instance.drawWithGPT({ X: e.clientX, Y: e.clientY }, this._selectedText, 5, 100, true)?.then( - action(() => { - this._isLoading = false; - }) - ); - } catch (err) { - console.error(err); - } - }; - - /** - * Defines how a GPT drawing should be added to the current document. - */ - @undoBatch - createDrawingAnnotation = action((drawing: Doc, opts: DrawingOptions, gptRes: string) => { - this.AddDrawingAnnotation(drawing); - const docData = drawing[DocData]; - docData.title = opts.text?.match(/^(.*?)~~~.*$/)?.[1] || opts.text; - docData.ai_drawing_input = opts.text; - docData.ai_drawing_complexity = opts.complexity; - docData.ai_drawing_colored = opts.autoColor; - docData.ai_drawing_size = opts.size; - docData.ai_drawing_data = gptRes; - docData.ai = 'gpt'; - }); - pointerDown = (e: React.PointerEvent) => { setupMoveUpEvents( this, @@ -232,17 +194,8 @@ export class AnchorMenu extends AntimodeMenu { /> )} {/* Adds a create flashcards option to the anchor menu, which calls the gptFlashcard method. */} - } color={SettingsManager.userColor} /> - } color={SettingsManager.userColor} /> - {this._selectedText && ( - this.gptDraw(e)} - icon={this._isLoading ? : } - color={SettingsManager.userColor} - /> - )} - {this._selectedText && RichTextMenu.Instance?.createLinkButton()} + {this.gptFlashcards === unimplementedFunction ? null : } color={SettingsManager.userColor} />} + {this.makeLabels === unimplementedFunction ? null : } color={SettingsManager.userColor} />} {AnchorMenu.Instance.OnAudio === unimplementedFunction ? null : ( { */ gptPDFFlashcards = async () => { const queryText = this._selectionText; - this._loading = true; + runInAction(() => (this._loading = true)); try { const res = await gptAPICall(queryText, GPTCallType.FLASHCARD); @@ -406,11 +406,12 @@ export class PDFViewer extends ObservableReactComponent { } catch (err) { console.error(err); } - this._loading = false; + runInAction(() => (this._loading = false)); }; @action finishMarquee = (/* x?: number, y?: number */) => { + AnchorMenu.Instance.makeLabels = unimplementedFunction; this._getAnchor = AnchorMenu.Instance?.GetAnchor; this.isAnnotating = false; this._marqueeref.current?.onTerminateSelection(); @@ -442,6 +443,7 @@ export class PDFViewer extends ObservableReactComponent { // allows for creating collection AnchorMenu.Instance.addToCollection = this._props.DocumentView?.()._props.addDocument; AnchorMenu.Instance.gptFlashcards = this.gptPDFFlashcards; + AnchorMenu.Instance.makeLabels = unimplementedFunction; AnchorMenu.Instance.AddDrawingAnnotation = this.addDrawingAnnotation; }; -- cgit v1.2.3-70-g09d2 From 429da4f68c4b661871128cc7763f03eb508ecba0 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 11 Mar 2025 13:12:15 -0400 Subject: restored linkbutton to text anchor menu --- src/client/views/pdf/AnchorMenu.tsx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index eaaeb8d97..6ae659ac1 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -12,6 +12,7 @@ import { AntimodeMenu, AntimodeMenuProps } from '../AntimodeMenu'; import { LinkPopup } from '../linking/LinkPopup'; import { ComparisonBox } from '../nodes/ComparisonBox'; import { DocumentView } from '../nodes/DocumentView'; +import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; import './AnchorMenu.scss'; import { GPTPopup } from './GPTPopup/GPTPopup'; @@ -196,6 +197,7 @@ export class AnchorMenu extends AntimodeMenu { {/* Adds a create flashcards option to the anchor menu, which calls the gptFlashcard method. */} {this.gptFlashcards === unimplementedFunction ? null : } color={SettingsManager.userColor} />} {this.makeLabels === unimplementedFunction ? null : } color={SettingsManager.userColor} />} + {this._selectedText && RichTextMenu.Instance?.createLinkButton()} {AnchorMenu.Instance.OnAudio === unimplementedFunction ? null : ( Date: Fri, 14 Mar 2025 12:20:41 -0400 Subject: simplified anchorMenu to just have an AskAI button .. then updated GPtPopup's summaryBox to have a flashcard option. --- src/client/views/StyleProviderQuiz.tsx | 31 ++-- .../views/nodes/formattedText/FormattedTextBox.tsx | 41 +----- src/client/views/nodes/trails/PresElementBox.tsx | 5 +- src/client/views/pdf/AnchorMenu.tsx | 26 +--- src/client/views/pdf/GPTPopup/GPTPopup.scss | 16 +-- src/client/views/pdf/GPTPopup/GPTPopup.tsx | 160 +++++++++++++++------ src/client/views/pdf/PDFViewer.tsx | 21 +-- 7 files changed, 152 insertions(+), 148 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/StyleProviderQuiz.tsx b/src/client/views/StyleProviderQuiz.tsx index acda38dd7..f9ee8d3db 100644 --- a/src/client/views/StyleProviderQuiz.tsx +++ b/src/client/views/StyleProviderQuiz.tsx @@ -9,7 +9,7 @@ import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; import { NumCast, StrCast } from '../../fields/Types'; import { Networking } from '../Network'; -import { GPTCallType, gptAPICall, gptImageLabel } from '../apis/gpt/GPT'; +import { GPTCallType, gptAPICall } from '../apis/gpt/GPT'; import { Docs } from '../documents/Documents'; import { ContextMenu } from './ContextMenu'; import { ContextMenuProps } from './ContextMenuItem'; @@ -110,20 +110,21 @@ export namespace styleProviderQuiz { const blob = await ImageUtility.canvasToBlob(canvas); return selectUrlToBase64(blob); } - /** - * Create flashcards from an image. - */ - async function makeFlashcardsForImage(img: ImageBox) { - img.Loading = true; - try { - const hrefBase64 = await createCanvas(img); - const response = await gptImageLabel(hrefBase64, 'Make flashcards out of this image with each question and answer labeled as "question" and "answer". Do not label each flashcard and do not include asterisks: '); - AnchorMenu.Instance.transferToFlashcard(response, NumCast(img.layoutDoc.x), NumCast(img.layoutDoc.y)); - } catch (error) { - console.log('Error', error); - } - img.Loading = false; - } + + // /** + // * Create flashcards from an image. + // */ + // async function makeFlashcardsForImage(img: ImageBox) { + // img.Loading = true; + // try { + // const hrefBase64 = await createCanvas(img); + // const response = await gptImageLabel(hrefBase64, 'Make flashcards out of this image with each question and answer labeled as "question" and "answer". Do not label each flashcard and do not include asterisks: '); + // AnchorMenu.Instance.transferToFlashcard(response, NumCast(img.layoutDoc.x), NumCast(img.layoutDoc.y)); + // } catch (error) { + // console.log('Error', error); + // } + // img.Loading = false; + // } /** * Calls the createCanvas and pushInfo methods to convert the diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index b86536f86..7b24125e7 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -13,7 +13,7 @@ import { EditorState, NodeSelection, Plugin, Selection, TextSelection, Transacti import { EditorView, NodeViewConstructor } from 'prosemirror-view'; import * as React from 'react'; import { BsMarkdownFill } from 'react-icons/bs'; -import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, imageUrlToBase64, returnFalse, returnZero, setupMoveUpEvents, simMouseEvent, smoothScroll, StopEvent } from '../../../../ClientUtils'; +import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, returnFalse, returnZero, setupMoveUpEvents, simMouseEvent, smoothScroll, StopEvent } from '../../../../ClientUtils'; import { DateField } from '../../../../fields/DateField'; import { CreateLinkToActiveAudio, Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, DocData, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols'; @@ -26,7 +26,7 @@ import { ComputedField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, DateCast, DocCast, FieldValue, NumCast, RTFCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util'; import { emptyFunction, numberRange, unimplementedFunction, Utils } from '../../../../Utils'; -import { gptAPICall, GPTCallType, gptImageLabel } from '../../../apis/gpt/GPT'; +import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT'; import { DocServer } from '../../../DocServer'; import { Docs } from '../../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; @@ -226,18 +226,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - const queryText = window.getSelection()?.toString() ?? ''; - try { - if (queryText) { - const res = await gptAPICall(queryText, GPTCallType.FLASHCARD); - AnchorMenu.Instance.transferToFlashcard(res || 'Something went wrong', NumCast(this.layoutDoc.x), NumCast(this.layoutDoc.y)); - } - } catch (err) { - console.error(err); - } - }; - @action setupAnchorMenu = () => { AnchorMenu.Instance.Status = 'marquee'; @@ -1012,31 +1000,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - const c = this.ProseRef?.getElementsByTagName('img'); - if (c) { - for (const i of c) { - // console.log(canvas.toDataURL()); - // canvas.style.zIndex = '2000000'; - // document.body.appendChild(canvas); - if (i.className !== 'ProseMirror-separator') this.getImageDesc(i.src); - } - } - }; - - getImageDesc = async (u: string) => { - try { - const hrefBase64 = await imageUrlToBase64(u); - const response = await gptImageLabel( - hrefBase64, - 'Make flashcards out of this text and image with each question and answer labeled as question and answer. Do not label each flashcard and do not include asterisks: ' + (this.dataDoc.text as RichTextField)?.Text - ); - AnchorMenu.Instance.transferToFlashcard(response || 'Something went wrong', NumCast(this.dataDoc['x']), NumCast(this.dataDoc['y'])); - } catch (error) { - console.log('Error', error); - } - }; - animateRes = (resIndex: number, newText: string) => { if (resIndex < newText.length) { const marks = this.EditorView?.state.storedMarks ?? []; diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx index 957df894c..31cd1603f 100644 --- a/src/client/views/nodes/trails/PresElementBox.tsx +++ b/src/client/views/nodes/trails/PresElementBox.tsx @@ -239,10 +239,7 @@ export class PresElementBox extends ViewBoxBaseComponent() { e.clientY, undefined, action(() => { - Array.from(classesToRestore).forEach(pair => { - // eslint-disable-next-line prefer-destructuring - pair[0].className = pair[1]; - }); + Array.from(classesToRestore).forEach(pair => (pair[0].className = pair[1])); this._dragging = false; }) ); diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index 6ae659ac1..eb6516403 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -10,7 +10,6 @@ import { Doc, Opt } from '../../../fields/Doc'; import { SettingsManager } from '../../util/SettingsManager'; import { AntimodeMenu, AntimodeMenuProps } from '../AntimodeMenu'; import { LinkPopup } from '../linking/LinkPopup'; -import { ComparisonBox } from '../nodes/ComparisonBox'; import { DocumentView } from '../nodes/DocumentView'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; import './AnchorMenu.scss'; @@ -69,7 +68,6 @@ export class AnchorMenu extends AntimodeMenu { public MakeTargetToggle: () => void = unimplementedFunction; public ShowTargetTrail: () => void = unimplementedFunction; public IsTargetToggler: () => boolean = returnFalse; - public gptFlashcards: () => void = unimplementedFunction; public makeLabels: () => void = unimplementedFunction; public marqueeWidth = 0; public marqueeHeight = 0; @@ -94,22 +92,9 @@ export class AnchorMenu extends AntimodeMenu { * Invokes the API with the selected text and stores it in the summarized text. * @param e pointer down event */ - gptSummarize = () => GPTPopup.Instance.generateSummary(this._selectedText); - - /* - * Transfers the flashcard text generated by GPT on flashcards and creates a collection out them. - */ - - transferToFlashcard = (text: string, x: number, y: number) => { - ComparisonBox.createFlashcardDeck(text, 250, 200, 'data_front', 'data_back').then( - action(newCol => { - newCol.x = x; - newCol.y = y; - newCol.zIndex = 1000; - this.addToCollection?.(newCol); - this._loading = false; - }) - ); + gptAskAboutSelection = () => { + GPTPopup.Instance.askAIAboutSelection(this._selectedText); + AnchorMenu.Instance.fadeOut(true); }; pointerDown = (e: React.PointerEvent) => { @@ -188,14 +173,13 @@ export class AnchorMenu extends AntimodeMenu { {/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection */} {this._selectedText && ( } color={SettingsManager.userColor} /> )} {/* Adds a create flashcards option to the anchor menu, which calls the gptFlashcard method. */} - {this.gptFlashcards === unimplementedFunction ? null : } color={SettingsManager.userColor} />} {this.makeLabels === unimplementedFunction ? null : } color={SettingsManager.userColor} />} {this._selectedText && RichTextMenu.Instance?.createLinkButton()} {AnchorMenu.Instance.OnAudio === unimplementedFunction ? null : ( diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.scss b/src/client/views/pdf/GPTPopup/GPTPopup.scss index c8903e09f..18441f76e 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.scss +++ b/src/client/views/pdf/GPTPopup/GPTPopup.scss @@ -15,12 +15,8 @@ $headingHeight: 32px; height: 100%; top: 0; left: 0; - pointer-events: none; border-top: solid gray 20px; border-radius: 16px; - padding: 16px; - padding-bottom: 0; - padding-top: 0px; z-index: 999; display: flex; flex-direction: column; @@ -29,11 +25,13 @@ $headingHeight: 32px; box-shadow: 0 2px 5px #7474748d; color: $textgrey; - .gptPopup-sortBox { + .gptPopup-summaryBox-content { + padding-right: 16px; + padding-left: 16px; + position: relative; + overflow: hidden; display: flex; flex-direction: column; - height: calc(100% - $inputHeight - $headingHeight); - pointer-events: all; } .summary-heading { @@ -65,7 +63,9 @@ $headingHeight: 32px; .gptPopup-content-wrapper { padding-top: 10px; min-height: 50px; - height: calc(100% - 32px); + white-space: pre-line; + overflow: auto; + margin-bottom: 10px; } .inputWrapper { diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 4dc45e6a0..67213382d 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -31,6 +31,7 @@ import { OpenWhere } from '../../nodes/OpenWhere'; import { DrawingFillHandler } from '../../smartdraw/DrawingFillHandler'; import { ImageField } from '../../../../fields/URLField'; import { List } from '../../../../fields/List'; +import { ComparisonBox } from '../../nodes/ComparisonBox'; export enum GPTPopupMode { SUMMARY, // summary of seleted document text @@ -56,7 +57,7 @@ export class GPTPopup extends ObservableReactComponent { private _dataJson: string = ''; private _documentDescriptions: Promise | undefined; // a cache of the descriptions of all docs in the selected collection. makes it more efficient when asking GPT multiple questions about the collection. private _sidebarFieldKey: string = ''; - private _textToSummarize: string = ''; + private _aiReferenceText: string = ''; private _imageDescription: string = ''; private _textToDocMap = new Map(); // when GPT answers with a doc's content, this helps us find the Doc private _addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined; @@ -79,7 +80,7 @@ export class GPTPopup extends ObservableReactComponent { }; componentDidUpdate() { - this._gptProcessing && this.setStopAnimatingResponse(false); + //this._gptProcessing && this.setStopAnimatingResponse(false); } componentDidMount(): void { reaction( @@ -100,14 +101,14 @@ export class GPTPopup extends ObservableReactComponent { ); } + @observable private _showOriginal = true; + @observable private _responseText: string = ''; @observable private _conversationArray: string[] = ['Hi! In this pop up, you can ask ChatGPT questions about your documents and filter / sort them. ']; @observable private _fireflyArray: string[] = ['Hi! In this pop up, you can ask Firefly to create images. ']; @observable private _chatEnabled: boolean = false; @action private setChatEnabled = (start: boolean) => (this._chatEnabled = start); @observable private _gptProcessing: boolean = false; @action private setGptProcessing = (loading: boolean) => (this._gptProcessing = loading); - @observable private _responseText: string = ''; - @action private setResponseText = (text: string) => (this._responseText = text); @observable private _imgUrls: string[][] = []; @action private setImgUrls = (imgs: string[][]) => (this._imgUrls = imgs); @observable private _collectionContext: Doc | undefined = undefined; @@ -286,18 +287,30 @@ export class GPTPopup extends ObservableReactComponent { /** * Completes an API call to generate a summary of the specified text * - * @param text the text to summarizz + * @param text the text to summarize */ - generateSummary = (text: string) => { + private generateSummary = action((text: string) => { SnappingManager.SetChatVisible(true); - this._textToSummarize = text; - this.setMode(GPTPopupMode.SUMMARY); + this._showOriginal = false; this.setGptProcessing(true); return gptAPICall(text, GPTCallType.SUMMARY) - .then(res => this.setResponseText(res || 'Something went wrong.')) + .then(action(res => (this._responseText = res || 'Something went wrong.'))) .catch(err => console.error(err)) .finally(() => this.setGptProcessing(false)); - }; + }); + + /** + * Completes an API call to generate a summary of the specified text + * + * @param text the text to summarizz + */ + askAIAboutSelection = action((text: string) => { + SnappingManager.SetChatVisible(true); + this._aiReferenceText = text; + this._responseText = ''; + this._showOriginal = true; + this.setMode(GPTPopupMode.SUMMARY); + }); /** * Completes an API call to generate an analysis of @@ -306,14 +319,16 @@ export class GPTPopup extends ObservableReactComponent { generateDataAnalysis = () => { this.setGptProcessing(true); return gptAPICall(this._dataJson, GPTCallType.DATA, this._dataChatPrompt) - .then(res => { - const json = JSON.parse(res! as string); - const keys = Object.keys(json); - this._correlatedColumns = []; - this._correlatedColumns.push(json[keys[0]]); - this._correlatedColumns.push(json[keys[1]]); - this.setResponseText(json[keys[2]] || 'Something went wrong.'); - }) + .then( + action(res => { + const json = JSON.parse(res! as string); + const keys = Object.keys(json); + this._correlatedColumns = []; + this._correlatedColumns.push(json[keys[0]]); + this._correlatedColumns.push(json[keys[1]]); + this._responseText = json[keys[2]] || 'Something went wrong.'; + }) + ) .catch(err => console.error(err)) .finally(() => this.setGptProcessing(false)); }; @@ -336,6 +351,24 @@ export class GPTPopup extends ObservableReactComponent { }); } }; + /** + * Create Flashcards for the selected text + */ + private createFlashcards = action( + () => + this.setGptProcessing(true) && + gptAPICall(this._aiReferenceText, GPTCallType.FLASHCARD, undefined, true) + .then(res => + ComparisonBox.createFlashcardDeck(res, 250, 200, 'data_front', 'data_back').then( + action(newCol => { + newCol.zIndex = 1000; + DocumentViewInternal.addDocTabFunc(newCol, OpenWhere.addRight); + }) + ) + ) + .catch(console.error) + .finally(action(() => (this._gptProcessing = false))) + ); /** * Creates a histogram to show the correlation relationship that was found @@ -536,35 +569,80 @@ export class GPTPopup extends ObservableReactComponent { summaryBox = () => ( <> -
- {this.heading('SUMMARY')} +
+
(this._showOriginal = !this._showOriginal))}>{this.heading(this._showOriginal ? 'SELECTION' : 'SUMMARY')}
- {!this._gptProcessing && - (!this._stopAnimatingResponse ? ( - { - setTimeout(() => this.setStopAnimatingResponse(true), 500); - }, - ]} - /> + {!this._gptProcessing && !this._stopAnimatingResponse && this._responseText ? ( + { + setTimeout(() => this.setStopAnimatingResponse(true), 500); + }, + ]} + /> + ) : this._showOriginal ? ( + this._gptProcessing ? ( + '...generating cards...' ) : ( - this._responseText - ))} + this._aiReferenceText + ) + ) : ( + this._responseText || (this._gptProcessing ? '...generating summary...' : '-no ai summary-') + )}
- {!this._gptProcessing && ( -
- {this._stopAnimatingResponse ? ( - <> - this.generateSummary(this._textToSummarize + ' ')} icon={} color={StrCast(SettingsManager.userVariantColor)} /> -
) : (
- Summarizing + {this._showOriginal ? 'Creating Cards...' : 'Summarizing'}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index a50526223..83b3dffe5 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -28,7 +28,6 @@ import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; import './PDFViewer.scss'; -import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT'; import ReactLoading from 'react-loading'; import { Transform } from '../../util/Transform'; @@ -392,23 +391,6 @@ export class PDFViewer extends ObservableReactComponent { } }; - /** - * Create a flashcard pile based on the selected text of a pdf. - */ - gptPDFFlashcards = async () => { - const queryText = this._selectionText; - runInAction(() => (this._loading = true)); - try { - const res = await gptAPICall(queryText, GPTCallType.FLASHCARD); - - AnchorMenu.Instance.transferToFlashcard(res || 'Something went wrong', NumCast(this._props.layoutDoc['x']), NumCast(this._props.layoutDoc['y'])); - this._selectionText = ''; - } catch (err) { - console.error(err); - } - runInAction(() => (this._loading = false)); - }; - @action finishMarquee = (/* x?: number, y?: number */) => { AnchorMenu.Instance.makeLabels = unimplementedFunction; @@ -430,7 +412,7 @@ export class PDFViewer extends ObservableReactComponent { if (sel) { AnchorMenu.Instance.setSelectedText(sel.toString()); - AnchorMenu.Instance.setLocation(NumCast(this._props.layoutDoc['x']), NumCast(this._props.layoutDoc['y'])); + AnchorMenu.Instance.setLocation(NumCast(this._props.layoutDoc.x), NumCast(this._props.layoutDoc.y)); } if (sel?.type === 'Range') { @@ -442,7 +424,6 @@ export class PDFViewer extends ObservableReactComponent { GPTPopup.Instance.addDoc = this._props.sidebarAddDoc; // allows for creating collection AnchorMenu.Instance.addToCollection = this._props.DocumentView?.()._props.addDocument; - AnchorMenu.Instance.gptFlashcards = this.gptPDFFlashcards; AnchorMenu.Instance.makeLabels = unimplementedFunction; AnchorMenu.Instance.AddDrawingAnnotation = this.addDrawingAnnotation; }; -- cgit v1.2.3-70-g09d2 From bd3b5ade4cad1a2322716cce811cce8db397d246 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 18 Mar 2025 19:15:42 -0400 Subject: updated and fixed breaking pdfjs-dist --- package-lock.json | 670 +++++++++++++++++++++---------------- package.json | 9 +- src/client/views/pdf/PDFViewer.tsx | 6 +- src/typings/index.d.ts | 1 + 4 files changed, 384 insertions(+), 302 deletions(-) (limited to 'src/client/views/pdf') diff --git a/package-lock.json b/package-lock.json index acb4b799c..7a6d786b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,7 +59,7 @@ "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/textfit": "^2.4.4", - "@types/web": "^0.0.211", + "@types/web": "^0.0.213", "@types/webpack-hot-middleware": "^2.25.9", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", @@ -92,6 +92,7 @@ "connect-mongo": "^5.1.0", "cookie-parser": "^1.4.6", "cookie-session": "^2.0.0", + "copy-webpack-plugin": "^13.0.0", "core-js": "^3.33.3", "cors": "^2.8.5", "css-loader": "^7.1.2", @@ -185,7 +186,7 @@ "path-browserify": "^1.0.1", "pdf-parse": "^1.1.1", "pdfjs": "^2.4.7", - "pdfjs-dist": "^4.0.269", + "pdfjs-dist": "^5.0.375", "pinecone": "^0.1.0", "probe-image-size": "^7.2.3", "process": "^0.11.10", @@ -260,7 +261,7 @@ "typescript-collections": "^1.3.3", "typescript-language-server": "^4.1.3", "uninstall": "^0.0.0", - "unstructured-client": "^0.21.0", + "unstructured-client": "^0.22.0", "url": "^0.11.3", "url-loader": "^4.1.1", "util": "^0.12.5", @@ -638,9 +639,9 @@ } }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.758.0.tgz", - "integrity": "sha512-8bOXVYtf/0OUN0jXTIHLv3V0TAS6kvvCRAy7nmiL/fDde0O+ChW1WZU7CVPAOtFEpFCdKskDcxFspM7m1k6qyg==", + "version": "3.768.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.768.0.tgz", + "integrity": "sha512-h/WOvKhuXVIhNKjDcsF6oY2oJuBusspnmEaX20h+GUzIrNMlf6qkJrWziT58KzzESyzeYZcGNWjcOfbVRpH6NA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -865,12 +866,12 @@ "license": "MIT" }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.758.0.tgz", - "integrity": "sha512-y/rHZqyChlEkNRr59gn4hv0gjhJwGmdCdW0JI1K9p3P9p7EurWGjr2M6+goTn3ilOlcAwrl5oFKR5jLt27TkOA==", + "version": "3.768.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.768.0.tgz", + "integrity": "sha512-nNBN+lb2N8Odi0abHln60HqA4z0+UsBw8j7XU+ElEi5E2qOBCJSkLIFDIcYfn+j88FP2oLiQlOPe7H8pav5ayQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-cognito-identity": "3.758.0", + "@aws-sdk/client-cognito-identity": "3.768.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", @@ -1018,14 +1019,14 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.758.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.758.0.tgz", - "integrity": "sha512-BaGVBdm9ynsErIc/mLuUwJ1OQcL/pkhCuAm24jpsif3evZ5wgyZnEAZB2yRin+mQnQaQT3L+KvTbdKGfjL8+fQ==", + "version": "3.768.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.768.0.tgz", + "integrity": "sha512-uEAtcdHArZxq7dbpgI4ofDclefNYnYWrT9bJn2Q6rf7VlQnoD37ptzVLQBLomXnRaBiQB/sRV2MJaugFqwOEQA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-cognito-identity": "3.758.0", + "@aws-sdk/client-cognito-identity": "3.768.0", "@aws-sdk/core": "3.758.0", - "@aws-sdk/credential-provider-cognito-identity": "3.758.0", + "@aws-sdk/credential-provider-cognito-identity": "3.768.0", "@aws-sdk/credential-provider-env": "3.758.0", "@aws-sdk/credential-provider-http": "3.758.0", "@aws-sdk/credential-provider-ini": "3.758.0", @@ -3203,9 +3204,9 @@ "license": "Apache-2.0" }, "node_modules/@chromatic-com/storybook": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-3.2.5.tgz", - "integrity": "sha512-Y388ft6po5FmGKdkcqz3r2sW6aMF5DSBaatC0jvT5bI/Dh27RJw3gPTmXJcZVNjteNl6tpiP3qxZ9MswAk5luw==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@chromatic-com/storybook/-/storybook-3.2.6.tgz", + "integrity": "sha512-FDmn5Ry2DzQdik+eq2sp/kJMMT36Ewe7ONXUXM2Izd97c7r6R/QyGli8eyh/F0iyqVvbLveNYFyF0dBOJNwLqw==", "dev": true, "license": "MIT", "dependencies": { @@ -5462,9 +5463,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.7.tgz", - "integrity": "sha512-XjJrKFNt9zAKvcnoIIBquXyFyhfrHYuttqMsoDS7lM7VwufYG4fAPw4kINjBFg++fqXM2BNAuWR9J7XVIuKIKg==", + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.8.tgz", + "integrity": "sha512-vjP4+A1ybyCRhDZC7r5EPWu/gLseFZxaGyPdDl94vzVvk6Yj6gahdaqcjbhkaCrJjdZj90m3VioltWPAnWF/zw==", "license": "MIT", "funding": { "type": "opencollective", @@ -5472,9 +5473,9 @@ } }, "node_modules/@mui/icons-material": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.4.7.tgz", - "integrity": "sha512-Rk8cs9ufQoLBw582Rdqq7fnSXXZTqhYRbpe1Y5SAz9lJKZP3CIdrj0PfG8HJLGw1hrsHFN/rkkm70IDzhJsG1g==", + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.4.8.tgz", + "integrity": "sha512-LKGWiLWRyoOw3dWxZQ+lV//mK+4DVTTAiLd2ljmJdD6XV0rDB8JFKjRD9nyn9cJAU5XgWnii7ZR3c93ttUnMKg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0" @@ -5487,7 +5488,7 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^6.4.7", + "@mui/material": "^6.4.8", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -5498,16 +5499,16 @@ } }, "node_modules/@mui/material": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.7.tgz", - "integrity": "sha512-K65StXUeGAtFJ4ikvHKtmDCO5Ab7g0FZUu2J5VpoKD+O6Y3CjLYzRi+TMlI3kaL4CL158+FccMoOd/eaddmeRQ==", + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.8.tgz", + "integrity": "sha512-5S9UTjKZZBd9GfbcYh/nYfD9cv6OXmj5Y7NgKYfk7JcSoshp8/pW5zP4wecRiroBSZX8wcrywSgogpVNO+5W0Q==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.4.7", - "@mui/system": "^6.4.7", - "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.6", + "@mui/core-downloads-tracker": "^6.4.8", + "@mui/system": "^6.4.8", + "@mui/types": "~7.2.24", + "@mui/utils": "^6.4.8", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.12", "clsx": "^2.1.1", @@ -5526,7 +5527,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.4.7", + "@mui/material-pigment-css": "^6.4.8", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -5547,13 +5548,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.6.tgz", - "integrity": "sha512-T5FxdPzCELuOrhpA2g4Pi6241HAxRwZudzAuL9vBvniuB5YU82HCmrARw32AuCiyTfWzbrYGGpZ4zyeqqp9RvQ==", + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.8.tgz", + "integrity": "sha512-sWwQoNSn6elsPTAtSqCf+w5aaGoh7AASURNmpy+QTTD/zwJ0Jgwt0ZaaP6mXq2IcgHxYnYloM/+vJgHPMkRKTQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.4.6", + "@mui/utils": "^6.4.8", "prop-types": "^15.8.1" }, "engines": { @@ -5574,9 +5575,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.6.tgz", - "integrity": "sha512-vSWYc9ZLX46be5gP+FCzWVn5rvDr4cXC5JBZwSIkYk9xbC7GeV+0kCvB8Q6XLFQJy+a62bbqtmdwS4Ghi9NBlQ==", + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.8.tgz", + "integrity": "sha512-oyjx1b1FvUCI85ZMO4trrjNxGm90eLN3Ohy0AP/SqK5gWvRQg1677UjNf7t6iETOKAleHctJjuq0B3aXO2gtmw==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", @@ -5608,16 +5609,16 @@ } }, "node_modules/@mui/system": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.7.tgz", - "integrity": "sha512-7wwc4++Ak6tGIooEVA9AY7FhH2p9fvBMORT4vNLMAysH3Yus/9B9RYMbrn3ANgsOyvT3Z7nE+SP8/+3FimQmcg==", + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.8.tgz", + "integrity": "sha512-gV7iBHoqlsIenU2BP0wq14BefRoZcASZ/4LeyuQglayBl+DfLX5rEd3EYR3J409V2EZpR0NOM1LATAGlNk2cyA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.4.6", - "@mui/styled-engine": "^6.4.6", - "@mui/types": "^7.2.21", - "@mui/utils": "^6.4.6", + "@mui/private-theming": "^6.4.8", + "@mui/styled-engine": "^6.4.8", + "@mui/types": "~7.2.24", + "@mui/utils": "^6.4.8", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -5648,9 +5649,9 @@ } }, "node_modules/@mui/types": { - "version": "7.2.21", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.21.tgz", - "integrity": "sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==", + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", "license": "MIT", "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -5662,13 +5663,13 @@ } }, "node_modules/@mui/utils": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.6.tgz", - "integrity": "sha512-43nZeE1pJF2anGafNydUcYFPtHwAqiBiauRtaMvurdrZI3YrUjHkAu43RBsxef7OFtJMXGiHFvq43kb7lig0sA==", + "version": "6.4.8", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.8.tgz", + "integrity": "sha512-C86gfiZ5BfZ51KqzqoHi1WuuM2QdSKoFhbkZeAfQRB+jCc4YNhhj11UXFVMMsqBgZ+Zy8IHNJW3M9Wj/LOwRXQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/types": "^7.2.21", + "@mui/types": "~7.2.24", "@types/prop-types": "^15.7.14", "clsx": "^2.1.1", "prop-types": "^15.8.1", @@ -10643,9 +10644,9 @@ } }, "node_modules/@storybook/addon-actions": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.4.tgz", - "integrity": "sha512-mCcyfkeb19fJX0dpQqqZCnWBwjVn0/27xcpR0mbm/KW2wTByU6bKFFujgrHsX3ONl97IcIaUnmwwUwBr1ebZXw==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-8.6.7.tgz", + "integrity": "sha512-XgZCwIcZGThEyD7e2q7rN/jzg7ZHUxn/ln403eex04jWAGBBbtC2IVuowwCWV8HwDihnhpCZEP6HlgjakOYZbQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10660,7 +10661,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-actions/node_modules/@types/uuid": { @@ -10685,9 +10686,9 @@ } }, "node_modules/@storybook/addon-backgrounds": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.4.tgz", - "integrity": "sha512-lRYGumlYdd1RptQJvOTRMx/q2pDmg2MO5GX4la7VfI8KrUyeuC1ZOSRDEcXeTuAZWJztqmtymg6bB7cAAoxCFA==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-8.6.7.tgz", + "integrity": "sha512-aDFzi83gDhYn0+FGjRYbY5TfBtoG/UgVr9Abi7s5ceabZRhPrYikMyFX0o8V3Z8COl6wUmWmF1luYE4MfXgN2g==", "dev": true, "license": "MIT", "dependencies": { @@ -10700,13 +10701,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-controls": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.4.tgz", - "integrity": "sha512-oMMP9Bj0RMfYmaitjFt6oBSjKH4titUqP+wE6PrZ3v+Om56f4buqfNKXRf80As2OrsZn0pjj95muWzVVHqIhyQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-8.6.7.tgz", + "integrity": "sha512-6ReB1Sc1qlqvAM7NUmtw2K1cKCgGBs8zYRgL44Q2ti+r55a2ownhm6WUm/kZs2ixSkV9ehm1osiqbGBfAn0Isw==", "dev": true, "license": "MIT", "dependencies": { @@ -10719,20 +10720,20 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-docs": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.4.tgz", - "integrity": "sha512-+kbcjvEAH0Xs+k+raAwfC0WmJilWhxBYnLLeazP3m5AkVI3sIjbzuuZ78NR0DCdRkw9BpuuXMHv5o4tIvLIUlw==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-8.6.7.tgz", + "integrity": "sha512-kgNPEVuLGNJE8EdVQi5Tg2DYgR66/gut07jvhqnJfNqUkj6UpBHad0JR1uwrd7xS3kJs29Fs7UyU87RJnSlwcg==", "dev": true, "license": "MIT", "dependencies": { "@mdx-js/react": "^3.0.0", - "@storybook/blocks": "8.6.4", - "@storybook/csf-plugin": "8.6.4", - "@storybook/react-dom-shim": "8.6.4", + "@storybook/blocks": "8.6.7", + "@storybook/csf-plugin": "8.6.7", + "@storybook/react-dom-shim": "8.6.7", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" @@ -10742,25 +10743,25 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-essentials": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.4.tgz", - "integrity": "sha512-3pF0ZDl5EICqe0eOupPQq6PxeupwkLsfTWANuuJUYTJur82kvJd3Chb7P9vqw0A0QBx6106mL6PIyjrFJJMhLg==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-8.6.7.tgz", + "integrity": "sha512-PFT62xuknk4wD1hTZEnYbGP1mJFPlhk7zVVlMjoldMUhmbHsFRhdWCpo93Vu9E3BWVxFxL3Jj+UwSwH4uVmekQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/addon-actions": "8.6.4", - "@storybook/addon-backgrounds": "8.6.4", - "@storybook/addon-controls": "8.6.4", - "@storybook/addon-docs": "8.6.4", - "@storybook/addon-highlight": "8.6.4", - "@storybook/addon-measure": "8.6.4", - "@storybook/addon-outline": "8.6.4", - "@storybook/addon-toolbars": "8.6.4", - "@storybook/addon-viewport": "8.6.4", + "@storybook/addon-actions": "8.6.7", + "@storybook/addon-backgrounds": "8.6.7", + "@storybook/addon-controls": "8.6.7", + "@storybook/addon-docs": "8.6.7", + "@storybook/addon-highlight": "8.6.7", + "@storybook/addon-measure": "8.6.7", + "@storybook/addon-outline": "8.6.7", + "@storybook/addon-toolbars": "8.6.7", + "@storybook/addon-viewport": "8.6.7", "ts-dedent": "^2.0.0" }, "funding": { @@ -10768,13 +10769,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-highlight": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.4.tgz", - "integrity": "sha512-jFREXnSE/7VuBR8kbluN+DBVkMXEV7MGuCe8Ytb1/D2Q0ohgJe395dfVgEgSMXErOwsn//NV/NgJp6JNXH2DrA==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.6.7.tgz", + "integrity": "sha512-4KE1RF4XfqII7XrJPgf/1W0t0EWRKmik5Rrpb6WofXfgZ2QYzLFnyESjf67/g2TMgDnle2drfa/pt5tGV4+I2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -10785,19 +10786,19 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-interactions": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.4.tgz", - "integrity": "sha512-MZAAZjyvmJXCvM35zEiPpXz7vK+fimovt+WZKAMayAbXy5fT+7El0c9dDyTQ2norNKNj9QU/8hiU/1zARSUELQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-interactions/-/addon-interactions-8.6.7.tgz", + "integrity": "sha512-FbEWWxCl/5DJDyEGTJqtTJ5XbxM2rOUGCPy+3CkPSpI9yvz3zprRTJRHPFrh7hUqQ4Qkqfjm7JCO29+0CmeE0g==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.6.4", - "@storybook/test": "8.6.4", + "@storybook/instrumenter": "8.6.7", + "@storybook/test": "8.6.7", "polished": "^4.2.2", "ts-dedent": "^2.2.0" }, @@ -10806,13 +10807,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-measure": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.4.tgz", - "integrity": "sha512-IpVL1rTy1tO8sy140eU3GdVB1QJ6J62+V6GSstcmqTLxDJQk5jFfg7hVbPEAZZ2sPFmeyceP9AMoBBo0EB355A==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-measure/-/addon-measure-8.6.7.tgz", + "integrity": "sha512-4dkkCltjKRcJH+ZMv5nbNT0LBQfcXIydVfN9mAvhDsiPFD5eZcHbN4XVfUslECWgrkaa/a6FE1W9PNEUBjCJaA==", "dev": true, "license": "MIT", "dependencies": { @@ -10824,13 +10825,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-onboarding": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-8.6.4.tgz", - "integrity": "sha512-Co/E93Lr3jWdc7+6WQO8DOjfAf1/o25TcqSJWK7dyfH6YimC8QeE9NPpaVshdVzbBajbc4CD7sUDCN7CiI34JA==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-onboarding/-/addon-onboarding-8.6.7.tgz", + "integrity": "sha512-40D1O9abhriKI/i4SQ7iyOMLusO8xFkyoMIBdx1iz4lfwO4cKhR5ymE4slAm+pYLc6+voD0EESCIHyXTEHDJxQ==", "dev": true, "license": "MIT", "funding": { @@ -10838,13 +10839,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-outline": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.4.tgz", - "integrity": "sha512-28nAslKTy0zWMdxAZcipMDYrEp1TkXVooAsqMGY5AMXMiORi1ObjhmjTLhVt1dXp+aDg0X+M3B6PqoingmHhqQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-outline/-/addon-outline-8.6.7.tgz", + "integrity": "sha512-atCpCi2CqAWQwL1nu1l5VpIA4fRMnbD4RZMsEiib1suUfNyJv0RdsSgZhp/f+e9sUS0TtMdwhzWT36eEA7VxhQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10856,7 +10857,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-styling-webpack": { @@ -10873,9 +10874,9 @@ } }, "node_modules/@storybook/addon-toolbars": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.4.tgz", - "integrity": "sha512-PU2lvgwCKDn93zpp5MEog103UUmSSugcxDf18xaoa9D15Qtr+YuQHd2hXbxA7+dnYL9lA7MLYsstfxE91ieM4Q==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.6.7.tgz", + "integrity": "sha512-gR+mRs+Cc5GINZdKgE7afJLFCSMHkz40+zzdrPu6yY2P4B3UOvuQpt+zC/Er5YQ31EEjIvM6/XMQTM0i2db8AA==", "dev": true, "license": "MIT", "funding": { @@ -10883,13 +10884,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-viewport": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.4.tgz", - "integrity": "sha512-O5Ij+SRVg6grY6JOL5lOpsFyopZxuZEl2GHfh2SUf9hfowNS0QAgFpJupqXkwZzRSrlf9uKrLkjB6ulLgN2gOQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/addon-viewport/-/addon-viewport-8.6.7.tgz", + "integrity": "sha512-kTrt6ByCbBIbqoRqQO9watDl5nSIKCC+R0/EmpEl6ZtzBV3l8trZHdvCHhIqOyv7nfaa7pIeTTG1GD6Gdrxk3w==", "dev": true, "license": "MIT", "dependencies": { @@ -10900,7 +10901,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/addon-webpack5-compiler-swc": { @@ -10918,9 +10919,9 @@ } }, "node_modules/@storybook/blocks": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.4.tgz", - "integrity": "sha512-+oPXwT3KzJzsdkQuGEzBqOKTIFlb6qmlCWWbDwAnP0SEqYHoTVRTAIa44icFP0EZeIe+ypFVAm1E7kWTLmw1hQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/blocks/-/blocks-8.6.7.tgz", + "integrity": "sha512-IFhIKO7R1UPpnoG/5tZH0FgC79oYgXNf+7aGUwq29M/CQWy6p/Pvp0y4P962btY1UZRol+SsU//33nH8o6yNRw==", "dev": true, "license": "MIT", "dependencies": { @@ -10934,7 +10935,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^8.6.4" + "storybook": "^8.6.7" }, "peerDependenciesMeta": { "react": { @@ -10946,13 +10947,13 @@ } }, "node_modules/@storybook/builder-webpack5": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.6.4.tgz", - "integrity": "sha512-6fhjt3uiBZeapRbF477bkJ+ln+yA8vOz0qR86XTq79VrYY5AbBL6F8swVMk9LG1t49vYPR/UuPjYBxsUNKK8MQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-8.6.7.tgz", + "integrity": "sha512-MRzfJto3wK6F4jKyyNJ71dMWqs1CQpj27bRjGanhvBsU+nUkZylcoaqGC52FJwzaEkuSzpGgKg/aLLd33VBM9g==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core-webpack": "8.6.4", + "@storybook/core-webpack": "8.6.7", "@types/semver": "^7.3.4", "browser-assert": "^1.2.1", "case-sensitive-paths-webpack-plugin": "^2.4.0", @@ -10982,7 +10983,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" }, "peerDependenciesMeta": { "typescript": { @@ -11192,9 +11193,9 @@ } }, "node_modules/@storybook/components": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.4.tgz", - "integrity": "sha512-91VEVFWOgHkEFoNFMk6gs1AuOE9Yp7N283BXQOW+AgP+atpzED6t/fIBPGqJ2ewAuzLJ+cFOrasSzoNwVfg3Jg==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.7.tgz", + "integrity": "sha512-8pnjH1w7PZ/Iiuve1/BJY7EO/kmu0qdE34X1ZM8DyHzuy33EL/PfUuhxNkrL4ayMXrEDp/EJMHx2bqO1RdRV6A==", "dev": true, "license": "MIT", "funding": { @@ -11206,13 +11207,13 @@ } }, "node_modules/@storybook/core": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.4.tgz", - "integrity": "sha512-glDbjEBi3wokw1T+KQtl93irHO9N0LCwgylWfWVXYDdQjUJ7pGRQGnw73gPX7Ds9tg3myXFC83GjmY94UYSMbA==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/core/-/core-8.6.7.tgz", + "integrity": "sha512-FcvLFA+Qn3+D6LgQkk0MOXA5FBz8DGc0UZmZuVbIwIUV4MV4ywCMwtKdG0cyhtzQg0YNyfiIYWJr7lZ4jLLhYg==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/theming": "8.6.4", + "@storybook/theming": "8.6.7", "better-opn": "^3.0.2", "browser-assert": "^1.2.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", @@ -11238,9 +11239,9 @@ } }, "node_modules/@storybook/core-webpack": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.6.4.tgz", - "integrity": "sha512-/E+NDs4Ls2KQhQJyEbqyddvcevPGCNbBIRoR691gq2lnZV7lYFfhpGfYlXL1uSoA3WUWmql/gBsa2/O3vB+HKg==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-8.6.7.tgz", + "integrity": "sha512-2mPRdRb27/UVO6ke64nCleNOTzUwjp0APFXs7bNhchb2evj6k4VeizCQjScGNy33ORKVwBImmHKyzHzzmAR/9A==", "dev": true, "license": "MIT", "dependencies": { @@ -11251,7 +11252,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/core/node_modules/semver": { @@ -11268,9 +11269,9 @@ } }, "node_modules/@storybook/csf-plugin": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.4.tgz", - "integrity": "sha512-7UpEp4PFTy1iKjZiRaYMG7zvnpLIRPyD0+lUJUlLYG4UIemV3onvnIi1Je1tSZ4hfTup+ulom7JLztVSHZGRMg==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-8.6.7.tgz", + "integrity": "sha512-HK7yQD4kFu04JOKnUwoFeR58r5WY6ucF0D8zfW4Gx+r8hBJ5K4t3z6k2dlIlRQF1X5+2vNkQOwD8liHjckuZ8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -11281,7 +11282,7 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/global": { @@ -11306,9 +11307,9 @@ } }, "node_modules/@storybook/instrumenter": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.4.tgz", - "integrity": "sha512-8OtIWLhayTUdqJEeXiPm6l3LTdSkWgQzzV2l2HIe4Adedeot+Rkwu6XHmyRDpnb0+Ish6zmMDqtJBxC2PQsy6Q==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/instrumenter/-/instrumenter-8.6.7.tgz", + "integrity": "sha512-FeQiV0g5crCWs0P1wKY4xZzb4PxAYNcrm2+9LLGVqwnC7qzrSCPf0p10MlveVfwsen1m6Wbqfe+wl21c31Hfmg==", "dev": true, "license": "MIT", "dependencies": { @@ -11320,13 +11321,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/manager-api": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.4.tgz", - "integrity": "sha512-w/Nn/VznfbIg2oezDfzZNwSTDY5kBZbzxVBHLCnIcyu2AKt2Yto3pfGi60SikFcTrsClaAKT7D92kMQ9qdQNQQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/manager-api/-/manager-api-8.6.7.tgz", + "integrity": "sha512-BA8RxaLP07WGF660LWo7qB3Jomr/+MPuCZmuKPqXxPhfIovqYjr0hnugxJBjEah0ic31aNX4NucNfDRuV7F5sA==", "dev": true, "license": "MIT", "funding": { @@ -11338,9 +11339,9 @@ } }, "node_modules/@storybook/node-logger": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-8.6.4.tgz", - "integrity": "sha512-hSjFZ+YfypyuSsdqXr5g2iZ5KMtVZXs3Iu2rYz7x5K2KGOQ69CW1xs2qVx1IsBRMpvvhcdvcBQRsLnFPZ7XOVQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-8.6.7.tgz", + "integrity": "sha512-TuiHy91ug/1Scg7P3nekIj9pupGHhKJEyG4m8JK5qehAQ00G3mftqyvrojcciOthGNRARDVxpMSOHJoO5uLTPQ==", "dev": true, "license": "MIT", "funding": { @@ -11352,14 +11353,14 @@ } }, "node_modules/@storybook/preset-react-webpack": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.6.4.tgz", - "integrity": "sha512-rFd1NvSE2ZP5ZFEqH7wdXXlvnyNChSMp+w4FyGSCgFQOwQKZhhWPPyloi3gGSWztFV9qpzC/ri7TTvG6ptqPPw==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/preset-react-webpack/-/preset-react-webpack-8.6.7.tgz", + "integrity": "sha512-gacUEwKsbCyxpT8S2Qjr/Y3y3x31FPABXXL9pNwG59TjcYZ/IfP4hF+uIE06Q+gqVoG6v/HSkllGTYwyybF2Lw==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core-webpack": "8.6.4", - "@storybook/react": "8.6.4", + "@storybook/core-webpack": "8.6.7", + "@storybook/react": "8.6.7", "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", "@types/semver": "^7.3.4", "find-up": "^5.0.0", @@ -11380,7 +11381,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.4" + "storybook": "^8.6.7" }, "peerDependenciesMeta": { "typescript": { @@ -11402,9 +11403,9 @@ } }, "node_modules/@storybook/preview-api": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.4.tgz", - "integrity": "sha512-5HBfxggzxGz0dg2c61NpPiQJav7UAmzsQlzmI5SzWOS6lkaylcDG8giwKzASVCXVWBxNji9qIDFM++UH090aDg==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/preview-api/-/preview-api-8.6.7.tgz", + "integrity": "sha512-Rz83Nx43v3Dn9/SjhIsorkcx1gPmlclueuzf6YywJTqE1E/L4dgoe2mOA9MfF0jr0bh3TwEA2J3ii0Jstg1Orw==", "dev": true, "license": "MIT", "funding": { @@ -11416,18 +11417,18 @@ } }, "node_modules/@storybook/react": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.4.tgz", - "integrity": "sha512-pfv4hMhu3AScOh0l86uIzmXLSQ0XA/e0reIVwQcxKht6miaKArhx9GkS4mMp6SO23ZoV5G/nfLgUaMVPVE0ZPg==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/react/-/react-8.6.7.tgz", + "integrity": "sha512-6R8znSm7kzsoAJyRbEiDWE+5xjeAIzwEcfT60fqx+uMdd0vDFM7f2uT4fYy+CijWas1oFWcNV/LMd3EqSkBGsQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/components": "8.6.4", + "@storybook/components": "8.6.7", "@storybook/global": "^5.0.0", - "@storybook/manager-api": "8.6.4", - "@storybook/preview-api": "8.6.4", - "@storybook/react-dom-shim": "8.6.4", - "@storybook/theming": "8.6.4" + "@storybook/manager-api": "8.6.7", + "@storybook/preview-api": "8.6.7", + "@storybook/react-dom-shim": "8.6.7", + "@storybook/theming": "8.6.7" }, "engines": { "node": ">=18.0.0" @@ -11437,10 +11438,10 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "@storybook/test": "8.6.4", + "@storybook/test": "8.6.7", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.4", + "storybook": "^8.6.7", "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { @@ -11638,9 +11639,9 @@ } }, "node_modules/@storybook/react-dom-shim": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.4.tgz", - "integrity": "sha512-kTGJ3aFdmfCFzYaDFGmZWfTXr9xhbUaf0tJ6+nEjc4tME6mFwMI+tTUT6U/J6mJhZuc2DjvIRA7bM0x77dIDqw==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-8.6.7.tgz", + "integrity": "sha512-+JH7gbRI6NRbt9o0l1rY4wFdeVt8wGRddm0b55OBlwBGlFo2nvGVOH73J4AGphXVhfY7z33I3TXIjXQ561UdEQ==", "dev": true, "license": "MIT", "funding": { @@ -11650,19 +11651,19 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/react-webpack5": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-8.6.4.tgz", - "integrity": "sha512-kH439Atpp94+hWF/xftOJ4ZCy7bnNWuLSni7sWvOGkYZpzzzkLXfACanvK6ZY9wUxAh0bbdGfbc3McMvIWfYlw==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/react-webpack5/-/react-webpack5-8.6.7.tgz", + "integrity": "sha512-xRgnrVqUxiBNJPtr1eTDwT/Drq47SIaII7v7dC0sGpeFdfLqjm+043YBMCGYTn67oGD0Sy5GrKBpeo1ahN4YLA==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/builder-webpack5": "8.6.4", - "@storybook/preset-react-webpack": "8.6.4", - "@storybook/react": "8.6.4" + "@storybook/builder-webpack5": "8.6.7", + "@storybook/preset-react-webpack": "8.6.7", + "@storybook/react": "8.6.7" }, "engines": { "node": ">=18.0.0" @@ -11674,7 +11675,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta", - "storybook": "^8.6.4", + "storybook": "^8.6.7", "typescript": ">= 4.2.x" }, "peerDependenciesMeta": { @@ -11684,14 +11685,14 @@ } }, "node_modules/@storybook/test": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.4.tgz", - "integrity": "sha512-JPjfbaMMuCBT47pg3/MDD9vYFF5OGPAOWEB9nJWJ9IjYAb2Nd8OYJQIDoYJQNT+aLkTVLtvzGnVNwdxpouAJcQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/test/-/test-8.6.7.tgz", + "integrity": "sha512-uF1JbBtdT7tuiXfEtHsUShBHIhm2vc0C39nKVJaTWyK9CybajXaj2Ny3IRa3oY9NKnklwGgN+kZ/Z9YiIOc4MQ==", "dev": true, "license": "MIT", "dependencies": { "@storybook/global": "^5.0.0", - "@storybook/instrumenter": "8.6.4", + "@storybook/instrumenter": "8.6.7", "@testing-library/dom": "10.4.0", "@testing-library/jest-dom": "6.5.0", "@testing-library/user-event": "14.5.2", @@ -11703,13 +11704,13 @@ "url": "https://opencollective.com/storybook" }, "peerDependencies": { - "storybook": "^8.6.4" + "storybook": "^8.6.7" } }, "node_modules/@storybook/theming": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.4.tgz", - "integrity": "sha512-g9Ns4uenC9oAWETaJ/tEKEIPMdS+CqjNWZz5Wbw1bLNhXwADZgKrVqawzZi64+bYYtQ+i8VCTjPoFa6s2eHiDQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.7.tgz", + "integrity": "sha512-F/i4XS5bew9dvtNiHvDJF0mko1IUbPM9PUjTYPaw6cK8ytS0kdec703MsJ/GUA7seeEWBeGdZjV3ua0pys650A==", "dev": true, "license": "MIT", "funding": { @@ -11721,9 +11722,9 @@ } }, "node_modules/@swc/core": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.11.9.tgz", - "integrity": "sha512-4UQ66FwTkFDr+UzYzRNKQyHMScOrc4zJbTJHyK6dP1yVMrxi5sl0FTzNKiqoYvRZ7j8TAYgtYvvuPSW/XXvp5g==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.11.11.tgz", + "integrity": "sha512-pCVY2Wn6dV/labNvssk9b3Owi4WOYsapcbWm90XkIj4xH/56Z6gzja9fsU+4MdPuEfC2Smw835nZHcdCFGyX6A==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -11739,16 +11740,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.11.9", - "@swc/core-darwin-x64": "1.11.9", - "@swc/core-linux-arm-gnueabihf": "1.11.9", - "@swc/core-linux-arm64-gnu": "1.11.9", - "@swc/core-linux-arm64-musl": "1.11.9", - "@swc/core-linux-x64-gnu": "1.11.9", - "@swc/core-linux-x64-musl": "1.11.9", - "@swc/core-win32-arm64-msvc": "1.11.9", - "@swc/core-win32-ia32-msvc": "1.11.9", - "@swc/core-win32-x64-msvc": "1.11.9" + "@swc/core-darwin-arm64": "1.11.11", + "@swc/core-darwin-x64": "1.11.11", + "@swc/core-linux-arm-gnueabihf": "1.11.11", + "@swc/core-linux-arm64-gnu": "1.11.11", + "@swc/core-linux-arm64-musl": "1.11.11", + "@swc/core-linux-x64-gnu": "1.11.11", + "@swc/core-linux-x64-musl": "1.11.11", + "@swc/core-win32-arm64-msvc": "1.11.11", + "@swc/core-win32-ia32-msvc": "1.11.11", + "@swc/core-win32-x64-msvc": "1.11.11" }, "peerDependencies": { "@swc/helpers": "*" @@ -11760,9 +11761,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.9.tgz", - "integrity": "sha512-moqbPCWG6SHiDMENTDYsEQJ0bFustbLtrdbDbdjnijSyhCyIcm9zKowmovE6MF8JBdOwmLxbuN1Yarq6CrPNlw==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.11.tgz", + "integrity": "sha512-vJcjGVDB8cZH7zyOkC0AfpFYI/7GHKG0NSsH3tpuKrmoAXJyCYspKPGid7FT53EAlWreN7+Pew+bukYf5j+Fmg==", "cpu": [ "arm64" ], @@ -11778,9 +11779,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.11.9.tgz", - "integrity": "sha512-/lgMo5l9q6y3jjLM3v30y6SBvuuyLsM/K94hv3hPvDf91N+YlZLw4D7KY0Qknfhj6WytoAcjOIDU6xwBRPyUWg==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.11.11.tgz", + "integrity": "sha512-/N4dGdqEYvD48mCF3QBSycAbbQd3yoZ2YHSzYesQf8usNc2YpIhYqEH3sql02UsxTjEFOJSf1bxZABDdhbSl6A==", "cpu": [ "x64" ], @@ -11796,9 +11797,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.9.tgz", - "integrity": "sha512-7bL6z/63If11IpBElQRozIGRadiy6rt3DoUyfGuFIFQKxtnZxzHuLxm1/wrCAGN9iAZxrpHxHP0VbPQvr6Mcjg==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.11.tgz", + "integrity": "sha512-hsBhKK+wVXdN3x9MrL5GW0yT8o9GxteE5zHAI2HJjRQel3HtW7m5Nvwaq+q8rwMf4YQRd8ydbvwl4iUOZx7i2Q==", "cpu": [ "arm" ], @@ -11814,9 +11815,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.9.tgz", - "integrity": "sha512-9ArpxjrNbyFTr7gG+toiGbbK2mfS+X97GIruBKPsD8CJH/yJlMknBsX3lfy9h/L119zYVnFBmZDnwsv5yW8/cw==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.11.tgz", + "integrity": "sha512-YOCdxsqbnn/HMPCNM6nrXUpSndLXMUssGTtzT7ffXqr7WuzRg2e170FVDVQFIkb08E7Ku5uOnnUVAChAJQbMOQ==", "cpu": [ "arm64" ], @@ -11832,9 +11833,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.9.tgz", - "integrity": "sha512-UOnunJWu7T7oNkBr4DLMwXXbldjiwi+JxmqBKrD2+BNiHGu6P5VpqDHiTGuWuLrda0TcTmeNE6gzlIVOVBo/vw==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.11.tgz", + "integrity": "sha512-nR2tfdQRRzwqR2XYw9NnBk9Fdvff/b8IiJzDL28gRR2QiJWLaE8LsRovtWrzCOYq6o5Uu9cJ3WbabWthLo4jLw==", "cpu": [ "arm64" ], @@ -11850,9 +11851,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.9.tgz", - "integrity": "sha512-HAqmCkNoNhRusBqSokyylXKsLJ/dr3dnMgBERdUrCIh47L8CKR2qEFUP6FI05sHVB85403ctWnfzBYblcarpqg==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.11.tgz", + "integrity": "sha512-b4gBp5HA9xNWNC5gsYbdzGBJWx4vKSGybGMGOVWWuF+ynx10+0sA/o4XJGuNHm8TEDuNh9YLKf6QkIO8+GPJ1g==", "cpu": [ "x64" ], @@ -11868,9 +11869,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.9.tgz", - "integrity": "sha512-THwUT2g2qSWUxhi3NGRCEdmh/q7WKl3d5jcN9mz/4jum76Tb46LB9p3oOVPBIcfnFQ9OaddExjCwLoUl0ju2pA==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.11.tgz", + "integrity": "sha512-dEvqmQVswjNvMBwXNb8q5uSvhWrJLdttBSef3s6UC5oDSwOr00t3RQPzyS3n5qmGJ8UMTdPRmsopxmqaODISdg==", "cpu": [ "x64" ], @@ -11886,9 +11887,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.9.tgz", - "integrity": "sha512-r4SGD9lR0MM9HSIsQ72BEL3Za3XsuVj+govuXQTlK0mty5gih4L+Qgfnb9PmhjFakK3F63gZyyEr2y8Fj0mN6Q==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.11.tgz", + "integrity": "sha512-aZNZznem9WRnw2FbTqVpnclvl8Q2apOBW2B316gZK+qxbe+ktjOUnYaMhdCG3+BYggyIBDOnaJeQrXbKIMmNdw==", "cpu": [ "arm64" ], @@ -11904,9 +11905,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.9.tgz", - "integrity": "sha512-jrEh6MDSnhwfpjRlSWd2Bk8pS5EjreQD1YbkNcnXviQf3+H0wSPmeVSktZyoIdkxAuc2suFx8mj7Yja2UXAgUg==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.11.tgz", + "integrity": "sha512-DjeJn/IfjgOddmJ8IBbWuDK53Fqw7UvOz7kyI/728CSdDYC3LXigzj3ZYs4VvyeOt+ZcQZUB2HA27edOifomGw==", "cpu": [ "ia32" ], @@ -11922,9 +11923,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.9.tgz", - "integrity": "sha512-oAwuhzr+1Bmb4As2wa3k57/WPJeyVEYRQelwEMYjPgi/h6TH+Y69jQAgKOd+ec1Yl8L5nkWTZMVA/dKDac1bAQ==", + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.11.tgz", + "integrity": "sha512-Gp/SLoeMtsU4n0uRoKDOlGrRC6wCfifq7bqLwSlAG8u8MyJYJCcwjg7ggm0rhLdC2vbiZ+lLVl3kkETp+JUvKg==", "cpu": [ "x64" ], @@ -15532,9 +15533,9 @@ "license": "MIT" }, "node_modules/@types/web": { - "version": "0.0.211", - "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.211.tgz", - "integrity": "sha512-IjFpdU00NjEce4W2zXQpV23DEr+OpoT/iFmLkgnzUdGPuVwjYyd+0r6pfLrmD5mwxnHLluCuf0GGwIIoysFKpg==", + "version": "0.0.213", + "resolved": "https://registry.npmjs.org/@types/web/-/web-0.0.213.tgz", + "integrity": "sha512-LuVykOBqlH+P9GI9Q2IWL3bwoV9oJqVGfjutUW0c1LJL4Jdceq5455cJHwcjyhip7+w9hmgv9IvaKXf+FWvRNg==", "license": "Apache-2.0" }, "node_modules/@types/webgl-ext": { @@ -17747,9 +17748,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001704", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001704.tgz", - "integrity": "sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==", + "version": "1.0.30001706", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001706.tgz", + "integrity": "sha512-3ZczoTApMAZwPKYWmwVbQMFpXBDds3/0VciVoUwPUbldlYyVLmRVuRs/PcUZtHpbLRpzzDvrvnFuREsGt6lUug==", "funding": [ { "type": "opencollective", @@ -18751,6 +18752,29 @@ "node": ">= 0.8" } }, + "node_modules/copy-webpack-plugin": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-13.0.0.tgz", + "integrity": "sha512-FgR/h5a6hzJqATDGd9YG41SeDViH+0bkHn6WNXCi5zKAZkeESeSxLySSsFLHqLEVCh0E+rITmCf0dusXWYukeQ==", + "license": "MIT", + "dependencies": { + "glob-parent": "^6.0.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2", + "tinyglobby": "^0.2.12" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, "node_modules/core-js": { "version": "3.41.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.41.0.tgz", @@ -20381,9 +20405,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.116", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.116.tgz", - "integrity": "sha512-mufxTCJzLBQVvSdZzX1s5YAuXsN1M4tTyYxOOL1TcSKtIzQ9rjIrm7yFK80rN5dwGTePgdoABDSHpuVtRQh0Zw==", + "version": "1.5.120", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.120.tgz", + "integrity": "sha512-oTUp3gfX1gZI+xfD2djr2rzQdHCwHzPQrrK0CD7WpTdF0nPdQ/INcRVjWgLdCT4a9W3jFObR9DAfsuyFQnI8CQ==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -21794,9 +21818,9 @@ "license": "BSD-3-Clause" }, "node_modules/fast-xml-parser": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.0.8.tgz", - "integrity": "sha512-qY8NiI5L8ff00F2giyICiJxSSKHO52tC36LJqx2JtvGyAd5ZfehC/l4iUVVHpmpIa6sM9N5mneSLHQG2INGoHA==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.0.9.tgz", + "integrity": "sha512-2mBwCiuW3ycKQQ6SOesSB8WeF+fIGb6I/GG5vU5/XEptwFFhp9PE8b9O7fbs2dpq9fXn4ULR3UsfydNUCntf5A==", "funding": [ { "type": "github", @@ -22144,9 +22168,9 @@ "license": "ISC" }, "node_modules/flexlayout-react": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/flexlayout-react/-/flexlayout-react-0.8.5.tgz", - "integrity": "sha512-m5JdRuEHPPxvr78zw/5sTEYzBtyDdqp/ADRzj94To7n9IO2xy98yM3sjx44EOmaqT2dczG2ND+asJAJAr0xuqg==", + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/flexlayout-react/-/flexlayout-react-0.8.7.tgz", + "integrity": "sha512-eWGS+Kn50T8MW6W3R+NpEvV6RTOZBbkrNv875qrWdhRNR+vkrM7lPlAOg9jKGIonNXP1AujTjE6ZTk3W2zwjZA==", "license": "ISC", "peerDependencies": { "react": "^18.0.0 || ^19.0.0", @@ -24246,7 +24270,7 @@ "node_modules/image-size-stream/node_modules/image-size": { "version": "0.3.5", "resolved": "git+ssh://git@github.com/netroy/image-size.git#da2c863807a3e9602617bdd357b0de3ab4a064c1", - "integrity": "sha512-nF4/PT7i5t72LJKRBAXfM8PCzUDQurOUzPsNUjQDpUhFpLNuCpSY0+XIHNcc/LtoU3GqSCK3wQDU+CCty3Bfcw==", + "integrity": "sha512-bOV/01RFEAMM7OJU4alHoipipEYAdVk1W9rto2aN1ZnEZsZ1A1OCVJJ2iMaaJIKidVXGZNbP9knmW/3wWTZ4/Q==", "license": "MIT", "bin": { "image-size": "bin/image-size" @@ -27879,9 +27903,9 @@ "license": "MIT" }, "node_modules/mobx": { - "version": "6.13.6", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.13.6.tgz", - "integrity": "sha512-r19KNV0uBN4b+ER8Z0gA4y+MzDYIQ2SvOmn3fUrqPnWXdQfakd9yfbPBDBF/p5I+bd3N5Rk1fHONIvMay+bJGA==", + "version": "6.13.7", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.13.7.tgz", + "integrity": "sha512-aChaVU/DO5aRPmk1GX8L+whocagUUpBQqoPtJk+cm7UOXUk87J4PeWCh6nNmTTIfEhiR9DI/+FnA8dln/hTK7g==", "license": "MIT", "funding": { "type": "opencollective", @@ -28318,9 +28342,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.9.tgz", - "integrity": "sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==", + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.10.tgz", + "integrity": "sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg==", "funding": [ { "type": "github", @@ -31144,9 +31168,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.18", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.18.tgz", - "integrity": "sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==", + "version": "2.2.19", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.19.tgz", + "integrity": "sha512-94bcyI3RsqiZufXjkr3ltkI86iEl+I7uiHVDtcq9wJUTwYQJ5odHDeSzkkrRzi80jJ8MaeZgqKjH1bAWAFw9bA==", "license": "MIT" }, "node_modules/oauth": { @@ -31282,15 +31306,16 @@ } }, "node_modules/object.entries": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", - "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-object-atoms": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -32102,15 +32127,15 @@ } }, "node_modules/pdfjs-dist": { - "version": "4.10.38", - "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.10.38.tgz", - "integrity": "sha512-/Y3fcFrXEAsMjJXeL9J8+ZG9U01LbuWaYypvDW2ycW1jL269L3js3DVBjDJ0Up9Np1uqDXsDrRihHANhZOlwdQ==", + "version": "5.0.375", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.0.375.tgz", + "integrity": "sha512-QDRlEVldf/cX88CElGAyRhjqNOO69kmB3HZlalDAfqJ/IvmqJNkipomhBZy4cWATfLVlkQTXE3H4yFvMF2uPsg==", "license": "Apache-2.0", "engines": { "node": ">=20" }, "optionalDependencies": { - "@napi-rs/canvas": "^0.1.65" + "@napi-rs/canvas": "^0.1.67" } }, "node_modules/pdfjs/node_modules/pako": { @@ -32784,9 +32809,9 @@ } }, "node_modules/prosemirror-inputrules": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz", - "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.0.tgz", + "integrity": "sha512-K0xJRCmt+uSw7xesnHmcn72yBGTbY45vm8gXI4LZXbx2Z0jwh5aF9xrGQgrVPu0WbyFVFF3E/o9VhJYz6SQWnA==", "license": "MIT", "dependencies": { "prosemirror-state": "^1.0.0", @@ -32804,9 +32829,9 @@ } }, "node_modules/prosemirror-model": { - "version": "1.24.1", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.24.1.tgz", - "integrity": "sha512-YM053N+vTThzlWJ/AtPtF1j0ebO36nvbmDy4U7qA2XQB8JVaQp1FmB9Jhrps8s+z+uxhhVTny4m20ptUvhk0Mg==", + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.0.tgz", + "integrity": "sha512-/8XUmxWf0pkj2BmtqZHYJipTBMHIdVjuvFzMvEoxrtyGNmfvdhBiRwYt/eFwy2wA9DtBW3RLqvZnjurEkHaFCw==", "license": "MIT", "dependencies": { "orderedmap": "^2.0.0" @@ -34015,9 +34040,9 @@ } }, "node_modules/react-textarea-autosize": { - "version": "8.5.7", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.7.tgz", - "integrity": "sha512-2MqJ3p0Jh69yt9ktFIaZmORHXw4c4bxSIhCeWiFwmJ9EYKgLmuNII3e9c9b2UO+ijl4StnpZdqpxNIhTdHvqtQ==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.8.tgz", + "integrity": "sha512-iUiIj70JefrTuSJ4LbVFiSqWiHHss5L63L717bqaWHMgkm9sz6eEvro4vZ3uQfGJbevzwT6rHOszHKA8RkhRMg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.13", @@ -35221,9 +35246,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.85.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.85.1.tgz", - "integrity": "sha512-Uk8WpxM5v+0cMR0XjX9KfRIacmSG86RH4DCCZjLU2rFh5tyutt9siAXJ7G+YfxQ99Q6wrRMbMlVl6KqUms71ag==", + "version": "1.86.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.86.0.tgz", + "integrity": "sha512-zV8vGUld/+mP4KbMLJMX7TyGCuUp7hnkOScgCMsWuHtns8CWBoz+vmEhoGMXsaJrbUP8gj+F1dLvVe79sK8UdA==", "license": "MIT", "dependencies": { "chokidar": "^4.0.0", @@ -35799,9 +35824,9 @@ } }, "node_modules/shelljs": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.9.1.tgz", - "integrity": "sha512-ngPynK9u9OmsL2DttaTOhEPahyAjVbjIwCK3R+2V9YDq0/equpq7hVz3XrnfIjAk1thN5ET5mEIzAmocmV6i+Q==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.9.2.tgz", + "integrity": "sha512-S3I64fEiKgTZzKCC46zT/Ib9meqofLrQVbpSswtjFfAVDW+AZ54WTnAM/3/yENoxz/V1Cy6u3kiiEbQ4DNphvw==", "license": "BSD-3-Clause", "dependencies": { "execa": "^1.0.0", @@ -36474,13 +36499,13 @@ } }, "node_modules/storybook": { - "version": "8.6.4", - "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.4.tgz", - "integrity": "sha512-XXh1Acvf1r3BQX0BDLQw6yhZ7yUGvYxIcKOBuMdetnX7iXtczipJTfw0uyFwk0ltkKEE9PpJvivYmARF3u64VQ==", + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-8.6.7.tgz", + "integrity": "sha512-9gktoFMQDSCINNGQH869d/sar9rVtAhr0HchcvDA6bssAqgQJvTphY4qC9lH54SxfTJm/7Sy+BKEngMK+dziJg==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/core": "8.6.4" + "@storybook/core": "8.6.7" }, "bin": { "getstorybook": "bin/index.cjs", @@ -36960,9 +36985,9 @@ } }, "node_modules/styled-components": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.15.tgz", - "integrity": "sha512-PpOTEztW87Ua2xbmLa7yssjNyUF9vE7wdldRfn1I2E6RTkqknkBYpj771OxM/xrvRGinLy2oysa7GOd7NcZZIA==", + "version": "6.1.16", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.16.tgz", + "integrity": "sha512-KpWB6ORAWGmbWM10cDJfEV6sXc/uVkkkQV3SLwTNQ/E/PqWgNHIoMSLh1Lnk2FkB9+JHK7uuMq1i+9ArxDD7iQ==", "license": "MIT", "dependencies": { "@emotion/is-prop-valid": "1.2.2", @@ -37370,6 +37395,48 @@ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", + "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "license": "MIT", + "dependencies": { + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tinyqueue": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", @@ -37518,9 +37585,9 @@ } }, "node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.0.tgz", + "integrity": "sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==", "license": "MIT", "dependencies": { "punycode": "^2.3.1" @@ -38744,15 +38811,24 @@ } }, "node_modules/unstructured-client": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/unstructured-client/-/unstructured-client-0.21.0.tgz", - "integrity": "sha512-IEGZPIH6clFfAdIkx4PmOw5kOJDV7wWCgWHSlnCQ3BdtyCBHaJNE049hWlM6XIp5urR5ZqVhkKtFaHUqWXC9FQ==", + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/unstructured-client/-/unstructured-client-0.22.0.tgz", + "integrity": "sha512-3TzkJ2jFA8iJsdxIWptd7Rbu5uqmJ2UhzrvZFqgOEYujHZB4pU/8u69G3tOFV9e7oVO3rnF5QXGvVsX/xU3IIg==", "dependencies": { "async": "^3.2.5", "pdf-lib": "^1.17.1" }, + "bin": { + "mcp": "bin/mcp-server.js" + }, "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.5.0", "zod": ">= 3" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } } }, "node_modules/update-browserslist-db": { @@ -39740,12 +39816,12 @@ } }, "node_modules/whatwg-url": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.1.tgz", - "integrity": "sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==", + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", "license": "MIT", "dependencies": { - "tr46": "^5.0.0", + "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" }, "engines": { diff --git a/package.json b/package.json index 84aabbecd..9081dbd98 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "scripts": { "start-release": "cross-env RELEASE=true USE_AZURE=false NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug -- src/server/index.ts", "start-release-debug": "cross-env RELEASE=true USE_AZURE=false NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --inspect -- src/server/index.ts", - "start": "cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug --transpile-only -- src/server/index.ts", + "start": "cp node_modules/pdfjs-dist/build/pdf.worker.* src/server/public/files; cross-env NODE_OPTIONS=--max_old_space_size=4096 ts-node-dev --debug --transpile-only -- src/server/index.ts", "debug": "cross-env NODE_OPTIONS=--max_old_space_size=8192 ts-node-dev --transpile-only --inspect -- src/server/index.ts", "monitor": "cross-env MONITORED=true NODE_OPTIONS=--max_old_space_size=4096 ts-node src/server/index.ts", "build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 webpack --env production", @@ -143,7 +143,7 @@ "@types/reveal": "^4.2.0", "@types/supercluster": "^7.1.3", "@types/textfit": "^2.4.4", - "@types/web": "^0.0.211", + "@types/web": "^0.0.213", "@types/webpack-hot-middleware": "^2.25.9", "@webscopeio/react-textarea-autocomplete": "^4.9.2", "adm-zip": "^0.5.10", @@ -176,6 +176,7 @@ "connect-mongo": "^5.1.0", "cookie-parser": "^1.4.6", "cookie-session": "^2.0.0", + "copy-webpack-plugin": "^13.0.0", "core-js": "^3.33.3", "cors": "^2.8.5", "css-loader": "^7.1.2", @@ -269,7 +270,7 @@ "path-browserify": "^1.0.1", "pdf-parse": "^1.1.1", "pdfjs": "^2.4.7", - "pdfjs-dist": "^4.0.269", + "pdfjs-dist": "^5.0.375", "pinecone": "^0.1.0", "probe-image-size": "^7.2.3", "process": "^0.11.10", @@ -344,7 +345,7 @@ "typescript-collections": "^1.3.3", "typescript-language-server": "^4.1.3", "uninstall": "^0.0.0", - "unstructured-client": "^0.21.0", + "unstructured-client": "^0.22.0", "url": "^0.11.3", "url-loader": "^4.1.1", "util": "^0.12.5", diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 83b3dffe5..f6f319831 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -2,7 +2,11 @@ import { action, computed, IReactionDisposer, makeObservable, observable, Observ import { observer } from 'mobx-react'; import * as Pdfjs from 'pdfjs-dist'; import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs'; -import 'pdfjs-dist/webpack.mjs'; // sets the PDF workerSrc +import { GlobalWorkerOptions } from 'pdfjs-dist/build/pdf.mjs'; +if (typeof window !== 'undefined' && 'Worker' in window) { + GlobalWorkerOptions.workerSrc = 'files/pdf.worker.min.mjs'; +} +export * from 'pdfjs-dist/build/pdf.mjs'; import * as React from 'react'; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, returnAll, returnFalse, returnNone, returnZero, smoothScroll } from '../../../ClientUtils'; import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc'; diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts index dbfabed51..abcec13c0 100644 --- a/src/typings/index.d.ts +++ b/src/typings/index.d.ts @@ -11,6 +11,7 @@ declare module 'bezier-curve'; declare module 'fit-curve'; declare module 'iink-js'; declare module 'pdfjs-dist/web/pdf_viewer'; +declare module 'pdfjs-dist/build/pdf.mjs'; declare module 'react-jsx-parser'; declare module 'type_decls.d'; declare module 'standard-http-error'; -- cgit v1.2.3-70-g09d2 From 2f06b1615fa1bcdc76efb170187dace6bed9d78e Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 18 Mar 2025 20:13:13 -0400 Subject: from last --- src/client/views/pdf/PDFViewer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index f6f319831..27dffa93b 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -3,7 +3,7 @@ import { observer } from 'mobx-react'; import * as Pdfjs from 'pdfjs-dist'; import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs'; import { GlobalWorkerOptions } from 'pdfjs-dist/build/pdf.mjs'; -if (typeof window !== 'undefined' && 'Worker' in window) { +if (window?.Worker) { GlobalWorkerOptions.workerSrc = 'files/pdf.worker.min.mjs'; } export * from 'pdfjs-dist/build/pdf.mjs'; -- cgit v1.2.3-70-g09d2 From d0789ff140b88a81afbf4d58ec984dc062dce462 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 18 Mar 2025 20:26:13 -0400 Subject: from last --- src/client/views/pdf/PDFViewer.scss | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss index 030251762..f4257a93c 100644 --- a/src/client/views/pdf/PDFViewer.scss +++ b/src/client/views/pdf/PDFViewer.scss @@ -30,6 +30,9 @@ opacity: unset; mix-blend-mode: multiply; // bcz: makes text fuzzy! transform: scale(var(--devicePixelRatio)); + .markedContent span { + --total-scale-factor: var(--scale-factor); + } } [data-main-rotation='90'] { transform: scale(var(--devicePixelRatio)) rotate(90deg) translateY(-100%); -- cgit v1.2.3-70-g09d2 From b85958e45b951320e92bbcae384abbde93a2d0c6 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 18 Mar 2025 20:35:57 -0400 Subject: from last --- src/client/views/pdf/PDFViewer.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 27dffa93b..dc7524bcd 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -1,13 +1,10 @@ import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as Pdfjs from 'pdfjs-dist'; -import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs'; import { GlobalWorkerOptions } from 'pdfjs-dist/build/pdf.mjs'; -if (window?.Worker) { - GlobalWorkerOptions.workerSrc = 'files/pdf.worker.min.mjs'; -} -export * from 'pdfjs-dist/build/pdf.mjs'; +import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs'; import * as React from 'react'; +import ReactLoading from 'react-loading'; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, returnAll, returnFalse, returnNone, returnZero, smoothScroll } from '../../../ClientUtils'; import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc'; import { DocData, Height } from '../../../fields/DocSymbols'; @@ -18,6 +15,7 @@ import { TraceMobx } from '../../../fields/util'; import { emptyFunction, numberRange, unimplementedFunction } from '../../../Utils'; import { DocUtils } from '../../documents/DocUtils'; import { SnappingManager } from '../../util/SnappingManager'; +import { Transform } from '../../util/Transform'; import { MarqueeOptionsMenu } from '../collections/collectionFreeForm'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { MarqueeAnnotator } from '../MarqueeAnnotator'; @@ -32,8 +30,8 @@ import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; import './PDFViewer.scss'; -import ReactLoading from 'react-loading'; -import { Transform } from '../../util/Transform'; +if (window?.Worker) GlobalWorkerOptions.workerSrc = 'files/pdf.worker.min.mjs'; +export * from 'pdfjs-dist/build/pdf.mjs'; interface IViewerProps extends FieldViewProps { pdfBox: PDFBox; -- cgit v1.2.3-70-g09d2 From 9cc9b2aca40e0a0c5e6027999e4d6316113ac6bf Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 18 Mar 2025 21:36:03 -0400 Subject: finally fixed selectionw with new version of PDFjs --- src/client/views/pdf/PDFViewer.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss index f4257a93c..1aab2b853 100644 --- a/src/client/views/pdf/PDFViewer.scss +++ b/src/client/views/pdf/PDFViewer.scss @@ -29,10 +29,11 @@ .textLayer { opacity: unset; mix-blend-mode: multiply; // bcz: makes text fuzzy! + // all these below fix issues with PDFjs transform: scale(var(--devicePixelRatio)); - .markedContent span { - --total-scale-factor: var(--scale-factor); - } + --total-scale-factor: var(--scale-factor); // these 3 are used by PDFjs but not defined. why??? + --scale-round-x: 1px; + --scale-round-y: 1px; } [data-main-rotation='90'] { transform: scale(var(--devicePixelRatio)) rotate(90deg) translateY(-100%); -- cgit v1.2.3-70-g09d2 From 7e4d793eaa7e5b6b564355a11fa02a5611645f20 Mon Sep 17 00:00:00 2001 From: bobzel Date: Fri, 21 Mar 2025 18:58:21 -0400 Subject: trying to improve how data / layout / root and templtae docs are accessed. --- src/client/documents/DocUtils.ts | 11 +++--- src/client/util/CalendarManager.tsx | 11 ++---- src/client/util/CurrentUserUtils.ts | 17 +++++---- src/client/util/DictationManager.ts | 6 ++-- src/client/util/DocumentManager.ts | 11 ++---- src/client/util/DragManager.ts | 5 +-- src/client/util/History.ts | 2 +- src/client/util/Import & Export/ImageUtils.ts | 14 ++++---- src/client/views/DashboardView.tsx | 26 +++++++------- src/client/views/DocComponent.tsx | 14 ++++---- src/client/views/DocumentDecorations.tsx | 4 +-- src/client/views/FilterPanel.tsx | 3 +- src/client/views/InkStrokeProperties.ts | 3 +- src/client/views/MainView.tsx | 3 +- src/client/views/MarqueeAnnotator.tsx | 22 ++++++------ src/client/views/PinFuncs.ts | 3 +- src/client/views/PropertiesButtons.tsx | 6 ++-- src/client/views/PropertiesView.tsx | 42 +++++++++++----------- src/client/views/ScriptBox.tsx | 6 ++-- .../views/collections/CollectionDockingView.tsx | 13 ++++--- src/client/views/nodes/DocumentView.tsx | 36 +++++++++---------- src/client/views/nodes/KeyValueBox.tsx | 36 +++++++++++-------- src/client/views/nodes/KeyValuePair.tsx | 18 +++++----- .../views/nodes/formattedText/FormattedTextBox.tsx | 9 +++-- .../views/nodes/formattedText/RichTextRules.ts | 36 ++++++++----------- src/client/views/nodes/trails/PresBox.tsx | 10 +++--- src/client/views/pdf/PDFViewer.tsx | 2 +- src/client/views/search/FaceRecognitionHandler.tsx | 21 ++++++----- src/client/views/search/SearchBox.tsx | 1 - src/client/views/smartdraw/DrawingFillHandler.tsx | 6 ++-- src/fields/Doc.ts | 14 +++++--- src/fields/util.ts | 10 ++++++ 32 files changed, 203 insertions(+), 218 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index 1c7ccadd1..13f6f6920 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -8,7 +8,6 @@ import * as JSZipUtils from '../../JSZipUtils'; import { decycle } from '../../decycler/decycler'; import { DateField } from '../../fields/DateField'; import { Doc, DocListCast, Field, FieldResult, FieldType, LinkedTo, Opt, StrListCast } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { InkData, InkDataFieldName, InkField } from '../../fields/InkField'; import { List, ListFieldName } from '../../fields/List'; @@ -383,10 +382,10 @@ export namespace DocUtils { event: undoable(() => { const newDoc = DocUtils.copyDragFactory(dragDoc); if (newDoc) { - newDoc.author = ClientUtils.CurrentUserEmail(); - newDoc.x = x; - newDoc.y = y; - newDoc[DocData].backgroundColor = Doc.UserDoc().textBackgroundColor; + newDoc._author = ClientUtils.CurrentUserEmail(); + newDoc._x = x; + newDoc._y = y; + newDoc.$backgroundColor = Doc.UserDoc().textBackgroundColor; DocumentView.SetSelectOnLoad(newDoc); if (pivotField) { newDoc[pivotField] = pivotValue; @@ -745,7 +744,7 @@ export namespace DocUtils { if (defaultTextTemplate) { tbox.layout_fieldKey = 'layout_' + StrCast(defaultTextTemplate.title); Doc.GetProto(tbox)[StrCast(tbox.layout_fieldKey)] = defaultTextTemplate; // set the text doc's layout to render with the text template - tbox[DocData].proto = defaultTextTemplate; // and also set the text doc to inherit from the template (this allows the template to specify default field values) + tbox.$proto = defaultTextTemplate; // and also set the text doc to inherit from the template (this allows the template to specify default field values) } return tbox; } diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx index d28b3a2c9..a0db4e32e 100644 --- a/src/client/util/CalendarManager.tsx +++ b/src/client/util/CalendarManager.tsx @@ -8,7 +8,6 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import Select from 'react-select'; import { Doc, DocListCast } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { StrCast } from '../../fields/Types'; import { Docs } from '../documents/Documents'; import { MainViewModal } from '../views/MainViewModal'; @@ -51,8 +50,6 @@ export class CalendarManager extends ObservableReactComponent { @observable private targetDocView: DocumentView | undefined = undefined; // the DocumentView of the target doc @observable private dialogueBoxOpacity = 1; // for the modal - @observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used - @observable private creationType: CreationType = 'new-calendar'; @observable private existingCalendars: Doc[] = DocListCast(Doc.MyCalendars?.data); @@ -97,7 +94,6 @@ export class CalendarManager extends ObservableReactComponent { }), 500 ); - this.layoutDocAcls = false; }); constructor(props: object) { @@ -122,9 +118,8 @@ export class CalendarManager extends ObservableReactComponent { // TODO: Make undoable private addToCalendar = () => { const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document); - const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; // doc to add to calendar + const targetDoc = docs[0]; // doc to add to calendar - console.log(targetDoc); if (targetDoc) { let calendar: Doc; if (this.creationType === 'new-calendar') { @@ -234,7 +229,7 @@ export class CalendarManager extends ObservableReactComponent { @computed get calendarInterface() { const docs = DocumentView.Selected().length < 2 ? [this.targetDoc] : DocumentView.Selected().map(docView => docView.Document); - const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; + const targetDoc = docs[0]; return (
{
Select a date range:
- this.setSelectedDateRange(v)} /> + v && this.setSelectedDateRange(v)} />
{this.createButtonActive && ( diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 21e1d3e12..924041552 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -3,7 +3,6 @@ import { reaction, runInAction } from "mobx"; import * as rp from 'request-promise'; import { ClientUtils, OmitKeys } from "../../ClientUtils"; import { Doc, DocListCast, DocListCastAsync, FieldType, Opt } from "../../fields/Doc"; -import { DocData } from "../../fields/DocSymbols"; import { InkEraserTool, InkInkTool, InkProperty, InkTool } from "../../fields/InkField"; import { List } from "../../fields/List"; import { PrefetchProxy } from "../../fields/Proxy"; @@ -323,10 +322,10 @@ export class CurrentUserUtils { type: 'scatter' }`); const slide = Docs.Create.TextDocument("", opts); - slide[DocData].text = rtfield; - slide[DocData].layout_textPainted = ``; - slide[DocData]._type_collection = CollectionViewType.Freeform; - slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); + slide.$text = rtfield; + slide.$layout_textPainted = ``; + slide.$type_collection = CollectionViewType.Freeform; + slide._onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); return slide; } const mermaidsApi = () => { @@ -374,10 +373,10 @@ pie title Minerals in my tap water "Potassium" : 50 "Magnesium" : 10.01`); const slide = Docs.Create.TextDocument("", opts); - slide[DocData].text = rtfield; - slide[DocData].layout_textPainted = ``; - slide[DocData]._type_collection = CollectionViewType.Freeform; - slide.onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); + slide.$text = rtfield; + slide.$layout_textPainted = ``; + slide.$_type_collection = CollectionViewType.Freeform; + slide._onPaint = ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, {documentView:"any"}); return slide; } plotlyApi(); mermaidsApi(); diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts index 897366757..44fbda319 100644 --- a/src/client/util/DictationManager.ts +++ b/src/client/util/DictationManager.ts @@ -2,7 +2,6 @@ import * as interpreter from 'words-to-numbers'; import { ClientUtils } from '../../ClientUtils'; import { Doc, Opt } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; import { RichTextField } from '../../fields/RichTextField'; import { listSpec } from '../../fields/Schema'; @@ -339,13 +338,12 @@ export namespace DictationManager { { action: (target: DocumentView) => { const newBox = Docs.Create.TextDocument('', { _width: 400, _height: 200, title: 'My Outline', _layout_autoHeight: true }); - const proto = newBox[DocData]; const prompt = 'Press alt + r to start dictating here...'; const head = 3; const anchor = head + prompt.length; const proseMirrorState = `{"doc":{"type":"doc","content":[{"type":"ordered_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"${prompt}"}]}]}]}]},"selection":{"type":"text","anchor":${anchor},"head":${head}}}`; - proto.data = new RichTextField(proseMirrorState, prompt); - proto.backgroundColor = '#eeffff'; + newBox.$data = new RichTextField(proseMirrorState, prompt); + newBox.$backgroundColor = '#eeffff'; target.props.addDocTab(newBox, OpenWhere.addRight); }, }, diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index e33449782..5ce005811 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -2,7 +2,6 @@ import { Howl } from 'howler'; import { action, computed, makeObservable, observable, ObservableSet, observe } from 'mobx'; import { Doc, Opt } from '../../fields/Doc'; import { Animation, DocData } from '../../fields/DocSymbols'; -import { Id } from '../../fields/FieldSymbols'; import { listSpec } from '../../fields/Schema'; import { Cast, DocCast, NumCast, StrCast } from '../../fields/Types'; import { AudioField } from '../../fields/URLField'; @@ -108,16 +107,16 @@ export class DocumentManager { }); // gets all views - public getDocumentViewsById(id: string) { + public getAllDocumentViews(doc: Doc) { const toReturn: DocumentView[] = []; DocumentManager.Instance.DocumentViews.forEach(view => { - if (view.Document[Id] === id) { + if (view.Document === doc) { toReturn.push(view); } }); if (toReturn.length === 0) { DocumentManager.Instance.DocumentViews.forEach(view => { - if (view.Document[DocData]?.[Id] === id) { + if (view.Document[DocData] === doc) { toReturn.push(view); } }); @@ -125,10 +124,6 @@ export class DocumentManager { return toReturn; } - public getAllDocumentViews(doc: Doc) { - return this.getDocumentViewsById(doc[Id]); - } - public getDocumentView(target: Doc | undefined, preferredCollection?: DocumentView): DocumentView | undefined { const docViewArray = DocumentManager.Instance.DocumentViews; const passes = !target ? [] : preferredCollection ? [preferredCollection, undefined] : [undefined]; diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 2a7859f09..e2e4c0fe4 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -280,11 +280,12 @@ export namespace DragManager { export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: FieldType }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) { const finishDrag = (e: DragCompleteEvent) => { const bd = Docs.Create.ButtonDocument({ toolTip: title, z: 1, _width: 150, _height: 50, title, onClick: ScriptField.MakeScript(script) }); + const bdData = bd[DocData]; params.forEach(p => { - Object.keys(vars).indexOf(p) !== -1 && (bd[DocData][p] = new PrefetchProxy(vars[p] as Doc)); + Object.keys(vars).indexOf(p) !== -1 && (bdData[p] = new PrefetchProxy(vars[p] as Doc)); }); // copy all "captured" arguments into document parameterfields initialize?.(bd); - bd[DocData]['onClick-paramFieldKeys'] = new List(params); + bd.$onClick_paramFieldKeys = new List(params); e.docDragData && (e.docDragData.droppedDocuments = [bd]); return e; }; diff --git a/src/client/util/History.ts b/src/client/util/History.ts index 9728e3177..0df0ec337 100644 --- a/src/client/util/History.ts +++ b/src/client/util/History.ts @@ -94,7 +94,7 @@ export namespace HistoryUtil { } if (Array.isArray(value)) { } else if (parser === true || parser === 'json') { - value = JSON.parse(value); + value = value === 'undefined' ? undefined : JSON.parse(value); } else if (parser === 'none') { } else { value = parser(value); diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts index 43807397f..9c32ca25a 100644 --- a/src/client/util/Import & Export/ImageUtils.ts +++ b/src/client/util/Import & Export/ImageUtils.ts @@ -1,6 +1,5 @@ import { ClientUtils } from '../../../ClientUtils'; import { Doc } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { Cast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; @@ -16,13 +15,12 @@ export namespace ImageUtils { export const AssignImgInfo = (document: Doc, data?: Upload.InspectionResults) => { if (data) { data.nativeWidth && (document._height = (NumCast(document._width) * data.nativeHeight) / data.nativeWidth); - const proto = document[DocData]; - const field = Doc.LayoutFieldKey(document); - proto[`${field}_nativeWidth`] = data.nativeWidth; - proto[`${field}_nativeHeight`] = data.nativeHeight; - proto[`${field}_path`] = data.source; - proto[`${field}_exif`] = JSON.stringify(data.exifData.data); - proto[`${field}_contentSize`] = data.contentSize ? data.contentSize : undefined; + const field = '$' + Doc.LayoutFieldKey(document); + document[`${field}_nativeWidth`] = data.nativeWidth; + document[`${field}_nativeHeight`] = data.nativeHeight; + document[`${field}_path`] = data.source; + document[`${field}_exif`] = JSON.stringify(data.exifData.data); + document[`${field}_contentSize`] = data.contentSize ? data.contentSize : undefined; } return document; }; diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 7f0118ed3..f61f6db18 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { FaPlus } from 'react-icons/fa'; import { ClientUtils } from '../../ClientUtils'; import { Doc, DocListCast } from '../../fields/Doc'; -import { AclPrivate, DocAcl, DocData } from '../../fields/DocSymbols'; +import { AclPrivate, DocAcl } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { List } from '../../fields/List'; import { PrefetchProxy } from '../../fields/Proxy'; @@ -113,7 +113,7 @@ export class DashboardView extends ObservableReactComponent { getDashboards = (whichGroup: DashboardGroup) => { if (whichGroup === DashboardGroup.MyDashboards) { - return DocListCast(Doc.MyDashboards.data).filter(dashboard => dashboard[DocData].author === ClientUtils.CurrentUserEmail()); + return DocListCast(Doc.MyDashboards.data).filter(dashboard => dashboard.$author === ClientUtils.CurrentUserEmail()); } return DocListCast(Doc.MySharedDocs.data_dashboards).filter(doc => doc.dockingConfig); }; @@ -226,7 +226,7 @@ export class DashboardView extends ObservableReactComponent { color={color} val={StrCast(dashboard.title)} setVal={val => { - dashboard[DocData].title = val; + dashboard.$title = val; }} /> {this.selectedDashboardGroup === DashboardGroup.SharedDashboards && this.isUnviewedSharedDashboard(dashboard) ?
unviewed
:
} @@ -403,8 +403,8 @@ export class DashboardView extends ObservableReactComponent { }, ], }; - if (dashboard.dockingConfig && dashboard.dockingConfig !== dashboard[DocData].dockingConfig) dashboard.dockingConfig = JSON.stringify(reset); - else Doc.SetInPlace(dashboard, 'dockingConfig', JSON.stringify(reset), true); + const dockingOnLayout = dashboard._dockingConfig && dashboard._dockingConfig !== dashboard.$dockingConfig; + dashboard[`${dockingOnLayout ? '_' : '$'}dockingConfig`] = JSON.stringify(reset); return reset; }; @@ -427,14 +427,14 @@ export class DashboardView extends ObservableReactComponent { Doc.AddDocToList(Doc.MyHeaderBar, 'data', freeformDoc, undefined, undefined, true); Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc); - dashboardDoc.pane_count = 1; - freeformDoc.embedContainer = dashboardDoc; - dashboardDoc.myOverlayDocs = new List(); - dashboardDoc[DocData].myPublishedDocs = new List(); - dashboardDoc[DocData].myTagCollections = new List(); - dashboardDoc[DocData].myUniqueFaces = new List(); - dashboardDoc[DocData].myTrails = DashboardView.SetupDashboardTrails(); - dashboardDoc[DocData].myCalendars = DashboardView.SetupDashboardCalendars(); + freeformDoc._embedContainer = dashboardDoc; + dashboardDoc.$myPaneCount = 1; + dashboardDoc.$myOverlayDocs = new List(); + dashboardDoc.$myPublishedDocs = new List(); + dashboardDoc.$myTagCollections = new List(); + dashboardDoc.$myUniqueFaces = new List(); + dashboardDoc.$myTrails = DashboardView.SetupDashboardTrails(); + dashboardDoc.$myCalendars = DashboardView.SetupDashboardCalendars(); // open this new dashboard Doc.ActiveDashboard = dashboardDoc; Doc.ActivePage = 'dashboard'; diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index e351e2dec..064906530 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -5,7 +5,7 @@ import { DateField } from '../../fields/DateField'; import { Doc, DocListCast, Opt } from '../../fields/Doc'; import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, DocData } from '../../fields/DocSymbols'; import { List } from '../../fields/List'; -import { toList } from '../../fields/Types'; +import { DocCast, toList } from '../../fields/Types'; import { GetEffectiveAcl, inheritParentAcls } from '../../fields/util'; import { DocumentType } from '../documents/DocumentTypes'; import { ObservableReactComponent } from './ObservableReactComponent'; @@ -35,14 +35,14 @@ export function DocComponent

() { * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,) */ get Document() { - return this._props.Document; + return DocCast(this._props.Document.rootDocument, this._props.Document); } /** * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. */ @computed get layoutDoc() { - return this._props.LayoutTemplateString ? this.Document : Doc.Layout(this.Document, this._props.LayoutTemplate?.()); + return this._props.LayoutTemplateString ? this.Document : Doc.Layout(this._props.Document, this._props.LayoutTemplate?.()); } /** @@ -80,13 +80,13 @@ export function ViewBoxBaseComponent

() { * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,) */ get Document() { - return this._props.Document; + return DocCast(this._props.Document.rootDocument, this._props.Document); } /** * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. */ @computed get layoutDoc() { - return Doc.Layout(this.Document); + return Doc.Layout(this._props.Document); } /** @@ -138,13 +138,13 @@ export function ViewBoxAnnotatableComponent

() { * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,) */ @computed get Document() { - return this._props.Document; + return DocCast(this._props.Document.rootDocument, this._props.Document); } /** * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. */ @computed get layoutDoc() { - return Doc.Layout(this.Document); + return Doc.Layout(this._props.Document); } /** diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 54e050f9f..92b4d6fbf 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -127,7 +127,7 @@ export class DocumentDecorations extends ObservableReactComponent#')) { DocumentView.SelectedDocs().forEach(doc => { - doc[DocData].onViewMounted = ScriptField.MakeScript(`updateTagsCollection(this)`); + doc.$onViewMounted = ScriptField.MakeScript(`updateTagsCollection(this)`); }); } const titleFieldKey = this._titleControlString.substring(1); @@ -621,7 +621,7 @@ export class DocumentDecorations extends ObservableReactComponent ({ oldbds, inkPts: Cast(oldbds.doc.data, InkField)?.inkData || [] })) .forEach(({ oldbds: { doc, x, y, width, height }, inkPts }) => { - doc[DocData].data = new InkField(inkPts.map( + doc.$data = new InkField(inkPts.map( (ipt) => ({// (new x — oldx) + newWidth * (oldxpoint /oldWidth) X: NumCast(doc.x) - x + (NumCast(doc.width) * ipt.X) / width, Y: NumCast(doc.y) - y + (NumCast(doc.height) * ipt.Y) / height, diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index 99738052d..4fc8d7a68 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -9,7 +9,6 @@ import { Handles, Rail, Slider, Ticks, Tracks } from 'react-compound-slider'; import { AiOutlineMinusSquare, AiOutlinePlusSquare } from 'react-icons/ai'; import { CiCircleRemove } from 'react-icons/ci'; import { Doc, DocListCast, Field, FieldType, LinkedTo, StrListCast } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { List } from '../../fields/List'; import { RichTextField } from '../../fields/RichTextField'; @@ -89,7 +88,7 @@ const HotKeyIconButton: React.FC = observer(({ hotKey /*, sel key={icon.toString()} onClick={undoable(e => { e.stopPropagation; - hotKey[DocData].icon = icon.toString(); + hotKey.$icon = icon.toString(); }, '')} className="icon-panel-button"> diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index 358274f0e..6854476e2 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -3,7 +3,6 @@ import * as fitCurve from 'fit-curve'; import * as _ from 'lodash'; import { action, makeObservable, observable, reaction, runInAction } from 'mobx'; import { Doc, NumListCast, Opt } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { InkData, InkField, InkTool } from '../../fields/InkField'; import { List } from '../../fields/List'; import { listSpec } from '../../fields/Schema'; @@ -509,7 +508,7 @@ export class InkStrokeProperties { const inkStroke = inkView?.ComponentView as InkingStroke; const polylinePoints = this.sampleBezier(inkStroke?.inkScaledData().inkData ?? [])?.map(pt => [pt.x, pt.y]); if (polylinePoints) { - inkDoc[DocData].stroke = new InkField( + inkDoc.$stroke = new InkField( fitCurve.default(polylinePoints, tolerance) .reduce((cpts, bez) => ({n: cpts.push(...bez.map(cpt => ({X:cpt[0], Y:cpt[1]}))), cpts}).cpts, diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index ef8d0c197..e70f9e5ed 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -11,7 +11,6 @@ import '@dash/components/src/global/globalCssVariables.scss'; import { ClientUtils, returnEmptyFilter, returnFalse, returnTrue, returnZero, setupMoveUpEvents } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; import { Doc, DocListCast, GetDocFromUrl, Opt, returnEmptyDoclist } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { DocCast, StrCast, toList } from '../../fields/Types'; import { DocServer } from '../DocServer'; @@ -849,7 +848,7 @@ export class MainView extends ObservableReactComponent { @action selectMenu = (button: Doc) => { - const title = StrCast(button[DocData].title); + const title = StrCast(button.$title); const willOpen = !this._leftMenuFlyoutWidth || this._panelContent !== title; this.closeFlyout(); if (willOpen) { diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx index 3f4200dce..e4811a902 100644 --- a/src/client/views/MarqueeAnnotator.tsx +++ b/src/client/views/MarqueeAnnotator.tsx @@ -97,7 +97,6 @@ export class MarqueeAnnotator extends ObservableReactComponent' + this.props.Document.title, }); - const textRegionAnnoProto = textRegionAnno[DocData]; let minX = Number.MAX_VALUE; let maxX = -Number.MAX_VALUE; let minY = Number.MAX_VALUE; @@ -118,15 +117,15 @@ export class MarqueeAnnotator extends ObservableReactComponent(annoRects); - textRegionAnnoProto.opacity = 0; - textRegionAnnoProto.layout_unrendered = true; + textRegionAnno.$text_inlineAnnotations = new List(annoRects); + textRegionAnno.$opacity = 0; + textRegionAnno.$layout_unrendered = true; savedAnnoMap.clear(); return textRegionAnno; }; @@ -226,9 +225,8 @@ export class MarqueeAnnotator extends ObservableReactComponent { if (!dragEx.aborted && dragEx.linkDocument) { - const linkDocData = dragEx.linkDocument[DocData]; - linkDocData.link_relationship = 'cropped image'; - linkDocData.title = 'crop: ' + this.props.Document.title; + dragEx.linkDocument.$link_relationship = 'cropped image'; + dragEx.linkDocument.$title = 'crop: ' + this.props.Document.title; } }, }); diff --git a/src/client/views/PinFuncs.ts b/src/client/views/PinFuncs.ts index ab02c2d07..1ab8575a8 100644 --- a/src/client/views/PinFuncs.ts +++ b/src/client/views/PinFuncs.ts @@ -1,5 +1,4 @@ import { Doc, DocListCast, Field } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { Copy, Id } from '../../fields/FieldSymbols'; import { List } from '../../fields/List'; import { ObjectField } from '../../fields/ObjectField'; @@ -78,7 +77,7 @@ export function PinDocView(pinDocIn: Doc, pinProps: PinProps, targetDoc: Doc) { } if (pinProps.pinData.dataannos) { const fieldKey = Doc.LayoutFieldKey(targetDoc); - pinDoc.config_annotations = new List(DocListCast(targetDoc[DocData][fieldKey + '_annotations']).filter(doc => !doc.layout_unrendered)); + pinDoc.config_annotations = new List(DocListCast(targetDoc['$' + fieldKey + '_annotations']).filter(doc => !doc.layout_unrendered)); } if (pinProps.pinData.inkable) { pinDoc.config_fillColor = targetDoc.fillColor; diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx index 606fb17ed..2b4fe478e 100644 --- a/src/client/views/PropertiesButtons.tsx +++ b/src/client/views/PropertiesButtons.tsx @@ -1,4 +1,3 @@ -/* eslint-disable react/no-unused-class-component-methods */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Dropdown, DropdownType, IListItemProps, Toggle, ToggleType, Type } from '@dash/components'; import { action, computed, observable } from 'mobx'; @@ -14,7 +13,6 @@ import { RxWidth } from 'react-icons/rx'; import { TbEditCircle, TbEditCircleOff, TbHandOff, TbHandStop, TbHighlight, TbHighlightOff } from 'react-icons/tb'; import { TfiBarChart } from 'react-icons/tfi'; import { Doc, Opt } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { ScriptField } from '../../fields/ScriptField'; import { BoolCast, ScriptCast, StrCast } from '../../fields/Types'; import { ImageField } from '../../fields/URLField'; @@ -134,8 +132,8 @@ export class PropertiesButtons extends React.Component { () => , (dv, doc) => { const on = !!doc.onPaint; - doc[DocData].onPaint = on ? undefined : ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, { documentView: 'any' }); - doc[DocData].layout_textPainted = on ? undefined : ``; + doc.$onPaint = on ? undefined : ScriptField.MakeScript(`toggleDetail(documentView, "textPainted")`, { documentView: 'any' }); + doc.$layout_textPainted = on ? undefined : ``; } ); } diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index 11adf7435..c72f958fc 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -282,7 +282,7 @@ export class PropertiesView extends ObservableReactComponent(tags) : undefined; + doc.$tags = tags.length ? new List(tags) : undefined; } return true; } @@ -498,7 +498,7 @@ export class PropertiesView extends ObservableReactComponent { let userOnDoc = true; @@ -777,7 +777,7 @@ export class PropertiesView extends ObservableReactComponent doc.layout_isSvg); + return this.containsInkDoc ? DocListCast(this.selectedDoc.$data) : DocumentView.SelectedSchemaDoc() ? [DocumentView.SelectedSchemaDoc()!] : DocumentView.SelectedDocs().filter(doc => doc.layout_isSvg); } @computed get shapeXps() { return NumCast(this.selectedDoc?.x); } // prettier-ignore set shapeXps(value) { this.selectedDoc && (this.selectedDoc.x = Math.round(value * 100) / 100); } // prettier-ignore @@ -839,10 +839,10 @@ export class PropertiesView extends ObservableReactComponent { - doc[DocData].stroke_width = Math.round(value * 100) / 100; + doc.$stroke_width = Math.round(value * 100) / 100; }); } @@ -881,20 +881,20 @@ export class PropertiesView extends ObservableReactComponent { const inkStroke = DocumentView.getDocumentView(doc)?.ComponentView as InkingStroke; const { inkData } = inkStroke.inkScaledData(); if (InkingStroke.IsClosed(inkData)) { - doc[DocData].fillColor = value || undefined; + doc.$fillColor = value || undefined; } }); } - @computed get colorStk() { return StrCast(this.selectedStrokes.lastElement()?.[DocData].color); } // prettier-ignore + @computed get colorStk() { return StrCast(this.selectedStrokes.lastElement()?.$olor); } // prettier-ignore set colorStk(value) { this.selectedStrokes.forEach(doc => { - doc[DocData].color = value || undefined; + doc.$color = value || undefined; }); } @computed get borderColor() { @@ -902,7 +902,7 @@ export class PropertiesView extends ObservableReactComponent void) { return ( @@ -1034,41 +1034,41 @@ export class PropertiesView extends ObservableReactComponent { - doc[DocData].stroke_dash = value ? this._lastDash : undefined; + doc.$stroke_dash = value ? this._lastDash : undefined; }); } @computed get widthStk() { return this.getField('stroke_width') || '1'; } // prettier-ignore set widthStk(value) { this.selectedStrokes.forEach(doc => { - doc[DocData].stroke_width = Number(value); + doc.$stroke_width = Number(value); }); } @computed get markScal() { return Number(this.getField('stroke_markerScale') || '1'); } // prettier-ignore set markScal(value) { this.selectedStrokes.forEach(doc => { - doc[DocData].stroke_markerScale = Number(value); + doc.$stroke_markerScale = Number(value); }); } @computed get refStrength() { return Number(this.getField('drawing_refStrength') || '50'); } // prettier-ignore set refStrength(value) { - this.selectedDoc[DocData].drawing_refStrength = Number(value); + this.selectedDoc.$drawing_refStrength = Number(value); } @computed get smoothAmt() { return Number(this.getField('stroke_smoothAmount') || '5'); } // prettier-ignore set smoothAmt(value) { this.selectedStrokes.forEach(doc => { - doc[DocData].stroke_smoothAmount = Number(value); + doc.$stroke_smoothAmount = Number(value); }); } @computed get markHead() { return this.getField('stroke_startMarker') || ''; } // prettier-ignore set markHead(value) { this.selectedStrokes.forEach(doc => { - doc[DocData].stroke_startMarker = value; + doc.$stroke_startMarker = value; }); } @computed get markTail() { return this.getField('stroke_endMarker') || ''; } // prettier-ignore set markTail(value) { this.selectedStrokes.forEach(doc => { - doc[DocData].stroke_endMarker = value; + doc.$stroke_endMarker = value; }); } @@ -1356,7 +1356,7 @@ export class PropertiesView extends ObservableReactComponent { - const childDocs: Doc[] = DocListCast(selectedDoc[DocData].data); + const childDocs: Doc[] = DocListCast(selectedDoc.$data); for (let i = 0; i < childDocs.length; i++) { if (DocumentView.getDocumentView(childDocs[i])?.layoutDoc?.layout_isSvg) { return true; @@ -1454,7 +1454,7 @@ export class PropertiesView extends ObservableReactComponent { if (this.selectedLink) { - this.selectedLink[DocData].link_description = value; + this.selectedLink.$link_description = value; } }); diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx index d05b0a6b6..52c0227d8 100644 --- a/src/client/views/ScriptBox.tsx +++ b/src/client/views/ScriptBox.tsx @@ -3,7 +3,6 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { emptyFunction } from '../../Utils'; import { Doc, Opt } from '../../fields/Doc'; -import { DocData } from '../../fields/DocSymbols'; import { ScriptField } from '../../fields/ScriptField'; import { ScriptCast } from '../../fields/Types'; import { DragManager } from '../util/DragManager'; @@ -101,7 +100,6 @@ export class ScriptBox extends React.Component { ); } // let l = docList(this.source[0].data).length; if (l) { let ind = this.target[0].index !== undefined ? (this.target[0].index+1) % l : 0; this.target[0].index = ind; this.target[0].proto = getProto(docList(this.source[0].data)[ind]);} - // eslint-disable-next-line react/sort-comp public static EditButtonScript(title: string, doc: Doc, fieldKey: string, clientX: number, clientY: number, contextParams?: { [name: string]: string }, defaultScript?: ScriptField) { let overlayDisposer: () => void = emptyFunction; const script = ScriptCast(doc[fieldKey]) || defaultScript; @@ -119,7 +117,7 @@ export class ScriptBox extends React.Component { onCancel={overlayDisposer} onSave={(text, onError) => { if (!text) { - doc[DocData][fieldKey] = undefined; + doc['$' + fieldKey] = undefined; } else { const compScript = CompileScript(text, { params: { this: Doc.name, ...contextParams }, @@ -142,7 +140,7 @@ export class ScriptBox extends React.Component { div.innerHTML = 'button'; params.length && DragManager.StartButtonDrag([div], text, doc.title + '-instance', {}, params, () => {}, clientX, clientY); - doc[DocData][fieldKey] = new ScriptField(compScript); + doc['$' + fieldKey] = new ScriptField(compScript); overlayDisposer(); } }} diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index e51bc18ef..a45b37f43 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -503,9 +503,8 @@ export class CollectionDockingView extends CollectionSubView() { }); const dashboardDoc = Docs.Create.DockDocument(newtabs, json, { title: incrementTitleCopy(StrCast(doc.title)) }); - dashboardDoc.pane_count = 1; - dashboardDoc.myOverlayDocs = new List(); - dashboardDoc.myPublishedDocs = new List(); + dashboardDoc.$myOverlayDocs = new List(); + dashboardDoc.$myPublishedDocs = new List(); DashboardView.SetupDashboardTrails(); DashboardView.SetupDashboardCalendars(); // Zaul TODO: needed? @@ -555,13 +554,13 @@ export class CollectionDockingView extends CollectionSubView() { stack.header?.element.on('mousedown', (e: MouseEvent) => { const dashboard = Doc.ActiveDashboard; if (dashboard && e.target === stack.header?.element[0] && e.button === 2) { - dashboard.pane_count = NumCast(dashboard.pane_count) + 1; + dashboard.$myPaneCount = NumCast(dashboard.$myPaneCount) + 1; const docToAdd = Docs.Create.FreeformDocument([], { _width: this._props.PanelWidth(), _height: this._props.PanelHeight(), _freeform_backgroundGrid: true, _layout_fitWidth: true, - title: `Untitled Tab ${NumCast(dashboard.pane_count)}`, + title: `Untitled Tab ${NumCast(dashboard.$myPaneCount)}`, }); Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd, undefined, undefined, true); inheritParentAcls(this.Document, docToAdd, false); @@ -572,13 +571,13 @@ export class CollectionDockingView extends CollectionSubView() { const addNewDoc = undoable(() => { const dashboard = Doc.ActiveDashboard; if (dashboard) { - dashboard.pane_count = NumCast(dashboard.pane_count) + 1; + dashboard.$myPaneCount = NumCast(dashboard.$myPaneCount) + 1; const docToAdd = Docs.Create.FreeformDocument([], { _width: this._props.PanelWidth(), _height: this._props.PanelHeight(), _layout_fitWidth: true, _freeform_backgroundGrid: true, - title: `Untitled Tab ${NumCast(dashboard.pane_count)}`, + title: `Untitled Tab ${NumCast(dashboard.$myPaneCount)}`, }); Doc.AddDocToList(Doc.MyHeaderBar, 'data', docToAdd, undefined, undefined, true); inheritParentAcls(this.dataDoc, docToAdd, false); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index cac276535..fdaf13733 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -88,7 +88,7 @@ export interface DocumentViewProps extends FieldViewSharedProps { @observer export class DocumentViewInternal extends DocComponent() { // this makes mobx trace() statements more descriptive - public get displayName() { return 'DocumentViewInternal(' + this.Document.title + ')'; } // prettier-ignore + public get displayName() { return 'DocumentViewInternal(' + this.Document.$title + ')'; } // prettier-ignore public static SelectAfterContextMenu = true; // whether a document should be selected after it's contextmenu is triggered. /** @@ -143,10 +143,10 @@ export class DocumentViewInternal extends DocComponent 0)) stopPropagate = false; preventDefault = false; } - this._singleClickFunc = undoable(clickFunc ?? sendToBack ?? selectFunc, 'click: ' + this.Document.title); + this._singleClickFunc = undoable(clickFunc ?? sendToBack ?? selectFunc, 'click: ' + this.Document.$title); const waitForDblClick = this._props.waitForDoubleClickToClick?.() ?? this.Document.waitForDoubleClickToClick; if ((clickFunc && waitForDblClick !== 'never') || waitForDblClick === 'always') { this._doubleClickTimeout && clearTimeout(this._doubleClickTimeout); @@ -519,7 +519,7 @@ export class DocumentViewInternal extends DocComponent { - if (this.Document.type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && this._props.select(false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. + if (this.Document.$type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && this._props.select(false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear. setTimeout(() => simulateMouseClick(document.elementFromPoint(e.clientX, e.clientY), e.clientX, e.clientY, e.screenX, e.screenY)); }; if (navigator.userAgent.includes('Macintosh')) { @@ -545,7 +545,7 @@ export class DocumentViewInternal extends DocComponent (item.method ? item.method() : item.script?.script.run({ this: this.Document, documentView: this, scriptContext: this._props.scriptContext })), icon: item.icon as IconProp }) ); - if (!this.Document.isFolder) { + if (!this.Document.$isFolder) { const templateDoc = Cast(this.Document[StrCast(this.Document.layout_fieldKey)], Doc, null); const appearance = cm.findByDescription('Appearance...'); const appearanceItems = appearance?.subitems ?? []; @@ -635,7 +635,7 @@ export class DocumentViewInternal extends DocComponent= 1 ? 0 : 1 / (1 + x * (viewXfScale - 1)); - const y = NumCast(this.Document.width) / viewXfScale / 200; + const y = NumCast(this.Document._width) / viewXfScale / 200; const yscale = y >= 1 ? 0 : 1 / (1 + y * viewXfScale - 1); return Math.max(xscale, yscale, 1 / viewXfScale); } @@ -735,7 +735,7 @@ export class DocumentViewInternal extends DocComponent
- {this._componentView?.isUnstyledView?.() || this.Document.type === DocumentType.CONFIG || !renderDoc ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)} + {this._componentView?.isUnstyledView?.() || this.Document.$type === DocumentType.CONFIG || !renderDoc ? renderDoc : DocumentViewInternal.AnimationEffect(renderDoc, this.Document[Animation], this.Document)} {jsx}
); @@ -1210,7 +1210,7 @@ export class DocumentView extends DocComponent() { } @computed private get nativeScaling() { if (this.shouldNotScale) return 1; - const minTextScale = this.Document.type === DocumentType.RTF ? 0.1 : 0; + const minTextScale = this.Document.$type === DocumentType.RTF ? 0.1 : 0; const ai = this._showAIEditor && this.nativeWidth === this.layoutDoc.width ? 95 : 0; const effNW = Math.max(this.effectiveNativeWidth - ai, 1); const effNH = Math.max(this.effectiveNativeHeight - ai, 1); @@ -1325,7 +1325,7 @@ export class DocumentView extends DocComponent() { public startDragging = (x: number, y: number, dropAction: dropActionType | undefined, hideSource = false) => this._docViewInternal?.startDragging(x, y, dropAction, hideSource); public showContextMenu = (pageX: number, pageY: number) => this._docViewInternal?.onContextMenu(undefined, pageX, pageY); - public toggleNativeDimensions = () => this._docViewInternal && this.Document.type !== DocumentType.INK && Doc.toggleNativeDimensions(this.layoutDoc, this.NativeDimScaling() ?? 1, this._props.PanelWidth(), this._props.PanelHeight()); + public toggleNativeDimensions = () => this._docViewInternal && this.Document.$type !== DocumentType.INK && Doc.toggleNativeDimensions(this.layoutDoc, this.NativeDimScaling() ?? 1, this._props.PanelWidth(), this._props.PanelHeight()); public iconify(finished?: () => void, animateTime?: number) { this.ComponentView?.updateIcon?.(); diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 40c687b7e..9795febbe 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -54,16 +54,12 @@ export class KeyValueBox extends ViewBoxBaseComponent() { @observable private rows: KeyValuePair[] = []; @observable _splitPercentage = 50; - get fieldDocToLayout() { - return DocCast(this.Document); - } - @action onEnterKey = (e: React.KeyboardEvent): void => { if (e.key === 'Enter') { e.stopPropagation(); - if (this._keyInput.current?.value && this._valInput.current?.value && this.fieldDocToLayout) { - if (KeyValueBox.SetField(this.fieldDocToLayout, this._keyInput.current.value, this._valInput.current.value)) { + if (this._keyInput.current?.value && this._valInput.current?.value && this._props.Document) { + if (KeyValueBox.SetField(this._props.Document, this._keyInput.current.value, this._valInput.current.value)) { this._keyInput.current.value = ''; this._valInput.current.value = ''; document.body.focus(); @@ -114,7 +110,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { if (key) target[key] = script.originalScript; return false; } - field === undefined && (field = res.result instanceof Array ? new List(res.result) : (typeof res.result === 'function' ? res.result.name : res.result as FieldType)); + field === undefined && (field = res.result instanceof Array ? new List(res.result) : typeof res.result === 'function' ? res.result.name : (res.result as FieldType)); } } if (!key) return false; @@ -141,7 +137,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { rowHeight = () => 30; @computed get createTable() { - const doc = this.fieldDocToLayout; + const doc = this._props.Document; if (!doc) { return ( @@ -149,25 +145,35 @@ export class KeyValueBox extends ViewBoxBaseComponent() { ); } - const realDoc = doc; const ids: { [key: string]: string } = {}; const protos = Doc.GetAllPrototypes(doc); protos.forEach(proto => { Object.keys(proto).forEach(key => { - if (!(key in ids) && realDoc[key] !== ComputedField.undefined) { + if (!(key in ids) && doc[key] !== ComputedField.undefined) { ids[key] = key; } }); }); + const layoutProtos = Doc.GetAllPrototypes(this.layoutDoc); + layoutProtos.forEach(proto => { + Object.keys(proto) + .map(key => '_' + key) + .forEach(key => { + if (!(key.replace(/^_/, '') in ids) && doc[key] !== ComputedField.undefined) { + ids[key] = key; + } + }); + }); + const rows: JSX.Element[] = []; let i = 0; const keys = Object.keys(ids).slice(); // for (const key of [...keys.filter(id => id !== 'layout' && !id.includes('_')).sort(), ...keys.filter(id => id === 'layout' || id.includes('_')).sort()]) { const sortedKeys = keys.sort((a: string, b: string) => { - const a_ = a.split('_')[0]; - const b_ = b.split('_')[0]; + const a_ = a.replace(/^_/, '').split('_')[0]; + const b_ = b.replace(/^_/, '').split('_')[0]; if (a_ < b_) return -1; if (a_ > b_) return 1; if (a === a_) return -1; @@ -177,7 +183,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { sortedKeys.forEach(key => { rows.push( () { openItems.push({ description: 'Default Perspective', event: () => { - this._props.addDocTab(this.Document, OpenWhere.close); - this._props.addDocTab(this.fieldDocToLayout, OpenWhere.addRight); + this._props.addDocTab(this._props.Document, OpenWhere.close); + this._props.addDocTab(this._props.Document, OpenWhere.addRight); }, icon: 'image', }); diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 85aff04c3..93f5231cb 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -61,17 +61,18 @@ export class KeyValuePair extends ObservableReactComponent { render() { // let fieldKey = Object.keys(props.Document).indexOf(props.fieldKey) !== -1 ? props.fieldKey : "(" + props.fieldKey + ")"; - let protoCount = 0; - let { doc } = this._props; + const layoutField = this._props.keyName.startsWith('_'); + let doc = layoutField ? Doc.Layout(this._props.doc) : this._props.doc; + let protoCount = doc !== this._props.doc && !layoutField ? 1 : 0; while (doc) { - if (Object.keys(doc).includes(this._props.keyName)) { + if (Object.keys(doc).includes(this._props.keyName.replace(/^_/, ''))) { break; } protoCount++; doc = DocCast(doc.proto); } - const parenCount = Math.max(0, protoCount - 1); - const keyStyle = protoCount === 0 ? 'black' : 'blue'; + const parenCount = Math.max(0, protoCount); + const keyStyle = protoCount === 0 && doc === this._props.doc ? 'black' : 'blue'; const hover = { transition: '0.3s ease opacity', opacity: this.isPointerOver || this.isChecked ? 1 : 0 }; @@ -99,10 +100,9 @@ export class KeyValuePair extends ObservableReactComponent { pair[0].replace(/^_/, '') === this._props.keyName)?.[1].description ?? ''}> -
- {'('.repeat(parenCount)} - {this._props.keyName} - {')'.repeat(parenCount)} +
+ {(layoutField ? '_' : '$').repeat(parenCount)} + {(keyStyle === 'blue' && !layoutField && !parenCount ? '$' : '') + this._props.keyName}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index b84575389..9078648e9 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -245,9 +245,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent void = emptyFunction; - const targetData = target[DocData]; - targetData.mediaState = mediaState.Recording; - DictationManager.recordAudioAnnotation(targetData, Doc.LayoutFieldKey(target), stop => { stopFunc = stop }); // prettier-ignore + target.$mediaState = mediaState.Recording; + DictationManager.recordAudioAnnotation(target[DocData], Doc.LayoutFieldKey(target), stop => { stopFunc = stop }); // prettier-ignore const reactionDisposer = reaction( () => target.mediaState, @@ -1067,7 +1066,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent::$/, (state, match, start, end) => { const creator = (doc: Doc) => { - const textDoc = this.Document[DocData]; - const numInlines = NumCast(textDoc.inlineTextCount); - textDoc.inlineTextCount = numInlines + 1; + const numInlines = NumCast(this.Document.$inlineTextCount); + this.Document.$inlineTextCount = numInlines + 1; const node = state.doc.resolve(start).nodeAfter; const newNode = schema.nodes.dashComment.create({ docId: doc[Id], reflow: false }); const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docId: doc[Id], float: 'right' }); @@ -109,16 +108,15 @@ export class RichTextRules { }), // Create annotation to a field on the text document new InputRule(/>>$/, (state, match, start, end) => { - const textDoc = this.Document[DocData]; - const numInlines = NumCast(textDoc.inlineTextCount); - textDoc.inlineTextCount = numInlines + 1; - const inlineFieldKey = 'inline' + numInlines; // which field on the text document this annotation will write to - const inlineLayoutKey = 'layout_' + inlineFieldKey; // the field holding the layout string that will render the inline annotation + const numInlines = NumCast(this.Document.$inlineTextCount); + this.Document.$inlineTextCount = numInlines + 1; + const inlineFieldKey = '$inline' + numInlines; // which field on the text document this annotation will write to + const inlineLayoutKey = '$layout_' + inlineFieldKey; // the field holding the layout string that will render the inline annotation const textDocInline = Docs.Create.TextDocument('', { _layout_fieldKey: inlineLayoutKey, _width: 75, _height: 35, - annotationOn: textDoc, + annotationOn: this.Document[DocData], _layout_fitWidth: true, _layout_autoHeight: true, text_fontSize: '9px', @@ -128,9 +126,9 @@ export class RichTextRules { textDocInline.title_custom = true; // And make sure that it's 'custom' so that editing text doesn't change the title of the containing doc textDocInline.isTemplateForField = inlineFieldKey; // this is needed in case the containing text doc is converted to a template at some point textDocInline.isDataDoc = true; - textDocInline.proto = textDoc; // make the annotation inherit from the outer text doc so that it can resolve any nested field references, e.g., [[field]] - textDoc[inlineLayoutKey] = FormattedTextBox.LayoutString(inlineFieldKey); // create a layout string for the layout key that will render the annotation text - textDoc[inlineFieldKey] = ''; // set a default value for the annotation + textDocInline.proto = this.Document[DocData]; // make the annotation inherit from the outer text doc so that it can resolve any nested field references, e.g., [[field]] + this.Document[inlineLayoutKey] = FormattedTextBox.LayoutString(inlineFieldKey); // create a layout string for the layout key that will render the annotation text + this.Document[inlineFieldKey] = ''; // set a default value for the annotation const node = state.doc.resolve(start).nodeAfter; const newNode = schema.nodes.dashComment.create({ docId: textDocInline[Id], reflow: true }); const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: 'dashDoc', docId: textDocInline[Id], float: 'right' }); @@ -334,18 +332,14 @@ export class RichTextRules { if (value?.includes(',') && !value.startsWith('((')) { const values = value.split(','); const strs = values.some(v => !v.match(/^[-]?[0-9.]$/)); - this.Document[DocData][fieldKey] = strs ? new List(values) : new List(values.map(v => Number(v))); + this.Document['$' + fieldKey] = strs ? new List(values) : new List(values.map(v => Number(v))); } else if (value) { Doc.SetField( this.Document, fieldKey, assign + value, Doc.IsDataProto(this.Document) ? true : undefined, - assign.includes(':=') - ? undefined - : (gptval: FieldResult) => { - (dataDoc ? this.Document[DocData] : this.Document)[fieldKey] = gptval as string; - } + assign.includes(':=') ? undefined : (gptval: FieldResult) => (this.Document[(dataDoc ? '$' : '_') + fieldKey] = gptval as string) ); if (fieldKey === this.TextBox.fieldKey) return this.TextBox.EditorView!.state.tr; } @@ -399,11 +393,11 @@ export class RichTextRules { new InputRule(/#(@?[a-zA-Z_-]+[a-zA-Z_\-0-9]*)\s$/, (state, match, start, end) => { const tag = match[1]; if (!tag) return state.tr; - // this.Document[DocData]['#' + tag] = '#' + tag; - const tags = StrListCast(this.Document[DocData].tags); + // this.Document[['$#' + tag] = '#' + tag; + const tags = StrListCast(this.Document.$tags); if (!tags.includes(tag)) { tags.push(tag); - this.Document[DocData].tags = new List(tags); + this.Document.$tags = new List(tags); this.Document._layout_showTags = true; } const fieldView = state.schema.nodes.dashField.create({ fieldKey: tag.startsWith('@') ? tag.replace(/^@/, '') : '#' + tag }); diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index f818c6e20..ec97e067a 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -596,11 +596,11 @@ export class PresBox extends ViewBoxBaseComponent() { } if (pinDataTypes?.inkable || (!pinDataTypes && (activeItem.config_fillColor !== undefined || activeItem.color !== undefined))) { if (bestTarget.fillColor !== activeItem.config_fillColor) { - bestTarget[DocData].fillColor = StrCast(activeItem.config_fillColor, StrCast(bestTarget.fillColor)); + bestTarget.$fillColor = StrCast(activeItem.config_fillColor, StrCast(bestTarget.fillColor)); changed = true; } if (bestTarget.color !== activeItem.config_color) { - bestTarget[DocData].color = StrCast(activeItem.config_color, StrCast(bestTarget.color)); + bestTarget.$color = StrCast(activeItem.config_color, StrCast(bestTarget.color)); changed = true; } if (bestTarget.width !== activeItem.width) { @@ -669,7 +669,7 @@ export class PresBox extends ViewBoxBaseComponent() { return doc; }); const newList = new List([...oldItems, ...hiddenItems, ...newItems]); - bestTarget[DocData][fkey + '_annotations'] = newList; + bestTarget['$' + fkey + '_annotations'] = newList; } if (pinDataTypes?.poslayoutview || (!pinDataTypes && activeItem.config_pinLayoutData !== undefined)) { changed = true; @@ -690,8 +690,8 @@ export class PresBox extends ViewBoxBaseComponent() { data.fill && (doc._fillColor = data.fill); doc._width = data.w; doc._height = data.h; - data.data && (doc[DocData].data = field); - data.text && (doc[DocData].text = tfield); + data.data && (doc.$data = field); + data.text && (doc.$text = tfield); Doc.AddDocToList(bestTarget[DocData], layoutField, doc); } }); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index dc7524bcd..2142adac8 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -431,7 +431,7 @@ export class PDFViewer extends ObservableReactComponent { }; addDrawingAnnotation = (drawing: Doc) => { - // drawing[DocData].x = this._props.pdfBox.ScreenToLocalBoxXf().TranslateX + // drawing.x = this._props.pdfBox.ScreenToLocalBoxXf().TranslateX // const scaleX = this._mainCont.current.offsetWidth / boundingRect.width; drawing.y = NumCast(drawing.y) + NumCast(this._props.Document.layout_scrollTop); this._props.addDocument?.(drawing); diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 6f70e96ab..841546a04 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -66,7 +66,7 @@ export class FaceRecognitionHandler { * returns a list of all face collection Docs on the current dashboard * @returns face collection Doc list */ - public static UniqueFaces = () => DocListCast(Doc.ActiveDashboard?.[DocData].myUniqueFaces); + public static UniqueFaces = () => DocListCast(Doc.ActiveDashboard?.$myUniqueFaces); /** * Find a unique face from its name @@ -87,22 +87,22 @@ export class FaceRecognitionHandler { * @param faceDoc unique face Doc * @returns label string */ - public static UniqueFaceLabel = (faceDoc: Doc) => StrCast(faceDoc[DocData].face); + public static UniqueFaceLabel = (faceDoc: Doc) => StrCast(faceDoc.$face); - public static SetUniqueFaceLabel = (faceDoc: Doc, value: string) => (faceDoc[DocData].face = value); + public static SetUniqueFaceLabel = (faceDoc: Doc, value: string) => (faceDoc.$face = value); /** * Returns all the face descriptors associated with a unique face Doc * @param faceDoc unique face Doc * @returns face descriptors */ - public static UniqueFaceDescriptors = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_annos).map(face => face.faceDescriptor as List); + public static UniqueFaceDescriptors = (faceDoc: Doc) => DocListCast(faceDoc.$face_annos).map(face => face.faceDescriptor as List); /** * Returns a list of all face image Docs associated with a unique face Doc * @param faceDoc unique face Doc * @returns image Docs */ - public static UniqueFaceImages = (faceDoc: Doc) => DocListCast(faceDoc[DocData].face_annos).map(face => DocCast(face.annotationOn, face)); + public static UniqueFaceImages = (faceDoc: Doc) => DocListCast(faceDoc.$face_annos).map(face => DocCast(face.annotationOn, face)); /** * Adds a face image to a unique face Doc, adds the unique face Doc to the images list of reognized faces, @@ -145,8 +145,8 @@ export class FaceRecognitionHandler { * @returns a unique face Doc */ private createUniqueFaceDoc = (dashboard: Doc) => { - const faceDocNum = NumCast(dashboard[DocData].myUniqueFaces_count) + 1; - dashboard[DocData].myUniqueFaces_count = faceDocNum; // TODO: improve to a better name + const faceDocNum = NumCast(dashboard.$myUniqueFaces_count) + 1; + dashboard.$myUniqueFaces_count = faceDocNum; // TODO: improve to a better name const uniqueFaceDoc = Docs.Create.UniqeFaceDocument({ title: ComputedField.MakeFunction('this.face', undefined, undefined, 'this.face = value') as unknown as string, @@ -160,9 +160,8 @@ export class FaceRecognitionHandler { _width: 400, _height: 100, }); - const uface = uniqueFaceDoc[DocData]; - uface.face = `Face${faceDocNum}`; - uface.face_annos = new List(); + uniqueFaceDoc.$face = `Face${faceDocNum}`; + uniqueFaceDoc.$face_annos = new List(); Doc.SetContainer(uniqueFaceDoc, Doc.MyFaceCollection); Doc.ActiveDashboard && Doc.AddDocToList(Doc.ActiveDashboard[DocData], 'myUniqueFaces', uniqueFaceDoc); @@ -241,7 +240,7 @@ export class FaceRecognitionHandler { annos.push(faceAnno); }); - imgDoc[DocData].data_annotations = new List(annos); + imgDoc.$data_annotations = new List(annos); imgDoc._layout_showTags = annos.length > 0; return imgDocFaceDescriptions; }) diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index af98355d1..8b7e77fba 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -465,7 +465,6 @@ export class SearchBox extends ViewBoxBaseComponent() { } }); - // eslint-disable-next-line react/jsx-props-no-spreading const recommendationsJSX: JSX.Element[] = []; // this._recommendations.map(props => ); return ( diff --git a/src/client/views/smartdraw/DrawingFillHandler.tsx b/src/client/views/smartdraw/DrawingFillHandler.tsx index c672bc718..f1d5f2cfe 100644 --- a/src/client/views/smartdraw/DrawingFillHandler.tsx +++ b/src/client/views/smartdraw/DrawingFillHandler.tsx @@ -1,6 +1,5 @@ import { imageUrlToBase64 } from '../../../ClientUtils'; import { Doc, StrListCast } from '../../../fields/Doc'; -import { DocData } from '../../../fields/DocSymbols'; import { List } from '../../../fields/List'; import { DocCast, ImageCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; @@ -15,8 +14,7 @@ import { AspectRatioLimits, FireflyDimensionsMap, FireflyImageDimensions, Firefl const DashDropboxId = '2m86iveqdr9vzsa'; export class DrawingFillHandler { static drawingToImage = async (drawing: Doc, strength: number, user_prompt: string, styleDoc?: Doc) => { - const docData = drawing[DocData]; - const tags = StrListCast(docData.tags).map(tag => tag.slice(1)); + const tags = StrListCast(drawing.$tags).map(tag => tag.slice(1)); const styles = tags.filter(tag => FireflyStylePresets.has(tag)); const styleDocs = !Doc.Links(drawing).length ? styleDoc && !tags.length @@ -47,7 +45,7 @@ export class DrawingFillHandler { Networking.PostToServer('/queryFireflyImageFromStructure', { prompt: `${newPrompt}`, width: dims.width, height: dims.height, structureUrl, strength, presets: styles, styleUrl }) .then(res => { const genratedDocs = DocCast(drawing.ai_firefly_generatedDocs) ?? Docs.Create.MasonryDocument([], { _width: 400, _height: 400 }); - drawing[DocData].ai_firefly_generatedDocs = genratedDocs; + drawing.$ai_firefly_generatedDocs = genratedDocs; (res as Upload.ImageInformation[]).map(info => Doc.AddDocToList( genratedDocs, diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index fc89dcbe7..f5bd4f44c 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -320,10 +320,11 @@ export class Doc extends RefField { UpdatingFromServer, Width, '__LAYOUT__', + '__DATA__', ]; }, getOwnPropertyDescriptor: (target, prop) => { - if (prop.toString() === '__LAYOUT__' || !(prop in target[FieldKeys])) { + if (prop.toString() === '__DATA__' || prop.toString() === '__LAYOUT__' || !(prop in target[FieldKeys])) { return Reflect.getOwnPropertyDescriptor(target, prop); } return { @@ -400,6 +401,9 @@ export class Doc extends RefField { public [ToString] = () => `Doc(${GetEffectiveAcl(this[SelfProxy]) === AclPrivate ? '-inaccessible-' : this[SelfProxy].title})`; public get [DocLayout]() { return this[SelfProxy].__LAYOUT__; } // prettier-ignore public get [DocData](): Doc { + return this[SelfProxy].__DATA__; + } + @computed get __DATA__(): Doc { const self = this[SelfProxy]; return self.resolvedDataDoc && !self.isTemplateForField ? self : Doc.GetProto(Cast(Doc.Layout(self).resolvedDataDoc, Doc, null) || self); } @@ -414,7 +418,7 @@ export class Doc extends RefField { } else { return Cast(layoutField, Doc, null); } - return Cast(self[renderFieldKey + '_layout[' + templateLayoutDoc[Id] + ']'], Doc, null) || templateLayoutDoc; + return Cast(self['layout_' + templateLayoutDoc.title + '(' + renderFieldKey + ')'], Doc, null) || templateLayoutDoc; } return undefined; } @@ -865,7 +869,7 @@ export namespace Doc { // If it doesn't find the expanded layout, then it makes a delegate of the template layout and // saves it on the data doc indexed by the template layout's id. // - const expandedLayoutFieldKey = templateField + '_layout[' + templateLayoutDoc[Id] + ']'; + const expandedLayoutFieldKey = 'layout_' + templateLayoutDoc.title + '(' + templateField + ')'; let expandedTemplateLayout = targetDoc?.[expandedLayoutFieldKey]; if (templateLayoutDoc.resolvedDataDoc instanceof Promise) { @@ -1152,7 +1156,9 @@ export namespace Doc { // the document containing the view layout information - will be the Document itself unless the Document has // a layout field or 'layout' is given. export function Layout(doc: Doc, layout?: Doc): Doc { - const overrideLayout = layout && Cast(doc[`${StrCast(layout.isTemplateForField, 'data')}_layout[` + layout[Id] + ']'], Doc, null); + const templateField = layout && StrCast(layout.isTemplateForField, Doc.LayoutFieldKey(layout)); // the field that the template renders + const overrideLayout = layout && Cast(doc[layout.title + '(' + templateField + ')'], Doc, null); + // [`${StrCast(layout.isTemplateForField, 'data')}_layout[` + layout[Id] + ']'], Doc, null); return overrideLayout || doc[DocLayout] || doc; } export function SetLayout(doc: Doc, layout: Doc | string) { diff --git a/src/fields/util.ts b/src/fields/util.ts index 33764aca5..abbe543e8 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -314,6 +314,13 @@ export function setter(target: ListImpl | Doc, inProp: string | symbo // if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't if (typeof prop === 'string' && prop.startsWith('acl_') && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined].includes(value as SharingPermissions))) return true; + if (typeof prop === 'string' && prop !== '__id' && prop !== '__fieldTuples' && prop.startsWith('$')) { + prop = prop.substring(1); + if (target.__DATA__ instanceof Doc) { + target.__DATA__[prop] = value as FieldResult; + return true; + } + } if (typeof prop === 'string' && prop !== '__id' && prop !== '__fieldTuples' && prop.startsWith('_')) { if (!prop.startsWith('__')) prop = prop.substring(1); if (target.__LAYOUT__ instanceof Doc) { @@ -351,6 +358,7 @@ export function getter(target: Doc | ListImpl, prop: string | symbol, case DocAcl : return target[DocAcl]; case $mobx: return target.__fieldTuples[prop]; case DocLayout: return target.__LAYOUT__; + case DocData: return target.__DATA__; case Height: case Width: if (GetEffectiveAcl(target) === AclPrivate) return returnZero; // eslint-disable-next-line no-fallthrough default : @@ -362,6 +370,8 @@ export function getter(target: Doc | ListImpl, prop: string | symbol, const layoutProp = prop.startsWith('_') ? prop.substring(1) : undefined; if (layoutProp && target.__LAYOUT__) return (target.__LAYOUT__ as Doc)[layoutProp]; + const dataProp = prop.startsWith('$') ? prop.substring(1) : undefined; + if (dataProp && target.__DATA__) return (target.__DATA__ as Doc)[dataProp]; return getFieldImpl(target, layoutProp ?? prop, proxy); } -- cgit v1.2.3-70-g09d2 From 705975eb43e7904c62e7e847478f6d0dac60d443 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sun, 23 Mar 2025 18:14:31 -0400 Subject: more _props.Document to .Document refactoring. type updates to prosemirrortransfer --- src/client/util/SharingManager.tsx | 2 +- src/client/views/DocComponent.tsx | 85 +++++++--- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/FieldsDropdown.tsx | 4 +- src/client/views/FilterPanel.tsx | 4 +- src/client/views/LightboxView.tsx | 2 +- src/client/views/SidebarAnnos.tsx | 24 +-- src/client/views/TemplateMenu.tsx | 1 - src/client/views/animationtimeline/Timeline.tsx | 56 +++---- .../collections/CollectionMasonryViewFieldRow.tsx | 8 +- .../views/collections/CollectionNoteTakingView.tsx | 15 +- .../collections/CollectionNoteTakingViewColumn.tsx | 18 +-- .../views/collections/CollectionPivotView.tsx | 2 +- .../views/collections/CollectionStackingView.tsx | 19 +-- .../CollectionStackingViewFieldColumn.tsx | 28 ++-- src/client/views/collections/CollectionSubView.tsx | 10 +- .../views/collections/CollectionTimeView.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 4 +- src/client/views/collections/TabDocView.tsx | 28 ++-- .../CollectionFreeFormInfoUI.tsx | 14 +- .../CollectionFreeFormPannableContents.tsx | 4 +- .../CollectionFreeFormRemoteCursors.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 48 +++--- .../collections/collectionFreeForm/MarqueeView.tsx | 1 + .../collectionSchema/SchemaCellField.tsx | 4 +- .../collections/collectionSchema/SchemaRowBox.tsx | 2 +- .../collectionSchema/SchemaTableCell.tsx | 46 +++--- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/DataVizBox/DataVizBox.tsx | 30 ++-- .../nodes/DataVizBox/components/Histogram.tsx | 13 +- .../nodes/DataVizBox/components/LineChart.tsx | 8 +- .../views/nodes/DataVizBox/components/PieChart.tsx | 16 +- .../views/nodes/DataVizBox/components/TableBox.tsx | 10 +- src/client/views/nodes/DocumentView.tsx | 4 +- src/client/views/nodes/FieldView.tsx | 4 +- src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/KeyValueBox.tsx | 10 +- src/client/views/nodes/MapBox/MapBox.tsx | 2 +- .../views/nodes/MapboxMapBox/MapboxContainer.tsx | 3 +- src/client/views/nodes/PDFBox.tsx | 3 +- src/client/views/nodes/ScreenshotBox.tsx | 2 - src/client/views/nodes/WebBox.tsx | 2 +- .../views/nodes/formattedText/DashFieldView.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 10 +- .../formattedText/ProsemirrorExampleTransfer.ts | 174 +++++++++++---------- .../views/nodes/formattedText/SummaryView.tsx | 46 +++--- src/client/views/pdf/PDFViewer.tsx | 30 ++-- src/client/views/search/SearchBox.tsx | 16 +- src/client/views/smartdraw/StickerPalette.tsx | 16 +- src/fields/RichTextUtils.ts | 3 +- src/fields/Types.ts | 5 - src/server/DashSession/DashSessionAgent.ts | 4 +- 52 files changed, 438 insertions(+), 414 deletions(-) (limited to 'src/client/views/pdf') diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 3a248400b..962f51cd4 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -633,7 +633,7 @@ export class SharingManager extends React.Component { private focusOn = (contents: string) => { const title = this.targetDoc ? StrCast(this.targetDoc.title) : ''; - const docs = DocumentView.Selected().length > 1 ? DocumentView.Selected().map(docView => docView.props.Document) : [this.targetDoc]; + const docs = DocumentView.Selected().length > 1 ? DocumentView.Selected().map(docView => docView.Document) : [this.targetDoc]; return ( () { } /** - * This is the document being rendered. In the case of a compound template, it - * may not be the actual document rendered and it also may not be the 'real' root document. - * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,) + * This is the doc that is being rendered. It will be either: + * 1) the same as Document if the root of a regular or compound Doc is rendered + * 2) the same as the layoutDoc if a component of a compound Doc is rendered. + * NOTE: it is very unlikely that you really want to use this method. Instead + * consider: Document, layoutDoc, dataDoc */ - get Document() { - return DocCast(this._props.Document.rootDocument, this._props.Document); + get _renderDoc() { + return this._props.Document; } /** - * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. + * This is the "root" Doc being rendered. In the case of a compound template Doc, + * this is the outermost Doc that represents the entire compound Doc. It is not + * necessarily the Doc being rendered in the current React component. + * This Doc inherits from the dataDoc, and may or may not inherit (or be) the layoutDoc. + */ + get Document() { + return DocCast(this._renderDoc.rootDocument, this._renderDoc); + } + /** + * This is the document being rendered by the React component. In the + * case of a compound template, this will be the expanded template Doc + * that represents the component of the compound Doc being rendered. + * This may or may not inherit from the data doc. */ @computed get layoutDoc() { - return this._props.LayoutTemplateString ? this._props.Document : Doc.Layout(this._props.Document, this._props.LayoutTemplate?.()); + return this._props.LayoutTemplateString ? this._renderDoc : Doc.Layout(this._renderDoc, this._props.LayoutTemplate?.()); } /** - * This is the unique data repository for a dcoument that stores the intrinsic document data + * This is the unique data repository for a document that stores the intrinsic document data. */ @computed get dataDoc() { - return this._props.Document[DocData]; + return this._renderDoc[DocData]; } } return Component; @@ -75,25 +89,40 @@ export function ViewBoxBaseComponent

() { } /** - * This is the document being rendered. In the case of a compound template, it - * may not be the actual document rendered and it also may not be the 'real' root document. - * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,) + * This is the doc that is being rendered. It will be either: + * 1) the same as Document if the root of a regular or compound Doc is rendered + * 2) the same as the layoutDoc if a component of a compound Doc is rendered. + * NOTE: it is very unlikely that you really want to use this method. Instead + * consider: Document, layoutDoc, dataDoc + */ + get _renderDoc() { + return this._props.Document; + } + + /** + * This is the "root" Doc being rendered. In the case of a compound template Doc, + * this is the outermost Doc that represents the entire compound Doc. It is not + * necessarily the Doc being rendered in the current React component. + * This Doc inherits from the dataDoc, and may or may not inherit (or be) the layoutDoc. */ get Document() { - return DocCast(this._props.Document.rootDocument, this._props.Document); + return DocCast(this._renderDoc.rootDocument, this._renderDoc); } /** - * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. + * This is the document being rendered by the React component. In the + * case of a compound template, this will be the expanded template Doc + * that represents the component of the compound Doc being rendered. + * This may or may not inherit from the data doc. */ @computed get layoutDoc() { - return Doc.Layout(this._props.Document); + return Doc.Layout(this._renderDoc); } /** * This is the unique data repository for a dcoument that stores the intrinsic document data */ @computed get dataDoc() { - return this._props.Document.isTemplateForField || this._props.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._props.Document[DocData]) : this._props.Document[DocData]; + return this._renderDoc.isTemplateForField || this._renderDoc.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._renderDoc[DocData]) : this._renderDoc[DocData]; } /** @@ -133,25 +162,37 @@ export function ViewBoxAnnotatableComponent

() { } /** - * This is the document being rendered. In the case of a compound template, it - * may not be the actual document rendered and it also may not be the 'real' root document. - * Rather, it specifies the shared properties of all layouts of the document (eg, x,y,) + * This is the doc that is being rendered. It will be either: + * 1) the same as Document if the root of a regular or compound Doc is rendered + * 2) the same as the layoutDoc if a component of a compound Doc is rendered. + * NOTE: it would unlikely that you really want to use this instead of the + * other Doc options (Document, layoutDoc, dataDoc) + */ + get _renderDoc() { + return this._props.Document; + } + + /** + * This is the "root" Doc being rendered. In the case of a compound template Doc, + * this is the outermost Doc that represents the entire compound Doc. It is not + * necessarily the Doc being rendered in the current React component. + * This Doc inherits from the dataDoc, and may or may not inherit (or be) the layoutDoc. */ @computed get Document() { - return DocCast(this._props.Document.rootDocument, this._props.Document); + return DocCast(this._renderDoc.rootDocument, this._renderDoc); } /** * This is the document being rendered. It may be a template so it may or may no inherit from the data doc. */ @computed get layoutDoc() { - return Doc.Layout(this._props.Document); + return Doc.Layout(this._renderDoc); } /** * This is the unique data repository for a dcoument that stores the intrinsic document data */ @computed get dataDoc() { - return this._props.Document.isTemplateForField || this._props.Document.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._props.Document[DocData]) : this._props.Document[DocData]; + return this._renderDoc.isTemplateForField || this._renderDoc.isTemplateDoc ? (this._props.TemplateDataDocument ?? this._renderDoc[DocData]) : this._props.Document[DocData]; } /** diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 92b4d6fbf..19b987cb5 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -635,7 +635,7 @@ export class DocumentDecorations extends ObservableReactComponent void; menuClose?: () => void; placeholder?: string | (() => string); @@ -36,7 +36,7 @@ export class FieldsDropdown extends ObservableReactComponent(); - SearchUtil.foreachRecursiveDoc([this._props.Document], (depth, doc) => allDocs.add(doc)); + SearchUtil.foreachRecursiveDoc([this._props.Doc], (depth, doc) => allDocs.add(doc)); return Array.from(allDocs); } diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index 4fc8d7a68..c3b3f9d0c 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -379,7 +379,7 @@ export class FilterPanel extends ObservableReactComponent {

- +
{/* THE FOLLOWING CODE SHOULD BE DEVELOPER FOR BOOLEAN EXPRESSION (AND / OR) */} {/*
@@ -443,7 +443,7 @@ export class FilterPanel extends ObservableReactComponent {
- +
diff --git a/src/client/views/LightboxView.tsx b/src/client/views/LightboxView.tsx index 5698da785..de2c7cd09 100644 --- a/src/client/views/LightboxView.tsx +++ b/src/client/views/LightboxView.tsx @@ -317,7 +317,7 @@ export class LightboxView extends ObservableReactComponent {
- {this._showPalette && (this._annoPaletteView = r)} Document={DocCast(Doc.UserDoc().myLightboxDrawings)} />} + {this._showPalette && (this._annoPaletteView = r)} Doc={DocCast(Doc.UserDoc().myLightboxDrawings)} />} {this.renderNavBtn(0, undefined, this._props.PanelHeight / 2 - 12.5, 'chevron-left', this._doc && this._history.length ? true : false, this.previous)} {this.renderNavBtn( this._props.PanelWidth - Math.min(this._props.PanelWidth / 4, this._props.maxBorder[0]), diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index b3f3a4478..3c0611f03 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -22,7 +22,7 @@ import { FieldViewProps } from './nodes/FieldView'; interface ExtraProps { fieldKey: string; - Document: Doc; + Doc: Doc; layoutDoc: Doc; dataDoc: Doc; // usePanelWidth: boolean; @@ -45,7 +45,7 @@ export class SidebarAnnos extends ObservableReactComponent(); @computed get allMetadata() { const keys = new Map>(); - DocListCast(this._props.Document[this.sidebarKey]).forEach(doc => + DocListCast(this._props.Doc[this.sidebarKey]).forEach(doc => SearchUtil.documentKeys(doc) .filter(key => key[0] && key[0] !== '_' && key[0] === key[0].toUpperCase()) .map(key => keys.set(key, doc[key])) @@ -54,7 +54,7 @@ export class SidebarAnnos extends ObservableReactComponent(); - DocListCast(this._props.Document[this.sidebarKey]).forEach(doc => StrListCast(doc.tags).forEach(tag => keys.add(tag))); + DocListCast(this._props.Doc[this.sidebarKey]).forEach(doc => StrListCast(doc.tags).forEach(tag => keys.add(tag))); return Array.from(keys.keys()) .filter(key => key[0]) .filter(key => !key.startsWith('_') && (key[0] === '#' || key[0] === key[0].toUpperCase())) @@ -62,7 +62,7 @@ export class SidebarAnnos extends ObservableReactComponent(); - DocListCast(this._props.Document[this.sidebarKey]).forEach(doc => keys.add(StrCast(doc.author))); + DocListCast(this._props.Doc[this.sidebarKey]).forEach(doc => keys.add(StrCast(doc.author))); return Array.from(keys.keys()).sort(); } @@ -72,7 +72,7 @@ export class SidebarAnnos extends ObservableReactComponent data.split(':')[0]) .filter(data => !filterExlusions?.includes(data.split(':')[0])) .map(data => { - const key = '$'+data.split(':')[0]; + const key = '$' + data.split(':')[0]; const val = Field.Copy(this.allMetadata.get(key)); target[key] = val; return { @@ -148,7 +148,7 @@ export class SidebarAnnos extends ObservableReactComponent { - if (DocListCast(this._props.Document[this.sidebarKey]).find(anno => Doc.AreProtosEqual(doc.layout_unrendered ? DocCast(doc.annotationOn) : doc, anno))) { + if (DocListCast(this._props.Doc[this.sidebarKey]).find(anno => Doc.AreProtosEqual(doc.layout_unrendered ? DocCast(doc.annotationOn) : doc, anno))) { if (this.childFilters()) { // if any child filters exist, get rid of them this._props.layoutDoc._childFilters = new List(); @@ -189,7 +189,7 @@ export class SidebarAnnos extends ObservableReactComponent { const active = this.childFilters().includes(`tags${Doc.FilterSep}${tag}${Doc.FilterSep}check`); return ( -
Doc.setDocFilter(this._props.Document, 'tags', tag, 'check', true, undefined, e.shiftKey)}> +
Doc.setDocFilter(this._props.Doc, 'tags', tag, 'check', true, undefined, e.shiftKey)}> {tag}
); @@ -197,7 +197,7 @@ export class SidebarAnnos extends ObservableReactComponent { const active = this.childFilters().includes(`${tag}${Doc.FilterSep}${Doc.FilterAny}${Doc.FilterSep}exists`); return ( -
Doc.setDocFilter(this._props.Document, tag, Doc.FilterAny, 'exists', true, undefined, e.shiftKey)}> +
Doc.setDocFilter(this._props.Doc, tag, Doc.FilterAny, 'exists', true, undefined, e.shiftKey)}> {tag}
); @@ -205,7 +205,7 @@ export class SidebarAnnos extends ObservableReactComponent { const active = this.childFilters().includes(`author:${user}:check`); return ( -
Doc.setDocFilter(this._props.Document, 'author', user, 'check', true, undefined, e.shiftKey)}> +
Doc.setDocFilter(this._props.Doc, 'author', user, 'check', true, undefined, e.shiftKey)}> {user}
); @@ -216,9 +216,9 @@ export class SidebarAnnos extends ObservableReactComponent diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 680c8ed0e..1266a11c1 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -80,7 +80,6 @@ export class TemplateMenu extends React.Component { const addedTypes = DocListCast(Cast(Doc.UserDoc().template_clickFuncs, Doc, null)?.data); const templateMenu: Array = []; templateMenu.push(); - // eslint-disable-next-line no-return-assign addedTypes.concat(noteTypes).map(template => (template.treeView_Checked = this.templateIsUsed(firstDoc, template))); this._addedKeys && Array.from(this._addedKeys) diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 15683ebf2..cd2c7df1b 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -46,7 +46,7 @@ import { Id } from '../../../fields/FieldSymbols'; */ @observer -export class Timeline extends ObservableReactComponent { +export class Timeline extends ObservableReactComponent { // readonly constants private readonly DEFAULT_TICK_SPACING: number = 50; private readonly MAX_TITLE_HEIGHT = 75; @@ -57,7 +57,7 @@ export class Timeline extends ObservableReactComponent { private DEFAULT_CONTAINER_HEIGHT: number = 330; private MIN_CONTAINER_HEIGHT: number = 205; - constructor(props: FieldViewProps) { + constructor(props: FieldViewProps & { Doc: Doc }) { super(props); makeObservable(this); } @@ -90,11 +90,11 @@ export class Timeline extends ObservableReactComponent { */ @computed private get children(): Doc[] { - const annotatedDoc = [DocumentType.IMG, DocumentType.VID, DocumentType.PDF, DocumentType.MAP].includes(StrCast(this._props.Document.type) as unknown as DocumentType); + const annotatedDoc = [DocumentType.IMG, DocumentType.VID, DocumentType.PDF, DocumentType.MAP].includes(StrCast(this._props.Doc.type) as unknown as DocumentType); if (annotatedDoc) { - return DocListCast(this._props.Document[Doc.LayoutFieldKey(this._props.Document) + '_annotations']); + return DocListCast(this._props.Doc[Doc.LayoutFieldKey(this._props.Doc) + '_annotations']); } - return DocListCast(this._props.Document[this._props.fieldKey]); + return DocListCast(this._props.Doc[this._props.fieldKey]); } /// //////lifecycle functions//////////// @@ -104,21 +104,21 @@ export class Timeline extends ObservableReactComponent { this._titleHeight = relativeHeight < this.MAX_TITLE_HEIGHT ? relativeHeight : this.MAX_TITLE_HEIGHT; // check if relHeight is less than Maxheight. Else, just set relheight to max this.MIN_CONTAINER_HEIGHT = this._titleHeight + 130; // offset this.DEFAULT_CONTAINER_HEIGHT = this._titleHeight * 2 + 130; // twice the titleheight + offset - if (!this._props.Document.AnimationLength) { + if (!this._props.Doc.AnimationLength) { // if animation length did not exist - this._props.Document.AnimationLength = this._time; // set it to default time + this._props.Doc.AnimationLength = this._time; // set it to default time } else { - this._time = NumCast(this._props.Document.AnimationLength); // else, set time to animationlength stored from before + this._time = NumCast(this._props.Doc.AnimationLength); // else, set time to animationlength stored from before } this._totalLength = this._tickSpacing * (this._time / this._tickIncrement); // the entire length of the timeline div (actual div part itself) this._visibleLength = this._infoContainer.current!.getBoundingClientRect().width; // the visible length of the timeline (the length that you current see) this._visibleStart = this._infoContainer.current!.scrollLeft; // where the div starts - this._props.Document.isATOn = !this._props.Document.isATOn; // turns the boolean on, saying AT (animation timeline) is on + this._props.Doc.isATOn = !this._props.Doc.isATOn; // turns the boolean on, saying AT (animation timeline) is on this.toggleHandle(); } componentWillUnmount() { - this._props.Document.AnimationLength = this._time; // save animation length + this._props.Doc.AnimationLength = this._time; // save animation length } /// ////////////////////////////////////////////// @@ -224,7 +224,7 @@ export class Timeline extends ObservableReactComponent { */ @action onPanDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, this.onPanMove, emptyFunction, e => this.changeCurrentBarX(this._trackbox.current!.scrollLeft + e.clientX - this._trackbox.current!.getBoundingClientRect().left)); + setupMoveUpEvents(this, e, this.onPanMove, emptyFunction, movEv => this.changeCurrentBarX(this._trackbox.current!.scrollLeft + movEv.clientX - this._trackbox.current!.getBoundingClientRect().left)); }; /** @@ -241,7 +241,7 @@ export class Timeline extends ObservableReactComponent { this._visibleStart -= e.movementX; this._totalLength -= e.movementX; this._time -= RegionHelpers.convertPixelTime(e.movementX, 'mili', 'time', this._tickSpacing, this._tickIncrement); - this._props.Document.AnimationLength = this._time; + this._props.Doc.AnimationLength = this._time; } return false; }; @@ -259,8 +259,8 @@ export class Timeline extends ObservableReactComponent { setupMoveUpEvents( this, e, - action(e => { - const offset = e.clientY - this._timelineContainer.current!.getBoundingClientRect().bottom; + action(movEv => { + const offset = movEv.clientY - this._timelineContainer.current!.getBoundingClientRect().bottom; this._containerHeight = clamp(this.MIN_CONTAINER_HEIGHT, this._containerHeight + offset, this.MAX_CONTAINER_HEIGHT); return false; }), @@ -358,7 +358,7 @@ export class Timeline extends ObservableReactComponent { const size = 40 * scale; // 50 is default const iconSize = 25; const width: number = this._props.PanelWidth(); - const modeType = this._props.Document.isATOn ? 'Author' : 'Play'; + const modeType = this._props.Doc.isATOn ? 'Author' : 'Play'; // decides if information should be omitted because the timeline is very small // if its less than 950 pixels then it's going to be overlapping @@ -397,7 +397,7 @@ export class Timeline extends ObservableReactComponent { tickIncrement={this._tickIncrement} time={this._time} parent={this} - isAuthoring={BoolCast(this._props.Document.isATOn)} + isAuthoring={BoolCast(this._props.Doc.isATOn)} currentBarX={this._currentBarX} totalLength={this._totalLength} visibleLength={this._visibleLength} @@ -418,10 +418,10 @@ export class Timeline extends ObservableReactComponent {
{this.timeIndicator(lengthString, totalTime)} -
this.resetView(this._props.Document)}> +
this.resetView(this._props.Doc)}>
-
this.setView(this._props.Document)}> +
this.setView(this._props.Doc)}>
@@ -431,17 +431,17 @@ export class Timeline extends ObservableReactComponent { }; timeIndicator(lengthString: string, totalTime: number) { - if (this._props.Document.isATOn) { - return
{`Total: ${this.toReadTime(totalTime)}`}
; + if (this._props.Doc.isATOn) { + return
{`Total: ${this.toReadTime(totalTime)}`}
; } else { const ctime = `Current: ${this.getCurrentTime()}`; const ttime = `Total: ${this.toReadTime(this._time)}`; return (
-
+
{ctime}
-
+
{ttime}
@@ -467,8 +467,8 @@ export class Timeline extends ObservableReactComponent { const roundToggleContainer = this._roundToggleContainerRef.current!; const timelineContainer = this._timelineContainer.current!; - this._props.Document.isATOn = !this._props.Document.isATOn; - if (!BoolCast(this._props.Document.isATOn)) { + this._props.Doc.isATOn = !this._props.Doc.isATOn; + if (!BoolCast(this._props.Doc.isATOn)) { // turning on playmode... roundToggle.style.transform = 'translate(0px, 0px)'; roundToggle.style.animationName = 'turnoff'; @@ -543,7 +543,7 @@ export class Timeline extends ObservableReactComponent { // change visible and total width return (
-
+
{this.drawTicks()} @@ -551,7 +551,7 @@ export class Timeline extends ObservableReactComponent {
- {[...this.children, this._props.Document].map(doc => ( + {[...this.children, this._props.Doc].map(doc => ( this.mapOfTracks.push(ref)} @@ -563,7 +563,7 @@ export class Timeline extends ObservableReactComponent { time={this._time} tickSpacing={this._tickSpacing} tickIncrement={this._tickIncrement} - collection={this._props.Document} + collection={this._props.Doc} timelineVisible={true} /> ))} @@ -571,7 +571,7 @@ export class Timeline extends ObservableReactComponent {
Current: {this.getCurrentTime()}
- {[...this.children, this._props.Document].map(doc => ( + {[...this.children, this._props.Doc].map(doc => (
Doc.BrushDoc(doc)} onPointerOut={() => Doc.UnBrushDoc(doc)}>

{StrCast(doc.title)}

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 4fe73895e..89ccf5a0f 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -22,7 +22,7 @@ import './CollectionStackingView.scss'; interface CMVFieldRowProps { rows: () => number; headings: () => object[]; - Document: Doc; + Doc: Doc; chromeHidden?: boolean; heading: string; headingObject: SchemaHeaderField | undefined; @@ -73,7 +73,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent { this._dropDisposer?.(); - if (ele) this._dropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this), this._props.Document); + if (ele) this._dropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this), this._props.Doc); else if (this._ele) this.props.refList.splice(this.props.refList.indexOf(this._ele), 1); this._ele = ele; }; @@ -189,7 +189,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent { - const embedding = Doc.MakeEmbedding(this._props.Document); + const embedding = Doc.MakeEmbedding(this._props.Doc); const key = this._props.pivotField; let value = this.getValue(this.heading); value = typeof value === 'string' ? `"${value}"` : value; @@ -289,7 +289,7 @@ export class CollectionMasonryViewFieldRow extends ObservableReactComponent evContents} SetValue={this.headingChanged} contents={evContents} oneLine />; - return this._props.Document.miniHeaders ? ( + return this._props.Doc.miniHeaders ? (
{editableHeaderView}
) : !this._props.headingObject ? null : (
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx index 4650727eb..2dabd3269 100644 --- a/src/client/views/collections/CollectionNoteTakingView.tsx +++ b/src/client/views/collections/CollectionNoteTakingView.tsx @@ -32,6 +32,7 @@ import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { Property } from 'csstype'; +import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; /** * CollectionNoteTakingView is a column-based view for displaying documents. In this view, the user can (1) @@ -437,10 +438,10 @@ export class CollectionNoteTakingView extends CollectionSubView() { }; @undoBatch - onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => { - if ((e.ctrlKey || fieldProps.Document._createDocOnCR) && ['Enter'].includes(e.key)) { + onKeyDown = (e: React.KeyboardEvent, textBox: FormattedTextBox) => { + if ((e.ctrlKey || textBox.Document._createDocOnCR) && ['Enter'].includes(e.key)) { e.stopPropagation?.(); - const newDoc = Doc.MakeCopy(fieldProps.Document, true); + const newDoc = Doc.MakeCopy(textBox.Document, true); newDoc.$text = undefined; DocumentView.SetSelectOnLoad(newDoc); return this.addDocument?.(newDoc); @@ -543,8 +544,8 @@ export class CollectionNoteTakingView extends CollectionSubView() { addDocument={this.addDocument} chromeHidden={this.chromeHidden} colHeaderData={this.colHeaderData} - Document={this.Document} - TemplateDataDocument={this._props.TemplateDataDocument} + Doc={this.Document} + TemplateDataDoc={this._props.TemplateDataDocument} resizeColumns={this.resizeColumns} renderChildren={this.children} numGroupColumns={this.numGroupColumns} @@ -567,7 +568,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { @undoBatch remColumn = (value: SchemaHeaderField) => { - const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); + const colHdrData = Array.from(Cast(this.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); if (value) { const index = colHdrData.indexOf(value); index !== -1 && colHdrData.splice(index, 1); @@ -701,7 +702,7 @@ export class CollectionNoteTakingView extends CollectionSubView() { {this.renderedSections}
{ this.layoutDoc._pivotField = fieldKey; this.removeEmptyColumns(); diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx index df9b5a1eb..f283b0abe 100644 --- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx +++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx @@ -21,8 +21,8 @@ import './CollectionNoteTakingView.scss'; import { DocumentView } from '../nodes/DocumentView'; interface CSVFieldColumnProps { - Document: Doc; - TemplateDataDocument: Opt; + Doc: Doc; + TemplateDataDoc: Opt; backgroundColor?: () => string | undefined; docList: Doc[]; heading: string; @@ -65,7 +65,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent hd.heading === this._props.headingObject?.heading && hd.color === this._props.headingObject.color); return ((this._props.colHeaderData[i].width * this._props.availableWidth) / this._props.PanelWidth()) * 100 + '%'; @@ -81,7 +81,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent { this.dropDisposer?.(); - if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Document); + if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Doc); else if (this._ele) this.props.refList.slice(this.props.refList.indexOf(this._ele), 1); this._ele = ele; }; @@ -155,7 +155,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent { - const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); + const colHdrData = Array.from(Cast(this._props.Doc[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null)); if (this._props.headingObject) { // this._props.docList.forEach(d => (d['$'+this._props.pivotField] = undefined)); colHdrData.splice(colHdrData.indexOf(this._props.headingObject), 1); @@ -184,11 +184,11 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent { - Doc.GetProto(this._props.Document)[name] = ''; + Doc.GetProto(this._props.Doc)[name] = ''; const created = Docs.Create.TextDocument('', { title: name, _width: 250, _layout_autoHeight: true }); if (created) { - if (this._props.Document.isTemplateDoc) { - Doc.MakeMetadataFieldTemplate(created, this._props.Document); + if (this._props.Doc.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this._props.Doc); } this._props.addDocument?.(created); } @@ -267,7 +267,7 @@ export class CollectionNoteTakingViewColumn extends ObservableReactComponent h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Document.xMargin) : 0, + marginLeft: this._props.headings().findIndex(h => h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Doc.xMargin) : 0, }}>
{this.innards} diff --git a/src/client/views/collections/CollectionPivotView.tsx b/src/client/views/collections/CollectionPivotView.tsx index 2600c0f57..4736070c3 100644 --- a/src/client/views/collections/CollectionPivotView.tsx +++ b/src/client/views/collections/CollectionPivotView.tsx @@ -103,7 +103,7 @@ export class CollectionPivotView extends CollectionSubView() { {this.contents}
{ this.layoutDoc._pivotField = fieldKey; }} diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 9972fe03d..883b0bbe3 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -34,6 +34,7 @@ import './CollectionStackingView.scss'; import { CollectionStackingViewFieldColumn } from './CollectionStackingViewFieldColumn'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; import { computedFn } from 'mobx-utils'; +import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox'; export type collectionStackingViewProps = { sortFunc?: (a: Doc, b: Doc) => number; @@ -309,15 +310,15 @@ export class CollectionStackingView extends CollectionSubView { + onKeyDown = (e: React.KeyboardEvent, textBox: FormattedTextBox) => { if (['Enter'].includes(e.key) && e.ctrlKey) { e.stopPropagation?.(); - const layoutFieldKey = StrCast(fieldProps.fieldKey); - const newDoc = Doc.MakeCopy(fieldProps.Document, true); - const dataField = fieldProps.Document[Doc.LayoutFieldKey(newDoc)]; + const layoutFieldKey = StrCast(textBox.fieldKey); + const newDoc = Doc.MakeCopy(textBox.Document, true); + const dataField = textBox.Document[Doc.LayoutFieldKey(newDoc)]; newDoc['$' + Doc.LayoutFieldKey(newDoc)] = dataField === undefined || Cast(dataField, listSpec(Doc), null)?.length !== undefined ? new List([]) : undefined; - if (layoutFieldKey !== 'layout' && fieldProps.Document[layoutFieldKey] instanceof Doc) { - newDoc[layoutFieldKey] = fieldProps.Document[layoutFieldKey]; + if (layoutFieldKey !== 'layout' && textBox.Document[layoutFieldKey] instanceof Doc) { + newDoc[layoutFieldKey] = textBox.Document[layoutFieldKey]; } newDoc.$text = undefined; DocumentView.SetSelectOnLoad(newDoc); @@ -574,8 +575,8 @@ export class CollectionStackingView extends CollectionSubView ; + Doc: Doc; + TemplateDataDoc: Opt; docList: Doc[]; heading: string; pivotField: string; @@ -90,7 +90,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< // is that the only way to have drop targets? createColumnDropRef = (ele: HTMLDivElement | null) => { this.dropDisposer?.(); - if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Document, this.onInternalPreDrop.bind(this)); + if (ele) this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this), this._props.Doc, this.onInternalPreDrop.bind(this)); else if (this._ele) this.props.refList.splice(this.props.refList.indexOf(this._ele), 1); this._ele = ele; }; @@ -183,7 +183,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< // TODO: I think this is where I'm supposed to edit stuff startDrag = (e: PointerEvent) => { // is MakeEmbedding a way to make a copy of a doc without rendering it? - const embedding = Doc.MakeEmbedding(this._props.Document); + const embedding = Doc.MakeEmbedding(this._props.Doc); embedding._width = this._props.columnWidth / (this._props.colHeaderData?.length || 1); embedding._pivotField = undefined; let value = this.getValue(this._heading); @@ -230,7 +230,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< ContextMenu.Instance.clearItems(); const layoutItems: ContextMenuProps[] = []; const docItems: ContextMenuProps[] = []; - const dataDoc = this._props.TemplateDataDocument || this._props.Document; + const dataDoc = this._props.TemplateDataDoc || this._props.Doc; const width = this._ele ? DivWidth(this._ele) : 0; const height = this._ele ? DivHeight(this._ele) : 0; DocUtils.addDocumentCreatorMenuItems( @@ -250,10 +250,10 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< docItems.push({ description: ':' + fieldKey, event: () => { - const created = DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document)); + const created = DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Doc)); if (created) { - if (this._props.Document.isTemplateDoc) { - Doc.MakeMetadataFieldTemplate(created, this._props.Document); + if (this._props.Doc.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this._props.Doc); } return this._props.addDocument?.(created); } @@ -270,7 +270,7 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< event: () => { const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey }); if (created) { - const container = this._props.Document.resolvedDataDoc ? Doc.GetProto(this._props.Document) : this._props.Document; + const container = this._props.Doc.resolvedDataDoc ? Doc.GetProto(this._props.Doc) : this._props.Doc; if (container.isTemplateDoc) { Doc.MakeMetadataFieldTemplate(created, container); return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created); @@ -285,11 +285,11 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Doc Fields ...', subitems: docItems, icon: 'eye' }); !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Containers ...', subitems: layoutItems, icon: 'eye' }); ContextMenu.Instance.setDefaultItem('::', (name: string): void => { - Doc.GetProto(this._props.Document)[name] = ''; + Doc.GetProto(this._props.Doc)[name] = ''; const created = Docs.Create.TextDocument('', { title: name, _width: 250, _layout_autoHeight: true }); if (created) { - if (this._props.Document.isTemplateDoc) { - Doc.MakeMetadataFieldTemplate(created, this._props.Document); + if (this._props.Doc.isTemplateDoc) { + Doc.MakeMetadataFieldTemplate(created, this._props.Doc); } this._props.addDocument?.(created); } @@ -350,10 +350,10 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent<
) : null; const templatecols = `${this._props.columnWidth / this._props.numGroupColumns}px `; - const { type } = this._props.Document; + const { type } = this._props.Doc; return ( <> - {this._props.Document._columnsHideIfEmpty ? null : headingView} + {this._props.Doc._columnsHideIfEmpty ? null : headingView} {this.collapsed ? null : (
() { constructor(props: X & SubCollectionViewProps) { super(props); makeObservable(this); - console.log(`propsTitle: ${this._props.Document.title} DocTitle: ${this.Document.title} LayoutTitle:${this.layoutDoc.title} DataTitle:${this.dataDoc.title}`); - console.log(`tempTitle: ${this._props.TemplateDataDocument?.title} LayouTResolve: ${DocCast(this.layoutDoc.resolvedDataDoc)?.title} propDocResolve: ${DocCast(this._props.Document.resolvedDataDoc)?.title}`); - console.log('Children:', this.childDocs, this.childLayoutPairs); } @observable _focusFilters: Opt = undefined; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it @@ -111,7 +108,6 @@ export function CollectionSubView() { } get dataDoc() { - console.log(this._props.Document.title + ' isTemplate: ' + this.layoutDoc.isTemplateForField); return this._props.TemplateDataDocument instanceof Doc && this.layoutDoc.isTemplateForField // ? this._props.TemplateDataDocument[DocData] : this.layoutDoc.resolvedDataDoc @@ -135,7 +131,7 @@ export function CollectionSubView() { hasChildDocs = () => this.childLayoutPairs.map(pair => pair.layout); @computed get childLayoutPairs(): { layout: Doc; data: Doc }[] { - const { Document, TemplateDataDocument } = this._props; + const { Document: Document, TemplateDataDocument } = this._props; const validPairs = this.childDocs .map(doc => Doc.GetLayoutDataDocPair(Document, !this._props.isAnnotationOverlay ? TemplateDataDocument : undefined, doc)) .filter( @@ -303,7 +299,7 @@ export function CollectionSubView() { const dragData = de.complete.docDragData; if (dragData) { const sourceDragAction = dragData.dropAction; - const sameCollection = !dragData.draggedDocuments.some(d => d.embedContainer !== this._props.Document); + const sameCollection = !dragData.draggedDocuments.some(d => d.embedContainer !== this._renderDoc); dragData.dropAction = !sameCollection // if doc from another tree ? sourceDragAction || targetDropAction // then use the source's dragAction otherwise the target's : sourceDragAction === dropActionType.inPlace // if source drag is inPlace diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 98bd06221..fd562e64f 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -121,7 +121,7 @@ export class CollectionTimeView extends CollectionSubView() { {this.contents}
{ this.layoutDoc._pivotField = fieldKey; }} diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index e93724dd4..b7f49ac20 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -241,7 +241,7 @@ export class CollectionTreeView extends CollectionSubView { + onKey = (e: React.KeyboardEvent /* , textBox: FormattedTextBox */) => { if (this.outlineMode && e.key === 'Enter') { e.stopPropagation(); this.makeTextCollection(this.treeChildren); @@ -252,7 +252,6 @@ export class CollectionTreeView extends CollectionSubView {!(this.Document instanceof Doc) || !this.treeChildren ? null : this.Document.treeView_HasOverlay ? ( DocumentView | undefined; addDocTab: (doc: Doc | Doc[], where: OpenWhere) => boolean; PanelWidth: () => number; @@ -100,15 +100,15 @@ export class TabMinimapView extends ObservableReactComponent Cast(this._props.document.childLayoutTemplate, Doc, null); - returnMiniSize = () => NumCast(this._props.document._miniMapSize, 150); + childLayoutTemplate = () => Cast(this._props.doc.childLayoutTemplate, Doc, null); + returnMiniSize = () => NumCast(this._props.doc._miniMapSize, 150); miniDown = (e: React.PointerEvent) => { - const doc = this._props.document; + const doc = this._props.doc; const miniSize = this.returnMiniSize(); doc && setupMoveUpEvents( @@ -127,15 +127,15 @@ export class TabMinimapView extends ObservableReactComponent { const { renderBounds } = this; if (!renderBounds) return
; - const miniWidth = () => (this._props.PanelWidth() / NumCast(this._props.document._freeform_scale, 1) / renderBounds.dim) * 100; - const miniHeight = () => (this._props.PanelHeight() / NumCast(this._props.document._freeform_scale, 1) / renderBounds.dim) * 100; - const miniLeft = () => 50 + ((NumCast(this._props.document._freeform_panX) - renderBounds.cx) / renderBounds.dim) * 100 - miniWidth() / 2; - const miniTop = () => 50 + ((NumCast(this._props.document._freeform_panY) - renderBounds.cy) / renderBounds.dim) * 100 - miniHeight() / 2; + const miniWidth = () => (this._props.PanelWidth() / NumCast(this._props.doc._freeform_scale, 1) / renderBounds.dim) * 100; + const miniHeight = () => (this._props.PanelHeight() / NumCast(this._props.doc._freeform_scale, 1) / renderBounds.dim) * 100; + const miniLeft = () => 50 + ((NumCast(this._props.doc._freeform_panX) - renderBounds.cx) / renderBounds.dim) * 100 - miniWidth() / 2; + const miniTop = () => 50 + ((NumCast(this._props.doc._freeform_panY) - renderBounds.cy) / renderBounds.dim) * 100 - miniHeight() / 2; const miniSize = this.returnMiniSize(); return (
} color={SnappingManager.userVariantColor} type={Type.TERT} onPointerDown={e => e.stopPropagation()} placement="top-end" popup={this.popup} />
@@ -631,7 +631,7 @@ export class TabDocView extends ObservableReactComponent { }}> {!this._activated || !this._document ? null : this.renderDocView(this._document)} {this.disableMinimap() || !this._document ? null : ( - + )}
); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx index 35c6d30fe..89d2bf2c3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx @@ -12,8 +12,8 @@ import { CollectionFreeFormView } from './CollectionFreeFormView'; import './CollectionFreeFormView.scss'; export interface CollectionFreeFormInfoUIProps { - Document: Doc; - LayoutDoc: Doc; + Doc: Doc; + layoutDoc: Doc; childDocs: () => Doc[]; close: () => void; } @@ -23,7 +23,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent Doc[], close: () => void) => ( // - + )); } _firstDocPos = { x: 0, y: 0 }; @@ -40,7 +40,7 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent {this._currState = val;}); } // prettier-ignore componentWillUnmount(): void { - this._props.Document.$backgroundColor = this._originalbackground; + this._props.Doc.$backgroundColor = this._originalbackground; } setCurrState = (state: infoState) => { @@ -51,10 +51,10 @@ export class CollectionFreeFormInfoUI extends ObservableReactComponent { - this._originalbackground = StrCast(this._props.Document.$backgroundColor); + this._originalbackground = StrCast(this._props.Doc.$backgroundColor); // state entry functions - // const setBackground = (colour: string) => () => {this._props.Document.$backgroundColor = colour;} // prettier-ignore - // const setOpacity = (opacity: number) => () => {this._props.LayoutDoc.opacity = opacity;} // prettier-ignore + // const setBackground = (colour: string) => () => {this._props.Doc.$backgroundColor = colour;} // prettier-ignore + // const setOpacity = (opacity: number) => () => {this._props.layoutDoc.opacity = opacity;} // prettier-ignore // arc transition trigger conditions const firstDoc = () => (this._props.childDocs().length ? this._props.childDocs()[0] : undefined); const numDocs = () => this._props.childDocs().length; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx index bc9dd022c..2683d9439 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx @@ -7,7 +7,7 @@ import { ObservableReactComponent } from '../../ObservableReactComponent'; import './CollectionFreeFormView.scss'; export interface CollectionFreeFormPannableContentsProps { - Document: Doc; + Doc: Doc; viewDefDivClick?: ScriptField; children?: React.ReactNode | undefined; transition: () => string; @@ -33,7 +33,7 @@ export class CollectionFreeFormPannableContents extends ObservableReactComponent makeObservable(this); } @computed get presPaths() { - return this._props.showPresPaths() ? CollectionFreeFormPannableContents._overlayPlugin?.(this._props.Document) : null; + return this._props.showPresPaths() ? CollectionFreeFormPannableContents._overlayPlugin?.(this._props.Doc) : null; } // rectangle highlight used when following trail/link to a region of a collection that isn't a document showViewport = (viewport: { panX: number; panY: number; width: number; height: number } | undefined) => diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx index f64c6715b..86310dca3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx @@ -13,7 +13,7 @@ import './CollectionFreeFormView.scss'; @observer export class CollectionFreeFormRemoteCursors extends React.Component { @computed protected get cursors(): CursorField[] { - const { Document } = this.props; + const { Document: Document } = this.props; const cursors = Cast(Document.cursors, listSpec(CursorField)); if (!cursors) { return []; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 6030e146c..25cec9c0d 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,10 +1,13 @@ -import { Bezier } from 'bezier-js'; import { Button, Colors, Type } from '@dash/components'; +import { Slider } from '@mui/material'; +import { Bezier } from 'bezier-js'; import { Property } from 'csstype'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { computedFn } from 'mobx-utils'; import * as React from 'react'; +import { AiOutlineSend } from 'react-icons/ai'; +import ReactLoading from 'react-loading'; import { ClientUtils, DashColor, lightOrDark, OmitKeys, returnFalse, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../../ClientUtils'; import { DateField } from '../../../../fields/DateField'; import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc'; @@ -28,6 +31,7 @@ import { DragManager } from '../../../util/DragManager'; import { dropActionType } from '../../../util/DropActionTypes'; import { CompileScript } from '../../../util/Scripting'; import { ScriptingGlobals } from '../../../util/ScriptingGlobals'; +import { SettingsManager } from '../../../util/SettingsManager'; import { freeformScrollMode, SnappingManager } from '../../../util/SnappingManager'; import { Transform } from '../../../util/Transform'; import { undoable, UndoManager } from '../../../util/UndoManager'; @@ -37,26 +41,26 @@ import { InkingStroke } from '../../InkingStroke'; import { CollectionFreeFormDocumentView } from '../../nodes/CollectionFreeFormDocumentView'; import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp'; import { + ActiveEraserWidth, ActiveInkArrowEnd, ActiveInkArrowStart, - ActiveInkDash, - ActiveEraserWidth, - ActiveInkFillColor, ActiveInkBezierApprox, ActiveInkColor, + ActiveInkDash, + ActiveInkFillColor, ActiveInkWidth, ActiveIsInkMask, DocumentView, SetActiveInkColor, SetActiveInkWidth, } from '../../nodes/DocumentView'; -import { FieldViewProps } from '../../nodes/FieldView'; import { FocusViewOptions } from '../../nodes/FocusViewOptions'; import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox'; import { OpenWhere } from '../../nodes/OpenWhere'; import { PinDocView, PinProps } from '../../PinFuncs'; -import { StickerPalette } from '../../smartdraw/StickerPalette'; +import { DrawingFillHandler } from '../../smartdraw/DrawingFillHandler'; import { DrawingOptions, SmartDrawHandler } from '../../smartdraw/SmartDrawHandler'; +import { StickerPalette } from '../../smartdraw/StickerPalette'; import { StyleProp } from '../../StyleProp'; import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import { TreeViewType } from '../CollectionTreeViewType'; @@ -67,11 +71,6 @@ import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannable import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors'; import './CollectionFreeFormView.scss'; import { MarqueeView } from './MarqueeView'; -import ReactLoading from 'react-loading'; -import { SettingsManager } from '../../../util/SettingsManager'; -import { Slider } from '@mui/material'; -import { AiOutlineSend } from 'react-icons/ai'; -import { DrawingFillHandler } from '../../smartdraw/DrawingFillHandler'; @observer class CollectionFreeFormOverlayView extends React.Component<{ elements: () => ViewDefResult[] }> { @@ -180,10 +179,10 @@ export class CollectionFreeFormView extends CollectionSubView this.fitContentBounds?.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panX, 1)); - panY = () => this.fitContentBounds?.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(Cast(this.Document.resolvedDataDoc, Doc, null)?.freeform_panY, 1)); + panX = () => this.fitContentBounds?.cx ?? NumCast(this.Document[this.panXFieldKey], NumCast(this.Document.freeform_panX, 1)); + panY = () => this.fitContentBounds?.cy ?? NumCast(this.Document[this.panYFieldKey], NumCast(this.Document.freeform_panY, 1)); zoomScaling = () => this.fitContentBounds?.scale ?? NumCast(Doc.Layout(this.Document)[this.scaleFieldKey], 1); // , NumCast(DocCast(this.Document.resolvedDataDoc)?.[this.scaleFieldKey], 1)); PanZoomCenterXf = () => (this._props.isAnnotationOverlay && this.zoomScaling() === 1 ? `` : `translate(${this.centeringShiftX}px, ${this.centeringShiftY}px) scale(${this.zoomScaling()}) translate(${-this.panX()}px, ${-this.panY()}px)`); ScreenToContentsXf = () => this.screenToFreeformContentsXf.copy(); @@ -1489,20 +1488,20 @@ export class CollectionFreeFormView extends CollectionSubView { - const textDoc = DocCast(fieldProps.Document.rootDocument, fieldProps.Document); + createTextDocCopy = undoable((textBox: FormattedTextBox, below: boolean) => { + const textDoc = DocCast(textBox.Document.rootDocument, textBox.Document); const newDoc = Doc.MakeCopy(textDoc, true); - newDoc['$' + Doc.LayoutFieldKey(newDoc, fieldProps.LayoutTemplateString)] = undefined; // the copy should not copy the text contents of it source, just the render style + newDoc['$' + Doc.LayoutFieldKey(newDoc, textBox._props.LayoutTemplateString)] = undefined; // the copy should not copy the text contents of it source, just the render style newDoc.x = NumCast(textDoc.x) + (below ? 0 : NumCast(textDoc._width) + 10); newDoc.y = NumCast(textDoc.y) + (below ? NumCast(textDoc._height) + 10 : 0); DocumentView.SetSelectOnLoad(newDoc); return this.addDocument?.(newDoc); }, 'copied text note'); - onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => { - if ((e.metaKey || e.ctrlKey || e.altKey || fieldProps.Document._createDocOnCR) && ['Tab', 'Enter'].includes(e.key)) { + onKeyDown = (e: React.KeyboardEvent, textBox: FormattedTextBox) => { + if ((e.metaKey || e.ctrlKey || e.altKey || textBox.Document._createDocOnCR) && ['Tab', 'Enter'].includes(e.key)) { e.stopPropagation?.(); - return this.createTextDocCopy(fieldProps, !e.altKey && e.key !== 'Tab'); + return this.createTextDocCopy(textBox, !e.altKey && e.key !== 'Tab'); } return undefined; }; @@ -1685,7 +1684,7 @@ export class CollectionFreeFormView extends CollectionSubView (this._props.Document.isTemplateDoc || this._props.Document.isTemplateForField ? false : !this._renderCutoffData.get(doc[Id] + ''))); + renderCutoffProvider = computedFn((doc: Doc) => (this.Document.isTemplateDoc || this.Document.isTemplateForField ? false : !this._renderCutoffData.get(doc[Id] + ''))); doEngineLayout( poolData: Map, @@ -2115,7 +2114,7 @@ export class CollectionFreeFormView extends CollectionSubView 0 ? undefined : this.nudge} addDocTab={this.addDocTab} @@ -2149,7 +2149,7 @@ export class CollectionFreeFormView extends CollectionSubView {this.layoutDoc._freeform_backgroundGrid ? this.backgroundGrid : null} {this.pannableContents} - {this._showAnimTimeline ? : null} + {this._showAnimTimeline ? : null} ); } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index e3f4c6605..eaa8826ed 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -32,6 +32,7 @@ import { MarqueeOptionsMenu } from './MarqueeOptionsMenu'; import './MarqueeView.scss'; interface MarqueeViewProps { + Doc: Doc; getContainerTransform: () => Transform; getTransform: () => Transform; activeDocuments: () => Doc[]; diff --git a/src/client/views/collections/collectionSchema/SchemaCellField.tsx b/src/client/views/collections/collectionSchema/SchemaCellField.tsx index e89822b4c..daffdf1f5 100644 --- a/src/client/views/collections/collectionSchema/SchemaCellField.tsx +++ b/src/client/views/collections/collectionSchema/SchemaCellField.tsx @@ -21,11 +21,11 @@ import DOMPurify from 'dompurify'; */ export interface SchemaCellFieldProps { + Doc: Doc; contents: FieldType | undefined; fieldContents?: FieldViewProps; editing?: boolean; oneLine?: boolean; - Document: Doc; fieldKey: string; // eslint-disable-next-line no-use-before-define refSelectModeInfo: { enabled: boolean; currEditing: SchemaCellField | undefined }; @@ -55,7 +55,7 @@ export class SchemaCellField extends ObservableReactComponent() { isolatedSelection={this.isolatedSelection} key={key} rowSelected={this._props.isSelected} - Document={this.Document} + Doc={this.Document} col={index} fieldKey={key} allowCRs={false} // to enter text with new lines, must use \n diff --git a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx index 1b4f200a3..e6fe46638 100644 --- a/src/client/views/collections/collectionSchema/SchemaTableCell.tsx +++ b/src/client/views/collections/collectionSchema/SchemaTableCell.tsx @@ -40,7 +40,7 @@ import { SchemaCellField } from './SchemaCellField'; */ export interface SchemaTableCellProps { - Document: Doc; + Doc: Doc; col: number; deselectCell: () => void; selectCell: (doc: Doc, col: number, shift: boolean, ctrl: boolean) => void; @@ -71,7 +71,7 @@ export interface SchemaTableCellProps { } function selectedCell(props: SchemaTableCellProps) { - return props.isRowActive() && props.selectedCol() === props.col && props.selectedCells()?.filter(d => d === props.Document)?.length; + return props.isRowActive() && props.selectedCol() === props.col && props.selectedCells()?.filter(d => d === props.Doc)?.length; } @observer @@ -84,11 +84,11 @@ export class SchemaTableCell extends ObservableReactComponent this._props.highlightCells(this.adjustSelfReference(text))} getCells={(text: string) => this._props.eqHighlightFunc(this.adjustSelfReference(text))} ref={r => selectedCell(this._props) && this._props.autoFocus && r?.setIsFocused(true)} @@ -224,7 +224,7 @@ export class SchemaTableCell extends ObservableReactComponent = []; sides[0] = selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // left sides[1] = selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // right - sides[2] = !this._props.isolatedSelection(this._props.Document)[0] && selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // top - sides[3] = !this._props.isolatedSelection(this._props.Document)[1] && selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // bottom + sides[2] = !this._props.isolatedSelection(this._props.Doc)[0] && selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // top + sides[3] = !this._props.isolatedSelection(this._props.Doc)[1] && selectedCell(this._props) ? `solid 2px ${Colors.MEDIUM_BLUE}` : undefined; // bottom return sides; } @@ -272,7 +272,7 @@ export class SchemaTableCell extends ObservableReactComponent Cast(doc[Doc.LayoutFieldKey(doc)], ImageField, null)?.url) .filter(url => url) @@ -359,7 +359,7 @@ export class SchemaImageCell extends ObservableReactComponent { @@ -388,7 +388,7 @@ export class SchemaDateCell extends ObservableReactComponent e.stopPropagation()} style={{ marginRight: 4 }} type="checkbox" - checked={BoolCast(this._props.Document[this._props.fieldKey])} + checked={BoolCast(this._props.Doc[this._props.fieldKey])} onChange={undoable((value: React.ChangeEvent | undefined) => { if ((value?.nativeEvent as MouseEvent | PointerEvent).shiftKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); - } else Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); + } else Doc.SetField(this._props.Doc, this._props.fieldKey.replace(/^_/, ''), (color === 'black' ? '=' : '') + (value?.target?.checked.toString() ?? '')); }, 'set bool cell')} /> @@ -463,14 +463,14 @@ export class SchemaBoolCell extends ObservableReactComponent Field.toKeyValueString(this._props.Document, this._props.fieldKey)} + GetValue={() => Field.toKeyValueString(this._props.Doc, this._props.fieldKey)} SetValue={undoable((value: string, shiftDown?: boolean, enterKey?: boolean) => { if (shiftDown && enterKey) { this._props.setColumnValues(this._props.fieldKey.replace(/^_/, ''), value); this._props.finishEdit?.(); return true; } - const set = Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Document) ? true : undefined); + const set = Doc.SetField(this._props.Doc, this._props.fieldKey.replace(/^_/, ''), value, Doc.IsDataProto(this._props.Doc) ? true : undefined); this._props.finishEdit?.(); return set; }, 'set bool cell')} @@ -538,10 +538,10 @@ export class SchemaEnumerationCell extends ObservableReactComponent Doc.SetField(this._props.Document, this._props.fieldKey.replace(/^_/, ''), `"${val?.value ?? ''}"`)} + onChange={val => Doc.SetField(this._props.Doc, this._props.fieldKey.replace(/^_/, ''), `"${val?.value ?? ''}"`)} />
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index ce1e9280a..6f86383c2 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -304,7 +304,7 @@ export class CollectionFreeFormDocumentView extends DocComponent val.lower)).omit} // prettier-ignore - Document={this._props.Document} + Document={this._renderDoc} renderDepth={this._props.renderDepth} isContentActive={this._props.isContentActive} childFilters={this._props.childFilters} diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx index d5e37b3b5..117eb05f8 100644 --- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx +++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx @@ -1,43 +1,39 @@ +import { Colors, Toggle, ToggleType, Type } from '@dash/components'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox } from '@mui/material'; -import { Colors, Toggle, ToggleType, Type } from '@dash/components'; import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { ClientUtils, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../ClientUtils'; +import { returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../ClientUtils'; import { emptyFunction } from '../../../../Utils'; -import { Doc, DocListCast, Field, FieldType, NumListCast, Opt, StrListCast } from '../../../../fields/Doc'; -import { AclAdmin, AclAugment, AclEdit } from '../../../../fields/DocSymbols'; +import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../../fields/Doc'; import { InkTool } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; -import { PrefetchProxy } from '../../../../fields/Proxy'; import { Cast, CsvCast, DocCast, NumCast, StrCast } from '../../../../fields/Types'; import { CsvField } from '../../../../fields/URLField'; -import { GetEffectiveAcl, TraceMobx } from '../../../../fields/util'; +import { TraceMobx } from '../../../../fields/util'; import { GPTCallType, gptAPICall } from '../../../apis/gpt/GPT'; import { DocUtils } from '../../../documents/DocUtils'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Docs } from '../../../documents/Documents'; -import { LinkManager } from '../../../util/LinkManager'; import { UndoManager, undoable } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; import { ViewBoxAnnotatableComponent } from '../../DocComponent'; import { MarqueeAnnotator } from '../../MarqueeAnnotator'; import { PinProps } from '../../PinFuncs'; import { SidebarAnnos } from '../../SidebarAnnos'; -import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; import { AnchorMenu } from '../../pdf/AnchorMenu'; import { GPTPopup, GPTPopupMode } from '../../pdf/GPTPopup/GPTPopup'; import { DocumentView } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; import { FocusViewOptions } from '../FocusViewOptions'; import './DataVizBox.scss'; -import { Col, DataVizTemplateInfo, DocCreatorMenu, LayoutType} from './DocCreatorMenu/DocCreatorMenu'; +import { Col, DocCreatorMenu } from './DocCreatorMenu/DocCreatorMenu'; +import { TemplateFieldSize, TemplateFieldType } from './DocCreatorMenu/TemplateBackend'; import { Histogram } from './components/Histogram'; import { LineChart } from './components/LineChart'; import { PieChart } from './components/PieChart'; import { TableBox } from './components/TableBox'; -import { TemplateFieldSize, TemplateFieldType } from './DocCreatorMenu/TemplateBackend'; export enum DataVizView { TABLE = 'table', @@ -440,10 +436,10 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { }; 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.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;}} margin={{ top: 10, right: 15, bottom: 15, left: 15 }} />; default: } // prettier-ignore @@ -574,9 +570,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { const cols = Array.from(Object.keys(this.records[0])).filter(header => header !== '' && header !== undefined); - cols.forEach(col => { - this.setColumnDefault(col, `${this.records[rowToCheck][col]}`); - }); + cols.forEach(col => this.setColumnDefault(col, `${this.records[rowToCheck][col]}`)); }; updateGPTSummary = async () => { @@ -706,7 +700,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent() { ref={this._sidebarRef} {...this._props} fieldKey={this.fieldKey} - Document={this.Document} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} usePanelWidth diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx index 5a9442d2f..776d65211 100644 --- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx +++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx @@ -17,7 +17,7 @@ import { scaleCreatorNumerical, yAxisCreator } from '../utils/D3Utils'; import './Chart.scss'; export interface HistogramProps { - Document: Doc; + Doc: Doc; layoutDoc: Doc; axes: string[]; titleCol: string; @@ -88,7 +88,7 @@ export class Histogram extends ObservableReactComponent { } @computed get parentViz() { - return DocCast(this._props.Document.dataViz_parentViz); + return DocCast(this._props.Doc.dataViz_parentViz); } @computed get rangeVals(): { xMin?: number; xMax?: number; yMin?: number; yMax?: number } { @@ -126,7 +126,7 @@ export class Histogram extends ObservableReactComponent { const anchor = Docs.Create.ConfigDocument({ title: 'histogram doc selection' + this._currSelected, }); - PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document); + PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Doc); return anchor; }; @@ -416,11 +416,9 @@ export class Histogram extends ObservableReactComponent { let barColor; const barColors = StrListCast(this._props.layoutDoc.dataViz_histogram_barColors).map(each => each.split('::')); barColors.forEach(each => { - // 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]; } }); @@ -454,11 +452,9 @@ export class Histogram extends ObservableReactComponent { let barColor; const barColors = StrListCast(this._props.layoutDoc.dataViz_histogram_barColors).map(each => each.split('::')); barColors.forEach(each => { - // 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]; } }); @@ -471,7 +467,7 @@ export class Histogram extends ObservableReactComponent { this.updateSavedUI(); this._histogramData; let curSelectedBarName = ''; - let titleAccessor: any = 'dataViz_histogram_title'; + let titleAccessor = '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; @@ -503,7 +499,6 @@ export class Histogram extends ObservableReactComponent { 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]); }); diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx index b55d509ff..6b047546c 100644 --- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx @@ -22,7 +22,7 @@ export interface SelectedDataPoint extends DataPoint { } export interface LineChartProps { vizBox: DataVizBox; - Document: Doc; + Doc: Doc; layoutDoc: Doc; axes: string[]; titleCol: string; @@ -53,7 +53,7 @@ export class LineChart extends ObservableReactComponent { } @computed get titleAccessor() { - let titleAccessor: any = 'dataViz_lineChart_title'; + let titleAccessor = '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]; return titleAccessor; @@ -74,7 +74,7 @@ export class LineChart extends ObservableReactComponent { return this._props.axes[1] + ' vs. ' + this._props.axes[0] + ' Line Chart'; } @computed get parentViz() { - return DocCast(this._props.Document.dataViz_parentViz); + return DocCast(this._props.Doc.dataViz_parentViz); } @computed get incomingHighlited() { // return selected x and y axes @@ -113,7 +113,7 @@ export class LineChart extends ObservableReactComponent { // title: 'line doc selection' + (this._currSelected?.x ?? ''), }); - PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document); + PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Doc); anchor.config_dataVizSelection = this._currSelected ? new List([this._currSelected.x, this._currSelected.y]) : undefined; return anchor; }; diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx index 86e6ad8e4..0ae70786f 100644 --- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx +++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx @@ -16,7 +16,7 @@ import { PinProps, PinDocView } from '../../../PinFuncs'; import './Chart.scss'; export interface PieChartProps { - Document: Doc; + Doc: Doc; layoutDoc: Doc; axes: string[]; titleCol: string; @@ -83,7 +83,7 @@ export class PieChart extends ObservableReactComponent { } @computed get parentViz() { - return DocCast(this._props.Document.dataViz_parentViz); + return DocCast(this._props.Doc.dataViz_parentViz); } componentWillUnmount() { @@ -114,7 +114,7 @@ export class PieChart extends ObservableReactComponent { // title: 'piechart doc selection' + this._currSelected, }); - PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Document); + PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: pinProps?.pinData }, this._props.Doc); return anchor; }; @@ -169,7 +169,6 @@ export class PieChart extends ObservableReactComponent { // inside the slice of it crosses an odd number of edges const showSelected = this.byCategory ? pieDataSet[index] : this._pieChartData[index]; let key = 'data'; // key that represents slice - // eslint-disable-next-line prefer-destructuring if (Object.keys(showSelected)[0] === 'frequency') key = Object.keys(showSelected)[1]; if (changeSelectedVariables) { let sameAsAny = false; @@ -296,7 +295,7 @@ export class PieChart extends ObservableReactComponent { if (descriptionField) dataPointVal[descriptionField] = each[descriptionField]; try { dataPointVal[percentField] = Number(dataPointVal[percentField].replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/ { // to make sure all important slice information is on 'd' object let addKey: any = false; if (pieDataSet.length && Object.keys(pieDataSet[0])[0] === 'frequency') { - // eslint-disable-next-line prefer-destructuring addKey = Object.keys(pieDataSet[0])[1]; } arcs.append('path') @@ -324,7 +322,6 @@ export class PieChart extends ObservableReactComponent { const sliceTitle = dataPoint[this._props.axes[0]]; const accessByName = StrCast(sliceTitle) ? StrCast(sliceTitle).replace(/\$/g, '').replace(/%/g, '').replace(/#/g, '').replace(/ { - // eslint-disable-next-line prefer-destructuring each[0] === accessByName && (sliceColor = each[1]); }); } @@ -337,7 +334,7 @@ export class PieChart extends ObservableReactComponent { }); return selectThisData ? 'slice hover' : 'slice'; }) - // @ts-ignore + // @ts-expect-error types don't match .attr('d', arc) .on('click', onPointClick) .on('mouseover', onHover) @@ -388,7 +385,7 @@ export class PieChart extends ObservableReactComponent { }; render() { - let titleAccessor: any = 'dataViz_pie_title'; + let titleAccessor = 'dataViz_pie_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; @@ -420,7 +417,6 @@ export class PieChart extends ObservableReactComponent { let selectedSliceColor; const sliceColors = StrListCast(this._props.layoutDoc.dataViz_pie_sliceColors).map(each => each.split('::')); sliceColors.forEach(each => { - // eslint-disable-next-line prefer-destructuring if (each[0] === curSelectedSliceName!) selectedSliceColor = each[1]; }); diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx index b6183946a..b73123691 100644 --- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx +++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx @@ -19,7 +19,7 @@ import './Chart.scss'; const { DATA_VIZ_TABLE_ROW_HEIGHT } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore interface TableBoxProps { - Document: Doc; + Doc: Doc; layoutDoc: Doc; records: { [key: string]: unknown }[]; selectAxes: (axes: string[]) => void; @@ -81,7 +81,7 @@ export class TableBox extends ObservableReactComponent { } @computed get parentViz() { - return DocCast(this._props.Document.dataViz_parentViz); + return DocCast(this._props.Doc.dataViz_parentViz); } @computed get columns() { @@ -139,21 +139,21 @@ export class TableBox extends ObservableReactComponent { e, moveEv => { // dragging off a column to create a brushed DataVizBox - const sourceAnchorCreator = () => this._props.docView?.()?.Document || this._props.Document; + const sourceAnchorCreator = () => this._props.docView?.()?.Document || this._props.Doc; const targetCreator = (annotationOn: Doc | undefined) => { const doc = this._props.docView?.()?.Document; if (doc) { const embedding = Doc.MakeEmbedding(doc); embedding._dataViz = DataVizView.TABLE; embedding._dataViz_axes = new List([col]); - embedding._dataViz_parentViz = this._props.Document; + embedding._dataViz_parentViz = this._props.Doc; embedding.annotationOn = annotationOn; embedding.histogramBarColors = Field.Copy(this._props.layoutDoc.histogramBarColors); embedding.defaultHistogramColor = this._props.layoutDoc.defaultHistogramColor; embedding.pieSliceColors = Field.Copy(this._props.layoutDoc.pieSliceColors); return embedding; } - return this._props.Document; + return this._props.Doc; }; 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, { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e9353b001..c355e57d4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -758,7 +758,7 @@ export class DocumentViewInternal extends DocComponent { this._changingTitleField = true; })} // prettier-ignore style={{ width: 'max-content', background: SnappingManager.userBackgroundColor, color: SnappingManager.userColor, transformOrigin: 'left', transform: `scale(${this.titleHeight / 30 /* height of Dropdown */})` }}> { if (this.layoutDoc.layout_showTitle) { diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 2e40f39ed..abba99c3d 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -15,6 +15,7 @@ import { FocusViewOptions } from './FocusViewOptions'; import { OpenWhere } from './OpenWhere'; import { WebField } from '../../../fields/URLField'; import { ContextMenuProps } from '../ContextMenuItem'; +import { FormattedTextBox } from './formattedText/FormattedTextBox'; export type FocusFuncType = (doc: Doc, options: FocusViewOptions) => Opt; export type StyleProviderFuncType = ( @@ -83,8 +84,7 @@ export interface FieldViewSharedProps { onDoubleClickScript?: () => ScriptField; onPointerDownScript?: () => ScriptField; onPointerUpScript?: () => ScriptField; - // eslint-disable-next-line no-use-before-define - onKey?: (e: React.KeyboardEvent, fieldProps: FieldViewProps) => boolean | undefined; + onKey?: (e: React.KeyboardEvent, textBox: FormattedTextBox) => boolean | undefined; fitWidth?: (doc: Doc) => boolean | undefined; dontCenter?: 'x' | 'y' | 'xy' | undefined; searchFilterDocs: () => Doc[]; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 5d9718760..d121b492f 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -648,7 +648,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { onClick={action(async () => { this._regenerateLoading = true; if (this._fireflyRefStrength) { - DrawingFillHandler.drawingToImage(this.props.Document, this._fireflyRefStrength, this._regenInput || StrCast(this.Document.title), this.Document)?.then(action(() => (this._regenerateLoading = false))); + DrawingFillHandler.drawingToImage(this.Document, this._fireflyRefStrength, this._regenInput || StrCast(this.Document.title), this.Document)?.then(action(() => (this._regenerateLoading = false))); } else { SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput || StrCast(this.Document.title), true).then( action(newImgs => { diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 32c9efbd9..8911fac6d 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -58,8 +58,8 @@ export class KeyValueBox extends ViewBoxBaseComponent() { onEnterKey = (e: React.KeyboardEvent): void => { if (e.key === 'Enter') { e.stopPropagation(); - if (this._keyInput.current?.value && this._valInput.current?.value && this._props.Document) { - if (KeyValueBox.SetField(this._props.Document, this._keyInput.current.value, this._valInput.current.value)) { + if (this._keyInput.current?.value && this._valInput.current?.value && this.Document) { + if (KeyValueBox.SetField(this.Document, this._keyInput.current.value, this._valInput.current.value)) { this._keyInput.current.value = ''; this._valInput.current.value = ''; document.body.focus(); @@ -137,7 +137,7 @@ export class KeyValueBox extends ViewBoxBaseComponent() { rowHeight = () => 30; @computed get createTable() { - const doc = this._props.Document; + const doc = this.Document; if (!doc) { return ( @@ -305,8 +305,8 @@ export class KeyValueBox extends ViewBoxBaseComponent() { openItems.push({ description: 'Default Perspective', event: () => { - this._props.addDocTab(this._props.Document, OpenWhere.close); - this._props.addDocTab(this._props.Document, OpenWhere.addRight); + this._props.addDocTab(this.Document, OpenWhere.close); + this._props.addDocTab(this.Document, OpenWhere.addRight); }, icon: 'image', }); diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx index 65d78f754..a563b7c1b 100644 --- a/src/client/views/nodes/MapBox/MapBox.tsx +++ b/src/client/views/nodes/MapBox/MapBox.tsx @@ -1300,7 +1300,7 @@ export class MapBox extends ViewBoxAnnotatableComponent() { ref={this._sidebarRef} {...this._props} fieldKey={this.fieldKey} - Document={this.Document} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} usePanelWidth diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx index ddeaf4d0d..e0efab576 100644 --- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx +++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx @@ -798,7 +798,6 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent PanelHeight={returnOne} NativeWidth={returnOne} NativeHeight={returnOne} - onKey={undefined} onDoubleClickScript={undefined} childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} @@ -830,7 +829,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent ref={this._sidebarRef} {...this._props} fieldKey={this.fieldKey} - Document={this.Document} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} usePanelWidth diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 5484179be..78ddafa88 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -535,7 +535,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent() { () { pdfBox={this} sidebarAddDoc={this.sidebarAddDocument} addDocTab={this.sidebarAddDocTab} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} pdf={this._pdf} diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index 6289470b6..999f9c1cd 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -301,7 +301,6 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent()
()
{!(this.dataDoc[this.fieldKey + '_dictation'] instanceof Doc) ? null : ( () { {...this._props} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} fieldKey={this.fieldKey + '_' + this._urlHash} - Document={this.Document} + Doc={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} setHeight={emptyFunction} diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index aa2829aaf..bb0efa917 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -162,7 +162,7 @@ export class DashFieldViewInternal extends ObservableReactComponent (this._expanded ? true : undefined)} diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 9078648e9..925109bfb 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -78,14 +78,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent new FormattedTextBoxComment() }), @@ -153,7 +153,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { let mapStyle = assignedMapStyle; - tx2.doc.descendants((node: any, offset: any /* , index: any */) => { + tx2.doc.descendants((node: Node, offset: number /* , index: any */) => { if ((from === undefined || to === undefined || (from <= offset + node.nodeSize && to >= offset)) && (node.type === schema.nodes.ordered_list || node.type === schema.nodes.list_item)) { - const { path } = tx2.doc.resolve(offset) as any; - let depth = Array.from(path).reduce((p: number, c: any) => p + (c.type === schema.nodes.ordered_list ? 1 : 0), 0); + const { path } = tx2.doc.resolve(offset) as unknown as { path: (number | Node)[] }; // bcz: can't access path .. need to FIX + let depth = Array.from(path).reduce((p: number, c: number | Node) => p + ((c as Node).type === schema.nodes.ordered_list ? 1 : 0), 0); if (node.type === schema.nodes.ordered_list) { if (depth === 0 && !assignedMapStyle) mapStyle = node.attrs.mapStyle; depth++; @@ -34,25 +35,25 @@ export const updateBullets = (tx2: Transaction, schema: Schema, assignedMapStyle return tx2; }; -export function buildKeymap>(schema: S, props: any): KeyMap { - const keys: { [key: string]: any } = {}; +export function buildKeymap>(schema: S, tbox?: FormattedTextBox): KeyMap { + const keys: { [key: string]: Command } = {}; - function bind(key: string, cmd: any) { + function bind(key: string, cmd: Command) { keys[key] = cmd; } function onKey(): boolean | undefined { // bcz: this is pretty hacky -- prosemirror doesn't send us the keyboard event, but the 'event' variable is in scope.. so we access it anyway - // eslint-disable-next-line no-restricted-globals - return props.onKey?.(event, props); + return tbox?._props.onKey?.(event, tbox); } - const canEdit = (state: any) => { - const permissions = GetEffectiveAcl(props.TemplateDataDocument ?? props.Document[DocData]); + const canEdit = (state: EditorState) => { + if (!tbox) return true; + const permissions = GetEffectiveAcl(tbox._props.TemplateDataDocument ?? tbox.Document[DocData]); switch (permissions) { case AclAugment: { - const prevNode = state.selection.$cursor.nodeBefore; + const prevNode = (state.selection as any).$cursor.nodeBefore; const prevUser = !prevNode ? ClientUtils.CurrentUserEmail() : prevNode.marks.lastElement()?.attrs.userid; if (prevUser !== ClientUtils.CurrentUserEmail()) { return false; @@ -64,7 +65,7 @@ export function buildKeymap>(schema: S, props: any): KeyMa return true; }; - const toggleEditableMark = (mark: any) => (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && toggleMark(mark)(state, dispatch); + const toggleEditableMark = (mark: MarkType) => (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && toggleMark(mark)(state, dispatch); // History commands bind('Mod-z', undo); @@ -84,13 +85,13 @@ export function buildKeymap>(schema: S, props: any): KeyMa bind('Mod-U', toggleEditableMark(schema.marks.underline)); // Commands for lists - bind('Ctrl-i', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state as any, dispatch as any)); + bind('Ctrl-i', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state, dispatch)); bind('Ctrl-Tab', () => onKey() || true); bind('Alt-Tab', () => onKey() || true); bind('Meta-Tab', () => onKey() || true); bind('Meta-Enter', () => onKey() || true); - bind('Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Tab', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (onKey()) return true; if (!canEdit(state)) return true; const ref = state.selection; @@ -101,13 +102,13 @@ export function buildKeymap>(schema: S, props: any): KeyMa const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - dispatch(tx3); + dispatch?.(tx3); }) ) { // couldn't sink into an existing list, so wrap in a new one const newstate = state.applyTransaction(state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end))); if ( - !wrapInList(schema.nodes.ordered_list)(newstate.state as any, (tx2: Transaction) => { + !wrapInList(schema.nodes.ordered_list)(newstate.state, (tx2: Transaction) => { const tx25 = updateBullets(tx2, schema); const olNode = tx25.doc.nodeAt(range!.start)!; const tx3 = tx25.setNodeMarkup(range!.start, olNode.type, olNode.attrs, marks); @@ -115,16 +116,16 @@ export function buildKeymap>(schema: S, props: any): KeyMa marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); const tx4 = tx3.setSelection(TextSelection.near(tx3.doc.resolve(state.selection.to + 2))); - dispatch(tx4); + dispatch?.(tx4); }) ) { console.log('bullet promote fail'); } } - return undefined; + return false; }); - bind('Shift-Tab', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Shift-Tab', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (onKey()) return true; if (!canEdit(state)) return true; const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); @@ -134,72 +135,83 @@ export function buildKeymap>(schema: S, props: any): KeyMa const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - dispatch(tx3); + dispatch?.(tx3); }) ) { console.log('bullet demote fail'); } - return undefined; + return false; }); // Command to create a new Tab with a PDF of all the command shortcuts - bind('Mod-/', () => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + bind('Mod-/', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { const newDoc = Docs.Create.PdfDocument(ClientUtils.prepend('/assets/cheat-sheet.pdf'), { _width: 300, _height: 300 }); - props.addDocTab(newDoc, OpenWhere.addRight); + tbox?._props.addDocTab(newDoc, OpenWhere.addRight); + return false; }); // Commands to modify BlockType - bind('Ctrl->', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state && wrapIn(schema.nodes.blockquote)(state as any, dispatch as any))); - bind('Alt-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.paragraph)(state as any, dispatch as any)); - bind('Shift-Ctrl-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.code_block)(state as any, dispatch as any)); + bind('Ctrl->', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && wrapIn(schema.nodes.blockquote)(state, dispatch)); + bind('Alt-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && setBlockType(schema.nodes.paragraph)(state, dispatch)); + bind('Shift-Ctrl-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && setBlockType(schema.nodes.code_block)(state, dispatch)); - bind('Ctrl-m', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Ctrl-m', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (canEdit(state)) { const tr = state.tr.replaceSelectionWith(schema.nodes.equation.create({ fieldKey: 'math' + Utils.GenerateGuid() })); - dispatch(tr.setSelection(new NodeSelection(tr.doc.resolve(tr.selection.$from.pos - 1)))); + dispatch?.(tr.setSelection(new NodeSelection(tr.doc.resolve(tr.selection.$from.pos - 1)))); + return true; } + return false; }); for (let i = 1; i <= 6; i++) { - bind('Shift-Ctrl-' + i, (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && setBlockType(schema.nodes.heading, { level: i })(state as any, dispatch as any)); + bind('Shift-Ctrl-' + i, (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && setBlockType(schema.nodes.heading, { level: i })(state, dispatch)); } // Command to create a horizontal break line const hr = schema.nodes.horizontal_rule; - bind('Mod-_', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView())); + bind('Mod-_', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + if (canEdit(state)) { + dispatch?.(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()); + return true; + } + return false; + }); // Command to unselect all - bind('Escape', (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); - (document.activeElement as any).blur?.(); + bind('Escape', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + dispatch?.(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); + (document.activeElement as HTMLElement)?.blur?.(); DocumentView.DeselectAll(); + return true; }); bind('Alt-Enter', () => onKey() || true); bind('Ctrl-Enter', () => onKey() || true); - bind('Cmd-a', (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); + bind('Cmd-a', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + dispatch?.(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); return true; }); bind('Cmd-?', () => { RTFMarkup.Instance.setOpen(true); return true; }); - bind('Cmd-e', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Cmd-e', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { if (!state.selection.empty) { const mark = state.schema.marks.summarizeInclusive.create(); const tr = state.tr.addMark(state.selection.$from.pos, state.selection.$to.pos, mark); const content = tr.selection.content(); - tr.selection.replaceWith(tr, schema.nodes.summary.create({ visibility: false, text: content, textslice: content.toJSON() })); - dispatch(tr); + tr.selection.replaceWith(tr, schema.nodes.summary.create({ visibility: false, text: content, textslice: content.toJSON() }, undefined, state.selection.$anchor.marks() ?? [])); + dispatch?.(tr); } return true; }); - bind('Cmd-]', (state: EditorState, dispatch: (tx: Transaction) => void) => { - const resolved = state.doc.resolve(state.selection.from) as any; + bind('Cmd-]', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + const resolved = state.doc.resolve(state.selection.from) as ResolvedPos & { path: (Node | number)[] }; // bcz: this is bad. path is not publically visible const { tr } = state; if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); + tr.setNodeMarkup(resolved.path[resolved.path.length - 4] as number, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'right' }, resolved.parent.marks); } else { const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -207,14 +219,14 @@ export function buildKeymap>(schema: S, props: any): KeyMa tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'right' })).setStoredMarks([...node.marks, ...(sm || [])]); } } - dispatch(tr); + dispatch?.(tr); return true; }); - bind('Cmd-\\', (state: EditorState, dispatch: (tx: Transaction) => void) => { - const resolved = state.doc.resolve(state.selection.from) as any; + bind('Cmd-\\', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + const resolved = state.doc.resolve(state.selection.from) as ResolvedPos & { path: (Node | number)[] }; // bcz: this is bad. path is not publically visible const { tr } = state; if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); + tr.setNodeMarkup(resolved.path[resolved.path.length - 4] as number, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'center' }, resolved.parent.marks); } else { const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -222,14 +234,14 @@ export function buildKeymap>(schema: S, props: any): KeyMa tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'center' })).setStoredMarks([...node.marks, ...(sm || [])]); } } - dispatch(tr); + dispatch?.(tr); return true; }); - bind('Cmd-[', (state: EditorState, dispatch: (tx: Transaction) => void) => { - const resolved = state.doc.resolve(state.selection.from) as any; + bind('Cmd-[', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + const resolved = state.doc.resolve(state.selection.from) as ResolvedPos & { path: (Node | number)[] }; // bcz: this is bad. path is not publically visible const { tr } = state; if (resolved?.parent.type.name === 'paragraph') { - tr.setNodeMarkup(resolved.path[resolved.path.length - 4], schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); + tr.setNodeMarkup(resolved.path[resolved.path.length - 4] as number, schema.nodes.paragraph, { ...resolved.parent.attrs, align: 'left' }, resolved.parent.marks); } else { const node = resolved.nodeAfter; const sm = state.storedMarks || undefined; @@ -237,16 +249,16 @@ export function buildKeymap>(schema: S, props: any): KeyMa tr.replaceRangeWith(state.selection.from, state.selection.from, schema.nodes.paragraph.create({ align: 'left' })).setStoredMarks([...node.marks, ...(sm || [])]); } } - dispatch(tr); + dispatch?.(tr); return true; }); - bind('Cmd-f', (state: EditorState, dispatch: (tx: Transaction) => void) => { + bind('Cmd-f', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { const content = state.tr.selection.empty ? undefined : state.tr.selection.content().content.textBetween(0, state.tr.selection.content().size + 1); const newNode = schema.nodes.footnote.create({}, content ? state.schema.text(content) : undefined); const { tr } = state; tr.replaceSelectionWith(newNode); // replace insertion with a footnote. - dispatch( + dispatch?.( tr.setSelection( new NodeSelection( // select the footnote node to open its display tr.doc.resolve( @@ -259,25 +271,25 @@ export function buildKeymap>(schema: S, props: any): KeyMa return true; }); - bind('Ctrl-a', (state: EditorState, dispatch: (tx: Transaction) => void) => { - dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); + bind('Ctrl-a', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => { + dispatch?.(state.tr.setSelection(new TextSelection(state.doc.resolve(1), state.doc.resolve(state.doc.content.size - 1)))); return true; }); // backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward); - const backspace = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView) => { + const backspace = (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined, view?: EditorView) => { if (onKey()) return true; if (!canEdit(state)) return true; if ( !deleteSelection(state, (tx: Transaction) => { - dispatch(updateBullets(tx, schema)); + dispatch?.(updateBullets(tx, schema)); }) ) { if ( !joinBackward(state, (tx: Transaction) => { - dispatch(updateBullets(tx, schema)); - if (view.state.selection.$anchor.node(-1)?.type === schema.nodes.list_item) { + dispatch?.(updateBullets(tx, schema)); + if (view?.state.selection.$anchor.node(-1)?.type === schema.nodes.list_item) { // gets rid of an extra paragraph when joining two list items together. joinBackward(view.state, (tx2: Transaction) => view.dispatch(tx2)); } @@ -285,7 +297,7 @@ export function buildKeymap>(schema: S, props: any): KeyMa ) { if ( !selectNodeBackward(state, (tx: Transaction) => { - dispatch(updateBullets(tx, schema)); + dispatch?.(updateBullets(tx, schema)); }) ) { return false; @@ -299,7 +311,7 @@ export function buildKeymap>(schema: S, props: any): KeyMa // newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock // command to break line - const enter = (state: EditorState, dispatch: (tx: Transaction) => void, view: EditorView, once = true) => { + const enter = (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined, view?: EditorView, once = true) => { if (onKey()) return true; if (!canEdit(state)) return true; @@ -311,31 +323,31 @@ export function buildKeymap>(schema: S, props: any): KeyMa !state.selection.$from.node().content.size && trange ) { - dispatch(state.tr.lift(trange, depth) as any); + dispatch?.(state.tr.lift(trange, depth)); return true; } const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); - if (!newlineInCode(state, dispatch as any)) { - const olNode = view.state.selection.$anchor.node(-2); - const liNode = view.state.selection.$anchor.node(-1); + if (!newlineInCode(state, dispatch)) { + const olNode = view?.state.selection.$anchor.node(-2); + const liNode = view?.state.selection.$anchor.node(-1); // prettier-ignore if (liNode?.type === schema.nodes.list_item && !liNode.textContent && - olNode?.type === schema.nodes.ordered_list && once && view.state.selection.$from.depth === 3) + olNode?.type === schema.nodes.ordered_list && once && view?.state.selection.$from.depth === 3) { // handles case of hitting enter at then end of a top-level empty list item - the result is to create a paragraph - for (let i = 0; i < 10 && view.state.selection.$from.depth > 1 && liftListItem(schema.nodes.list_item)(view.state, view.dispatch); i++); + for (let i = 0; i < 10 && view?.state.selection.$from.depth > 1 && liftListItem(schema.nodes.list_item)(view.state, view.dispatch); i++); } else if ( - !splitListItem(schema.nodes.list_item)(state as any, (tx2: Transaction) => { + !splitListItem(schema.nodes.list_item)(state, (tx2: Transaction) => { const tx3 = updateBullets(tx2, schema); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - dispatch(tx3); + dispatch?.(tx3); // removes an extra paragraph created when selecting text across two list items or splitting an empty list item - !once && view.dispatch(view.state.tr.deleteRange(view.state.selection.from - 5, view.state.selection.from - 2)); + !once && view?.dispatch(view?.state.tr.deleteRange(view.state.selection.from - 5, view.state.selection.from - 2)); }) ) { - if (once && view.state.selection.$from.node(-2)?.type === schema.nodes.ordered_list && view.state.selection.$from.node(-1)?.type === schema.nodes.list_item && view.state.selection.$from.node(-1)?.textContent === '') { + if (once && view?.state.selection.$from.node(-2)?.type === schema.nodes.ordered_list && view?.state.selection.$from.node(-1)?.type === schema.nodes.list_item && view.state.selection.$from.node(-1)?.textContent === '') { // handles case of hitting enter on an empty list item which needs to create a second empty paragraph, then split it by calling enter() again view.dispatch(view.state.tr.insert(view.state.selection.from, schema.nodes.paragraph.create({}))); enter(view.state, view.dispatch, view, false); @@ -346,12 +358,12 @@ export function buildKeymap>(schema: S, props: any): KeyMa const tonode = tx3.selection.$to.node(); if (tx3.selection.to && tx3.doc.nodeAt(tx3.selection.to - 1)) { const tx4 = tx3.setNodeMarkup(tx3.selection.to - 1, tonode.type, fromattrs, tonode.marks).setStoredMarks(marks || []); - dispatch(tx4); + dispatch?.(tx4); } - if (view.state.selection.$anchor.depth > 0 && - view.state.selection.$anchor.node(view.state.selection.$anchor.depth-1).type === schema.nodes.list_item && - view.state.selection.$anchor.nodeAfter?.type === schema.nodes.text && once) { + if ((view?.state.selection.$anchor.depth ??0) > 0 && + view?.state.selection.$anchor.node(view.state.selection.$anchor.depth-1).type === schema.nodes.list_item && + view?.state.selection.$anchor.nodeAfter?.type === schema.nodes.text && once) { // if text is selected across list items, then we need to forcibly insert a new line since the splitBlock code joins the two list items. enter(view.state, dispatch, view, false); } @@ -368,14 +380,14 @@ export function buildKeymap>(schema: S, props: any): KeyMa // Command to create a blank space bind('Space', () => { - const editDoc = props.TemplateDataDocument ?? props.Document[DocData]; + const editDoc = tbox?._props.TemplateDataDocument ?? tbox?.Document[DocData]; if (editDoc && ![AclAdmin, AclAugment, AclEdit].includes(GetEffectiveAcl(editDoc))) return true; return false; }); - bind('Alt-ArrowUp', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && joinUp(state, dispatch as any)); - bind('Alt-ArrowDown', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && joinDown(state, dispatch as any)); - bind('Mod-BracketLeft', (state: EditorState, dispatch: (tx: Transaction) => void) => canEdit(state) && lift(state, dispatch as any)); + bind('Alt-ArrowUp', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && joinUp(state, dispatch)); + bind('Alt-ArrowDown', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && joinDown(state, dispatch)); + bind('Mod-BracketLeft', (state: EditorState, dispatch: ((tx: Transaction) => void) | undefined) => canEdit(state) && lift(state, dispatch)); const cmd = chainCommands(exitCode, (state, dispatch) => { if (dispatch) { diff --git a/src/client/views/nodes/formattedText/SummaryView.tsx b/src/client/views/nodes/formattedText/SummaryView.tsx index 238267f6e..6dea891a0 100644 --- a/src/client/views/nodes/formattedText/SummaryView.tsx +++ b/src/client/views/nodes/formattedText/SummaryView.tsx @@ -1,12 +1,11 @@ import { TextSelection } from 'prosemirror-state'; -import { Fragment, Node, Slice } from 'prosemirror-model'; +import { Attrs, Fragment, Node, Slice } from 'prosemirror-model'; import * as ReactDOM from 'react-dom/client'; import * as React from 'react'; +import { EditorView } from 'prosemirror-view'; -interface ISummaryView {} // currently nothing needs to be rendered for the internal view of a summary. -// eslint-disable-next-line react/prefer-stateless-function -export class SummaryViewInternal extends React.Component { +export class SummaryViewInternal extends React.Component { render() { return null; } @@ -18,30 +17,30 @@ export class SummaryViewInternal extends React.Component { // method instead of changing prosemirror's text when the expand/elide buttons are clicked. export class SummaryView { dom: HTMLSpanElement; // container for label and value - root: any; + root: ReactDOM.Root; - constructor(node: any, view: any, getPos: any) { + constructor(node: Node, view: EditorView, getPos: () => number | undefined) { this.dom = document.createElement('span'); this.dom.className = this.className(node.attrs.visibility); - this.dom.onpointerdown = (e: any) => { + this.dom.onpointerdown = (e: PointerEvent) => { this.onPointerDown(e, node, view, getPos); }; - this.dom.onkeypress = function (e: any) { + this.dom.onkeypress = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onkeydown = function (e: any) { + this.dom.onkeydown = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onkeyup = function (e: any) { + this.dom.onkeyup = function (e: KeyboardEvent) { e.stopPropagation(); }; - this.dom.onmousedown = function (e: any) { + this.dom.onmousedown = function (e: MouseEvent) { e.stopPropagation(); }; const js = node.toJSON; - node.toJSON = function (...args: any[]) { - return js.apply(this, args); + node.toJSON = function (...args: unknown[]) { + return js.apply(this, args as []); }; this.root = ReactDOM.createRoot(this.dom); @@ -54,7 +53,7 @@ export class SummaryView { } selectNode() {} - updateSummarizedText(start: any, view: any) { + updateSummarizedText(start: number, view: EditorView) { const mtype = view.state.schema.marks.summarize; const mtypeInc = view.state.schema.marks.summarizeInclusive; let endPos = start; @@ -65,7 +64,7 @@ export class SummaryView { // eslint-disable-next-line no-loop-func view.state.doc.nodesBetween(start, i, (node: Node /* , pos: number, parent: Node, index: number */) => { if (node.isLeaf && !visited.has(node) && !skip) { - if (node.marks.find((m: any) => m.type === mtype || m.type === mtypeInc)) { + if (node.marks.find(m => m.type === mtype || m.type === mtypeInc)) { visited.add(node); endPos = i + node.nodeSize - 1; } else skip = true; @@ -75,21 +74,18 @@ export class SummaryView { return TextSelection.create(view.state.doc, start, endPos); } - onPointerDown = (e: any, node: any, view: any, getPos: any) => { + onPointerDown = (e: PointerEvent, node: Node, view: EditorView, getPos: () => number | undefined) => { const visible = !node.attrs.visibility; - const attrs = { ...node.attrs, visibility: visible }; - let textSelection = TextSelection.create(view.state.doc, getPos() + 1); - if (!visible) { - // update summarized text and save in attrs - textSelection = this.updateSummarizedText(getPos() + 1, view); - attrs.text = textSelection.content(); - attrs.textslice = attrs.text.toJSON(); - } + const textSelection = visible // + ? TextSelection.create(view.state.doc, (getPos() ?? 0) + 1) + : this.updateSummarizedText((getPos() ?? 0) + 1, view); // update summarized text and save in attrs + const text = textSelection.content(); + const attrs = { ...node.attrs, visibility: visible, ...(!visible ? { text, textslice: text.toJSON() } : {}) } as Attrs; view.dispatch( view.state.tr .setSelection(textSelection) // select the current summarized text (or where it will be if its collapsed) .replaceSelection(!visible ? new Slice(Fragment.fromArray([]), 0, 0) : node.attrs.text) // collapse/expand it - .setNodeMarkup(getPos(), undefined, attrs) + .setNodeMarkup(getPos() ?? 0, undefined, attrs) ); // update the attrs e.preventDefault(); e.stopPropagation(); diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 2142adac8..73c2f5eb8 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -35,7 +35,7 @@ export * from 'pdfjs-dist/build/pdf.mjs'; interface IViewerProps extends FieldViewProps { pdfBox: PDFBox; - Document: Doc; + Doc: Doc; dataDoc: Doc; layoutDoc: Doc; fieldKey: string; @@ -113,8 +113,8 @@ export class PDFViewer extends ObservableReactComponent { () => this._props.layoutDoc._layout_autoHeight, layoutAutoHeight => { if (layoutAutoHeight) { - this._props.layoutDoc._nativeHeight = NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']); - this._props.setHeight?.(NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1)); + this._props.layoutDoc._nativeHeight = NumCast(this._props.Doc[this._props.fieldKey + '_nativeHeight']); + this._props.setHeight?.(NumCast(this._props.Doc[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1)); } } ); @@ -125,7 +125,7 @@ export class PDFViewer extends ObservableReactComponent { { fireImmediately: true } ); this._disposers.curPage = reaction( - () => Cast(this._props.Document._layout_curPage, 'number', null), + () => Cast(this._props.Doc._layout_curPage, 'number', null), page => page !== undefined && page !== this._pdfViewer?.currentPageNumber && this.gotoPage(page), { fireImmediately: true } ); @@ -181,7 +181,7 @@ export class PDFViewer extends ObservableReactComponent { scrollFocus = (doc: Doc, scrollTop: number, options: FocusViewOptions) => { const mainCont = this._mainCont.current; let focusSpeed: Opt; - if (doc !== this._props.Document && mainCont) { + if (doc !== this._props.Doc && mainCont) { const windowHeight = this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); const scrollTo = ClientUtils.scrollIntoView(scrollTop, doc[Height](), NumCast(this._props.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, this._scrollHeight); if (scrollTo !== undefined && scrollTo !== this._props.layoutDoc._layout_scrollTop) { @@ -216,11 +216,11 @@ export class PDFViewer extends ObservableReactComponent { { fireImmediately: true } ); this._disposers.scroll = reaction( - () => Math.abs(NumCast(this._props.Document._layout_scrollTop)), + () => Math.abs(NumCast(this._props.Doc._layout_scrollTop)), pos => { if (!this._ignoreScroll) { this._showWaiting && this.setupPdfJsViewer(); - const viewTrans = quickScroll?.loc ?? StrCast(this._props.Document._viewTransition); + const viewTrans = quickScroll?.loc ?? StrCast(this._props.Doc._viewTransition); const durationMiliStr = viewTrans.match(/([0-9]*)ms/); const durationSecStr = viewTrans.match(/([0-9.]*)s/); const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0; @@ -371,9 +371,9 @@ export class PDFViewer extends ObservableReactComponent { // if alt+left click, drag and annotate this._downX = e.clientX; this._downY = e.clientY; - if ((this._props.Document._freeform_scale || 1) !== 1) return; + if ((this._props.Doc._freeform_scale || 1) !== 1) return; if ((e.button !== 0 || e.altKey) && this._props.isContentActive()) { - this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this._props.Document); + this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this._props.Doc); } if (!e.altKey && e.button === 0 && this._props.isContentActive() && Doc.ActiveTool !== InkTool.Ink) { this._props.select(false); @@ -433,7 +433,7 @@ export class PDFViewer extends ObservableReactComponent { addDrawingAnnotation = (drawing: Doc) => { // drawing.x = this._props.pdfBox.ScreenToLocalBoxXf().TranslateX // const scaleX = this._mainCont.current.offsetWidth / boundingRect.width; - drawing.y = NumCast(drawing.y) + NumCast(this._props.Document.layout_scrollTop); + drawing.y = NumCast(drawing.y) + NumCast(this._props.Doc.layout_scrollTop); this._props.addDocument?.(drawing); }; @@ -478,7 +478,7 @@ export class PDFViewer extends ObservableReactComponent { onClick = (e: React.MouseEvent) => { this._scrollStopper?.(); if (this._setPreviewCursor && e.button === 0 && Math.abs(e.clientX - this._downX) < ClientUtils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < ClientUtils.DRAG_THRESHOLD) { - this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Document); + this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Doc); } // e.stopPropagation(); // bcz: not sure why this was here. We need to allow the DocumentView to get clicks to process doubleClicks }; @@ -506,7 +506,7 @@ export class PDFViewer extends ObservableReactComponent { @computed get annotationLayer() { const inlineAnnos = this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).filter(anno => !anno.hidden); return ( -
+
{inlineAnnos.map(anno => ( ))} @@ -597,7 +597,7 @@ export class PDFViewer extends ObservableReactComponent { onClick={this.onClick} style={{ overflowX: NumCast(this._props.layoutDoc._freeform_scale, 1) !== 1 ? 'scroll' : undefined, - height: !this._props.Document._layout_fitWidth && window.screen.width > 600 ? Doc.NativeHeight(this._props.Document) : `100%`, + height: !this._props.Doc._layout_fitWidth && window.screen.width > 600 ? Doc.NativeHeight(this._props.Doc) : `100%`, }}> {this.pdfViewerDiv} {this.annotationLayer} @@ -606,12 +606,12 @@ export class PDFViewer extends ObservableReactComponent { {!this._mainCont.current || !this._annotationLayer.current || !this.props.pdfBox.DocumentView ? null : ( Pdfjs.PixelsPerInch.PDF_TO_CSS_UNITS} - annotationLayerScrollTop={NumCast(this._props.Document._layout_scrollTop)} + annotationLayerScrollTop={NumCast(this._props.Doc._layout_scrollTop)} addDocument={this.addDocumentWrapper} docView={this.props.pdfBox.DocumentView} screenTransform={this.screenToMarqueeXf} diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 8b7e77fba..1f6e80bd1 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -27,7 +27,7 @@ const MAX_ITERATIONS = 25; const ERROR = 0.03; export interface SearchBoxItemProps { - Document: Doc; + Doc: Doc; searchString: string; isLinkSearch: boolean; matchedKeys: string[]; @@ -64,7 +64,7 @@ export class SearchBoxItem extends ObservableReactComponent }); componentWillUnmount(): void { - const doc = this._props.Document; + const doc = this._props.Doc; DocumentView.getFirstDocumentView(doc)?.ComponentView?.search?.('', undefined, true); } @@ -79,23 +79,23 @@ export class SearchBoxItem extends ObservableReactComponent render() { // eslint-disable-next-line no-use-before-define - const formattedType = SearchBox.formatType(StrCast(this._props.Document.type), StrCast(this._props.Document.type_collection)); - const { title } = this._props.Document; + const formattedType = SearchBox.formatType(StrCast(this._props.Doc.type), StrCast(this._props.Doc.type_collection)); + const { title } = this._props.Doc; return ( {title as string}
}>
this.makeLink(this._props.Document) + ? () => this.makeLink(this._props.Doc) : e => { - this.onResultClick(this._props.Document); + this.onResultClick(this._props.Doc); e.stopPropagation(); } } style={{ fontWeight: Doc.Links(this._props.linkFrom).find( - link => Doc.AreProtosEqual(Doc.getOppositeAnchor(link, this._props.linkFrom!), this._props.Document) || Doc.AreProtosEqual(DocCast(Doc.getOppositeAnchor(link, this._props.linkFrom!)?.annotationOn), this._props.Document) + link => Doc.AreProtosEqual(Doc.getOppositeAnchor(link, this._props.linkFrom!), this._props.Doc) || Doc.AreProtosEqual(DocCast(Doc.getOppositeAnchor(link, this._props.linkFrom!)?.annotationOn), this._props.Doc) ) ? 'bold' : '', @@ -449,7 +449,7 @@ export class SearchBox extends ViewBoxBaseComponent() { resultsJSX.push( { this._selectedResult = doc; })} diff --git a/src/client/views/smartdraw/StickerPalette.tsx b/src/client/views/smartdraw/StickerPalette.tsx index 080a05d42..2260d1f73 100644 --- a/src/client/views/smartdraw/StickerPalette.tsx +++ b/src/client/views/smartdraw/StickerPalette.tsx @@ -25,7 +25,7 @@ import { DrawingOptions, SmartDrawHandler } from './SmartDrawHandler'; import './StickerPalette.scss'; interface StickerPaletteProps { - Document: Doc; + Doc: Doc; } enum StickerPaletteMode { @@ -132,7 +132,7 @@ export class StickerPalette extends ObservableReactComponent { this._isLoading = true; - const prevDrawings = DocListCast(this._props.Document.$data); - this._props.Document.$data = undefined; + const prevDrawings = DocListCast(this._props.Doc.$data); + this._props.Doc.$data = undefined; SmartDrawHandler.Instance.AddDrawing = this.addDrawing; this._canInteract = false; Promise.all( @@ -164,7 +164,7 @@ export class StickerPalette extends ObservableReactComponent { this._gptRes.push(gptRes); drawing.$freeform_fitContentsToBox = true; - Doc.AddDocToList(this._props.Document, 'data', drawing); + Doc.AddDocToList(this._props.Doc, 'data', drawing); }; /** @@ -173,8 +173,8 @@ export class StickerPalette extends ObservableReactComponent { - const cIndex = NumCast(this._props.Document.carousel_index); - const focusedDrawing = DocListCast(this._props.Document.data)[cIndex]; + const cIndex = NumCast(this._props.Doc.carousel_index); + const focusedDrawing = DocListCast(this._props.Doc.data)[cIndex]; focusedDrawing.$title = this._opts.text?.match(/^(.*?)~~~.*$/)?.[1] || this._opts.text; focusedDrawing.$ai_drawing_input = this._opts.text; focusedDrawing.$ai_drawing_complexity = this._opts.complexity; @@ -313,7 +313,7 @@ export class StickerPalette extends ObservableReactComponent {this.renderCreateInput()} {this.renderCreateOptions()} - {this.renderDoc(this._props.Document, (r: DocumentView) => { + {this.renderDoc(this._props.Doc, (r: DocumentView) => { this._docCarouselView = r; })}
diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts index 42dd0d432..e16073ff4 100644 --- a/src/fields/RichTextUtils.ts +++ b/src/fields/RichTextUtils.ts @@ -20,6 +20,7 @@ import { Doc, Opt } from './Doc'; import { Id } from './FieldSymbols'; import { RichTextField } from './RichTextField'; import { Cast, StrCast } from './Types'; +import { Upload } from '../server/SharedMediaTypes'; export namespace RichTextUtils { const delimiter = '\n'; @@ -127,7 +128,7 @@ export namespace RichTextUtils { return { baseUrl: embeddedObject.imageProperties!.contentUri! }; }); - const uploads = await Networking.PostToServer('/googlePhotosMediaGet', { mediaItems }); + const uploads = (await Networking.PostToServer('/googlePhotosMediaGet', { mediaItems })) as Upload.FileInformation[]; if (uploads.length !== mediaItems.length) { throw new AssertionError({ expected: mediaItems.length, actual: uploads.length, message: 'Error with internally uploading inlineObjects!' }); diff --git a/src/fields/Types.ts b/src/fields/Types.ts index 474882959..af9cb1180 100644 --- a/src/fields/Types.ts +++ b/src/fields/Types.ts @@ -60,16 +60,13 @@ export type CastCtor = ToConstructor | ListSpec; type WithoutList = T extends List ? (R extends RefField ? (R | Promise)[] : R[]) : T; export function Cast(field: FieldResult, ctor: T): FieldResult>; -// eslint-disable-next-line no-redeclare export function Cast(field: FieldResult, ctor: T, defaultVal: WithoutList>> | null): WithoutList>; -// eslint-disable-next-line no-redeclare export function Cast(field: FieldResult, ctor: T, defaultVal?: ToType | null): FieldResult> | undefined { if (field instanceof Promise) { return defaultVal === undefined ? (field.then(f => Cast(f, ctor) as any) as any) : defaultVal === null ? undefined : defaultVal; } if (field !== undefined && !(field instanceof Promise)) { if (typeof ctor === 'string') { - // eslint-disable-next-line valid-typeof if (typeof field === ctor) { return field as ToType; } @@ -140,9 +137,7 @@ export function ImageCastWithSuffix(field: FieldResult, suffix: string, defaultV } export function FieldValue>(field: FieldResult, defaultValue: U): WithoutList; -// eslint-disable-next-line no-redeclare export function FieldValue(field: FieldResult): Opt; -// eslint-disable-next-line no-redeclare export function FieldValue(field: FieldResult, defaultValue?: T): Opt { return field instanceof Promise || field === undefined ? defaultValue : field; } diff --git a/src/server/DashSession/DashSessionAgent.ts b/src/server/DashSession/DashSessionAgent.ts index 891316b80..8688ec049 100644 --- a/src/server/DashSession/DashSessionAgent.ts +++ b/src/server/DashSession/DashSessionAgent.ts @@ -213,9 +213,9 @@ export class DashSessionAgent extends AppliedSessionAgent { // indicate success or failure mainLog(`${error === null ? green('successfully dispatched') : red('failed to dispatch')} ${zipName} to ${cyan(to)}`); error && mainLog(red(error.message)); - } catch (error: any) { + } catch (error: unknown) { mainLog(red('unable to dispatch zipped backup...')); - mainLog(red(error.message)); + mainLog(red((error as { message: string }).message)); } } } -- cgit v1.2.3-70-g09d2 From 29a1fe16297c99ddbed7974b7c602294da9a311d Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 25 Mar 2025 22:40:30 -0400 Subject: fixes to components so that things highlight reasonably in different skins. fixed color picker alternate selection. --- .../components/src/components/Button/Button.scss | 12 +- .../components/src/components/Button/Button.tsx | 345 ++++++++++----------- .../src/components/ColorPicker/ColorPicker.tsx | 44 ++- .../src/components/Dropdown/Dropdown.tsx | 13 +- .../components/DropdownSearch/DropdownSearch.tsx | 190 +++++------- .../src/components/EditableText/EditableText.tsx | 309 +++++++++--------- .../src/components/IconButton/IconButton.scss | 17 +- .../src/components/IconButton/IconButton.tsx | 27 +- .../src/components/ListItem/ListItem.tsx | 2 +- .../src/components/MultiToggle/MultiToggle.tsx | 143 +++++---- .../components/NumberDropdown/NumberDropdown.tsx | 46 ++- .../src/components/NumberInput/NumberInput.tsx | 137 ++++---- packages/components/src/components/Popup/Popup.tsx | 8 +- .../components/src/components/Slider/Slider.tsx | 16 +- .../components/src/components/Toggle/Toggle.tsx | 309 +++++++++--------- packages/components/src/global/globalEnums.tsx | 67 ++-- packages/components/src/global/globalUtils.tsx | 163 +++++----- src/client/util/CalendarManager.tsx | 2 +- src/client/util/GroupManager.tsx | 14 +- src/client/util/SettingsManager.tsx | 28 +- src/client/util/SharingManager.tsx | 4 +- src/client/util/SnappingManager.ts | 54 ++-- src/client/views/StyleProvider.tsx | 4 +- src/client/views/collections/CollectionMenu.tsx | 11 +- src/client/views/nodes/FontIconBox/FontIconBox.tsx | 36 ++- src/client/views/pdf/GPTPopup/GPTPopup.scss | 4 +- src/client/views/pdf/GPTPopup/GPTPopup.tsx | 46 +-- src/client/views/topbar/TopBar.tsx | 23 +- 28 files changed, 1048 insertions(+), 1026 deletions(-) (limited to 'src/client/views/pdf') diff --git a/packages/components/src/components/Button/Button.scss b/packages/components/src/components/Button/Button.scss index bbe2e2470..b2fb48344 100644 --- a/packages/components/src/components/Button/Button.scss +++ b/packages/components/src/components/Button/Button.scss @@ -53,7 +53,7 @@ &.inactive { &:hover { .background { - filter: opacity(0) !important; + filter: opacity(0); } } } @@ -63,13 +63,13 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.5); } } &:hover { .background { - filter: opacity(0.2); + filter: opacity(0.3); } } } @@ -79,7 +79,7 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.2); } } @@ -96,12 +96,12 @@ } .background { - filter: opacity(1) !important; + filter: opacity(1); } &:hover { .background { - filter: brightness(0.8); + filter: opacity(0.3); } } } diff --git a/packages/components/src/components/Button/Button.tsx b/packages/components/src/components/Button/Button.tsx index a91c74a4c..885403640 100644 --- a/packages/components/src/components/Button/Button.tsx +++ b/packages/components/src/components/Button/Button.tsx @@ -1,195 +1,188 @@ -import { Tooltip } from '@mui/material' -import React from 'react' -import { Alignment, IGlobalProps, Placement, Type , getFormLabelSize } from '../../global' -import { Colors, Size } from '../../global/globalEnums' -import { getFontSize, getHeight, isDark } from '../../global/globalUtils' -import { IconButton } from '../IconButton' -import './Button.scss' +import { Tooltip } from '@mui/material'; +import React from 'react'; +import { Alignment, IGlobalProps, Placement, Type, getFormLabelSize } from '../../global'; +import { Colors, Size } from '../../global/globalEnums'; +import { getFontSize, getHeight } from '../../global/globalUtils'; +import { IconButton } from '../IconButton'; +import './Button.scss'; export interface IButtonProps extends IGlobalProps { - onClick?: (event: React.MouseEvent) => void - onDoubleClick?: (event: React.MouseEvent) => void - type?: Type - active?: boolean + onClick?: (event: React.MouseEvent) => void; + onDoubleClick?: (event: React.MouseEvent) => void; + type?: Type; + active?: boolean; - // Content - text?: string - icon?: JSX.Element | string + // Content + text?: string; + icon?: JSX.Element | string; - // Additional stylization - iconPlacement?: Placement - color?: string - colorPicker?: string, - uppercase?: boolean, - align?: Alignment + // Additional stylization + iconPlacement?: Placement; + color?: string; + colorPicker?: string; + uppercase?: boolean; + align?: Alignment; + filter?: string; } export const Button = (props: IButtonProps) => { - const { - text, - icon, - onClick, - onDoubleClick, - onPointerDown, - active, - height, - inactive, - type = Type.PRIM, - label, - uppercase = false, - iconPlacement = 'right', - size = Size.SMALL, - color = Colors.MEDIUM_BLUE, - background, - style, - tooltip, - tooltipPlacement = 'top', - colorPicker, - formLabel, - formLabelPlacement, - fillWidth, - align = fillWidth ? 'flex-start' : 'center' - } = props + const { + text, + icon, + onClick, + onDoubleClick, + onPointerDown, + active, + height, + inactive, + type = Type.PRIM, + filter, + uppercase = false, + iconPlacement = 'right', + size = Size.SMALL, + color = Colors.MEDIUM_BLUE, + background, + style, + tooltip, + tooltipPlacement = 'top', + colorPicker, + formLabel, + formLabelPlacement, + fillWidth, + align = fillWidth ? 'flex-start' : 'center', + } = props; - if (!text) { - return - } - - /** - * Pointer down - * @param e - */ - const handlePointerDown = (e: React.PointerEvent) => { - - if (!inactive && onPointerDown) { - e.stopPropagation(); - e.preventDefault(); - onPointerDown(e) + if (!text) { + return ; } - } - /** - * In the event that there is a single click - * @param e - */ - const handleClick = (e: React.MouseEvent) => { - if (!inactive && onClick) { - e.stopPropagation(); - e.preventDefault(); - onClick(e) - } - } + /** + * Pointer down + * @param e + */ + const handlePointerDown = (e: React.PointerEvent) => { + if (!inactive && onPointerDown) { + e.stopPropagation(); + e.preventDefault(); + onPointerDown(e); + } + }; - /** - * Double click - * @param e - */ - const handleDoubleClick = (e: React.MouseEvent) => { - if (!inactive && onDoubleClick){ - e.stopPropagation(); - e.preventDefault(); - onDoubleClick(e) - } - } + /** + * In the event that there is a single click + * @param e + */ + const handleClick = (e: React.MouseEvent) => { + if (!inactive && onClick) { + e.stopPropagation(); + e.preventDefault(); + onClick(e); + } + }; - const getBorderColor = (): Colors | string | undefined => { - switch(type){ - case Type.PRIM: - return undefined; - case Type.SEC: - if (colorPicker) return colorPicker; - return color; - case Type.TERT: - if (colorPicker) return colorPicker; - if (active) return color; - else return color; - } - } + /** + * Double click + * @param e + */ + const handleDoubleClick = (e: React.MouseEvent) => { + if (!inactive && onDoubleClick) { + e.stopPropagation(); + e.preventDefault(); + onDoubleClick(e); + } + }; - const getColor = (): Colors | string | undefined => { - if (color && background) return color; - switch(type){ - case Type.PRIM: - if (colorPicker) return colorPicker - return color; - case Type.SEC: - if (colorPicker) return colorPicker - return color; - case Type.TERT: - if (colorPicker) { - if (isDark(colorPicker)) return Colors.WHITE; - else return Colors.BLACK + const getBorderColor = (): Colors | string | undefined => { + switch (type) { + case Type.PRIM: + return undefined; + case Type.SEC: + if (colorPicker) return colorPicker; + return color; + case Type.TERT: + return color; } - if (isDark(color)) return Colors.WHITE; - else return Colors.BLACK - } - } + }; - const getBackground = (): Colors | string | undefined => { - if (background) return background; - switch(type) { - case Type.PRIM: - if (colorPicker) return colorPicker - return color; - case Type.SEC: - if (colorPicker) return colorPicker - return color; - case Type.TERT: - if (colorPicker) return colorPicker - else return color - } - } + const getColor = (): Colors | string | undefined => { + if (color && background) return color; + switch (type) { + case Type.PRIM: + case Type.SEC: + if (colorPicker) return colorPicker; + return color; + case Type.TERT: + return ''; + } + }; - const defaultProperties: React.CSSProperties = { - height: getHeight(height, size), - minHeight: getHeight(height, size), - width: fillWidth ? '100%' : 'fit-content', - justifyContent: align ? align : undefined, - padding: fillWidth && align === 'center' ? 0 : undefined, - fontWeight: 500, - fontSize: getFontSize(size), - fontFamily: 'sans-serif', - textTransform: uppercase ? 'uppercase' : undefined, - borderColor: getBorderColor(), - color: getColor(), - } + const getBackground = (): Colors | string | undefined => { + if (background) return background; + switch (type) { + case Type.PRIM: + case Type.SEC: + if (colorPicker) return colorPicker; + return color; + case Type.TERT: + } + }; - const backgroundProperties: React.CSSProperties = { - background: getBackground() - } + const defaultProperties: React.CSSProperties = { + height: getHeight(height, size), + minHeight: getHeight(height, size), + width: fillWidth ? '100%' : 'fit-content', + justifyContent: align ? align : undefined, + padding: fillWidth && align === 'center' ? 0 : undefined, + fontWeight: 500, + fontSize: getFontSize(size), + fontFamily: 'sans-serif', + textTransform: uppercase ? 'uppercase' : undefined, + borderColor: getBorderColor(), + color: getColor(), + }; - const button: JSX.Element = ( - -
-
- {iconPlacement == 'left' && icon ?
{icon}
: null} - {text} - {iconPlacement == 'right' && icon ?
{icon}
: null} -
-
-
- - ) + const backgroundProperties: React.CSSProperties = { + background: getBackground(), + filter, + }; - return ( - formLabel ? -
-
{formLabel}
- {button} -
- : - button - ) -} + const button: JSX.Element = ( + +
+
+ {iconPlacement == 'left' && icon ? ( +
+ {icon} +
+ ) : null} + {text} + {iconPlacement == 'right' && icon ? ( +
+ {icon} +
+ ) : null} +
+
+
+ + ); + + return formLabel ? ( +
+
+ {formLabel} +
+ {button} +
+ ) : ( + button + ); +}; diff --git a/packages/components/src/components/ColorPicker/ColorPicker.tsx b/packages/components/src/components/ColorPicker/ColorPicker.tsx index 632b470f0..72e02d955 100644 --- a/packages/components/src/components/ColorPicker/ColorPicker.tsx +++ b/packages/components/src/components/ColorPicker/ColorPicker.tsx @@ -1,5 +1,5 @@ import React, { useRef, useState } from 'react'; -import { GithubPicker, ChromePicker, BlockPicker, SliderPicker, SketchPicker } from 'react-color'; +import { GithubPicker, ChromePicker, BlockPicker, SliderPicker, SketchPicker, ColorResult } from 'react-color'; import { IGlobalProps, Size, Type, getFormLabelSize } from '../../global'; import { Button } from '../Button'; import { IconButton } from '../IconButton'; @@ -16,12 +16,12 @@ export interface IColorPickerProps extends IGlobalProps { colorPickerType?: ColorPickerType; defaultPickerType?: ColorPickerType; selectedColor?: string; - setSelectedColor: (color: any) => unknown; - setFinalColor: (color: any) => unknown; + setSelectedColor: (color: string) => unknown; + setFinalColor: (color: string) => unknown; } export const ColorPicker = (props: IColorPickerProps) => { - const [selectedColorLoc, setSelectedColorLoc] = useState(); + const [selectedColorLoc, setSelectedColorLoc] = useState(); const { defaultPickerType, text, @@ -31,6 +31,7 @@ export const ColorPicker = (props: IColorPickerProps) => { size = Size.SMALL, type = Type.TERT, icon, + background, selectedColor = selectedColorLoc, setSelectedColor = setSelectedColorLoc, setFinalColor = setSelectedColorLoc, @@ -40,32 +41,25 @@ export const ColorPicker = (props: IColorPickerProps) => { } = props; const [isOpen, setOpen] = useState(false); const [pickerSelectorOpen, setPickerSelectorOpen] = useState(false); - const decimalToHexString = (number: number) => { + const decimalToHexString = (numberIn: number) => { + let number = numberIn; if (number < 0) { number = 0xffffffff + number + 1; } return (number < 16 ? '0' : '') + number.toString(16).toUpperCase(); }; - const colorString = (color: any) => { - return color.hex === 'transparent' ? color.hex : color.hex + (color.rgb.a ? decimalToHexString(Math.round(color.rgb.a * 255)) : 'ff'); - }; - const onChange = (color: any) => { - setSelectedColor(colorString(color) as any); - }; - const onChangeComplete = (color: any) => { - setFinalColor(colorString(color) as any); - }; + const colorString = (c: ColorResult) => (c.hex === 'transparent' ? c.hex : c.hex + (c.rgb.a ? decimalToHexString(Math.round(c.rgb.a * 255)) : 'ff')); + const onChange = (c: ColorResult) => setSelectedColor(colorString(c)); + const onChangeComplete = (c: ColorResult) => setFinalColor(colorString(c)); const [picker, setPicker] = useState(defaultPickerType ?? 'Classic'); const toggleRef = useRef(null); const getToggle = () => (
- {icon && !text ? ( - - ) : text ? ( -
); @@ -92,14 +86,12 @@ export const ColorPicker = (props: IColorPickerProps) => { ); } // prettier-ignore }; - const openChanged = (isOpen: boolean) => setPickerSelectorOpen(isOpen); + const openChanged = (state: boolean) => setPickerSelectorOpen(state); const getPopup = (): JSX.Element => { if (colorPickerType) { return getColorPicker(colorPickerType); } else { - // Todo: this would be much easier if the selectedColor was a Color, not a string. - const newColor = selectedColor === 'transparent' ? 'white' : selectedColor?.startsWith('#') ? selectedColor.substring(0, 7) : selectedColor?.startsWith('rgba') ? selectedColor?.replace(/,[0-9]*\)/, '1)') : selectedColor; return (
{ val: item, }; })} + background={background} activeChanged={openChanged} placement={'right'} - color={newColor} + color={color} type={Type.PRIM} dropdownType={DropdownType.SELECT} selectedVal={picker} @@ -126,7 +119,7 @@ export const ColorPicker = (props: IColorPickerProps) => { const popupContainsPt = (x: number, y: number) => { const rect = toggleRef.current?.getBoundingClientRect(); - return rect && rect.left < x && rect.top < y && rect.right > x && rect.bottom > y; + return pickerSelectorOpen || (rect && rect.left < x && rect.top < y && rect.right > x && rect.bottom > y) ? true : false; }; const colorPicker: JSX.Element = ( @@ -138,6 +131,7 @@ export const ColorPicker = (props: IColorPickerProps) => { tooltip={tooltip} size={size} color={selectedColor} + background={background} popup={getPopup()} popupContainsPt={popupContainsPt} // this should prohbably test to see if the click pt is actually within the picker selector list popup. /> @@ -145,7 +139,7 @@ export const ColorPicker = (props: IColorPickerProps) => { return formLabel ? (
-
+
{formLabel}
{colorPicker} diff --git a/packages/components/src/components/Dropdown/Dropdown.tsx b/packages/components/src/components/Dropdown/Dropdown.tsx index b9b6f01b8..783c7daa4 100644 --- a/packages/components/src/components/Dropdown/Dropdown.tsx +++ b/packages/components/src/components/Dropdown/Dropdown.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { FaCaretDown, FaCaretLeft, FaCaretRight, FaCaretUp } from 'react-icons/fa'; import { Popup, PopupTrigger } from '..'; -import { Colors, IGlobalProps, Placement, Type, getFontSize, getHeight, isDark, getFormLabelSize } from '../../global'; +import { Colors, IGlobalProps, Placement, Type, getFontSize, getHeight, getFormLabelSize } from '../../global'; import { IconButton } from '../IconButton'; import { ListBox } from '../ListBox'; import { IListItemProps, ListItem } from '../ListItem'; @@ -92,7 +92,7 @@ export const Dropdown = (props: IDropdownProps) => { textTransform: uppercase ? 'uppercase' : undefined, borderColor: getBorderColor(), background, - color: color && background ? color : type == Type.TERT ? (isDark(color) ? Colors.WHITE : Colors.BLACK) : color, + color: color, }; const backgroundProperties: React.CSSProperties = { @@ -116,9 +116,9 @@ export const Dropdown = (props: IDropdownProps) => {
{selectedVal && }
- +
-
+
); case DropdownType.CLICK: @@ -127,9 +127,9 @@ export const Dropdown = (props: IDropdownProps) => {
- +
-
+
); } @@ -157,6 +157,7 @@ export const Dropdown = (props: IDropdownProps) => { size={size} fillWidth={true} color={color} + background={background} popup={ { - const { - size, - height, - maxItems, - items, - dropdownSearchType, - selectedVal, - // setSelectedVal, - tooltip, - title = "DropdownSearch", - type, - width, - color - } = props + const { size, height, maxItems, items, dropdownSearchType, type, width, color } = props; - // const [selectedItem, setSelectedItem] = useState< - // IListItemProps | undefined - // >(selectedVal) + // const [selectedItem, setSelectedItem] = useState< + // IListItemProps | undefined + // >(selectedVal) - const [searchTerm, setSearchTerm] = useState(undefined) - const [isEditing, setIsEditing] = useState(false) - const [active, setActive] = useState(false) + const [searchTerm, setSearchTerm] = useState(undefined); + const [isEditing, setIsEditing] = useState(false); + const [active, setActive] = useState(false); - const getToggle = () => { - switch (dropdownSearchType) { - case DropdownSearchType.SELECT: - return (
{ - e.stopPropagation() - !isEditing && setIsEditing(true) - }} - > - {/* {selectedItem && !isEditing ? ( + const getToggle = () => { + switch (dropdownSearchType) { + case DropdownSearchType.SELECT: + return ( +
{ + e.stopPropagation(); + !isEditing && setIsEditing(true); + }}> + {/* {selectedItem && !isEditing ? ( ) : ( */} -
- { - // setSearchTerm(val) - // }} - size={Size.SMALL} - setEditing={setIsEditing} - /> -
- {/* )} */} -
- } - inactive - /> -
-
-
); - case DropdownSearchType.CLICK: - default: - return ( -
-
- ) - } - } +
+ { + // setSearchTerm(val) + // }} + size={Size.SMALL} + setEditing={setIsEditing} + /> +
+ {/* )} */} +
+ } inactive /> +
+
+
+ ); + case DropdownSearchType.CLICK: + default: + return
; + } + }; - return ( -
- - } - /> -
- ) -} + return ( +
+ + } + /> +
+ ); +}; diff --git a/packages/components/src/components/EditableText/EditableText.tsx b/packages/components/src/components/EditableText/EditableText.tsx index c361cf183..56cbc064d 100644 --- a/packages/components/src/components/EditableText/EditableText.tsx +++ b/packages/components/src/components/EditableText/EditableText.tsx @@ -1,21 +1,21 @@ -import React, { useState } from 'react' -import { Colors, IGlobalProps, Size, TextAlignment, Type, getFontSize, getFormLabelSize, getHeight, isDark } from '../../global' -import './EditableText.scss' -import { Toggle, ToggleType } from '../Toggle' -import { FaEye, FaEyeSlash} from 'react-icons/fa' +import React, { useState } from 'react'; +import { Colors, IGlobalProps, Size, TextAlignment, Type, getFontSize, getFormLabelSize, getHeight, isDark } from '../../global'; +import './EditableText.scss'; +import { Toggle, ToggleType } from '../Toggle'; +import { FaEye, FaEyeSlash } from 'react-icons/fa'; export interface IEditableTextProps extends IGlobalProps { - val?: string | number - setVal?: (newText: string | number) => unknown - onEnter?: (newText: string | number) => unknown - setEditing?: (bool: boolean) => unknown - placeholder?: string - editing?: boolean - size?: Size - height?: number - multiline?: boolean - textAlign?: TextAlignment - password?: boolean + val?: string | number; + setVal?: (newText: string | number) => unknown; + onEnter?: (newText: string | number) => unknown; + setEditing?: (bool: boolean) => unknown; + placeholder?: string; + editing?: boolean; + size?: Size; + height?: number; + multiline?: boolean; + textAlign?: TextAlignment; + password?: boolean; } /** @@ -25,152 +25,149 @@ export interface IEditableTextProps extends IGlobalProps { * @returns */ export const EditableText = (props: IEditableTextProps) => { - const [valLoc, setValLoc] = useState('') - const [editingLoc, setEditingLoc] = useState(false) - const { - height, - size, - val = valLoc, - setVal = setValLoc, - onEnter, - setEditing = setEditingLoc, - color = Colors.MEDIUM_BLUE, - background, - type = Type.PRIM, - placeholder, - width, - multiline, - textAlign = 'left', - formLabel, - formLabelPlacement, - fillWidth, - password, - editing = password ? true : editingLoc, - style - } = props - const [showPassword, setShowPassword] = useState(false) + const [valLoc, setValLoc] = useState(''); + const [editingLoc, setEditingLoc] = useState(false); + const { + height, + size, + val = valLoc, + setVal = setValLoc, + onEnter, + setEditing = setEditingLoc, + color = Colors.MEDIUM_BLUE, + background, + type = Type.PRIM, + placeholder, + width, + textAlign = 'left', + formLabel, + formLabelPlacement, + fillWidth, + password, + editing = password ? true : editingLoc, + style, + } = props; + const [showPassword, setShowPassword] = useState(false); - const handleOnChange = (event: React.ChangeEvent) => { - setVal(event.target.value) - } - const handleKeyPress = (event: React.KeyboardEvent) => { - if (event.key === 'Enter') { - onEnter?.((event.target as HTMLInputElement).value) - } - } + const handleOnChange = (event: React.ChangeEvent) => { + setVal(event.target.value); + }; + const handleKeyPress = (event: React.KeyboardEvent) => { + if (event.key === 'Enter') { + onEnter?.((event.target as HTMLInputElement).value); + } + }; - const getBorderColor = (): Colors | string | undefined => { - switch(type){ - case Type.PRIM: - return undefined; - case Type.SEC: - return color; - case Type.TERT: - if (editing) return color; - else return color; - } - } + const getBorderColor = (): Colors | string | undefined => { + switch (type) { + case Type.PRIM: + return undefined; + case Type.SEC: + return color; + case Type.TERT: + if (editing) return color; + else return color; + } + }; - const getColor = (): Colors | string | undefined => { - if (color && background) return color; - switch(type){ - case Type.PRIM: - return color; - case Type.SEC: - return color; - case Type.TERT: - if (isDark(color)) return Colors.WHITE; - else return Colors.BLACK - } - } + const getColor = (): Colors | string | undefined => { + if (color && background) return color; + switch (type) { + case Type.PRIM: + return color; + case Type.SEC: + return color; + case Type.TERT: + if (isDark(color)) return Colors.WHITE; + else return Colors.BLACK; + } + }; - const getBackground = (): Colors | string | undefined => { - if (background) return background; - switch(type){ - case Type.PRIM: - return color; - case Type.SEC: - return color; - case Type.TERT: - return color - } - } + const getBackground = (): Colors | string | undefined => { + if (background) return background; + switch (type) { + case Type.PRIM: + return color; + case Type.SEC: + return color; + case Type.TERT: + return color; + } + }; - const defaultProperties: React.CSSProperties = { - height: getHeight(height, size), - minHeight: getHeight(height, size), - width: fillWidth ? '100%' : width, - padding: undefined, - fontWeight: 500, - fontSize: getFontSize(size), - fontFamily: 'sans-serif', - borderColor: getBorderColor(), - color: getColor() - } + const defaultProperties: React.CSSProperties = { + height: getHeight(height, size), + minHeight: getHeight(height, size), + width: fillWidth ? '100%' : width, + padding: undefined, + fontWeight: 500, + fontSize: getFontSize(size), + fontFamily: 'sans-serif', + borderColor: getBorderColor(), + color: getColor(), + }; - const backgroundProperties: React.CSSProperties = { - background: getBackground() - } + const backgroundProperties: React.CSSProperties = { + background: getBackground(), + }; - const editableText: JSX.Element = ( -
setEditing(true)} - > - {editing ? ( - { - !password && setEditing(false) - }} - defaultValue={val} - > - ) : ( -
- {val ? val : placeholder} + const editableText: JSX.Element = ( +
setEditing(true)}> + {editing ? ( + { + !password && setEditing(false); + }} + defaultValue={val}> + ) : ( +
+ {val ? val : placeholder} +
+ )} + {password && ( +
+ setShowPassword(!showPassword)} + tooltip={`${showPassword ? 'Hide' : 'Show'} Password`} + icon={} + iconFalse={} + /> +
+ )} +
- )} - {password &&
- setShowPassword(!showPassword)} - tooltip={`${showPassword ? 'Hide' : 'Show'} Password`} - icon={} - iconFalse={} - /> -
} -
-
- ) + ); -return ( - formLabel ? -
-
{formLabel}
- {editableText} -
- : - editableText - ) -} + return formLabel ? ( +
+
+ {formLabel} +
+ {editableText} +
+ ) : ( + editableText + ); +}; diff --git a/packages/components/src/components/IconButton/IconButton.scss b/packages/components/src/components/IconButton/IconButton.scss index f899dc50f..3f0dd26ea 100644 --- a/packages/components/src/components/IconButton/IconButton.scss +++ b/packages/components/src/components/IconButton/IconButton.scss @@ -45,7 +45,7 @@ &.inactive { .background { - filter: opacity(0) !important; + filter: opacity(0); } } @@ -54,13 +54,13 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.5); } } &:hover { .background { - filter: opacity(0.2); + filter: opacity(0.3); } } } @@ -70,7 +70,7 @@ filter: opacity(0); &.active { - filter: opacity(0.2) !important; + filter: opacity(0.2); } } @@ -85,10 +85,17 @@ &:hover { box-shadow: global.$standard-button-shadow; } + .background { + filter: opacity(0); + + &.active { + filter: opacity(0.5); + } + } &:hover { .background { - filter: brightness(0.8); + filter: opacity(0.3); } } } diff --git a/packages/components/src/components/IconButton/IconButton.tsx b/packages/components/src/components/IconButton/IconButton.tsx index 048048b20..f61f589b9 100644 --- a/packages/components/src/components/IconButton/IconButton.tsx +++ b/packages/components/src/components/IconButton/IconButton.tsx @@ -1,6 +1,6 @@ import { Tooltip } from '@mui/material'; import React from 'react'; -import { Colors, Size, Type, getFontSize, getHeight, isDark, getFormLabelSize } from '../../global'; +import { Colors, Size, Type, getFontSize, getHeight, getFormLabelSize } from '../../global'; import { IButtonProps } from '../Button'; import './IconButton.scss'; @@ -15,6 +15,7 @@ export const IconButton = (props: IButtonProps) => { type = Type.PRIM, color = Colors.MEDIUM_BLUE, background, + filter, label, height, size = Size.SMALL, @@ -71,6 +72,7 @@ export const IconButton = (props: IButtonProps) => { case Type.SEC: return color; case Type.TERT: + return ''; if (colorPicker) return colorPicker; if (active) return color; else return color; @@ -85,12 +87,7 @@ export const IconButton = (props: IButtonProps) => { case Type.SEC: return color; case Type.TERT: - if (colorPicker) { - if (isDark(colorPicker)) return Colors.WHITE; - else return Colors.BLACK; - } - if (isDark(color)) return Colors.WHITE; - else return Colors.BLACK; + return ''; } }; @@ -102,15 +99,14 @@ export const IconButton = (props: IButtonProps) => { case Type.SEC: return color; case Type.TERT: - if (colorPicker) return colorPicker; - else return color; + return ''; //color; } }; const defaultProperties: React.CSSProperties = { - height: getHeight(+(height ?? 0), size), - width: fillWidth ? '100%' : getHeight(+(height ?? 0), size), - minWidth: getHeight(+(height ?? 0), size), + height: getHeight(height, size), + width: fillWidth ? '100%' : getHeight(height, size), + minWidth: getHeight(height, size), fontWeight: 500, fontSize: getFontSize(size, true), borderColor: getBorderColor(), @@ -119,6 +115,7 @@ export const IconButton = (props: IButtonProps) => { const backgroundProperties: React.CSSProperties = { background: getBackground(), + filter, }; const iconButton: JSX.Element = ( @@ -126,9 +123,9 @@ export const IconButton = (props: IButtonProps) => {
{icon} - {colorPicker && type !== Type.TERT &&
} + {colorPicker &&
} {label && !hideLabel && ( -
+
{label}
)} @@ -140,7 +137,7 @@ export const IconButton = (props: IButtonProps) => { return formLabel ? (
-
+
{formLabel}
{iconButton} diff --git a/packages/components/src/components/ListItem/ListItem.tsx b/packages/components/src/components/ListItem/ListItem.tsx index e04c6fbee..6bb3e3824 100644 --- a/packages/components/src/components/ListItem/ListItem.tsx +++ b/packages/components/src/components/ListItem/ListItem.tsx @@ -85,7 +85,7 @@ export const ListItem = (props: IListItemProps) => {
diff --git a/packages/components/src/components/MultiToggle/MultiToggle.tsx b/packages/components/src/components/MultiToggle/MultiToggle.tsx index 7fff12c8e..0f659c5ca 100644 --- a/packages/components/src/components/MultiToggle/MultiToggle.tsx +++ b/packages/components/src/components/MultiToggle/MultiToggle.tsx @@ -1,29 +1,29 @@ -import * as React from 'react' -import { useState } from 'react' -import { Colors, IGlobalProps, Type } from '../../global' -import { Group } from '../Group' -import { IconButton } from '../IconButton' -import { Popup } from '../Popup' -import { IToggleProps, Toggle, ToggleType } from '../Toggle' +import * as React from 'react'; +import { useState } from 'react'; +import { Colors, IGlobalProps, Type } from '../../global'; +import { Group } from '../Group'; +import { IconButton } from '../IconButton'; +import { Popup } from '../Popup'; +import { IToggleProps, Toggle, ToggleType } from '../Toggle'; export interface IToggleItemProps extends IToggleProps { - val: string + val: string; } export interface IMultiToggleProps extends IGlobalProps { - items: IToggleItemProps[] + items: IToggleItemProps[]; multiSelect?: boolean; - defaultSelectedItems?: (string|number) | ((string|number)[]), - selectedItems?: (string | number) | ((string|number)[]), - onSelectionChange?: (val: (string|number) | (string|number)[], added: boolean) => unknown, + defaultSelectedItems?: (string | number) | (string | number)[]; + selectedItems?: (string | number) | (string | number)[]; + onSelectionChange?: (val: (string | number) | (string | number)[], added: boolean) => unknown; isToggle?: boolean; toggleStatus?: boolean; } -function promoteToArrayOrUndefined(d : (string|number)[]|(string|number)|undefined) { - return d instanceof Array || d === undefined ? d: [d]; +function promoteToArrayOrUndefined(d: (string | number)[] | (string | number) | undefined) { + return d instanceof Array || d === undefined ? d : [d]; } -function promoteToArray(d : (string|number)[]|(string|number)|undefined) { +function promoteToArray(d: (string | number)[] | (string | number) | undefined) { return promoteToArrayOrUndefined(d) ?? []; } @@ -32,56 +32,67 @@ export const MultiToggle = (props: IMultiToggleProps) => { const initVal = (!init ? undefined : promoteToArrayOrUndefined(props.defaultSelectedItems)) ?? promoteToArrayOrUndefined(props.selectedItems) ?? []; init = false; - const [selectedItemsLocal, setSelectedItemsLocal] = useState(initVal as (string|number) | ((string|number)[])); + const [selectedItemsLocal, setSelectedItemsLocal] = useState(initVal as (string | number) | (string | number)[]); const { items, selectedItems = selectedItemsLocal, tooltip, tooltipPlacement = 'top', onSelectionChange, color, background } = props; const itemsMap = new Map(); - items.forEach((item) => itemsMap.set(item.val, item)); - return
- - - {promoteToArray(selectedItems).length < 2 ? null : -
- + -
} -
} - isToggle={props.isToggle} - toggleFunc={() => { - const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val)); - selItem && setSelectedItemsLocal([selItem.val]); - }} - type={props.type} - label={props.isToggle ? props.label : undefined} - toggleStatus={props.isToggle ? props.toggleStatus : undefined} - color={color} - popup={ - {items.map((item, i) => - { - const selected = new Set(); - promoteToArray(selectedItems).forEach(val => val && selected.add(val)); - const toAdd = !props.multiSelect || !selected.has(item.val) - if (!toAdd) selected.delete(item.val); - else item.val && selected.add(item.val); - onSelectionChange?.(item.val, toAdd); - setSelectedItemsLocal(props.multiSelect ? Array.from(selected) : item.val); - e.stopPropagation(); - }}/> - )} - } - /> -
-} \ No newline at end of file + items.forEach(item => itemsMap.set(item.val, item)); + return ( +
+ + + {promoteToArray(selectedItems).length < 2 ? null :
+
} +
+ ) + } + isToggle={props.isToggle} + toggleFunc={() => { + const selItem = items.find(item => promoteToArray(selectedItems).includes(item.val)); + selItem && setSelectedItemsLocal([selItem.val]); + }} + type={props.type} + label={props.isToggle ? props.label : undefined} + toggleStatus={props.isToggle ? props.toggleStatus : undefined} + color={color} + background={background} + popup={ + + {items.map((item, i) => ( + { + const selected = new Set(); + promoteToArray(selectedItems).forEach(val => val && selected.add(val)); + const toAdd = !props.multiSelect || !selected.has(item.val); + if (!toAdd) selected.delete(item.val); + else item.val && selected.add(item.val); + onSelectionChange?.(item.val, toAdd); + setSelectedItemsLocal(props.multiSelect ? Array.from(selected) : item.val); + e.stopPropagation(); + }} + /> + ))} + + } + /> +
+ ); +}; diff --git a/packages/components/src/components/NumberDropdown/NumberDropdown.tsx b/packages/components/src/components/NumberDropdown/NumberDropdown.tsx index 7f12198d5..b5f55bacf 100644 --- a/packages/components/src/components/NumberDropdown/NumberDropdown.tsx +++ b/packages/components/src/components/NumberDropdown/NumberDropdown.tsx @@ -20,11 +20,41 @@ export interface INumberDropdownProps extends INumberProps { export const NumberDropdown = (props: INumberDropdownProps) => { const [numberLoc, setNumberLoc] = useState(0); - const { fillWidth, numberDropdownType = false, color = Colors.MEDIUM_BLUE, type, formLabelPlacement, showPlusMinus, min, max, unit, step = 1, number = numberLoc, setNumber = setNumberLoc, size, formLabel, tooltip } = props; + const { + fillWidth, // + numberDropdownType = false, + color = Colors.MEDIUM_BLUE, + type, + formLabelPlacement, + showPlusMinus, + min, + max, + unit, + background, + step = 1, + number = numberLoc, + setNumber = setNumberLoc, + size, + formLabel, + tooltip, + } = props; const [isOpen, setOpen] = useState(false); let toggleText = number.toString(); if (unit) toggleText = toggleText + unit; - let toggle = setOpen(!isOpen)} />; + let toggle = ( + setOpen(!isOpen)} + /> + ); if (showPlusMinus) { toggle = ( @@ -75,23 +105,23 @@ export const NumberDropdown = (props: INumberDropdownProps) => { break; case 'slider': default: - popup = ; + popup = ; break; case 'input': - popup = ; + popup = ; break; } const numberDropdown: JSX.Element = ( -
- +
+
); return formLabel ? ( -
+
{numberDropdown} -
+
setOpen(!isOpen)} style={{ cursor: 'pointer', height: '25%', fontSize: getFormLabelSize(size) }}> {formLabel}
diff --git a/packages/components/src/components/NumberInput/NumberInput.tsx b/packages/components/src/components/NumberInput/NumberInput.tsx index 33573d000..56c61a41e 100644 --- a/packages/components/src/components/NumberInput/NumberInput.tsx +++ b/packages/components/src/components/NumberInput/NumberInput.tsx @@ -1,89 +1,76 @@ -import * as React from 'react' -import { Colors, INumberProps , Type, getFormLabelSize, getHeight } from '../../global' -import './NumberInput.scss' -import { useState } from 'react' -import { Group } from '../Group' -import { Toggle, ToggleType } from '../Toggle' -import { IconButton } from '../IconButton' -import * as fa from 'react-icons/fa' -import { EditableText } from '../EditableText' +import * as React from 'react'; +import { Colors, INumberProps, getFormLabelSize, getHeight } from '../../global'; +import './NumberInput.scss'; +import { useState } from 'react'; +import { Group } from '../Group'; +import { IconButton } from '../IconButton'; +import * as fa from 'react-icons/fa'; +import { EditableText } from '../EditableText'; export interface INumberInputProps extends INumberProps { - showPlusMinus?: boolean + showPlusMinus?: boolean; } export const NumberInput = (props: INumberInputProps) => { - const [numberLoc, setNumberLoc] = useState(10) - const { - color = Colors.MEDIUM_BLUE, - type, - formLabelPlacement, - showPlusMinus, - min, - max, - unit = '', - width, - fillWidth = width ? true : false, - step = 1, - number = numberLoc, - setNumber = setNumberLoc, - size, - formLabel, - tooltip } = - props; + const [numberLoc, setNumberLoc] = useState(10); + const { color = Colors.MEDIUM_BLUE, type, formLabelPlacement, showPlusMinus, min, max, unit = '', width, fillWidth = width ? true : false, step = 1, number = numberLoc, setNumber = setNumberLoc, size, formLabel } = props; + + let input = ( + setNumber(!isNaN(Number(val)) ? Number(val) : number)} + /> + ); - let input = setNumber(!isNaN(Number(val)) ? Number(val) : number)} - />; - if (showPlusMinus) { - input = - {input} - } - color={color} - onClick={(e) => { - e.stopPropagation(); - setNumber(number - step); - }} - inactive={number - step < min} - tooltip={`Subtract ${step}${unit}`} - /> - } - color={color} - onClick={(e) => { - e.stopPropagation(); - setNumber(number + step); - }} - inactive={number + step > max} - tooltip={`Add ${step}${unit}`} - /> - + input = ( + + {input} + } + color={color} + onClick={e => { + e.stopPropagation(); + setNumber(number - step); + }} + inactive={number - step < min} + tooltip={`Subtract ${step}${unit}`} + /> + } + color={color} + onClick={e => { + e.stopPropagation(); + setNumber(number + step); + }} + inactive={number + step > max} + tooltip={`Add ${step}${unit}`} + /> + + ); } - - return ( - formLabel ? -
-
{formLabel}
-
+ return formLabel ? ( +
+
+ {formLabel} +
+
{input}
- : -
+ ) : ( +
{input}
- ) -} \ No newline at end of file + ); +}; diff --git a/packages/components/src/components/Popup/Popup.tsx b/packages/components/src/components/Popup/Popup.tsx index 5a58fee29..82e60f343 100644 --- a/packages/components/src/components/Popup/Popup.tsx +++ b/packages/components/src/components/Popup/Popup.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useRef, useState } from 'react'; -import { Colors, IGlobalProps, Placement, Size, isDark } from '../../global'; +import { IGlobalProps, Placement, Size } from '../../global'; import { Toggle, ToggleType } from '../Toggle'; import './Popup.scss'; import { Popper } from '@mui/material'; @@ -57,7 +57,7 @@ export const Popup = (props: IPopupProps) => { height, fillWidth, iconPlacement = 'left', - background = isDark(color) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, + background, popupContainsPt, } = props; @@ -116,7 +116,7 @@ export const Popup = (props: IPopupProps) => { size={size} type={type} color={color} - background={props.isToggle ? undefined : background} + background={background} toggleType={ToggleType.BUTTON} icon={icon} iconPlacement={iconPlacement} @@ -138,7 +138,7 @@ export const Popup = (props: IPopupProps) => {
{ const toDecimal = (num: number) => (decimals !== undefined ? Math.round(num * Math.pow(10, decimals)) / Math.pow(10, decimals) : num); const getLeftPos = (locVal: number) => { - const dragger = getHeight(+(height || 0), size); + const dragger = +getHeight(height, size); return ((locVal - min) / (max - min)) * (width - dragger); }; @@ -65,8 +65,8 @@ export const Slider = (props: ISliderProps) => { background: color, color: isDark(color) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, fontSize: getFontSize(size), - height: getHeight(+(height || 0), size), - width: getHeight(+(height || 0), size), + height: getHeight(height, size), + width: getHeight(height, size), top: 0, }}> {toDecimal(locVal)} @@ -132,7 +132,7 @@ export const Slider = (props: ISliderProps) => { lastEndVal = endNumberLoc; }} style={{ - padding: `5px 0px ${getHeight(+(height || 0), size)}px 0px`, + padding: `5px 0px ${getHeight(height, size)}px 0px`, width: fillWidth ? '100%' : 'fit-content', }}>
{ r && new ResizeObserver(() => setWidth(+(r?.clientWidth ?? 100))).observe(r); setWidth(+(r?.clientWidth ?? 100)); }} - style={{ height: getHeight(+(height || 0), size) }} + style={{ height: getHeight(height, size) }} onPointerDown={onPointerDown}> {ValSlider}
selected, false -> unselected - toggleType?: ToggleType - iconFalse?: JSX.Element | string + toggleStatus?: boolean; // true -> selected, false -> unselected + toggleType?: ToggleType; + iconFalse?: JSX.Element | string; + triState?: boolean; } export const Toggle = (props: IToggleProps) => { - const [toggleStatusLoc, setToggleStatusLoc] = useState(true); - const { - toggleStatus = toggleStatusLoc, - toggleType = ToggleType.CHECKBOX, - type = Type.SEC, - style, - color, - background, - text, - icon, - iconFalse = icon, - height, - inactive, - label, - iconPlacement, - onPointerDown, - onClick, - tooltip, - tooltipPlacement = 'top', - size = Size.SMALL, - formLabel, - formLabelPlacement, - fillWidth, - align - } = props + const [toggleStatusLoc, setToggleStatusLoc] = useState(true); + const { + toggleStatus = toggleStatusLoc, + toggleType = ToggleType.CHECKBOX, + type = Type.SEC, + color, + background, + text, + icon, + iconFalse = icon, + height, + inactive, + label, + iconPlacement, + onPointerDown, + onClick, + triState, + tooltip, + tooltipPlacement = 'top', + size = Size.SMALL, + formLabel, + formLabelPlacement, + fillWidth, + align, + } = props; - /** - * Pointer down - * @param e - */ - const handlePointerDown = (e: React.PointerEvent) => { - if (!inactive && onPointerDown){ - e.stopPropagation(); - e.preventDefault(); - onPointerDown(e) - } - } + /** + * Pointer down + * @param e + */ + const handlePointerDown = (e: React.PointerEvent) => { + if (!inactive && onPointerDown) { + e.stopPropagation(); + e.preventDefault(); + onPointerDown(e); + } + }; - /** - * Single click - * @param e - */ - const handleClick = (e: React.MouseEvent) => { - if (toggleStatus === toggleStatusLoc) { - setToggleStatusLoc(!toggleStatus) - } - - if (!inactive && onClick) { - e.stopPropagation(); - e.preventDefault(); - onClick(e); - } - } + /** + * Single click + * @param e + */ + const handleClick = (e: React.MouseEvent) => { + if (toggleStatus === toggleStatusLoc) { + setToggleStatusLoc(!toggleStatus); + } - const defaultProperties = { - height: getHeight(height, size), - borderColor: color - } + if (!inactive && onClick) { + e.stopPropagation(); + e.preventDefault(); + onClick(e); + } + }; - let toggleElement: JSX.Element; + const defaultProperties = { + height: getHeight(height, size), + borderColor: color, + }; - switch(toggleType) { - case ToggleType.BUTTON: - toggleElement = ( -