Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -499,8 +499,8 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
storage={storage}
setAlertErrorMessage={setAlertErrorMessage}
gotoTab={setActiveTab}
project={project}
setProject={setProject}
currentProject={project}
setCurrentProject={setProject}
onProjectChanged={onProjectChanged}
openWPIToolboxSettings={() => setToolboxSettingsModalIsOpen(true)}
theme={theme}
Expand Down
1 change: 1 addition & 0 deletions src/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"ACTIONS": "Actions",
"DELETE_PROJECT_CONFIRM": "Delete {{projectName}}?",
"DELETE_CANNOT_BE_UNDONE": "This action cannot be undone.",
"PROJECT_MANAGEMENT": "Project Management",
"NO_PROJECTS_FOUND": "No projects found",
"CREATE_PROJECT_TO_START": "Please create a new project to get started.",
"PAGINATION_ITEMS": "{{range0}}-{{range1}} of {{total}} items",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"ACTIONS": "Acciones",
"DELETE_PROJECT_CONFIRM": "¿Eliminar {{projectName}}?",
"DELETE_CANNOT_BE_UNDONE": "Esta acción no se puede deshacer.",
"PROJECT_MANAGEMENT": "Gestión de proyectos",
"NO_PROJECTS_FOUND": "No se encontraron proyectos",
"CREATE_PROJECT_TO_START": "Por favor crea un nuevo proyecto para comenzar.",
"PAGINATION_ITEMS": "{{range0}}-{{range1}} de {{total}} elementos",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/locales/he/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"ACTIONS": "פעולות",
"DELETE_PROJECT_CONFIRM": "מחק את {{projectName}}?",
"DELETE_CANNOT_BE_UNDONE": "פעולה זו לא ניתנת לביטול.",
"PROJECT_MANAGEMENT": "ניהול פרויקטים",
"NO_PROJECTS_FOUND": "לא נמצאו פרויקטים",
"CREATE_PROJECT_TO_START": "אנא צור פרויקט חדש כדי להתחיל.",
"PAGINATION_ITEMS": "{{range0}}-{{range1}} מתוך {{total}} פריטים",
Expand Down
53 changes: 27 additions & 26 deletions src/reactComponents/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ export interface MenuProps {
storage: commonStorage.Storage | null;
setAlertErrorMessage: (message: string) => void;
gotoTab: (tabKey: string) => void;
project: storageProject.Project | null;
setProject: (project: storageProject.Project | null) => void;
currentProject: storageProject.Project | null;
setCurrentProject: (project: storageProject.Project | null) => void;
onProjectChanged: () => Promise<void>;
openWPIToolboxSettings: () => void;
theme: string;
Expand Down Expand Up @@ -137,20 +137,20 @@ function getMenuItems(t: (key: string) => string, project: storageProject.Projec
getItem(t('THEME') + '...', 'theme', <BgColorsOutlined />),
getItem(t('LANGUAGE'), 'language', <GlobalOutlined />, [
getItem(
t('ENGLISH'),
'setlang:en',
t('ENGLISH'),
'setlang:en',
currentLanguage === 'en' ? <CheckOutlined /> : undefined
),
getItem(
t('SPANISH'),
'setlang:es',
t('SPANISH'),
'setlang:es',
currentLanguage === 'es' ? <CheckOutlined /> : undefined
),
getItem(
t('HEBREW'),
'setlang:he',
t('HEBREW'),
'setlang:he',
currentLanguage === 'he' ? <CheckOutlined /> : undefined
),
),
]),
]),
getItem(t('HELP'), 'help', <QuestionCircleOutlined />, [
Expand Down Expand Up @@ -223,7 +223,7 @@ export function Component(props: MenuProps): React.JSX.Element {
}
if (projectNameToFetch) {
const project = await storageProject.fetchProject(props.storage, projectNameToFetch);
props.setProject(project);
props.setCurrentProject(project);
}
}
};
Expand All @@ -233,15 +233,15 @@ export function Component(props: MenuProps): React.JSX.Element {
if (props.storage) {
await props.storage.saveEntry(
MOST_RECENT_PROJECT_NAME_KEY,
props.project?.projectName || ''
props.currentProject?.projectName || ''
);
}
};

