@firecms/entity_history 3.0.0 → 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.
@@ -7,7 +7,8 @@ import {
7
7
  ErrorBoundary,
8
8
  useAuthController,
9
9
  useDataSource,
10
- useSnackbarController
10
+ useSnackbarController,
11
+ useTranslation
11
12
  } from "@firecms/core";
12
13
  import { cls, HistoryIcon, IconButton, Label, Tooltip, Typography } from "@firecms/ui";
13
14
  import { EntityHistoryEntry } from "./EntityHistoryEntry";
@@ -20,6 +21,7 @@ export function EntityHistoryView({
20
21
 
21
22
  const authController = useAuthController();
22
23
  const snackbarController = useSnackbarController();
24
+ const { t } = useTranslation();
23
25
  const dirty = formContext?.formex.dirty;
24
26
 
25
27
  const dataSource = useDataSource();
@@ -44,6 +46,7 @@ export function EntityHistoryView({
44
46
  setIsLoading(true); // Set loading true when fetching starts
45
47
  const listener = dataSource.listenCollection?.({
46
48
  path: pathAndId + "/__history",
49
+ collection: collection,
47
50
  order: "desc",
48
51
  orderBy: "__metadata.updated_on",
49
52
  limit: limit,
@@ -113,7 +116,7 @@ export function EntityHistoryView({
113
116
 
114
117
  if (!entity) {
115
118
  return <div className="flex items-center justify-center h-full">
116
- <Label>History is only available for existing entities</Label>
119
+ <Label>{t("entity_history_only_existing")}</Label>
117
120
  </div>
118
121
  }
119
122
 
@@ -151,14 +154,14 @@ export function EntityHistoryView({
151
154
  });
152
155
  setRevertVersionDialog(undefined);
153
156
  snackbarController.open({
154
- message: "Reverted version",
157
+ message: t("entity_history_reverted"),
155
158
  type: "info"
156
159
  });
157
160
  }
158
161
  ).catch((error) => {
159
162
  console.error("Error reverting entity:", error);
160
163
  snackbarController.open({
161
- message: "Error reverting entity",
164
+ message: t("entity_history_error_reverting"),
162
165
  type: "error"
163
166
  });
164
167
  });
@@ -171,15 +174,15 @@ export function EntityHistoryView({
171
174
  <div className="flex flex-col gap-2 max-w-6xl mx-auto w-full">
172
175
 
173
176
  <Typography variant={"h5"} className={"mt-24 ml-4"}>
174
- History
177
+ {t("history")}
175
178
  </Typography>
176
179
 
177
180
  {revisions.length === 0 && <>
178
181
  <Label className={"ml-4 mt-8"}>
179
- No history available
182
+ {t("entity_history_no_history")}
180
183
  </Label>
181
184
  <Typography variant={"caption"} className={"ml-4"}>
182
- When you save an entity, a new version is created and stored in the history.
185
+ {t("entity_history_when_save")}
183
186
  </Typography>
184
187
  </>}
185
188
 
@@ -193,13 +196,13 @@ export function EntityHistoryView({
193
196
  previewKeys={previewKeys}
194
197
  previousValues={previousValues}
195
198
  actions={
196
- <Tooltip title={"Revert to this version"}
199
+ <Tooltip title={t("entity_history_revert_tooltip")}
197
200
  className={"m-2 grow-0 self-start"}>
198
201
  <IconButton
199
202
  onClick={() => {
200
203
  if (dirty) {
201
204
  snackbarController.open({
202
- message: "Please save or discard your changes before reverting",
205
+ message: t("entity_history_please_save"),
203
206
  type: "warning"
204
207
  });
205
208
  } else {
@@ -219,8 +222,8 @@ export function EntityHistoryView({
219
222
  ref={loadMoreRef}
220
223
  className="py-4 text-center"
221
224
  >
222
- {isLoading && <Label>Loading more...</Label>}
223
- {!hasMore && revisions.length > PAGE_SIZE && <Label>No more history available</Label>}
225
+ {isLoading && <Label>{t("loading_more")}</Label>}
226
+ {!hasMore && revisions.length > PAGE_SIZE && <Label>{t("entity_history_no_more")}</Label>}
224
227
  </div>
225
228
  )}
226
229
  </div>
@@ -234,7 +237,7 @@ export function EntityHistoryView({
234
237
  onCancel={function (): void {
235
238
  setRevertVersionDialog(undefined);
236
239
  }}
237
- title={<Typography variant={"subtitle2"}>Revert data to this version?</Typography>}
240
+ title={<Typography variant={"subtitle2"}>{t("entity_history_revert_dialog_title")}</Typography>}
238
241
  body={revertVersionDialog ?
239
242
  <EntityView entity={revertVersionDialog}
240
243
  collection={collection}
@@ -0,0 +1,96 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { Entity, useDataSource, User, useTranslation } from "@firecms/core";
3
+ import { useHistoryController } from "../HistoryControllerProvider";
4
+
5
+ function getRelativeTimeString(date: Date, t: any): string {
6
+ const now = new Date();
7
+ const diffMs = now.getTime() - date.getTime();
8
+ const diffSeconds = Math.floor(diffMs / 1000);
9
+ const diffMinutes = Math.floor(diffSeconds / 60);
10
+ const diffHours = Math.floor(diffMinutes / 60);
11
+ const diffDays = Math.floor(diffHours / 24);
12
+
13
+ if (diffSeconds < 60) return t("entity_history_just_now");
14
+ if (diffMinutes < 60) return t("entity_history_minutes_ago", { minutes: diffMinutes });
15
+ if (diffHours < 24) return t("entity_history_hours_ago", { hours: diffHours });
16
+ if (diffDays < 30) return t("entity_history_days_ago", { days: diffDays });
17
+ return date.toLocaleDateString();
18
+ }
19
+
20
+ /**
21
+ * Fetches the latest history entry from the __history subcollection
22
+ * and displays who last edited the entity and when.
23
+ */
24
+ export function LastEditedByIndicator({
25
+ path,
26
+ entityId,
27
+ collection
28
+ }: {
29
+ path: string;
30
+ entityId: string;
31
+ collection: any;
32
+ }) {
33
+ const { t } = useTranslation();
34
+ const { getUser } = useHistoryController();
35
+ const dataSource = useDataSource();
36
+ const [latestEntry, setLatestEntry] = useState<Entity | undefined>();
37
+
38
+ useEffect(() => {
39
+ if (!path || !entityId) return;
40
+
41
+ const historyPath = `${path}/${entityId}/__history`;
42
+ const unsubscribe = dataSource.listenCollection?.({
43
+ path: historyPath,
44
+ collection,
45
+ orderBy: "__metadata.updated_on",
46
+ order: "desc",
47
+ limit: 1,
48
+ onUpdate: (entities) => {
49
+ setLatestEntry(entities[0]);
50
+ },
51
+ onError: (error) => {
52
+ console.error("Error fetching latest history entry:", error);
53
+ }
54
+ });
55
+
56
+ return () => {
57
+ if (typeof unsubscribe === "function") {
58
+ unsubscribe();
59
+ }
60
+ };
61
+ }, [path, entityId, dataSource]);
62
+
63
+ const metadata = latestEntry?.values?.__metadata;
64
+ const uid = metadata?.updated_by;
65
+ const editedOn = metadata?.updated_on;
66
+
67
+ const hasData = Boolean(uid || editedOn);
68
+
69
+ const user: User | null | undefined = uid ? getUser?.(uid) : undefined;
70
+ const date = editedOn instanceof Date ? editedOn : (editedOn?.toDate ? editedOn.toDate() : null);
71
+ const timeString = date ? getRelativeTimeString(date, t) : null;
72
+
73
+ const displayName = user?.displayName ?? user?.email ?? uid;
74
+ const photoURL = user?.photoURL;
75
+
76
+ return (
77
+ <div className="flex items-center gap-2 text-xs text-text-secondary dark:text-text-secondary-dark min-h-6">
78
+ {hasData && <>
79
+ {photoURL ? (
80
+ <img
81
+ src={photoURL}
82
+ alt={displayName ?? "User"}
83
+ className="rounded-full object-cover w-6 h-6"
84
+ />
85
+ ) : (
86
+ <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">
87
+ {(displayName ?? "?").charAt(0).toUpperCase()}
88
+ </div>
89
+ )}
90
+ <span>
91
+ {displayName}{timeString ? ` · ${timeString}` : ""}
92
+ </span>
93
+ </>}
94
+ </div>
95
+ );
96
+ }
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ import { PluginFormActionProps } from "@firecms/core";
3
+ import { LastEditedByIndicator } from "./LastEditedByIndicator";
4
+
5
+ /**
6
+ * Renders the "last edited by" indicator in the entity form top bar.
7
+ * Used as a plugin `form.ActionsTop` component.
8
+ */
9
+ export function LastEditedByFormAction({
10
+ entityId,
11
+ path,
12
+ status,
13
+ collection,
14
+ }: PluginFormActionProps) {
15
+ if (status === "new" || status === "copy" || !entityId) return null;
16
+ if (!collection.history) return null;
17
+
18
+ return <LastEditedByIndicator
19
+ path={path}
20
+ entityId={entityId}
21
+ collection={collection}
22
+ />;
23
+ }
@@ -1,13 +1,14 @@
1
- import { User } from "@firecms/core";
1
+ import { User, useTranslation } from "@firecms/core";
2
2
  import { Chip, Tooltip } from "@firecms/ui";
3
3
 
4
4
  export function UserChip({ user }: { user: User }) {
5
+ const { t } = useTranslation();
5
6
  return (
6
7
  <Tooltip title={user.email ?? user.uid}>
7
8
  <Chip size={"small"} className={"flex items-center"}>
8
9
  {user.photoURL && <img
9
10
  className={"rounded-full w-6 h-6 mr-2"}
10
- src={user.photoURL} alt={user.displayName ?? "User picture"}/>}
11
+ src={user.photoURL} alt={user.displayName ?? t("user_picture")}/>}
11
12
  <span>{user.displayName ?? user.email ?? user.uid}</span>
12
13
  </Chip>
13
14
  </Tooltip>
@@ -5,12 +5,13 @@ import { HistoryEntry, NewHistoryEntryParams } from "./types";
5
5
 
6
6
 
7
7
  export function createHistoryEntry<T = any>({
8
- context,
9
- previousValues,
10
- values,
11
- path,
12
- entityId
13
- }: NewHistoryEntryParams<T>) {
8
+ context,
9
+ previousValues,
10
+ values,
11
+ path,
12
+ entityId,
13
+ collection
14
+ }: NewHistoryEntryParams<T>) {
14
15
 
15
16
  const uid = context.authController.user?.uid;
16
17
  const dataSource = context.dataSource;
@@ -28,7 +29,8 @@ export function createHistoryEntry<T = any>({
28
29
  dataSource.saveEntity({
29
30
  path: path + "/" + entityId + "/__history",
30
31
  values: entry,
31
- status: "new"
32
+ status: "new",
33
+ collection
32
34
  }).then(() => {
33
35
  console.debug("History saved for", path, entityId);
34
36
  });
@@ -42,12 +44,14 @@ export const entityHistoryCallbacks: EntityCallbacks = {
42
44
  const path = props.path;
43
45
  const entityId = props.entityId;
44
46
  const context = props.context;
47
+ const collection = props.collection;
45
48
  createHistoryEntry({
46
49
  context: context,
47
50
  previousValues: previousValues,
48
51
  values: values,
49
52
  path: path,
50
- entityId: entityId
53
+ entityId: entityId,
54
+ collection: collection
51
55
  });
52
56
  }
53
57
  }
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./useEntityHistoryPlugin";
2
2
  export * from "./HistoryControllerProvider";
3
3
  export { createHistoryEntry } from "./entity_history_callbacks";
4
+ export { LastEditedByIndicator } from "./components/LastEditedByIndicator";
4
5
  export * from "./types";
@@ -0,0 +1,20 @@
1
+ export const entityHistoryTranslationsDe = {
2
+ history: "Verlauf",
3
+ entity_history_only_existing: "Verlauf ist nur für vorhandene Entitäten verfügbar",
4
+ entity_history_reverted: "Wiederhergestellte Version",
5
+ entity_history_error_reverting: "Fehler beim Wiederherstellen der Entität",
6
+ entity_history_no_history: "Kein Verlauf verfügbar",
7
+ entity_history_when_save: "Wenn Sie eine Entität speichern, wird eine neue Version erstellt und im Verlauf gespeichert.",
8
+ entity_history_revert_tooltip: "Zu dieser Version zurückkehren",
9
+ entity_history_please_save: "Bitte speichern oder verwerfen Sie Ihre Änderungen vor der Wiederherstellung",
10
+ loading_more: "Mehr laden...",
11
+ entity_history_no_more: "Kein weiterer Verlauf verfügbar",
12
+ entity_history_revert_dialog_title: "Daten auf diese Version zurücksetzen?",
13
+ entity_history_previous_value: "Vorheriger Wert",
14
+ entity_history_see_details: "Details zu dieser Überarbeitung anzeigen",
15
+ entity_history_just_now: "gerade eben",
16
+ entity_history_minutes_ago: "vor {{minutes}}m",
17
+ entity_history_hours_ago: "vor {{hours}}h",
18
+ entity_history_days_ago: "vor {{days}}d",
19
+ user_picture: "Benutzerbild"
20
+ };
@@ -0,0 +1,20 @@
1
+ export const entityHistoryTranslationsEn = {
2
+ history: "History",
3
+ entity_history_only_existing: "History is only available for existing entities",
4
+ entity_history_reverted: "Reverted version",
5
+ entity_history_error_reverting: "Error reverting entity",
6
+ entity_history_no_history: "No history available",
7
+ entity_history_when_save: "When you save an entity, a new version is created and stored in the history.",
8
+ entity_history_revert_tooltip: "Revert to this version",
9
+ entity_history_please_save: "Please save or discard your changes before reverting",
10
+ loading_more: "Loading more...",
11
+ entity_history_no_more: "No more history available",
12
+ entity_history_revert_dialog_title: "Revert data to this version?",
13
+ entity_history_previous_value: "Previous value",
14
+ entity_history_see_details: "See details for this revision",
15
+ entity_history_just_now: "just now",
16
+ entity_history_minutes_ago: "{{minutes}}m ago",
17
+ entity_history_hours_ago: "{{hours}}h ago",
18
+ entity_history_days_ago: "{{days}}d ago",
19
+ user_picture: "User picture"
20
+ };
@@ -0,0 +1,20 @@
1
+ export const entityHistoryTranslationsEs = {
2
+ history: "Historial",
3
+ entity_history_only_existing: "El historial solo está disponible para entidades existentes",
4
+ entity_history_reverted: "Versión revertida",
5
+ entity_history_error_reverting: "Error al revertir la entidad",
6
+ entity_history_no_history: "No hay historial disponible",
7
+ entity_history_when_save: "Cuando guardas una entidad, se crea una nueva versión y se almacena en el historial.",
8
+ entity_history_revert_tooltip: "Revertir a esta versión",
9
+ entity_history_please_save: "Por favor, guarda o descarta tus cambios antes de revertir",
10
+ loading_more: "Cargando más...",
11
+ entity_history_no_more: "No hay más historial disponible",
12
+ entity_history_revert_dialog_title: "¿Revertir datos a esta versión?",
13
+ entity_history_previous_value: "Valor anterior",
14
+ entity_history_see_details: "Ver detalles de esta revisión",
15
+ entity_history_just_now: "justo ahora",
16
+ entity_history_minutes_ago: "hace {{minutes}}m",
17
+ entity_history_hours_ago: "hace {{hours}}h",
18
+ entity_history_days_ago: "hace {{days}}d",
19
+ user_picture: "Foto de usuario"
20
+ };
@@ -0,0 +1,20 @@
1
+ export const entityHistoryTranslationsFr = {
2
+ history: "Historique",
3
+ entity_history_only_existing: "L'historique n'est disponible que pour les entités existantes",
4
+ entity_history_reverted: "Version restaurée",
5
+ entity_history_error_reverting: "Erreur lors de la restauration de l'entité",
6
+ entity_history_no_history: "Aucun historique disponible",
7
+ entity_history_when_save: "Lorsque vous enregistrez une entité, une nouvelle version est créée et stockée dans l'historique.",
8
+ entity_history_revert_tooltip: "Revenir à cette version",
9
+ entity_history_please_save: "Veuillez enregistrer ou annuler vos modifications avant de restaurer",
10
+ loading_more: "Chargement en cours...",
11
+ entity_history_no_more: "Aucun autre historique disponible",
12
+ entity_history_revert_dialog_title: "Restaurer les données à cette version ?",
13
+ entity_history_previous_value: "Valeur précédente",
14
+ entity_history_see_details: "Voir les détails de cette révision",
15
+ entity_history_just_now: "à l'instant",
16
+ entity_history_minutes_ago: "il y a {{minutes}}m",
17
+ entity_history_hours_ago: "il y a {{hours}}h",
18
+ entity_history_days_ago: "il y a {{days}}j",
19
+ user_picture: "Photo de l'utilisateur"
20
+ };
@@ -0,0 +1,20 @@
1
+ export const entityHistoryTranslationsHi = {
2
+ history: "इतिहास",
3
+ entity_history_only_existing: "इतिहास केवल मौजूद संस्थाओं के लिए उपलब्ध है",
4
+ entity_history_reverted: "परिवर्तित संस्करण",
5
+ entity_history_error_reverting: "संस्था को वापस लाने में त्रुटि",
6
+ entity_history_no_history: "कोई इतिहास उपलब्ध नहीं",
7
+ entity_history_when_save: "जब आप किसी संस्था को सहेजते हैं, तो एक नया संस्करण बनाया जाता है और इतिहास में संग्रहीत किया जाता है।",
8
+ entity_history_revert_tooltip: "इस संस्करण पर वापस जाएं",
9
+ entity_history_please_save: "कृपया वापस जाने से पहले अपने परिवर्तनों को सहेजें या हटा दें",
10
+ loading_more: "और लोड हो रहा है...",
11
+ entity_history_no_more: "कोई और इतिहास उपलब्ध नहीं",
12
+ entity_history_revert_dialog_title: "डेटा को इस संस्करण में वापस लाएँ?",
13
+ entity_history_previous_value: "पिछला मान",
14
+ entity_history_see_details: "इस संशोधन के लिए विवरण यहाँ देखें",
15
+ entity_history_just_now: "अभी-अभी",
16
+ entity_history_minutes_ago: "{{minutes}}m पहले",
17
+ entity_history_hours_ago: "{{hours}}h पहले",
18
+ entity_history_days_ago: "{{days}}d पहले",
19
+ user_picture: "उपयोगकर्ता चित्र"
20
+ };
@@ -0,0 +1,20 @@
1
+ export const entityHistoryTranslationsIt = {
2
+ history: "Cronologia",
3
+ entity_history_only_existing: "La cronologia è disponibile solo per le entità esistenti",
4
+ entity_history_reverted: "Versione ripristinata",
5
+ entity_history_error_reverting: "Errore durante il ripristino dell'entità",
6
+ entity_history_no_history: "Nessuna cronologia disponibile",
7
+ entity_history_when_save: "Quando salvi un'entità, viene creata una nuova versione e memorizzata nella cronologia.",
8
+ entity_history_revert_tooltip: "Ripristina a questa versione",
9
+ entity_history_please_save: "Salva o annulla le modifiche prima del ripristino",
10
+ loading_more: "Caricamento in corso...",
11
+ entity_history_no_more: "Nessuna ulteriore cronologia disponibile",
12
+ entity_history_revert_dialog_title: "Vuoi ripristinare i dati a questa versione?",
13
+ entity_history_previous_value: "Valore precedente",
14
+ entity_history_see_details: "Vedi i dettagli per questa revisione",
15
+ entity_history_just_now: "proprio adesso",
16
+ entity_history_minutes_ago: "{{minutes}} min fa",
17
+ entity_history_hours_ago: "{{hours}} h fa",
18
+ entity_history_days_ago: "{{days}} g fa",
19
+ user_picture: "Immagine utente"
20
+ };
@@ -0,0 +1,20 @@
1
+ export const entityHistoryTranslationsPt = {
2
+ history: "Histórico",
3
+ entity_history_only_existing: "O histórico está disponível apenas para entidades existentes",
4
+ entity_history_reverted: "Versão revertida",
5
+ entity_history_error_reverting: "Erro ao reverter entidade",
6
+ entity_history_no_history: "Sem histórico disponível",
7
+ entity_history_when_save: "Quando guarda uma entidade, é criada uma nova versão e armazenada no histórico.",
8
+ entity_history_revert_tooltip: "Reverter para esta versão",
9
+ entity_history_please_save: "Por favor guarde ou descarte as suas alterações antes de reverter",
10
+ loading_more: "A carregar mais...",
11
+ entity_history_no_more: "Sem mais histórico disponível",
12
+ entity_history_revert_dialog_title: "Reverter dados para esta versão?",
13
+ entity_history_previous_value: "Valor anterior",
14
+ entity_history_see_details: "Ver detalhes desta revisão",
15
+ entity_history_just_now: "agora mesmo",
16
+ entity_history_minutes_ago: "há {{minutes}}m",
17
+ entity_history_hours_ago: "há {{hours}}h",
18
+ entity_history_days_ago: "há {{days}}d",
19
+ user_picture: "Foto do utilizador"
20
+ };
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { FireCMSContext, User } from "@firecms/core";
1
+ import { EntityCollection, FireCMSContext, User } from "@firecms/core";
2
2
 
3
3
  export type HistoryEntryMetadata<T> = {
4
4
  previous_values?: Partial<T>;
@@ -17,4 +17,5 @@ export interface NewHistoryEntryParams<T = any> {
17
17
  values: Partial<T>;
18
18
  path: string;
19
19
  entityId: string;
20
+ collection?: EntityCollection;
20
21
  }
@@ -1,27 +1,35 @@
1
1
  import { useCallback, useMemo } from "react";
2
- import { EntityCollection, FireCMSPlugin, mergeCallbacks, User } from "@firecms/core";
2
+ import { EntityCollection, FireCMSPlugin, mergeCallbacks, User, useTranslation } from "@firecms/core";
3
3
  import { EntityHistoryView } from "./components/EntityHistoryView";
4
4
  import { HistoryIcon } from "@firecms/ui";
5
5
  import { entityHistoryCallbacks } from "./entity_history_callbacks";
6
6
  import { HistoryControllerProvider } from "./HistoryControllerProvider";
7
+ import { LastEditedByFormAction } from "./components/LastEditedByPluginComponents";
8
+ import { entityHistoryTranslationsEn } from "./locales/en";
9
+ import { entityHistoryTranslationsEs } from "./locales/es";
10
+ import { entityHistoryTranslationsDe } from "./locales/de";
11
+ import { entityHistoryTranslationsFr } from "./locales/fr";
12
+ import { entityHistoryTranslationsIt } from "./locales/it";
13
+ import { entityHistoryTranslationsHi } from "./locales/hi";
14
+ import { entityHistoryTranslationsPt } from "./locales/pt";
7
15
 
8
16
  /**
9
17
  * This plugin adds a history view to the entity side panel.
10
18
  */
11
19
  export function useEntityHistoryPlugin(props?: EntityHistoryPluginProps): FireCMSPlugin<any, any, any, EntityHistoryPluginProps> {
12
-
13
20
  const { defaultEnabled = false } = props ?? {};
14
21
 
15
22
  const modifyCollection = useCallback((collection: EntityCollection) => {
16
23
  if (collection.history === true || (defaultEnabled && collection.history !== false)) {
17
24
  return {
18
25
  ...collection,
26
+ history: true,
19
27
  entityViews: [
20
28
  ...(collection.entityViews ?? []),
21
29
  {
22
30
  key: "__history",
23
31
  name: "History",
24
- tabComponent: <HistoryIcon size={"small"}/>,
32
+ tabComponent: <HistoryIcon size={"small"} />,
25
33
  Builder: EntityHistoryView,
26
34
  position: "start"
27
35
  }
@@ -40,8 +48,20 @@ export function useEntityHistoryPlugin(props?: EntityHistoryPluginProps): FireCM
40
48
  getUser: props?.getUser
41
49
  }
42
50
  },
51
+ form: {
52
+ BeforeTitle: LastEditedByFormAction
53
+ },
43
54
  collection: {
44
55
  modifyCollection
56
+ },
57
+ i18n: {
58
+ en: entityHistoryTranslationsEn,
59
+ es: entityHistoryTranslationsEs,
60
+ de: entityHistoryTranslationsDe,
61
+ fr: entityHistoryTranslationsFr,
62
+ it: entityHistoryTranslationsIt,
63
+ hi: entityHistoryTranslationsHi,
64
+ pt: entityHistoryTranslationsPt
45
65
  }
46
66
  } satisfies FireCMSPlugin), [props]);
47
67
  }