diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 85541bd2..1eca7964 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -55,6 +55,7 @@ "@vitest/ui": "4.1.8", "deepmerge": "4.3.1", "eslint": "9.39.2", + "eslint-plugin-i18next": "6.1.4", "eslint-plugin-react-hooks": "7.1.1", "i18next-cli": "1.34.1", "jsdom": "27.4.0", @@ -13905,6 +13906,20 @@ } } }, + "node_modules/eslint-plugin-i18next": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-i18next/-/eslint-plugin-i18next-6.1.4.tgz", + "integrity": "sha512-BekXQu1VaVFkREepQGsntBYoKuPsf89V16n/s2xpKMtsw0/lDseds1wBhj3RtO1dKnHsfTPaG+xul1vF0R7LEQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "lodash": "^4.17.21", + "requireindex": "~1.1.0" + }, + "engines": { + "node": ">=18.10.0" + } + }, "node_modules/eslint-plugin-react-hooks": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", @@ -21266,6 +21281,16 @@ "node": ">=0.10.0" } }, + "node_modules/requireindex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", + "integrity": "sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.5" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", diff --git a/src/frontend/package.json b/src/frontend/package.json index c2410c6d..163789fb 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -73,6 +73,7 @@ "@vitest/ui": "4.1.8", "deepmerge": "4.3.1", "eslint": "9.39.2", + "eslint-plugin-i18next": "6.1.4", "eslint-plugin-react-hooks": "7.1.1", "i18next-cli": "1.34.1", "jsdom": "27.4.0", diff --git a/src/frontend/src/features/controlled-modals/message-importer/step-completed.tsx b/src/frontend/src/features/controlled-modals/message-importer/step-completed.tsx index aebae116..517511d3 100644 --- a/src/frontend/src/features/controlled-modals/message-importer/step-completed.tsx +++ b/src/frontend/src/features/controlled-modals/message-importer/step-completed.tsx @@ -1,4 +1,5 @@ import { Button } from "@gouvfr-lasuite/cunningham-react"; +import { Icon } from "@gouvfr-lasuite/ui-kit"; import { useTranslation } from "react-i18next"; import { ImportTaskRecap } from "@/hooks/use-task-status"; import clsx from "clsx"; @@ -26,9 +27,7 @@ export const StepCompleted = ({ onClose, recap }: StepCompletedProps) => { 'importer-completed__badge', { 'importer-completed__badge--warning': showFailureWarning } )}> - - {showFailureWarning ? 'report_problem' : 'check'} - +

{t('Import complete')}

