diff options
author | bobzel <zzzman@gmail.com> | 2024-09-20 14:49:46 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2024-09-20 14:49:46 -0400 |
commit | 702949ed50a1d9819d58a6154fee20d086664505 (patch) | |
tree | ea1e8fc9300b8ea96f7c6ee1e63023ba5f7c1620 | |
parent | 77e087625bd02cfa170e3f1903b0a744b81380ce (diff) | |
parent | 650ddd4c72510ed29d023d4861dedede0737d3b9 (diff) |
Merge branch 'master' into zach-starter
-rw-r--r-- | package-lock.json | 8 | ||||
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/client/documents/DocUtils.ts | 3 | ||||
-rw-r--r-- | src/client/util/CurrentUserUtils.ts | 10 | ||||
-rw-r--r-- | src/client/views/collections/CollectionCardDeckView.scss | 6 | ||||
-rw-r--r-- | src/client/views/collections/CollectionCardDeckView.tsx | 45 | ||||
-rw-r--r-- | src/client/views/global/globalScripts.ts | 20 | ||||
-rw-r--r-- | src/client/views/nodes/FontIconBox/FontIconBox.tsx | 21 | ||||
-rw-r--r-- | src/client/views/nodes/IconTagBox.tsx | 5 |
9 files changed, 47 insertions, 73 deletions
diff --git a/package-lock.json b/package-lock.json index 5e2e67839..fac1cc20b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -70,7 +70,7 @@ "body-parser": "^1.20.2", "bootstrap": "^5.3.2", "brotli": "^1.3.3", - "browndash-components": "^0.1.45", + "browndash-components": "^0.1.47", "browser-assert": "^1.2.1", "bson": "^6.2.0", "canvas": "^2.11.2", @@ -11553,9 +11553,9 @@ } }, "node_modules/browndash-components": { - "version": "0.1.45", - "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.1.45.tgz", - "integrity": "sha512-A2/3SikcA1kntY8jajwWJjnRGVRP9+DheaOMh9fAdgiQrdMZVMty+nUasbXk9HjyjkMfAUAkGvCR+SS28QL/zA==", + "version": "0.1.47", + "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.1.47.tgz", + "integrity": "sha512-562nWku81I1wccgEQbMU/30+RP/81sxsIGoPGLH7Otm9TdrHXWgW8yJS4tzBPXBF03Q2AX8DyQusi6T0LSc7Mw==", "dependencies": { "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", diff --git a/package.json b/package.json index b8a23d0b5..fdd0fc9cf 100644 --- a/package.json +++ b/package.json @@ -149,7 +149,7 @@ "body-parser": "^1.20.2", "bootstrap": "^5.3.2", "brotli": "^1.3.3", - "browndash-components": "^0.1.45", + "browndash-components": "^0.1.47", "browser-assert": "^1.2.1", "bson": "^6.2.0", "canvas": "^2.11.2", diff --git a/src/client/documents/DocUtils.ts b/src/client/documents/DocUtils.ts index 30b71a09b..4d105e372 100644 --- a/src/client/documents/DocUtils.ts +++ b/src/client/documents/DocUtils.ts @@ -241,7 +241,10 @@ export namespace DocUtils { Object.keys(scripts).forEach(key => { const script = scripts[key] as string; if (ScriptCast(doc[key])?.script.originalScript !== scripts[key] && script) { + const additionalItems: { [key: string]: unknown } = {}; + script.match(/_[a-zA-Z]*_/)?.forEach(match => (additionalItems[match] = 'any')); (key.startsWith('_') ? doc : Doc.GetProto(doc))[key] = ScriptField.MakeScript(script, { + ...additionalItems, this: Doc.name, dragData: Doc.DocDragDataName, value: 'any', diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 698e4e315..4d702c971 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -688,14 +688,14 @@ pie title Minerals in my tap water static tagGroupTools(): Button[] { const defaultTagButtonDescs = [ - { title: "Star", isSystem: false,icon: "star", toolTip:"Click to toggle visibility of Star tagged Docs", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"#star", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, - { title: "Like", isSystem: false,icon: "heart", toolTip:"Click to toggle visibility of Like tagged Docs", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"#like", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, - { title: "Todo", isSystem: false,icon: "bolt", toolTip:"Click to toggle visibility of Todo tagged Docs", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"#todo", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, - { title: "Idea", isSystem: false,icon: "cloud", toolTip:"Click to toggle visibility of Idea tagged Docs", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"#idea", funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, + { title: "Star", isSystem: false,icon: "star", toolTip:"Click to toggle visibility of Star tagged Docs", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"#star", funcs: {}, scripts: { onClick: '{ return setTagFilter(this.toolType, _added_, _readOnly_);}'}}, + { title: "Like", isSystem: false,icon: "heart", toolTip:"Click to toggle visibility of Like tagged Docs", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"#like", funcs: {}, scripts: { onClick: '{ return setTagFilter(this.toolType, _added_, _readOnly_);}'}}, + { title: "Todo", isSystem: false,icon: "bolt", toolTip:"Click to toggle visibility of Todo tagged Docs", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"#todo", funcs: {}, scripts: { onClick: '{ return setTagFilter(this.toolType, _added_, _readOnly_);}'}}, + { title: "Idea", isSystem: false,icon: "cloud", toolTip:"Click to toggle visibility of Idea tagged Docs", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"#idea", funcs: {}, scripts: { onClick: '{ return setTagFilter(this.toolType, _added_, _readOnly_);}'}}, ]; // hack: if there's no dashboard, create default filters. otherwise, just make sure that the Options button is preserved return [ - { title:"Options",isSystem: true,icon: "gear", toolTip:"Click to customize list of filter buttons", btnType: ButtonType.ClickButton, expertMode: false, toolType:"-opts-",funcs: {}, scripts: { onClick: '{ return handleTags(this.toolType, _readOnly_);}'}}, + { title:"Options",isSystem: true,icon: "gear", toolTip:"Click to customize list of filter buttons", btnType: ButtonType.ClickButton, expertMode: false, toolType:"-opts-",funcs: {}, scripts: { onClick: '{ return setTagFilter(this.toolType, false,_readOnly_);}'}}, ...(Doc.UserDoc().activeDashboard ? [] : defaultTagButtonDescs) ] } diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss index e5fb7aba6..d1731c244 100644 --- a/src/client/views/collections/CollectionCardDeckView.scss +++ b/src/client/views/collections/CollectionCardDeckView.scss @@ -8,11 +8,7 @@ overflow: hidden; button { - width: 35px; - height: 35px; border-radius: 50%; - background-color: $dark-gray; - margin: 5px; // transform: translateY(-50px); } } @@ -40,7 +36,7 @@ .card-item-active, .card-item { position: relative; - transition: transform 0.5s ease-in-out; + transition: transform 0.3s ease-in-out; display: flex; flex-direction: column; } diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index bcb42111f..d9c27254a 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 } from '../../../Utils'; -import { Doc, StrListCast } from '../../../fields/Doc'; +import { Doc } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { List } from '../../../fields/List'; @@ -18,6 +18,7 @@ import { SnappingManager } from '../../util/SnappingManager'; import { Transform } from '../../util/Transform'; import { undoable } from '../../util/UndoManager'; import { StyleProp } from '../StyleProp'; +import { TagItem } from '../TagsView'; import { DocumentView } from '../nodes/DocumentView'; import { GPTPopup, GPTPopupMode } from '../pdf/GPTPopup/GPTPopup'; import './CollectionCardDeckView.scss'; @@ -242,7 +243,6 @@ export class CollectionCardView extends CollectionSubView() { const currRow = Math.floor((mouseY - 100) / rowHeight); //rows start at 0 if (adjustedX < 0) { - console.log('DROP INDEX NO '); return 0; // Before the first column } @@ -257,7 +257,6 @@ export class CollectionCardView extends CollectionSubView() { index = Math.floor(adjustedX / cardWidth) + currRow * this._maxRowCount; } - console.log('DROP INDEX = ' + index); return index; }; @@ -327,35 +326,11 @@ export class CollectionCardView extends CollectionSubView() { * @returns its value based on its tags */ - tagValue = (doc: Doc) => { - const keys = Doc.MyFilterHotKeys; - - const isTagActive = (key: Doc) => BoolCast(key.active); - - let base = ''; - let fraction = ''; - - keys.forEach(key => { - if (isTagActive(key)) { - if (base === '') { - base = StrCast(key.toolType); // First active tag becomes the base - } else { - fraction += StrCast(key.toolType); // Subsequent active tags become part of the fraction - } - } - }); - - // If no tag was active, return 0 by default - if (base === '') { - return 0; - } - - // Construct the final number by appending the fraction if it exists - const numberString = fraction ? `${base}.${fraction}` : base; - - // Convert the result to a number and return - return Number(numberString); - }; + tagValue = (doc: Doc) => + Doc.MyFilterHotKeys.map((key, i) => ({ has: TagItem.docHasTag(doc, StrCast(key.toolType)), i })) + .filter(({ has }) => has) + .map(({ i }) => i) + .join('.'); /** * Called in the sortedDocsType method. Compares the cards' value in regards to the desired sort type-- earlier cards are move to the @@ -492,7 +467,7 @@ export class CollectionCardView extends CollectionSubView() { }; const docTextPromises = this.childDocsWithoutLinks.map(async doc => { const docText = (await docToText(doc)) ?? ''; - doc['gptInputText'] = docText; + doc.gptInputText = docText; this._textToDoc.set(docText.replace(/\n/g, ' ').trim(), doc); return `======${docText.replace(/\n/g, ' ').trim()}======`; }); @@ -532,7 +507,7 @@ export class CollectionCardView extends CollectionSubView() { if (questionType === '2' || questionType === '4') { this.childDocs.forEach(d => { - d['chatFilter'] = false; + d.chatFilter = false; }); } @@ -573,7 +548,7 @@ export class CollectionCardView extends CollectionSubView() { } case '2': case '4': - doc['chatFilter'] = true; + doc.chatFilter = true; Doc.setDocFilter(DocCast(this.Document.embedContainer), 'chatFilter', true, 'match'); break; } diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 0afb3635f..7f6c726d6 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -271,24 +271,24 @@ ScriptingGlobals.add(function showFreeform(attr: 'hcenter' | 'vcenter' | 'grid' }); /** - * Applies a filter to the selected document (or, if the settings button is pressed, opens the filter panel) + * Applies (or removes) a filter to the selected document for the specified tag + * NOTE: this also opens the filter panel if the settings button is clicked (probably should be a different function) */ // eslint-disable-next-line prefer-arrow-callback -ScriptingGlobals.add(function handleTags(value: string, checkResult?: boolean) { +ScriptingGlobals.add(function setTagFilter(tag: string, added: boolean, checkResult?: boolean) { const selected = DocumentView.SelectedDocs().lastElement(); - const isOptions = value === '-opts-'; - - const isAttrFiltered = (attr: string) => - StrListCast(selected._childFilters) - .map(filter => filter.split(Doc.FilterSep)) - .some(([key, val]) => key === 'tags' && val === attr); + const isOptions = tag === '-opts-'; if (checkResult) { - return isOptions ? false : isAttrFiltered(value); + return isOptions + ? false + : StrListCast(selected._childFilters) // check all filters for one that filters tags:value where value is the tag's name + .map(filter => filter.split(Doc.FilterSep)) + .some(([key, val]) => key === 'tags' && val === tag); } if (!isOptions) { - isAttrFiltered(value) ? Doc.setDocFilter(selected, 'tags', value, 'remove') : Doc.setDocFilter(selected, 'tags', value, 'check'); + added ? Doc.setDocFilter(selected, 'tags', tag, 'check') : Doc.setDocFilter(selected, 'tags', tag, 'remove'); } else { SnappingManager.PropertiesWidth < 5 && SnappingManager.SetPropertiesWidth(0); SnappingManager.SetPropertiesWidth(MainView.Instance.propertiesWidth() < 15 ? 250 : 0); diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx index 0e4288574..cb0c4d188 100644 --- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx +++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx @@ -266,28 +266,31 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() { // Colors const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string; const items = DocListCast(this.dataDoc.data); - const multiDoc = this.Document; - const selectedItem = StrCast(items.find(itemDoc => ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, value: undefined, _readOnly_: true }).result)?.toolType ?? StrCast(multiDoc.toolType)); - console.log(selectedItem); + const selectedItems = items.filter(itemDoc => ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, value: undefined, _readOnly_: true }).result).map(item => StrCast(item.toolType)); return ( <MultiToggle tooltip={`Toggle ${tooltip}`} type={Type.PRIM} color={color} - onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => script.run({ this: multiDoc, value: undefined, _readOnly_: false }))} + multiSelect={true} + onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => script.run({ this: this.Document, value: undefined, _readOnly_: false }))} isToggle={script ? true : false} toggleStatus={toggleStatus} //background={SnappingManager.userBackgroundColor} label={this.label} - items={DocListCast(this.dataDoc.data).map(item => ({ + items={items.map(item => ({ icon: <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={StrCast(item.icon) as IconProp} color={color} />, tooltip: StrCast(item.toolTip), val: StrCast(item.toolType), }))} - selectedVal={selectedItem} - setSelectedVal={(val: string | number) => { - const itemDoc = items.find(item => item.toolType === val); - itemDoc && ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, value: val, _readOnly_: false }); + selectedItems={selectedItems} + onSelectionChange={(val: (string | number) | (string | number)[], added: boolean) => { + // note: the multitoggle is telling us whether the selection was toggled on or off, but we ignore this since we know the state of all the buttons + // and control it through the selectedItems prop. Therefore, the callback script will have to re-determine the toggle information. + // it would be better to pas the 'added' flag to the callback script, but our script generator from currentUserUtils makes it hard to define + // arbitrary parameter variables (but it could be done as a special case or with additional effort when creating the sript) + const itemsChanged = items.filter(item => (val instanceof Array ? val.includes(item.toolType as string | number) : item.toolType === val)); + itemsChanged.forEach(itemDoc => ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, _added_: added, itemDoc, _readOnly_: false })); }} /> ); diff --git a/src/client/views/nodes/IconTagBox.tsx b/src/client/views/nodes/IconTagBox.tsx index 292f9b523..8faf8ffa5 100644 --- a/src/client/views/nodes/IconTagBox.tsx +++ b/src/client/views/nodes/IconTagBox.tsx @@ -1,18 +1,15 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; -import { action, computed, makeObservable } from 'mobx'; +import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils'; import { emptyFunction } from '../../../Utils'; import { Doc } from '../../../fields/Doc'; import { StrCast } from '../../../fields/Types'; -import { SnappingManager } from '../../util/SnappingManager'; import { undoable } from '../../util/UndoManager'; -import { MainView } from '../MainView'; import { ObservableReactComponent } from '../ObservableReactComponent'; -import { PropertiesView } from '../PropertiesView'; import { TagItem } from '../TagsView'; import { DocumentView } from './DocumentView'; import './IconTagBox.scss'; |