@firecms/entity_history 3.0.1 → 3.1.0-canary.02232f4

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.es.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import * as React from "react";
3
3
  import React__default, { useContext, useState, useRef, useEffect, useCallback, useMemo } from "react";
4
- import { useAuthController, useCustomizationController, useNavigationController, useSideEntityController, resolveCollection, getPropertyInPath, getValueInPath, PropertyPreview, SkeletonPropertyComponent, useSnackbarController, useDataSource, EntityView, ErrorBoundary, ConfirmationDialog, mergeCallbacks } from "@firecms/core";
4
+ import { useTranslation, useAuthController, useCustomizationController, useNavigationController, useSideEntityController, resolveCollection, getPropertyInPath, getValueInPath, PropertyPreview, SkeletonPropertyComponent, jsonStringifyReplacer, useSnackbarController, useDataSource, EntityView, ErrorBoundary, ConfirmationDialog, mergeCallbacks } from "@firecms/core";
5
5
  import { c } from "react-compiler-runtime";
6
- import { Chip, Tooltip, Typography, cls, IconButton, KeyboardTabIcon, defaultBorderMixin, KeyboardBackspaceIcon, Label, HistoryIcon } from "@firecms/ui";
6
+ import { Chip, Tooltip, Typography, IconButton, KeyboardTabIcon, cls, defaultBorderMixin, KeyboardBackspaceIcon, Label, HistoryIcon } from "@firecms/ui";
7
7
  import equal from "react-fast-compare";
8
8
  const HistoryControllerContext = React__default.createContext({});
9
9
  const useHistoryController = () => {
@@ -37,59 +37,66 @@ const HistoryControllerProvider = React__default.memo(function HistoryController
37
37
  return t2;
38
38
  }, equal);
