feat: add spatial workspace refactor design document and implement dirty tracking for layout persistence.
This commit is contained in:
@@ -26,6 +26,7 @@ export class LayoutCard implements LayoutCardState {
|
|||||||
public store: LayoutStore;
|
public store: LayoutStore;
|
||||||
public dragStartX: number = 0;
|
public dragStartX: number = 0;
|
||||||
public dragStartY: number = 0;
|
public dragStartY: number = 0;
|
||||||
|
public isDirty: boolean = false;
|
||||||
private dragOffset: { x: number, y: number } | null = null;
|
private dragOffset: { x: number, y: number } | null = null;
|
||||||
|
|
||||||
constructor(id: string, store: LayoutStore, initialData: Partial<LayoutCardState> = {}, ref: HTMLElement | null = null) {
|
constructor(id: string, store: LayoutStore, initialData: Partial<LayoutCardState> = {}, ref: HTMLElement | null = null) {
|
||||||
@@ -56,18 +57,23 @@ export class LayoutCard implements LayoutCardState {
|
|||||||
this.update({
|
this.update({
|
||||||
x: newX,
|
x: newX,
|
||||||
y: newY
|
y: newY
|
||||||
});
|
}, { markDirty: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
finishDrag() {
|
finishDrag() {
|
||||||
this.dragOffset = null;
|
this.dragOffset = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
update(changes: Partial<LayoutCardState>) {
|
update(changes: Partial<LayoutCardState>, options: { markDirty?: boolean } = {}) {
|
||||||
Object.assign(this, changes);
|
Object.assign(this, changes);
|
||||||
if (changes.width !== undefined || changes.height !== undefined) {
|
if (changes.width !== undefined || changes.height !== undefined) {
|
||||||
this.recalculateRadii();
|
this.recalculateRadii();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.markDirty) {
|
||||||
|
this.isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
this.applyTransform();
|
this.applyTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +187,7 @@ export class LayoutCard implements LayoutCardState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
snapTo(x: number, y: number) {
|
snapTo(x: number, y: number) {
|
||||||
this.update({ x, y });
|
this.update({ x, y }, { markDirty: true });
|
||||||
|
|
||||||
if (!this.ref)
|
if (!this.ref)
|
||||||
return;
|
return;
|
||||||
@@ -273,9 +279,15 @@ export class LayoutStore {
|
|||||||
height,
|
height,
|
||||||
z
|
z
|
||||||
}, ref);
|
}, ref);
|
||||||
|
|
||||||
|
// If it was a saved layout, it's not dirty.
|
||||||
|
if (!saved) {
|
||||||
|
card.isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
this.items.set(id, card);
|
this.items.set(id, card);
|
||||||
} else {
|
} else {
|
||||||
card.update({ width, height });
|
card.update({ width, height }, { markDirty: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always update ref and ensure transform is applied
|
// Always update ref and ensure transform is applied
|
||||||
@@ -334,7 +346,7 @@ export class LayoutStore {
|
|||||||
|
|
||||||
// Assign new Z-indices
|
// Assign new Z-indices
|
||||||
for (const card of cards) {
|
for (const card of cards) {
|
||||||
card.update({ z: this.zCounter++ });
|
card.update({ z: this.zCounter++ }, { markDirty: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +383,7 @@ export class LayoutStore {
|
|||||||
for (const [id, card] of this.items) {
|
for (const [id, card] of this.items) {
|
||||||
const saved = this.savedLayouts.get(id);
|
const saved = this.savedLayouts.get(id);
|
||||||
if (saved) {
|
if (saved) {
|
||||||
card.update(saved);
|
card.update(saved, { markDirty: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,7 +391,10 @@ export class LayoutStore {
|
|||||||
async saveLayout() {
|
async saveLayout() {
|
||||||
if (!this.tenantId || !this.viewId) return;
|
if (!this.tenantId || !this.viewId) return;
|
||||||
|
|
||||||
const entries = Array.from(this.items.values()).map(card => ({
|
const dirtyCards = Array.from(this.items.values()).filter(card => card.isDirty);
|
||||||
|
if (dirtyCards.length === 0) return;
|
||||||
|
|
||||||
|
const entries = dirtyCards.map(card => ({
|
||||||
documentId: card.id,
|
documentId: card.id,
|
||||||
centerX: card.x,
|
centerX: card.x,
|
||||||
centerY: card.y,
|
centerY: card.y,
|
||||||
@@ -393,5 +408,10 @@ export class LayoutStore {
|
|||||||
viewId: this.viewId,
|
viewId: this.viewId,
|
||||||
entries
|
entries
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Reset dirty flag for saved cards
|
||||||
|
for (const card of dirtyCards) {
|
||||||
|
card.isDirty = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user