From 27cac1fe0ffe3dc7552400842174ac6b225d320e Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Tue, 30 Sep 2025 19:42:12 -0400 Subject: [PATCH 1/5] Add i18n support for Tabs --- src/i18n/locales/en/translation.json | 7 +++++ src/i18n/locales/es/translation.json | 7 +++++ src/i18n/locales/he/translation.json | 7 +++++ src/reactComponents/Tabs.tsx | 40 +++++++++++++--------------- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index 2cea6220..46ccb0f2 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -69,6 +69,13 @@ "COPY_TYPE_TITLE": "Copy {{type}}: {{title}}", "RENAME": "Rename", "NO_FILES_FOUND": "No {{type}} files found", + "DELETE": "Delete", + "CANCEL": "Cancel", + "CLOSE_TAB": "Close Tab", + "CLOSE_OTHER_TABS": "Close Other tabs", + "RENAME_ELLIPSIS": "Rename...", + "DELETE_ELLIPSIS": "Delete...", + "COPY_ELLIPSIS": "Copy...", "MECHANISMS": "Mechanisms", "OPMODES": "OpModes", "BLOCKLY":{ diff --git a/src/i18n/locales/es/translation.json b/src/i18n/locales/es/translation.json index ebb5764c..22cc14c5 100644 --- a/src/i18n/locales/es/translation.json +++ b/src/i18n/locales/es/translation.json @@ -66,6 +66,13 @@ "COPY_TYPE_TITLE": "Copiar {{type}}: {{title}}", "RENAME": "Renombrar", "NO_FILES_FOUND": "No se encontraron archivos de {{type}}", + "DELETE": "Eliminar", + "CANCEL": "Cancelar", + "CLOSE_TAB": "Cerrar Pestaña", + "CLOSE_OTHER_TABS": "Cerrar Otras Pestañas", + "RENAME_ELLIPSIS": "Renombrar...", + "DELETE_ELLIPSIS": "Eliminar...", + "COPY_ELLIPSIS": "Copiar...", "addTabDialog": { "title": "Agregar Pestaña", "search": "Buscar..." diff --git a/src/i18n/locales/he/translation.json b/src/i18n/locales/he/translation.json index dbd63d19..0d4b471b 100644 --- a/src/i18n/locales/he/translation.json +++ b/src/i18n/locales/he/translation.json @@ -69,6 +69,13 @@ "COPY_TYPE_TITLE": "העתקת {{type}}: {{title}}", "RENAME": "שנה שם", "NO_FILES_FOUND": "לא נמצאו קבצי {{type}}", + "DELETE": "מחק", + "CANCEL": "בטל", + "CLOSE_TAB": "סגור לשונית", + "CLOSE_OTHER_TABS": "סגור לשוניות אחרות", + "RENAME_ELLIPSIS": "שנה שם...", + "DELETE_ELLIPSIS": "מחק...", + "COPY_ELLIPSIS": "העתק...", "MECHANISMS": "מנגנונים", "OPMODES": "אופמודים", "BLOCKLY": { diff --git a/src/reactComponents/Tabs.tsx b/src/reactComponents/Tabs.tsx index dfe96c53..918b54ed 100644 --- a/src/reactComponents/Tabs.tsx +++ b/src/reactComponents/Tabs.tsx @@ -56,7 +56,7 @@ export interface TabsProps { } /** Default copy suffix for tab names. */ -const COPY_SUFFIX = 'Copy'; +const COPY_SUFFIX = ' (copy)'; /** Minimum number of tabs required to show close others option. */ const MIN_TABS_FOR_CLOSE_OTHERS = 2; @@ -186,7 +186,7 @@ export function Component(props: TabsProps): React.JSX.Element { triggerProjectUpdate(); } catch (error) { console.error('Error renaming module:', error); - props.setAlertErrorMessage('Failed to rename module'); + props.setAlertErrorMessage(t('FAILED_TO_RENAME_MODULE')); } setRenameModalOpen(false); @@ -213,7 +213,7 @@ export function Component(props: TabsProps): React.JSX.Element { if (!originalTab) { console.error('Original tab not found for copying:', key); - props.setAlertErrorMessage('Original tab not found for copying'); + props.setAlertErrorMessage(t('MODULE_NOT_FOUND_FOR_COPYING')); return; } @@ -223,7 +223,7 @@ export function Component(props: TabsProps): React.JSX.Element { triggerProjectUpdate(); } catch (error) { console.error('Error copying module:', error); - props.setAlertErrorMessage('Failed to copy module'); + props.setAlertErrorMessage(t('FAILED_TO_COPY_MODULE')); } setCopyModalOpen(false); @@ -260,11 +260,11 @@ export function Component(props: TabsProps): React.JSX.Element { const titleToShow = currentTab ? currentTab.title : tab.title; modal.confirm({ - title: `${t('Delete')} ${TabTypeUtils.toString(tab.type)}: ${titleToShow}`, - content: t('Are you sure you want to delete this? This action cannot be undone.'), - okText: t('Delete'), + title: t('DELETE_MODULE_CONFIRM', { title: `${TabTypeUtils.toString(tab.type)}: ${titleToShow}` }), + content: t('DELETE_CANNOT_BE_UNDONE'), + okText: t('DELETE'), okType: 'danger', - cancelText: t('Cancel'), + cancelText: t('CANCEL'), onOk: async (): Promise => { const newTabs = props.tabList.filter((t) => t.key !== tab.key); props.setTabList(newTabs); @@ -290,35 +290,35 @@ export function Component(props: TabsProps): React.JSX.Element { const createTabContextMenuItems = (tab: TabItem): any[] => [ { key: 'close', - label: t('Close Tab'), + label: t('CLOSE_TAB'), onClick: () => handleTabEdit(tab.key, 'remove'), disabled: tab.type === TabType.ROBOT, icon: , }, { key: 'close-others', - label: t('Close Other tabs'), + label: t('CLOSE_OTHER_TABS'), onClick: () => handleCloseOtherTabs(tab.key), disabled: props.tabList.length <= getMinTabsForCloseOthers(tab.type), icon: , }, { key: 'rename', - label: t('Rename...'), + label: t('RENAME_ELLIPSIS'), disabled: tab.type === TabType.ROBOT, onClick: () => handleOpenRenameModal(tab), icon: , }, { key: 'delete', - label: t('Delete...'), + label: t('DELETE_ELLIPSIS'), disabled: tab.type === TabType.ROBOT, icon: , onClick: () => handleDeleteTab(tab), }, { key: 'copy', - label: t('Copy...'), + label: t('COPY_ELLIPSIS'), disabled: tab.type === TabType.ROBOT, icon: , onClick: () => handleOpenCopyModal(tab), @@ -366,8 +366,7 @@ export function Component(props: TabsProps): React.JSX.Element { /> setRenameModalOpen(false)} onOk={() => { @@ -375,8 +374,8 @@ export function Component(props: TabsProps): React.JSX.Element { handleRename(currentTab.key, name); } }} - okText={t('Rename')} - cancelText={t('Cancel')} + okText={t('RENAME')} + cancelText={t('CANCEL')} > {currentTab && ( setCopyModalOpen(false)} onOk={() => { @@ -405,8 +403,8 @@ export function Component(props: TabsProps): React.JSX.Element { handleCopy(currentTab.key, name); } }} - okText={t('Copy')} - cancelText={t('Cancel')} + okText={t('COPY')} + cancelText={t('CANCEL')} > {currentTab && ( Date: Tue, 30 Sep 2025 19:47:23 -0400 Subject: [PATCH 2/5] Add i18n support for ThemeModal --- src/i18n/locales/en/translation.json | 20 ++++++ src/i18n/locales/es/translation.json | 20 ++++++ src/i18n/locales/he/translation.json | 20 ++++++ src/reactComponents/ThemeModal.tsx | 95 ++++++++++++++-------------- 4 files changed, 109 insertions(+), 46 deletions(-) diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index 46ccb0f2..5ad45c38 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -78,6 +78,26 @@ "COPY_ELLIPSIS": "Copy...", "MECHANISMS": "Mechanisms", "OPMODES": "OpModes", + "THEME_MODAL": { + "LIGHT": "Light Theme", + "LIGHT_DESCRIPTION": "Clean and bright interface for daytime use", + "DARK": "Dark Theme", + "DARK_DESCRIPTION": "Easy on the eyes for low-light environments", + "TRITANOPIA": "Tritanopia Theme", + "TRITANOPIA_DESCRIPTION": "Designed for those with Tritanopia color blindness", + "TRITANOPIA_DARK": "Tritanopia Dark", + "TRITANOPIA_DARK_DESCRIPTION": "Dark theme for those with Tritanopia color blindness", + "DEUTERANOPIA": "Deuteranopia Theme", + "DEUTERANOPIA_DESCRIPTION": "Designed for those with Deuteranopia color blindness", + "DEUTERANOPIA_DARK": "Deuteranopia Dark", + "DEUTERANOPIA_DARK_DESCRIPTION": "Dark theme for those with Deuteranopia color blindness", + "SELECTION": "Theme Selection", + "APPLY": "Apply Theme", + "CHOOSE_DESCRIPTION": "Choose a theme that best suits your preference and working environment.", + "PRIMARY_BUTTON": "Primary", + "PREVIEW": "Theme Preview", + "PREVIEW_DESCRIPTION": "The selected theme will be applied to the entire application interface." + }, "BLOCKLY":{ "OF_TYPE": "of type", "WITH": "with", diff --git a/src/i18n/locales/es/translation.json b/src/i18n/locales/es/translation.json index 22cc14c5..c0712263 100644 --- a/src/i18n/locales/es/translation.json +++ b/src/i18n/locales/es/translation.json @@ -79,6 +79,26 @@ }, "MECHANISMS": "Mecanismos", "OPMODES": "OpModes", + "THEME_MODAL": { + "LIGHT": "Tema Claro", + "LIGHT_DESCRIPTION": "Interfaz limpia y brillante para uso diurno", + "DARK": "Tema Oscuro", + "DARK_DESCRIPTION": "Fácil para los ojos en ambientes de poca luz", + "TRITANOPIA": "Tema Tritanopia", + "TRITANOPIA_DESCRIPTION": "Diseñado para personas con daltonismo Tritanopia", + "TRITANOPIA_DARK": "Tritanopia Oscuro", + "TRITANOPIA_DARK_DESCRIPTION": "Tema oscuro para personas con daltonismo Tritanopia", + "DEUTERANOPIA": "Tema Deuteranopia", + "DEUTERANOPIA_DESCRIPTION": "Diseñado para personas con daltonismo Deuteranopia", + "DEUTERANOPIA_DARK": "Deuteranopia Oscuro", + "DEUTERANOPIA_DARK_DESCRIPTION": "Tema oscuro para personas con daltonismo Deuteranopia", + "SELECTION": "Selección de Tema", + "APPLY": "Aplicar Tema", + "CHOOSE_DESCRIPTION": "Elija un tema que mejor se adapte a sus preferencias y entorno de trabajo.", + "PRIMARY_BUTTON": "Primario", + "PREVIEW": "Vista Previa del Tema", + "PREVIEW_DESCRIPTION": "El tema seleccionado se aplicará a toda la interfaz de la aplicación." + }, "BLOCKLY": { "OF_TYPE": "de tipo", "WITH": "con", diff --git a/src/i18n/locales/he/translation.json b/src/i18n/locales/he/translation.json index 0d4b471b..38ccc4da 100644 --- a/src/i18n/locales/he/translation.json +++ b/src/i18n/locales/he/translation.json @@ -78,6 +78,26 @@ "COPY_ELLIPSIS": "העתק...", "MECHANISMS": "מנגנונים", "OPMODES": "אופמודים", + "THEME_MODAL": { + "LIGHT": "ערכת נושא בהירה", + "LIGHT_DESCRIPTION": "ממשק נקי ובהיר לשימוש ביום", + "DARK": "ערכת נושא כהה", + "DARK_DESCRIPTION": "קל על העיניים בסביבות עם תאורה נמוכה", + "TRITANOPIA": "ערכת נושא טריטנופיה", + "TRITANOPIA_DESCRIPTION": "מעוצב עבור אנשים עם עיוורון צבעים טריטנופיה", + "TRITANOPIA_DARK": "טריטנופיה כהה", + "TRITANOPIA_DARK_DESCRIPTION": "ערכת נושא כהה עבור אנשים עם עיוורון צבעים טריטנופיה", + "DEUTERANOPIA": "ערכת נושא דיוטרנופיה", + "DEUTERANOPIA_DESCRIPTION": "מעוצב עבור אנשים עם עיוורון צבעים דיוטרנופיה", + "DEUTERANOPIA_DARK": "דיוטרנופיה כהה", + "DEUTERANOPIA_DARK_DESCRIPTION": "ערכת נושא כהה עבור אנשים עם עיוורון צבעים דיוטרנופיה", + "SELECTION": "בחירת ערכת נושא", + "APPLY": "החל ערכת נושא", + "CHOOSE_DESCRIPTION": "בחר ערכת נושא שמתאימה ביותר להעדפותיך וסביבת העבודה שלך.", + "PRIMARY_BUTTON": "ראשי", + "PREVIEW": "תצוגה מקדימה של ערכת נושא", + "PREVIEW_DESCRIPTION": "ערכת הנושא הנבחרת תוחל על כל ממשק האפליקציה." + }, "BLOCKLY": { "OF_TYPE": "מטיפוס", "WITH": "עם", diff --git a/src/reactComponents/ThemeModal.tsx b/src/reactComponents/ThemeModal.tsx index f93823a4..1e5d016e 100644 --- a/src/reactComponents/ThemeModal.tsx +++ b/src/reactComponents/ThemeModal.tsx @@ -4,6 +4,8 @@ import * as React from 'react'; import * as Antd from 'antd'; +import * as I18Next from 'react-i18next'; + import { BgColorsOutlined, CheckOutlined, @@ -25,53 +27,54 @@ export interface ThemeModalProps { onThemeChange: (themeKey: string) => void; } -const THEME_OPTIONS: ThemeOption[] = [ - { - key: 'light', - name: 'Light Theme', - icon: , - description: 'Clean and bright interface for daytime use', - }, - { - key: 'dark', - name: 'Dark Theme', - icon: , - description: 'Easy on the eyes for low-light environments', - }, - { - key: 'tritanopia', - name: 'Tritanopia Theme', - icon: , - description: 'Designed for those with Tritanopia color blindness', - }, - { - key: 'tritanopia-dark', - name: 'Tritanopia Dark', - icon: , - description: 'Dark theme for those with Tritanopia color blindness', - }, - { - key: 'deuteranopia', - name: 'Deuteranopia Theme', - icon: , - description: 'Designed for those with Deuteranopia color blindness', - }, - { - key: 'deuteranopia-dark', - name: 'Deuteranopia Dark', - icon: , - description: 'Dark theme for those with Deuteranopia color blindness', - }, -]; - const ThemeModal: React.FC = ({ open, onClose, currentTheme, onThemeChange, }) => { + const { t } = I18Next.useTranslation(); const [selectedTheme, setSelectedTheme] = React.useState(currentTheme); + const THEME_OPTIONS: ThemeOption[] = [ + { + key: 'light', + name: t('THEME_MODAL.LIGHT'), + icon: , + description: t('THEME_MODAL.LIGHT_DESCRIPTION'), + }, + { + key: 'dark', + name: t('THEME_MODAL.DARK'), + icon: , + description: t('THEME_MODAL.DARK_DESCRIPTION'), + }, + { + key: 'tritanopia', + name: t('THEME_MODAL.TRITANOPIA'), + icon: , + description: t('THEME_MODAL.TRITANOPIA_DESCRIPTION'), + }, + { + key: 'tritanopia-dark', + name: t('THEME_MODAL.TRITANOPIA_DARK'), + icon: , + description: t('THEME_MODAL.TRITANOPIA_DARK_DESCRIPTION'), + }, + { + key: 'deuteranopia', + name: t('THEME_MODAL.DEUTERANOPIA'), + icon: , + description: t('THEME_MODAL.DEUTERANOPIA_DESCRIPTION'), + }, + { + key: 'deuteranopia-dark', + name: t('THEME_MODAL.DEUTERANOPIA_DARK'), + icon: , + description: t('THEME_MODAL.DEUTERANOPIA_DARK_DESCRIPTION'), + }, + ]; + React.useEffect(() => { setSelectedTheme(currentTheme); }, [currentTheme]); @@ -95,14 +98,14 @@ const ThemeModal: React.FC = ({ title={
- Theme Selection + {t('THEME_MODAL.SELECTION')}
} open={open} onCancel={handleCancel} footer={[ - Cancel + {t('CANCEL')} , = ({ onClick={handleApplyTheme} disabled={selectedTheme === currentTheme} > - Apply Theme + {t('THEME_MODAL.APPLY')} , ]} width={600} @@ -118,7 +121,7 @@ const ThemeModal: React.FC = ({ >
- Choose a theme that best suits your preference and working environment. + {t('THEME_MODAL.CHOOSE_DESCRIPTION')} @@ -176,7 +179,7 @@ const ThemeModal: React.FC = ({
- Primary + {t('THEME_MODAL.PRIMARY_BUTTON')}
@@ -190,8 +193,8 @@ const ThemeModal: React.FC = ({ Date: Tue, 30 Sep 2025 19:50:06 -0400 Subject: [PATCH 3/5] Added translations for the error that can come from project.ts --- src/i18n/locales/en/translation.json | 2 ++ src/i18n/locales/es/translation.json | 2 ++ src/i18n/locales/he/translation.json | 2 ++ src/reactComponents/ClassNameComponent.tsx | 2 +- src/storage/project.ts | 7 ++++--- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index 5ad45c38..62fafe31 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -78,6 +78,8 @@ "COPY_ELLIPSIS": "Copy...", "MECHANISMS": "Mechanisms", "OPMODES": "OpModes", + "INVALID_CLASS_NAME": "{{name}} is not a valid name. Please enter a different name.", + "CLASS_NAME_ALREADY_EXISTS": "Another Mechanism or OpMode is already named {{name}}. Please enter a different name.", "THEME_MODAL": { "LIGHT": "Light Theme", "LIGHT_DESCRIPTION": "Clean and bright interface for daytime use", diff --git a/src/i18n/locales/es/translation.json b/src/i18n/locales/es/translation.json index c0712263..e2fdd6fb 100644 --- a/src/i18n/locales/es/translation.json +++ b/src/i18n/locales/es/translation.json @@ -79,6 +79,8 @@ }, "MECHANISMS": "Mecanismos", "OPMODES": "OpModes", + "INVALID_CLASS_NAME": "{{name}} no es un nombre válido. Por favor ingrese un nombre diferente.", + "CLASS_NAME_ALREADY_EXISTS": "Otro Mecanismo u OpMode ya se llama {{name}}. Por favor ingrese un nombre diferente.", "THEME_MODAL": { "LIGHT": "Tema Claro", "LIGHT_DESCRIPTION": "Interfaz limpia y brillante para uso diurno", diff --git a/src/i18n/locales/he/translation.json b/src/i18n/locales/he/translation.json index 38ccc4da..be87d8a7 100644 --- a/src/i18n/locales/he/translation.json +++ b/src/i18n/locales/he/translation.json @@ -78,6 +78,8 @@ "COPY_ELLIPSIS": "העתק...", "MECHANISMS": "מנגנונים", "OPMODES": "אופמודים", + "INVALID_CLASS_NAME": "{{name}} אינו שם תקין. אנא הזן שם אחר.", + "CLASS_NAME_ALREADY_EXISTS": "מנגנון או אופמוד אחר כבר נקרא {{name}}. אנא הזן שם אחר.", "THEME_MODAL": { "LIGHT": "ערכת נושא בהירה", "LIGHT_DESCRIPTION": "ממשק נקי ובהיר לשימוש ביום", diff --git a/src/reactComponents/ClassNameComponent.tsx b/src/reactComponents/ClassNameComponent.tsx index 16111e88..1af278b5 100644 --- a/src/reactComponents/ClassNameComponent.tsx +++ b/src/reactComponents/ClassNameComponent.tsx @@ -66,7 +66,7 @@ export default function ClassNameComponent(props: ClassNameComponentProps): Reac return; } - const {ok, error} = storageProject.isClassNameOk(props.project, newClassName); + const {ok, error} = storageProject.isClassNameOk(props.project, newClassName, t); if (ok) { clearError(); props.onAddNewItem(); diff --git a/src/storage/project.ts b/src/storage/project.ts index 78645074..caafcf16 100644 --- a/src/storage/project.ts +++ b/src/storage/project.ts @@ -322,18 +322,19 @@ export async function copyModuleInProject( * Checks if the proposed class name is valid and does not conflict with existing names in the project. * @param project The project to check against. * @param proposedClassName The proposed class name to validate. + * @param t Translation function for internationalized error messages. * @returns An object containing a boolean `ok` indicating if the name is valid, and an `error` message if it is not. */ -export function isClassNameOk(project: Project, proposedClassName: string) { +export function isClassNameOk(project: Project, proposedClassName: string, t: (key: string, params?: any) => string) { let ok = true; let error = ''; if (!storageNames.isValidClassName(proposedClassName)) { ok = false; - error = proposedClassName + ' is not a valid name. Please enter a different name.'; + error = t('INVALID_CLASS_NAME', { name: proposedClassName }); } else if (findModuleByClassName(project, proposedClassName) != null) { ok = false; - error = 'Another Mechanism or OpMode is already named ' + proposedClassName + '. Please enter a different name.' + error = t('CLASS_NAME_ALREADY_EXISTS', { name: proposedClassName }); } return { From c541ebf18b56572879b5926c6cdabc9c5550bbf3 Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Fri, 3 Oct 2025 09:48:07 -0400 Subject: [PATCH 4/5] Change back to Copy suffix --- src/reactComponents/Tabs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactComponents/Tabs.tsx b/src/reactComponents/Tabs.tsx index 918b54ed..f1fec91f 100644 --- a/src/reactComponents/Tabs.tsx +++ b/src/reactComponents/Tabs.tsx @@ -56,7 +56,7 @@ export interface TabsProps { } /** Default copy suffix for tab names. */ -const COPY_SUFFIX = ' (copy)'; +const COPY_SUFFIX = 'Copy'; /** Minimum number of tabs required to show close others option. */ const MIN_TABS_FOR_CLOSE_OTHERS = 2; From 364176d1b6ebf03208e59ff581ea759ce5d21bc5 Mon Sep 17 00:00:00 2001 From: Alan Smith Date: Fri, 3 Oct 2025 10:02:04 -0400 Subject: [PATCH 5/5] Refactor isClassNameOk into ClassNameComponent --- src/reactComponents/ClassNameComponent.tsx | 12 +++++++++-- src/storage/project.ts | 25 ---------------------- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/src/reactComponents/ClassNameComponent.tsx b/src/reactComponents/ClassNameComponent.tsx index 1af278b5..f13a2a97 100644 --- a/src/reactComponents/ClassNameComponent.tsx +++ b/src/reactComponents/ClassNameComponent.tsx @@ -25,6 +25,7 @@ import * as I18Next from 'react-i18next'; import * as React from 'react'; import * as commonStorage from '../storage/common_storage'; import * as storageProject from '../storage/project'; +import * as storageNames from '../storage/names'; /** Props for the ClassNameComponent. */ interface ClassNameComponentProps { @@ -66,8 +67,15 @@ export default function ClassNameComponent(props: ClassNameComponentProps): Reac return; } - const {ok, error} = storageProject.isClassNameOk(props.project, newClassName, t); - if (ok) { + let error = ''; + + if (!storageNames.isValidClassName(newClassName)) { + error = t('INVALID_CLASS_NAME', { name: newClassName }); + } else if (storageProject.findModuleByClassName(props.project!, newClassName) != null) { + error = t('CLASS_NAME_ALREADY_EXISTS', { name: newClassName }); + } + + if (!error) { clearError(); props.onAddNewItem(); } else { diff --git a/src/storage/project.ts b/src/storage/project.ts index caafcf16..34a65898 100644 --- a/src/storage/project.ts +++ b/src/storage/project.ts @@ -318,31 +318,6 @@ export async function copyModuleInProject( return newModulePath; } -/** - * Checks if the proposed class name is valid and does not conflict with existing names in the project. - * @param project The project to check against. - * @param proposedClassName The proposed class name to validate. - * @param t Translation function for internationalized error messages. - * @returns An object containing a boolean `ok` indicating if the name is valid, and an `error` message if it is not. - */ -export function isClassNameOk(project: Project, proposedClassName: string, t: (key: string, params?: any) => string) { - let ok = true; - let error = ''; - - if (!storageNames.isValidClassName(proposedClassName)) { - ok = false; - error = t('INVALID_CLASS_NAME', { name: proposedClassName }); - } else if (findModuleByClassName(project, proposedClassName) != null) { - ok = false; - error = t('CLASS_NAME_ALREADY_EXISTS', { name: proposedClassName }); - } - - return { - ok: ok, - error: error - } -} - /** * Returns the module in the given project with the given class name. */