@bigbinary/neeto-webhooks-frontend 2.2.15 → 2.2.16

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/README.md CHANGED
@@ -82,6 +82,7 @@ The engine is used to manage webhooks across neeto products.
82
82
  You can learn more about the setup and usage here:
83
83
 
84
84
  1. [Models](/docs/engine/models.md)
85
+ 2. [Webhook Versioning Implementation](/docs/webhook-versioning.md)
85
86
 
86
87
  ## Frontend package
87
88
 
@@ -13,6 +13,7 @@
13
13
  "configure": "Configure"
14
14
  },
15
15
  "buttons": {
16
+ "save": "Save",
16
17
  "saveChanges": "Save changes",
17
18
  "cancel": "Cancel",
18
19
  "delete": "Delete",
@@ -72,7 +73,25 @@
72
73
  "inactive": "Inactive"
73
74
  },
74
75
  "statusActiveHelpDescription": "The webhook is currently active. Toggle to make it inactive.",
75
- "statusInactiveHelpDescription": "The webhook is currently inactive. Toggle to make it active."
76
+ "statusInactiveHelpDescription": "The webhook is currently inactive. Toggle to make it active.",
77
+ "version": "Version",
78
+ "versionStatus": {
79
+ "expired": {
80
+ "title": "Webhook Expired",
81
+ "message": "This webhook version has expired and cannot be edited. Only deletion is allowed."
82
+ },
83
+ "deprecated": {
84
+ "title": "Webhook Deprecated",
85
+ "message": "This webhook version is deprecated and cannot be edited. Only deletion is allowed."
86
+ },
87
+ "expiresIn": {
88
+ "days": "Expires in {{count}} day",
89
+ "days_other": "Expires in {{count}} days",
90
+ "hoursAndMinutes": "Expires in {{hours}} hour{{hoursPlural}} and {{minutes}} minute{{minutesPlural}}"
91
+ },
92
+ "expiredOn": "Expired on {{date}}",
93
+ "moreDetails": "More details."
94
+ }
76
95
  },
