From cca4b5bbc32ccfaafbaba9306545eaddc6953954 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Mon, 10 Jun 2024 12:32:20 -0400 Subject: hm --- src/client/documents/Documents.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a67e6b4f6..34407c641 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -479,6 +479,7 @@ export class DocumentOptions { userColor?: STRt = new StrInfo('color associated with a Dash user (seen in header fields of shared documents)'); cardSort?: STRt = new StrInfo('way cards are sorted in deck view'); + cardSortForDropDown?: STRt = new StrInfo('needed for dropdown and i dont know why') cardSort_customField?: STRt = new StrInfo('field key used for sorting cards'); cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) } -- cgit v1.2.3-70-g09d2 From 3f940bd45fd1bf72f6c16edc188f754b01f689ba Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Fri, 21 Jun 2024 15:11:23 -0400 Subject: yay dragging --- src/client/documents/Documents.ts | 3 +- src/client/util/CurrentUserUtils.ts | 12 +- src/client/views/MainView.tsx | 3 +- .../views/collections/CollectionCardDeckView.tsx | 231 ++++++++++++--------- 4 files changed, 149 insertions(+), 100 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 34407c641..a190fe11b 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -479,8 +479,9 @@ export class DocumentOptions { userColor?: STRt = new StrInfo('color associated with a Dash user (seen in header fields of shared documents)'); cardSort?: STRt = new StrInfo('way cards are sorted in deck view'); - cardSortForDropDown?: STRt = new StrInfo('needed for dropdown and i dont know why') + // cardSortForDropDown?: STRt = new StrInfo('needed for dropdown and i dont know why') cardSort_customField?: STRt = new StrInfo('field key used for sorting cards'); + cardSort_activeIcons?: List; cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 2ca2ce9c9..94eee6711 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -660,13 +660,15 @@ pie title Minerals in my tap water } static cardTools(): Button[] { return [ - { btnList: new List(["Time", "Type", "Color", "Chat GPT", "Custom 1", "Custom 2", "Custom 3" ]), - title: "Sort Type", toolTip: "Card Sort Type", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: '{ return setCardSort(value, _readOnly_); }'}}, + // { btnList: new List(["Time", "Type", "Color", "Chat GPT", "Custom 1", "Custom 2", "Custom 3" ]), + // title: "Sort Type", toolTip: "Card Sort Type", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: '{ return setCardSort(value, _readOnly_); }'}}, // { title: "Font", toolTip: "Font", width: 100, btnType: ButtonType.DropdownList, toolType:"font", ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'}, // btnList: new List(["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]) }, - // { title: "Time", icon:"hourglass-half", toolTip:"Sort by most recent document creation", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"time", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Type", icon:"eye", toolTip:"Sort by document type", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"docType",funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Color", icon:"palette", toolTip:"Sort by document color", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"color", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "Time", icon:"hourglass-half", toolTip:"Sort by most recent document creation", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"time", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "Type", icon:"eye", toolTip:"Sort by document type", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"docType",funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "Color", icon:"palette", toolTip:"Sort by document color", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"color", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "AI Sort", icon:"palette", toolTip:"Have Chat GPT sort your cards for you !", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"chat", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "AIs", icon:"Visibility", toolTip:"Filter AI labels", subMenu: this.cardGroupTools("robot"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("chat", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // { title: "Custom", icon:"heart", toolTip:"Add Like labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"like", funcs: {hidden:`showFreeform ("like", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "1st", icon:"Visibility", toolTip:"Filter likes", width: 150, subMenu: this.cardGroupTools("heart"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("like", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index f61c784df..b06d785e1 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -548,7 +548,8 @@ export class MainView extends ObservableReactComponent<{}> { fa.faRobot, fa.faSatellite, fa.faStar, - fa.faCloud + fa.faCloud, + fa.faBolt ] ); } diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index 76536ed48..2ad7f0ed1 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -3,7 +3,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { ClientUtils, DashColor, returnFalse, returnZero } from '../../../ClientUtils'; import { emptyFunction, numberRange } from '../../../Utils'; -import { Doc, NumListCast } from '../../../fields/Doc'; +import { Doc, NumListCast, StrListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { BoolCast, Cast, DateCast, NumCast, RTFCast, ScriptCast, StrCast } from '../../../fields/Types'; @@ -27,12 +27,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { SettingsManager } from '../../util/SettingsManager'; import { Tooltip } from '@mui/material'; import { dropActionType } from '../../util/DropActionTypes'; +import { List } from '../../../fields/List'; enum cardSortings { Time = 'time', Type = 'type', Color = 'color', Custom = 'custom', + Drag = 'drag', None = '', } @observer @@ -48,7 +50,7 @@ export class CollectionCardView extends CollectionSubView() { @observable _docRefs = new ObservableMap(); _draggerRef = React.createRef(); @observable _maxRowCount = 10; - @observable _docsDraggedIndex: number[] = []; + @observable _docDraggedIndex: number = -1; @observable _isACardBeingDragged: boolean = false; @observable overIndex: number = -1; @@ -73,12 +75,6 @@ export class CollectionCardView extends CollectionSubView() { } }; - protected createDashEventsTarget = (ele: HTMLDivElement | null) => { - this._dropDisposer?.(); - if (ele) { - this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); - } - }; constructor(props: any) { super(props); @@ -145,12 +141,7 @@ export class CollectionCardView extends CollectionSubView() { return regularDocs; } - /** - * Determines the order in which the cards will be rendered depending on the current sort type - */ - @computed get sortedDocs() { - return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.layoutDoc.sortDesc)); - } + /** * Number of rows of cards to be rendered @@ -226,27 +217,71 @@ export class CollectionCardView extends CollectionSubView() { return Math.abs(stepMag * (apex - index - 1)) - rowOffset; }; - /** - * Translates the selected node to the middle fo the screen - * @param index - * @returns - */ - // translateSelected = (index: number): number => { - // // if (this.isSelected(index)) { - // const middleOfPanel = this._props.PanelWidth() / 2; - // const scaledNodeWidth = this.panelWidth() * 1.25; + findCardDropIndex = (mouseX: number, mouseY: number) => { + + const amCardsTotal = this.sortedDocs.length + let index = 0; + const cardWidth = amCardsTotal < this._maxRowCount ? this._props.PanelWidth() / amCardsTotal : this._props.PanelWidth() / this._maxRowCount; + + // Calculate the adjusted X position accounting for the initial offset + let adjustedX = mouseX + + const amRows = Math.ceil(amCardsTotal / this._maxRowCount); + const rowHeight = this._props.PanelHeight( ) / amRows + const currRow = Math.floor((mouseY - 100) / rowHeight) //rows start at 0 + + if (adjustedX < 0) { + return 0; // Before the first column + } + + if (amCardsTotal < this._maxRowCount) { + index = Math.floor(adjustedX / cardWidth); + } + + else if (currRow != amRows -1 ){ + index = Math.floor(adjustedX / cardWidth) + (currRow * this._maxRowCount) + } - // // Calculate the position of the node's left edge before scaling - // const nodeLeftEdge = index * this.panelWidth(); - // // Find the center of the node after scaling - // const scaledNodeCenter = nodeLeftEdge + scaledNodeWidth / 2; + else { + // console.log(amRows + "am rows") + const rowAmCards = amCardsTotal - (currRow * this._maxRowCount) + const offset = ((this._maxRowCount - rowAmCards ) / 2) * cardWidth + adjustedX = mouseX - offset - // // Calculate the translation needed to align the scaled node's center with the panel's center - // const translation = middleOfPanel - scaledNodeCenter - scaledNodeWidth - scaledNodeWidth / 4; + index = Math.floor(adjustedX / cardWidth) + (currRow * this._maxRowCount); + } + return index; + }; - // return translation; - // }; + @action + onPointerMove = (e: React.PointerEvent) => { + if (DragManager.docsBeingDragged.length != 0 ) { + this._isACardBeingDragged = true + + const newIndex = this.findCardDropIndex(e.clientX, e.clientY); + + if (newIndex !== this._docDraggedIndex && newIndex != -1) { + this._docDraggedIndex = newIndex; + } + } + }; + + onInternalDrop = (e: Event, de: DragManager.DropEvent) => { + if (de.complete.docDragData) { + this._isACardBeingDragged = false; + this._docDraggedIndex = -1; + e.stopPropagation() + const draggedDocs = de.complete.docDragData?.draggedDocuments; + return true; + } + return false; + }; + + @computed get sortedDocs() { + // console.log("hi hi hi") + return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.layoutDoc.sortDesc), this._docDraggedIndex); + } /** * Called in the sortedDocsType method. Compares the cards' value in regards to the desired sort type-- earlier cards are move to the * front, latter cards to the back @@ -255,7 +290,8 @@ export class CollectionCardView extends CollectionSubView() { * @param isDesc * @returns */ - sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean) => { + sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean, dragIndex: number) => { + // console.log('HIIIIIIIII') if (sortType === cardSortings.None) return docs; docs.sort((docA, docB) => { const [typeA, typeB] = (() => { @@ -281,9 +317,25 @@ export class CollectionCardView extends CollectionSubView() { return isDesc ? -out : out; // Reverse the sort order if descending is true }); + if (dragIndex != -1){ + // console.log("what what") + + const draggedDoc = DragManager.docsBeingDragged[0] + const originalIndex = docs.findIndex(doc => doc === draggedDoc); + + + // Remove the dragged document from its original position + docs.splice(originalIndex, 1); + // Insert the dragged document at the new position + docs.splice(dragIndex, 0, draggedDoc); + // } + } + return docs; }; + + displayDoc = (doc: Doc, screenToLocalTransform: () => Transform) => ( { - this.cardSort_customField && (doc[this.cardSort_customField] = buttonID); - }, 'toggle custom button'); - + /** * A list of the text content of all the child docs. RTF documents will have just their text and pdf documents will have the first 50 words. * Image documents are converted to bse64 and gpt generates a description for them. all other documents use their title. This string is @@ -456,27 +499,37 @@ export class CollectionCardView extends CollectionSubView() { * @returns */ renderButtons = (doc: Doc, cardSort: cardSortings): JSX.Element | null => { - if (cardSort !== cardSortings.Custom) return null; + // if (cardSort !== cardSortings.Custom) return null; - const amButtons = Math.max( - 4, - this.childDocs?.reduce((set, d) => { - if (this.cardSort_customField) { - set.add(NumCast(d[this.cardSort_customField])); - } - return set; - }, new Set()).size ?? 0 - ); + const amButtons = 4 + + // const amButtons = Math.max( + // 4, + // this.childDocs?.reduce((set, d) => { + // if (this.cardSort_customField) { + // set.add(NumCast(d[this.cardSort_customField])); + // } + // return set; + // }, new Set()).size ?? 0 + // ); const activeButtonIndex = CollectionCardView.getButtonGroup(this.cardSort_customField, doc); + const totalWidth = amButtons * 72 + amButtons * 2 * 5 + 6; + const iconMap: { [key: number]: any } = { + 0: 'star', + 1: 'heart', + 2: 'cloud', + 3: 'bolt' + }; + return (
{numberRange(amButtons).map(i => ( - Click to add/remove this card from group {i + 1}
}> - ))} @@ -484,53 +537,44 @@ export class CollectionCardView extends CollectionSubView() { ); }; - getButtonIcon = (isActive: boolean): JSX.Element => { - const iconMap: { [key: string]: any } = { - like: 'heart', - chat: 'robot', - idea: 'cloud', - }; + /** + * Toggles the buttons between on and off when creating custom sort groupings/changing those created by gpt + * @param childPairIndex + * @param buttonID + * @param doc + */ + toggleButton = undoable((doc: Doc, icon: string) => { + + + + // this.cardSort_customField && (doc[this.cardSort_customField] = buttonID); + + // doc.cardSort_activeIcons = new List() + - const icon = iconMap[this.cardSort_customField ?? ''] || 'star'; + const list = StrListCast(doc.cardSort_activeIcons); + doc.cardSort_activeIcons = new List(list.includes(icon) ? list.filter(d => d !== icon) : [...list, icon]); + + + + // StrListCast(doc.cardSort_activeIcons).push(iconMap[buttonID]) + }, 'toggle card tag'); + + + getButtonIcon = (doc: Doc, icon: any): JSX.Element => { + + const isActive = StrListCast(doc.cardSort_activeIcons).includes(icon) + + console.log(StrListCast(doc.cardSort_activeIcons)) const color = isActive ? '#4476f7' : '#323232'; return ; }; - // @action - // onDragStart = (index: number) => { - // this.draggedIndex = index; - // }; - - // @action - // onDragOver = (index: number) => { - // if (this.draggedIndex !== index) { - // this.overIndex = index; - // } - // }; - - // @action - // onDrop = () => { - // if (this.draggedIndex !== -1 && this.overIndex !== -1) { - // const draggedDoc = this.sortedDocs[this.draggedIndex]; - // this.sortedDocs.splice(this.draggedIndex, 1); - // this.sortedDocs.splice(this.overIndex, 0, draggedDoc); - // this.draggedIndex = -1; - // this.overIndex = -1; - // } - // }; - - // @action - // onDragEnd = () => { - // this.draggedIndex = -1; - // this.overIndex = -1; - // }; - /** * Actually renders all the cards */ renderCards = () => { - console.log(DragManager.docsBeingDragged.length + 'drag ha'); const anySelected = this.childDocs.some(doc => DocumentView.SelectedDocs().includes(doc)); const isEmpty = this.childDocsWithoutLinks.length === 0; @@ -599,8 +643,9 @@ export class CollectionCardView extends CollectionSubView() { render() { return (
this.onPointerMove(e)} className="collectionCardView-outer" - ref={this.createDashEventsTarget} + ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} style={{ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor), color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color), -- cgit v1.2.3-70-g09d2 From 3a3d4433e0b4bfc134370ba4938f22cbed61428b Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Wed, 26 Jun 2024 14:17:18 -0400 Subject: sigh --- src/client/apis/gpt/GPT.ts | 7 +- src/client/documents/Documents.ts | 8 +- src/client/util/CurrentUserUtils.ts | 46 ++++--- .../views/collections/CollectionCardDeckView.tsx | 147 ++++++++++++--------- src/client/views/global/globalScripts.ts | 94 +++++++------ src/client/views/pdf/GPTPopup/GPTPopup.tsx | 1 + 6 files changed, 182 insertions(+), 121 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 585398204..40af70d99 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -42,8 +42,9 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { sort: { model: 'gpt-4o', maxTokens: 2048, - temp: 0.5, - prompt: "I'm going to give you a list of descriptions. Each one is separated by `======` on either side. Descriptions will vary in length, so make sure to only separate when you see `======`. Sort them into lists by shared content. Make sure each description is in only one list. Each list should be separated by `======` with the elements within it separated by `~~~~~~`. Immediately afterward, surrounded by `------` on BOTH SIDES, provide some insight into your reasoning for the way you sorted. It is VERY important that you format it exactly as described, ensuring the proper number of `=` `~` and `-` (6 of each) and no commas.Try to create around 4 groups, but a little more or less is ok. Also, I may provide some more insight after this colon:" + temp: 0.25, + prompt: "The user is going to give you a list of descriptions. Each one is separated by `======` on either side. Descriptions will vary in length, so make sure to only separate when you see `======`. Sort them by shared content. Make sure each description is only in the list once. Each item should be separated by `======`. Immediately afterward, surrounded by `------` on BOTH SIDES, provide some insight into your reasoning for the way you sorted (and mention nothing about the formatting details given in this description). It is VERY important that you format it exactly as described, ensuring the proper number of `=` and `-` (6 of each) and no commas" + // prompt: "I'm going to give you a list of descriptions. Each one is separated by `======` on either side. Descriptions will vary in length, so make sure to only separate when you see `======`. Sort them into lists by shared content. Make sure each description is in only one list. Each list should be separated by `======` with the elements within it separated by `~~~~~~`. Immediately afterward, surrounded by `------` on BOTH SIDES, provide some insight into your reasoning for the way you sorted. It is VERY important that you format it exactly as described, ensuring the proper number of `=` `~` and `-` (6 of each) and no commas.Try to create around 4 groups, but a little more or less is ok. Also, I may provide some more insight after this colon:" }, describe: { model: 'gpt-4-vision-preview', maxTokens: 2048, temp: 0, prompt: 'Describe these images in 3-5 words' }, chatcard: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'Answer the following question as a short flashcard response. Do not include a label.' }, @@ -75,7 +76,7 @@ const gptAPICall = async (inputTextIn: string, callType: GPTCallType, prompt?: a // dangerouslyAllowBrowser: true, // }; - const usePrompt = prompt ? opts.prompt + prompt : opts.prompt; + const usePrompt = prompt ? prompt + opts.prompt : opts.prompt; const messages: ChatCompletionMessageParam[] = [ { role: 'system', content: usePrompt }, { role: 'user', content: inputText }, diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a190fe11b..53422b0c8 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -481,8 +481,12 @@ export class DocumentOptions { cardSort?: STRt = new StrInfo('way cards are sorted in deck view'); // cardSortForDropDown?: STRt = new StrInfo('needed for dropdown and i dont know why') cardSort_customField?: STRt = new StrInfo('field key used for sorting cards'); - cardSort_activeIcons?: List; - cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) + cardSort_activeIcons?: List; //icons each card is tagges with + cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) + + // cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) + cardSort_isDesc?: BOOLt = new BoolInfo('whether the cards are sorted ascending or descending'); + test?: STRt = new StrInfo('testing for filtering') } export const DocOptions = new DocumentOptions(); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 9cf3bfe9b..48e4441de 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -668,15 +668,25 @@ pie title Minerals in my tap water { title: "Type", icon:"eye", toolTip:"Sort by document type", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"docType",funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Color", icon:"palette", toolTip:"Sort by document color", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"color", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "AI Sort", icon:"robot", toolTip:"Have Chat GPT sort your cards for you !", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"chat", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + + { title: "Sort", toolTip: "Manage sort order / lock status", icon: "sort" , btnType: ButtonType.MultiToggleButton, toolType:"alignment", ignoreClick: true, + subMenu: [ + { title: "Ascending", toolTip: "Sort the cards in ascending order", btnType: ButtonType.ToggleButton, icon: "sort-up", toolType:"up", ignoreClick: true, scripts: {onClick: '{ return showFreeform(this.toolType, _readOnly_);}' }}, + { title: "Descending", toolTip: "Sort the cards in descending order",btnType: ButtonType.ToggleButton, icon: "sort-down",toolType:"down",ignoreClick: true, scripts: {onClick: '{ return showFreeform(this.toolType, _readOnly_);}'} }, + ]}, + { title: "Filter", icon:"Filter", toolTip:"Filter cards by tags", width: 150, subMenu: this.cardGroupTools(), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, + + + - // { title: "AIs", icon:"Visibility", toolTip:"Filter AI labels", subMenu: this.cardGroupTools("robot"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("chat", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // { title: "Custom", icon:"heart", toolTip:"Add Like labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"like", funcs: {hidden:`showFreeform ("like", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - { title: "1st", icon:"Visibility", toolTip:"Filter likes", width: 150, subMenu: this.cardGroupTools("heart"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("like", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // { title: "Custom", icon:"star", toolTip:"Add Star labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {hidden:`showFreeform ("star", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - { title: "2nd", icon:"Visibility", toolTip:"Filter stars", width: 150, subMenu: this.cardGroupTools("star"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("star", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // { title: "Custom", icon:"cloud", toolTip:"Add Idea labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"idea", funcs: {hidden:`showFreeform ("idea", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - { title: "3rd", icon:"Visibility", toolTip:"Filter ideas", width: 150, subMenu: this.cardGroupTools("cloud"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("idea", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, + // // { title: "AIs", icon:"Visibility", toolTip:"Filter AI labels", subMenu: this.cardGroupTools("robot"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("chat", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, + // // { title: "Custom", icon:"heart", toolTip:"Add Like labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"like", funcs: {hidden:`showFreeform ("like", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // { title: "1st", icon:"Visibility", toolTip:"Filter likes", width: 150, subMenu: this.cardGroupTools("heart"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("like", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, + // // { title: "Custom", icon:"star", toolTip:"Add Star labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {hidden:`showFreeform ("star", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // { title: "2nd", icon:"Visibility", toolTip:"Filter stars", width: 150, subMenu: this.cardGroupTools("star"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("star", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, + // // { title: "Custom", icon:"cloud", toolTip:"Add Idea labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"idea", funcs: {hidden:`showFreeform ("idea", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // { title: "3rd", icon:"Visibility", toolTip:"Filter ideas", width: 150, subMenu: this.cardGroupTools("cloud"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("idea", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, ] } // static labelTools(): Button[] { @@ -691,15 +701,21 @@ pie title Minerals in my tap water // { title: "3rd", icon:"3rd", toolTip:"Filter ideas", width: 80, subMenu: this.cardGroupTools("cloud"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("idea", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // ] // } - static cardGroupTools(icon: string): Button[] { + static cardGroupTools(): Button[] { return [ - { title: "Group 1", icon, toolTip:"Click to toggle group 1's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"1", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - { title: "Group 2", icon, toolTip:"Click to toggle group 2's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"2", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - { title: "Group 3", icon, toolTip:"Click to toggle group 3's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"3", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - { title: "Group 4", icon, toolTip:"Click to toggle group 4's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"4", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - { title: "", icon, toolTip:"Click to toggle group 5's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"5", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - { title: "", icon, toolTip:"Click to toggle group 6's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"6", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - { title: "", icon, toolTip:"Click to toggle group 7's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"7", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "Star", icon: "star", toolTip:"Click to toggle the star group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "Heart", icon: "heart", toolTip:"Click to toggle the heart group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"heart", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "Bolt", icon: "bolt", toolTip:"Click to toggle the bolt group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"bolt", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "Cloud", icon: "cloud", toolTip:"Click to toggle the cloud group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"cloud", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + + + // { title: "Group 1", icon, toolTip:"Click to toggle group 1's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"1", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // { title: "Group 2", icon, toolTip:"Click to toggle group 2's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"2", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // { title: "Group 3", icon, toolTip:"Click to toggle group 3's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"3", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // { title: "Group 4", icon, toolTip:"Click to toggle group 4's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"4", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // { title: "", icon, toolTip:"Click to toggle group 5's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"5", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // { title: "", icon, toolTip:"Click to toggle group 6's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"6", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // { title: "", icon, toolTip:"Click to toggle group 7's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"7", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, ] } static viewTools(): Button[] { diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index 09cddda19..d8f4362f1 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -34,7 +34,7 @@ enum cardSortings { Type = 'type', Color = 'color', Custom = 'custom', - Drag = 'drag', + Chat = 'chat', None = '', } @observer @@ -45,7 +45,7 @@ export class CollectionCardView extends CollectionSubView() { private _textToDoc = new Map(); @observable _forceChildXf = false; - @observable _isLoading = false; + // @observable _isLoading = false; @observable _hoveredNodeIndex = -1; @observable _docRefs = new ObservableMap(); _draggerRef = React.createRef(); @@ -94,9 +94,10 @@ export class CollectionCardView extends CollectionSubView() { }; componentDidMount(): void { + this.Document.childFilters_boolean = 'OR' this._disposers.sort = reaction( - () => ({ cardSort: this.cardSort, field: this.cardSort_customField }), - ({ cardSort, field }) => (cardSort === cardSortings.Custom && field === 'chat' ? this.openChatPopup() : GPTPopup.Instance.setVisible(false)) + () => ({ cardSort: this.cardSort }), + ({ cardSort}) => (cardSort === cardSortings.Chat ? this.openChatPopup() : GPTPopup.Instance.setVisible(false)) ); } @@ -112,6 +113,7 @@ export class CollectionCardView extends CollectionSubView() { @computed get cardSort() { return StrCast(this.Document.cardSort) as any as cardSortings; } + /** * how much to scale down the contents of the view so that everything will fit */ @@ -126,15 +128,13 @@ export class CollectionCardView extends CollectionSubView() { */ @computed get childDocsWithoutLinks() { const regularDocs = this.childDocs.filter(l => l.type !== DocumentType.LINK); - const activeGroups = NumListCast(this.Document.cardSort_visibleSortGroups); + const activeGroups = StrListCast(this.Document.cardSort_visibleSortGroups); - if (activeGroups.length > 0 && this.cardSort === cardSortings.Custom) { + if (activeGroups.length > 0) { return regularDocs.filter(doc => { - // Get the group number for the current index - const groupNumber = CollectionCardView.getButtonGroup(this.cardSort_customField, doc); - // Check if the group number is in the active groups - return groupNumber !== undefined && activeGroups.includes(groupNumber); - }); + const activeTags = StrListCast(doc.cardSort_activeIcons) + return activeTags !== undefined && activeTags.some(tag => activeGroups.includes(tag)); + }) } // Default return for non-custom cardSort or other cases, filtering out links @@ -217,7 +217,7 @@ export class CollectionCardView extends CollectionSubView() { return Math.abs(stepMag * (apex - index - 1)) - rowOffset; }; - findCardDropIndex = (mouseX: number, mouseY: number) => { + findCardDropIndex = (mouseX: number, mouseY: number, direction: 'left' | 'right') => { const amCardsTotal = this.sortedDocs.length let index = 0; @@ -257,8 +257,9 @@ export class CollectionCardView extends CollectionSubView() { onPointerMove = (e: React.PointerEvent) => { if (DragManager.docsBeingDragged.length != 0 ) { this._isACardBeingDragged = true - - const newIndex = this.findCardDropIndex(e.clientX, e.clientY); + + const direction = e.movementX > 0 ? 'right' : 'left'; + const newIndex = this.findCardDropIndex(e.clientX, e.clientY, direction); if (newIndex !== this._docDraggedIndex && newIndex != -1) { this._docDraggedIndex = newIndex; @@ -278,9 +279,13 @@ export class CollectionCardView extends CollectionSubView() { return false; }; + @computed get sortedDocs() { // console.log("hi hi hi") - return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.layoutDoc.sortDesc), this._docDraggedIndex); + // console.log(this.layoutDoc.cardSort_isDesc + "layoutdoc desc") + console.log(this.cardSort + "card sort") + + return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.layoutDoc.cardSort_isDesc), this._docDraggedIndex); } /** * Called in the sortedDocsType method. Compares the cards' value in regards to the desired sort type-- earlier cards are move to the @@ -291,48 +296,53 @@ export class CollectionCardView extends CollectionSubView() { * @returns */ sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean, dragIndex: number) => { - // console.log('HIIIIIIIII') - if (sortType === cardSortings.None) return docs; - docs.sort((docA, docB) => { - const [typeA, typeB] = (() => { + // if (sortType === cardSortings.None) return docs; + + if(sortType !== cardSortings.None){ + docs.sort((docA, docB) => { + + const [typeA, typeB] = (() => { switch (sortType) { case cardSortings.Time: - return [DateCast(docA.author_date)?.date ?? Date.now(), - DateCast(docB.author_date)?.date ?? Date.now()]; + return [DateCast(docA.author_date)?.date ?? Date.now(), + DateCast(docB.author_date)?.date ?? Date.now()]; case cardSortings.Color: - return [ClientUtils.hexToHsv(StrCast(docA.backgroundColor)), // If docA.type is undefined, use an empty string - ClientUtils.hexToHsv(StrCast(docB.backgroundColor))]; // If docB.type is undefined, use an empty string + return [ClientUtils.hexToHsv(StrCast(docA.backgroundColor)), + ClientUtils.hexToHsv(StrCast(docB.backgroundColor))]; case cardSortings.Custom: - return [CollectionCardView.getButtonGroup(this.cardSort_customField, docA)??9999, - CollectionCardView.getButtonGroup(this.cardSort_customField, docB)??9999]; - default: return [StrCast(docA.type), // If docA.type is undefined, use an empty string - StrCast(docB.type)]; // If docB.type is undefined, use an empty string - } // prettier-ignore + return [CollectionCardView.getButtonGroup(this.cardSort_customField, docA) ?? 9999, + CollectionCardView.getButtonGroup(this.cardSort_customField, docB) ?? 9999]; + case cardSortings.Chat: + return [NumCast(docA.chat) ?? 9999, + NumCast(docB.chat) ?? 9999] + default: + return [StrCast(docA.type), StrCast(docB.type)] + } })(); - - // console.log(ClientUtils.hexToHsv(StrCast(docA.backgroundColor)) ?? 9999 + "docA col") - // console.log(ClientUtils.hexToHsv(StrCast(docB.backgroundColor)) ?? 9999 + "docB col") - + + // console.log(`Sorting ${sortType}: ${typeA} vs ${typeB}`); const out = typeA < typeB ? -1 : typeA > typeB ? 1 : 0; - return isDesc ? -out : out; // Reverse the sort order if descending is true - }); + // console.log(`Comparison result: ${out} (isDesc: ${isDesc})`); - if (dragIndex != -1){ - // console.log("what what") + if (isDesc){ + return out + } - const draggedDoc = DragManager.docsBeingDragged[0] + return -out + + });} + + if (dragIndex != -1) { + const draggedDoc = DragManager.docsBeingDragged[0]; const originalIndex = docs.findIndex(doc => doc === draggedDoc); - - - // Remove the dragged document from its original position + docs.splice(originalIndex, 1); - // Insert the dragged document at the new position docs.splice(dragIndex, 0, draggedDoc); - // } } - + return docs; }; + @@ -464,22 +474,35 @@ export class CollectionCardView extends CollectionSubView() { * Converts the gpt output into a hashmap that can be used for sorting. lists are seperated by ==== while elements within the list are seperated by ~~~~~~ * @param gptOutput */ - processGptOutput = (gptOutput: string) => { + @action processGptOutput = (gptOutput: string) => { // Split the string into individual list items const listItems = gptOutput.split('======').filter(item => item.trim() !== ''); + // console.log(listItems + " LISTT"); + + // Debug: print the map contents + // console.log("Map contents:", Array.from(this._textToDoc.entries())); + listItems.forEach((item, index) => { - // Split the item by '~~~~~~' to get all descriptors - const parts = item.split('~~~~~~').map(part => part.trim()); - - parts.forEach(part => { - // Find the corresponding Doc in the textToDoc map - const doc = this._textToDoc.get(part); - if (doc) { - doc.chat = index; - } - }); + // Normalize the item (trim whitespace) + const normalizedItem = item.trim(); + // console.log("Normalized item:", normalizedItem); + + // Find the corresponding Doc in the textToDoc map + const doc = this._textToDoc.get(normalizedItem); + // console.log("DOC:", doc); + // console.log("ITEM:", normalizedItem); + + if (doc) { + doc.chat = index; + } else { + console.warn(`No matching document found for item: ${normalizedItem}`); + } }); - }; + + } + + // ); + // }; /** * Opens up the chat popup and starts the process for smart sorting. */ @@ -513,7 +536,7 @@ export class CollectionCardView extends CollectionSubView() { // }, new Set()).size ?? 0 // ); - const activeButtonIndex = CollectionCardView.getButtonGroup(this.cardSort_customField, doc); + // const activeButtonIndex = CollectionCardView.getButtonGroup(this.cardSort_customField, doc); const totalWidth = amButtons * 72 + amButtons * 2 * 5 + 6; @@ -552,8 +575,10 @@ export class CollectionCardView extends CollectionSubView() { // doc.cardSort_activeIcons = new List() - const list = StrListCast(doc.cardSort_activeIcons); - doc.cardSort_activeIcons = new List(list.includes(icon) ? list.filter(d => d !== icon) : [...list, icon]); + // const list = StrListCast(doc.cardSort_activeIcons); + // doc.cardSort_activeIcons = new List(list.includes(icon) ? list.filter(d => d !== icon) : [...list, icon]); + + BoolCast(doc[icon]) ? doc[icon] = false : doc[icon] = true @@ -563,9 +588,10 @@ export class CollectionCardView extends CollectionSubView() { getButtonIcon = (doc: Doc, icon: any): JSX.Element => { - const isActive = StrListCast(doc.cardSort_activeIcons).includes(icon) + // const isActive = StrListCast(doc.cardSort_activeIcons).includes(icon) + const isActive = doc[icon] - console.log(StrListCast(doc.cardSort_activeIcons)) + // console.log(StrListCast(doc.cardSort_activeIcons)) const color = isActive ? '#4476f7' : '#323232'; return ; @@ -577,6 +603,7 @@ export class CollectionCardView extends CollectionSubView() { renderCards = () => { const anySelected = this.childDocs.some(doc => DocumentView.SelectedDocs().includes(doc)); const isEmpty = this.childDocsWithoutLinks.length === 0; + const isDesc = BoolCast(this.Document.cardSort_isDesc) if (isEmpty) { return ( diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 1344dd071..4239329dd 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -36,7 +36,7 @@ import { ImageBox } from '../nodes/ImageBox'; import { VideoBox } from '../nodes/VideoBox'; import { WebBox } from '../nodes/WebBox'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; -import { NumListCast } from '../../../fields/Doc'; +import { NumListCast, StrListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; // import { InkTranscription } from '../InkTranscription'; @@ -137,20 +137,25 @@ ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) { // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' | 'clusters' | 'viewAll' | 'fitOnce', checkResult?: boolean, persist?: boolean) { const selected = DocumentView.SelectedDocs().lastElement(); + + function isAttrFiltered(attr: string) { + return StrListCast(selected._childFilters).some(filter => filter.includes(attr)) + } + // prettier-ignore - const map: Map<'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'like' | 'star' | 'idea' | 'chat' | '1' | '2' | '3' | '4', + const map: Map<'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'heart' | 'star' | 'cloud' | 'bolt' | 'chat' | '1' | '2' | '3' | '4' | 'up' | 'down', { waitForRender?: boolean; checkResult: (doc: Doc) => any; setDoc: (doc: Doc, dv: DocumentView) => void; }> = new Map([ ['grid', { - checkResult: (doc:Doc) => BoolCast(doc?._freeform_backgroundGrid, false), - setDoc: (doc:Doc) => { doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid; }, + checkResult: (doc: Doc) => BoolCast(doc?._freeform_backgroundGrid, false), + setDoc: (doc: Doc) => { doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid; }, }], ['snaplines', { - checkResult: (doc:Doc) => BoolCast(doc?._freeform_snapLines, false), - setDoc: (doc:Doc) => { doc._freeform_snapLines = !doc._freeform_snapLines; }, + checkResult: (doc: Doc) => BoolCast(doc?._freeform_snapLines, false), + setDoc: (doc: Doc) => { doc._freeform_snapLines = !doc._freeform_snapLines; }, }], ['viewAll', { checkResult: (doc: Doc) => BoolCast(doc?._freeform_fitContentsToBox, false), @@ -161,13 +166,13 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' }, }], ['center', { - checkResult: (doc:Doc) => BoolCast(doc?._stacking_alignCenter, false), - setDoc: (doc:Doc) => { doc._stacking_alignCenter = !doc._stacking_alignCenter; }, + checkResult: (doc: Doc) => BoolCast(doc?._stacking_alignCenter, false), + setDoc: (doc: Doc) => { doc._stacking_alignCenter = !doc._stacking_alignCenter; }, }], ['clusters', { waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire - checkResult: (doc:Doc) => BoolCast(doc?._freeform_useClusters, false), - setDoc: (doc:Doc) => { doc._freeform_useClusters = !doc._freeform_useClusters; }, + checkResult: (doc: Doc) => BoolCast(doc?._freeform_useClusters, false), + setDoc: (doc: Doc) => { doc._freeform_useClusters = !doc._freeform_useClusters; }, }], ['flashcards', { checkResult: (doc: Doc) => BoolCast(Doc.UserDoc().defaultToFlashcards, false), @@ -185,63 +190,70 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "color", setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort === "color" ? doc.cardSort = '' : doc.cardSort = 'color', }], - ['links', { - checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "links", - setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort = "links", - }], - ['like', { - checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && StrCast(doc?.cardSort_customField) === "like", + ['heart', { + checkResult: (doc: Doc) => isAttrFiltered('heart'), setDoc: (doc: Doc, dv: DocumentView) => { - doc.cardSort = "custom"; - doc.cardSort_customField = "like"; - doc.cardSort_visibleSortGroups = new List(); + isAttrFiltered('heart') ? Doc.setDocFilter(doc, 'heart', true, 'remove') : Doc.setDocFilter(doc, 'heart', true, 'match'); + } }], ['star', { - checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && StrCast(doc?.cardSort_customField) === "star", + checkResult: (doc: Doc) => isAttrFiltered('star'), + setDoc: (doc: Doc, dv: DocumentView) => { - doc.cardSort = "custom"; - doc.cardSort_customField = "star"; - doc.cardSort_visibleSortGroups = new List(); + isAttrFiltered('star') ? Doc.setDocFilter(doc, 'star', true, 'remove') : Doc.setDocFilter(doc, 'star', true, 'match'); } }], - ['idea', { - checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && StrCast(doc?.cardSort_customField) === "idea", + ['bolt', { + checkResult: (doc: Doc) => isAttrFiltered('bolt'), setDoc: (doc: Doc, dv: DocumentView) => { - doc.cardSort = "custom"; - doc.cardSort_customField = "idea"; - doc.cardSort_visibleSortGroups = new List(); + isAttrFiltered('bolt') ? Doc.setDocFilter(doc, 'bolt', true, 'remove') : Doc.setDocFilter(doc, 'bolt', true, 'match'); + + } + }], + ['cloud', { + checkResult: (doc: Doc) => isAttrFiltered('cloud'), + setDoc: (doc: Doc, dv: DocumentView) => { + isAttrFiltered('cloud') ? Doc.setDocFilter(doc, 'cloud', true, 'remove') : Doc.setDocFilter(doc, 'cloud', true, 'match'); + } }], ['chat', { - checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "custom" && StrCast(doc?.cardSort_customField) === "chat", + checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "chat", setDoc: (doc: Doc, dv: DocumentView) => { - doc.cardSort === "custom" ? doc.cardSort = '' : doc.cardSort = 'custom'; - doc.cardSort_customField === "chat" ? doc.cardSort_customField = '' : doc.cardSort_customField = 'chat'; - doc.cardSort_visibleSortGroups = new List(); + doc.cardSort === "chat" ? doc.cardSort = '' : doc.cardSort = 'chat'; }, }], - ]); - for (let i = 0; i < 8; i++) { - map.set((i + 1 + '') as any, { - checkResult: (doc: Doc) => NumListCast(doc?.cardSort_visibleSortGroups).includes(i), + ['up', { + checkResult: (doc: Doc) => BoolCast(!doc?.cardSort_isDesc), setDoc: (doc: Doc, dv: DocumentView) => { - const list = NumListCast(doc.cardSort_visibleSortGroups); - doc.cardSort_visibleSortGroups = new List(list.includes(i) ? list.filter(d => d !== i) : [...list, i]); + doc.cardSort_isDesc = false; }, - }); - } + }], + ['down', { + checkResult: (doc: Doc) => BoolCast(doc?.cardSort_isDesc), + setDoc: (doc: Doc, dv: DocumentView) => { + doc.cardSort_isDesc = true; + }, + }], + ]); if (checkResult) { - // console.log("HIIIIII") return map.get(attr)?.checkResult(selected); } + const filters = StrListCast(selected._childFilters).concat(StrListCast(selected?._childFiltersByRanges).filter((filter, i) => !(i % 3))); + + + + // console.log(filters.some(filter => filter.includes('star'))+ "SUOOOOPPP") + const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} }; DocumentView.Selected().map(dv => map.get(attr)?.setDoc(dv.layoutDoc, dv)); setTimeout(() => batch.end(), 100); return undefined; }); + ScriptingGlobals.add(function cardHasLabel(label: string) { const selected = DocumentView.SelectedDocs().lastElement(); const labelNum = Number(label) - 1; diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 468922532..6184a7b73 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -180,6 +180,7 @@ export class GPTPopup extends ObservableReactComponent { * Sorts cards in the CollectionCardDeckView */ generateSort = async () => { + console.log(this.chatSortPrompt + "USER PROMPT") this.setLoading(true); this.setSortDone(false); -- cgit v1.2.3-70-g09d2 From 9b0fa4d5581942c54375c10e3887c8010d3eb5e4 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Thu, 27 Jun 2024 14:06:22 -0400 Subject: time --- src/client/documents/Documents.ts | 6 +- src/client/util/CurrentUserUtils.ts | 2 + .../views/collections/CollectionCardDeckView.tsx | 8 ++- .../views/collections/CollectionCarouselView.tsx | 2 +- src/client/views/global/globalScripts.ts | 80 +++++++++++++++++----- src/client/views/pdf/AnchorMenu.tsx | 2 +- 6 files changed, 75 insertions(+), 25 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 53422b0c8..324d80581 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -480,13 +480,13 @@ export class DocumentOptions { cardSort?: STRt = new StrInfo('way cards are sorted in deck view'); // cardSortForDropDown?: STRt = new StrInfo('needed for dropdown and i dont know why') - cardSort_customField?: STRt = new StrInfo('field key used for sorting cards'); + // cardSort_customField?: STRt = new StrInfo('field key used for sorting cards'); cardSort_activeIcons?: List; //icons each card is tagges with - cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) + // cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) // cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) cardSort_isDesc?: BOOLt = new BoolInfo('whether the cards are sorted ascending or descending'); - test?: STRt = new StrInfo('testing for filtering') + // test?: STRt = new StrInfo('testing for filtering') } export const DocOptions = new DocumentOptions(); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 48e4441de..f3b5e5b1d 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -668,12 +668,14 @@ pie title Minerals in my tap water { title: "Type", icon:"eye", toolTip:"Sort by document type", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"docType",funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Color", icon:"palette", toolTip:"Sort by document color", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"color", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "AI Sort", icon:"robot", toolTip:"Have Chat GPT sort your cards for you !", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"chat", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + { title: "Pile", icon:"layer-group", toolTip:"View the cards as a pile in the free form view !", btnType: ButtonType.ClickButton, expertMode: false, toolType:"pile", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Sort", toolTip: "Manage sort order / lock status", icon: "sort" , btnType: ButtonType.MultiToggleButton, toolType:"alignment", ignoreClick: true, subMenu: [ { title: "Ascending", toolTip: "Sort the cards in ascending order", btnType: ButtonType.ToggleButton, icon: "sort-up", toolType:"up", ignoreClick: true, scripts: {onClick: '{ return showFreeform(this.toolType, _readOnly_);}' }}, { title: "Descending", toolTip: "Sort the cards in descending order",btnType: ButtonType.ToggleButton, icon: "sort-down",toolType:"down",ignoreClick: true, scripts: {onClick: '{ return showFreeform(this.toolType, _readOnly_);}'} }, ]}, + { title: "Filter", icon:"Filter", toolTip:"Filter cards by tags", width: 150, subMenu: this.cardGroupTools(), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index d8f4362f1..d3e23c962 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -53,6 +53,7 @@ export class CollectionCardView extends CollectionSubView() { @observable _docDraggedIndex: number = -1; @observable _isACardBeingDragged: boolean = false; @observable overIndex: number = -1; + static getButtonGroup(groupFieldKey: 'chat' | 'star' | 'idea' | 'like', doc: Doc): number | undefined { return Cast(doc[groupFieldKey], 'number', null); @@ -97,8 +98,10 @@ export class CollectionCardView extends CollectionSubView() { this.Document.childFilters_boolean = 'OR' this._disposers.sort = reaction( () => ({ cardSort: this.cardSort }), - ({ cardSort}) => (cardSort === cardSortings.Chat ? this.openChatPopup() : GPTPopup.Instance.setVisible(false)) + ({ cardSort}) => (cardSort === cardSortings.Chat ? this.openChatPopup() : GPTPopup.Instance.setVisible(false)) ); + + } componentWillUnmount() { @@ -475,6 +478,9 @@ export class CollectionCardView extends CollectionSubView() { * @param gptOutput */ @action processGptOutput = (gptOutput: string) => { + + console.log("HIIII") + console.log(StrCast(this.Document.cardSort) + "cardSort") // Split the string into individual list items const listItems = gptOutput.split('======').filter(item => item.trim() !== ''); // console.log(listItems + " LISTT"); diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 2adad68e0..4884db709 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -33,7 +33,7 @@ enum practiceVal { export class CollectionCarouselView extends CollectionSubView() { private _dropDisposer?: DragManager.DragDropDisposer; get practiceField() { return this.fieldKey + "_practice"; } // prettier-ignore - get starField() { return this.fieldKey + "_star"; } // prettier-ignore + get starField() { return "star"; } // prettier-ignore constructor(props: any) { super(props); diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 4239329dd..2ecde0eee 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -38,8 +38,10 @@ import { WebBox } from '../nodes/WebBox'; import { RichTextMenu } from '../nodes/formattedText/RichTextMenu'; import { NumListCast, StrListCast } from '../../../fields/Doc'; import { List } from '../../../fields/List'; - +import { CollectionViewType } from '../../documents/DocumentTypes'; // import { InkTranscription } from '../InkTranscription'; +import { Docs } from '../../documents/Documents'; +import { CollectionSubView } from '../collections/CollectionSubView'; // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function IsNoneSelected() { @@ -139,11 +141,11 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' const selected = DocumentView.SelectedDocs().lastElement(); function isAttrFiltered(attr: string) { - return StrListCast(selected._childFilters).some(filter => filter.includes(attr)) + return StrListCast(selected._childFilters).some(filter => filter.includes(attr)); } // prettier-ignore - const map: Map<'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'heart' | 'star' | 'cloud' | 'bolt' | 'chat' | '1' | '2' | '3' | '4' | 'up' | 'down', + const map: Map<'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'heart' | 'star' | 'cloud' | 'bolt' | 'chat' | '1' | '2' | '3' | '4' | 'up' | 'down' | 'pile', { waitForRender?: boolean; checkResult: (doc: Doc) => any; @@ -219,7 +221,11 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' } }], ['chat', { - checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "chat", + checkResult: (doc: Doc) => { + + if (StrCast(doc?.cardSort) === "chat"){ + return true + }} , setDoc: (doc: Doc, dv: DocumentView) => { doc.cardSort === "chat" ? doc.cardSort = '' : doc.cardSort = 'chat'; }, @@ -236,6 +242,46 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' doc.cardSort_isDesc = true; }, }], + ['pile', { + checkResult: (doc: Doc) => doc._type_collection == CollectionViewType.Freeform, + setDoc: (doc: Doc, dv: DocumentView) => { + doc._type_collection = CollectionViewType.Freeform; + const newCol = Docs.Create.CarouselDocument(DocListCast(doc[Doc.LayoutFieldKey(doc)]), { + _width: 250, + _height: 200, + _layout_fitWidth: false, + _layout_autoHeight: true, + }); + + + const iconMap: { [key: number]: any } = { + 0: 'star', + 1: 'heart', + 2: 'cloud', + 3: 'bolt' + }; + + for (let i=0; i<4; i++){ + if (isAttrFiltered(iconMap[i])){ + newCol[iconMap[i]] = true + } + } + + // if (doc.type == DocumentType.COL ) { + newCol && dv.ComponentView?.addDocument?.(newCol); + dv.ComponentView?._props.focus(newCol, {willPan: true , willZoomCentered: true, zoomScale: 200} ) + + // } + // doc as CollectionFreeFormView + // doc as typeof CollectionSubView + + // doc._props + + // CollectionFreeFormView.addDocumemnt + + // doc?.addDocument; //this._props.addDocument(newCol) + }, + }], ]); if (checkResult) { @@ -243,8 +289,6 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' } const filters = StrListCast(selected._childFilters).concat(StrListCast(selected?._childFiltersByRanges).filter((filter, i) => !(i % 3))); - - // console.log(filters.some(filter => filter.includes('star'))+ "SUOOOOPPP") const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} }; @@ -253,7 +297,6 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' return undefined; }); - ScriptingGlobals.add(function cardHasLabel(label: string) { const selected = DocumentView.SelectedDocs().lastElement(); const labelNum = Number(label) - 1; @@ -355,37 +398,36 @@ ScriptingGlobals.add(function setCardSort(value?: any, checkResult?: boolean) { if (checkResult) { // console.log(attr + "attricute") // console.log(map.get(attr)?.checkResult(selected) + "check result") - console.log(StrCast(selected?.cardSort) + "check") - const hi = StrCast(selected?.cardSort) - return StrCast(selected?.cardSortForDropDown) ?? "Time"; + console.log(StrCast(selected?.cardSort) + 'check'); + const hi = StrCast(selected?.cardSort); + return StrCast(selected?.cardSortForDropDown) ?? 'Time'; } - + function docFields(doc: Doc): void { - switch(value){ + switch (value) { case 'Custom 1': - doc.cardSort_customField = "like"; + doc.cardSort_customField = 'like'; break; case 'Custom 2': - doc.cardSort_customField = "star"; + doc.cardSort_customField = 'star'; break; case 'Custom 3': - doc.cardSort_customField = "idea"; + doc.cardSort_customField = 'idea'; break; case 'Chat GPT': - doc.cardSort = "custom"; - doc.cardSort_customField = "chat"; + doc.cardSort = 'custom'; + doc.cardSort_customField = 'chat'; break; default: break; } doc.cardSort_visibleSortGroups = new List(); - } // const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} }; DocumentView.Selected().map(dv => { - dv.Document.cardSortForDropDown = value + dv.Document.cardSortForDropDown = value; if (value != 'Chat GPT') { dv.Document.cardSort = value.trim().split(/\s+/)[0].toLowerCase(); diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx index 2f6824466..96f025ca0 100644 --- a/src/client/views/pdf/AnchorMenu.tsx +++ b/src/client/views/pdf/AnchorMenu.tsx @@ -133,7 +133,7 @@ export class AnchorMenu extends AntimodeMenu { _layout_autoHeight: true, }); - this.addToCollection?.(newCol); + this.addToCollection?.(newCol); //this._props.addDocument(newCol) }; pointerDown = (e: React.PointerEvent) => { -- cgit v1.2.3-70-g09d2 From de253f5acca34f20017895a2d8469b5ebd6032bf Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Tue, 30 Jul 2024 14:31:00 -0400 Subject: fight w css --- src/client/apis/gpt/GPT.ts | 9 ++ src/client/documents/Documents.ts | 2 + src/client/util/CurrentUserUtils.ts | 4 +- src/client/views/DocumentButtonBar.tsx | 6 +- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/FilterPanel.tsx | 95 ++++++++++++ src/client/views/StyleProvider.tsx | 7 + .../views/collections/CollectionCardDeckView.scss | 50 +++--- .../views/collections/CollectionCardDeckView.tsx | 1 + src/client/views/nodes/IconTagBox.scss | 30 ++++ src/client/views/nodes/IconTagBox.tsx | 168 +++++++++++++++++++++ src/client/views/pdf/GPTPopup/GPTPopup.scss | 3 +- src/client/views/pdf/GPTPopup/GPTPopup.tsx | 164 ++++++++++++++------ 13 files changed, 460 insertions(+), 81 deletions(-) create mode 100644 src/client/views/nodes/IconTagBox.scss create mode 100644 src/client/views/nodes/IconTagBox.tsx (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 40af70d99..d95e564c7 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -12,6 +12,7 @@ enum GPTCallType { DESCRIBE = 'describe', MERMAID = 'mermaid', DATA = 'data', + RUBRIC = 'rubric' } type GPTCallOpts = { @@ -26,6 +27,7 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { summary: { model: 'gpt-4-turbo', maxTokens: 256, temp: 0.5, prompt: 'Summarize the text given in simpler terms.' }, edit: { model: 'gpt-4-turbo', maxTokens: 256, temp: 0.5, prompt: 'Reword the text.' }, flashcard: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'Make flashcards out of this text with each question and answer labeled. Do not label each flashcard and do not include asterisks: ' }, + completion: { model: 'gpt-4-turbo', maxTokens: 256, temp: 0.5, prompt: "You are a helpful assistant. Answer the user's prompt." }, mermaid: { model: 'gpt-4-turbo', @@ -54,6 +56,13 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { temp: 0, prompt: 'List unique differences between the content of the UserAnswer and Rubric. Before each difference, label it and provide any additional information the UserAnswer missed and explain it in second person without separating it into UserAnswer and Rubric content and additional information. If there are no differences, say correct', }, + + rubric: { + model: 'gpt-4-turbo', + maxTokens: 1024, + temp: 0, + prompt: "Provide a definition for the vollowing term. It will be used as a rubric to evaluate the user's understanding of the topic", + }, }; let lastCall = ''; diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index e8e9b4fb6..612629f89 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -493,6 +493,8 @@ export class DocumentOptions { // cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) cardSort_isDesc?: BOOLt = new BoolInfo('whether the cards are sorted ascending or descending'); // test?: STRt = new StrInfo('testing for filtering') + keywords?: MAPt = new MapInfo('keywords', true); + } export const DocOptions = new DocumentOptions(); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 380d16686..67f8dafc4 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -39,7 +39,7 @@ import { ColorScheme } from "./SettingsManager"; import { SnappingManager } from "./SnappingManager"; import { UndoManager } from "./UndoManager"; -interface Button { +export interface Button { // DocumentOptions fields a button can set title?: string; toolTip?: string; @@ -714,7 +714,7 @@ pie title Minerals in my tap water // } static tagGroupTools(): Button[] { return [ - { title: "Star", icon: "star", toolTip:"Click to toggle the star group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, + { title: "Star", icon: StrCast(Doc.UserDoc().myFilterHotKeyIcons) ?? "Star", toolTip:"Click to toggle the star group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, { title: "Heart", icon: "heart", toolTip:"Click to toggle the heart group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"heart", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, { title: "Bolt", icon: "bolt", toolTip:"Click to toggle the bolt group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"bolt", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, { title: "Cloud", icon: "cloud", toolTip:"Click to toggle the cloud group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"cloud", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 3d6436cb5..c8df66535 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -309,7 +309,7 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( // this.subPin = ''; // })} onClick={e => { - name === 'keywords' ? targetDoc && (targetDoc[DocData].showLabels = !targetDoc[DocData].showLabels) : 'hi' + name === 'tags' ? targetDoc && (targetDoc[DocData].showIconTags = !targetDoc[DocData].showIconTags) : 'hi' }} @@ -332,7 +332,9 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( }}>
- {/* {pinBtn(true, false, 'window-maximize')} + { + metaBtn('tags', "tag") + /* {pinBtn(true, false, 'window-maximize')} {pinBtn(false, true, 'address-card')} {pinBtn(true, true, 'id-card')} */}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index dc40562e8..b5d819b97 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -832,7 +832,7 @@ export class DocumentDecorations extends ObservableReactComponent DocumentView.Selected()} /> diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index 5db627d23..332a89a96 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -19,6 +19,16 @@ import './FilterPanel.scss'; import { DocumentView } from './nodes/DocumentView'; import { Handle, Tick, TooltipRail, Track } from './nodes/SliderBox-components'; import { ObservableReactComponent } from './ObservableReactComponent'; +import { Button } from '../util/CurrentUserUtils'; +import { ButtonType } from './nodes/FontIconBox/FontIconBox'; +import { DocCast } from '../../fields/Types'; +// import { Docs } from '../../documents/Documents'; +import { Docs } from '../documents/Documents'; +import { CurrentUserUtils } from '../util/CurrentUserUtils'; +import { DocumentOptions } from '../documents/Documents'; +import { DocUtils } from '../documents/DocUtils'; +import { dropActionType } from '../util/DropActionTypes'; + interface filterProps { Document: Doc; @@ -217,6 +227,83 @@ export class FilterPanel extends ObservableReactComponent { return nonNumbers / facetValues.length > 0.1 ? facetValues.sort() : facetValues.sort((n1: string, n2: string) => Number(n1) - Number(n2)); }; + addHotkey() { + + const buttons = DocCast(Doc.UserDoc().myContextMenuBtns); + const filter = buttons['Filter'] + const filter2 = DocCast(filter) + const but2 = Doc.UserDoc().myContextMenuBtns + + // const newCol = Docs.Create.CarouselDocument(DocListCast(doc[Doc.LayoutFieldKey(doc)]), { + // _width: 250, + // _height: 200, + // _layout_fitWidth: false, + // _layout_autoHeight: true, + // }); + + // CurrentUserUtils.setupContextMenuButtons() + + // const hm = Docs.Create.FontIconDocument() + + // DocumentView.getDocumentView(filter2)?.ComponentView?.addDocument?.(hm) + + // console.log(DocumentView.getDocumentView(filter2) + "hiiiii") + + // DocumentView.getDocumentView(DocCast(buttons['Card']))?.ComponentView?.addDocument?.(hm) + + const hi = CurrentUserUtils.contextMenuTools() + + const newKey: Button = { title: "Cloud", icon: "cloud", toolTip:"Click to toggle the cloud group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"cloud", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}} + + + const heyy = [...hi, newKey] + + Doc.UserDoc().myFilterHotKeyIcons = "palette" + Doc.UserDoc().myFilterHotKeyTitles = "hi" + + CurrentUserUtils.setupContextMenuButtons(Doc.UserDoc()); + + + + Doc.UserDoc().hi = Docs.Create.FontIconDocument( + { title: '', + icon: 'map-pin', + + backgroundColor: '#ACCEF7', + layout_hideAllLinks: true, + _width: 15, + _height: 15, + _xPadding: 0, + } + ) + + + // buttons['Filter'] + + + + + const reqdCtxtOpts:DocumentOptions = { title: "hi", undoIgnoreFields:new List(['width', "linearView_IsOpen"]), flexGap: 0, childDragAction: dropActionType.embed, childDontRegisterViews: true, linearView_IsOpen: true, ignoreClick: true, linearView_Expandable: false, _height: 35 }; + const ctxtMenuBtns = CurrentUserUtils.setupContextMenuBtn(newKey, buttons); + // DocUtils.AssignOpts(buttons, reqdCtxtOpts, ctxtMenuBtns); + + + DocUtils.AssignOpts(DocCast(buttons['Filter']), reqdCtxtOpts, [ctxtMenuBtns]); + + + // newCol && dv.ComponentView?.addDocument?.(newCol); + + // console.log(but2 + "omgg") + + + + // doc.cardSort_activeIcons = new List(list.includes(icon) ? list.filter(d => d !== icon) : [...list, icon]); + + + + // Doc.UserDoc().myContextMenuBtns = new List([...buttons, newKey as Doc]) + } + render() { return (
@@ -283,6 +370,14 @@ export class FilterPanel extends ObservableReactComponent { ) )}
+
+
+
+ +
+
+ +
); } diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 40d0358d2..55e6217ff 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -30,6 +30,7 @@ import { DocumentView, DocumentViewProps } from './nodes/DocumentView'; import { FieldViewProps } from './nodes/FieldView'; import { StyleProp } from './StyleProp'; import './StyleProvider.scss'; +import { IconTagBox } from './nodes/IconTagBox'; function toggleLockedPosition(doc: Doc) { UndoManager.RunInBatch(() => Doc.toggleLockedPosition(doc), 'toggleBackground'); @@ -377,6 +378,11 @@ export function DefaultStyleProvider(doc: Opt, props: Opt) } } + + const iconTags = () => { + if (doc && doc![DocData].showIconTags) + {return ()} + } return ( <> {paint()} @@ -384,6 +390,7 @@ export function DefaultStyleProvider(doc: Opt, props: Opt ); } diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss index eb1b456f5..5869f89e1 100644 --- a/src/client/views/collections/CollectionCardDeckView.scss +++ b/src/client/views/collections/CollectionCardDeckView.scss @@ -22,32 +22,32 @@ transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); } -.card-button-container { - display: flex; - padding: 3px; - // width: 300px; - // height:100px; - pointer-events: none; /* This ensures the container does not capture hover events */ - - background-color: rgb(218, 218, 218); /* Background color of the container */ - border-radius: 50px; /* Rounds the corners of the container */ - transform: translateY(25px); - // box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* Optional: Adds shadow for depth */ - align-items: center; /* Centers buttons vertically */ - justify-content: start; /* Centers buttons horizontally */ - - button { - pointer-events: auto; /* Re-enable pointer events for the buttons */ +// .card-button-container { +// display: flex; +// padding: 3px; +// // width: 300px; +// // height:100px; +// pointer-events: none; /* This ensures the container does not capture hover events */ + +// background-color: rgb(218, 218, 218); /* Background color of the container */ +// border-radius: 50px; /* Rounds the corners of the container */ +// transform: translateY(25px); +// // box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* Optional: Adds shadow for depth */ +// align-items: center; /* Centers buttons vertically */ +// justify-content: start; /* Centers buttons horizontally */ + +// button { +// pointer-events: auto; /* Re-enable pointer events for the buttons */ - width: 70px; - height: 70px; - border-radius: 50%; - background-color: $dark-gray; - // border-color: $medium-blue; - margin: 5px; // transform: translateY(-50px); - background-color: transparent; - } -} +// width: 70px; +// height: 70px; +// border-radius: 50%; +// background-color: $dark-gray; +// // border-color: $medium-blue; +// margin: 5px; // transform: translateY(-50px); +// background-color: transparent; +// } +// } .no-card-span{ position: relative; diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index 410ddc355..736cc2354 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -446,6 +446,7 @@ export class CollectionCardView extends CollectionSubView() { }; const docTextPromises = this.childDocsWithoutLinks.map(async doc => { const docText = (await docToText(doc)) ?? ''; + doc['gptInputText'] = docText this._textToDoc.set(docText.replace(/\n/g, ' ').trim(), doc); return `======${docText.replace(/\n/g, ' ').trim()}======`; }); diff --git a/src/client/views/nodes/IconTagBox.scss b/src/client/views/nodes/IconTagBox.scss new file mode 100644 index 000000000..8c0f92c90 --- /dev/null +++ b/src/client/views/nodes/IconTagBox.scss @@ -0,0 +1,30 @@ +@import '../global/globalCssVariables.module.scss'; + +.card-button-container { + display: flex; + padding: 3px; + position: absolute; + // width: 300px; + // height:100px; + pointer-events: none; /* This ensures the container does not capture hover events */ + + background-color: rgb(218, 218, 218); /* Background color of the container */ + border-radius: 50px; /* Rounds the corners of the container */ + transform: translateY(25px); + // box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* Optional: Adds shadow for depth */ + align-items: center; /* Centers buttons vertically */ + justify-content: start; /* Centers buttons horizontally */ + + button { + pointer-events: auto; /* Re-enable pointer events for the buttons */ + transform: translateY(-7.5px); + + width: 30px; + height: 30px; + border-radius: 50%; + background-color: $dark-gray; + // border-color: $medium-blue; + margin: 5px; // transform: translateY(-50px); + background-color: transparent; + } +} \ No newline at end of file diff --git a/src/client/views/nodes/IconTagBox.tsx b/src/client/views/nodes/IconTagBox.tsx new file mode 100644 index 000000000..9a2273c3a --- /dev/null +++ b/src/client/views/nodes/IconTagBox.tsx @@ -0,0 +1,168 @@ +import React from "react"; +import { observer } from "mobx-react"; +import { computed } from "mobx"; + +import { ObservableReactComponent } from "../ObservableReactComponent"; +import { NumCast } from "../../../fields/Types"; +import { makeObservable } from "mobx"; +import { Doc } from "../../../fields/Doc"; +import { Reaction } from "mobx"; +import { reaction } from "mobx"; +import { numberRange } from "../../../Utils"; +import { Tooltip } from "@mui/material"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { undoable } from "../../util/UndoManager"; +import { BoolCast } from "../../../fields/Types"; +import { DocCast } from "../../../fields/Types"; +import './IconTagBox.scss'; +import { AclAdmin, AclAugment, AclEdit, DocData } from '../../../fields/DocSymbols'; + + +export interface IconTagProps { + doc: Doc; + + +} + +@observer +export class IconTagBox extends ObservableReactComponent { + private ref: React.RefObject; + private height: number = 0; + + + @computed + get currentScale() { + return NumCast((this._props.doc.embedContainer as Doc)?._freeform_scale, 1); + } + + constructor(props: any) { + super(props); + makeObservable(this); + this.ref = React.createRef(); + } + + componentDidMount(): void { + this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; + this._props.doc._keywordHeight = this.height; + + reaction( + () => this.currentScale, + () => { + if (this.currentScale < 1) { + this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; + this._props.doc._keywordHeight = this.height; + } + } + ); + } + + componentDidUpdate(prevProps: Readonly): void { + this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; + this._props.doc._keywordHeight = this.height; + } + + /** + * Renders the buttons to customize sorting depending on which group the card belongs to and the amount of total groups + * @param doc + * @param cardSort + * @returns + */ + renderButtons = (doc: Doc): JSX.Element | null => { + // if (cardSort !== cardSortings.Custom) return null; + + const amButtons = 4 + + // const amButtons = Math.max( + // 4, + // this.childDocs?.reduce((set, d) => { + // if (this.cardSort_customField) { + // set.add(NumCast(d[this.cardSort_customField])); + // } + // return set; + // }, new Set()).size ?? 0 + // ); + + // const activeButtonIndex = CollectionCardView.getButtonGroup(this.cardSort_customField, doc); + + const totalWidth = amButtons * 35 + amButtons * 2 * 5 + 6; + + const iconMap: { [key: number]: any } = { + 0: 'star', + 1: 'heart', + 2: 'cloud', + 3: 'bolt' + }; + + return ( +
+ {numberRange(amButtons).map(i => ( + Click to add/remove this card from the {iconMap[i]} group
}> + + + ))} + + ); + }; + + /** + * Toggles the buttons between on and off when creating custom sort groupings/changing those created by gpt + * @param childPairIndex + * @param buttonID + * @param doc + */ + toggleButton = undoable((doc: Doc, icon: string) => { + + + + // this.cardSort_customField && (doc[this.cardSort_customField] = buttonID); + + // doc.cardSort_activeIcons = new List() + + + // const list = StrListCast(doc.cardSort_activeIcons); + // doc.cardSort_activeIcons = new List(list.includes(icon) ? list.filter(d => d !== icon) : [...list, icon]); + + BoolCast(doc[icon]) ? doc[icon] = false : doc[icon] = true + + + + // StrListCast(doc.cardSort_activeIcons).push(iconMap[buttonID]) + }, 'toggle card tag'); + + + getButtonIcon = (doc: Doc, icon: any): JSX.Element => { + + // const isActive = StrListCast(doc.cardSort_activeIcons).includes(icon) + const isActive = doc[icon] + + // console.log(StrListCast(doc.cardSort_activeIcons)) + const color = isActive ? '#4476f7' : '#323232'; + + return ; + }; + + render (){ + return ( + <> + {this.renderButtons(this._props.doc)} + + + ) + + } + + + +} + + diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.scss b/src/client/views/pdf/GPTPopup/GPTPopup.scss index 57973ef34..eaa3eaebf 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.scss +++ b/src/client/views/pdf/GPTPopup/GPTPopup.scss @@ -66,8 +66,9 @@ $highlightedText: #82e0ff; .content-wrapper { padding-top: 10px; min-height: 50px; - max-height: 150px; + // max-height: 150px; overflow-y: auto; + height: 100% } .btns-wrapper-gpt { diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index bbd5ea630..a41c33a4d 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -19,7 +19,9 @@ import { AnchorMenu } from '../AnchorMenu'; import './GPTPopup.scss'; import { SettingsManager } from '../../../util/SettingsManager'; import { SnappingManager } from '../../../util/SnappingManager'; - +import { DocumentView } from '../../nodes/DocumentView'; +import { DocCast } from '../../../../fields/Types'; +import { RTFCast } from '../../../../fields/Types'; export enum GPTPopupMode { SUMMARY, @@ -177,6 +179,59 @@ export class GPTPopup extends ObservableReactComponent { this.quizAnswer = e.target.value; }); + generateQuiz = async () => { + this.setLoading(true); + this.setSortDone(false); + + + const selected = DocumentView.SelectedDocs().lastElement(); + + const questionText = 'Question: ' + StrCast(selected['gptInputText']); + + if (StrCast(selected['gptRubric']) === '') { + const rubricText = 'Rubric: ' + await this.generateRubric(StrCast(selected['gptInputText']), selected) + } + + const rubricText = 'Rubric: ' + (StrCast(selected['gptRubric'])) + // const rubricText = 'Rubric: ' + StrCast(RTFCast(DocCast(this.dataDoc[this.fieldKey + '_0']).text)?.Text); + const queryText = questionText + ' UserAnswer: ' + this.quizAnswer + '. ' + 'Rubric' + rubricText; + + try { + const res = await gptAPICall(queryText, GPTCallType.QUIZ); + if (!res) { + console.error('GPT call failed'); + return; + } + console.log(res) + this.setQuizResp(res) + + this.setLoading(false); + this.setSortDone(true); + + // this._outputValue = res; + } catch (err) { + console.error('GPT call failed'); + } + + + } + + generateRubric = async (inputText: string, doc:Doc) => { + try { + const res = await gptAPICall(inputText, GPTCallType.RUBRIC); + console.log(res + "rubbbb") + // if (!res) { + // console.error('GPT call failed'); + // return; + // } + doc['gptRubric']= res; + return res + } catch (err) { + console.error('GPT call failed'); + } + + } + @observable private regenerateCallback: (() => Promise) | null = null; @@ -192,6 +247,14 @@ export class GPTPopup extends ObservableReactComponent { public createFilteredDoc: (axes?: any) => boolean = () => false; public addToCollection: ((doc: Doc | Doc[], annotationKey?: string | undefined) => boolean) | undefined; + @observable quizRespText: string = '' + + @action setQuizResp (resp: string) { + this.quizRespText = resp + + } + + /** * Sorts cards in the CollectionCardDeckView */ @@ -403,7 +466,8 @@ export class GPTPopup extends ObservableReactComponent { ) cardActual = (opt: GPTPopupMode) => { - if (opt === GPTPopupMode.SORT) { + const isSort = opt === GPTPopupMode.SORT + // if (opt === GPTPopupMode.SORT) { return ( !this.sortDone ? ( <> @@ -412,24 +476,24 @@ export class GPTPopup extends ObservableReactComponent { className="searchBox-input" defaultValue="" autoComplete="off" - onChange={this.sortPromptChanged} + onChange={isSort ? this.sortPromptChanged : this.quizAnswerChanged} onKeyDown={e => { if (e.key === 'Enter') { - this.generateSort(); + isSort ? this.generateSort() : this.generateQuiz(); } e.stopPropagation(); }} type="text" - placeholder="How do you want to sort your cards?" + placeholder={`${isSort ? 'How do you want to sort your cards?' : 'What is the selected card?'}`} id="search-input" style={{ width: '100%' }} /> {/*
*/}
- - ); - } + // } else if (opt === GPTPopupMode.QUIZ) { + // return ( + // <> + //
+ // { + // if (e.key === 'Enter') { + // this.generateQuiz(); + // } + // e.stopPropagation(); + // }} + // type="text" + // placeholder="What is the selected card?" + // id="search-input" + // style={{ width: '100%' }} + // /> + // {/*
+ //
*/} + //
+ // + // ); + // } }; sortBox = () => (
- {this.heading('SORTING')} + {this.heading(this.mode === GPTPopupMode.SORT ? 'SORTING' : 'QUIZ')} <> {!this.cardsDoneLoading || this.loading ? (
@@ -673,7 +737,7 @@ export class GPTPopup extends ObservableReactComponent { tooltip="back" icon={} onClick={() => this.mode = GPTPopupMode.CARD} - style = {{right: '-55px'}} + style = {{right: '-20%'}} /> )} Date: Wed, 4 Sep 2024 09:03:13 -0400 Subject: updated filter panel to allow filtering by tags --- src/client/documents/Documents.ts | 1 + src/client/views/FilterPanel.tsx | 26 +++++++++++--------------- 2 files changed, 12 insertions(+), 15 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index af181b031..1acc6bb46 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -450,6 +450,7 @@ export class DocumentOptions { onDragStart?: ScriptField; // script to execute at start of drag operation -- e.g., when a "creator" button is dragged this script generates a different document to drop target?: Doc; // available for use in scripts. used to provide a document parameter to the script (Note, this is a convenience entry since any field could be used for parameterizing a script) tags?: LISTt = new ListInfo('hashtags added to document, typically using a text view', true); + tags_chat?: LISTt = new ListInfo('hashtags added to document by chatGPT', true); treeView_HideTitle?: BOOLt = new BoolInfo('whether to hide the top document title of a tree view'); treeView_HideUnrendered?: BOOLt = new BoolInfo("tells tree view not to display documents that have an 'layout_unrendered' tag unless they also have a treeView_FieldKey tag (presBox)"); treeView_HideHeaderIfTemplate?: BOOLt = new BoolInfo('whether to hide the header for a document in a tree view only if a childLayoutTemplate is provided (presBox)'); diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index b11fa3bd5..2f6d1fbaa 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -192,21 +192,17 @@ export class FilterPanel extends ObservableReactComponent { const allCollectionDocs = new Set(); SearchUtil.foreachRecursiveDoc(this.targetDocChildren, (depth: number, doc: Doc) => allCollectionDocs.add(doc)); const set = new Set([...StrListCast(this.Document.childFilters).map(filter => filter.split(Doc.FilterSep)[1]), Doc.FilterNone, Doc.FilterAny]); - if (facetHeader === 'tags') - allCollectionDocs.forEach(child => - StrListCast(child[facetHeader]) - .filter(h => h) - .forEach(key => set.add(key)) - ); - else - allCollectionDocs.forEach(child => { - const fieldVal = child[facetHeader] as FieldType; - if (!(fieldVal instanceof List)) { - // currently we have no good way of filtering based on a field that is a list - set.add(Field.toString(fieldVal)); - (fieldVal === true || fieldVal === false) && set.add((!fieldVal).toString()); - } - }); + + allCollectionDocs.forEach(child => { + const fieldVal = child[facetHeader] as FieldType; + const fieldStrList = StrListCast(child[facetHeader]).filter(h => h); + if (fieldStrList.length) fieldStrList.forEach(key => set.add(key)); + else if (!(fieldVal instanceof List)) { + // currently we have no good way of filtering based on a field that is a list + set.add(Field.toString(fieldVal)); + (fieldVal === true || fieldVal === false) && set.add((!fieldVal).toString()); + } + }); const facetValues = Array.from(set).filter(v => v); let nonNumbers = 0; -- cgit v1.2.3-70-g09d2 From a5ac17898151df59c748547acbcb0d2ac63d357d Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 4 Sep 2024 13:21:52 -0400 Subject: start of conversion of Calendar into a CollectionView --- src/client/documents/DocumentTypes.ts | 1 - src/client/documents/Documents.ts | 14 +++++++++----- src/client/util/CurrentUserUtils.ts | 2 +- src/client/views/DashboardView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 4 +++- src/client/views/nodes/calendarBox/CalendarBox.tsx | 16 +++------------- 6 files changed, 17 insertions(+), 22 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index b055546fc..56d505681 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -39,7 +39,6 @@ export enum DocumentType { COMPARISON = 'comparison', PUSHPIN = 'pushpin', MAPROUTE = 'maproute', - CALENDAR = 'calendar', SCRIPTDB = 'scriptdb', // database of scripts GROUPDB = 'groupdb', // database of groups diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1acc6bb46..d5a7b0465 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -913,7 +913,15 @@ export namespace Docs { } export function CalendarDocument(options: DocumentOptions, documents: Array) { - return InstanceFromProto(Prototypes.get(DocumentType.CALENDAR), new List(documents), { ...options }); + const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { + _layout_nativeDimEditable: true, + _layout_reflowHorizontal: true, + _layout_reflowVertical: true, + ...options, + _type_collection: CollectionViewType.Calendar, + }); + documents.forEach(d => Doc.SetContainer(d, inst)); + return inst; } // shouldn't ever need to create a KVP document-- instead set the LayoutTemplateString to be a KeyValueBox for the DocumentView (see addDocTab in TabDocView) @@ -970,10 +978,6 @@ export namespace Docs { return doc; } - export function CalendarCollectionDocument(documents: Array, options: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Calendar }); - } - export function StackingDocument(documents: Array, options: DocumentOptions, id?: string, protoId?: string) { return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Stacking }, id, undefined, protoId); } diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 14fb65252..f042f33ce 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -787,7 +787,7 @@ pie title Minerals in my tap water CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Multicolumn, CollectionViewType.Multirow, CollectionViewType.Time, CollectionViewType.Carousel, CollectionViewType.Carousel3D, CollectionViewType.Card, CollectionViewType.Linear, CollectionViewType.Map, - CollectionViewType.Grid, CollectionViewType.NoteTaking, ]), + CollectionViewType.Calendar, CollectionViewType.Grid, CollectionViewType.NoteTaking, ]), title: "Perspective", toolTip: "View", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: '{ return setView(value, _readOnly_); }'}}, { title: "Pin", icon: "map-pin", toolTip: "Pin View to Trail", btnType: ButtonType.ClickButton, expertMode: false, width: 30, scripts: { onClick: 'pinWithView(altKey)'}, funcs: {hidden: "IsNoneSelected()"}}, { title: "Header", icon: "heading", toolTip: "Doc Titlebar Color", btnType: ButtonType.ColorButton, expertMode: false, ignoreClick: true, scripts: { script: 'return setHeaderColor(value, _readOnly_)'} }, diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx index 33e905a54..eced64524 100644 --- a/src/client/views/DashboardView.tsx +++ b/src/client/views/DashboardView.tsx @@ -465,7 +465,7 @@ export class DashboardView extends ObservableReactComponent { isSystem: true, layout_explainer: 'All of the calendars that you have created will appear here.', }; - const myCalendars = DocUtils.AssignScripts(Docs.Create.CalendarCollectionDocument([], reqdOpts)); + const myCalendars = DocUtils.AssignScripts(Docs.Create.StackingDocument([], reqdOpts)); // { treeView_ChildDoubleClick: 'openPresentation(documentView.rootDoc)' } return new PrefetchProxy(myCalendars); } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index ab93abab6..c9e934448 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -34,6 +34,7 @@ import { CollectionLinearView } from './collectionLinear'; import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { CollectionSchemaView } from './collectionSchema/CollectionSchemaView'; +import { CalendarBox } from '../nodes/calendarBox/CalendarBox'; @observer export class CollectionView extends ViewBoxAnnotatableComponent() { @@ -91,7 +92,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent; - case CollectionViewType.Calendar: return ; + case CollectionViewType.Calendar: return ; case CollectionViewType.Docking: return ; case CollectionViewType.Tree: return ; case CollectionViewType.Multicolumn: return ; @@ -126,6 +127,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent func(CollectionViewType.Masonry), icon: 'columns' }, { description: 'Carousel', event: () => func(CollectionViewType.Carousel), icon: 'columns' }, { description: '3D Carousel', event: () => func(CollectionViewType.Carousel3D), icon: 'columns' }, + { description: 'Calendar', event: () => func(CollectionViewType.Calendar), icon: 'columns' }, { description: 'Pivot/Time', event: () => func(CollectionViewType.Time), icon: 'columns' }, { description: 'Map', event: () => func(CollectionViewType.Map), icon: 'globe-americas' }, { description: 'Grid', event: () => func(CollectionViewType.Grid), icon: 'th-list' }, diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx index ca35d85b3..20650d648 100644 --- a/src/client/views/nodes/calendarBox/CalendarBox.tsx +++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx @@ -12,21 +12,18 @@ import { Docs } from '../../../documents/Documents'; import { ViewBoxBaseComponent } from '../../DocComponent'; import { FieldView, FieldViewProps } from '../FieldView'; import './CalendarBox.scss'; +import { CollectionSubView, SubCollectionViewProps } from '../../collections/CollectionSubView'; type CalendarView = 'month' | 'multi-month' | 'week'; @observer -export class CalendarBox extends ViewBoxBaseComponent() { - public static LayoutString(fieldKey: string = 'calendar') { - return FieldView.LayoutString(CalendarBox, fieldKey); - } - +export class CalendarBox extends CollectionSubView() { _calendarRef: HTMLDivElement | null = null; _calendar: Calendar | undefined; _oldWheel: HTMLElement | null = null; _observer: ResizeObserver | undefined; - constructor(props: FieldViewProps) { + constructor(props: SubCollectionViewProps) { super(props); makeObservable(this); } @@ -78,9 +75,6 @@ export class CalendarBox extends ViewBoxBaseComponent() { if (Math.abs(startDate.getDay() - endDate.getDay()) > 7) return 'month'; return 'week'; } - @computed get childDocs() { - return DocListCast(this.dataDoc[this.fieldKey]); - } eventToColor(event: Doc): string { // TODO: Return a different color based on the event type @@ -149,7 +143,3 @@ export class CalendarBox extends ViewBoxBaseComponent() { ); } } -Docs.Prototypes.TemplateMap.set(DocumentType.CALENDAR, { - layout: { view: CalendarBox, dataField: 'data' }, - options: { acl: '', _layout_nativeDimEditable: true, _layout_reflowHorizontal: true, _layout_reflowVertical: true }, -}); -- cgit v1.2.3-70-g09d2 From b9f15c10e4cfa1288e176cbd1d312c628c5998ad Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 10 Sep 2024 14:54:44 -0400 Subject: moved TagsView up into DocumentView so that one row of tags will be visible. fixed setting pixel size of images to resize annotations so they don't appear to change. added vert/horiz centering for stacking views. fixed pres box to not have scroll bars. fixed resizing properties panel. --- src/client/documents/Documents.ts | 3 ++- src/client/util/CurrentUserUtils.ts | 12 ++++++----- src/client/views/MainView.tsx | 8 +++++--- src/client/views/SidebarAnnos.tsx | 1 + src/client/views/StyleProvider.tsx | 2 +- src/client/views/TagsView.tsx | 7 +++++-- .../views/collections/CollectionCalendarView.tsx | 1 + .../views/collections/CollectionStackingView.scss | 7 ++----- .../views/collections/CollectionStackingView.tsx | 13 +++++++++--- .../CollectionStackingViewFieldColumn.tsx | 24 ++++++++++------------ src/client/views/collections/TreeView.tsx | 2 +- .../collectionFreeForm/FaceCollectionBox.tsx | 1 + src/client/views/global/globalScripts.ts | 14 ++++++++----- src/client/views/nodes/DocumentView.scss | 2 +- src/client/views/nodes/FieldView.tsx | 1 + src/client/views/nodes/ImageBox.tsx | 14 +++++++++++-- 16 files changed, 70 insertions(+), 42 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index d5a7b0465..fbdf361dd 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -260,6 +260,7 @@ export class DocumentOptions { _layout_noSidebar?: BOOLt = new BoolInfo('whether to display the sidebar toggle button'); layout_boxShadow?: string; // box-shadow css string OR "standard" to use dash standard box shadow layout_maxShown?: NUMt = new NumInfo('maximum number of children to display at one time (see multicolumnview)'); + _layout_dontCenter?: STRt = new StrInfo("whether collections will center their content - values of 'x', 'xy', or 'y'"); _layout_autoHeight?: BOOLt = new BoolInfo('whether document automatically resizes vertically to display contents'); _layout_autoHeightMargins?: NUMt = new NumInfo('Margin heights to be added to the computed auto height of a Doc'); _layout_curPage?: NUMt = new NumInfo('current page of a PDF or other? paginated document', false); @@ -979,7 +980,7 @@ export namespace Docs { } export function StackingDocument(documents: Array, options: DocumentOptions, id?: string, protoId?: string) { - return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Stacking }, id, undefined, protoId); + return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _layout_dontCenter: 'y', ...options, _type_collection: CollectionViewType.Stacking }, id, undefined, protoId); } export function NoteTakingDocument(documents: Array, options: DocumentOptions, id?: string, protoId?: string) { diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index f042f33ce..2014c48e1 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -368,7 +368,7 @@ pie title Minerals in my tap water {key: "Chat", creator: Docs.Create.ChatDocument, opts: { _width: 300, _height: 300, }}, {key: "Header", creator: headerTemplate, opts: { _width: 300, _height: 120, _header_pointerEvents: "all", _header_height: 50, _header_fontSize: 9,_layout_autoHeightMargins: 50, _layout_autoHeight: true, treeView_HideUnrendered: true}}, {key: "ViewSlide", creator: slideView, opts: { _width: 400, _height: 300, _xMargin: 3, _yMargin: 3,}}, - {key: "Trail", creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 30, _type_collection: CollectionViewType.Stacking, dropAction: dropActionType.embed, treeView_HideTitle: true, _layout_fitWidth:true, layout_boxShadow: "0 0" }}, + {key: "Trail", creator: Docs.Create.PresDocument, opts: { _width: 400, _height: 30, _type_collection: CollectionViewType.Stacking, _layout_dontCenter:'xy', dropAction: dropActionType.embed, treeView_HideTitle: true, _layout_fitWidth:true, layout_boxShadow: "0 0" }}, {key: "Tab", creator: opts => Docs.Create.FreeformDocument([], opts), opts: { _width: 500, _height: 800, _layout_fitWidth: true, _freeform_backgroundGrid: true, }}, {key: "Slide", creator: opts => Docs.Create.TreeDocument([], opts), opts: { _width: 300, _height: 200, _type_collection: CollectionViewType.Tree, treeView_HasOverlay: true, _text_fontSize: "20px", _layout_autoHeight: true, @@ -477,6 +477,7 @@ pie title Minerals in my tap water const reqdStackOpts:DocumentOptions ={ title: "menuItemPanel", childDragAction: dropActionType.same, layout_boxShadow: "rgba(0,0,0,0)", dontRegisterView: true, ignoreClick: true, + _layout_dontCenter: 'y', _chromeHidden: true, _gridGap: 0, _yMargin: 0, _xMargin: 0, _layout_autoHeight: false, _width: 60, _columnWidth: 60, _lockedPosition: true, isSystem: true, }; return DocUtils.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(items??[], opts), reqdStackOpts, menuBtns, { dropConverter: "convertToButtons(dragData)" }); @@ -510,7 +511,7 @@ pie title Minerals in my tap water // doc.myUserBtns = new PrefetchProxy(userBtns); const reqdToolOps:DocumentOptions = { title: "My Tools", isSystem: true, ignoreClick: true, layout_boxShadow: "0 0", - layout_explainer: "This is a palette of documents that can be created.", + layout_explainer: "This is a palette of documents that can be created.", _layout_dontCenter: "y", _layout_showTitle: "title", _width: 500, _yMargin: 20, _lockedPosition: true, _forceActive: true, _dragOnlyWithinContainer: true, layout_hideContextMenu: true, _chromeHidden: true, }; return DocUtils.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(items??[], opts), reqdToolOps, [creatorBtns, userBtns]); @@ -663,7 +664,8 @@ pie title Minerals in my tap water } static stackTools(): Button[] { return [ - { title: "Center", icon: "align-center", toolTip: "Center Align Stack", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"center", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform + { title: "V. Align", icon: "pallet", toolTip: "Center Align Stack", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"vcenter", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform + { title: "Center", icon: "align-center", toolTip: "Center Align Stack", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"hcenter", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform ] } static cardTools(): Button[] { @@ -777,8 +779,8 @@ pie title Minerals in my tap water } static imageTools() { return [ - { title: "Pixels",toolTip: "Set Native Pixel Sizze", btnType: ButtonType.ClickButton, icon: "portrait", scripts: { onClick: 'imageSetPixelSize();' }}, - { title: "Rotate",toolTip: "Rotate 90", btnType: ButtonType.ClickButton, icon: "redo-alt", scripts: { onClick: 'imageRotate90();' }}, + { title: "Pixels",toolTip: "Set Native Pixel Size", btnType: ButtonType.ClickButton, icon: "portrait", scripts: { onClick: 'imageSetPixelSize();' }}, + { title: "Rotate",toolTip: "Rotate 90", btnType: ButtonType.ClickButton, icon: "redo-alt", scripts: { onClick: 'imageRotate90();' }}, ]; } static contextMenuTools():Button[] { diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 9f1c7da3d..393abea53 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -3,7 +3,7 @@ import { faBuffer, faHireAHelper } from '@fortawesome/free-brands-svg-icons'; import * as far from '@fortawesome/free-regular-svg-icons'; import * as fa from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { action, computed, configure, makeObservable, observable, reaction, runInAction } from 'mobx'; +import { action, computed, configure, makeObservable, observable, reaction, runInAction, trace } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import ResizeObserver from 'resize-observer-polyfill'; @@ -707,8 +707,8 @@ export class MainView extends ObservableReactComponent { setupMoveUpEvents( this, e, - action(() => { - SnappingManager.SetPropertiesWidth(Math.max(0, this._dashUIWidth - e.clientX)); + action(moveEv => { + SnappingManager.SetPropertiesWidth(Math.max(0, this._dashUIWidth - moveEv.clientX)); return !SnappingManager.PropertiesWidth; }), action(() => { @@ -807,6 +807,7 @@ export class MainView extends ObservableReactComponent { childFilters={returnEmptyFilter} childFiltersByRanges={returnEmptyFilter} searchFilterDocs={returnEmptyDoclist} + dontCenter="y" /> ); @@ -832,6 +833,7 @@ export class MainView extends ObservableReactComponent { }; @computed get mainInnerContent() { + trace(); const leftMenuFlyoutWidth = this._leftMenuFlyoutWidth + this.leftMenuWidth(); const width = this.propertiesWidth() + leftMenuFlyoutWidth; return ( diff --git a/src/client/views/SidebarAnnos.tsx b/src/client/views/SidebarAnnos.tsx index 8f0a35df0..dd60bfa65 100644 --- a/src/client/views/SidebarAnnos.tsx +++ b/src/client/views/SidebarAnnos.tsx @@ -246,6 +246,7 @@ export class SidebarAnnos extends ObservableReactComponent, props: Opt ); }; - const tags = () => props?.DocumentView?.() && CollectionFreeFormDocumentView.from(props.DocumentView()) ? : null; + const tags = () => props?.DocumentView?.() ? : null; return ( <> {paint()} diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index 65e70e8fc..8047363d9 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -91,7 +91,7 @@ export class TagItem extends ObservableReactComponent { const tagCollection = TagItem.findTagCollectionDoc(tag) ?? TagItem.createTagCollectionDoc(tag); // If the document is of type COLLECTION, make it a smart collection, otherwise, add the tag to the document. - if (doc.type === DocumentType.COL) { + if (doc.type === DocumentType.COL && !doc.annotationOn) { Doc.AddDocToList(tagCollection[DocData], 'collections', doc); // Iterate through the tag Doc collections and add a copy of the document to each collection @@ -257,6 +257,7 @@ export class TagsView extends ObservableReactComponent { super(props); makeObservable(this); } + InsetDist = 25; // how far tag panel is moved up to overlap DocumentView. @observable _panelHeightDirty = 0; @observable _currentInput = ''; @@ -328,7 +329,7 @@ export class TagsView extends ObservableReactComponent { return !this._props.View.Document.showTags ? null : (
r && new ResizeObserver(action(() => (this._props.View.TagPanelHeight = r?.getBoundingClientRect().height ?? 0))).observe(r)} + ref={r => r && new ResizeObserver(action(() => (this._props.View.TagPanelHeight = Math.max(0, (r?.getBoundingClientRect().height ?? 0) - this.InsetDist)))).observe(r)} style={{ transformOrigin: 'top left', maxWidth: `${100 * this.currentScale}%`, @@ -336,6 +337,8 @@ export class TagsView extends ObservableReactComponent { transform: `scale(${1 / this.currentScale})`, backgroundColor: this.isEditing ? Colors.LIGHT_GRAY : Colors.TRANSPARENT, borderColor: this.isEditing ? Colors.BLACK : Colors.TRANSPARENT, + position: 'relative', + top: `calc(-${this.InsetDist} * ${1 / this.currentScale}px)`, }}>
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx index 30fd9fc2b..0ea9f8ebc 100644 --- a/src/client/views/collections/CollectionCalendarView.tsx +++ b/src/client/views/collections/CollectionCalendarView.tsx @@ -82,6 +82,7 @@ export class CollectionCalendarView extends CollectionSubView() { isAnnotationOverlay={false} // select={emptyFunction} What does this mean? isAnyChildContentActive={returnTrue} // ?? + dontCenter="y" // childDocumentsActive={} // whenChildContentsActiveChanged={} childHideDecorationTitle={false} diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 6225cc52a..6400a0a8e 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -54,11 +54,8 @@ } .collectionStackingViewFieldColumn { - height: max-content; - } - - .collectionStackingViewFieldColumnDragging { - height: 100%; + display: flex; + flex-direction: column; } .collectionSchemaView-previewDoc { diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 6402ef16c..2cfe9329a 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -146,7 +146,7 @@ export class CollectionStackingView extends CollectionSubView @@ -343,7 +343,7 @@ export class CollectionStackingView extends CollectionSubView Array.from(this.Sections); // what a section looks like if we're in stacking view sectionStacking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => { @@ -565,6 +571,7 @@ export class CollectionStackingView extends CollectionSubView ); }; diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 5ae08e535..aba6b51d4 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -41,6 +41,7 @@ interface CSVFieldColumnProps { columnWidth: number; numGroupColumns: number; gridGap: number; + dontCenter: 'x' | 'xy' | 'y'; type: 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | undefined; headings: () => object[]; // I think that stacking view actually has a single column and then supposedly you can add more columns? Unsure @@ -345,15 +346,6 @@ export class CollectionStackingViewFieldColumn extends ObservableReactComponent< - {/* {evContents === noValueHeader ? null : ( -
- - - -
- )} */}
{this._props.Document._columnsHideIfEmpty ? null : headingView} {this.collapsed ? null : ( -
+
headings.indexOf(i) === idx); return (
{ }; docTransform = () => this.refTransform(this._dref?.ContentDiv); getTransform = () => this.refTransform(this._tref.current); - embeddedPanelWidth = () => this._props.panelWidth() / (this.treeView._props.NativeDimScaling?.() || 1); + embeddedPanelWidth = () => this._props.panelWidth() / (this.treeView._props.NativeDimScaling?.() || 1) - 3 /* paddingRight for bullet */; embeddedPanelHeight = () => { const layoutDoc = (temp => temp && Doc.expandTemplateLayout(temp, this.Document))(this.treeView._props.childLayoutTemplate?.()) || this.layoutDoc; return Math.min( diff --git a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx index 717081666..f9f6c81ab 100644 --- a/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx +++ b/src/client/views/collections/collectionFreeForm/FaceCollectionBox.tsx @@ -264,6 +264,7 @@ export class FaceCollectionBox extends ViewBoxBaseComponent() { isContentActive={returnTrue} isAnyChildContentActive={returnTrue} childHideDecorations={true} + dontCenter="y" />
); diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 2c7920bdd..934ed6c3e 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -133,10 +133,10 @@ ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) { }); // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' | 'clusters' | 'viewAll' | 'fitOnce', checkResult?: boolean, persist?: boolean) { +ScriptingGlobals.add(function showFreeform(attr: 'hcenter' | 'vcenter' | 'grid' | 'snaplines' | 'clusters' | 'viewAll' | 'fitOnce', checkResult?: boolean, persist?: boolean) { const selected = DocumentView.SelectedDocs().lastElement(); // prettier-ignore - const map: Map<'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'like' | 'star' | 'idea' | 'chat' | '1' | '2' | '3' | '4', + const map: Map<'flashcards' | 'hcenter' | 'vcenter' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'like' | 'star' | 'idea' | 'chat' | '1' | '2' | '3' | '4', { waitForRender?: boolean; checkResult: (doc: Doc) => boolean; @@ -158,9 +158,13 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' else (dv.ComponentView as CollectionFreeFormView)?.fitContentOnce(); }, }], - ['center', { - checkResult: (doc:Doc) => BoolCast(doc?._stacking_alignCenter, false), - setDoc: (doc:Doc) => { doc._stacking_alignCenter = !doc._stacking_alignCenter; }, + ['vcenter', { + checkResult: (doc:Doc) => !StrCast(doc?._layout_dontCenter).includes('y'), + setDoc: (doc:Doc) => { doc._layout_dontCenter = StrCast(doc.layout_dontCenter).includes('y') ? StrCast(doc.layout_dontCenter).replace(/y/,"") : StrCast(doc.layout_dontCenter) + 'y'; }, + }], + ['hcenter', { + checkResult: (doc:Doc) => !StrCast(doc?._layout_dontCenter).includes('x'), + setDoc: (doc:Doc) => { doc._layout_dontCenter = StrCast(doc.layout_dontCenter).includes('x') ? StrCast(doc.layout_dontCenter).replace(/x/,"") : 'x'+ StrCast(doc.layout_dontCenter); }, }], ['clusters', { waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 23dada260..2873b4bba 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -242,7 +242,7 @@ .contentFittingDocumentView { position: relative; - display: flex; + display: block; width: 100%; height: 100%; transition: inherit; diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index dd71fd946..c269c7bcb 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -82,6 +82,7 @@ export interface FieldViewSharedProps { // eslint-disable-next-line no-use-before-define onKey?: (e: React.KeyboardEvent, fieldProps: FieldViewProps) => boolean | undefined; fitWidth?: (doc: Doc) => boolean | undefined; + dontCenter?: 'x' | 'y' | 'xy' | undefined; searchFilterDocs: () => Doc[]; showTitle?: () => string; whenChildContentsActiveChanged: (isActive: boolean) => void; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index d0a7fc6ac..be3525544 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -11,7 +11,7 @@ import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; import { ObjectField } from '../../../fields/ObjectField'; -import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types'; +import { Cast, ImageCast, NumCast, RTFCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; import { emptyFunction } from '../../../Utils'; @@ -188,8 +188,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { @undoBatch setNativeSize = action(() => { + const oldnativeWidth = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']); const nscale = NumCast(this._props.PanelWidth()) * NumCast(this.layoutDoc._freeform_scale, 1); - const nw = nscale / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']); + const nw = nscale / oldnativeWidth; this.dataDoc[this.fieldKey + '_nativeHeight'] = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']) * nw; this.dataDoc[this.fieldKey + '_nativeWidth'] = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']) * nw; this.dataDoc._freeform_panX = nw * NumCast(this.dataDoc._freeform_panX); @@ -198,6 +199,15 @@ export class ImageBox extends ViewBoxAnnotatableComponent() { this.dataDoc._freeform_panX_min = this.dataDoc._freeform_panX_min ? nw * NumCast(this.dataDoc._freeform_panX_min) : undefined; this.dataDoc._freeform_panY_max = this.dataDoc._freeform_panY_max ? nw * NumCast(this.dataDoc._freeform_panY_max) : undefined; this.dataDoc._freeform_panY_min = this.dataDoc._freeform_panY_min ? nw * NumCast(this.dataDoc._freeform_panY_min) : undefined; + const newnativeWidth = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']); + DocListCast(this.dataDoc[this.annotationKey]).forEach(doc => { + doc.x = (NumCast(doc.x) / oldnativeWidth) * newnativeWidth; + doc.y = (NumCast(doc.y) / oldnativeWidth) * newnativeWidth; + if (!RTFCast(doc[Doc.LayoutFieldKey(doc)])) { + doc.width = (NumCast(doc.width) / oldnativeWidth) * newnativeWidth; + doc.height = (NumCast(doc.height) / oldnativeWidth) * newnativeWidth; + } + }); }); @undoBatch rotate = action(() => { -- cgit v1.2.3-70-g09d2 From bb1f4c62071987cc59461a8ce53522fa7a9036cc Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 12 Sep 2024 14:42:10 -0400 Subject: changed closing of face rectangles to hide them. added Shift+click of tags button to show face rectangles. --- src/client/documents/Documents.ts | 1 + src/client/views/DocumentButtonBar.tsx | 14 +++++++++----- src/client/views/DocumentDecorations.tsx | 7 ++++--- src/client/views/TagsView.tsx | 6 +++--- .../views/collections/collectionFreeForm/ImageLabelBox.tsx | 4 ++-- src/client/views/nodes/formattedText/RichTextRules.ts | 2 +- src/client/views/search/FaceRecognitionHandler.tsx | 3 +++ 7 files changed, 23 insertions(+), 14 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index fbdf361dd..89356072a 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -273,6 +273,7 @@ export class DocumentOptions { _layout_showTitle?: string; // field name to display in header (:hover is an optional suffix) _layout_showSidebar?: BOOLt = new BoolInfo('whether an annotationsidebar should be displayed for text docuemnts'); _layout_showCaption?: string; // which field to display in the caption area. leave empty to have no caption + _layout_showTags?: BOOLt = new BoolInfo('whether to show the list of document tags at the bottom of a DocView'); _chromeHidden?: BOOLt = new BoolInfo('whether the editing chrome for a document is hidden'); hideClickBehaviors?: BOOLt = new BoolInfo('whether to hide click behaviors in context menu'); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 785e69f84..f14fd033b 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -9,7 +9,7 @@ import * as React from 'react'; import { FaEdit } from 'react-icons/fa'; import { returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; -import { Doc } from '../../fields/Doc'; +import { Doc, DocListCast } from '../../fields/Doc'; import { Cast, DocCast } from '../../fields/Types'; import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils'; import { CalendarManager } from '../util/CalendarManager'; @@ -270,12 +270,16 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
{ - const showing = DocumentView.Selected().some(dv => dv.dataDoc.showTags); + onClick={undoable(e => { + const showing = DocumentView.Selected().some(dv => dv.layoutDoc._layout_showTags); DocumentView.Selected().forEach(dv => { - dv.dataDoc.showTags = !showing; + dv.layoutDoc._layout_showTags = !showing; + if (e.shiftKey) + DocListCast(dv.Document[Doc.LayoutFieldKey(dv.Document) + '_annotations']).forEach(doc => { + if (doc.face) doc.hidden = showing; + }); }); - }}> + }, 'show Doc tags')}>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 118a5bd3d..907bb2614 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -232,7 +232,8 @@ export class DocumentDecorations extends ObservableReactComponent 1 ? 0 : `${doc[DocData].showTags ? 4 + seldocview.TagPanelHeight : 4}px`, + top: DocumentView.Selected().length > 1 ? 0 : `${doc._layout_showTags ? 4 + seldocview.TagPanelHeight : 4}px`, transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `, }}> DocumentView.Selected()} /> @@ -845,7 +846,7 @@ export class DocumentDecorations extends ObservableReactComponent {DocumentView.Selected().length > 1 ? : null} diff --git a/src/client/views/TagsView.tsx b/src/client/views/TagsView.tsx index ae9d42749..0b303f6f5 100644 --- a/src/client/views/TagsView.tsx +++ b/src/client/views/TagsView.tsx @@ -172,12 +172,12 @@ export class TagItem extends ObservableReactComponent { docData.data = new List(newEmbeddings); docData.title = this._props.tag; docData.tags = new List([this._props.tag]); - docData.showTags = true; docData.freeform_fitContentsToBox = true; doc._freeform_panX = doc._freeform_panY = 0; doc._width = 900; doc._height = 900; doc.layout_fitWidth = true; + doc._layout_showTags = true; return doc; })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true)); newEmbeddings.forEach(embed => Doc.SetContainer(embed, newCollection)); @@ -322,7 +322,7 @@ export class TagsView extends ObservableReactComponent { ); /** - * When 'showTags' is set on a Doc, this displays a wrapping panel of tagItemViews corresponding to all the tags set on the Doc). + * When 'layout_showTags' is set on a Doc, this displays a wrapping panel of tagItemViews corresponding to all the tags set on the Doc). * When the dropdown is clicked, this will toggle an extended UI that allows additional tags to be added/removed. */ render() { @@ -336,7 +336,7 @@ export class TagsView extends ObservableReactComponent { ); this._panelHeightDirty; - return !this.View.Document.showTags && this._props.Views.length === 1 ? null : ( + return !this.View.Document._layout_showTags && this._props.Views.length === 1 ? null : (
r && new ResizeObserver(action(() => this._props.Views.length === 1 && (this.View.TagPanelHeight = Math.max(0, (r?.getBoundingClientRect().height ?? 0) - this.InsetDist)))).observe(r)} diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx index e419e522c..033d1590d 100644 --- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx +++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx @@ -139,9 +139,9 @@ export class ImageLabelBox extends ViewBoxBaseComponent() { toggleDisplayInformation = () => { this._displayImageInformation = !this._displayImageInformation; if (this._displayImageInformation) { - this._selectedImages.forEach(doc => (doc[DocData].showTags = true)); + this._selectedImages.forEach(doc => (doc._layout_showTags = true)); } else { - this._selectedImages.forEach(doc => (doc[DocData].showTags = false)); + this._selectedImages.forEach(doc => (doc._layout_showTags = false)); } }; diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index e0d6c7c05..0ef67b4be 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -404,7 +404,7 @@ export class RichTextRules { if (!tags.includes(tag)) { tags.push(tag); this.Document[DocData].tags = new List(tags); - this.Document[DocData].showTags = true; + this.Document._layout_showTags = true; } const fieldView = state.schema.nodes.dashField.create({ fieldKey: '#' + tag }); return state.tr diff --git a/src/client/views/search/FaceRecognitionHandler.tsx b/src/client/views/search/FaceRecognitionHandler.tsx index 636a44984..c507e54b6 100644 --- a/src/client/views/search/FaceRecognitionHandler.tsx +++ b/src/client/views/search/FaceRecognitionHandler.tsx @@ -220,6 +220,7 @@ export class FaceRecognitionHandler { .then(imgDocFaceDescriptions => { // For each face detected, find a match. const annos = [] as Doc[]; const scale = NumCast(imgDoc.data_nativeWidth) / img.width; + const showTags= imgDocFaceDescriptions.length > 1; imgDocFaceDescriptions.forEach((fd, i) => { const faceDescriptor = new List(Array.from(fd.descriptor)); const matchedUniqueFace = this.findMatchingFaceDoc(fd.descriptor) ?? this.createUniqueFaceDoc(activeDashboard); @@ -233,12 +234,14 @@ export class FaceRecognitionHandler { y: fd.alignedRect.box.top * scale, _width: fd.alignedRect.box.width * scale, _height: fd.alignedRect.box.height * scale, + _layout_showTags: showTags }) FaceRecognitionHandler.UniqueFaceAddFaceImage(faceAnno, matchedUniqueFace); // add image/faceDescriptor to matched unique face annos.push(faceAnno); }); imgDoc[DocData].data_annotations = new List(annos); + imgDoc._layout_showTags = annos.length > 0; return imgDocFaceDescriptions; }) ); // prettier-ignore -- cgit v1.2.3-70-g09d2 From 313b3d3e67689b175cdc85426ff6af809d476622 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Tue, 17 Sep 2024 12:55:38 -0400 Subject: done with comments-- pull request --- eslint.config.mjs | 66 +----- package-lock.json | 176 +++++++++------ package.json | 12 +- src/client/apis/gpt/GPT.ts | 8 +- src/client/documents/Documents.ts | 2 - src/client/util/CurrentUserUtils.ts | 79 +------ src/client/util/Scripting.ts | 4 +- src/client/views/FilterPanel.scss | 12 -- src/client/views/FilterPanel.tsx | 145 +++++-------- src/client/views/PropertiesView.tsx | 2 +- src/client/views/StyleProvider.tsx | 6 + .../views/collections/CollectionCardDeckView.tsx | 41 ++-- src/client/views/global/globalScripts.ts | 240 ++------------------- src/client/views/nodes/IconTagBox.tsx | 141 ++---------- src/client/views/pdf/GPTPopup/GPTPopup.tsx | 5 +- src/typings/index.d.ts | 2 +- 16 files changed, 255 insertions(+), 686 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/eslint.config.mjs b/eslint.config.mjs index 619966f20..c69209327 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,57 +1,13 @@ -import pluginJs from '@eslint/js'; -import pluginReactConfig from 'eslint-plugin-react/configs/recommended.js'; -import globals from 'globals'; -import tseslint from 'typescript-eslint'; +import globals from "globals"; +import pluginJs from "@eslint/js"; +import tseslint from "typescript-eslint"; +import pluginReact from "eslint-plugin-react"; -export default [ - { - languageOptions: { globals: { ...globals.browser, ...globals.node } }, - }, - pluginJs.configs.recommended, - ...tseslint.configs.recommended, - { - rules: { - 'node/no-missing-import': 0, - 'no-console': 'off', - 'func-names': 'off', - 'no-process-exit': 'off', - 'object-shorthand': 'off', - 'class-methods-use-this': 'off', - 'single-quote': 'off', - 'max-classes-per-file': 0, - - 'react/jsx-filename-extension': [ - 2, - { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - }, - ], - 'import/prefer-default-export': 'off', - 'no-unused-expressions': 'off', - '@typescript-eslint/no-unused-expressions': 'off', - 'prefer-template': 'off', - 'no-inner-declarations': 'off', - 'no-plusplus': 'off', - 'no-multi-assign': 'off', - 'no-underscore-dangle': 'off', - 'no-nested-ternary': 'off', - 'lines-between-class-members': 'off', - 'no-shadow': 'off', - '@typescript-eslint/no-shadow': 'warn', - 'no-unused-vars': 'off', - '@typescript-eslint/no-unused-vars': 'error', - '@typescript-eslint/no-namespace': 'off', - 'react/destructuring-assignment': 0, - 'prefer-arrow-callback': 'error', - 'no-return-assign': 'error', - 'no-await-in-loop': 'error', - 'no-loop-func': 'error', - 'no-cond-assign': 'error', - 'no-use-before-define': 'error', - 'no-explicit-any': 'error', - 'no-restricted-globals': ['error', 'event'], - }, - }, - pluginReactConfig, -]; +export default [ + {files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"]}, + {languageOptions: { globals: globals.browser }}, + pluginJs.configs.recommended, + ...tseslint.configs.recommended, + pluginReact.configs.flat.recommended, +]; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1e738fcb1..3c9c5c81b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,7 +92,7 @@ "D": "^1.0.0", "d3": "^7.8.5", "depcheck": "^1.4.7", - "dotenv": "^16.3.1", + "dotenv": "^16.4.5", "eslint-webpack-plugin": "^4.1.0", "exif": "^0.6.0", "exifr": "^7.1.3", @@ -130,6 +130,7 @@ "image-data-uri": "^2.0.1", "image-size": "^1.0.2", "image-size-stream": "^1.1.0", + "install": "^0.13.0", "is-plain-obj": "^4.1.0", "jimp": "^0.22.10", "jpeg-autorotate": "^9.0.0", @@ -154,7 +155,7 @@ "node-stream-zip": "^1.15.0", "nodemailer": "^6.9.7", "nodemon": "^3.0.2", - "npm": "^10.2.5", + "npm": "^10.8.1", "openai": "^4.26.0", "p-limit": "^6.1.0", "passport": "^0.7.0", @@ -188,6 +189,7 @@ "react-compound-slider": "^3.4.0", "react-datepicker": "^7.3.0", "react-dom": "^18.2.0", + "react-draggable": "^4.4.6", "react-grid-layout": "^1.4.4", "react-icons": "^5.0.1", "react-jsx-parser": "^2.0.0", @@ -246,7 +248,7 @@ "xregexp": "^5.1.1" }, "devDependencies": { - "@eslint/js": "^9.1.1", + "@eslint/js": "^9.10.0", "@types/adm-zip": "^0.5.5", "@types/animejs": "^3.1.12", "@types/archiver": "^6.0.2", @@ -295,9 +297,9 @@ "@types/youtube": "^0.1.0", "chai": "^5.0.0", "cross-env": "^7.0.3", - "eslint": "^9.9.0", - "eslint-plugin-react": "^7.34.1", - "globals": "^15.1.0", + "eslint": "^9.10.0", + "eslint-plugin-react": "^7.36.1", + "globals": "^15.9.0", "jsdom": "^25.0.0", "mocha": "^10.2.0", "prettier": "^3.1.0", @@ -306,7 +308,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", - "typescript-eslint": "^8.2.0", + "typescript-eslint": "^8.6.0", "webpack-dev-server": "^5.0.4" }, "engines": { @@ -2675,9 +2677,10 @@ } }, "node_modules/@eslint/js": { - "version": "9.9.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.1.tgz", - "integrity": "sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==", + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", + "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -2690,6 +2693,17 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/plugin-kit": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz", + "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@ffmpeg/core": { "version": "0.12.6", "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.12.6.tgz", @@ -9993,16 +10007,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.3.0.tgz", - "integrity": "sha512-FLAIn63G5KH+adZosDYiutqkOkYEx0nvcwNNfJAf+c7Ae/H35qWwTYvPZUKFj5AS+WfHG/WJJfWnDnyNUlp8UA==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz", + "integrity": "sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.3.0", - "@typescript-eslint/type-utils": "8.3.0", - "@typescript-eslint/utils": "8.3.0", - "@typescript-eslint/visitor-keys": "8.3.0", + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/type-utils": "8.6.0", + "@typescript-eslint/utils": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -10026,15 +10041,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.3.0.tgz", - "integrity": "sha512-h53RhVyLu6AtpUzVCYLPhZGL5jzTD9fZL+SYf/+hYOx2bDkyQXztXSc4tbvKYHzfMXExMLiL9CWqJmVz6+78IQ==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.6.0.tgz", + "integrity": "sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.3.0", - "@typescript-eslint/types": "8.3.0", - "@typescript-eslint/typescript-estree": "8.3.0", - "@typescript-eslint/visitor-keys": "8.3.0", + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/typescript-estree": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", "debug": "^4.3.4" }, "engines": { @@ -10054,13 +10070,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.3.0.tgz", - "integrity": "sha512-mz2X8WcN2nVu5Hodku+IR8GgCOl4C0G/Z1ruaWN4dgec64kDBabuXyPAr+/RgJtumv8EEkqIzf3X2U5DUKB2eg==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz", + "integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.3.0", - "@typescript-eslint/visitor-keys": "8.3.0" + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10071,13 +10088,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.3.0.tgz", - "integrity": "sha512-wrV6qh//nLbfXZQoj32EXKmwHf4b7L+xXLrP3FZ0GOUU72gSvLjeWUl5J5Ue5IwRxIV1TfF73j/eaBapxx99Lg==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.6.0.tgz", + "integrity": "sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.3.0", - "@typescript-eslint/utils": "8.3.0", + "@typescript-eslint/typescript-estree": "8.6.0", + "@typescript-eslint/utils": "8.6.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -10095,10 +10113,11 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.3.0.tgz", - "integrity": "sha512-y6sSEeK+facMaAyixM36dQ5NVXTnKWunfD1Ft4xraYqxP0lC0POJmIaL/mw72CUMqjY9qfyVfXafMeaUj0noWw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz", + "integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -10108,13 +10127,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.3.0.tgz", - "integrity": "sha512-Mq7FTHl0R36EmWlCJWojIC1qn/ZWo2YiWYc1XVtasJ7FIgjo0MVv9rZWXEE7IK2CGrtwe1dVOxWwqXUdNgfRCA==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz", + "integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.3.0", - "@typescript-eslint/visitor-keys": "8.3.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -10140,6 +10160,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10155,6 +10176,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -10163,15 +10185,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.3.0.tgz", - "integrity": "sha512-F77WwqxIi/qGkIGOGXNBLV7nykwfjLsdauRB/DOFPdv6LTF3BHHkBpq81/b5iMPSF055oO2BiivDJV4ChvNtXA==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz", + "integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.3.0", - "@typescript-eslint/types": "8.3.0", - "@typescript-eslint/typescript-estree": "8.3.0" + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/typescript-estree": "8.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10185,12 +10208,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.3.0.tgz", - "integrity": "sha512-RmZwrTbQ9QveF15m/Cl28n0LXD6ea2CjkhH5rQ55ewz3H24w+AMCJHPVYaZ8/0HoG8Z3cLLFFycRXxeO2tz9FA==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz", + "integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.3.0", + "@typescript-eslint/types": "8.6.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -10206,6 +10230,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -17448,15 +17473,17 @@ } }, "node_modules/eslint": { - "version": "9.9.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.1.tgz", - "integrity": "sha512-dHvhrbfr4xFQ9/dq+jcVneZMyRYLjggWjk6RVsIiHsP8Rz6yZ8LvZ//iU4TrZF+SXWG+JkNF2OyiZRvzgRDqMg==", + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz", + "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==", + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", "@eslint/config-array": "^0.18.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.9.1", + "@eslint/js": "9.10.0", + "@eslint/plugin-kit": "^0.1.0", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", @@ -17479,7 +17506,6 @@ "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", @@ -17506,10 +17532,11 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.35.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", - "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", + "version": "7.36.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz", + "integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==", "dev": true, + "license": "MIT", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", @@ -18101,6 +18128,7 @@ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -18117,6 +18145,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -19305,6 +19334,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-15.9.0.tgz", "integrity": "sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -19458,7 +19488,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/grid-index": { "version": "1.1.0", @@ -20727,6 +20758,14 @@ "inspect-function": "^0.3.1" } }, + "node_modules/install": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/internal-slot": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", @@ -27554,6 +27593,7 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -37377,6 +37417,7 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -38075,14 +38116,15 @@ "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==" }, "node_modules/typescript-eslint": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.3.0.tgz", - "integrity": "sha512-EvWjwWLwwKDIJuBjk2I6UkV8KEQcwZ0VM10nR1rIunRDIP67QJTZAHBXTX0HW/oI1H10YESF8yWie8fRQxjvFA==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.6.0.tgz", + "integrity": "sha512-eEhhlxCEpCd4helh3AO1hk0UP2MvbRi9CtIAJTVPQjuSXOOO2jsEacNi4UdcJzZJbeuVg1gMhtZ8UYb+NFYPrA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.3.0", - "@typescript-eslint/parser": "8.3.0", - "@typescript-eslint/utils": "8.3.0" + "@typescript-eslint/eslint-plugin": "8.6.0", + "@typescript-eslint/parser": "8.6.0", + "@typescript-eslint/utils": "8.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/package.json b/package.json index cb4633c6d..f92a533a9 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "tsc": "tsc -t es5" }, "devDependencies": { - "@eslint/js": "^9.1.1", + "@eslint/js": "^9.10.0", "@types/adm-zip": "^0.5.5", "@types/animejs": "^3.1.12", "@types/archiver": "^6.0.2", @@ -72,9 +72,9 @@ "@types/youtube": "^0.1.0", "chai": "^5.0.0", "cross-env": "^7.0.3", - "eslint": "^9.9.0", - "eslint-plugin-react": "^7.34.1", - "globals": "^15.1.0", + "eslint": "^9.10.0", + "eslint-plugin-react": "^7.36.1", + "globals": "^15.9.0", "jsdom": "^25.0.0", "mocha": "^10.2.0", "prettier": "^3.1.0", @@ -83,7 +83,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", - "typescript-eslint": "^8.2.0", + "typescript-eslint": "^8.6.0", "webpack-dev-server": "^5.0.4" }, "dependencies": { @@ -132,7 +132,6 @@ "@types/web": "^0.0.157", "@types/webpack-hot-middleware": "^2.25.9", "@webscopeio/react-textarea-autocomplete": "^4.9.2", - "D": "^1.0.0", "adm-zip": "^0.5.10", "archiver": "^7.0.1", "async": "^3.2.5", @@ -169,6 +168,7 @@ "csv-parser": "^3.0.0", "csv-stringify": "^6.4.4", "csvtojson": "^2.0.10", + "D": "^1.0.0", "d3": "^7.8.5", "depcheck": "^1.4.7", "dotenv": "^16.4.5", diff --git a/src/client/apis/gpt/GPT.ts b/src/client/apis/gpt/GPT.ts index 0b1a5160c..2657bf12e 100644 --- a/src/client/apis/gpt/GPT.ts +++ b/src/client/apis/gpt/GPT.ts @@ -49,7 +49,6 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { maxTokens: 2048, temp: 0.25, prompt: "The user is going to give you a list of descriptions. Each one is separated by `======` on either side. Descriptions will vary in length, so make sure to only separate when you see `======`. Sort them by the user's specifications. Make sure each description is only in the list once. Each item should be separated by `======`. Immediately afterward, surrounded by `------` on BOTH SIDES, provide some insight into your reasoning for the way you sorted (and mention nothing about the formatting details given in this description). It is VERY important that you format it exactly as described, ensuring the proper number of `=` and `-` (6 of each) and NO commas" - // prompt: "I'm going to give you a list of descriptions. Each one is separated by `======` on either side. Descriptions will vary in length, so make sure to only separate when you see `======`. Sort them into lists by shared content. Make sure each description is in only one list. Each list should be separated by `======` with the elements within it separated by `~~~~~~`. Immediately afterward, surrounded by `------` on BOTH SIDES, provide some insight into your reasoning for the way you sorted. It is VERY important that you format it exactly as described, ensuring the proper number of `=` `~` and `-` (6 of each) and no commas.Try to create around 4 groups, but a little more or less is ok. Also, I may provide some more insight after this colon:" }, describe: { model: 'gpt-4-vision-preview', maxTokens: 2048, temp: 0, prompt: 'Describe these images in 3-5 words' }, chatcard: { model: 'gpt-4-turbo', maxTokens: 512, temp: 0.5, prompt: 'Answer the following question as a short flashcard response. Do not include a label.' }, @@ -64,7 +63,7 @@ const callTypeMap: { [type: string]: GPTCallOpts } = { model: 'gpt-4-turbo', maxTokens: 1024, temp: 0, - prompt: "BRIEFLY (<75 words) provide a definition for the following term. It will be used as a rubric to evaluate the user's understanding of the topic", + prompt: "BRIEFLY (<25 words) provide a definition for the following term. It will be used as a rubric to evaluate the user's understanding of the topic", }, type: { @@ -106,11 +105,6 @@ const gptAPICall = async (inputTextIn: string, callType: GPTCallType, prompt?: a try { lastCall = inputText; - // const configuration: ClientOptions = { - // apiKey: process.env.OPENAI_KEY, - // dangerouslyAllowBrowser: true, - // }; - const usePrompt = prompt ? prompt + opts.prompt : opts.prompt; const messages: ChatCompletionMessageParam[] = [ { role: 'system', content: usePrompt }, diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 188f07991..83e236cba 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -493,8 +493,6 @@ export class DocumentOptions { // cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) cardSort_isDesc?: BOOLt = new BoolInfo('whether the cards are sorted ascending or descending'); // test?: STRt = new StrInfo('testing for filtering') - keywords?: MAPt = new MapInfo('keywords', true); - } export const DocOptions = new DocumentOptions(); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 702d6e6e5..997d5c5a9 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -669,15 +669,10 @@ pie title Minerals in my tap water } static cardTools(): Button[] { return [ - // { btnList: new List(["Time", "Type", "Color", "Chat GPT", "Custom 1", "Custom 2", "Custom 3" ]), - // title: "Sort Type", toolTip: "Card Sort Type", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: '{ return setCardSort(value, _readOnly_); }'}}, - // { title: "Font", toolTip: "Font", width: 100, btnType: ButtonType.DropdownList, toolType:"font", ignoreClick: true, scripts: {script: '{ return setFontAttr(this.toolType, value, _readOnly_);}'}, - // btnList: new List(["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]) }, { title: "Time", icon:"hourglass-half", toolTip:"Sort by most recent document creation", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"time", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Type", icon:"eye", toolTip:"Sort by document type", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"docType",funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Color", icon:"palette", toolTip:"Sort by document color", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"color", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Tags", icon:"bolt", toolTip:"Sort by document's tags", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"tag", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "AI Sort", icon:"robot", toolTip:"Have Chat GPT sort your cards for you !", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"chat", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Pile", icon:"layer-group", toolTip:"View the cards as a pile in the free form view !", btnType: ButtonType.ClickButton, expertMode: false, toolType:"pile", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Chat Popup", icon:"lightbulb", toolTip:"Toggle the chat popup's visibility!", width: 45 ,btnType: ButtonType.ToggleButton, expertMode: false, toolType:"toggle-chat", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'} }, @@ -686,62 +681,23 @@ pie title Minerals in my tap water { title: "Ascending", toolTip: "Sort the cards in ascending order", btnType: ButtonType.ToggleButton, icon: "sort-up", toolType:"up", ignoreClick: true, scripts: {onClick: '{ return showFreeform(this.toolType, _readOnly_);}' }}, { title: "Descending", toolTip: "Sort the cards in descending order",btnType: ButtonType.ToggleButton, icon: "sort-down",toolType:"down",ignoreClick: true, scripts: {onClick: '{ return showFreeform(this.toolType, _readOnly_);}'} }, ]}, - - // { title: "Filter", icon:"Filter", toolTip:"Filter cards by tags", width: 150, subMenu: this.cardGroupTools(), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - - - - - - - // // { title: "AIs", icon:"Visibility", toolTip:"Filter AI labels", subMenu: this.cardGroupTools("robot"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("chat", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // // { title: "Custom", icon:"heart", toolTip:"Add Like labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"like", funcs: {hidden:`showFreeform ("like", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "1st", icon:"Visibility", toolTip:"Filter likes", width: 150, subMenu: this.cardGroupTools("heart"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("like", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // // { title: "Custom", icon:"star", toolTip:"Add Star labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {hidden:`showFreeform ("star", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "2nd", icon:"Visibility", toolTip:"Filter stars", width: 150, subMenu: this.cardGroupTools("star"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("star", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // // { title: "Custom", icon:"cloud", toolTip:"Add Idea labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"idea", funcs: {hidden:`showFreeform ("idea", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "3rd", icon:"Visibility", toolTip:"Filter ideas", width: 150, subMenu: this.cardGroupTools("cloud"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("idea", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, ] } - // static labelTools(): Button[] { - // return [ - // // { title: "Smart", icon:"robot", toolTip:"Have ChatGPT Label and sort your cards for you!", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"chat", funcs: {hidden:`showFreeform ("chat", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "AIs", icon:"AI Sort", toolTip:"Filter AI labels", subMenu: this.cardGroupTools("robot"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("chat", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // // { title: "Custom", icon:"heart", toolTip:"Add Like labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"like", funcs: {hidden:`showFreeform ("like", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "1st", icon:"1st", toolTip:"Filter likes", width: 10, subMenu: this.cardGroupTools("heart"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("like", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // // { title: "Custom", icon:"star", toolTip:"Add Star labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {hidden:`showFreeform ("star", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "2nd", icon:"2nd", toolTip:"Filter stars", width: 80, subMenu: this.cardGroupTools("star"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("star", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // // { title: "Custom", icon:"cloud", toolTip:"Add Idea labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"idea", funcs: {hidden:`showFreeform ("idea", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "3rd", icon:"3rd", toolTip:"Filter ideas", width: 80, subMenu: this.cardGroupTools("cloud"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("idea", true)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // ] - // } + static tagGroupTools(): Button[] { - if (!Doc.UserDoc().activeDashboard){ - Doc.UserDoc().myFilterHotKeyTitles = new List(['Star', 'Heart', 'Bolt', 'Cloud' ]) - - Doc.UserDoc()['Star'] = 'star' - Doc.UserDoc()['Heart'] = 'heart' - Doc.UserDoc()['Bolt'] = 'bolt' - Doc.UserDoc()['Cloud'] = 'cloud' + if (!Doc.UserDoc().activeDashboard) { + Doc.UserDoc().myFilterHotKeyTitles = new List(['Star', 'Heart', 'Bolt', 'Cloud']); - } - - + ['Star', 'Heart', 'Bolt', 'Cloud'].forEach(key => { + Doc.UserDoc()[key] = key.toLowerCase(); + }); +} // hack: if there's no dashboard, create default filters. otherwise, just make sure that the Options button is preserved return (Doc.UserDoc().activeDashboard ? [] : [ { title: "Star", isSystem: false, icon: "star", toolTip:"Click to toggle the star group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, { title: "Heart", isSystem: false,icon: "heart", toolTip:"Click to toggle the heart group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"heart", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, { title: "Bolt", isSystem: false,icon: "bolt", toolTip:"Click to toggle the bolt group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"bolt", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, { title: "Cloud", isSystem: false,icon: "cloud", toolTip:"Click to toggle the cloud group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"cloud", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, - - - // { title: "Group 1", icon, toolTip:"Click to toggle group 1's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"1", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Group 2", icon, toolTip:"Click to toggle group 2's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"2", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Group 3", icon, toolTip:"Click to toggle group 3's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"3", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Group 4", icon, toolTip:"Click to toggle group 4's visibility", btnType: ButtonType.ToggleButton, width: 40, expertMode: false, toolType:"4", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "", icon, toolTip:"Click to toggle group 5's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"5", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "", icon, toolTip:"Click to toggle group 6's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"6", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "", icon, toolTip:"Click to toggle group 7's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"7", funcs: {hidden:`!cardHasLabel(this.toolType)`}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, ]).concat([ { title: "Options", isSystem: true,icon: "gear", toolTip:"Click to customize your filter panel", btnType: ButtonType.ClickButton, expertMode: false, toolType:"opts", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}} ]) @@ -856,19 +812,6 @@ pie title Minerals in my tap water { title: "View", icon: "View", toolTip: "View tools", subMenu: CurrentUserUtils.viewTools(), expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available { title: "Stack", icon: "View", toolTip: "Stacking tools", subMenu: CurrentUserUtils.stackTools(), expertMode: false, toolType:CollectionViewType.Stacking, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available - - // { title: "SortType", btnList: new List(["Time", "Type", "Color", "ChatGPT", "Custom 1", "Custom 2", "Custom 3" ]), - // toolTip: "Card Sort Type", btnType: ButtonType.DropdownList, ignoreClick: true, width: 100, scripts: { script: '{ return showFreeform(value, _readOnly_); }' }, - // // funcs: {hidden: `!SelectedDocType("card", this.expertMode)`} - // }, - // { title: "Visibility", icon:"Visibility", toolTip:"Filter AI labels", subMenu: this.cardGroupTools("robot"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("chat", true)`, width: 100, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // // { title: "Custom", icon:"heart", toolTip:"Add Like labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"like", funcs: {hidden:`showFreeform ("like", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Visibility", icon:"Visibility", toolTip:"Filter likes", width: 10, subMenu: this.cardGroupTools("heart"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("like", true)`, width: 100, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // // { title: "Custom", icon:"star", toolTip:"Add Star labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {hidden:`showFreeform ("star", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Visibility", icon:"Visibility", toolTip:"Filter stars", width: 80, subMenu: this.cardGroupTools("star"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("star", true)`, width: 100, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - // // { title: "Custom", icon:"cloud", toolTip:"Add Idea labels", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"idea", funcs: {hidden:`showFreeform ("idea", true)`},scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Visibility", icon:"Visibility", toolTip:"Filter ideas", width: 80, subMenu: this.cardGroupTools("cloud"), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden:`!showFreeform("idea", true)`,width: 100, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, - { title: "Card", icon: "Card", toolTip: "Card View Tools", subMenu: CurrentUserUtils.cardTools(), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available // { title: "Create", icon: "Create", toolTip: "Assign card labels", subMenu: CurrentUserUtils.labelTools(), expertMode: false, toolType:CollectionViewType.Card, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Always available { title: "Web", icon: "Web", toolTip: "Web functions", subMenu: CurrentUserUtils.webTools(), expertMode: false, toolType:DocumentType.WEB, funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when Web is selected @@ -877,13 +820,7 @@ pie title Minerals in my tap water { title: "Schema", icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(),expertMode: false,toolType:CollectionViewType.Schema,funcs: {hidden: `!SelectedDocType(this.toolType, this.expertMode)`, linearView_IsOpen: `SelectedDocType(this.toolType, this.expertMode)`} }, // Only when Schema is selected { title: "Filter", icon:"=", toolTip:"Filter cards by tags", btnType: ButtonType.MultiToggleButton, width: 150, ignoreClick: true,toolType:DocumentType.COL, subMenu: this.tagGroupTools(), funcs: {hidden: '!SelectedDocType(this.toolType, this.expertMode)'}, - // [ - // { title: "Star", icon: "star", toolTip:"Click to toggle the star group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"star", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Heart", icon: "heart", toolTip:"Click to toggle the heart group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"heart", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Bolt", icon: "bolt", toolTip:"Click to toggle the bolt group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"bolt", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - // { title: "Cloud", icon: "cloud", toolTip:"Click to toggle the cloud group's visibility", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"cloud", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - - // ] + }, ]; diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts index c63d3d7cb..cb314e3f1 100644 --- a/src/client/util/Scripting.ts +++ b/src/client/util/Scripting.ts @@ -1,7 +1,7 @@ // export const ts = (window as any).ts; // import * as typescriptlib from '!!raw-loader!../../../node_modules/typescript/lib/lib.d.ts' // import * as typescriptes5 from '!!raw-loader!../../../node_modules/typescript/lib/lib.es5.d.ts' -import typescriptlib from 'type_decls.d'; +// import typescriptlib from 'type_decls.d'; import * as ts from 'typescript'; import { Doc, FieldType } from '../../fields/Doc'; import { RefField } from '../../fields/RefField'; @@ -248,7 +248,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp const funcScript = `(function(${paramString})${reqTypes} { ${body} })`; host.writeFile('file.ts', funcScript); - if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); + // if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib); const program = ts.createProgram(['file.ts'], {}, host); const testResult = program.emit(); const outputText = host.readFile('file.js'); diff --git a/src/client/views/FilterPanel.scss b/src/client/views/FilterPanel.scss index 34c3d2fc1..fbdebde0d 100644 --- a/src/client/views/FilterPanel.scss +++ b/src/client/views/FilterPanel.scss @@ -350,19 +350,7 @@ } -.drawing-box{ - position: absolute; - z-index: 10000; - border-color: black; - border-style: solid; - border-width: medium; - border-radius: 10%; - background-color: #323232; - - - -} // .sliderBox-outerDiv { // width: 30%;// width: calc(100% - 14px); // 14px accounts for handles that are at the max value of the slider that would extend outside the box // height: 40; // height: 100%; diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx index e15285007..e73d9c2c9 100644 --- a/src/client/views/FilterPanel.tsx +++ b/src/client/views/FilterPanel.tsx @@ -11,7 +11,7 @@ import { List } from '../../fields/List'; import { RichTextField } from '../../fields/RichTextField'; import { SearchUtil } from '../util/SearchUtil'; import { SnappingManager } from '../util/SnappingManager'; -import { undoable } from '../util/UndoManager'; +import { undoable, undoBatch } from '../util/UndoManager'; import { FieldsDropdown } from './FieldsDropdown'; import './FilterPanel.scss'; import { DocumentView } from './nodes/DocumentView'; @@ -20,26 +20,14 @@ import { ObservableReactComponent } from './ObservableReactComponent'; import { Button } from '../util/CurrentUserUtils'; import { ButtonType } from './nodes/FontIconBox/FontIconBox'; import { DocCast } from '../../fields/Types'; -// import { Docs } from '../../documents/Documents'; -import { Docs } from '../documents/Documents'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; -import { DocumentOptions } from '../documents/Documents'; -import { DocUtils } from '../documents/DocUtils'; -import { dropActionType } from '../util/DropActionTypes'; -import { Toggle } from 'browndash-components'; -import { SettingsManager } from '../util/SettingsManager'; import { StrCast } from '../../fields/Types'; -import { ToggleType } from 'browndash-components'; -import { MultiToggle } from 'browndash-components'; -import { Type } from 'browndash-components'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { DocData } from '../../fields/DocSymbols'; -import { DocumentType } from '../documents/DocumentTypes'; import { Tooltip } from '@mui/material'; import { useLocalObservable } from 'mobx-react'; import { useRef } from 'react'; import { useEffect } from 'react'; -import { useState } from 'react'; interface filterProps { @@ -242,12 +230,14 @@ export class FilterPanel extends ObservableReactComponent { return nonNumbers / facetValues.length > 0.1 ? facetValues.sort() : facetValues.sort((n1: string, n2: string) => Number(n1) - Number(n2)); }; - addHotkey(hotKey: string) { + /** + * Allows users to add a filter hotkey to the properties panel. Will also update the multitoggle at the top menu and the + * icontags tht are displayed on the documents themselves + * @param hotKey tite of the new hotkey + */ + addHotkey = (hotKey: string) => { const buttons = DocCast(Doc.UserDoc().myContextMenuBtns); const filter = DocCast(buttons.Filter); - const filter2 = DocCast(filter); - const but2 = Doc.UserDoc().myContextMenuBtns; - const newKey: Button = { title: hotKey, @@ -260,15 +250,11 @@ export class FilterPanel extends ObservableReactComponent { scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}' }, }; - // const heyy = [...hi, newKey] - const currHotKeys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles) Doc.UserDoc().myFilterHotKeyTitles = new List(currHotKeys.concat(hotKey)) Doc.UserDoc()[hotKey] = 'bolt' - // Doc.UserDoc()['supppp'] = 'star' - const newBtn = CurrentUserUtils.setupContextMenuBtn(newKey, filter); newBtn.isSystem = newBtn[DocData].isSystem = undefined; @@ -276,32 +262,16 @@ export class FilterPanel extends ObservableReactComponent { const subDocs = DocListCast(filter.data) const opts = subDocs[subDocs.length-1] Doc.AddDocToList(filter, 'data', newBtn, opts, true); - - - - // console.log(filter[DocData].data + 'ok') - // // console.log(filter[DocData][0] + 'help') - // console.log(filter[DocData] + 'good grief') - - // console.log(DocCast(DocCast(filter.data))[0]) - // this.removeHotKey() - - // console.log(DocCast(filter.data) + 'HI') - // console.log(DocListCast(filter.data) + 'WOOOOO') - // console.log(DocCast(filter.data)[0] + 'hm :(') - } - - hotKeyButtons() { + /** + * Renders the newly formed hotkey icon buttons + * @returns the buttons to be rendered + */ + hotKeyButtons = () => { const selected = DocumentView.SelectedDocs().lastElement(); - - // console.log(StrListCast(Doc.UserDoc().myFilterHotKeyTitles) + "hiii") - const hotKeys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles); - - // hotKeys.forEach(l => console.log(l + "render")) // Selecting a button should make it so that the icon on the top filter panel becomes said icon const buttons = hotKeys.map((hotKey, i) => ( @@ -506,6 +476,10 @@ interface HotKeyButtonProps { selected?: Doc } +/** + * Renders the buttons that correspond to each icon tag in the properties view. Allows users to change the icon, + * title, and delete. + */ const HotKeyIconButton: React.FC = observer(({ hotKey, selected}) => { const state = useLocalObservable(() => ({ isActive: false, @@ -534,36 +508,34 @@ const HotKeyIconButton: React.FC = observer(({ hotKey, select const handleClick = () => { state.toggleActive(); - // console.log(state.isActive + "hmmm") }; const hotKeys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles) + const buttons = DocCast(Doc.UserDoc().myContextMenuBtns); + const filter = DocCast(buttons.Filter); + /** + * The doc of the button in the context menu that corresponds to the current hotkey + * @returns + */ const myHotKeyDoc = () => { - const buttons = DocCast(Doc.UserDoc().myContextMenuBtns); - const filter = DocCast(buttons.Filter); const hotKeyDocs = DocListCast(filter.data) return hotKeyDocs.filter(k => StrCast(k.title) === hotKey)[0] } + /** + * Removes a hotkey from list + */ const removeHotKey = () => { - const buttons = DocCast(Doc.UserDoc().myContextMenuBtns); - const filter = DocCast(buttons.Filter); - Doc.RemoveDocFromList(filter, 'data', myHotKeyDoc()); - - - - - // console.log((DocListCast(filter.data)[0].title) + "emmanuel") - - - // console.log(DocCast(filter.data) + 'HI') - // console.log(DocCast(filter.data)[0] + 'hm :(') - } + + /** + * Deselects if the user clicks outside the button + * @param event + */ const handleClickOutside = (event: MouseEvent) => { if (panelRef.current && !panelRef.current.contains(event.target as Node)) { state.deactivate(); @@ -571,23 +543,22 @@ const HotKeyIconButton: React.FC = observer(({ hotKey, select state.stopEditing(); updateFromInput() - - - - // Doc.UserDoc().myFilterHotKeyTitles = new List(hotKeys.map(k => k === hotKey ? state.myHotKey : k)); - // Doc.UserDoc()[state.myHotKey] = StrCast(Doc.UserDoc()[hotKey]) - } } }; - const updateFromInput = () => { - const hi = myHotKeyDoc() + /** + * Updates the list of hotkeys based on the users input. replaces the old title with the new one and then assigns this new + * hotkey with the current icon + */ + const updateFromInput = undoable (() => { + const myDoc = myHotKeyDoc() Doc.UserDoc().myFilterHotKeyTitles = new List(hotKeys.map(k => k === hotKey ? state.myHotKey : k)); Doc.UserDoc()[state.myHotKey] = StrCast(Doc.UserDoc()[hotKey]) - hi.title = state.myHotKey - hi.toolTip = `Click to toggle the ${state.myHotKey}'s group's visibility` - } + Doc.UserDoc()[hotKey] = '' + myDoc.title = state.myHotKey + myDoc.toolTip = `Click to toggle the ${state.myHotKey}'s group's visibility` + }, '') useEffect(() => { @@ -599,31 +570,25 @@ const HotKeyIconButton: React.FC = observer(({ hotKey, select const iconOpts = ['star', 'heart', 'bolt', 'satellite', 'palette', 'robot', 'lightbulb', 'highlighter', 'book', 'chalkboard' ]; + /** + * Panel of icons the user can choose from to represent their tag + */ const iconPanel = iconOpts.map((icon, i) => ( - )); - function isAttrFiltered(attr: string) { - if (selected && selected._childFilters !== undefined && selected.type === DocumentType.COL) { - return StrListCast(selected._childFilters).some(filter => filter.includes(attr)); - } else { - return false; - } - } - + /** + * Actually renders the buttons + */ return ( -
{ e.stopPropagation(); state.startEditing(); @@ -673,20 +638,12 @@ const HotKeyIconButton: React.FC = observer(({ hotKey, select )}
); -}) +}) \ No newline at end of file diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index daa8e1720..e940ba6f9 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -54,7 +54,7 @@ export class PropertiesView extends ObservableReactComponent Doc.toggleLockedPosition(doc), 'toggleBackground'); @@ -368,6 +369,11 @@ export function DefaultStyleProvider(doc: Opt, props: Opt props?.DocumentView?.() && CollectionFreeFormDocumentView.from(props.DocumentView()) ? : null; + const iconTags = () => { + if (doc && doc![DocData].showIconTags) + {return ()} + } + return ( <> {paint()} diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index 2390d162c..3d9f28a49 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -23,6 +23,8 @@ import { dropActionType } from '../../util/DropActionTypes'; import { DocCast } from '../../../fields/Types'; import { SelectionManager } from '../../util/SelectionManager'; + + enum cardSortings { Time = 'time', Type = 'type', @@ -32,6 +34,14 @@ enum cardSortings { Tag = 'tag', None = '', } + +/** + * New view type specifically for studying more dynamically. Allows you to reorder docs however you see fit, easily + * sort and filter using presets, and customize your experience with chat gpt. + * + * This file contains code as to how the docs are to be rendered (there place geographically and also in regards to sorting), + * and callback functions for the gpt popup + */ @observer export class CollectionCardView extends CollectionSubView() { private _dropDisposer?: DragManager.DragDropDisposer; @@ -40,10 +50,8 @@ export class CollectionCardView extends CollectionSubView() { private _textToDoc = new Map(); @observable _forceChildXf = false; - // @observable _isLoading = false; @observable _hoveredNodeIndex = -1; @observable _docRefs = new ObservableMap(); - _draggerRef = React.createRef(); @observable _maxRowCount = 10; @observable _docDraggedIndex: number = -1; @observable _isACardBeingDragged: boolean = false; @@ -99,12 +107,12 @@ export class CollectionCardView extends CollectionSubView() { // Reaction to cardSort changes this._disposers.sort = reaction( - () => this.cardSort, - cardSort => { - if (cardSort === cardSortings.Chat) { + () => GPTPopup.Instance.visible, + isVis => { + if (isVis) { this.openChatPopup(); } else { - GPTPopup.Instance.setVisible(false); + this.Document.cardSort = (this.cardSort === cardSortings.Chat) ? '' : this.Document.cardSort; } } ); @@ -296,7 +304,7 @@ export class CollectionCardView extends CollectionSubView() { * @param de drop event * @returns true if a card has been dropped, falls if not */ - onInternalDrop = (e: Event, de: DragManager.DropEvent) => { + onInternalDrop = undoable((e: Event, de: DragManager.DropEvent) => { if (de.complete.docDragData) { this._isACardBeingDragged = false; this._docDraggedIndex = -1; @@ -304,7 +312,7 @@ export class CollectionCardView extends CollectionSubView() { return true; } return false; - }; + }, '' ); get sortedDocs() { return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.Document.cardSort_isDesc), this._docDraggedIndex); @@ -511,8 +519,6 @@ export class CollectionCardView extends CollectionSubView() { image[DocData].description = response.trim(); return response; // Return the response from gptImageLabel } catch (error) { - console.log('bad things have happened'); - console.log(error); } return ''; @@ -523,18 +529,22 @@ export class CollectionCardView extends CollectionSubView() { * usable code * @param gptOutput */ - @action processGptOutput = (gptOutput: string, questionType: string, tag?: string) => { - console.log('HIIII'); - console.log(StrCast(this.Document.cardSort) + 'cardSort'); + @action + + processGptOutput = undoable((gptOutput: string, questionType: string, tag?: string) => { // Split the string into individual list items const listItems = gptOutput.split('======').filter(item => item.trim() !== ''); - if (questionType == '2' || questionType == '4') { + if (questionType === '2' || questionType === '4') { this.childDocs.forEach(d => { d['chatFilter'] = false; }); } + if (questionType ==='6'){ + this.Document.cardSort = 'chat' + } + listItems.forEach((item, index) => { const normalizedItem = item.trim(); @@ -545,7 +555,6 @@ export class CollectionCardView extends CollectionSubView() { switch (questionType) { case '6': doc.chatIndex = index; - console.log(index); break; case '1': const allHotKeys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles); @@ -578,7 +587,7 @@ export class CollectionCardView extends CollectionSubView() { console.warn(`No matching document found for item: ${normalizedItem}`); } }); - }; + }, ''); /** diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 8b9f128e0..9e56d313e 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -198,44 +198,6 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "tag", setDoc: (doc: Doc, dv: DocumentView) => doc.cardSort === "tag" ? doc.cardSort = '' : doc.cardSort = 'tag', }], - // ['heart', { - // checkResult: (doc: Doc) => isAttrFiltered('heart'), - // setDoc: (doc: Doc, dv: DocumentView) => { - // isAttrFiltered('heart') ? Doc.setDocFilter(doc, 'heart', true, 'remove') : Doc.setDocFilter(doc, 'heart', true, 'match'); - - // } - // }], - // ['star', { - // checkResult: (doc: Doc) => isAttrFiltered('star'), - - // setDoc: (doc: Doc, dv: DocumentView) => { - // isAttrFiltered('star') ? Doc.setDocFilter(doc, 'star', true, 'remove') : Doc.setDocFilter(doc, 'star', true, 'match'); - // } - // }], - // ['bolt', { - // checkResult: (doc: Doc) => isAttrFiltered('bolt'), - // setDoc: (doc: Doc, dv: DocumentView) => { - // isAttrFiltered('bolt') ? Doc.setDocFilter(doc, 'bolt', true, 'remove') : Doc.setDocFilter(doc, 'bolt', true, 'match'); - - // } - // }], - // ['cloud', { - // checkResult: (doc: Doc) => isAttrFiltered('cloud'), - // setDoc: (doc: Doc, dv: DocumentView) => { - // isAttrFiltered('cloud') ? Doc.setDocFilter(doc, 'cloud', true, 'remove') : Doc.setDocFilter(doc, 'cloud', true, 'match'); - - // } - // }], - // ['chat', { - // checkResult: (doc: Doc) => { - - // if (StrCast(doc?.cardSort) === "chat"){ - // return true - // }} , - // setDoc: (doc: Doc, dv: DocumentView) => { - // doc.cardSort === "chat" ? doc.cardSort = '' : doc.cardSort = 'chat'; - // }, - // }], ['up', { checkResult: (doc: Doc) => BoolCast(!doc?.cardSort_isDesc), setDoc: (doc: Doc, dv: DocumentView) => { @@ -251,10 +213,17 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' ['toggle-chat', { checkResult: (doc: Doc) => GPTPopup.Instance.visible, setDoc: (doc: Doc, dv: DocumentView) => { - GPTPopup.Instance.setVisible(!GPTPopup.Instance.visible); - GPTPopup.Instance.setMode(GPTPopupMode.SORT); - doc.cardSort === "chat" ? doc.cardSort = '' : doc.cardSort = 'chat'; + if (GPTPopup.Instance.visible){ + doc.cardSort = '' + GPTPopup.Instance.setVisible(false); + + } else { + GPTPopup.Instance.setVisible(true); + GPTPopup.Instance.setMode(GPTPopupMode.CARD); + GPTPopup.Instance.setCardsDoneLoading(true); + } + }, }], @@ -293,9 +262,6 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' if (checkResult) { return map.get(attr)?.checkResult(selected); } - const filters = StrListCast(selected._childFilters).concat(StrListCast(selected?._childFiltersByRanges).filter((filter, i) => !(i % 3))); - - // console.log(filters.some(filter => filter.includes('star'))+ "SUOOOOPPP") const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} }; DocumentView.Selected().map(dv => map.get(attr)?.setDoc(dv.layoutDoc, dv)); @@ -303,7 +269,9 @@ ScriptingGlobals.add(function showFreeform(attr: 'center' | 'grid' | 'snaplines' return undefined; }); - +/** + * Applies a filter to the selected document (or, if the settins button is pressed, opens the filter panel) + */ ScriptingGlobals.add(function handleTags(value?: any, checkResult?: boolean) { const selected = DocumentView.SelectedDocs().lastElement(); @@ -312,7 +280,7 @@ ScriptingGlobals.add(function handleTags(value?: any, checkResult?: boolean) { } if (checkResult) { - return value=== 'opts' ? PropertiesView.Instance.openFilters : isAttrFiltered(value) + return value=== 'opts' ? PropertiesView.Instance?.openFilters : isAttrFiltered(value) } if (value != 'opts'){ @@ -321,8 +289,7 @@ ScriptingGlobals.add(function handleTags(value?: any, checkResult?: boolean) { else { SnappingManager.PropertiesWidth < 5 && SnappingManager.SetPropertiesWidth(0); SnappingManager.SetPropertiesWidth(MainView.Instance.propertiesWidth() < 15 ? Math.min(MainView.Instance._dashUIWidth - 50, 250) : 0); - - PropertiesView.Instance.CloseAll() + PropertiesView.Instance?.CloseAll() PropertiesView.Instance.openFilters = true } @@ -330,183 +297,6 @@ ScriptingGlobals.add(function handleTags(value?: any, checkResult?: boolean) { return undefined; }, ''); - - -// ScriptingGlobals.add(function cardHasLabel(label: string) { -// const selected = DocumentView.SelectedDocs().lastElement(); -// const labelNum = Number(label) - 1; -// return labelNum < 4 || (selected && DocListCast(selected[Doc.LayoutFieldKey(selected)]).some(doc => doc[StrCast(selected.cardSort_customField)] == labelNum)); -// }, ''); - -// ScriptingGlobals.add(function setCardSort(attr: "Time" | "Type"| "Color"| "ChatGPT"| "Custom 1"| "Custom 2"| "Custom 3", value?: any, checkResult?: boolean) { -// // const editorView = RichTextMenu.Instance?.TextView?.EditorView; -// const selected = DocumentView.SelectedDocs().lastElement(); - -// // prettier-ignore -// const map: Map<"Time" | "Type"| "Color"| "ChatGPT"| "Custom 1"| "Custom 2"| "Custom 3", { checkResult: (doc: Doc) => any; setDoc: (doc: Doc) => void;}> = new Map([ -// ['Time', { - -// checkResult: (doc: Doc) => {StrCast(doc?.cardSort); -// console.log(StrCast(doc?.cardSort + "card sort"))}, -// setDoc: (doc: Doc) => {doc.cardSort = "time" -// console.log("hewwo")} - -// , -// }], -// ['Type', { -// checkResult: (doc: Doc) => StrCast(doc?.cardSort), -// setDoc: (doc: Doc) => doc.cardSort = "type", -// }], -// ['Color', { -// checkResult: (doc: Doc) => StrCast(doc?.cardSort), -// setDoc: (doc: Doc) => doc.cardSort = "color", -// }], -// // ['links', { -// // checkResult: (doc: Doc) => StrCast(doc?.cardSort) === "links", -// // setDoc: (doc: Doc) => doc.cardSort = "links", -// // }], -// ['Custom 1', { -// checkResult: (doc: Doc) => StrCast(doc?.cardSort) + " 1", -// setDoc: (doc: Doc) => { -// doc.cardSort = "custom"; -// doc.cardSort_customField = "like"; -// doc.cardSort_visibleSortGroups = new List(); -// } -// }], -// ['Custom 2', { -// checkResult: (doc: Doc) => StrCast(doc?.cardSort) + " 2", -// setDoc: (doc: Doc) => { -// doc.cardSort = "custom"; -// doc.cardSort_customField = "star"; -// doc.cardSort_visibleSortGroups = new List(); -// } -// }], -// ['Custom 3', { -// checkResult: (doc: Doc) => StrCast(doc?.cardSort) + " 3", -// setDoc: (doc: Doc) => { -// doc.cardSort = "custom"; -// doc.cardSort_customField = "idea"; -// doc.cardSort_visibleSortGroups = new List(); -// } -// }], -// ['ChatGPT', { -// checkResult: (doc: Doc) => StrCast(doc?.cardSort_customField), -// setDoc: (doc: Doc) => { -// doc.cardSort = "custom"; -// doc.cardSort_customField = "chat"; -// doc.cardSort_visibleSortGroups = new List(); -// }, -// }], -// ]); - -// for (let i = 0; i < 8; i++) { -// map.set((i + 1 + '') as any, { -// checkResult: (doc: Doc) => NumListCast(doc?.cardSort_visibleSortGroups).includes(i), -// setDoc: (doc: Doc) => { -// const list = NumListCast(doc.cardSort_visibleSortGroups); -// doc.cardSort_visibleSortGroups = new List(list.includes(i) ? list.filter(d => d !== i) : [...list, i]); -// }, -// }); -// } - -// if (checkResult) { -// console.log(attr + "attricute") -// console.log(map.get(attr)?.checkResult(selected) + "check result") -// return map.get(attr)?.checkResult(selected); -// } - -// console.log(attr + "attricute lol") - -// // const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} }; -// DocumentView.Selected().map(dv => map.get(attr)?.setDoc(dv.layoutDoc)); -// // setTimeout(() => batch.end(), 100); -// return undefined; - -// // map.get(attr)?.setDoc?.(); -// // return undefined; -// }); - -// ScriptingGlobals.add(function setCardSort(value?: any, checkResult?: boolean) { -// // const editorView = RichTextMenu.Instance?.TextView?.EditorView; -// const selected = DocumentView.SelectedDocs().lastElement(); -// if (checkResult) { -// // console.log(attr + "attricute") -// // console.log(map.get(attr)?.checkResult(selected) + "check result") -// console.log(StrCast(selected?.cardSort) + 'check'); -// const hi = StrCast(selected?.cardSort); -// return StrCast(selected?.cardSortForDropDown) ?? 'Time'; -// } -// function docFields(doc: Doc): void { -// switch (value) { -// case 'Custom 1': -// doc.cardSort_customField = 'like'; -// break; -// case 'Custom 2': -// doc.cardSort_customField = 'star'; -// break; -// case 'Custom 3': -// doc.cardSort_customField = 'idea'; -// break; -// case 'Chat GPT': -// doc.cardSort = 'custom'; -// doc.cardSort_customField = 'chat'; -// break; -// default: -// break; -// } - -// doc.cardSort_visibleSortGroups = new List(); -// } - -// // const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} }; -// DocumentView.Selected().map(dv => { -// dv.Document.cardSortForDropDown = value; - -// if (value != 'Chat GPT') { -// dv.Document.cardSort = value.trim().split(/\s+/)[0].toLowerCase(); -// } -// docFields(dv.Document); -// }); - -// return undefined; - -// // map.get(attr)?.setDoc?.(); -// // return undefined; -// }); - -// ScriptingGlobals.add(function setCardSortAttr(attr: 'time' | 'docType' | 'color', value: any, checkResult?: boolean) { -// // const editorView = RichTextMenu.Instance?.TextView?.EditorView; -// const selected = SelectionManager.Docs.lastElement(); -// // prettier-ignore -// const map: Map<'time' | 'docType' | 'color', { waitForRender?: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc, dv:DocumentView) => void;}> = new Map([ -// ['time', { -// checkResult: (doc:Doc) => StrCast(doc?.cardSort), -// setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "time", -// }], -// ['docType', { -// checkResult: (doc:Doc) => StrCast(doc?.cardSort), -// setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "type", -// }], -// ['color', { -// checkResult: (doc:Doc) => StrCast(doc?.cardSort), -// setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "color", -// }], -// // ['custom', { -// // checkResult: () => RichTextMenu.Instance.textAlign, -// // setDoc: () => value && editorView?.state ? RichTextMenu.Instance.align(editorView, editorView.dispatch, value):(Doc.UserDoc().textAlign = value), -// // }] -// // , -// ]); - -// if (checkResult) { -// return map.get(attr)?.checkResult(selected); -// } - -// console.log('hey') -// SelectionManager.Views.map(dv => map.get(attr)?.setDoc(dv.layoutDoc, dv)); -// console.log('success') -// }); - // eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highlight' | 'fontSize' | 'alignment', value: string | number, checkResult?: boolean) { const editorView = RichTextMenu.Instance?.TextView?.EditorView; diff --git a/src/client/views/nodes/IconTagBox.tsx b/src/client/views/nodes/IconTagBox.tsx index 8aa6bff2b..370ce51d1 100644 --- a/src/client/views/nodes/IconTagBox.tsx +++ b/src/client/views/nodes/IconTagBox.tsx @@ -1,13 +1,9 @@ import React from "react"; import { observer } from "mobx-react"; import { computed } from "mobx"; - import { ObservableReactComponent } from "../ObservableReactComponent"; import { NumCast } from "../../../fields/Types"; -import { makeObservable } from "mobx"; import { Doc } from "../../../fields/Doc"; -import { Reaction } from "mobx"; -import { reaction } from "mobx"; import { numberRange } from "../../../Utils"; import { Tooltip } from "@mui/material"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; @@ -15,16 +11,9 @@ import { undoable } from "../../util/UndoManager"; import { BoolCast } from "../../../fields/Types"; import { DocCast } from "../../../fields/Types"; import './IconTagBox.scss'; -import { AclAdmin, AclAugment, AclEdit, DocData } from '../../../fields/DocSymbols'; +import {DocData } from '../../../fields/DocSymbols'; import { StrListCast } from "../../../fields/Doc"; import { StrCast } from "../../../fields/Types"; -import { DocListCast } from "../../../fields/Doc"; -import { List } from "../../../fields/List"; -import { action } from "mobx"; -import { DragManager } from "../../util/DragManager"; -import { setupMoveUpEvents } from "../../../ClientUtils"; -import { returnFalse } from "../../../ClientUtils"; -import { emptyFunction } from "../../../Utils"; import { CollectionViewType } from "../../documents/DocumentTypes"; import { SnappingManager } from "../../util/SnappingManager"; import { MainView } from "../MainView"; @@ -33,95 +22,28 @@ import { PropertiesView } from "../PropertiesView"; export interface IconTagProps { doc: Doc; - - } +/** + * Renders the icon tags that rest under the document. The icons rendered are determined by the values of + * each icon in the userdoc. + */ @observer export class IconTagBox extends ObservableReactComponent { - private ref: React.RefObject; - private height: number = 0; - - @computed get currentScale() { - // console.log(NumCast((this._props.doc.embedContainer as Doc)?._freeform_scale, 1)) return NumCast((this._props.doc.embedContainer as Doc)?._freeform_scale, 1); } constructor(props: any) { super(props); - makeObservable(this); - this.ref = React.createRef(); } - // componentDidMount(): void { - // this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; - // this._props.doc._keywordHeight = this.height; - - // reaction( - // () => this.currentScale, - // () => { - // if (this.currentScale < 1) { - // this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; - // this._props.doc._keywordHeight = this.height; - // } - // } - // ); - // } - componentDidUpdate(prevProps: Readonly): void { - // this.height = this.ref.current?.getBoundingClientRect().height ? this.ref.current?.getBoundingClientRect().height : 0; this._props.doc[DocData].tagHeight = 36*this.currentScale; } - // createCollection = () => { - // // Get the documents that contain the keyword. - // const selected = DocListCast(this.getKeywordCollectionDocs()!); - // const newEmbeddings = selected.map(doc => Doc.MakeEmbedding(doc)); - - // // Create a new collection and set up configurations. - // const newCollection = ((doc: Doc) => { - // const docData = doc[DocData]; - // docData.data = new List(newEmbeddings); - // docData.title = this._props.keyword; - // doc._freeform_panX = doc._freeform_panY = 0; - // return doc; - // })(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true)); - // newEmbeddings.forEach(embed => (embed.embedContainer = newCollection)); - // newCollection._width = 900; - // newCollection._height = 900; - // newCollection.layout_fitWidth = true; - - // // Add the collection to the keyword document's list of associated smart collections. - // this._props.keywordDoc.collections = new List([...DocListCast(this._props.keywordDoc.collections), newCollection]); - // newCollection[DocData].data_labels = new List([this._props.keyword]); - // newCollection[DocData][`${this._props.keyword}`] = true; - // newCollection[DocData].showLabels = true; - // return newCollection; - // }; - - // @action - // handleDragStart = (e: React.PointerEvent) => { - // if (this._props.isEditing) { - // const clone = this.ref.current?.cloneNode(true) as HTMLElement; - // if (!clone) return; - - // setupMoveUpEvents( - // this, - // e, - // () => { - // const dragData = new DragManager.DocumentDragData([this.createCollection()]); - // DragManager.StartDocumentDrag([this.ref.current!], dragData, e.clientX, e.clientY, {}); - // return true; - // }, - // returnFalse, - // emptyFunction - // ); - // e.preventDefault(); - // } - // }; /** * Renders the buttons to customize sorting depending on which group the card belongs to and the amount of total groups @@ -130,25 +52,10 @@ export class IconTagBox extends ObservableReactComponent { * @returns */ renderButtons = (doc: Doc): JSX.Element | null => { - // if (cardSort !== cardSortings.Custom) return null; - const amButtons = (StrListCast(Doc.UserDoc().myFilterHotKeyTitles).length) + 1 const keys = StrListCast(Doc.UserDoc().myFilterHotKeyTitles) - - - // const amButtons = Math.max( - // 4, - // this.childDocs?.reduce((set, d) => { - // if (this.cardSort_customField) { - // set.add(NumCast(d[this.cardSort_customField])); - // } - // return set; - // }, new Set()).size ?? 0 - // ); - - // const activeButtonIndex = CollectionCardView.getButtonGroup(this.cardSort_customField, doc); - + const totalWidth = (amButtons -1) * 35 + (amButtons -1) * 2 * 5 + 6; const iconMap = (buttonID: number) => { @@ -179,16 +86,14 @@ export class IconTagBox extends ObservableReactComponent { ))} - - {/* Click to customize these icons
}> - - */}
); }; + /** + * Opens the filter panel in the properties menu + */ + openHotKeyMenu = () => { SnappingManager.PropertiesWidth < 5 && SnappingManager.SetPropertiesWidth(0); SnappingManager.SetPropertiesWidth(MainView.Instance.propertiesWidth() < 15 ? Math.min(MainView.Instance._dashUIWidth - 50, 250) : 0); @@ -204,31 +109,19 @@ export class IconTagBox extends ObservableReactComponent { * @param doc */ toggleButton = undoable((doc: Doc, icon: string) => { - - - - // this.cardSort_customField && (doc[this.cardSort_customField] = buttonID); - - // doc.cardSort_activeIcons = new List() - - - // const list = StrListCast(doc.cardSort_activeIcons); - // doc.cardSort_activeIcons = new List(list.includes(icon) ? list.filter(d => d !== icon) : [...list, icon]); - BoolCast(doc[icon]) ? doc[icon] = false : doc[icon] = true - - - // StrListCast(doc.cardSort_activeIcons).push(iconMap[buttonID]) }, 'toggle card tag'); + /** + * Determines whether or not the given icon is active depending on the doc's data + * @param doc + * @param icon + * @returns + */ getButtonIcon = (doc: Doc, icon: any): JSX.Element => { - - // const isActive = StrListCast(doc.cardSort_activeIcons).includes(icon) const isActive = doc[icon] - - // console.log(StrListCast(doc.cardSort_activeIcons)) const color = isActive ? '#4476f7' : '#323232'; return ; @@ -244,8 +137,6 @@ export class IconTagBox extends ObservableReactComponent { } - - } diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx index 002e82332..53bedbb65 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx +++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx @@ -279,7 +279,7 @@ export class GPTPopup extends ObservableReactComponent { } /** - * Generates a response to the user's questoin depending on the type of their question + * Generates a response to the user's question depending on the type of their question */ generateCard = async () => { console.log(this.chatSortPrompt + "USER PROMPT") @@ -798,7 +798,8 @@ export class GPTPopup extends ObservableReactComponent { color={StrCast(SettingsManager.userVariantColor)} tooltip="close" icon={} - onClick={() => this.setVisible(false)} + onClick={() => { + this.setVisible(false)}} /> diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts index bee79a38d..fea88cdcb 100644 --- a/src/typings/index.d.ts +++ b/src/typings/index.d.ts @@ -12,7 +12,7 @@ declare module 'fit-curve'; declare module 'iink-js'; declare module 'pdfjs-dist/web/pdf_viewer'; declare module 'react-jsx-parser'; -declare module 'type_decls.d'; +// declare module 'type_decls.d'; declare module '@react-pdf/renderer' { import * as React from 'react'; -- cgit v1.2.3-70-g09d2 From 64635a0a0e07a107c4019e366feb2fe5b01c8b04 Mon Sep 17 00:00:00 2001 From: aidahosa1 Date: Tue, 17 Sep 2024 13:43:40 -0400 Subject: ready to pull --- package-lock.json | 153 ++++++++++++--------- src/client/documents/Documents.ts | 7 - src/client/views/DocumentButtonBar.tsx | 54 +++++--- src/client/views/DocumentDecorations.tsx | 4 - src/client/views/StyleProvider.tsx | 3 +- .../views/collections/CollectionCardDeckView.scss | 58 -------- .../views/collections/CollectionCardDeckView.tsx | 19 +-- src/client/views/global/globalScripts.ts | 12 +- src/client/views/nodes/IconTagBox.scss | 20 +-- src/client/views/pdf/GPTPopup/GPTPopup.scss | 12 +- 10 files changed, 145 insertions(+), 197 deletions(-) (limited to 'src/client/documents/Documents.ts') diff --git a/package-lock.json b/package-lock.json index fabc6d90a..d20aac0c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -94,7 +94,7 @@ "D": "^1.0.0", "d3": "^7.8.5", "depcheck": "^1.4.7", - "dotenv": "^16.3.1", + "dotenv": "^16.4.5", "eslint-webpack-plugin": "^4.1.0", "exif": "^0.6.0", "exifr": "^7.1.3", @@ -133,6 +133,7 @@ "image-data-uri": "^2.0.1", "image-size": "^1.0.2", "image-size-stream": "^1.1.0", + "install": "^0.13.0", "is-plain-obj": "^4.1.0", "jimp": "^1.0.4", "jpeg-autorotate": "^9.0.0", @@ -157,7 +158,7 @@ "node-stream-zip": "^1.15.0", "nodemailer": "^6.9.7", "nodemon": "^3.0.2", - "npm": "^10.2.5", + "npm": "^10.8.1", "openai": "^4.26.0", "p-limit": "^6.1.0", "passport": "^0.7.0", @@ -191,6 +192,7 @@ "react-compound-slider": "^3.4.0", "react-datepicker": "^7.3.0", "react-dom": "^18.2.0", + "react-draggable": "^4.4.6", "react-grid-layout": "^1.4.4", "react-icons": "^5.0.1", "react-jsx-parser": "^2.0.0", @@ -249,7 +251,7 @@ "xregexp": "^5.1.1" }, "devDependencies": { - "@eslint/js": "^9.1.1", + "@eslint/js": "^9.10.0", "@types/adm-zip": "^0.5.5", "@types/animejs": "^3.1.12", "@types/archiver": "^6.0.2", @@ -298,9 +300,9 @@ "@types/youtube": "^0.1.0", "chai": "^5.0.0", "cross-env": "^7.0.3", - "eslint": "^9.9.0", - "eslint-plugin-react": "^7.34.1", - "globals": "^15.1.0", + "eslint": "^9.10.0", + "eslint-plugin-react": "^7.36.1", + "globals": "^15.9.0", "jsdom": "^25.0.0", "mocha": "^10.2.0", "prettier": "^3.1.0", @@ -309,7 +311,7 @@ "ts-loader": "^9.5.1", "ts-node": "^10.9.1", "ts-node-dev": "^2.0.0", - "typescript-eslint": "^8.2.0", + "typescript-eslint": "^8.6.0", "webpack-dev-server": "^5.0.4" }, "engines": { @@ -2698,9 +2700,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.9.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.1.tgz", - "integrity": "sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==", + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.10.0.tgz", + "integrity": "sha512-fuXtbiP5GWIn8Fz+LWoOMVf/Jxm+aajZYkhi6CuEm4SxymFM+eUWzbO9qXT+L0iCkL5+KGYMCSGxo686H19S1g==", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -2713,6 +2715,17 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/plugin-kit": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz", + "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@ffmpeg/core": { "version": "0.12.6", "resolved": "https://registry.npmjs.org/@ffmpeg/core/-/core-0.12.6.tgz", @@ -10064,16 +10077,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.4.0.tgz", - "integrity": "sha512-rg8LGdv7ri3oAlenMACk9e+AR4wUV0yrrG+XKsGKOK0EVgeEDqurkXMPILG2836fW4ibokTB5v4b6Z9+GYQDEw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz", + "integrity": "sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.4.0", - "@typescript-eslint/type-utils": "8.4.0", - "@typescript-eslint/utils": "8.4.0", - "@typescript-eslint/visitor-keys": "8.4.0", + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/type-utils": "8.6.0", + "@typescript-eslint/utils": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -10097,15 +10110,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.4.0.tgz", - "integrity": "sha512-NHgWmKSgJk5K9N16GIhQ4jSobBoJwrmURaLErad0qlLjrpP5bECYg+wxVTGlGZmJbU03jj/dfnb6V9bw+5icsA==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.6.0.tgz", + "integrity": "sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.4.0", - "@typescript-eslint/types": "8.4.0", - "@typescript-eslint/typescript-estree": "8.4.0", - "@typescript-eslint/visitor-keys": "8.4.0", + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/typescript-estree": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", "debug": "^4.3.4" }, "engines": { @@ -10125,13 +10138,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.4.0.tgz", - "integrity": "sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz", + "integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.4.0", - "@typescript-eslint/visitor-keys": "8.4.0" + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10142,13 +10155,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.4.0.tgz", - "integrity": "sha512-pu2PAmNrl9KX6TtirVOrbLPLwDmASpZhK/XU7WvoKoCUkdtq9zF7qQ7gna0GBZFN0hci0vHaSusiL2WpsQk37A==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.6.0.tgz", + "integrity": "sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.4.0", - "@typescript-eslint/utils": "8.4.0", + "@typescript-eslint/typescript-estree": "8.6.0", + "@typescript-eslint/utils": "8.6.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -10166,9 +10179,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.4.0.tgz", - "integrity": "sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz", + "integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10179,13 +10192,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.4.0.tgz", - "integrity": "sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz", + "integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.4.0", - "@typescript-eslint/visitor-keys": "8.4.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/visitor-keys": "8.6.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -10234,15 +10247,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.4.0.tgz", - "integrity": "sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz", + "integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.4.0", - "@typescript-eslint/types": "8.4.0", - "@typescript-eslint/typescript-estree": "8.4.0" + "@typescript-eslint/scope-manager": "8.6.0", + "@typescript-eslint/types": "8.6.0", + "@typescript-eslint/typescript-estree": "8.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10256,12 +10269,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.4.0.tgz", - "integrity": "sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz", + "integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/types": "8.6.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -17701,15 +17714,16 @@ } }, "node_modules/eslint": { - "version": "9.9.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.1.tgz", - "integrity": "sha512-dHvhrbfr4xFQ9/dq+jcVneZMyRYLjggWjk6RVsIiHsP8Rz6yZ8LvZ//iU4TrZF+SXWG+JkNF2OyiZRvzgRDqMg==", + "version": "9.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.10.0.tgz", + "integrity": "sha512-Y4D0IgtBZfOcOUAIQTSXBKoNGfY0REGqHJG6+Q81vNippW5YlKjHFj4soMxamKK1NXHUWuBZTLdU3Km+L/pcHw==", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", "@eslint/config-array": "^0.18.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.9.1", + "@eslint/js": "9.10.0", + "@eslint/plugin-kit": "^0.1.0", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", @@ -17732,7 +17746,6 @@ "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", @@ -17759,9 +17772,9 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.35.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.2.tgz", - "integrity": "sha512-Rbj2R9zwP2GYNcIak4xoAMV57hrBh3hTaR0k7hVjwCQgryE/pw5px4b13EYjduOI0hfXyZhwBxaGpOTbWSGzKQ==", + "version": "7.36.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.36.1.tgz", + "integrity": "sha512-/qwbqNXZoq+VP30s1d4Nc1C5GTxjJQjk4Jzs4Wq2qzxFM7dSmuG2UkIjg2USMLh3A/aVcUNrK7v0J5U1XEGGwA==", "dev": true, "dependencies": { "array-includes": "^3.1.8", @@ -20914,6 +20927,14 @@ "inspect-function": "^0.3.1" } }, + "node_modules/install": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/internal-slot": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", @@ -32710,14 +32731,14 @@ "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ==" }, "node_modules/typescript-eslint": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.4.0.tgz", - "integrity": "sha512-67qoc3zQZe3CAkO0ua17+7aCLI0dU+sSQd1eKPGq06QE4rfQjstVXR6woHO5qQvGUa550NfGckT4tzh3b3c8Pw==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.6.0.tgz", + "integrity": "sha512-eEhhlxCEpCd4helh3AO1hk0UP2MvbRi9CtIAJTVPQjuSXOOO2jsEacNi4UdcJzZJbeuVg1gMhtZ8UYb+NFYPrA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.4.0", - "@typescript-eslint/parser": "8.4.0", - "@typescript-eslint/utils": "8.4.0" + "@typescript-eslint/eslint-plugin": "8.6.0", + "@typescript-eslint/parser": "8.6.0", + "@typescript-eslint/utils": "8.6.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 623a5251e..aac15059e 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -488,14 +488,7 @@ export class DocumentOptions { userColor?: STRt = new StrInfo('color associated with a Dash user (seen in header fields of shared documents)'); cardSort?: STRt = new StrInfo('way cards are sorted in deck view'); - // cardSortForDropDown?: STRt = new StrInfo('needed for dropdown and i dont know why') - // cardSort_customField?: STRt = new StrInfo('field key used for sorting cards'); - cardSort_activeIcons?: List; //icons each card is tagges with - // cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) - - // cardSort_visibleSortGroups?: List; // which sorting values are being filtered (shown) cardSort_isDesc?: BOOLt = new BoolInfo('whether the cards are sorted ascending or descending'); - // test?: STRt = new StrInfo('testing for filtering') } export const DocOptions = new DocumentOptions(); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index ea859a1e5..ccde1de80 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -9,7 +9,7 @@ import * as React from 'react'; import { FaEdit } from 'react-icons/fa'; import { returnFalse, returnTrue, setupMoveUpEvents, simulateMouseClick } from '../../ClientUtils'; import { emptyFunction } from '../../Utils'; -import { Doc, DocListCast } from '../../fields/Doc'; +import { Doc } from '../../fields/Doc'; import { Cast, DocCast } from '../../fields/Types'; import { DocUtils, IsFollowLinkScript } from '../documents/DocUtils'; import { CalendarManager } from '../util/CalendarManager'; @@ -263,6 +263,26 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( ); } + @computed + get calendarButton() { + const targetDoc = this.view0?.Document; + return !targetDoc ? null : ( + Open calendar menu
}> +
{ + CalendarManager.Instance.open(this.view0, targetDoc); + }}> + +
+ + ); + } + + /** + * Allows for both the keywords and the icon tags to be shown using a quasi- multitoggle + */ @computed get keywordButton() { const targetDoc = this.view0?.Document; @@ -279,21 +299,10 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( size="sm" icon={icon} onClick={e => { - // console.log('wtfff') - // name === 'tags' ?? if (name === 'tags'){ - undoable(e => (targetDoc && (targetDoc[DocData].showIconTags = !targetDoc[DocData].showIconTags)), 'show icon tags') + (targetDoc && (targetDoc[DocData].showIconTags = !targetDoc[DocData].showIconTags)) } else { - undoable(e => { - const showing = DocumentView.Selected().some(dv => dv.layoutDoc._layout_showTags); - DocumentView.Selected().forEach(dv => { - dv.layoutDoc._layout_showTags = !showing; - if (e.shiftKey) - DocListCast(dv.Document[Doc.LayoutFieldKey(dv.Document) + '_annotations']).forEach(doc => { - if (doc.face) doc.hidden = showing; - }); - }); - }, 'show Doc tags') + (targetDoc && (targetDoc[DocData].showLabels = !targetDoc[DocData].showLabels)) } @@ -309,15 +318,23 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( - return !DocumentView.Selected().length ? null : ( + return !targetDoc ? null : (
{metaBtn('tags', 'star')} {metaBtn("keywords", 'id-card')}
- Open keyword / icon tag menu
}> -
+ Open keyword menu
}> +
{ + // targetDoc[DocData].showIconTags = !targetDoc[DocData].showIconTags; + }} + > + +
@@ -495,10 +512,11 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => ( {!DocumentView.Selected().some(v => v.allLinks.length) ? null :
{this.followLinkButton}
}
{this.pinButton}
{this.recordButton}
+
{this.calendarButton}
{this.keywordButton}
{!Doc.UserDoc().documentLinksButton_fullMenu ? null :
{this.shareButton}
}
{this.menuButton}
); } -} +} \ No newline at end of file diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 45ce681aa..37b1f04e7 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -773,10 +773,6 @@ export class DocumentDecorations extends ObservableReactComponent CollectionFreeFormDocumentView.from(v)); - const keyWordTrans = doc[DocData].showLabels ? NumCast(doc[DocData].keywordHeight) : 0 - const tagTrans = doc[DocData].showIconTags ? NumCast(doc[DocData].tagHeight) : 0 - - return (
, props: Opt ); }; - const tags = () => props?.DocumentView?.() && CollectionFreeFormDocumentView.from(props.DocumentView()) ? : null; + const tags = () => props?.DocumentView?.() ? : null; const iconTags = () => { if (doc && doc![DocData].showIconTags) {return ()} } - return ( <> {paint()} diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss index 1728f7aee..5ccc3d9a8 100644 --- a/src/client/views/collections/CollectionCardDeckView.scss +++ b/src/client/views/collections/CollectionCardDeckView.scss @@ -12,7 +12,6 @@ height: 35px; border-radius: 50%; background-color: $dark-gray; - // border-color: $medium-blue; margin: 5px; // transform: translateY(-50px); } } @@ -20,7 +19,6 @@ .card-wrapper { display: grid; grid-template-columns: repeat(10, 1fr); - // width: 100%; transform-origin: top left; position: absolute; @@ -31,33 +29,6 @@ transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); } -// .card-button-container { -// display: flex; -// padding: 3px; -// // width: 300px; -// // height:100px; -// pointer-events: none; /* This ensures the container does not capture hover events */ - -// background-color: rgb(218, 218, 218); /* Background color of the container */ -// border-radius: 50px; /* Rounds the corners of the container */ -// transform: translateY(25px); -// // box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* Optional: Adds shadow for depth */ -// align-items: center; /* Centers buttons vertically */ -// justify-content: start; /* Centers buttons horizontally */ - -// button { -// pointer-events: auto; /* Re-enable pointer events for the buttons */ - -// width: 70px; -// height: 70px; -// border-radius: 50%; -// background-color: $dark-gray; -// // border-color: $medium-blue; -// margin: 5px; // transform: translateY(-50px); -// background-color: transparent; -// } -// } - .no-card-span{ position: relative; width: fit-content; @@ -70,28 +41,6 @@ -// button:hover { -// transform: translateY(-50px); -// } - -// .card-wrapper::after { -// content: ""; -// width: 100%; /* Forces wrapping */ -// } - -// .card-wrapper > .card-item:nth-child(10n)::after { -// content: ""; -// width: 100%; /* Forces wrapping after every 10th item */ -// } - -// .card-row{ -// display: flex; -// position: absolute; -// align-items: center; -// transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); - -// } - .card-item-inactive, .card-item-active, .card-item { @@ -101,18 +50,11 @@ flex-direction: column; } -// .card-item:hover { -// box-shadow: 0 20px 20px $medium-blue; -// transform: scale(1.05); - - -// } .card-item-inactive { opacity: 0.5; } .card-item-active { - // position: absolute; z-index: 100; } diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index 3d9f28a49..bb932b8b2 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -1,9 +1,9 @@ import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; -import { ClientUtils, DashColor, returnFalse, returnZero } from '../../../ClientUtils'; -import { emptyFunction, numberRange } from '../../../Utils'; -import { Doc, NumListCast, StrListCast } from '../../../fields/Doc'; +import { ClientUtils, returnFalse, returnZero } from '../../../ClientUtils'; +import { emptyFunction } from '../../../Utils'; +import { Doc, StrListCast } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { BoolCast, Cast, DateCast, NumCast, RTFCast, ScriptCast, StrCast } from '../../../fields/Types'; @@ -144,18 +144,7 @@ export class CollectionCardView extends CollectionSubView() { * custom group */ @computed get childDocsWithoutLinks() { - const regularDocs = this.childDocs.filter(l => l.type !== DocumentType.LINK); - const activeGroups = StrListCast(this.Document.cardSort_visibleSortGroups); - - if (activeGroups.length > 0) { - return regularDocs.filter(doc => { - const activeTags = StrListCast(doc.cardSort_activeIcons); - return activeTags !== undefined && activeTags.some(tag => activeGroups.includes(tag)); - }); - } - - // Default return for non-custom cardSort or other cases, filtering out links - return regularDocs; + return this.childDocs.filter(l => l.type !== DocumentType.LINK); } /** diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 53e10d44d..65bd524fe 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -147,7 +147,7 @@ ScriptingGlobals.add(function showFreeform(attr: 'hcenter' | 'vcenter' | 'grid' } // prettier-ignore - const map: Map<'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'chat' | 'up' | 'down' | 'pile' | 'toggle-chat' | 'tag', + const map: Map<'flashcards' | 'hcenter' | 'vcenter' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'chat' | 'up' | 'down' | 'pile' | 'toggle-chat' | 'tag', { waitForRender?: boolean; checkResult: (doc: Doc) => boolean; @@ -169,9 +169,13 @@ ScriptingGlobals.add(function showFreeform(attr: 'hcenter' | 'vcenter' | 'grid' else (dv.ComponentView as CollectionFreeFormView)?.fitContentOnce(); }, }], - ['center', { - checkResult: (doc: Doc) => BoolCast(doc?._stacking_alignCenter, false), - setDoc: (doc: Doc) => { doc._stacking_alignCenter = !doc._stacking_alignCenter; }, + ['vcenter', { + checkResult: (doc:Doc) => !StrCast(doc?._layout_dontCenter).includes('y'), + setDoc: (doc:Doc) => { doc._layout_dontCenter = StrCast(doc.layout_dontCenter).includes('y') ? StrCast(doc.layout_dontCenter).replace(/y/,"") : StrCast(doc.layout_dontCenter) + 'y'; }, + }], + ['hcenter', { + checkResult: (doc:Doc) => !StrCast(doc?._layout_dontCenter).includes('x'), + setDoc: (doc:Doc) => { doc._layout_dontCenter = StrCast(doc.layout_dontCenter).includes('x') ? StrCast(doc.layout_dontCenter).replace(/x/,"") : 'x'+ StrCast(doc.layout_dontCenter); }, }], ['clusters', { waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire diff --git a/src/client/views/nodes/IconTagBox.scss b/src/client/views/nodes/IconTagBox.scss index 8c0f92c90..211a961c1 100644 --- a/src/client/views/nodes/IconTagBox.scss +++ b/src/client/views/nodes/IconTagBox.scss @@ -4,27 +4,21 @@ display: flex; padding: 3px; position: absolute; - // width: 300px; - // height:100px; - pointer-events: none; /* This ensures the container does not capture hover events */ - - background-color: rgb(218, 218, 218); /* Background color of the container */ - border-radius: 50px; /* Rounds the corners of the container */ + pointer-events: none; + background-color: rgb(218, 218, 218); + border-radius: 50px; transform: translateY(25px); - // box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* Optional: Adds shadow for depth */ - align-items: center; /* Centers buttons vertically */ - justify-content: start; /* Centers buttons horizontally */ + align-items: center; + justify-content: start; button { - pointer-events: auto; /* Re-enable pointer events for the buttons */ + pointer-events: auto; transform: translateY(-7.5px); - width: 30px; height: 30px; border-radius: 50%; background-color: $dark-gray; - // border-color: $medium-blue; - margin: 5px; // transform: translateY(-50px); + margin: 5px; background-color: transparent; } } \ No newline at end of file diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.scss b/src/client/views/pdf/GPTPopup/GPTPopup.scss index 1defd1a7f..0247dc10c 100644 --- a/src/client/views/pdf/GPTPopup/GPTPopup.scss +++ b/src/client/views/pdf/GPTPopup/GPTPopup.scss @@ -104,9 +104,9 @@ $highlightedText: #82e0ff; display: flex; flex-direction: column; width: 100%; - max-height: calc(100vh - 80px); /* Height minus the input box and some padding */ + max-height: calc(100vh - 80px); overflow-y: auto; - padding-bottom: 60px; /* Space for the input */ + padding-bottom: 60px; } .chat-bubbles { @@ -150,15 +150,7 @@ $highlightedText: #82e0ff; } - // button { - // font-size: 9px; - // padding: 10px; - // color: #ffffff; - // width: 100%; - // background-color: $button; - // border-radius: 5px; - // } .text-btn { &:hover { -- cgit v1.2.3-70-g09d2