@sapui5/sap.fe.core 1.102.1 → 1.102.4

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.
@@ -247,22 +247,12 @@ class TransactionHelper {
247
247
  delete mParameters.data["@odata.context"];
248
248
  }
249
249
  if (aNonComputedVisibleKeyFields.length > 0) {
250
- const oTransientListBinding = oModel.bindList(oMainListBinding.getPath(), oMainListBinding.getContext(), [], [], {
251
- $$updateGroupId: "submitLater"
252
- });
253
- oTransientListBinding.refreshInternal = function () {
254
- /* */
255
- };
256
- oNewDocumentContext = oTransientListBinding.create(mParameters.data, true);
257
- return that._launchDialogWithKeyFields(
258
- oMainListBinding,
259
- oTransientListBinding,
260
- oNewDocumentContext,
261
- aNonComputedVisibleKeyFields,
262
- oModel,
263
- mParameters,
264
- messageHandler
265
- );
250
+ return that
251
+ ._launchDialogWithKeyFields(oMainListBinding, aNonComputedVisibleKeyFields, oModel, mParameters, messageHandler)
252
+ .then((oResult) => {
253
+ oNewDocumentContext = oResult.newContext;
254
+ return oResult;
255
+ });
266
256
  } else {
267
257
  let onBeforeCreatePromise;
268
258
  if (mParameters.beforeCreateCallBack) {
@@ -310,7 +300,7 @@ class TransactionHelper {
310
300
  // for instance, on cancel of create dialog, the promise is rejected
311
301
  // a return here would restore the promise chain and result in errors while routing
312
302
  // solution - reject here as well
313
- if (oError && oError.bDeleteTransientContext && oNewDocumentContext.isTransient()) {
303
+ if (oError && oError.bDeleteTransientContext && oNewDocumentContext?.isTransient()) {
314
304
  // This is a workaround suggested by model as Context.delete results in an error
315
305
  // TODO: remove the $direct once model resolves this issue
316
306
  // this line shows the expected console error Uncaught (in promise) Error: Request canceled: POST Travel; group: submitLater
@@ -828,7 +818,7 @@ class TransactionHelper {
828
818
  });
829
819
  })
830
820
  .catch(function (err: any) {
831
- return messageHandler.showMessages().then(function () {
821
+ return messageHandler.showMessages({ concurrentEditFlag: true }).then(function () {
832
822
  return Promise.reject(err);
833
823
  });
834
824
  })
@@ -1398,20 +1388,22 @@ class TransactionHelper {
1398
1388
  }
1399
1389
  }
1400
1390
 
1401
- _launchDialogWithKeyFields(
1402
- oListBinding: any,
1403
- oTransientListBinding: any,
1404
- oTransientContext: any,
1405
- mFields: any,
1406
- oModel: any,
1407
- mParameters: any,
1408
- messageHandler: any
1409
- ) {
1391
+ _launchDialogWithKeyFields(oListBinding: any, mFields: any, oModel: any, mParameters: any, messageHandler: any) {
1410
1392
  // eslint-disable-next-line @typescript-eslint/no-this-alias
1411
1393
  const that = this;
1412
1394
  let oDialog: Dialog;
1413
1395
  const oParentControl = mParameters.parentControl,
1414
1396
  bSuccess = false;
1397
+
1398
+ // Create a fake (transient) listBinding and context, just for the binding context of the dialog
1399
+ const oTransientListBinding = oModel.bindList(oListBinding.getPath(), oListBinding.getContext(), [], [], {
1400
+ $$updateGroupId: "submitLater"
1401
+ });
1402
+ oTransientListBinding.refreshInternal = function () {
1403
+ /* */
1404
+ };
1405
+ const oTransientContext = oTransientListBinding.create(mParameters.data, true);
1406
+
1415
1407
  return new Promise(function (resolve: (value: any) => void, reject: (reason?: any) => void) {
1416
1408
  const sFragmentName = "sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog";
1417
1409
  const oFragment = XMLTemplateProcessor.loadTemplate(sFragmentName, "fragment"),
@@ -1518,6 +1510,7 @@ class TransactionHelper {
1518
1510
  type: "Emphasized",
1519
1511
  press: function (oEvent: any) {
1520
1512
  const oCreateButton = oEvent.getSource();
1513
+ let oNewDocumentContext: any;
1521
1514
  oCreateButton.setEnabled(false);
1522
1515
  BusyLocker.lock(oDialog);
1523
1516
  mParameters.bIsCreateDialog = true;
@@ -1543,18 +1536,33 @@ class TransactionHelper {
1543
1536
  return onBeforeCreatePromise;
1544
1537
  })
1545
1538
  .then(function () {
1546
- const oPromise = that.onAfterCreateCompletion(
1547
- oTransientListBinding,
1548
- oTransientContext,
1549
- mParameters
1539
+ const transientData = oTransientContext.getObject();
1540
+ const createData: any = {};
1541
+ Object.keys(transientData).forEach(function (sPropertyPath: string) {
1542
+ const oProperty = oMetaModel.getObject(`${sMetaPath}/${sPropertyPath}`);
1543
+ // ensure navigation properties are not part of the payload, deep create not supported
1544
+ if (oProperty && oProperty.$kind === "NavigationProperty") {
1545
+ return;
1546
+ }
1547
+ createData[sPropertyPath] = transientData[sPropertyPath];
1548
+ });
1549
+ oNewDocumentContext = oListBinding.create(
1550
+ createData,
1551
+ true,
1552
+ mParameters.createAtEnd,
1553
+ mParameters.inactive
1550
1554
  );
1551
- oModel.submitBatch("submitLater");
1555
+
1556
+ const oPromise = that.onAfterCreateCompletion(oListBinding, oNewDocumentContext, mParameters);
1557
+
1552
1558
  return oPromise;
1553
1559
  })
1554
1560
  .then(function (oResponse: any) {
1555
1561
  if (!oResponse || (oResponse && oResponse.bKeepDialogOpen !== true)) {
1562
+ oResponse = oResponse ?? {};
1556
1563
  oDialog.setBindingContext(null as any);
1557
1564
  oDialog.close();
1565
+ oResponse.newContext = oNewDocumentContext;
1558
1566
  resolve(oResponse);
1559
1567
  }
1560
1568
  })
@@ -1578,6 +1586,7 @@ class TransactionHelper {
1578
1586
  // show footer as per UX guidelines when dialog is not open
1579
1587
  (oDialog.getBindingContext("internal") as InternalModelContext)?.setProperty("isCreateDialogOpen", false);
1580
1588
  oDialog.destroy();
1589
+ oTransientListBinding.destroy();
1581
1590
  if (!bSuccess) {
1582
1591
  reject({
1583
1592
  bDeleteTransientContext: true,
@@ -1620,48 +1629,53 @@ class TransactionHelper {
1620
1629
  });
1621
1630
  }
1622
1631
  onAfterCreateCompletion(oListBinding: any, oNewDocumentContext: any, mParameters: any) {
1623
- let fnResolve: Function, fnReject: Function;
1624
- const oPromise = new Promise(function (resolve, reject) {
1632
+ let fnResolve: Function;
1633
+ const oPromise = new Promise<boolean>((resolve) => {
1625
1634
  fnResolve = resolve;
1626
- fnReject = reject;
1627
1635
  });
1628
- // eslint-disable-next-line @typescript-eslint/no-this-alias
1629
- const that = this;
1630
- // Workaround suggested by OData model v4 colleagues
1631
- const fnCreateCompleted = function (oEvent: any) {
1636
+
1637
+ const fnCreateCompleted = (oEvent: any) => {
1632
1638
  const oContext = oEvent.getParameter("context"),
1633
1639
  bSuccess = oEvent.getParameter("success");
1634
1640
  if (oContext === oNewDocumentContext) {
1635
- oListBinding.detachCreateCompleted(fnCreateCompleted, that);
1636
- if (!bSuccess) {
1637
- const oError: any = { bDeleteTransientContext: false };
1638
- if (!mParameters.keepTransientContextOnFailed) {
1639
- // the context is deleted
1641
+ oListBinding.detachCreateCompleted(fnCreateCompleted, this);
1642
+ fnResolve(bSuccess);
1643
+ }
1644
+ };
1645
+ const fnSafeContextCreated = () => {
1646
+ oNewDocumentContext
1647
+ .created()
1648
+ .then(undefined, function () {
1649
+ Log.trace("transient creation context deleted");
1650
+ })
1651
+ .catch(function (contextError: any) {
1652
+ Log.trace("transient creation context deletion error", contextError);
1653
+ });
1654
+ };
1640
1655
 
1641
- // this is needed to avoid console errors TO be checked with model colleagues
1642
- oContext
1643
- .created()
1644
- .then(undefined, function () {
1645
- Log.trace("transient creation context deleted");
1646
- })
1647
- .catch(function (oError: any) {
1648
- Log.trace("transient creation context deletion error", oError);
1649
- });
1650
- if (!mParameters.bIsCreateDialog) {
1651
- // if current state is transient (...), browser will come back to previous state
1652
- oError.navigateBackFromTransientState = true;
1653
- oError.bDeleteTransientContext = true;
1654
- fnReject(oError);
1655
- }
1656
+ oListBinding.attachCreateCompleted(fnCreateCompleted, this);
1657
+
1658
+ return oPromise.then((bSuccess: boolean) => {
1659
+ if (!bSuccess) {
1660
+ const oError: any = { bDeleteTransientContext: false };
1661
+ if (!mParameters.keepTransientContextOnFailed) {
1662
+ // Cancel the pending POST and delete the context in the listBinding
1663
+ fnSafeContextCreated(); // To avoid a 'request cancelled' error in the console
1664
+ oListBinding.resetChanges();
1665
+ oListBinding.getModel().resetChanges(oListBinding.getUpdateGroupId());
1666
+
1667
+ if (!mParameters.bIsCreateDialog) {
1668
+ // if current state is transient (...), browser will come back to previous state
1669
+ oError.navigateBackFromTransientState = true;
1670
+ oError.bDeleteTransientContext = true;
1671
+ throw oError;
1656
1672
  }
1657
- fnResolve({ bKeepDialogOpen: true });
1658
- } else {
1659
- return oContext.created().then(fnResolve);
1660
1673
  }
1674
+ return { bKeepDialogOpen: true };
1675
+ } else {
1676
+ return oNewDocumentContext.created();
1661
1677
  }
1662
- };
1663
- oListBinding.attachCreateCompleted(fnCreateCompleted, this);
1664
- return oPromise;
1678
+ });
1665
1679
  }
1666
1680
  /**
1667
1681
  * Retrieves the name of the NewAction to be executed.