@@ -56,13 +55,12 @@ export const StepCompleted = ({ onClose, recap }: StepCompletedProps) => { {t('Failed: {{count}} messages', { count: failure })} {showFailureWarning && ( - - report_problem - + /> )} )} diff --git a/src/frontend/src/features/controlled-modals/message-importer/step-form.tsx b/src/frontend/src/features/controlled-modals/message-importer/step-form.tsx index 0b8f8a24..72aeeb26 100644 --- a/src/frontend/src/features/controlled-modals/message-importer/step-form.tsx +++ b/src/frontend/src/features/controlled-modals/message-importer/step-form.tsx @@ -3,7 +3,7 @@ import z from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { FormProvider, useForm, useWatch } from "react-hook-form"; import { Button } from "@gouvfr-lasuite/cunningham-react"; -import { Spinner } from "@gouvfr-lasuite/ui-kit"; +import { Icon, Spinner } from "@gouvfr-lasuite/ui-kit"; import { useTranslation } from "react-i18next"; import { useParams } from "@tanstack/react-router"; import { importFileCreateResponse202, importImapCreateResponse202, useImportFileCreate, useImportImapCreate } from "@/features/api/gen"; @@ -277,8 +277,8 @@ export const StepForm = ({ onUploading, onSuccess, onError, error, step }: StepF inventory_2} - fileSelectedIcon={inventory_2} + icon={} + fileSelectedIcon={} bigText={t('Drag and drop an archive here')} text={t('EML, MBOX or PST')} fullWidth diff --git a/src/frontend/src/features/forms/components/message-form/dropzone.tsx b/src/frontend/src/features/forms/components/message-form/dropzone.tsx index d75dff46..87930b93 100644 --- a/src/frontend/src/features/forms/components/message-form/dropzone.tsx +++ b/src/frontend/src/features/forms/components/message-form/dropzone.tsx @@ -1,3 +1,4 @@ +import { Icon } from "@gouvfr-lasuite/ui-kit"; import clsx from "clsx"; import { useTranslation } from "react-i18next"; @@ -10,7 +11,7 @@ export const DropZone = ({ isHidden }: DropZoneProps) => { return (
- file_download + {t("Drop your attachments here")}
); diff --git a/src/frontend/src/features/forms/components/message-form/index.tsx b/src/frontend/src/features/forms/components/message-form/index.tsx index 68ef3a91..54d3e21e 100644 --- a/src/frontend/src/features/forms/components/message-form/index.tsx +++ b/src/frontend/src/features/forms/components/message-form/index.tsx @@ -679,14 +679,13 @@ export const MessageForm = ({ name="to" label={t("To:")} autoFocus={mode === "forward"} - // icon={group} text={form.formState.errors.to && !Array.isArray(form.formState.errors.to) ? form.formState.errors.to.message : t("Enter the email addresses of the recipients separated by commas")} textItems={Array.isArray(form.formState.errors.to) ? form.formState.errors.to?.map((error, index) => t(error!.message as string, { email: form.getValues('to')?.[index] })) : []} disabled={!canWriteMessages} rightText={
- - + +
as unknown as string // TODO: Allow ReactNode as rightText in Cunningham } fullWidth @@ -699,7 +698,6 @@ export const MessageForm = ({ group} text={form.formState.errors.cc && !Array.isArray(form.formState.errors.cc) ? t(form.formState.errors.cc.message as string) : t("Enter the email addresses of the recipients separated by commas")} textItems={Array.isArray(form.formState.errors.cc) ? form.formState.errors.cc?.map((error, index) => t(error!.message as string, { email: form.getValues('cc')?.[index] })) : []} disabled={!canWriteMessages} @@ -714,7 +712,6 @@ export const MessageForm = ({ visibility_off} text={form.formState.errors.bcc && !Array.isArray(form.formState.errors.bcc) ? t(form.formState.errors.bcc.message as string) : t("Enter the email addresses of the recipients separated by commas")} textItems={Array.isArray(form.formState.errors.bcc) ? form.formState.errors.bcc?.map((error, index) => t(error!.message as string, { email: form.getValues('bcc')?.[index] })) : []} disabled={!canWriteMessages} diff --git a/src/frontend/src/features/forms/components/search-filters-form/index.tsx b/src/frontend/src/features/forms/components/search-filters-form/index.tsx index 6717e66b..8de1f9cf 100644 --- a/src/frontend/src/features/forms/components/search-filters-form/index.tsx +++ b/src/frontend/src/features/forms/components/search-filters-form/index.tsx @@ -1,6 +1,6 @@ import { ALL_MESSAGES_FOLDER, MAILBOX_FOLDERS } from "@/features/layouts/components/mailbox-panel/components/mailbox-list"; import { SearchHelper } from "@/features/utils/search-helper"; -import { Label } from "@gouvfr-lasuite/ui-kit"; +import { Icon, Label } from "@gouvfr-lasuite/ui-kit"; import { Button, Checkbox, Input, Select } from "@gouvfr-lasuite/cunningham-react"; import { useId, useRef } from "react"; import { useTranslation } from "react-i18next"; @@ -111,7 +111,7 @@ type FolderOptionProps = { const FolderOption = ({ label, icon }: FolderOptionProps) => { return (
- {icon} + {label}
); diff --git a/src/frontend/src/features/forms/components/search-input/index.tsx b/src/frontend/src/features/forms/components/search-input/index.tsx index 2ba30cf6..0bab73eb 100644 --- a/src/frontend/src/features/forms/components/search-input/index.tsx +++ b/src/frontend/src/features/forms/components/search-input/index.tsx @@ -103,7 +103,7 @@ export const SearchInput = () => { title={t("Reset")} size="small" > - close + {t("Reset")} )} @@ -114,7 +114,7 @@ export const SearchInput = () => { title={showFilters ? t("Close filters") : t("Open filters")} size="small" > - tune + {showFilters ? t("Close filters") : t("Open filters")}
diff --git a/src/frontend/src/features/layouts/components/admin/admin-layout.tsx b/src/frontend/src/features/layouts/components/admin/admin-layout.tsx index b4c7049a..1476ac56 100644 --- a/src/frontend/src/features/layouts/components/admin/admin-layout.tsx +++ b/src/frontend/src/features/layouts/components/admin/admin-layout.tsx @@ -127,6 +127,7 @@ function AdminLayoutContent({ export function AdminLayout(props: AdminLayoutProps) { const { theme, variant } = useTheme(); + const { t } = useTranslation(); return ( @@ -136,7 +137,7 @@ export function AdminLayout(props: AdminLayoutProps) { leftPanelContent={null} hideSearch hideLeftPanelOnDesktop={true} - icon={logo} + icon={{t("logo")}} > diff --git a/src/frontend/src/features/layouts/components/mailbox-panel/components/mailbox-labels/components/label-form-modal/components/color-palette-field/index.tsx b/src/frontend/src/features/layouts/components/mailbox-panel/components/mailbox-labels/components/label-form-modal/components/color-palette-field/index.tsx index d3d957ad..9f79c4e8 100644 --- a/src/frontend/src/features/layouts/components/mailbox-panel/components/mailbox-labels/components/label-form-modal/components/color-palette-field/index.tsx +++ b/src/frontend/src/features/layouts/components/mailbox-panel/components/mailbox-labels/components/label-form-modal/components/color-palette-field/index.tsx @@ -57,6 +57,7 @@ export const RhfColorPaletteField = (props: { name: string }) => { htmlFor="color" style={{ '--char-color': charColor } as React.CSSProperties} > + {/* eslint-disable-next-line i18next/no-literal-string */} a edit, + icon: , callback: () => onEdit(label), }, { label: t('Add a sub-label'), - icon: add, + icon: , callback: () => onEdit({ name: `${label.name}/`, color: label.color }), showSeparator: true, }, { label: t('Delete'), - icon: delete, + icon: , callback: handleDelete, variant: 'danger' }, diff --git a/src/frontend/src/features/layouts/components/thread-panel/components/thread-panel-header.tsx b/src/frontend/src/features/layouts/components/thread-panel/components/thread-panel-header.tsx index 0f6a78c3..67d78eaa 100644 --- a/src/frontend/src/features/layouts/components/thread-panel/components/thread-panel-header.tsx +++ b/src/frontend/src/features/layouts/components/thread-panel/components/thread-panel-header.tsx @@ -306,7 +306,7 @@ const ThreadPanelTitle = ({ selectedThreadIds, isAllSelected, isSomeSelected, is }, ...([SelectionReadStatus.MIXED, SelectionReadStatus.UNREAD].includes(selectionReadStatus) ? [{ label: markAllTooltip, - icon: drafts, + icon: , callback: () => { markAsReadAt({ threadIds: threadIdsToMark, @@ -320,7 +320,7 @@ const ThreadPanelTitle = ({ selectedThreadIds, isAllSelected, isSomeSelected, is }] : []), ...([SelectionReadStatus.MIXED, SelectionReadStatus.READ, SelectionReadStatus.NONE].includes(selectionReadStatus) ? [{ label: markAllUnreadLabel, - icon: mark_email_unread, + icon: , callback: () => { // Close the open thread before the mutation so the visibility // observer cannot re-mark the newly-unread messages as read. @@ -363,7 +363,7 @@ const ThreadPanelTitle = ({ selectedThreadIds, isAllSelected, isSomeSelected, is ))} {closeButton && ( @@ -66,7 +67,7 @@ export const ToasterItem = ({ color={buttonColor} variant="tertiary" size="small" - icon={close} + icon={} > )} diff --git a/src/frontend/src/features/utils/text-helper/index.test.tsx b/src/frontend/src/features/utils/text-helper/index.test.tsx index f5f6e734..9a7d7762 100644 --- a/src/frontend/src/features/utils/text-helper/index.test.tsx +++ b/src/frontend/src/features/utils/text-helper/index.test.tsx @@ -1,3 +1,4 @@ +/* eslint-disable i18next/no-literal-string */ import React from "react"; import { describe, it, expect } from "vitest"; import { renderToStaticMarkup } from "react-dom/server"; diff --git a/src/frontend/src/routes/index.tsx b/src/frontend/src/routes/index.tsx index 6133bbf4..cbb393a1 100644 --- a/src/frontend/src/routes/index.tsx +++ b/src/frontend/src/routes/index.tsx @@ -25,12 +25,12 @@ const HomePage = () => { hideLeftPanelOnDesktop leftPanelContent={} rightHeaderContent={} - icon={logo} + icon={{t("logo")}} >