@apia/execution 4.0.31 → 4.0.32

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.
package/dist/index.d.ts CHANGED
@@ -2742,7 +2742,7 @@ type TEntity = {
2742
2742
  title: string;
2743
2743
  readOnly: boolean;
2744
2744
  separator: string;
2745
- associations: Associations[];
2745
+ associations: Association[];
2746
2746
  date: {
2747
2747
  label: string;
2748
2748
  toolTip: string;
@@ -2825,10 +2825,13 @@ type PoolId = {
2825
2825
  poolName: string;
2826
2826
  canUpdate: boolean;
2827
2827
  };
2828
- type Associations = {
2828
+ type Association = {
2829
2829
  asocName: string;
2830
2830
  asocId: string;
2831
2831
  asocRelName: string;
2832
+ errorNameMessage?: string;
2833
+ errorRelNameMessage?: string;
2834
+ focusTarget?: boolean;
2832
2835
  };
2833
2836
 
2834
2837
  declare class Entity {
@@ -2840,13 +2843,15 @@ declare class Entity {
2840
2843
  get name(): string | undefined;
2841
2844
  private hasInited;
2842
2845
  init(): Promise<void>;
2846
+ addAssociation(): void;
2843
2847
  getConfirmParams(): any;
2844
- loadCategories: () => Promise<void>;
2845
- loadPools: () => Promise<void>;
2846
- loadAssociations: () => Promise<void>;
2848
+ protected loadCategories: () => Promise<void>;
2849
+ protected loadPools: () => Promise<void>;
2850
+ protected loadAssociations: () => Promise<void>;
2847
2851
  private parseRows;
2848
- deleteRow(): void;
2849
- addRow(): void;
2852
+ deleteAssociation(): void;
2853
+ deleteVisibility(id: string): void;
2854
+ validateAssociations(): boolean;
2850
2855
  }
2851
2856
 
2852
2857
  type TObservations = {
@@ -3404,6 +3409,7 @@ type EditorEvents = 'onChange';
3404
3409
  declare class Editor extends TranslatableField<TApiaEditorProperties, string> {
3405
3410
  fireEvent(eventName: EditorEvents, options?: TFireEventOptions): Promise<boolean>;
3406
3411
  protected isValidValue(): boolean;
3412
+ protected getSynchronizePostConfiguration(value: string): IApiaApiPostConfig<any>;
3407
3413
  }
3408
3414
 
3409
3415
  declare class File$1 extends FieldWithAttribute<TApiaFileProperties> {
@@ -3726,6 +3732,7 @@ declare class Select extends FieldWithAttribute<TApiaSelectProperties, string, T
3726
3732
 
3727
3733
  declare class Textarea extends TranslatableField<TApiaTextareaProperties, string> {
3728
3734
  protected isValidValue(): boolean;
3735
+ protected getSynchronizePostConfiguration(value: string): IApiaApiPostConfig<any>;
3729
3736
  }
3730
3737
 
3731
3738
  declare class Title extends Field<TApiaTitleProperties> {
package/dist/index.js CHANGED
@@ -4,12 +4,13 @@ import xml2js from 'xml2js';
4
4
  import he from 'he';
5
5
  import { parseBooleans, parseNumbers } from 'xml2js/lib/processors';
6
6
  import QueryString from 'qs';
7
- import { arrayOrArray, EventEmitter as EventEmitter$1, isTrue, toBoolean, downloadUrl, addBoundary, formatMessage, parseAsSize, shallowEqual as shallowEqual$1, Mutex, awaitTime, noNaN as noNaN$1, getDateFormat, uniqueId, parseXMLRequestResponse, Url, postNavigation } from '@apia/util';
7
+ import { arrayOrArray, EventEmitter as EventEmitter$1, isTrue, toBoolean, downloadUrl, addBoundary, formatMessage, parseAsSize, shallowEqual as shallowEqual$1, Mutex, awaitTime, noNaN as noNaN$1, getDateFormat, decodeBase64ToUtf8 as decodeBase64ToUtf8$1, uniqueId, parseXMLRequestResponse, Url, postNavigation } from '@apia/util';
8
8
  import { Cell, TableController, Row, FocusControllerPlugin } from '@apia/table2-controller';
9
9
  import dayjs from 'dayjs';
10
10
  import customParseFormat from 'dayjs/plugin/customParseFormat';
11
11
  import { MobXTree } from '@apia/tree2-controller';
12
12
  import { Scheduler } from '@apia/scheduler-controller';
13
+ import { ApiaUtil } from '@apia/components';
13
14
 
14
15
  const deepEqual = (a, b) => {
15
16
  if (Object.is(a, b))
@@ -683,7 +684,7 @@ function makeApiaUrl(execution, props) {
683
684
  if (props?.queryString && props.queryString.includes("timestamp=") || queryString?.includes("timestamp=")) {
684
685
  timestamp = "";
685
686
  }
686
- const contextWord = CONTEXT.replaceAll("/", "");
687
+ const contextWord = CONTEXT.replace(/^\/?(.+?)\/?$/, "$1");
687
688
  actualAjaxUrl = actualAjaxUrl.match(
688
689
  new RegExp(`^(?:(?:/?${contextWord})?/)?(.+)$`)
689
690
  )?.[1];
@@ -1990,6 +1991,11 @@ class Editor extends TranslatableField {
1990
1991
  isValidValue() {
1991
1992
  return !!new DOMParser().parseFromString(this.getValue(), "text/html").documentElement.textContent;
1992
1993
  }
1994
+ getSynchronizePostConfiguration(value) {
1995
+ const conf = super.getSynchronizePostConfiguration(value);
1996
+ conf.postData.clearValues = "true";
1997
+ return conf;
1998
+ }
1993
1999
  }
1994
2000
 
1995
2001
  var __defProp$j = Object.defineProperty;
@@ -2250,7 +2256,8 @@ class UploaderModalController {
2250
2256
  isValid = false;
2251
2257
  }
2252
2258
  if (c.value.trim() === "") {
2253
- c.errorMessage = getLabel(this.api.execution, "msgReqField").text;
2259
+ if (!c.errorMessage)
2260
+ c.errorMessage = getLabel(this.api.execution, "msgReqField").text;
2254
2261
  isValid = false;
2255
2262
  }
2256
2263
  }
@@ -2828,7 +2835,7 @@ class UploaderApi extends EventEmitter$1 {
2828
2835
  if (isOneClickUploadEnabled(
2829
2836
  this.execution,
2830
2837
  this.modalConfig.oneClickUpload
2831
- ) && !this.state.versioningFile) {
2838
+ )) {
2832
2839
  if (langId && translatingFile)
2833
2840
  void this.confirmDropModal({ langId, translatingFile });
2834
2841
  else
@@ -5254,15 +5261,21 @@ class Input extends TranslatableField {
5254
5261
  const inFmt = getDateFormat(options?.format);
5255
5262
  const outFmt = getDateFormat();
5256
5263
  if (typeof newValue === "string") {
5257
- const d = dayjs(newValue.trim(), inFmt, true);
5258
- if (!d.isValid() && newValue.trim() !== "") {
5259
- this.state.validation.errorMessage = getLabel(
5260
- this.getForm().execution,
5261
- "msgInvalidDate"
5262
- ).text;
5263
- this.validDate = false;
5264
+ if (newValue.match(/^\d+$/)) {
5265
+ const value = new Date(Number.parseInt(newValue));
5266
+ const d = dayjs(value);
5267
+ return super.setValue(d.isValid() ? d.format(outFmt) : "", options);
5268
+ } else {
5269
+ const d = dayjs(newValue.trim(), inFmt, true);
5270
+ if (!d.isValid() && newValue.trim() !== "") {
5271
+ this.state.validation.errorMessage = getLabel(
5272
+ this.getForm().execution,
5273
+ "msgInvalidDate"
5274
+ ).text;
5275
+ this.validDate = false;
5276
+ }
5277
+ return super.setValue(d.isValid() ? d.format(outFmt) : "", options);
5264
5278
  }
5265
- return super.setValue(d.isValid() ? d.format(outFmt) : "", options);
5266
5279
  }
5267
5280
  if (newValue instanceof Date) {
5268
5281
  const d = dayjs(newValue);
@@ -5389,6 +5402,11 @@ class Textarea extends TranslatableField {
5389
5402
  isValidValue() {
5390
5403
  return !!String(this.getValue()).trim();
5391
5404
  }
5405
+ getSynchronizePostConfiguration(value) {
5406
+ const conf = super.getSynchronizePostConfiguration(value);
5407
+ conf.postData.clearValues = "true";
5408
+ return conf;
5409
+ }
5392
5410
  }
5393
5411
 
5394
5412
  class Title extends Field {
@@ -7253,7 +7271,9 @@ class CustomComponent {
7253
7271
  }
7254
7272
  }
7255
7273
  arrayOrArray(o.attribute).forEach((c) => {
7256
- this._state.attributes[c.name] = arrayOrArray(JSON.parse(atob(c.values)));
7274
+ this._state.attributes[c.name] = arrayOrArray(
7275
+ JSON.parse(decodeBase64ToUtf8$1(c.values))
7276
+ );
7257
7277
  });
7258
7278
  arrayOrArray(o.property).forEach((c) => {
7259
7279
  this._state.properties[c.name] = c.value;
@@ -8215,6 +8235,24 @@ class Entity {
8215
8235
  }
8216
8236
  }
8217
8237
  }
8238
+ addAssociation() {
8239
+ const id = String(uniqueId());
8240
+ this.state.associations.push({
8241
+ asocId: id,
8242
+ asocName: "",
8243
+ asocRelName: ""
8244
+ });
8245
+ const row = new Row(id);
8246
+ row.build({
8247
+ id: String(uniqueId()),
8248
+ cells: [{ colName: "name" }, { colName: "relName" }],
8249
+ isSelected: true
8250
+ });
8251
+ this.controller.body.addRow(row);
8252
+ this.controller.setSelection([
8253
+ this.controller.body.getState("rows").length
8254
+ ]);
8255
+ }
8218
8256
  getConfirmParams() {
8219
8257
  const result = {
8220
8258
  busEntSta: this.state?.status.value ?? ""
@@ -8262,27 +8300,46 @@ class Entity {
8262
8300
  return newRow;
8263
8301
  });
8264
8302
  }
8265
- deleteRow() {
8303
+ deleteAssociation() {
8266
8304
  const selectedRows = this.controller.getState("selection");
8267
- [...selectedRows.values()].map((row, rowIndex) => {
8268
- this.state.associations = this.state?.associations.filter((_, idx) => rowIndex !== idx) ?? [];
8305
+ const lastIdx = Array.from(selectedRows).pop()?.index;
8306
+ [...selectedRows.values()].forEach((row) => {
8307
+ this.state.associations = this.state?.associations.filter((_, idx) => row.index !== idx) ?? [];
8269
8308
  this.controller.body.removeRow(row);
8270
8309
  });
8310
+ if (lastIdx)
8311
+ this.controller.setSelection([lastIdx - 1]);
8271
8312
  }
8272
- addRow() {
8273
- const id = String(uniqueId());
8274
- this.state.associations.push({
8275
- asocId: id,
8276
- asocName: "",
8277
- asocRelName: ""
8278
- });
8279
- const row = new Row(id);
8280
- row.build({
8281
- id: String(uniqueId()),
8282
- cells: [{ colName: "name" }, { colName: "relName" }],
8283
- isSelected: true
8284
- });
8285
- this.controller.body.addRow(row);
8313
+ deleteVisibility(id) {
8314
+ if (this.state) {
8315
+ this.state.visibilities = this.state.visibilities.filter(
8316
+ (c) => c.poolId !== id
8317
+ );
8318
+ }
8319
+ }
8320
+ validateAssociations() {
8321
+ if (this.state?.associations.length === 0)
8322
+ return true;
8323
+ if (this.state) {
8324
+ const invalidAssociations = this.state.associations.filter(
8325
+ (c) => !c.asocName || !c.asocRelName
8326
+ );
8327
+ if (invalidAssociations.length > 0) {
8328
+ invalidAssociations.forEach((c, idx) => {
8329
+ c.errorRelNameMessage = "";
8330
+ c.errorNameMessage = "";
8331
+ c.focusTarget = void 0;
8332
+ if (idx === 0)
8333
+ c.focusTarget = true;
8334
+ if (c.asocName === "")
8335
+ c.errorNameMessage = labels.errorFieldRequired(this.execution);
8336
+ if (c.asocRelName === "")
8337
+ c.errorRelNameMessage = labels.errorFieldRequired(this.execution);
8338
+ });
8339
+ return false;
8340
+ }
8341
+ }
8342
+ return true;
8286
8343
  }
8287
8344
  }
8288
8345
 
@@ -8904,17 +8961,21 @@ async function defaultConfirm(execution, status) {
8904
8961
  setAjaxFormResponse(execution, checkConfirmEntity.data?.form);
8905
8962
  }
8906
8963
  const url = arrayOrArray(confirmResponse.data.actions?.action.param)[1];
8907
- const c = new Url(url);
8908
- getWindow(execution).location.assign(
8909
- makeApiaUrl(execution, {
8910
- ajaxUrl: c.base,
8911
- action: c.getParameter("action")
8912
- })
8913
- );
8914
- (getWindow(execution)?.top?.ApiaUtil).notifications.notify({
8915
- message: confirmResponse?.data?.load?.text?.label,
8916
- type: "success"
8917
- });
8964
+ if (url === "callNavigateClose") {
8965
+ ApiaUtil.instance.tabs.currentTab.close(true);
8966
+ } else {
8967
+ const c = new Url(url);
8968
+ getWindow(execution).location.assign(
8969
+ makeApiaUrl(execution, {
8970
+ ajaxUrl: c.base,
8971
+ action: c.getParameter("action")
8972
+ })
8973
+ );
8974
+ (getWindow(execution)?.top?.ApiaUtil).notifications.notify({
8975
+ message: confirmResponse?.data?.load?.text?.label,
8976
+ type: "success"
8977
+ });
8978
+ }
8918
8979
  }
8919
8980
  return {
8920
8981
  ...status,
@@ -9237,6 +9298,9 @@ class Execution extends EventEmitter$1 {
9237
9298
  if (validationResult !== true) {
9238
9299
  return validationResult;
9239
9300
  }
9301
+ if (this.executionConfig?.isEntity && !this.entity.validateAssociations()) {
9302
+ return false;
9303
+ }
9240
9304
  const isValid = status !== void 0 || await this.fireEvents("onSubmit");
9241
9305
  const canConfirm = this.executionConfig?.canConfirm && isValid === true;
9242
9306
  if (canConfirm) {