@acorex/platform 20.2.4-next.9 → 20.3.0-next.0

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.
@@ -28,7 +28,7 @@ import { AXFormatService, AXFormatModule } from '@acorex/core/format';
28
28
  import { AXPSessionService } from '@acorex/platform/auth';
29
29
  import { isNil, isEmpty, isEqual, cloneDeep } from 'lodash-es';
30
30
  import { AXBasePageComponent } from '@acorex/components/page';
31
- import { getChangedPaths, getSmart, AXPExpressionEvaluatorService } from '@acorex/platform/core';
31
+ import { getChangedPaths, getSmart, AXPExpressionEvaluatorService, AXPBroadcastEventService } from '@acorex/platform/core';
32
32
  import * as i6$1 from '@acorex/platform/layout/builder';
33
33
  import { AXPPageStatus, AXPWidgetContainerComponent, AXPLayoutBuilderModule } from '@acorex/platform/layout/builder';
34
34
  import { Router, ActivatedRoute } from '@angular/router';
@@ -45,6 +45,7 @@ import * as i7 from '@acorex/components/form';
45
45
  import { AXFormModule } from '@acorex/components/form';
46
46
  import * as i5$1 from '@acorex/components/tabs';
47
47
  import { AXTabsModule } from '@acorex/components/tabs';
48
+ import { Subject, takeUntil } from 'rxjs';
48
49
 
49
50
  class AXPPageLayoutBase {
50
51
  }
@@ -577,7 +578,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
577
578
  rootContext: cloneDeep(adapterContext),
578
579
  });
579
580
  },
580
- async loadPage(pageId) {
581
+ async loadPage(pageId, forceRefresh) {
581
582
  const adapter = store.adapter();
582
583
  if (!adapter) {
583
584
  throw new Error('Adapter must be loaded before loading page');
@@ -607,7 +608,7 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
607
608
  let context = {};
608
609
  if (currentPage) {
609
610
  const currentPageIndex = adapter.pages.findIndex((p) => p.id === currentPage.id);
610
- const loadResult = await adapter.pages[currentPageIndex]?.load?.(store.rootContext());
611
+ const loadResult = await adapter.pages[currentPageIndex]?.load?.({ forceRefresh });
611
612
  context = loadResult?.result ?? {};
612
613
  }
613
614
  // Set current tab to first tab of the current page (internal state only)
@@ -836,10 +837,21 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
836
837
  patchState(store, {
837
838
  previousContext: store.context(),
838
839
  });
840
+ // After successful save, force refresh the rootContext and reload the current page
841
+ try {
842
+ await this.loadPage(store.currentPage()?.id, true);
843
+ }
844
+ catch (error) {
845
+ console.error('Failed to refresh page after save', error);
846
+ }
839
847
  toastService.show({
840
848
  color: 'success',
841
- title: await translateService.translateAsync('actions.accept.title', { scope: 'general' }),
842
- content: await translateService.translateAsync('actions.accept.message', { scope: 'general' }),
849
+ title: await translateService.translateAsync('messages.generic.success.title', {
850
+ scope: 'general',
851
+ }),
852
+ content: await translateService.translateAsync('messages.generic.success.description', {
853
+ scope: 'general',
854
+ }),
843
855
  location: 'bottom-center',
844
856
  closeButton: true,
845
857
  timeOut: 3000,
@@ -851,7 +863,9 @@ const AXPLayoutDetailsViewViewModel = signalStore(withState(() => {
851
863
  });
852
864
  },
853
865
  goToListPage() {
854
- //TODO: Implement
866
+ if (store.adapter()?.exitUrl) {
867
+ router.navigate([store.adapter()?.exitUrl]);
868
+ }
855
869
  },
856
870
  };
857
871
  }));
@@ -862,6 +876,10 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
862
876
  this.adapter = input.required(...(ngDevMode ? [{ debugName: "adapter" }] : []));
863
877
  //
864
878
  this.vm = inject(AXPLayoutDetailsViewViewModel);
879
+ this.router = inject(Router);
880
+ this.route = inject(ActivatedRoute);
881
+ this.eventService = inject(AXPBroadcastEventService);
882
+ this.destroyed$ = new Subject();
865
883
  this.form = viewChild('form', ...(ngDevMode ? [{ debugName: "form" }] : []));
866
884
  this.widgetContainer = viewChild(AXPWidgetContainerComponent, ...(ngDevMode ? [{ debugName: "widgetContainer" }] : []));
867
885
  this.footerPrimaryActions = signal([], ...(ngDevMode ? [{ debugName: "footerPrimaryActions" }] : []));
@@ -886,10 +904,31 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
886
904
  this.footerSecondaryActions.set(footerSecondaryActions);
887
905
  }, ...(ngDevMode ? [{ debugName: "#FooterActionsEffect" }] : []));
888
906
  }
907
+ /**
908
+ * Append timestamp query param to trigger router to re-run guards/resolvers
909
+ */
910
+ async refreshLayout() {
911
+ const router = this.router;
912
+ const route = this.route;
913
+ const now = Date.now();
914
+ await router.navigate([], {
915
+ relativeTo: route,
916
+ queryParams: { _ts: now },
917
+ queryParamsHandling: 'merge',
918
+ });
919
+ }
889
920
  async ngOnInit() {
890
921
  await super.ngOnInit();
891
922
  //
892
923
  await this.vm.load(this.adapter());
924
+ this.eventService
925
+ .listen('REFRESH_LAYOUT')
926
+ .pipe(takeUntil(this.destroyed$))
927
+ .subscribe((e) => {
928
+ if (e.data.name == this.vm.adapter()?.name) {
929
+ this.refreshLayout();
930
+ }
931
+ });
893
932
  }
894
933
  async ngAfterViewInit() {
895
934
  const listWidget = (await this.widgetContainer()?.find('page-list_table'));
@@ -905,6 +944,8 @@ class AXPLayoutDetailsViewComponent extends AXPPageLayoutBaseComponent {
905
944
  }
906
945
  ngOnDestroy() {
907
946
  this.onSelectionChangeSubscription?.unsubscribe();
947
+ this.destroyed$.next();
948
+ this.destroyed$.complete();
908
949
  }
909
950
  #FooterActionsEffect;
910
951
  handleOnContextChanged(e) {