@acorex/platform 20.9.20 → 20.9.22

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.
@@ -1241,6 +1241,7 @@ class AXPEntityMasterToolbarViewComponent {
1241
1241
  this.deviceService = inject(AXPDeviceService);
1242
1242
  this.parent = inject(AXPEntityMasterListViewComponent);
1243
1243
  this.router = inject(Router);
1244
+ this.activeRoute = inject(ActivatedRoute);
1244
1245
  this.settingsService = inject(AXPSettingsService);
1245
1246
  this.injector = inject(Injector);
1246
1247
  this.isInitializing = false;
@@ -1326,9 +1327,9 @@ class AXPEntityMasterToolbarViewComponent {
1326
1327
  }, ...(ngDevMode ? [{ debugName: "sortDefinitions" }] : /* istanbul ignore next */ []));
1327
1328
  }
1328
1329
  async ngOnInit() {
1329
- // Prefer saved settings (view/columns/sorts/filters) if available, then apply once
1330
+ // Prefer URL `view` over saved settings; fall back to settings when URL has no view.
1330
1331
  await this.loadSettings();
1331
- await this.vm.setView();
1332
+ await this.vm.setView(this.activeRoute.snapshot.queryParamMap.get('view'));
1332
1333
  await this.vm.ensureListPagingResolved();
1333
1334
  await this.runInitialListLoad();
1334
1335
  }
@@ -1374,6 +1375,7 @@ class AXPEntityMasterToolbarViewComponent {
1374
1375
  async onViewChanged(view) {
1375
1376
  await this.vm.setView(view.name);
1376
1377
  if (axpIsEntityListRoute(this.router)) {
1378
+ this.vm.markRouteQueryContextSynced(this.activeRoute.snapshot.queryParamMap, { view: view.name });
1377
1379
  axpReplaceEntityListRouteQueryParams(this.router, { view: view.name });
1378
1380
  }
1379
1381
  await this.runInitialListLoad();
@@ -1424,6 +1426,8 @@ class AXPEntityMasterToolbarViewComponent {
1424
1426
  if (!url.includes('filters=')) {
1425
1427
  return;
1426
1428
  }
1429
+ // Mark the post-strip key first so queryParamMap emission does not trigger an extra list reload.
1430
+ this.vm.markRouteQueryContextSynced(this.activeRoute.snapshot.queryParamMap, { filters: null });
1427
1431
  axpReplaceEntityListRouteQueryParams(this.router, { filters: null });
1428
1432
  }
1429
1433
  onSortQueriesChange(e) {
@@ -2063,12 +2067,22 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
2063
2067
  this.restoreExpandedRowsScheduled = false;
2064
2068
  /** Blocks deferred `replaceUrl` view sync after destroy or once details navigation has started. */
2065
2069
  this.listQueryParamSyncDisabled = false;
2070
+ /** Tracks layout so card → table can reveal rows without a second fetch. */
2071
+ this.lastListLayout = this.vm.activeListLayout();
2066
2072
  effect(() => {
2067
2073
  const grid = this.grid();
2068
2074
  if (grid) {
2069
2075
  grid.selectedRows = this.vm.selectedItems();
2070
2076
  }
2071
2077
  });
2078
+ effect(() => {
2079
+ const layout = this.vm.activeListLayout();
2080
+ const previousLayout = untracked(() => this.lastListLayout);
2081
+ this.lastListLayout = layout;
2082
+ if (layout === 'table' && previousLayout === 'card') {
2083
+ untracked(() => this.acknowledgeManualTableReady());
2084
+ }
2085
+ });
2072
2086
  this.vm.events$.subscribe(async (e) => {
2073
2087
  const refreshTargetId = e.meta?.refreshTargetId;
2074
2088
  const highlightRowId = e.meta?.highlightRowId;
@@ -2098,7 +2112,8 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
2098
2112
  }
2099
2113
  const currentViewName = this.vm.view().name;
2100
2114
  const urlView = this.activeRoute.snapshot.queryParamMap.get('view');
2101
- if (currentViewName && currentViewName !== urlView) {
2115
+ // Only fill a missing `view` query param. When URL and VM diverge, URL wins via queryParam sync.
2116
+ if (currentViewName && !urlView) {
2102
2117
  this.syncListViewQueryParam(currentViewName);
2103
2118
  }
2104
2119
  });
@@ -2143,9 +2158,13 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
2143
2158
  const resolvedView = this.vm.view().name;
2144
2159
  const currentUrlView = this.activeRoute.snapshot.queryParamMap.get('view');
2145
2160
  if (currentUrlView !== resolvedView) {
2161
+ // Mark the post-replaceUrl key before navigating so the emission does not reload without filters.
2162
+ this.vm.markRouteQueryContextSynced(this.activeRoute.snapshot.queryParamMap, { view: resolvedView });
2146
2163
  this.syncListViewQueryParam(resolvedView);
2147
2164
  }
2148
- this.vm.markRouteQueryContextSynced(this.activeRoute.snapshot.queryParamMap);
2165
+ else {
2166
+ this.vm.markRouteQueryContextSynced(this.activeRoute.snapshot.queryParamMap);
2167
+ }
2149
2168
  this.initializedFromRoute = true;
2150
2169
  this.bindExpandedRowPersistence();
2151
2170
  this.scheduleRestoreExpandedRows();
@@ -2283,6 +2302,7 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
2283
2302
  if (this.listQueryParamSyncDisabled) {
2284
2303
  return;
2285
2304
  }
2305
+ this.vm.markRouteQueryContextSynced(this.activeRoute.snapshot.queryParamMap, { view: viewName });
2286
2306
  axpReplaceEntityListRouteQueryParams(this.router, { view: viewName });
2287
2307
  });
2288
2308
  }
@@ -2293,6 +2313,8 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
2293
2313
  }
2294
2314
  if (this.vm.activeListLayout() === 'card') {
2295
2315
  await this.cardList()?.reload(resetPagination);
2316
+ // Shared DS load updates table rows via onChanged but not isRefreshCalled; prepare for a later table switch.
2317
+ this.acknowledgeManualTableReady();
2296
2318
  return;
2297
2319
  }
2298
2320
  const grid = this.grid();
@@ -2311,6 +2333,19 @@ class AXPEntityMasterListViewComponent extends AXPPageLayoutBaseComponent {
2311
2333
  await dataReady;
2312
2334
  }
2313
2335
  }
2336
+ /**
2337
+ * Manual-mode table gates the body on `isRefreshCalled` (set only by `grid.refresh()`).
2338
+ * Card loads use shared `dataSource.refresh()`, so rows/totalCount update while the gate stays closed.
2339
+ * Opening the gate here avoids an extra network refresh when switching to table.
2340
+ */
2341
+ acknowledgeManualTableReady() {
2342
+ // `isRefreshCalled` is private on AXDataTableComponent; runtime access is intentional (zero-fetch reveal).
2343
+ const grid = this.grid();
2344
+ if (!grid?.isRefreshCalled || grid.isRefreshCalled()) {
2345
+ return;
2346
+ }
2347
+ grid.isRefreshCalled.set(true);
2348
+ }
2314
2349
  /**
2315
2350
  * Waits until a `refresh()` load cycle completes (loading started, then finished with data).
2316
2351
  */