39
39
  function UserChip(t0) {
40
- const $ = c(11);
40
+ const $ = c(12);
41
41
  const {
42
42
  user
43
43
  } = t0;
44
+ const {
45
+ t
46
+ } = useTranslation();
44
47
  const t1 = user.email ?? user.uid;
45
48
  let t2;
46
- if ($[0] !== user.displayName || $[1] !== user.photoURL) {
47
- t2 = user.photoURL && /* @__PURE__ */ jsx("img", { className: "rounded-full w-6 h-6 mr-2", src: user.photoURL, alt: user.displayName ?? "User picture" });
48
- $[0] = user.displayName;
49
- $[1] = user.photoURL;
50
- $[2] = t2;
49
+ if ($[0] !== t || $[1] !== user.displayName || $[2] !== user.photoURL) {
50
+ t2 = user.photoURL && /* @__PURE__ */ jsx("img", { className: "rounded-full w-6 h-6 mr-2", src: user.photoURL, alt: user.displayName ?? t("user_picture") });
51
+ $[0] = t;
52
+ $[1] = user.displayName;
53
+ $[2] = user.photoURL;
54
+ $[3] = t2;
51
55
  } else {
52
- t2 = $[2];
56
+ t2 = $[3];
53
57
  }
54
58
  const t3 = user.displayName ?? user.email ?? user.uid;
55
59
  let t4;
56
- if ($[3] !== t3) {
60
+ if ($[4] !== t3) {
57
61
  t4 = /* @__PURE__ */ jsx("span", { children: t3 });
58
- $[3] = t3;
59
- $[4] = t4;
62
+ $[4] = t3;
63
+ $[5] = t4;
60
64
  } else {
61
- t4 = $[4];
65
+ t4 = $[5];
62
66
  }
63
67
  let t5;
64
- if ($[5] !== t2 || $[6] !== t4) {
68
+ if ($[6] !== t2 || $[7] !== t4) {
65
69
  t5 = /* @__PURE__ */ jsxs(Chip, { size: "small", className: "flex items-center", children: [
66
70
  t2,
67
71
  t4
68
72
  ] });
69
- $[5] = t2;
70
- $[6] = t4;
71
- $[7] = t5;
73
+ $[6] = t2;
74
+ $[7] = t4;
75
+ $[8] = t5;
72
76
  } else {
73
- t5 = $[7];
77
+ t5 = $[8];
74
78
  }
75
79
  let t6;
76
- if ($[8] !== t1 || $[9] !== t5) {
80
+ if ($[9] !== t1 || $[10] !== t5) {
77
81
  t6 = /* @__PURE__ */ jsx(Tooltip, { title: t1, children: t5 });
78
- $[8] = t1;
79
- $[9] = t5;
80
- $[10] = t6;
82
+ $[9] = t1;
83
+ $[10] = t5;
84
+ $[11] = t6;
81
85
  } else {
82
- t6 = $[10];
86
+ t6 = $[11];
83
87
  }
84
88
  return t6;
85
89
  }
86
90
  function PreviousValueView(t0) {
87
- const $ = c(12);
91
+ const $ = c(18);
88
92
  const {
89
93
  previousValueInPath,
90
94
  childProperty,
91
95
  propertyKey
92
96
  } = t0;
97
+ const {
98
+ t
99
+ } = useTranslation();
93
100
  if (typeof previousValueInPath === "string" || typeof previousValueInPath === "number") {
94
101
  let t1;
95
102
  if ($[0] !== previousValueInPath) {
@@ -114,43 +121,61 @@ function PreviousValueView(t0) {
114
121
  return t2;
115
122
  } else {
116
123
  let t1;
117
- if ($[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
118
- t1 = /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: "Previous value" });
119
- $[4] = t1;
124
+ if ($[4] !== t) {
125
+ t1 = t("entity_history_previous_value");
126
+ $[4] = t;
127
+ $[5] = t1;
120
128
  } else {
121
- t1 = $[4];
129
+ t1 = $[5];
122
130
  }
123
- const t2 = propertyKey;
124
- const t3 = childProperty;
125
- let t4;
126
- if ($[5] !== previousValueInPath || $[6] !== t2 || $[7] !== t3) {
127
- t4 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
128
- t1,
129
- /* @__PURE__ */ jsx(PropertyPreview, { propertyKey: t2, value: previousValueInPath, property: t3, size: "small" })
130
- ] });
131
- $[5] = previousValueInPath;
132
- $[6] = t2;
133
- $[7] = t3;
134
- $[8] = t4;
131
+ let t2;
132
+ if ($[6] !== t1) {
133
+ t2 = /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: t1 });
134
+ $[6] = t1;
135
+ $[7] = t2;
135
136
  } else {
136
- t4 = $[8];
137
+ t2 = $[7];
137
138
  }
139
+ const t3 = propertyKey;
140
+ const t4 = childProperty;
138
141
  let t5;
139
- if ($[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
140
- t5 = /* @__PURE__ */ jsx(KeyboardBackspaceIcon, { size: "smallest", color: "disabled", className: "mb-1" });
141
- $[9] = t5;
142
+ if ($[8] !== previousValueInPath || $[9] !== t3 || $[10] !== t4) {
143
+ t5 = /* @__PURE__ */ jsx(PropertyPreview, { propertyKey: t3, value: previousValueInPath, property: t4, size: "small" });
144
+ $[8] = previousValueInPath;
145
+ $[9] = t3;
146
+ $[10] = t4;
147
+ $[11] = t5;
142
148
  } else {
143
- t5 = $[9];
149
+ t5 = $[11];
144
150
  }
145
151
  let t6;
146
- if ($[10] !== t4) {
147
- t6 = /* @__PURE__ */ jsx(Tooltip, { side: "left", title: t4, children: t5 });
148
- $[10] = t4;
149
- $[11] = t6;
152
+ if ($[12] !== t2 || $[13] !== t5) {
153
+ t6 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
154
+ t2,
155
+ t5
156
+ ] });
157
+ $[12] = t2;
158
+ $[13] = t5;
159
+ $[14] = t6;
160
+ } else {
161
+ t6 = $[14];
162
+ }
163
+ let t7;
164
+ if ($[15] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
165
+ t7 = /* @__PURE__ */ jsx(KeyboardBackspaceIcon, { size: "smallest", color: "disabled", className: "mb-1" });
166
+ $[15] = t7;
167
+ } else {
168
+ t7 = $[15];
169
+ }
170
+ let t8;
171
+ if ($[16] !== t6) {
172
+ t8 = /* @__PURE__ */ jsx(Tooltip, { side: "left", title: t6, children: t7 });
173
+ $[16] = t6;
174
+ $[17] = t8;
150
175
  } else {
151
- t6 = $[11];
176
+ t8 = $[17];
152
177
  }
153
- return t6;
178
+ return t8;
154
179
  }
155
180
  }
156
181
  }
@@ -168,6 +193,9 @@ function EntityHistoryEntry({
168
193
  const customizationController = useCustomizationController();
169
194
  const navigationController = useNavigationController();
170
195
  const sideEntityController = useSideEntityController();
196
+ const {
197
+ t
198
+ } = useTranslation();
171
199
  const collection = collectionProp ?? navigationController.getCollection(entity.path);
172
200
  const updatedOn = entity.values?.["__metadata"]?.["updated_on"];
173
201
  if (!collection) {
@@ -193,7 +221,7 @@ function EntityHistoryEntry({
193
221
  ] }),
194
222
  /* @__PURE__ */ jsxs("div", { className: cls("bg-white dark:bg-surface-900", "min-h-[44px]", "w-full", "items-center", hover ? "hover:bg-surface-accent-50 dark:hover:bg-surface-800 group-hover:bg-surface-accent-50 dark:group-hover:bg-surface-800" : "", size === "small" ? "p-1" : "px-2 py-1", "flex border rounded-lg", onClick ? "cursor-pointer" : "", defaultBorderMixin), children: [
195
223
  actions,
196
- entity && /* @__PURE__ */ jsx(Tooltip, { title: "See details for this revision", className: "my-2 grow-0 shrink-0 self-start", children: /* @__PURE__ */ jsx(IconButton, { color: "inherit", className: "", onClick: (e) => {
224
+ entity && /* @__PURE__ */ jsx(Tooltip, { title: t("entity_history_see_details"), className: "my-2 grow-0 shrink-0 self-start", children: /* @__PURE__ */ jsx(IconButton, { color: "inherit", className: "", onClick: (e) => {
197
225
  sideEntityController.open({
198
226
  entityId: entity.id,
199
227
  path: entity.path,
@@ -216,7 +244,7 @@ function EntityHistoryEntry({
216
244
  const childProperty = getPropertyInPath(resolvedCollection.properties, key);
217
245
  const valueInPath = getValueInPath(entity.values, key);
218
246
  const previousValueInPath = previousValues ? getValueInPath(previousValues, key) : void 0;
219
- const element = childProperty ? entity ? /* @__PURE__ */ jsx(PropertyPreview, { propertyKey: key, value: valueInPath, property: childProperty, size: "small" }) : /* @__PURE__ */ jsx(SkeletonPropertyComponent, { property: childProperty, size: "small" }) : /* @__PURE__ */ jsx(Typography, { variant: "body2", children: typeof valueInPath === "string" ? valueInPath : JSON.stringify(valueInPath) });
247
+ const element = childProperty ? entity ? /* @__PURE__ */ jsx(PropertyPreview, { propertyKey: key, value: valueInPath, property: childProperty, size: "small" }) : /* @__PURE__ */ jsx(SkeletonPropertyComponent, { property: childProperty, size: "small" }) : /* @__PURE__ */ jsx(Typography, { variant: "body2", children: typeof valueInPath === "string" ? valueInPath : JSON.stringify(valueInPath, jsonStringifyReplacer) });
220
248
  return /* @__PURE__ */ jsxs("div", { className: "flex w-full my-1 items-center", children: [
221
249
  /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "min-w-[140px] md:min-w-[200px] w-1/5 pr-8 overflow-hidden text-ellipsis text-right", children: key }),
222
250
  /* @__PURE__ */ jsxs("div", { className: "w-4/5", children: [
@@ -229,7 +257,7 @@ function EntityHistoryEntry({
229
257
  ] });
230
258
  }
231
259
  function EntityHistoryView(t0) {
232
- const $ = c(62);
260
+ const $ = c(78);
233
261
  const {
234
262
  entity,
235
263
  collection,
@@ -237,6 +265,9 @@ function EntityHistoryView(t0) {
237
265
  } = t0;
238
266
  const authController = useAuthController();
239
267
  const snackbarController = useSnackbarController();
268
+ const {
269
+ t
270
+ } = useTranslation();
240
271
  const dirty = formContext?.formex.dirty;
241
272
  const dataSource = useDataSource();
242
273
  const pathAndId = entity ? entity?.path + "/" + entity?.id : void 0;
@@ -325,7 +356,7 @@ function EntityHistoryView(t0) {
325
356
  const handleObserver = (entries) => {
326
357
  const target = entries[0];
327
358
  if (target.isIntersecting && hasMore && !isLoading) {
328
- setLimit(_temp);
359
+ setLimit(_temp$1);
329
360
  }
330
361
  };
331
362
  const observer = new IntersectionObserver(handleObserver, options);
@@ -357,16 +388,25 @@ function EntityHistoryView(t0) {
357
388
  useEffect(t4, t5);
358
389
  if (!entity) {
359
390
  let t62;
360
- if ($[17] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
361
- t62 = /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsx(Label, { children: "History is only available for existing entities" }) });
362
- $[17] = t62;
391
+ if ($[17] !== t) {
392
+ t62 = t("entity_history_only_existing");
393
+ $[17] = t;
394
+ $[18] = t62;
363
395
  } else {
364
- t62 = $[17];
396
+ t62 = $[18];
365
397
  }
366
- return t62;
398
+ let t72;
399
+ if ($[19] !== t62) {
400
+ t72 = /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsx(Label, { children: t62 }) });
401
+ $[19] = t62;
402
+ $[20] = t72;
403
+ } else {
404
+ t72 = $[20];
405
+ }
406
+ return t72;
367
407
  }
368
408
  let t6;
369
- if ($[18] !== authController || $[19] !== collection || $[20] !== dataSource || $[21] !== entity || $[22] !== formContext || $[23] !== snackbarController) {
409
+ if ($[21] !== authController || $[22] !== collection || $[23] !== dataSource || $[24] !== entity || $[25] !== formContext || $[26] !== snackbarController || $[27] !== t) {
370
410
  t6 = function doRevert2(revertVersion) {
371
411
  if (!entity) {
372
412
  throw new Error("No entity to revert");
@@ -400,64 +440,75 @@ function EntityHistoryView(t0) {
400
440
  });
401
441
  setRevertVersionDialog(void 0);
402
442
  snackbarController.open({
403
- message: "Reverted version",
443
+ message: t("entity_history_reverted"),
404
444
  type: "info"
405
445
  });
406
446
  }).catch((error_0) => {
407
447
  console.error("Error reverting entity:", error_0);
408
448
  snackbarController.open({
409
- message: "Error reverting entity",
449
+ message: t("entity_history_error_reverting"),
410
450
  type: "error"
411
451
  });
412
452
  });
413
453
  };
414
- $[18] = authController;
415
- $[19] = collection;
416
- $[20] = dataSource;
417
- $[21] = entity;
418
- $[22] = formContext;
419
- $[23] = snackbarController;
420
- $[24] = t6;
454
+ $[21] = authController;
455
+ $[22] = collection;
456
+ $[23] = dataSource;
457
+ $[24] = entity;
458
+ $[25] = formContext;
459
+ $[26] = snackbarController;
460
+ $[27] = t;
461
+ $[28] = t6;
421
462
  } else {
422
- t6 = $[24];
463
+ t6 = $[28];
423
464
  }
424
465
  const doRevert = t6;
425
466
  let t7;
426
- if ($[25] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
467
+ if ($[29] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
427
468
  t7 = cls("relative flex-1 h-full overflow-auto w-full flex flex-col gap-4 p-8");
428
- $[25] = t7;
469
+ $[29] = t7;
429
470
  } else {
430
- t7 = $[25];
471
+ t7 = $[29];
431
472
  }
432
473
  let t8;
433
- if ($[26] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
434
- t8 = /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "mt-24 ml-4", children: "History" });
435
- $[26] = t8;
474
+ if ($[30] !== t) {
475
+ t8 = t("history");
476
+ $[30] = t;
477
+ $[31] = t8;
436
478
  } else {
437
- t8 = $[26];
479
+ t8 = $[31];
438
480
  }
439
481
  let t9;
440
- if ($[27] !== revisions.length) {
441
- t9 = revisions.length === 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
442
- /* @__PURE__ */ jsx(Label, { className: "ml-4 mt-8", children: "No history available" }),
443
- /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "ml-4", children: "When you save an entity, a new version is created and stored in the history." })
444
- ] });
445
- $[27] = revisions.length;
446
- $[28] = t9;
482
+ if ($[32] !== t8) {
483
+ t9 = /* @__PURE__ */ jsx(Typography, { variant: "h5", className: "mt-24 ml-4", children: t8 });
484
+ $[32] = t8;
485
+ $[33] = t9;
447
486
  } else {
448
- t9 = $[28];
487
+ t9 = $[33];
449
488
  }
450
489
  let t10;
451
- if ($[29] !== collection || $[30] !== dirty || $[31] !== revisions || $[32] !== snackbarController) {
452
- let t112;
453
- if ($[34] !== collection || $[35] !== dirty || $[36] !== snackbarController) {
454
- t112 = (revision, index) => {
490
+ if ($[34] !== revisions.length || $[35] !== t) {
491
+ t10 = revisions.length === 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
492
+ /* @__PURE__ */ jsx(Label, { className: "ml-4 mt-8", children: t("entity_history_no_history") }),
493
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", className: "ml-4", children: t("entity_history_when_save") })
494
+ ] });
495
+ $[34] = revisions.length;
496
+ $[35] = t;
497
+ $[36] = t10;
498
+ } else {
499
+ t10 = $[36];
500
+ }
501
+ let t11;
502
+ if ($[37] !== collection || $[38] !== dirty || $[39] !== revisions || $[40] !== snackbarController || $[41] !== t) {
503
+ let t122;
504
+ if ($[43] !== collection || $[44] !== dirty || $[45] !== snackbarController || $[46] !== t) {
505
+ t122 = (revision, index) => {
455
506
  const previewKeys = revision.values?.__metadata?.changed_fields;
456
507
  const previousValues = revision.values?.__metadata?.previous_values;
457
- return /* @__PURE__ */ jsx("div", { className: "flex flex-cols gap-2 w-full", children: /* @__PURE__ */ jsx(EntityHistoryEntry, { size: "large", entity: revision, collection, previewKeys, previousValues, actions: /* @__PURE__ */ jsx(Tooltip, { title: "Revert to this version", className: "m-2 grow-0 self-start", children: /* @__PURE__ */ jsx(IconButton, { onClick: () => {
508
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-cols gap-2 w-full", children: /* @__PURE__ */ jsx(EntityHistoryEntry, { size: "large", entity: revision, collection, previewKeys, previousValues, actions: /* @__PURE__ */ jsx(Tooltip, { title: t("entity_history_revert_tooltip"), className: "m-2 grow-0 self-start", children: /* @__PURE__ */ jsx(IconButton, { onClick: () => {
458
509
  if (dirty) {
459
510
  snackbarController.open({
460
- message: "Please save or discard your changes before reverting",
511
+ message: t("entity_history_please_save"),
461
512
  type: "warning"
462
513
  });
463
514
  } else {
@@ -465,113 +516,130 @@ function EntityHistoryView(t0) {
465
516
  }
466
517
  }, children: /* @__PURE__ */ jsx(HistoryIcon, {}) }) }) }) }, index);
467
518
  };
468
- $[34] = collection;
469
- $[35] = dirty;
470
- $[36] = snackbarController;
471
- $[37] = t112;
519
+ $[43] = collection;
520
+ $[44] = dirty;
521
+ $[45] = snackbarController;
522
+ $[46] = t;
523
+ $[47] = t122;
472
524
  } else {
473
- t112 = $[37];
525
+ t122 = $[47];
474
526
  }
475
- t10 = revisions.map(t112);
476
- $[29] = collection;
477
- $[30] = dirty;
478
- $[31] = revisions;
479
- $[32] = snackbarController;
480
- $[33] = t10;
527
+ t11 = revisions.map(t122);
528
+ $[37] = collection;
529
+ $[38] = dirty;
530
+ $[39] = revisions;
531
+ $[40] = snackbarController;
532
+ $[41] = t;
533
+ $[42] = t11;
481
534
  } else {
482
- t10 = $[33];
535
+ t11 = $[42];
483
536
  }
484
- let t11;
485
- if ($[38] !== hasMore || $[39] !== isLoading || $[40] !== revisions.length) {
486
- t11 = revisions.length > 0 && /* @__PURE__ */ jsxs("div", { ref: loadMoreRef, className: "py-4 text-center", children: [
487
- isLoading && /* @__PURE__ */ jsx(Label, { children: "Loading more..." }),
488
- !hasMore && revisions.length > 5 && /* @__PURE__ */ jsx(Label, { children: "No more history available" })
537
+ let t12;
538
+ if ($[48] !== hasMore || $[49] !== isLoading || $[50] !== revisions.length || $[51] !== t) {
539
+ t12 = revisions.length > 0 && /* @__PURE__ */ jsxs("div", { ref: loadMoreRef, className: "py-4 text-center", children: [
540
+ isLoading && /* @__PURE__ */ jsx(Label, { children: t("loading_more") }),
541
+ !hasMore && revisions.length > 5 && /* @__PURE__ */ jsx(Label, { children: t("entity_history_no_more") })
489
542
  ] });
490
- $[38] = hasMore;
491
- $[39] = isLoading;
492
- $[40] = revisions.length;
493
- $[41] = t11;
543
+ $[48] = hasMore;
544
+ $[49] = isLoading;
545
+ $[50] = revisions.length;
546
+ $[51] = t;
547
+ $[52] = t12;
494
548
  } else {
495
- t11 = $[41];
549
+ t12 = $[52];
496
550
  }
497
- let t12;
498
- if ($[42] !== t10 || $[43] !== t11 || $[44] !== t9) {
499
- t12 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 max-w-6xl mx-auto w-full", children: [
500
- t8,
551
+ let t13;
552
+ if ($[53] !== t10 || $[54] !== t11 || $[55] !== t12 || $[56] !== t9) {
553
+ t13 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 max-w-6xl mx-auto w-full", children: [
501
554
  t9,
502
555
  t10,
503
- t11
556
+ t11,
557
+ t12
504
558
  ] });
505
- $[42] = t10;
506
- $[43] = t11;
507
- $[44] = t9;
508
- $[45] = t12;
559
+ $[53] = t10;
560
+ $[54] = t11;
561
+ $[55] = t12;
562
+ $[56] = t9;
563
+ $[57] = t13;
509
564
  } else {
510
- t12 = $[45];
565
+ t13 = $[57];
511
566
  }
512
- const t13 = Boolean(revertVersionDialog);
513
- let t14;
514
- if ($[46] !== doRevert || $[47] !== revertVersionDialog) {
515
- t14 = function() {
567
+ const t14 = Boolean(revertVersionDialog);
568
+ let t15;
569
+ if ($[58] !== doRevert || $[59] !== revertVersionDialog) {
570
+ t15 = function() {
516
571
  if (!revertVersionDialog) {
517
572
  return;
518
573
  }
519
574
  doRevert(revertVersionDialog);
520
575
  };
521
- $[46] = doRevert;
522
- $[47] = revertVersionDialog;
523
- $[48] = t14;
576
+ $[58] = doRevert;
577
+ $[59] = revertVersionDialog;
578
+ $[60] = t15;
524
579
  } else {
525
- t14 = $[48];
580
+ t15 = $[60];
526
581
  }
527
- let t15;
528
582
  let t16;
529
- if ($[49] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
530
- t15 = function() {
583
+ if ($[61] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
584
+ t16 = function() {
531
585
  setRevertVersionDialog(void 0);
532
586
  };
533
- t16 = /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", children: "Revert data to this version?" });
534
- $[49] = t15;
535
- $[50] = t16;
587
+ $[61] = t16;
536
588
  } else {
537
- t15 = $[49];
538
- t16 = $[50];
589
+ t16 = $[61];
539
590
  }
540
591
  let t17;
541
- if ($[51] !== collection || $[52] !== entity?.path || $[53] !== revertVersionDialog) {
542
- t17 = revertVersionDialog ? /* @__PURE__ */ jsx(EntityView, { entity: revertVersionDialog, collection, path: entity?.path }) : null;
543
- $[51] = collection;
544
- $[52] = entity?.path;
545
- $[53] = revertVersionDialog;
546
- $[54] = t17;
592
+ if ($[62] !== t) {
593
+ t17 = t("entity_history_revert_dialog_title");
594
+ $[62] = t;
595
+ $[63] = t17;
547
596
  } else {
548
- t17 = $[54];
597
+ t17 = $[63];
549
598
  }
550
599
  let t18;
551
- if ($[55] !== t13 || $[56] !== t14 || $[57] !== t17) {
552
- t18 = /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(ConfirmationDialog, { open: t13, onAccept: t14, onCancel: t15, title: t16, body: t17 }) });
553
- $[55] = t13;
554
- $[56] = t14;
555
- $[57] = t17;
556
- $[58] = t18;
600
+ if ($[64] !== t17) {
601
+ t18 = /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", children: t17 });
602
+ $[64] = t17;
603
+ $[65] = t18;
557
604
  } else {
558
- t18 = $[58];
605
+ t18 = $[65];
559
606
  }
560
607
  let t19;
561
- if ($[59] !== t12 || $[60] !== t18) {
562
- t19 = /* @__PURE__ */ jsxs("div", { ref: containerRef, className: t7, children: [
563
- t12,
564
- t18
608
+ if ($[66] !== collection || $[67] !== entity?.path || $[68] !== revertVersionDialog) {
609
+ t19 = revertVersionDialog ? /* @__PURE__ */ jsx(EntityView, { entity: revertVersionDialog, collection, path: entity?.path }) : null;
610
+ $[66] = collection;
611
+ $[67] = entity?.path;
612
+ $[68] = revertVersionDialog;
613
+ $[69] = t19;
614
+ } else {
615
+ t19 = $[69];
616
+ }
617
+ let t20;
618
+ if ($[70] !== t14 || $[71] !== t15 || $[72] !== t18 || $[73] !== t19) {
619
+ t20 = /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(ConfirmationDialog, { open: t14, onAccept: t15, onCancel: t16, title: t18, body: t19 }) });
620
+ $[70] = t14;
621
+ $[71] = t15;
622
+ $[72] = t18;
623
+ $[73] = t19;
624
+ $[74] = t20;
625
+ } else {
626
+ t20 = $[74];
627
+ }
628
+ let t21;
629
+ if ($[75] !== t13 || $[76] !== t20) {
630
+ t21 = /* @__PURE__ */ jsxs("div", { ref: containerRef, className: t7, children: [
631
+ t13,
632
+ t20
565
633
  ] });
566
- $[59] = t12;
567
- $[60] = t18;
568
- $[61] = t19;
634
+ $[75] = t13;
635
+ $[76] = t20;
636
+ $[77] = t21;
569
637
  } else {
570
- t19 = $[61];
638
+ t21 = $[77];
571
639
  }
572
- return t19;
640
+ return t21;
573
641
  }
574
- function _temp(prev) {
642
+ function _temp$1(prev) {
575
643
  return prev + 5;
576
644
  }
577
645
  function createHistoryEntry({
@@ -661,6 +729,314 @@ function findChangedFields(oldValues, newValues, prefix = "") {
661
729
  }
662
730
  return changedFields;
663
731
  }
732
+ function getRelativeTimeString(date, t) {
733
+ const now = /* @__PURE__ */ new Date();
734
+ const diffMs = now.getTime() - date.getTime();
735
+ const diffSeconds = Math.floor(diffMs / 1e3);
736
+ const diffMinutes = Math.floor(diffSeconds / 60);
737
+ const diffHours = Math.floor(diffMinutes / 60);
738
+ const diffDays = Math.floor(diffHours / 24);
739
+ if (diffSeconds < 60) return t("entity_history_just_now");
740
+ if (diffMinutes < 60) return t("entity_history_minutes_ago", {
741
+ minutes: diffMinutes
742
+ });
743
+ if (diffHours < 24) return t("entity_history_hours_ago", {
744
+ hours: diffHours
745
+ });
746
+ if (diffDays < 30) return t("entity_history_days_ago", {
747
+ days: diffDays
748
+ });
749
+ return date.toLocaleDateString();
750
+ }
751
+ function LastEditedByIndicator(t0) {
752
+ const $ = c(24);
753
+ const {
754
+ path,
755
+ entityId,
756
+ collection
757
+ } = t0;
758
+ const {
759
+ t
760
+ } = useTranslation();
761
+ const {
762
+ getUser
763
+ } = useHistoryController();
764
+ const dataSource = useDataSource();
765
+ const [latestEntry, setLatestEntry] = useState();
766
+ let t1;
767
+ if ($[0] !== collection || $[1] !== dataSource || $[2] !== entityId || $[3] !== path) {
768
+ t1 = () => {
769
+ if (!path || !entityId) {
770
+ return;
771
+ }
772
+ const historyPath = `${path}/${entityId}/__history`;
773
+ const unsubscribe = dataSource.listenCollection?.({
774
+ path: historyPath,
775
+ collection,
776
+ orderBy: "__metadata.updated_on",
777
+ order: "desc",
778
+ limit: 1,
779
+ onUpdate: (entities) => {
780
+ setLatestEntry(entities[0]);
781
+ },
782
+ onError: _temp
783
+ });
784
+ return () => {
785
+ if (typeof unsubscribe === "function") {
786
+ unsubscribe();
787
+ }
788
+ };
789
+ };
790
+ $[0] = collection;
791
+ $[1] = dataSource;
792
+ $[2] = entityId;
793
+ $[3] = path;
794
+ $[4] = t1;
795
+ } else {
796
+ t1 = $[4];
797
+ }
798
+ let t2;
799
+ if ($[5] !== dataSource || $[6] !== entityId || $[7] !== path) {
800
+ t2 = [path, entityId, dataSource];
801
+ $[5] = dataSource;
802
+ $[6] = entityId;
803
+ $[7] = path;
804
+ $[8] = t2;
805
+ } else {
806
+ t2 = $[8];
807
+ }
808
+ useEffect(t1, t2);
809
+ const metadata = latestEntry?.values?.__metadata;
810
+ const uid = metadata?.updated_by;
811
+ const editedOn = metadata?.updated_on;
812
+ const hasData = Boolean(uid || editedOn);
813
+ let t3;
814
+ if ($[9] !== getUser || $[10] !== uid) {
815
+ t3 = uid ? getUser?.(uid) : void 0;
816
+ $[9] = getUser;
817
+ $[10] = uid;
818
+ $[11] = t3;
819
+ } else {
820
+ t3 = $[11];
821
+ }
822
+ const user = t3;
823
+ let t4;
824
+ if ($[12] !== editedOn) {
825
+ t4 = editedOn instanceof Date ? editedOn : editedOn?.toDate ? editedOn.toDate() : null;
826
+ $[12] = editedOn;
827
+ $[13] = t4;
828
+ } else {
829
+ t4 = $[13];
830
+ }
831
+ const date = t4;
832
+ let t5;
833
+ if ($[14] !== date || $[15] !== t) {
834
+ t5 = date ? getRelativeTimeString(date, t) : null;
835
+ $[14] = date;
836
+ $[15] = t;
837
+ $[16] = t5;
838
+ } else {
839
+ t5 = $[16];
840
+ }
841
+ const timeString = t5;
842
+ const displayName = user?.displayName ?? user?.email ?? uid;
843
+ const photoURL = user?.photoURL;
844
+ let t6;
845
+ if ($[17] !== displayName || $[18] !== hasData || $[19] !== photoURL || $[20] !== timeString) {
846
+ t6 = hasData && /* @__PURE__ */ jsxs(Fragment, { children: [
847
+ photoURL ? /* @__PURE__ */ jsx("img", { src: photoURL, alt: displayName ?? "User", className: "rounded-full object-cover w-6 h-6" }) : /* @__PURE__ */ jsx("div", { className: "rounded-full bg-primary/10 dark:bg-primary-dark/20 flex items-center justify-center text-primary dark:text-primary-dark font-medium w-6 h-6 text-xs", children: (displayName ?? "?").charAt(0).toUpperCase() }),
848
+ /* @__PURE__ */ jsxs("span", { children: [
849
+ displayName,
850
+ timeString ? ` · ${timeString}` : ""
851
+ ] })
852
+ ] });
853
+ $[17] = displayName;
854
+ $[18] = hasData;
855
+ $[19] = photoURL;
856
+ $[20] = timeString;
857
+ $[21] = t6;
858
+ } else {
859
+ t6 = $[21];
860
+ }
861
+ let t7;
862
+ if ($[22] !== t6) {
863
+ t7 = /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 text-xs text-text-secondary dark:text-text-secondary-dark min-h-6", children: t6 });
864
+ $[22] = t6;
865
+ $[23] = t7;
866
+ } else {
867
+ t7 = $[23];
868
+ }
869
+ return t7;
870
+ }
871
+ function _temp(error) {
872
+ console.error("Error fetching latest history entry:", error);
873
+ }
874
+ function LastEditedByFormAction(t0) {
875
+ const $ = c(4);
876
+ const {
877
+ entityId,
878
+ path,
879
+ status,
880
+ collection
881
+ } = t0;
882
+ if (status === "new" || status === "copy" || !entityId) {
883
+ return null;
884
+ }
885
+ if (!collection.history) {
886
+ return null;
887
+ }
888
+ let t1;
889
+ if ($[0] !== collection || $[1] !== entityId || $[2] !== path) {
890
+ t1 = /* @__PURE__ */ jsx(LastEditedByIndicator, { path, entityId, collection });
891
+ $[0] = collection;
892
+ $[1] = entityId;
893
+ $[2] = path;
894
+ $[3] = t1;
895
+ } else {
896
+ t1 = $[3];
897
+ }
898
+ return t1;
899
+ }
900
+ const entityHistoryTranslationsEn = {
901
+ history: "History",
902
+ entity_history_only_existing: "History is only available for existing entities",
903
+ entity_history_reverted: "Reverted version",
904
+ entity_history_error_reverting: "Error reverting entity",
905
+ entity_history_no_history: "No history available",
906
+ entity_history_when_save: "When you save an entity, a new version is created and stored in the history.",
907
+ entity_history_revert_tooltip: "Revert to this version",
908
+ entity_history_please_save: "Please save or discard your changes before reverting",
909
+ loading_more: "Loading more...",
910
+ entity_history_no_more: "No more history available",
911
+ entity_history_revert_dialog_title: "Revert data to this version?",
912
+ entity_history_previous_value: "Previous value",
913
+ entity_history_see_details: "See details for this revision",
914
+ entity_history_just_now: "just now",
915
+ entity_history_minutes_ago: "{{minutes}}m ago",
916
+ entity_history_hours_ago: "{{hours}}h ago",
917
+ entity_history_days_ago: "{{days}}d ago",
918
+ user_picture: "User picture"
919
+ };
920
+ const entityHistoryTranslationsEs = {
921
+ history: "Historial",
922
+ entity_history_only_existing: "El historial solo está disponible para entidades existentes",
923
+ entity_history_reverted: "Versión revertida",
924
+ entity_history_error_reverting: "Error al revertir la entidad",
925
+ entity_history_no_history: "No hay historial disponible",
926
+ entity_history_when_save: "Cuando guardas una entidad, se crea una nueva versión y se almacena en el historial.",
927
+ entity_history_revert_tooltip: "Revertir a esta versión",
928
+ entity_history_please_save: "Por favor, guarda o descarta tus cambios antes de revertir",
929
+ loading_more: "Cargando más...",
930
+ entity_history_no_more: "No hay más historial disponible",
931
+ entity_history_revert_dialog_title: "¿Revertir datos a esta versión?",
932
+ entity_history_previous_value: "Valor anterior",
933
+ entity_history_see_details: "Ver detalles de esta revisión",
934
+ entity_history_just_now: "justo ahora",
935
+ entity_history_minutes_ago: "hace {{minutes}}m",
936
+ entity_history_hours_ago: "hace {{hours}}h",
937
+ entity_history_days_ago: "hace {{days}}d",
938
+ user_picture: "Foto de usuario"
939
+ };
940
+ const entityHistoryTranslationsDe = {
941
+ history: "Verlauf",
942
+ entity_history_only_existing: "Verlauf ist nur für vorhandene Entitäten verfügbar",
943
+ entity_history_reverted: "Wiederhergestellte Version",
944
+ entity_history_error_reverting: "Fehler beim Wiederherstellen der Entität",
945
+ entity_history_no_history: "Kein Verlauf verfügbar",
946
+ entity_history_when_save: "Wenn Sie eine Entität speichern, wird eine neue Version erstellt und im Verlauf gespeichert.",
947
+ entity_history_revert_tooltip: "Zu dieser Version zurückkehren",
948
+ entity_history_please_save: "Bitte speichern oder verwerfen Sie Ihre Änderungen vor der Wiederherstellung",
949
+ loading_more: "Mehr laden...",
950
+ entity_history_no_more: "Kein weiterer Verlauf verfügbar",
951
+ entity_history_revert_dialog_title: "Daten auf diese Version zurücksetzen?",
952
+ entity_history_previous_value: "Vorheriger Wert",
953
+ entity_history_see_details: "Details zu dieser Überarbeitung anzeigen",
954
+ entity_history_just_now: "gerade eben",
955
+ entity_history_minutes_ago: "vor {{minutes}}m",
956
+ entity_history_hours_ago: "vor {{hours}}h",
957
+ entity_history_days_ago: "vor {{days}}d",
958
+ user_picture: "Benutzerbild"
959
+ };
960
+ const entityHistoryTranslationsFr = {
961
+ history: "Historique",
962
+ entity_history_only_existing: "L'historique n'est disponible que pour les entités existantes",
963
+ entity_history_reverted: "Version restaurée",
964
+ entity_history_error_reverting: "Erreur lors de la restauration de l'entité",
965
+ entity_history_no_history: "Aucun historique disponible",
966
+ entity_history_when_save: "Lorsque vous enregistrez une entité, une nouvelle version est créée et stockée dans l'historique.",
967
+ entity_history_revert_tooltip: "Revenir à cette version",
968
+ entity_history_please_save: "Veuillez enregistrer ou annuler vos modifications avant de restaurer",
969
+ loading_more: "Chargement en cours...",
970
+ entity_history_no_more: "Aucun autre historique disponible",
971
+ entity_history_revert_dialog_title: "Restaurer les données à cette version ?",
972
+ entity_history_previous_value: "Valeur précédente",
973
+ entity_history_see_details: "Voir les détails de cette révision",
974
+ entity_history_just_now: "à l'instant",
975
+ entity_history_minutes_ago: "il y a {{minutes}}m",
976
+ entity_history_hours_ago: "il y a {{hours}}h",
977
+ entity_history_days_ago: "il y a {{days}}j",
978
+ user_picture: "Photo de l'utilisateur"
979
+ };
980
+ const entityHistoryTranslationsIt = {
981
+ history: "Cronologia",
982
+ entity_history_only_existing: "La cronologia è disponibile solo per le entità esistenti",
983
+ entity_history_reverted: "Versione ripristinata",
984
+ entity_history_error_reverting: "Errore durante il ripristino dell'entità",
985
+ entity_history_no_history: "Nessuna cronologia disponibile",
986
+ entity_history_when_save: "Quando salvi un'entità, viene creata una nuova versione e memorizzata nella cronologia.",
987
+ entity_history_revert_tooltip: "Ripristina a questa versione",
988
+ entity_history_please_save: "Salva o annulla le modifiche prima del ripristino",
989
+ loading_more: "Caricamento in corso...",
990
+ entity_history_no_more: "Nessuna ulteriore cronologia disponibile",
991
+ entity_history_revert_dialog_title: "Vuoi ripristinare i dati a questa versione?",
992
+ entity_history_previous_value: "Valore precedente",
993
+ entity_history_see_details: "Vedi i dettagli per questa revisione",
994
+ entity_history_just_now: "proprio adesso",
995
+ entity_history_minutes_ago: "{{minutes}} min fa",
996
+ entity_history_hours_ago: "{{hours}} h fa",
997
+ entity_history_days_ago: "{{days}} g fa",
998
+ user_picture: "Immagine utente"
999
+ };
1000
+ const entityHistoryTranslationsHi = {
1001
+ history: "इतिहास",
1002
+ entity_history_only_existing: "इतिहास केवल मौजूद संस्थाओं के लिए उपलब्ध है",
1003
+ entity_history_reverted: "परिवर्तित संस्करण",
1004
+ entity_history_error_reverting: "संस्था को वापस लाने में त्रुटि",
1005
+ entity_history_no_history: "कोई इतिहास उपलब्ध नहीं",
1006
+ entity_history_when_save: "जब आप किसी संस्था को सहेजते हैं, तो एक नया संस्करण बनाया जाता है और इतिहास में संग्रहीत किया जाता है।",
1007
+ entity_history_revert_tooltip: "इस संस्करण पर वापस जाएं",
1008
+ entity_history_please_save: "कृपया वापस जाने से पहले अपने परिवर्तनों को सहेजें या हटा दें",
1009
+ loading_more: "और लोड हो रहा है...",
1010
+ entity_history_no_more: "कोई और इतिहास उपलब्ध नहीं",
1011
+ entity_history_revert_dialog_title: "डेटा को इस संस्करण में वापस लाएँ?",
1012
+ entity_history_previous_value: "पिछला मान",
1013
+ entity_history_see_details: "इस संशोधन के लिए विवरण यहाँ देखें",
1014
+ entity_history_just_now: "अभी-अभी",
1015
+ entity_history_minutes_ago: "{{minutes}}m पहले",
1016
+ entity_history_hours_ago: "{{hours}}h पहले",
1017
+ entity_history_days_ago: "{{days}}d पहले",
1018
+ user_picture: "उपयोगकर्ता चित्र"
1019
+ };
1020
+ const entityHistoryTranslationsPt = {
1021
+ history: "Histórico",
1022
+ entity_history_only_existing: "O histórico está disponível apenas para entidades existentes",
1023
+ entity_history_reverted: "Versão revertida",
1024
+ entity_history_error_reverting: "Erro ao reverter entidade",
1025
+ entity_history_no_history: "Sem histórico disponível",
1026
+ entity_history_when_save: "Quando guarda uma entidade, é criada uma nova versão e armazenada no histórico.",
1027
+ entity_history_revert_tooltip: "Reverter para esta versão",
1028
+ entity_history_please_save: "Por favor guarde ou descarte as suas alterações antes de reverter",
1029
+ loading_more: "A carregar mais...",
1030
+ entity_history_no_more: "Sem mais histórico disponível",
1031
+ entity_history_revert_dialog_title: "Reverter dados para esta versão?",
1032
+ entity_history_previous_value: "Valor anterior",
1033
+ entity_history_see_details: "Ver detalhes desta revisão",
1034
+ entity_history_just_now: "agora mesmo",
1035
+ entity_history_minutes_ago: "há {{minutes}}m",
1036
+ entity_history_hours_ago: "há {{hours}}h",
1037
+ entity_history_days_ago: "há {{days}}d",
1038
+ user_picture: "Foto do utilizador"
1039
+ };
664
1040
  function useEntityHistoryPlugin(props) {
665
1041
  const {
666
1042
  defaultEnabled = false
@@ -669,6 +1045,7 @@ function useEntityHistoryPlugin(props) {
669
1045
  if (collection.history === true || defaultEnabled && collection.history !== false) {
670
1046
  return {
671
1047
  ...collection,
1048
+ history: true,
672
1049
  entityViews: [...collection.entityViews ?? [], {
673
1050
  key: "__history",
674
1051
  name: "History",
@@ -689,14 +1066,27 @@ function useEntityHistoryPlugin(props) {
689
1066
  getUser: props?.getUser
690
1067
  }
691
1068
  },
1069
+ form: {
1070
+ BeforeTitle: LastEditedByFormAction
1071
+ },
692
1072
  collection: {
693
1073
  modifyCollection
1074
+ },
1075
+ i18n: {
1076
+ en: entityHistoryTranslationsEn,
1077
+ es: entityHistoryTranslationsEs,
1078
+ de: entityHistoryTranslationsDe,
1079
+ fr: entityHistoryTranslationsFr,
1080
+ it: entityHistoryTranslationsIt,
1081
+ hi: entityHistoryTranslationsHi,
1082
+ pt: entityHistoryTranslationsPt
694
1083
  }
695
1084
  }), [props]);
696
1085
  }
697
1086
  export {
698
1087
  HistoryControllerContext,
699
1088
  HistoryControllerProvider,
1089
+ LastEditedByIndicator,
700
1090
  createHistoryEntry,
701
1091
  useEntityHistoryPlugin,
702
1092
  useHistoryController