directual-web-components-v2 3.11.335 → 3.11.337

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.js CHANGED
@@ -19497,6 +19497,11 @@ function ElementAction(props) {
19497
19497
  if (action.actionSubmit) {
19498
19498
  console.log("onSubmit");
19499
19499
  onSubmit(res => {
19500
+ if (res === false) {
19501
+ setLoading(false);
19502
+ finish && finish(false);
19503
+ return;
19504
+ }
19500
19505
  console.log("finish onSubmit", res);
19501
19506
  console.log("payload => " + action.endpoint);
19502
19507
  console.log(payload);
@@ -19669,6 +19674,11 @@ function ElementText(props) {
19669
19674
  if (action.actionSubmit) {
19670
19675
  console.log("onSubmit");
19671
19676
  onSubmit(res => {
19677
+ if (res === false) {
19678
+ setLoading(false);
19679
+ finish && finish(false);
19680
+ return;
19681
+ }
19672
19682
  console.log("finish onSubmit", res);
19673
19683
  console.log("payload => " + action.endpoint);
19674
19684
  console.log(payload);
@@ -19961,6 +19971,7 @@ function FpsForm2(props) {
19961
19971
  const isSocketUpdateRef = React.useRef(false);
19962
19972
  const restoredStepRef = React.useRef(null);
19963
19973
  const isAutoSubmittingRef = React.useRef(false);
19974
+ const initialObjectIdRef = React.useRef(edditingOn ? _$1__default.get(data, "data[0].id") : null);
19964
19975
  function usePrevious(value) {
19965
19976
  const ref = React.useRef();
19966
19977
  React.useEffect(() => {
@@ -20025,7 +20036,9 @@ function FpsForm2(props) {
20025
20036
  return newModel;
20026
20037
  }
20027
20038
  React.useEffect(() => {
20028
- if (_$1__default.get(model, "id") && _$1__default.get(data, "data[0].id") && _$1__default.get(model, "id") !== _$1__default.get(data, "data[0].id")) {
20039
+ const _incomingId = _$1__default.get(data, "data[0].id");
20040
+ if (initialObjectIdRef.current && _incomingId && initialObjectIdRef.current !== _incomingId) {
20041
+ console.warn('[SOCKET GUARD] Отклонён апдейт для чужого объекта:', _incomingId, '(наш:', initialObjectIdRef.current + ')');
20029
20042
  return;
20030
20043
  }
20031
20044
  const timestampToISO = timestamp => {
@@ -20055,15 +20068,21 @@ function FpsForm2(props) {
20055
20068
  }, {});
20056
20069
  const newExtendedModel = _extends({}, gatherDefaults(), _$1__default.get(data, "data[0]"), convertedDates, convertedBools);
20057
20070
  setExtendedModel(newExtendedModel);
20058
- let saveSate = _extends({}, state);
20071
+ let saveSate = _extends({}, stateRef.current);
20059
20072
  const newModel = _extends({}, flatternModel(_extends({}, gatherDefaults(), _$1__default.get(data, "data[0]"), convertedDates, convertedBools)));
20060
- if (!_$1__default.isEqual(newModel, model)) {
20073
+ if (!_$1__default.isEqual(newModel, originalModelRef.current)) {
20061
20074
  submitDebouncedRef.current.cancel();
20062
- console.log('[SOCKET MODEL LOG] === МОДЕЛЬ ОБНОВЛЕНА СОКЕТОМ ===');
20063
- console.log('[SOCKET MODEL LOG] Старая модель:', JSON.parse(JSON.stringify(model)));
20064
- console.log('[SOCKET MODEL LOG] Новая модель:', JSON.parse(JSON.stringify(newModel)));
20075
+ const userChangedFields = Object.keys(model).filter(key => !_$1__default.isEqual(model[key], originalModelRef.current[key]));
20076
+ const mergedModel = _extends({}, newModel);
20077
+ userChangedFields.forEach(key => {
20078
+ mergedModel[key] = model[key];
20079
+ });
20080
+ console.log('[SOCKET MODEL LOG] === СОКЕТ: ОБНОВЛЕНИЕ МОДЕЛИ ===');
20081
+ console.log('[SOCKET MODEL LOG] Серверная модель:', JSON.parse(JSON.stringify(newModel)));
20082
+ console.log('[SOCKET MODEL LOG] Изменённые пользователем поля (сохранены):', userChangedFields);
20083
+ console.log('[SOCKET MODEL LOG] Итоговая модель:', JSON.parse(JSON.stringify(mergedModel)));
20065
20084
  isSocketUpdateRef.current = true;
20066
- setModel(newModel);
20085
+ setModel(mergedModel);
20067
20086
  setOriginalModel(newModel);
20068
20087
  }
20069
20088
  setOriginalExtendedModel(newExtendedModel);
@@ -20448,6 +20467,9 @@ function FpsForm2(props) {
20448
20467
  if (autoSubmit) {
20449
20468
  console.log('[AUTOSUBMIT LOG] Устанавливаем state перед отправкой:', JSON.parse(JSON.stringify(localState)));
20450
20469
  }
20470
+ if (localModel.id && initialObjectIdRef.current && localModel.id !== initialObjectIdRef.current) {
20471
+ console.error('[SUBMIT ID MISMATCH] id в модели:', localModel.id, '!= initialObjectId:', initialObjectIdRef.current, '— возможна подмена объекта!', JSON.parse(JSON.stringify(localModel)));
20472
+ }
20451
20473
  setState(_extends({}, localState));
20452
20474
  setLoading(true);
20453
20475
  const endpoint = _$1__default.get(data, "sl");
@@ -20509,7 +20531,7 @@ function FpsForm2(props) {
20509
20531
  }, stateUpdate));
20510
20532
  }
20511
20533
  if (submitKeepModel && !resetModel) {
20512
- modelUpdate = _extends({}, model, modelToSend, modelUpdate);
20534
+ modelUpdate = _extends({}, currentModel, modelToSend, modelUpdate);
20513
20535
  } else if (resetModel) {
20514
20536
  modelUpdate = {};
20515
20537
  extendedModelUpdate = {};
@@ -21077,6 +21099,10 @@ function FpsForm2(props) {
21077
21099
  currentStep: currentStep,
21078
21100
  refreshOptions: refreshOptions,
21079
21101
  model: model,
21102
+ modelRef: modelRef,
21103
+ extendedModelRef: extendedModelRef,
21104
+ stateRef: stateRef,
21105
+ edditingOn: edditingOn,
21080
21106
  checkHidden: checkHidden,
21081
21107
  dict: dict,
21082
21108
  extendedModel: extendedModel,
@@ -21146,6 +21172,10 @@ function FpsForm2(props) {
21146
21172
  refreshOptions: refreshOptions,
21147
21173
  currentStep: currentStep,
21148
21174
  model: model,
21175
+ modelRef: modelRef,
21176
+ extendedModelRef: extendedModelRef,
21177
+ stateRef: stateRef,
21178
+ edditingOn: edditingOn,
21149
21179
  userDebug: userDebug,
21150
21180
  setOriginalModel: setOriginalModel,
21151
21181
  originalExtendedModel: originalExtendedModel,
@@ -21187,6 +21217,10 @@ function RenderStep(props) {
21187
21217
  editModelAL,
21188
21218
  originalModel,
21189
21219
  model,
21220
+ modelRef,
21221
+ extendedModelRef,
21222
+ stateRef,
21223
+ edditingOn,
21190
21224
  checkHidden,
21191
21225
  userDebug,
21192
21226
  dict,
@@ -21217,21 +21251,40 @@ function RenderStep(props) {
21217
21251
  if (ignoreResponse) return;
21218
21252
  try {
21219
21253
  const response = JSON.parse(content);
21254
+ const currentModel = modelRef && modelRef.current || model;
21255
+ const currentExtendedModel = extendedModelRef && extendedModelRef.current || extendedModel;
21256
+ const currentState = stateRef && stateRef.current || state;
21220
21257
  if (!_$1.isEmpty(_$1__default.get(response, "state"))) {
21221
21258
  const stateUpdate = _$1__default.get(response, "state");
21222
- setState(_extends({}, state, stateUpdate));
21259
+ setState(_extends({}, currentState, stateUpdate));
21223
21260
  }
21224
21261
  if (!_$1.isEmpty(_$1__default.get(response, "object"))) {
21225
- const modelUpdate = _$1__default.get(response, "object");
21226
- setModel(_extends({}, model, modelUpdate));
21227
- setOriginalModel(_extends({}, model, modelUpdate));
21228
- setOriginalExtendedModel(_extends({}, extendedModel, modelUpdate));
21262
+ let modelUpdate = _$1__default.get(response, "object");
21263
+ if (edditingOn && currentModel.id) {
21264
+ if (modelUpdate.id && modelUpdate.id !== currentModel.id) {
21265
+ console.warn('[callEndpointPOST] Отклонена попытка подмены id модели:', currentModel.id, '->', modelUpdate.id);
21266
+ }
21267
+ modelUpdate = _extends({}, modelUpdate, {
21268
+ id: currentModel.id
21269
+ });
21270
+ }
21271
+ setModel(_extends({}, currentModel, modelUpdate));
21272
+ setOriginalModel(_extends({}, currentModel, modelUpdate));
21273
+ setOriginalExtendedModel(_extends({}, currentExtendedModel, modelUpdate));
21229
21274
  }
21230
21275
  if (!_$1.isEmpty(_$1__default.get(response, "model"))) {
21231
- const modelUpdate = _$1__default.get(response, "model");
21232
- setModel(_extends({}, model, modelUpdate));
21233
- setOriginalModel(_extends({}, model, modelUpdate));
21234
- setOriginalExtendedModel(_extends({}, extendedModel, modelUpdate));
21276
+ let modelUpdate = _$1__default.get(response, "model");
21277
+ if (edditingOn && currentModel.id) {
21278
+ if (modelUpdate.id && modelUpdate.id !== currentModel.id) {
21279
+ console.warn('[callEndpointPOST] Отклонена попытка подмены id модели:', currentModel.id, '->', modelUpdate.id);
21280
+ }
21281
+ modelUpdate = _extends({}, modelUpdate, {
21282
+ id: currentModel.id
21283
+ });
21284
+ }
21285
+ setModel(_extends({}, currentModel, modelUpdate));
21286
+ setOriginalModel(_extends({}, currentModel, modelUpdate));
21287
+ setOriginalExtendedModel(_extends({}, currentExtendedModel, modelUpdate));
21235
21288
  }
21236
21289
  if (!_$1.isEmpty(_$1__default.get(response, "redirect")) && !_$1.isEmpty(_$1__default.get(response, "redirect.target"))) {
21237
21290
  let delay = 0;
@@ -26650,6 +26703,8 @@ function Comments(props) {
26650
26703
  handleRoute
26651
26704
  } = props;
26652
26705
  const lang = locale ? locale.length == 3 ? locale : 'ENG' : 'ENG';
26706
+ const buttonTexts = _$1__default.get(data, "params.buttonTexts") || {};
26707
+ const t = (key, fallback) => buttonTexts[key] || fallback;
26653
26708
  const [comments, setComments] = React.useState(_$1__default.get(data, "data") || []);
26654
26709
  const [loading, setLoading] = React.useState(false);
26655
26710
  const [error, setError] = React.useState('');
@@ -26702,9 +26757,10 @@ function Comments(props) {
26702
26757
  return /*#__PURE__*/React__default.createElement("div", {
26703
26758
  className: styles$N.comments + " FPS_COMMENTS"
26704
26759
  }, /*#__PURE__*/React__default.createElement(CommentsHeader, _extends({
26705
- header: dict[lang].comments.comments,
26760
+ header: t('headerText', dict[lang].comments.comments),
26706
26761
  counter: (comments || []).length
26707
26762
  }, props)), allowSend && /*#__PURE__*/React__default.createElement(AddComment, _extends({}, props, {
26763
+ t: t,
26708
26764
  lang: lang,
26709
26765
  loading: loading,
26710
26766
  sendComment: sendComment,
@@ -26716,6 +26772,7 @@ function Comments(props) {
26716
26772
  }, error), /*#__PURE__*/React__default.createElement("div", {
26717
26773
  className: styles$N.commentsList
26718
26774
  }, comments.filter(comment => !_$1__default.get(comment, _$1__default.get(data, "params._replyField")) || _$1__default.get(comment, _$1__default.get(data, "params._replyField")) == 'root').map(comment => /*#__PURE__*/React__default.createElement(Comment, _extends({}, props, {
26775
+ t: t,
26719
26776
  sendComment: sendComment,
26720
26777
  updateCommentText: updateCommentText,
26721
26778
  lang: lang,
@@ -26739,7 +26796,8 @@ function Comment(props) {
26739
26796
  allowSend,
26740
26797
  allowEdit,
26741
26798
  sendComment,
26742
- updateCommentText
26799
+ updateCommentText,
26800
+ t
26743
26801
  } = props;
26744
26802
  const [addReply, setAddReply] = React.useState(false);
26745
26803
  const [isEditing, setIsEditing] = React.useState(false);
@@ -26819,13 +26877,13 @@ function Comment(props) {
26819
26877
  className: styles$N.commentWrapperAssignTo + " " + (isResoled ? styles$N.taskResolved : "") + " FPS_COMMENT_WRAPPER__ASSIGN"
26820
26878
  }, isAssignedToMe ? /*#__PURE__*/React__default.createElement("span", null, dict[lang].comments.assignedToMe) : /*#__PURE__*/React__default.createElement("span", null, dict[lang].comments.assignedTo, " ", /*#__PURE__*/React__default.createElement("b", null, assigneName)), isResoled ? /*#__PURE__*/React__default.createElement("span", {
26821
26879
  className: "icon icon-done"
26822
- }, dict[lang].comments.taskResolved, " ", formatDate(resolvedDate, formatResolvedDate)) : isAssignedToMe ? /*#__PURE__*/React__default.createElement(Button, {
26880
+ }, t('taskResolvedText', dict[lang].comments.taskResolved), " ", formatDate(resolvedDate, formatResolvedDate)) : isAssignedToMe ? /*#__PURE__*/React__default.createElement(Button, {
26823
26881
  loading: localLoading,
26824
26882
  onClick: resolveTask,
26825
26883
  small: true,
26826
26884
  height: 32,
26827
26885
  icon: "done"
26828
- }, dict[lang].comments.resolveTask) : ''), /*#__PURE__*/React__default.createElement("div", {
26886
+ }, t('resolveTaskText', dict[lang].comments.resolveTask)) : ''), /*#__PURE__*/React__default.createElement("div", {
26829
26887
  className: styles$N.commentBody
26830
26888
  }, parent && /*#__PURE__*/React__default.createElement("div", {
26831
26889
  className: styles$N.commentParent + " icon icon-arrowRight small"
@@ -26863,11 +26921,11 @@ function Comment(props) {
26863
26921
  height: 32,
26864
26922
  accent: true,
26865
26923
  disabled: !editText
26866
- }, dict[lang].comments.save), /*#__PURE__*/React__default.createElement(Button, {
26924
+ }, t('saveText', dict[lang].comments.save)), /*#__PURE__*/React__default.createElement(Button, {
26867
26925
  onClick: cancelEdit,
26868
26926
  small: true,
26869
26927
  height: 32
26870
- }, dict[lang].comments.cancel))) : /*#__PURE__*/React__default.createElement("div", {
26928
+ }, t('cancelText', dict[lang].comments.cancel)))) : /*#__PURE__*/React__default.createElement("div", {
26871
26929
  className: styles$N.commentBodyText
26872
26930
  }, commentText), commentAttachment && commentAttachment.length > 0 && commentAttachment.map(file => {
26873
26931
  const fileName = file.split("/")[file.split("/").length - 1];
@@ -26883,10 +26941,10 @@ function Comment(props) {
26883
26941
  }, _$1__default.includes(data.writeFields, _$1__default.get(data, "params._replyField")) && allowSend && /*#__PURE__*/React__default.createElement("div", {
26884
26942
  onClick: e => setAddReply(true),
26885
26943
  className: "icon icon-bubble small " + styles$N.commentReplyButton
26886
- }, dict[lang].comments.reply), allowEdit && isAuthor && /*#__PURE__*/React__default.createElement("div", {
26944
+ }, t('replyText', dict[lang].comments.reply)), allowEdit && isAuthor && /*#__PURE__*/React__default.createElement("div", {
26887
26945
  onClick: e => setIsEditing(true),
26888
26946
  className: "icon icon-edit small " + styles$N.commentReplyButton
26889
- }, dict[lang].comments.edit)))), addReply && /*#__PURE__*/React__default.createElement("div", {
26947
+ }, t('editText', dict[lang].comments.edit))))), addReply && /*#__PURE__*/React__default.createElement("div", {
26890
26948
  className: styles$N.childComments
26891
26949
  }, /*#__PURE__*/React__default.createElement(AddComment, _extends({}, props, {
26892
26950
  parentID: commentID,
@@ -26924,7 +26982,8 @@ function AddComment(props) {
26924
26982
  sendComment,
26925
26983
  parentID,
26926
26984
  data,
26927
- loading
26985
+ loading,
26986
+ t
26928
26987
  } = props;
26929
26988
  const rolesExample = [{
26930
26989
  key: 'admin',
@@ -26966,7 +27025,7 @@ function AddComment(props) {
26966
27025
  bottom: 0
26967
27026
  },
26968
27027
  ok: true
26969
- }, dict[lang].comments.submitted);
27028
+ }, t('submittedText', dict[lang].comments.submitted));
26970
27029
  return /*#__PURE__*/React__default.createElement("div", {
26971
27030
  className: styles$N.commentsAdd
26972
27031
  }, /*#__PURE__*/React__default.createElement(Input, {
@@ -26975,7 +27034,7 @@ function AddComment(props) {
26975
27034
  defaultValue: comment[_$1__default.get(data, "params._textField")],
26976
27035
  onChange: setCommentField(_$1__default.get(data, "params._textField")),
26977
27036
  rows: "auto",
26978
- placeholder: dict[lang].comments.write
27037
+ placeholder: t('placeholderText', dict[lang].comments.write)
26979
27038
  }), /*#__PURE__*/React__default.createElement("div", {
26980
27039
  className: styles$N.commentsAdditionslControls
26981
27040
  }, addFile && allowAttachment && /*#__PURE__*/React__default.createElement(FileUpload, {
@@ -27057,9 +27116,9 @@ function AddComment(props) {
27057
27116
  accent: true,
27058
27117
  icon: "bubble",
27059
27118
  onClick: () => sendComment(comment, finish)
27060
- }, dict[lang].comments.send), onCancel && /*#__PURE__*/React__default.createElement(Button, {
27119
+ }, t('sendText', dict[lang].comments.send)), onCancel && /*#__PURE__*/React__default.createElement(Button, {
27061
27120
  onClick: onCancel
27062
- }, dict[lang].comments.cancel)));
27121
+ }, t('cancelText', dict[lang].comments.cancel))));
27063
27122
  }
27064
27123
  Comments.propTypes = {
27065
27124
  data: propTypes.object,