aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/CollectionCardDeckView.tsx102
1 files changed, 70 insertions, 32 deletions
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
index 9ce0873bd..3d5b92213 100644
--- a/src/client/views/collections/CollectionCardDeckView.tsx
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -46,7 +46,11 @@ export class CollectionCardView extends CollectionSubView() {
@observable _isLoading = false;
@observable _hoveredNodeIndex = -1;
@observable _docRefs = new ObservableMap<Doc, DocumentView>();
+ _draggerRef = React.createRef<HTMLDivElement>();
@observable _maxRowCount = 10;
+ @observable docsBeingDragged: number[] = [];
+ @observable draggedIndex: number = -1;
+ @observable overIndex: number = -1;
static getButtonGroup(groupFieldKey: 'chat' | 'star' | 'idea' | 'like', doc: Doc): number | undefined {
return Cast(doc[groupFieldKey], 'number', null);
@@ -447,48 +451,81 @@ export class CollectionCardView extends CollectionSubView() {
GPTPopup.Instance.onSortComplete = (sortResult: string) => this.processGptOutput(sortResult);
};
- /**
+ /**
* Renders the buttons to customize sorting depending on which group the card belongs to and the amount of total groups
- * @param childPairIndex
* @param doc
+ * @param cardSort
* @returns
*/
- renderButtons = (doc: Doc, cardSort: cardSortings) => {
- if (cardSort !== cardSortings.Custom) return '';
- const amButtons = Math.max(4, this.childDocs?.reduce((set, d) => this.cardSort_customField && set.add(NumCast(d[this.cardSort_customField])), new Set<number>()).size ?? 0);
- const activeButtonIndex = CollectionCardView.getButtonGroup(this.cardSort_customField, doc);
- const totalWidth = amButtons * 72 + amButtons * 2 * 5 + 6;
- return (
- <div className="card-button-container" style={{ width: `${totalWidth}px`, fontSize: '50px' }} >
- {numberRange(amButtons).map(i => (
- // eslint-disable-next-line jsx-a11y/control-has-associated-label
- <Tooltip title={<div key = {i} className="dash-tooltip">Click to add/ remove this card from group {i +1}</div>}>
+ renderButtons = (doc: Doc, cardSort: cardSortings): JSX.Element | null => {
+ if (cardSort !== cardSortings.Custom) return null;
- <button key={i} type="button"
- // style={{ backgroundColor: activeButtonIndex === i ? '#4476f7' : '#323232' }}
- onClick={() => this.toggleButton(i, doc)}>
- {this.getButtonIcons(activeButtonIndex === i)}
- </button>
+ 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;
+
+ 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)}
+ </button>
+ </Tooltip>
+ ))}
+ </div>
+ );
+};
- </Tooltip>
+ getButtonIcon = (isActive: boolean): JSX.Element => {
+ const iconMap: { [key: string]: any } = {
+ like: 'heart',
+ chat: 'robot',
+ idea: 'cloud'
+ };
- ))}
- </div>
- );
+ const icon = iconMap[this.cardSort_customField ?? ''] || 'star';
+ const color = isActive ? '#4476f7' : '#323232';
+
+ return <FontAwesomeIcon icon={icon} size='lg' style={{ color }} />;
+ };
+
+
+
+ @action
+ onDragStart = (index: number) => {
+ this.draggedIndex = index;
};
- getButtonIcons = (isActive: boolean) => {
- switch (this.cardSort_customField) {
- case 'like':
- return <FontAwesomeIcon icon = 'heart' size= 'lg' style = {{color: isActive ? '#4476f7' : '#323232'}}/>;
- case 'chat':
- return <FontAwesomeIcon icon = 'robot' size= 'lg' style = {{color: isActive ? '#4476f7' : '#323232'}}/>;
- case 'idea':
- return <FontAwesomeIcon icon = 'cloud' size= 'lg' style = {{color: isActive ? '#4476f7' : '#323232'}}/>;
- default:
- return <FontAwesomeIcon icon = 'star' size= 'lg' style = {{color: isActive ? '#4476f7' : '#323232'}}/>;
+ @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
*/
@@ -508,6 +545,7 @@ export class CollectionCardView extends CollectionSubView() {
const amCards = this.overflowAmCardsCalc(realIndex);
const isSelected = DocumentView.SelectedDocs().includes(doc);
+
const childScreenToLocal = () => {
this._forceChildXf;
const dref = this._docRefs.get(doc);
@@ -526,7 +564,7 @@ export class CollectionCardView extends CollectionSubView() {
return (
<div
key={doc[Id]}
- className={`card-item${isSelected ? '-active' : anySelected ? '-inactive' : ''}`}
+ className={`card-item${isSelected ? '-active' : anySelected ? '-inactive' : ''}`}
onPointerUp={() => {
// this turns off documentDecorations during a transition, then turns them back on afterward.
SnappingManager.SetIsResizing(this.Document[Id]);