aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/documents/Documents.ts3
-rw-r--r--src/client/util/CurrentUserUtils.ts12
-rw-r--r--src/client/views/MainView.tsx3
-rw-r--r--src/client/views/collections/CollectionCardDeckView.tsx231
4 files changed, 149 insertions, 100 deletions
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<string>;
cardSort_visibleSortGroups?: List<number>; // 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<string>(["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<string>(["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<string>(["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<Doc, DocumentView>();
_draggerRef = React.createRef<HTMLDivElement>();
@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<HTMLDivElement>) => {
+ 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) => (
<DocumentView
// eslint-disable-next-line react/jsx-props-no-spreading
@@ -361,16 +413,7 @@ export class CollectionCardView extends CollectionSubView() {
return trans + this.translateY(amCards, calcRowIndex, realIndex);
};
- /**
- * 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((buttonID: number, doc: Doc) => {
- 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<number>()).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<number>()).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 (
<div className="card-button-container" style={{ width: `${totalWidth}px`, fontSize: '50px' }}>
{numberRange(amButtons).map(i => (
- <Tooltip key={i} title={<div className="dash-tooltip">Click to add/remove this card from group {i + 1}</div>}>
- <button type="button" onClick={() => this.toggleButton(i, doc)}>
- {this.getButtonIcon(activeButtonIndex === i)}
+ <Tooltip key={i} title={<div className="dash-tooltip">Click to add/remove this card from the {iconMap[i]} group</div>}>
+ <button type="button" onClick={() => this.toggleButton(doc, iconMap[i] )}>
+ {this.getButtonIcon(doc, iconMap[i])}
</button>
</Tooltip>
))}
@@ -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<string>()
+
- const icon = iconMap[this.cardSort_customField ?? ''] || 'star';
+ const list = StrListCast(doc.cardSort_activeIcons);
+ doc.cardSort_activeIcons = new List<string>(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 <FontAwesomeIcon icon={icon} size="lg" style={{ color }} />;
};
- // @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 (
<div
+ onPointerMove={e => 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),