@vectoriox/iox-builder 1.4.57 → 1.4.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -309,6 +309,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
309
309
|
type: Injectable
|
|
310
310
|
}] });
|
|
311
311
|
|
|
312
|
+
/**
|
|
313
|
+
* SymbolRegistryService — in-memory store for org-level symbols.
|
|
314
|
+
*
|
|
315
|
+
* Loaded once per page by PageUiComponent alongside the page layout.
|
|
316
|
+
* Scoped to PageUiComponent.providers[] via IoxBuilderModule — one registry per builder instance.
|
|
317
|
+
*/
|
|
318
|
+
class SymbolRegistryService {
|
|
319
|
+
constructor() {
|
|
320
|
+
this.symbols = new Map();
|
|
321
|
+
/** symbolIds that have a live reusable block in the DB — used to guard isDetachedSymbol. */
|
|
322
|
+
this.blockSymbolIds = new Set();
|
|
323
|
+
}
|
|
324
|
+
setSymbols(symbols) {
|
|
325
|
+
this.symbols.clear();
|
|
326
|
+
for (const s of symbols) {
|
|
327
|
+
this.symbols.set(s.id, s);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
getSymbol(id) {
|
|
331
|
+
return this.symbols.get(id);
|
|
332
|
+
}
|
|
333
|
+
getAll() {
|
|
334
|
+
return Array.from(this.symbols.values());
|
|
335
|
+
}
|
|
336
|
+
upsert(symbol) {
|
|
337
|
+
this.symbols.set(symbol.id, symbol);
|
|
338
|
+
}
|
|
339
|
+
remove(id) {
|
|
340
|
+
this.symbols.delete(id);
|
|
341
|
+
}
|
|
342
|
+
/** Set the symbolIds that have a live reusable block. Called on page load. */
|
|
343
|
+
setBlockSymbolIds(ids) {
|
|
344
|
+
this.blockSymbolIds = new Set(ids);
|
|
345
|
+
}
|
|
346
|
+
/** Returns true only when the symbol has a live backing reusable block. */
|
|
347
|
+
isBlockSymbol(id) {
|
|
348
|
+
return this.blockSymbolIds.has(id);
|
|
349
|
+
}
|
|
350
|
+
/** Remove a symbolId from the block-backed set (called when a block is deleted). */
|
|
351
|
+
removeBlockSymbolId(id) {
|
|
352
|
+
this.blockSymbolIds.delete(id);
|
|
353
|
+
}
|
|
354
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SymbolRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
355
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SymbolRegistryService }); }
|
|
356
|
+
}
|
|
357
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SymbolRegistryService, decorators: [{
|
|
358
|
+
type: Injectable
|
|
359
|
+
}] });
|
|
360
|
+
|
|
312
361
|
function deepCloneNode(node) {
|
|
313
362
|
const clone = JSON.parse(JSON.stringify(node));
|
|
314
363
|
regenerateIds(clone);
|
|
@@ -320,8 +369,9 @@ function regenerateIds(node) {
|
|
|
320
369
|
(node.children || []).forEach(regenerateIds);
|
|
321
370
|
}
|
|
322
371
|
class DragEngineService {
|
|
323
|
-
constructor(registry) {
|
|
372
|
+
constructor(registry, symbolRegistry) {
|
|
324
373
|
this.registry = registry;
|
|
374
|
+
this.symbolRegistry = symbolRegistry;
|
|
325
375
|
// ── Drop-zone registry ────────────────────────────────────
|
|
326
376
|
this.ids = [];
|
|
327
377
|
this.elMap = new Map();
|
|
@@ -385,7 +435,9 @@ class DragEngineService {
|
|
|
385
435
|
}
|
|
386
436
|
else {
|
|
387
437
|
// Full block object { node, symbolId, syncInstances } or bare ComponentNode.
|
|
388
|
-
|
|
438
|
+
// Prefer symbol.node (always up-to-date) over block.node (original snapshot).
|
|
439
|
+
const symbolNode = data.symbolId ? this.symbolRegistry.getSymbol(data.symbolId)?.node : null;
|
|
440
|
+
const nodeData = (symbolNode ?? data.node ?? data);
|
|
389
441
|
const cloned = deepCloneNode(nodeData);
|
|
390
442
|
if (data.syncInstances && data.symbolId) {
|
|
391
443
|
cloned.symbolId = data.symbolId;
|
|
@@ -417,10 +469,13 @@ class DragEngineService {
|
|
|
417
469
|
// produces a fully independent node, preventing shared CSS rules.
|
|
418
470
|
// The panel may supply a bare ComponentNode OR a block wrapper object
|
|
419
471
|
// { node, symbolId, syncInstances } — extract the node first.
|
|
420
|
-
|
|
472
|
+
// Prefer symbol.node (always up-to-date) over block.node (original snapshot).
|
|
473
|
+
const blk = item;
|
|
474
|
+
const symbolNode2 = blk.symbolId ? this.symbolRegistry.getSymbol(blk.symbolId)?.node : null;
|
|
475
|
+
const nodeData = (symbolNode2 ?? blk.node ?? item);
|
|
421
476
|
const cloned = deepCloneNode(nodeData);
|
|
422
|
-
if (
|
|
423
|
-
cloned.symbolId =
|
|
477
|
+
if (blk.syncInstances && blk.symbolId) {
|
|
478
|
+
cloned.symbolId = blk.symbolId;
|
|
424
479
|
}
|
|
425
480
|
children.splice(insertIndex, 0, cloned);
|
|
426
481
|
cdr.detectChanges();
|
|
@@ -992,12 +1047,12 @@ class DragEngineService {
|
|
|
992
1047
|
}
|
|
993
1048
|
return children.length;
|
|
994
1049
|
}
|
|
995
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DragEngineService, deps: [{ token: ComponentRegistryService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1050
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DragEngineService, deps: [{ token: ComponentRegistryService }, { token: SymbolRegistryService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
996
1051
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DragEngineService }); }
|
|
997
1052
|
}
|
|
998
1053
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: DragEngineService, decorators: [{
|
|
999
1054
|
type: Injectable
|
|
1000
|
-
}], ctorParameters: () => [{ type: ComponentRegistryService }] });
|
|
1055
|
+
}], ctorParameters: () => [{ type: ComponentRegistryService }, { type: SymbolRegistryService }] });
|
|
1001
1056
|
|
|
1002
1057
|
/**
|
|
1003
1058
|
* Page-scoped registry that holds the current page's data sources.
|
|
@@ -1640,41 +1695,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImpo
|
|
|
1640
1695
|
type: Injectable
|
|
1641
1696
|
}] });
|
|
1642
1697
|
|
|
1643
|
-
/**
|
|
1644
|
-
* SymbolRegistryService — in-memory store for org-level symbols.
|
|
1645
|
-
*
|
|
1646
|
-
* Loaded once per page by PageUiComponent alongside the page layout.
|
|
1647
|
-
* Scoped to PageUiComponent.providers[] via IoxBuilderModule — one registry per builder instance.
|
|
1648
|
-
*/
|
|
1649
|
-
class SymbolRegistryService {
|
|
1650
|
-
constructor() {
|
|
1651
|
-
this.symbols = new Map();
|
|
1652
|
-
}
|
|
1653
|
-
setSymbols(symbols) {
|
|
1654
|
-
this.symbols.clear();
|
|
1655
|
-
for (const s of symbols) {
|
|
1656
|
-
this.symbols.set(s.id, s);
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
getSymbol(id) {
|
|
1660
|
-
return this.symbols.get(id);
|
|
1661
|
-
}
|
|
1662
|
-
getAll() {
|
|
1663
|
-
return Array.from(this.symbols.values());
|
|
1664
|
-
}
|
|
1665
|
-
upsert(symbol) {
|
|
1666
|
-
this.symbols.set(symbol.id, symbol);
|
|
1667
|
-
}
|
|
1668
|
-
remove(id) {
|
|
1669
|
-
this.symbols.delete(id);
|
|
1670
|
-
}
|
|
1671
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SymbolRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1672
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SymbolRegistryService }); }
|
|
1673
|
-
}
|
|
1674
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.11", ngImport: i0, type: SymbolRegistryService, decorators: [{
|
|
1675
|
-
type: Injectable
|
|
1676
|
-
}] });
|
|
1677
|
-
|
|
1678
1698
|
// Virtual trait → composed CSS property helpers.
|
|
1679
1699
|
//
|
|
1680
1700
|
// Several style traits are "virtual" — they don't map 1:1 to a CSS property but
|
|
@@ -2947,7 +2967,11 @@ class OverlayComponent {
|
|
|
2947
2967
|
return !!this.selectEntry?.node?.symbolId;
|
|
2948
2968
|
}
|
|
2949
2969
|
get isDetachedSymbol() {
|
|
2950
|
-
|
|
2970
|
+
const node = this.selectEntry?.node;
|
|
2971
|
+
if (!node || node.symbolId || !node.detachedSymbolId)
|
|
2972
|
+
return false;
|
|
2973
|
+
// Only show the re-link button when the backing block still exists.
|
|
2974
|
+
return this.symbolRegistry.isBlockSymbol(node.detachedSymbolId);
|
|
2951
2975
|
}
|
|
2952
2976
|
get linkedSymbolName() {
|
|
2953
2977
|
const id = this.selectEntry?.node?.symbolId;
|
|
@@ -3878,8 +3902,10 @@ class BuilderComponent {
|
|
|
3878
3902
|
if (payload.sourceId === 'blocks-panel') {
|
|
3879
3903
|
// Reusable block from the palette — may be a bare ComponentNode or a
|
|
3880
3904
|
// block wrapper { name, node, syncInstances, symbolId }. Extract the node.
|
|
3905
|
+
// Prefer symbol.node (always up-to-date) over block.node (original snapshot).
|
|
3881
3906
|
const data = item;
|
|
3882
|
-
const
|
|
3907
|
+
const symbolNode = data.symbolId ? this.symbolRegistry.getSymbol(data.symbolId)?.node : null;
|
|
3908
|
+
const nodeData = (symbolNode ?? data.node ?? data);
|
|
3883
3909
|
const clone = this.deepCloneWithNewIds(nodeData);
|
|
3884
3910
|
if (data.syncInstances && data.symbolId) {
|
|
3885
3911
|
clone.symbolId = data.symbolId;
|