aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionCardDeckView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/collections/CollectionCardDeckView.tsx')
-rw-r--r--src/client/views/collections/CollectionCardDeckView.tsx424
1 files changed, 309 insertions, 115 deletions
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
index de46180e6..907a5a343 100644
--- a/src/client/views/collections/CollectionCardDeckView.tsx
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -2,8 +2,8 @@ import { IReactionDisposer, ObservableMap, action, computed, makeObservable, obs
import { observer } from 'mobx-react';
import * as React from 'react';
import { ClientUtils, DashColor, returnFalse, returnZero } from '../../../ClientUtils';
-import { numberRange } from '../../../Utils';
-import { Doc, NumListCast } from '../../../fields/Doc';
+import { emptyFunction, numberRange } from '../../../Utils';
+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';
@@ -19,12 +19,22 @@ import { DocumentView } from '../nodes/DocumentView';
import { GPTPopup, GPTPopupMode } from '../pdf/GPTPopup/GPTPopup';
import './CollectionCardDeckView.scss';
import { CollectionSubView } from './CollectionSubView';
+import { FieldsDropdown } from '../FieldsDropdown';
+import { Button, IconButton } from 'browndash-components';
+import { faStar } from '@fortawesome/free-solid-svg-icons';
+import { FaStar, FaHeart, FaRobot, FaCloud } from 'react-icons/fa';
+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',
+ Chat = 'chat',
None = '',
}
@observer
@@ -35,10 +45,15 @@ export class CollectionCardView extends CollectionSubView() {
private _textToDoc = new Map<string, Doc>();
@observable _forceChildXf = false;
- @observable _isLoading = false;
+ // @observable _isLoading = false;
@observable _hoveredNodeIndex = -1;
@observable _docRefs = new ObservableMap<Doc, DocumentView>();
+ _draggerRef = React.createRef<HTMLDivElement>();
@observable _maxRowCount = 10;
+ @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);
@@ -61,23 +76,32 @@ 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);
makeObservable(this);
+ this.setRegenerateCallback();
}
+ setRegenerateCallback() {
+ GPTPopup.Instance.setRegenerateCallback(this.childPairStringListAndUpdateSortDesc);
+ }
+
+ @action
+ childPairStringListAndUpdateSortDesc = async () => {
+ const sortDesc = await this.childPairStringList(); // Await the promise to get the string result
+ GPTPopup.Instance.setSortDesc(sortDesc.join());
+ GPTPopup.Instance.onSortComplete = (sortResult: string) => this.processGptOutput(sortResult);
+ };
+
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))
);
+
+
}
componentWillUnmount() {
@@ -92,6 +116,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
*/
@@ -100,42 +125,31 @@ export class CollectionCardView extends CollectionSubView() {
return (this._childDocumentWidth * length) / this._props.PanelWidth();
}
- @computed get translateWrapperX() {
- let translate = 0;
-
- if (this.inactiveDocs().length !== this.childDocsWithoutLinks.length && this.inactiveDocs().length < 10) {
- translate += this.panelWidth() / 2;
- }
- return translate;
- }
-
/**
* The child documents to be rendered-- either all of them except the Links or the docs in the currently active
* custom group
*/
@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
return regularDocs;
}
+
+
/**
- * Determines the order in which the cards will be rendered depending on the current sort type
+ * Number of rows of cards to be rendered
*/
- @computed get sortedDocs() {
- return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.layoutDoc.sortDesc));
- }
+ @computed get numRows() { return Math.ceil(this.sortedDocs.length / 10); }
@action
setHoveredNodeIndex = (index: number) => {
@@ -170,6 +184,8 @@ export class CollectionCardView extends CollectionSubView() {
* @returns
*/
rotate = (amCards: number, index: number) => {
+ if (amCards == 1) return 0;
+
const possRotate = -30 + index * (30 / ((amCards - (amCards % 2)) / 2));
const stepMag = Math.abs(-30 + (amCards / 2 - 1) * (30 / ((amCards - (amCards % 2)) / 2)));
@@ -204,27 +220,76 @@ 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, direction: 'left' | 'right') => {
+
+ 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
- // 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;
+ const amRows = Math.ceil(amCardsTotal / this._maxRowCount);
+ const rowHeight = this._props.PanelHeight( ) / amRows
+ const currRow = Math.floor((mouseY - 100) / rowHeight) //rows start at 0
- // Calculate the translation needed to align the scaled node's center with the panel's center
- const translation = middleOfPanel - scaledNodeCenter - scaledNodeWidth - scaledNodeWidth / 4;
+ if (adjustedX < 0) {
+ return 0; // Before the first column
+ }
+
+ if (amCardsTotal < this._maxRowCount) {
+ index = Math.floor(adjustedX / cardWidth);
+ }
- return translation;
+ else if (currRow != amRows -1 ){
+ index = Math.floor(adjustedX / cardWidth) + (currRow * this._maxRowCount)
+ }
+
+ else {
+ // console.log(amRows + "am rows")
+ const rowAmCards = amCardsTotal - (currRow * this._maxRowCount)
+ const offset = ((this._maxRowCount - rowAmCards ) / 2) * cardWidth
+ adjustedX = mouseX - offset
+
+ index = Math.floor(adjustedX / cardWidth) + (currRow * this._maxRowCount);
+ }
+ return index;
};
+ @action
+ onPointerMove = (e: React.PointerEvent<HTMLDivElement>) => {
+ if (DragManager.docsBeingDragged.length != 0 ) {
+ this._isACardBeingDragged = true
+
+ 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;
+ }
+ }
+ };
+
+
+ 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")
+ // 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
* front, latter cards to the back
@@ -233,38 +298,65 @@ export class CollectionCardView extends CollectionSubView() {
* @param isDesc
* @returns
*/
- sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean) => {
- if (sortType === cardSortings.None) return docs;
- docs.sort((docA, docB) => {
- const [typeA, typeB] = (() => {
+ sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean, dragIndex: number) => {
+ // 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 [DashColor(StrCast(docA.backgroundColor)).hsv().toString(), // If docA.type is undefined, use an empty string
- DashColor(StrCast(docB.backgroundColor)).hsv().toString()]; // 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)??0,
- CollectionCardView.getButtonGroup(this.cardSort_customField, docB)??0];
- 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(`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 (isDesc){
+ return out
+ }
+ return -out
+
+ });
+ // }
+
+ if (dragIndex != -1) {
+ const draggedDoc = DragManager.docsBeingDragged[0];
+ const originalIndex = docs.findIndex(doc => doc === draggedDoc);
+
+ docs.splice(originalIndex, 1);
+ docs.splice(dragIndex, 0, draggedDoc);
+ }
+
return docs;
};
+
+
+
displayDoc = (doc: Doc, screenToLocalTransform: () => Transform) => (
<DocumentView
// eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
ref={action((r: DocumentView) => r?.ContentDiv && this._docRefs.set(doc, r))}
- Document={doc}
+ Document={doc}
NativeWidth={returnZero}
NativeHeight={returnZero}
fitWidth={returnFalse}
@@ -273,10 +365,13 @@ export class CollectionCardView extends CollectionSubView() {
LayoutTemplate={this._props.childLayoutTemplate}
LayoutTemplateString={this._props.childLayoutString}
ScreenToLocalTransform={screenToLocalTransform} // makes sure the box wrapper thing is in the right spot
- isContentActive={this.isChildContentActive}
+ isContentActive={emptyFunction}
isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
PanelWidth={this.panelWidth}
PanelHeight={this.panelHeight(doc)}
+ dragAction={(this.Document.childDragAction ?? this._props.childDragAction) as dropActionType}
+ dontHideOnDrag
+ // pointerEvents={this.blockPointerEventsWhenDragging(doc)}
/>
);
@@ -286,11 +381,11 @@ export class CollectionCardView extends CollectionSubView() {
* @returns
*/
overflowAmCardsCalc = (index: number) => {
- if (this.inactiveDocs().length < this._maxRowCount) {
- return this.inactiveDocs().length;
+ if (this.sortedDocs.length < this._maxRowCount) {
+ return this.sortedDocs.length;
}
// 13 - 3 = 10
- const totalCards = this.inactiveDocs().length;
+ const totalCards = this.sortedDocs.length;
// if 9 or less
if (index < totalCards - (totalCards % 10)) {
return this._maxRowCount;
@@ -323,21 +418,17 @@ export class CollectionCardView extends CollectionSubView() {
* @returns
*/
calculateTranslateY = (isHovered: boolean, isSelected: boolean, realIndex: number, amCards: number, calcRowIndex: number) => {
- if (isSelected) return 50 * this.fitContentScale;
- const trans = isHovered ? this.translateHover(realIndex) : 0;
+ const rowHeight = this._props.PanelHeight() * this.fitContentScale / this.numRows;
+ const rowIndex = Math.trunc(realIndex / this._maxRowCount);
+ const rowToCenterShift = (this.numRows / 2) - rowIndex;
+ if (isSelected) return rowToCenterShift * rowHeight - rowHeight / 2;
+ if (amCards == 1) return 50 * this.fitContentScale;
+ // const trans = isHovered ? this.translateHover(realIndex) : 0;
+ const trans = 0;
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
@@ -378,6 +469,8 @@ export class CollectionCardView extends CollectionSubView() {
return response; // Return the response from gptImageLabel
} catch (error) {
console.log('bad things have happened');
+
+ console.log(error);
}
return '';
};
@@ -386,22 +479,38 @@ 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) => {
+
+ 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");
+
+ // 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.
*/
@@ -416,40 +525,111 @@ export class CollectionCardView extends CollectionSubView() {
/**
* 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 * 35 + amButtons * 2 * 5 + 6;
+ renderButtons = (doc: Doc, cardSort: cardSortings): 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<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` }}>
+ <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
- <button
- key={i}
- type="button"
- style={{ backgroundColor: activeButtonIndex === i ? '#4476f7' : '#323232' }} //
- onClick={() => this.toggleButton(i, doc)}
- />
+ <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>
))}
</div>
);
};
+
+ /**
+ * 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 list = StrListCast(doc.cardSort_activeIcons);
+ // doc.cardSort_activeIcons = new List<string>(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 <FontAwesomeIcon icon={icon} size="lg" style={{ color }} />;
+ };
+
/**
* Actually renders all the cards
*/
renderCards = () => {
const anySelected = this.childDocs.some(doc => DocumentView.SelectedDocs().includes(doc));
+ const isEmpty = this.childDocsWithoutLinks.length === 0;
+ const isDesc = BoolCast(this.Document.cardSort_isDesc)
+
+ console.log(this.childDocsWithoutLinks.length + "length")
+
+ if (isEmpty) {
+ return (
+ <span className="no-card-span" style={{ width: ` ${this._props.PanelWidth()}px`, height: ` ${this._props.PanelHeight()}px` }}>
+ Sorry ! There are no cards in this group
+ </span>
+ );
+ }
+
// Map sorted documents to their rendered components
return this.sortedDocs.map((doc, index) => {
- const realIndex = this.sortedDocs.filter(sortDoc => !DocumentView.SelectedDocs().includes(sortDoc)).indexOf(doc);
+ const realIndex = this.sortedDocs.indexOf(doc);
const calcRowIndex = this.overflowIndexCalc(realIndex);
const amCards = this.overflowAmCardsCalc(realIndex);
const isSelected = DocumentView.SelectedDocs().includes(doc);
+ const isDragging = DragManager.docsBeingDragged.includes(doc);
const childScreenToLocal = () => {
this._forceChildXf;
@@ -460,6 +640,12 @@ export class CollectionCardView extends CollectionSubView() {
.scale(1 / scale).rotate(!isSelected ? -this.rotate(amCards, calcRowIndex) : 0); // prettier-ignore
};
+ const translateIfSelected = () => {
+ const indexInRow = index % this._maxRowCount;
+ const rowIndex = Math.trunc(index / this._maxRowCount);
+ const rowCenterIndex = Math.min(this._maxRowCount, this.sortedDocs.length - rowIndex * this._maxRowCount)/2;
+ return (rowCenterIndex - indexInRow) * 100 - 50;
+ }
return (
<div
key={doc[Id]}
@@ -472,17 +658,17 @@ export class CollectionCardView extends CollectionSubView() {
SnappingManager.SetIsResizing(undefined);
this._forceChildXf = !this._forceChildXf;
}),
- 700
+ 900
);
}}
style={{
width: this.panelWidth(),
- height: 'max-content', // this.panelHeight(childPair.layout)(),
+ height: 'max-content',
transform: `translateY(${this.calculateTranslateY(this._hoveredNodeIndex === index, isSelected, realIndex, amCards, calcRowIndex)}px)
- translateX(${isSelected ? this.translateSelected(calcRowIndex) : this.translateOverflowX(realIndex, amCards)}px)
+ translateX(calc(${(isSelected ? translateIfSelected() : 0) + "% + " + this.translateOverflowX(realIndex, amCards)+"px"}))
rotate(${!isSelected ? this.rotate(amCards, calcRowIndex) : 0}deg)
- scale(${isSelected ? 1.25 : 1})`,
- }}
+ scale(${isSelected ? 2 : this._hoveredNodeIndex === index ? 1.05 : 1})`,
+ }}
onMouseEnter={() => this.setHoveredNodeIndex(index)}>
{this.displayDoc(doc, childScreenToLocal)}
{this.renderButtons(doc, this.cardSort)}
@@ -490,11 +676,17 @@ export class CollectionCardView extends CollectionSubView() {
);
});
};
+
render() {
+ const isEmpty = this.childDocsWithoutLinks.length === 0;
+ const transformValue = `scale(${1 / this.fitContentScale})`;
+ const heightValue = `${100 * this.fitContentScale}%`;
+
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),
@@ -502,8 +694,9 @@ export class CollectionCardView extends CollectionSubView() {
<div
className="card-wrapper"
style={{
- transform: ` scale(${1 / this.fitContentScale}) translateX(${this.translateWrapperX}px)`,
- height: `${100 * this.fitContentScale}%`,
+ ...(!isEmpty && { transform: transformValue }),
+ ...(!isEmpty && { height: heightValue }),
+ gridAutoRows: `${100 / this.numRows}%`
}}
onMouseLeave={() => this.setHoveredNodeIndex(-1)}>
{this.renderCards()}
@@ -511,4 +704,5 @@ export class CollectionCardView extends CollectionSubView() {
</div>
);
}
+
}