77
96
  "operation": {
78
97
  "edit": "Edit",
@@ -275,6 +275,7 @@ var TransactionDetails = function TransactionDetails(_ref) {
275
275
  };
276
276
 
277
277
  var Details = function Details(_ref) {
278
+ var _delivery$webhook;
278
279
  var onClose = _ref.onClose,
279
280
  deliveryId = _ref.deliveryId,
280
281
  webhookSid = _ref.webhookSid;
@@ -345,7 +346,7 @@ var Details = function Details(_ref) {
345
346
  }), /*#__PURE__*/jsxs(Pane.Footer, {
346
347
  className: "gap-x-2",
347
348
  children: [(delivery === null || delivery === void 0 ? void 0 : delivery.eventId) && /*#__PURE__*/jsx(Button, {
348
- disabled: isRedelivering,
349
+ disabled: isRedelivering || ((_delivery$webhook = delivery.webhook) === null || _delivery$webhook === void 0 ? void 0 : _delivery$webhook.versionExpired),
349
350
  label: t("neetoWebhooks.delivery.redeliver"),
350
351
  loading: isRedelivering,
351
352
  style: "primary",
@@ -584,6 +585,10 @@ var useUpdateWebhook = function useUpdateWebhook(id, options) {
584
585
  onSuccess: function onSuccess() {
585
586
  var _options$onSuccess2;
586
587
  options === null || options === void 0 || (_options$onSuccess2 = options.onSuccess) === null || _options$onSuccess2 === void 0 || _options$onSuccess2.call(options);
588
+ },
589
+ onError: function onError(error) {
590
+ var _options$onError;
591
+ options === null || options === void 0 || (_options$onError = options.onError) === null || _options$onError === void 0 || _options$onError.call(options, error);
587
592
  }
588
593
  });
589
594
  };
@@ -722,10 +727,22 @@ var ToggleActiveSwitch = function ToggleActiveSwitch(_ref) {
722
727
  _useState2 = _slicedToArray(_useState, 2),
723
728
  status = _useState2[0],
724
729
  setStatus = _useState2[1];
725
- var _useUpdateWebhook = useUpdateWebhook(webhookId),
730
+ var previousStatusRef = useRef(isActive);
731
+ var _useUpdateWebhook = useUpdateWebhook(webhookId, {
732
+ onError: function onError() {
733
+ // Revert to the previous state
734
+ setStatus(previousStatusRef.current);
735
+ },
736
+ onSuccess: function onSuccess() {
737
+ // Update the previous status ref on successful update
738
+ previousStatusRef.current = status;
739
+ }
740
+ }),
726
741
  updateWebhook = _useUpdateWebhook.mutate;
727
742
  var handleToggle = function handleToggle(event) {
728
743
  var updatedStatus = event.target.checked;
744
+ // Store the current status as previous before changing
745
+ previousStatusRef.current = status;
729
746
  setStatus(updatedStatus);
730
747
  updateWebhook({
731
748
  id: webhookId,
@@ -796,6 +813,35 @@ var buildPayload = function buildPayload(_ref2) {
796
813
  eventsAttributes: [].concat(_toConsumableArray(creatable), _toConsumableArray(deletable))
797
814
  });
798
815
  };
816
+ var formatTimeUntilExpiration = function formatTimeUntilExpiration(expiresAt) {
817
+ if (!expiresAt) return null;
818
+ var now = new Date();
819
+ var expiry = new Date(expiresAt);
820
+ var diffMs = expiry - now;
821
+ if (diffMs <= 0) return null;
822
+ var diffHours = Math.floor(diffMs / (1000 * 60 * 60));
823
+ var diffDays = Math.floor(diffHours / 24);
824
+ if (diffDays > 0) {
825
+ return t$1("neetoWebhooks.webhook.versionStatus.expiresIn.days", {
826
+ count: diffDays
827
+ });
828
+ }
829
+ var remainingHours = diffHours;
830
+ var remainingMinutes = Math.floor(diffMs % (1000 * 60 * 60) / (1000 * 60));
831
+ return t$1("neetoWebhooks.webhook.versionStatus.expiresIn.hoursAndMinutes", {
832
+ hours: remainingHours,
833
+ hoursPlural: remainingHours !== 1 ? "s" : "",
834
+ minutes: remainingMinutes,
835
+ minutesPlural: remainingMinutes !== 1 ? "s" : ""
836
+ });
837
+ };
838
+ var formatExpiredDate = function formatExpiredDate(expiresAt) {
839
+ if (!expiresAt) return null;
840
+ var expiry = new Date(expiresAt);
841
+ return t$1("neetoWebhooks.webhook.versionStatus.expiredOn", {
842
+ date: expiry.toLocaleDateString()
843
+ });
844
+ };
799
845
  var buildColumns = function buildColumns(_ref6) {
800
846
  var handleDelete = _ref6.handleDelete,
801
847
  handleEdit = _ref6.handleEdit,
@@ -840,6 +886,38 @@ var buildColumns = function buildColumns(_ref6) {
840
886
  });
841
887
  },
842
888
  width: 150
889
+ }, {
890
+ title: t$1("neetoWebhooks.webhook.version"),
891
+ dataIndex: "version",
892
+ key: "version",
893
+ render: function render(version, webhook) {
894
+ var timeMessage = webhook.versionExpired ? formatExpiredDate(webhook.versionExpiresAt) : formatTimeUntilExpiration(webhook.versionExpiresAt);
895
+ return /*#__PURE__*/jsxs("div", {
896
+ className: "flex flex-col space-y-1",
897
+ children: [/*#__PURE__*/jsxs("div", {
898
+ className: "flex items-center space-x-2",
899
+ children: [/*#__PURE__*/jsx("span", {
900
+ children: version
901
+ }), webhook.versionExpired && /*#__PURE__*/jsx(Tag, {
902
+ label: "expired",
903
+ style: "danger"
904
+ }), webhook.versionDeprecated && !webhook.versionExpired && /*#__PURE__*/jsx(Tag, {
905
+ label: "deprecated",
906
+ style: "warning"
907
+ })]
908
+ }), timeMessage && /*#__PURE__*/jsxs("div", {
909
+ className: "text-xs neeto-ui-text-gray-600",
910
+ children: [timeMessage, ".", " ", /*#__PURE__*/jsx("a", {
911
+ className: "text-blue-600 hover:text-blue-800 underline",
912
+ href: webhook.defaultVersionPayloadDocUrl,
913
+ rel: "noopener noreferrer",
914
+ target: "_blank",
915
+ children: t$1("neetoWebhooks.webhook.versionStatus.moreDetails")
916
+ }), "."]
917
+ })]
918
+ });
919
+ },
920
+ width: 200
843
921
  }, {
844
922
  title: t$1("neetoWebhooks.common.event", PLURAL),
845
923
  dataIndex: "events",
@@ -898,7 +976,12 @@ var AddWebhookPane = function AddWebhookPane(_ref) {
898
976
  var initialValues = editingWebhookId ? _objectSpread$1(_objectSpread$1({}, WEBHOOK_INITIAL_VALUES), webhook) : _objectSpread$1(_objectSpread$1({}, WEBHOOK_INITIAL_VALUES), {}, {
899
977
  events: events
900
978
  });
979
+ var isWebhookExpiredOrDeprecated = editingWebhookId && (webhook.versionExpired || webhook.versionDeprecated);
901
980
  var handleSubmit = function handleSubmit(values) {
981
+ // Check if webhook is expired or deprecated before allowing edit
982
+ if (editingWebhookId && (webhook.versionExpired || webhook.versionDeprecated)) {
983
+ return;
984
+ }
902
985
  var payload = buildPayload({
903
986
  isEditing: editingWebhookId,
904
987
  values: values,
@@ -1052,6 +1135,9 @@ var AddWebhookPane = function AddWebhookPane(_ref) {
1052
1135
  children: /*#__PURE__*/jsx(ActionBlock, {
1053
1136
  cancelButtonProps: {
1054
1137
  onClick: onClose
1138
+ },
1139
+ submitButtonProps: {
1140
+ disabled: isWebhookExpiredOrDeprecated
1055
1141
  }
1056
1142
  })
1057
1143
  })]