Skip to content

Commit

Permalink
refactor: merge inline
Browse files Browse the repository at this point in the history
  • Loading branch information
cpvalente committed Sep 1, 2024
1 parent b6fabed commit d8b0d8b
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 57 deletions.
23 changes: 0 additions & 23 deletions apps/client/src/common/utils/mergeProjects.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,18 @@ import * as Panel from '../PanelUtils';

import ProjectCreateForm from './ProjectCreateForm';
import ProjectList from './ProjectList';
import ProjectMergeForm from './ProjectMergeForm';

import style from './ProjectPanel.module.scss';

export default function ManageProjects() {
const [isCreatingProject, setIsCreatingProject] = useState(false);
const [isMergingProject, setIsMergingProject] = useState<string | null>(null);
const [error, setError] = useState('');
const [loading, setLoading] = useState<'import' | null>(null);

const fileInputRef = useRef<HTMLInputElement>(null);

const handleToggleCreate = () => {
setIsCreatingProject((prev) => !prev);
setIsMergingProject(null);
};

const handleStartMerge = (fileName: string) => {
setIsMergingProject(fileName);
setIsCreatingProject(false);
};

const handleSelectFile = () => {
Expand Down Expand Up @@ -57,7 +49,6 @@ export default function ManageProjects() {
};

const handleCloseForm = () => {
setIsMergingProject(null);
setIsCreatingProject(false);
};

Expand All @@ -79,7 +70,7 @@ export default function ManageProjects() {
variant='ontime-subtle'
onClick={handleSelectFile}
size='sm'
isDisabled={Boolean(loading) || isCreatingProject || Boolean(isMergingProject)}
isDisabled={Boolean(loading) || isCreatingProject}
isLoading={loading === 'import'}
>
Import
Expand All @@ -88,7 +79,7 @@ export default function ManageProjects() {
variant='ontime-subtle'
onClick={handleToggleCreate}
size='sm'
isDisabled={Boolean(loading) || isCreatingProject || Boolean(isMergingProject)}
isDisabled={Boolean(loading) || isCreatingProject}
rightIcon={<IoAdd />}
>
New
Expand All @@ -98,8 +89,7 @@ export default function ManageProjects() {
{error && <Panel.Error>{error}</Panel.Error>}
<Panel.Divider />
{isCreatingProject && <ProjectCreateForm onClose={handleCloseForm} />}
{isMergingProject && <ProjectMergeForm onClose={handleCloseForm} fileName={isMergingProject} />}
<ProjectList onMerge={handleStartMerge} />
<ProjectList />
</Panel.Card>
</Panel.Section>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export type ProjectFormValues = {
};

interface ProjectFormProps {
action: 'duplicate' | 'rename';
action: 'duplicate' | 'rename' | 'merge';
filename: string;
onCancel: () => void;
onSubmit: (values: ProjectFormValues) => Promise<void>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@ import ProjectListItem, { EditMode } from './ProjectListItem';

import style from './ProjectPanel.module.scss';

interface ProjectListProps {
onMerge: (fileName: string) => void;
}

export default function ProjectList(props: ProjectListProps) {
const { onMerge } = props;
export default function ProjectList() {
const { data, refetch } = useProjectList();
const { files, lastLoadedProject } = data;

Expand Down Expand Up @@ -64,7 +59,6 @@ export default function ProjectList(props: ProjectListProps) {
editingFilename={editingFilename}
editingMode={editingMode}
current={project.filename === lastLoadedProject}
onMerge={onMerge}
/>
))}
</tbody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import {
renameProject,
} from '../../../../common/api/db';
import { invalidateAllCaches, maybeAxiosError } from '../../../../common/api/utils';
import { cx } from '../../../../common/utils/styleUtils';
import * as Panel from '../PanelUtils';

import ProjectForm, { ProjectFormValues } from './ProjectForm';
import ProjectMergeForm from './ProjectMergeForm';

import style from './ProjectPanel.module.scss';

export type EditMode = 'rename' | 'duplicate' | null;
export type EditMode = 'rename' | 'duplicate' | 'merge' | null;

interface ProjectListItemProps {
current?: boolean;
Expand All @@ -28,7 +30,6 @@ interface ProjectListItemProps {
onRefetch: () => Promise<void>;
editingFilename: string | null;
editingMode: EditMode | null;
onMerge: (filename: string) => void;
}

export default function ProjectListItem({
Expand All @@ -40,7 +41,6 @@ export default function ProjectListItem({
onRefetch,
onSubmit,
onToggleEditMode,
onMerge,
}: ProjectListItemProps) {
const [submitError, setSubmitError] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
Expand Down Expand Up @@ -102,8 +102,10 @@ export default function ProjectListItem({
handleToggleEditMode(null, null);
};

const isCurrentlyBeingEdited = editingMode && filename === editingFilename;
const classes = current && !isCurrentlyBeingEdited ? style.current : undefined;
const isCurrentlyBeingEdited = filename === editingFilename;
const showProjectForm = (editingMode === 'rename' || editingMode === 'duplicate') && filename === editingFilename;
const showMergeForm = editingMode === 'merge' && isCurrentlyBeingEdited;
const classes = cx([current && !isCurrentlyBeingEdited && style.current, isCurrentlyBeingEdited && style.isEditing]);

return (
<>
Expand All @@ -115,7 +117,7 @@ export default function ProjectListItem({
</tr>
)}
<tr key={filename} className={classes}>
{isCurrentlyBeingEdited ? (
{showProjectForm ? (
<td colSpan={99}>
<ProjectForm
action={editingMode}
Expand All @@ -127,21 +129,28 @@ export default function ProjectListItem({
) : (
<>
<td className={style.containCell}>{filename}</td>
<td>{new Date(updatedAt).toLocaleString()}</td>
<td>{current ? 'Currently loaded' : new Date(updatedAt).toLocaleString()}</td>
<td className={style.actionButton}>
<ActionMenu
current={current}
filename={filename}
onChangeEditMode={handleToggleEditMode}
onDelete={handleDelete}
onLoad={handleLoad}
isDisabled={loading}
onMerge={onMerge}
isDisabled={loading || showMergeForm}
onMerge={(filename) => handleToggleEditMode('merge', filename)}
/>
</td>
</>
)}
</tr>
{showMergeForm && (
<tr>
<td colSpan={99}>
<ProjectMergeForm onClose={handleCancel} fileName={filename} />
</td>
</tr>
)}
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import { Button, Switch } from '@chakra-ui/react';
import { useQueryClient } from '@tanstack/react-query';

import { PROJECT_DATA } from '../../../../common/api/constants';
import { getDb, patchData } from '../../../../common/api/db';
import { maybeAxiosError } from '../../../../common/api/utils';
import { mergeProjects } from '../../../../common/utils/mergeProjects';
import * as Panel from '../PanelUtils';

import { makeProjectPatch } from './project.utils';

import style from './ProjectPanel.module.scss';

interface ProjectMergeFromProps {
Expand Down Expand Up @@ -48,10 +50,21 @@ export default function ProjectMergeForm(props: ProjectMergeFromProps) {
});

const handleSubmitCreate = async (values: ProjectMergeFormValues) => {
const allFalse = Object.values(values).every((value) => !value);
if (allFalse) {
setError('At least one option must be selected');
return;
}

try {
setError(null);

await mergeProjects(fileName, values);
// make patch object
const { data } = await getDb(fileName);
const patch = await makeProjectPatch(data, values);

// request patch
await patchData(patch);
await queryClient.invalidateQueries({ queryKey: PROJECT_DATA });
onClose();
} catch (error) {
Expand All @@ -62,7 +75,7 @@ export default function ProjectMergeForm(props: ProjectMergeFromProps) {
return (
<Panel.Section as='form' onSubmit={handleSubmit(handleSubmitCreate)}>
<Panel.Title>
Partial load project
Merge {`"${fileName}"`}
<div className={style.createActionButtons}>
<Button onClick={onClose} variant='ontime-ghosted' size='sm' isDisabled={isSubmitting}>
Cancel
Expand All @@ -80,7 +93,10 @@ export default function ProjectMergeForm(props: ProjectMergeFromProps) {
</Panel.Title>
{error && <Panel.Error>{error}</Panel.Error>}
<div className={style.innerColumn}>
<Panel.Description>Select data to load from {`"${fileName}"`} into the current project</Panel.Description>
<Panel.Description>
Select partial data from {`"${fileName}"`} to merge into the current project.
<br /> This process is irreversible.
</Panel.Description>
<label className={style.toggleOption}>
<Switch variant='ontime' {...register('project')} />
Project data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
background-color: $blue-1100;
}

.isEditing {
color: $blue-500;
}

.actionButton {
flex: 1;
text-align: right;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { DatabaseModel, isKeyOfType } from 'ontime-types';

export async function makeProjectPatch(data: DatabaseModel, mergeKeys: Record<string, boolean>) {
const patchObject: Partial<DatabaseModel> = {};

for (const key in mergeKeys) {
if (isKeyOfType(key, data) && mergeKeys[key]) {
// if the rundown is merged we also need the custom fields
if (key === 'rundown') {
patchObject.customFields = data['customFields'];
}
Object.assign(patchObject, { [key]: data[key] });
}
}

return patchObject;
}

0 comments on commit d8b0d8b

Please sign in to comment.