mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-14 20:03:52 +00:00
refactor(logo): improve flow for managing logo
This commit is contained in:
@@ -69,6 +69,9 @@ export default function ProjectData() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
const message = maybeAxiosError(error);
|
const message = maybeAxiosError(error);
|
||||||
setError('logo', { message });
|
setError('logo', { message });
|
||||||
|
} finally {
|
||||||
|
// Allow selecting the same local file again after an upload attempt.
|
||||||
|
event.target.value = '';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -153,14 +156,21 @@ export default function ProjectData() {
|
|||||||
{watch('logo') ? (
|
{watch('logo') ? (
|
||||||
<>
|
<>
|
||||||
<img src={`${projectLogoPath}/${watch('logo')}`} />
|
<img src={`${projectLogoPath}/${watch('logo')}`} />
|
||||||
<Button
|
<div className={style.logoActions}>
|
||||||
variant='subtle-destructive'
|
<Button disabled={isSubmitting} onClick={handleClickUpload} type='button'>
|
||||||
disabled={isSubmitting || !watch('logo')}
|
<IoDownloadOutline />
|
||||||
onClick={handleDeleteLogo}
|
Replace logo
|
||||||
>
|
</Button>
|
||||||
<IoTrash />
|
<Button
|
||||||
Delete
|
variant='subtle-destructive'
|
||||||
</Button>
|
disabled={isSubmitting || !watch('logo')}
|
||||||
|
onClick={handleDeleteLogo}
|
||||||
|
type='button'
|
||||||
|
>
|
||||||
|
<IoTrash />
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Button disabled={isSubmitting} onClick={handleClickUpload} type='button'>
|
<Button disabled={isSubmitting} onClick={handleClickUpload} type='button'>
|
||||||
|
|||||||
@@ -15,6 +15,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logoActions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.customDataItem {
|
.customDataItem {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -16,19 +16,13 @@ export function getProjectData(): Readonly<ProjectData> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Patches the current project data
|
* Patches the current project data
|
||||||
* Handles deleting the local logo if the logo has been removed
|
|
||||||
*/
|
*/
|
||||||
export async function editCurrentProjectData(newData: Partial<ProjectData>) {
|
export async function editCurrentProjectData(newData: Partial<ProjectData>) {
|
||||||
const currentProjectData = getDataProvider().getProjectData();
|
const currentProjectData = getDataProvider().getProjectData();
|
||||||
const updatedProjectData = await getDataProvider().setProjectData(newData);
|
const updatedProjectData = await getDataProvider().setProjectData(newData);
|
||||||
|
|
||||||
// Delete the old logo if the logo has been removed
|
if (currentProjectData.logo && currentProjectData.logo !== updatedProjectData.logo) {
|
||||||
if (!updatedProjectData.logo && currentProjectData.logo) {
|
deleteFile(join(publicDir.logoDir, currentProjectData.logo));
|
||||||
const filePath = join(publicDir.logoDir, currentProjectData.logo);
|
|
||||||
|
|
||||||
deleteFile(filePath).catch((_error) => {
|
|
||||||
/** we do not handle this error */
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the websocket clients to refetch the project data
|
// Notify the websocket clients to refetch the project data
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { readFile, stat } from 'fs/promises';
|
|||||||
import { extname, join } from 'path';
|
import { extname, join } from 'path';
|
||||||
|
|
||||||
import { DatabaseModel, MaybeString, ProjectFile } from 'ontime-types';
|
import { DatabaseModel, MaybeString, ProjectFile } from 'ontime-types';
|
||||||
|
import { generateId } from 'ontime-utils';
|
||||||
|
|
||||||
import { publicDir } from '../../setup/index.js';
|
import { publicDir } from '../../setup/index.js';
|
||||||
import { dockerSafeRename, getFilesFromFolder, removeFileExtension } from '../../utils/fileManagement.js';
|
import { dockerSafeRename, getFilesFromFolder, removeFileExtension } from '../../utils/fileManagement.js';
|
||||||
@@ -20,15 +21,16 @@ export async function handleProjectUploaded(filePath: string, name: string) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the upload of a logo image
|
* Handles the upload of a logo image
|
||||||
* @throws if the file already exits
|
* Each upload gets a unique filename so logos cannot conflict across projects.
|
||||||
* @param filePath
|
* @param filePath
|
||||||
* @param name
|
* @param name
|
||||||
* @returns
|
* @returns the generated filename
|
||||||
*/
|
*/
|
||||||
export async function handleImageUpload(filePath: string, name: string): Promise<string> {
|
export async function handleImageUpload(filePath: string, name: string): Promise<string> {
|
||||||
const newFilePath = join(publicDir.logoDir, name);
|
const filename = `${generateId()}${extname(name)}`;
|
||||||
|
const newFilePath = join(publicDir.logoDir, filename);
|
||||||
await dockerSafeRename(filePath, newFilePath);
|
await dockerSafeRename(filePath, newFilePath);
|
||||||
return name;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user