@alfresco/adf-process-services-cloud 9.2.0-35569866168 → 9.2.0-35636294809

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.
@@ -3,7 +3,7 @@ import { inject, Injectable, InjectionToken, EventEmitter, DestroyRef, Output, I
3
3
  import * as i3 from '@alfresco/adf-core';
4
4
  import { AppConfigService, JwtHelperService, OAuth2Service, TranslationService, DataTableSchema, UserPreferencesService, UserPreferenceValues, CustomEmptyContentTemplateDirective, ObjectDataTableAdapter, ColumnsSelectorComponent, MainMenuDataTableTemplateDirective, EmptyContentComponent, NoContentTemplateDirective, LoadingContentTemplateDirective, DataTableComponent, AdfDateFnsAdapter, MOMENT_DATE_FORMATS, AuthenticationService, StorageService, IconModule, DateFnsUtils, ADF_DATE_FORMATS, FullNamePipe, InitialUsernamePipe, FormService, FormModel, FormFieldTypes, ROW_ID_PREFIX, FormBaseComponent, ADF_DISPLAY_TEXT_SETTINGS, WidgetVisibilityService, FormExpressionService, UploadWidgetContentLinkModel, FormEvent, FormOutcomeModel, ConfirmDialogComponent, FormRulesEvent, FormOutcomeEvent, FormRendererComponent, ToolbarDividerComponent, ToolbarComponent, FormatSpacePipe, NotificationService, DownloadService, WidgetComponent, ThumbnailService, ErrorWidgetComponent, LocalizedDatePipe, UploadDirective, ContentLinkModel, ErrorMessageModel, DEFAULT_DATE_FORMAT, FormFieldValueFormatterService, ADF_TYPED_VALUE_FORMATTING_ENABLED, FormFieldEvent, SelectFilterInputComponent, FormRenderingService, DynamicComponentMapper, CardViewUpdateService, ClipboardService, CardViewTextItemModel, CardViewSelectItemModel, CardViewDatetimeItemModel, CardViewDateItemModel, CardViewArrayItemModel, CardViewComponent, CustomLoadingContentTemplateDirective, isOutcomeButtonVisible, InplaceFormInputComponent, BaseViewerWidgetComponent, BaseDisplayTextWidgetComponent, ObjectDataColumn, ObjectDataRow, FormBaseModule, provideTranslations } from '@alfresco/adf-core';
5
5
  import { from, EMPTY, isObservable, of, Subject, throwError, BehaviorSubject, combineLatest, defer, merge, asapScheduler, firstValueFrom, forkJoin, catchError as catchError$1 } from 'rxjs';
6
- import { map, take, switchMap, catchError, tap, filter, finalize, debounceTime, shareReplay, mergeMap, distinctUntilChanged, expand, reduce, mapTo, concatMap } from 'rxjs/operators';
6
+ import { map, take, switchMap, catchError, distinctUntilChanged, filter, tap, finalize, debounceTime, shareReplay, mergeMap, expand, reduce, mapTo, concatMap } from 'rxjs/operators';
7
7
  import { AlfrescoApiService, NodeAction, ContentNodeSelectorComponent, NodesApiService, ContentService, ContentNodeSelectorPanelService, NewVersionUploaderService, NewVersionUploaderDataAction, ContentMetadataComponent, AlfrescoViewerComponent } from '@alfresco/adf-content-services';
8
8
  import { AdfHttpClient } from '@alfresco/adf-core/api';
9
9
  import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
@@ -1479,15 +1479,20 @@ class TaskListCloudComponent extends BaseTaskListCloudComponent {
1479
1479
  this.rows = [];
1480
1480
  this.isReloadingSubject$ = new BehaviorSubject(false);
1481
1481
  this.isLoading$ = combineLatest([this.isLoadingPreferences$, this.isReloadingSubject$]).pipe(map(([isLoadingPreferences, isReloading]) => isLoadingPreferences || isReloading));
1482
+ // incremented on every explicit reload() so it always refetches, even when the computed request is unchanged
1483
+ this.reloadNonce = 0;
1482
1484
  this.fetchProcessesTrigger$ = new Subject();
1483
- combineLatest([this.isLoadingPreferences$, this.isColumnSchemaCreated$, this.fetchProcessesTrigger$])
1484
- .pipe(tap(() => this.isReloadingSubject$.next(true)), filter(([isLoadingPreferences, isColumnSchemaCreated]) => !isLoadingPreferences && !!isColumnSchemaCreated), switchMap(() => {
1485
+ combineLatest([this.isLoadingPreferences$.pipe(distinctUntilChanged()), this.isColumnSchemaCreated$, this.fetchProcessesTrigger$])
1486
+ .pipe(filter(([isLoadingPreferences, isColumnSchemaCreated]) => !isLoadingPreferences && !!isColumnSchemaCreated), map(([, , reloadNonce]) => {
1487
+ const requestNode = this.searchApiMethod === 'POST' ? this.createTaskListRequestNode() : this.createRequestNode();
1488
+ return { reloadNonce, requestNode, requestKey: JSON.stringify(requestNode) };
1489
+ }),
1490
+ // skip identical requests triggered by schema/preference re-emissions, but always refetch on an explicit reload()
1491
+ distinctUntilChanged((previous, current) => previous.reloadNonce === current.reloadNonce && previous.requestKey === current.requestKey), tap(() => this.isReloadingSubject$.next(true)), switchMap(({ requestNode }) => {
1485
1492
  if (this.searchApiMethod === 'POST') {
1486
- const requestNode = this.createTaskListRequestNode();
1487
1493
  return this.taskListCloudService.fetchTaskList(requestNode).pipe(take(1));
1488
1494
  }
1489
1495
  else {
1490
- const requestNode = this.createRequestNode();
1491
1496
  this.requestNode = requestNode;
1492
1497
  return this.taskListCloudService.getTaskByRequest(requestNode);
1493
1498
  }
@@ -1513,7 +1518,7 @@ class TaskListCloudComponent extends BaseTaskListCloudComponent {
1513
1518
  }
1514
1519
  reload() {
1515
1520
  this.isReloadingSubject$.next(true);
1516
- this.fetchProcessesTrigger$.next();
1521
+ this.fetchProcessesTrigger$.next(++this.reloadNonce);
1517
1522
  }
1518
1523
  createTaskListRequestNode() {
1519
1524
  const requestNode = {
@@ -8688,6 +8693,7 @@ class FormCloudComponent extends FormBaseComponent {
8688
8693
  }
8689
8694
  refreshFormData(previousData = []) {
8690
8695
  const snapshot = this.snapshotRuntimeState();
8696
+ const variableSnapshot = this.snapshotVariablesRuntimeState();
8691
8697
  this.mergeProcessVariables(this.data ?? []);
8692
8698
  this.form = this.parseForm(this.formCloudRepresentationJSON);
8693
8699
  if (!this.form) {
@@ -8695,6 +8701,7 @@ class FormCloudComponent extends FormBaseComponent {
8695
8701
  }
8696
8702
  const changedFieldIds = this.getChangedFieldIds(previousData, this.data ?? []);
8697
8703
  this.restoreRuntimeState(this.form, snapshot, changedFieldIds);
8704
+ this.restoreVariablesRuntimeState(this.form, variableSnapshot, changedFieldIds, this.data ?? []);
8698
8705
  this.setCheckParentVisibilityForValidationOnFields();
8699
8706
  this.visibilityService.refreshVisibility(this.form, this.data);
8700
8707
  this.form.validateForm();
@@ -8716,7 +8723,8 @@ class FormCloudComponent extends FormBaseComponent {
8716
8723
  const byName = new Map();
8717
8724
  for (const variable of [...existing, ...updates]) {
8718
8725
  if (variable?.name) {
8719
- byName.set(variable.name, variable);
8726
+ const name = variable.name.startsWith('variables.') ? variable.name.slice('variables.'.length) : variable.name;
8727
+ byName.set(name, variable);
8720
8728
  }
8721
8729
  }
8722
8730
  this.formCloudRepresentationJSON.processVariables = Array.from(byName.values());
@@ -8766,6 +8774,45 @@ class FormCloudComponent extends FormBaseComponent {
8766
8774
  field.visibilityCondition = prior.visibilityCondition;
8767
8775
  }
8768
8776
  }
8777
+ snapshotVariablesRuntimeState() {
8778
+ const snapshot = new Map();
8779
+ if (!this.form?.variables?.length) {
8780
+ return snapshot;
8781
+ }
8782
+ for (const variable of this.form.variables) {
8783
+ snapshot.set(variable.id, {
8784
+ value: variable.value,
8785
+ runtimeSet: variable.runtimeSet
8786
+ });
8787
+ }
8788
+ return snapshot;
8789
+ }
8790
+ restoreVariablesRuntimeState(form, snapshot, changedVariableNames, updates) {
8791
+ if (!form?.variables?.length || !snapshot.size) {
8792
+ return;
8793
+ }
8794
+ for (const variable of form.variables) {
8795
+ const prior = snapshot.get(variable.id);
8796
+ if (!prior?.runtimeSet) {
8797
+ continue;
8798
+ }
8799
+ const identifiers = [variable.id, variable.name, `variables.${variable.name}`];
8800
+ const changedIdentifier = identifiers.find((identifier) => changedVariableNames.has(identifier));
8801
+ /*
8802
+ Form variables are shared with the stored representation, so a value set at runtime survives
8803
+ the re-parse on its own. It has to be cleared explicitly once the refresh brings a newer value,
8804
+ otherwise the runtime value would mask every later update from the server.
8805
+ */
8806
+ if (changedIdentifier) {
8807
+ const refreshed = updates.find((update) => update?.name === changedIdentifier);
8808
+ variable.value = refreshed ? refreshed.value : variable.value;
8809
+ variable.runtimeSet = false;
8810
+ continue;
8811
+ }
8812
+ variable.value = prior.value;
8813
+ variable.runtimeSet = true;
8814
+ }
8815
+ }
8769
8816
  recomputeVisibleOutcomes() {
8770
8817
  const outcomes = this.form?.outcomes;
8771
8818
  if (!outcomes) {
@@ -9936,12 +9983,25 @@ class DropdownCloudWidgetComponent extends WidgetComponent {
9936
9983
  this.dropdownControl.setValue(value, { emitEvent: false });
9937
9984
  });
9938
9985
  this.setupDropdown();
9939
- this.formService.onFormVariableChanged.subscribe(({ field }) => {
9940
- if (field.id === this.field.id) {
9986
+ /*
9987
+ Wired once: both read `this.field` when they emit, so they survive every later setup run.
9988
+ Re-wiring them on each setup would stack subscriptions and duplicate the events they raise.
9989
+ */
9990
+ this.subscribeToInputChanges();
9991
+ this.initFilter();
9992
+ this.formService.onFormVariableChanged.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ field }) => {
9993
+ if (this.isDependentOnChangedVariable(field)) {
9941
9994
  this.setupDropdown();
9942
9995
  }
9943
9996
  });
9944
9997
  }
9998
+ isDependentOnChangedVariable(field) {
9999
+ const variableName = this.field?.variableConfig?.variableName;
10000
+ if (field.id === this.field.id) {
10001
+ return true;
10002
+ }
10003
+ return this.isVariableOptionType && !!variableName && field?.variableConfig?.variableName === variableName;
10004
+ }
9945
10005
  computeReadOnlyDisplayValue() {
9946
10006
  const value = this.field.value;
9947
10007
  const isFormattableValue = value != null && (typeof value !== 'string' || this.formatter.hasFormatter(this.field.type));
@@ -9983,8 +10043,6 @@ class DropdownCloudWidgetComponent extends WidgetComponent {
9983
10043
  this.updateOptions();
9984
10044
  this.setFormControlValue();
9985
10045
  this.updateFormControlState();
9986
- this.subscribeToInputChanges();
9987
- this.initFilter();
9988
10046
  this.handleErrors();
9989
10047
  }
9990
10048
  subscribeToInputChanges() {
@@ -10060,10 +10118,8 @@ class DropdownCloudWidgetComponent extends WidgetComponent {
10060
10118
  persistFieldOptionsFromVariable() {
10061
10119
  const optionsPath = this.field?.variableConfig?.optionsPath ?? this.defaultVariableOptionPath;
10062
10120
  const variableName = this.field?.variableConfig?.variableName;
10063
- const processVariables = this.field?.form?.processVariables;
10064
- const formVariables = this.field?.form?.variables;
10065
- const dropdownOptions = this.getOptionsFromVariable(processVariables, formVariables, variableName);
10066
- if (dropdownOptions) {
10121
+ const dropdownOptions = this.field?.form?.resolveVariableValue(variableName);
10122
+ if (dropdownOptions != null) {
10067
10123
  const formVariableOptions = this.getOptionsFromPath(dropdownOptions, optionsPath);
10068
10124
  this.updateOptions(formVariableOptions);
10069
10125
  this.resetInvalidValue();
@@ -10112,15 +10168,6 @@ class DropdownCloudWidgetComponent extends WidgetComponent {
10112
10168
  }
10113
10169
  return option;
10114
10170
  }
10115
- getOptionsFromVariable(processVariables, formVariables, variableName) {
10116
- const processVariableDropdownOptions = this.getVariableValueByName(processVariables, variableName);
10117
- const formVariableDropdownOptions = this.getVariableValueByName(formVariables, variableName);
10118
- return processVariableDropdownOptions ?? formVariableDropdownOptions;
10119
- }
10120
- getVariableValueByName(variables, variableName) {
10121
- return variables?.find((variable) => variable?.name === `variables.${variableName}` || variable?.name === variableName)
10122
- ?.value;
10123
- }
10124
10171
  persistFieldOptionsFromRestApi() {
10125
10172
  if (this.isValidRestConfig) {
10126
10173
  this.resetRestApiErrorMessage();
@@ -15770,15 +15817,20 @@ class DataTableWidgetComponent extends WidgetComponent {
15770
15817
  this.defaultResponseProperty = 'data';
15771
15818
  this.pathParserHelper = new DataTablePathParserHelper();
15772
15819
  this.formCloudService = inject(FormCloudService);
15820
+ this.destroyRef = inject(DestroyRef);
15773
15821
  }
15774
15822
  ngOnInit() {
15775
15823
  this.init();
15776
- this.formService.onFormVariableChanged.subscribe(({ field }) => {
15777
- if (field.id === this.field.id) {
15824
+ this.formService.onFormVariableChanged.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ field }) => {
15825
+ if (this.isDependentOnChangedVariable(field)) {
15778
15826
  this.init();
15779
15827
  }
15780
15828
  });
15781
15829
  }
15830
+ isDependentOnChangedVariable(field) {
15831
+ const variableName = this.field?.variableConfig?.variableName;
15832
+ return field.id === this.field.id || (!!variableName && field?.variableConfig?.variableName === variableName);
15833
+ }
15782
15834
  init() {
15783
15835
  this.dataTableLoadFailed = false;
15784
15836
  this.setPreviewState();
@@ -15818,15 +15870,7 @@ class DataTableWidgetComponent extends WidgetComponent {
15818
15870
  return this.pathParserHelper.retrieveDataFromPath(rowsData, optionsPath);
15819
15871
  }
15820
15872
  getDataFromVariable() {
15821
- const processVariables = this.field?.form?.processVariables;
15822
- const formVariables = this.field?.form?.variables;
15823
- const processVariableData = this.getVariableValueByName(processVariables, this.variableName);
15824
- const formVariableData = this.getVariableValueByName(formVariables, this.variableName);
15825
- return processVariableData ?? formVariableData;
15826
- }
15827
- getVariableValueByName(variables, variableName) {
15828
- return variables?.find((variable) => variable?.name === `variables.${variableName}` || variable?.name === variableName)
15829
- ?.value;
15873
+ return this.field?.form?.resolveVariableValue(this.variableName);
15830
15874
  }
15831
15875
  setPreviewState() {
15832
15876
  this.previewState = this.formCloudService.getPreviewState();