aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/DocUtils.ts3
-rw-r--r--src/client/util/CurrentUserUtils.ts10
-rw-r--r--src/client/views/collections/CollectionCardDeckView.scss6
-rw-r--r--src/client/views/collections/CollectionCardDeckView.tsx45
-rw-r--r--src/client/views/global/globalScripts.ts20
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBox.tsx21
-rw-r--r--src/client/views/nodes/IconTagBox.tsx5
7 files changed, 42 insertions, 68 deletions
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';