/** Handles menu item clicks. */
const handleClick: Antd.MenuProps['onClick'] = ({key}): void => {
const newModule = props.project ?
storageProject.findModuleByModulePath(props.project, key) :
const newModule = props.currentProject ?
storageProject.findModuleByModulePath(props.currentProject, key) :
null;

if (newModule) {
Expand Down Expand Up @@ -284,7 +284,7 @@ export function Component(props: MenuProps): React.JSX.Element {

/** Handles the deploy action to generate and download Python files. */
const handleDeploy = async (): Promise<void> => {
if (!props.project) {
if (!props.currentProject) {
props.setAlertErrorMessage(t('NO_PROJECT_SELECTED'));
return;
}
Expand All @@ -293,16 +293,16 @@ export function Component(props: MenuProps): React.JSX.Element {
}

try {
const blobUrl = await createPythonFiles.producePythonProjectBlob(props.project, props.storage);
const blobUrl = await createPythonFiles.producePythonProjectBlob(props.currentProject, props.storage);

// Create a temporary link to download the file
const link = document.createElement('a');
link.href = blobUrl;
link.download = `${props.project.projectName}.zip`;
link.download = `${props.currentProject.projectName}.zip`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);

// Clean up the blob URL
URL.revokeObjectURL(blobUrl);
} catch (error) {
Expand All @@ -314,7 +314,7 @@ export function Component(props: MenuProps): React.JSX.Element {
// TODO: Add UI for the download action.
/** Handles the download action to generate and download json files. */
const handleDownload = async (): Promise<void> => {
if (!props.project) {
if (!props.currentProject) {
props.setAlertErrorMessage(t('NO_PROJECT_SELECTED'));
return;
}
Expand All @@ -323,8 +323,8 @@ export function Component(props: MenuProps): React.JSX.Element {
}

try {
const blobUrl = await storageProject.downloadProject(props.storage, props.project.projectName);
const filename = props.project.projectName + storageNames.UPLOAD_DOWNLOAD_FILE_EXTENSION;
const blobUrl = await storageProject.downloadProject(props.storage, props.currentProject.projectName);
const filename = props.currentProject.projectName + storageNames.UPLOAD_DOWNLOAD_FILE_EXTENSION;

// Create a temporary link to download the file
const link = document.createElement('a');
Expand Down Expand Up @@ -415,19 +415,19 @@ export function Component(props: MenuProps): React.JSX.Element {

// Update menu items and save project when project or language changes
React.useEffect(() => {
if (props.project) {
if (props.currentProject) {
setMostRecentProjectName();
setMenuItems(getMenuItems(t, props.project, i18n.language));
setMenuItems(getMenuItems(t, props.currentProject, i18n.language));
setNoProjects(false);
}
}, [props.project, i18n.language]);
}, [props.currentProject, i18n.language]);

return (
<>
<FileManageModal
isOpen={fileModalOpen}
onClose={handleFileModalClose}
project={props.project}
project={props.currentProject}
storage={props.storage}
tabType={tabType}
onProjectChanged={props.onProjectChanged}
Expand All @@ -439,7 +439,8 @@ export function Component(props: MenuProps): React.JSX.Element {
isOpen={projectModalOpen}
onCancel={handleProjectModalClose}
storage={props.storage}
setProject={props.setProject}
currentProject={props.currentProject}
setCurrentProject={props.setCurrentProject}
setAlertErrorMessage={props.setAlertErrorMessage}
/>
<Antd.Menu
Expand All @@ -464,7 +465,7 @@ export function Component(props: MenuProps): React.JSX.Element {
<Antd.Button
icon={<DownloadOutlined />}
size="small"
disabled={!props.project}
disabled={!props.currentProject}
onClick={handleDownload}
style={{ color: 'white' }}
/>
Expand Down
55 changes: 28 additions & 27 deletions src/reactComponents/ProjectManageModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ interface ProjectManageModalProps {
isOpen: boolean;
noProjects: boolean;
onCancel: () => void;
setProject: (project: storageProject.Project | null) => void;
currentProject: storageProject.Project | null;
setCurrentProject: (project: storageProject.Project | null) => void;
setAlertErrorMessage: (message: string) => void;
storage: commonStorage.Storage | null;
}
Expand Down Expand Up @@ -87,7 +88,7 @@ export default function ProjectManageModal(props: ProjectManageModalProps): Reac
if (projectNames.length > 0 && props.noProjects) {
// Set the first project as the current project
const project = await storageProject.fetchProject(storage, projectNames[0]);
props.setProject(project);
props.setCurrentProject(project);
props.onCancel(); // Close the modal after selecting
}
};
Expand All @@ -109,7 +110,7 @@ export default function ProjectManageModal(props: ProjectManageModalProps): Reac
console.error('Error renaming project:', error);
props.setAlertErrorMessage(t('FAILED_TO_RENAME_PROJECT'));
}

setRenameModalOpen(false);
};

Expand All @@ -130,7 +131,7 @@ export default function ProjectManageModal(props: ProjectManageModalProps): Reac
console.error('Error copying project:', error);
props.setAlertErrorMessage(t('FAILED_TO_COPY_PROJECT'));
}

setCopyModalOpen(false);
};

Expand All @@ -157,37 +158,37 @@ export default function ProjectManageModal(props: ProjectManageModalProps): Reac
};

/** Handles project deletion with proper cleanup. */
const handleDeleteProject = async (project: ProjectRecord): Promise<void> => {
const handleDeleteProject = async (projectToDelete: ProjectRecord): Promise<void> => {
if (!props.storage) {
return;
}

const updatedProjectNames = allProjectNames.filter(projectName => projectName !== project.name);
const updatedProjectNames = allProjectNames.filter(projectName => projectName !== projectToDelete.name);
setAllProjectNames(updatedProjectNames);
const updatedProjectRecords = allProjectRecords.filter((r) => r.name !== project.name);
const updatedProjectRecords = allProjectRecords.filter((r) => r.name !== projectToDelete.name);
setAllProjectRecords(updatedProjectRecords);

// Find another project to set as current
let foundAnotherProject = false;
for (const projectName of allProjectNames) {
if (projectName !== project.name) {
const project = await storageProject.fetchProject(props.storage, projectName);
props.setProject(project);
foundAnotherProject = true;
break;
let projectToSelect: storageProject.Project | null = null;
if (props.currentProject && props.currentProject.projectName === projectToDelete.name) {
// Find another project to set as current
for (const projectName of allProjectNames) {
if (projectName !== projectToDelete.name) {
projectToSelect = await storageProject.fetchProject(props.storage, projectName);
break;
}
}
}

if (!foundAnotherProject) {
props.setProject(null);
}

try {
await storageProject.deleteProject(props.storage, project.name);
await storageProject.deleteProject(props.storage, projectToDelete.name);
} catch (e) {
console.error('Failed to delete the project:', e);
props.setAlertErrorMessage(t('FAILED_TO_DELETE_PROJECT'));
}

if (projectToSelect) {
props.setCurrentProject(projectToSelect);
}
};

/** Handles project selection. */
Expand All @@ -197,7 +198,7 @@ export default function ProjectManageModal(props: ProjectManageModalProps): Reac
}

const project = await storageProject.fetchProject(props.storage, projectRecord.name);
props.setProject(project);
props.setCurrentProject(project);
props.onCancel();
};

Expand Down Expand Up @@ -256,8 +257,8 @@ export default function ProjectManageModal(props: ProjectManageModalProps): Reac
handleRename(currentRecord.name, name);
}
}}
okText={t('Rename')}
cancelText={t('Cancel')}
okText={t('RENAME')}
cancelText={t('CANCEL')}
>
{currentRecord && (
<ProjectNameComponent
Expand All @@ -282,8 +283,8 @@ export default function ProjectManageModal(props: ProjectManageModalProps): Reac
handleCopy(currentRecord.name, name);
}
}}
okText={t('Copy')}
cancelText={t('Cancel')}
okText={t('COPY')}
cancelText={t('CANCEL')}
>
{currentRecord && (
<ProjectNameComponent
Expand All @@ -300,7 +301,7 @@ export default function ProjectManageModal(props: ProjectManageModalProps): Reac
</Antd.Modal>

<Antd.Modal
title={t('Project Management')}
title={t('PROJECT_MANAGEMENT')}
open={props.isOpen}
onCancel={props.onCancel}
footer={null}
Expand Down Expand Up @@ -330,7 +331,7 @@ export default function ProjectManageModal(props: ProjectManageModalProps): Reac
<br />
<h4 style={{margin: '0 0 8px 0'}}>
{t('CREATE_NEW', { type: t('PROJECT') })}
</h4>
</h4>
<div style={getContainerStyle()}>
<ProjectNameComponent
newItemName={newItemName}
Expand Down