Skip to content

Commit

Permalink
fix: rich text editing in accounts, projects, activities
Browse files Browse the repository at this point in the history
  • Loading branch information
Carsten Koch committed May 21, 2024
1 parent 1433555 commit 107a809
Show file tree
Hide file tree
Showing 23 changed files with 478 additions and 276 deletions.
66 changes: 48 additions & 18 deletions api/ContextAccounts.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { FC, ReactNode, createContext, useContext } from "react";
import { type Schema } from "@/amplify/data/resource";
import {
EditorJsonContent,
transformNotesVersion,
} from "@/components/ui-elements/notes-writer/NotesWriter";
import { SelectionSet, generateClient } from "aws-amplify/data";
import { FC, ReactNode, createContext, useContext } from "react";
import useSWR from "swr";
import { handleApiErrors } from "./globals";
import { EditorJsonContent, initialNotesJson, transformNotesVersion } from "@/components/ui-elements/notes-writer/NotesWriter";
const client = generateClient<Schema>();

type UpdateAccountProps = {
id: string;
name?: string;
introduction?: EditorJsonContent;
};

interface AccountsContextType {
accounts: Account[] | undefined;
errorAccounts: any;
Expand All @@ -14,16 +23,13 @@ interface AccountsContextType {
accountName: string
) => Promise<Schema["Account"]["type"] | undefined>;
getAccountById: (accountId: string) => Account | undefined;
saveAccountName: (
accountId: string,
accountName: string
) => Promise<string | undefined>;
updateAccount: (props: UpdateAccountProps) => Promise<string | undefined>;
}

export type Account = {
id: string;
name: string;
introduction: EditorJsonContent;
introduction?: EditorJsonContent | string;
controllerId?: string;
order: number;
responsibilities: { startDate: Date; endDate?: Date }[];
Expand Down Expand Up @@ -55,7 +61,11 @@ export const mapAccount: (account: AccountData) => Account = ({
}) => ({
id,
name,
introduction: transformNotesVersion({version: formatVersion, notes: introduction, notesJson: introductionJson}),
introduction: transformNotesVersion({
version: formatVersion,
notes: introduction,
notesJson: introductionJson,
}),
controllerId: accountSubsidiariesId || undefined,
order: order || 0,
responsibilities: responsibilities
Expand Down Expand Up @@ -97,7 +107,6 @@ export const AccountsContextProvider: FC<AccountsContextProviderProps> = ({
const newAccount: Account = {
id: crypto.randomUUID(),
name: accountName,
introduction: initialNotesJson,
order: 0,
responsibilities: [],
};
Expand All @@ -117,16 +126,37 @@ export const AccountsContextProvider: FC<AccountsContextProviderProps> = ({
const getAccountById = (accountId: string) =>
accounts?.find((account) => account.id === accountId);

const saveAccountName = async (accountId: string, accountName: string) => {
const updateAccount = async ({
id,
name,
introduction,
}: UpdateAccountProps) => {
const updAccount: Account | undefined = accounts?.find((a) => a.id === id);
if (!updAccount) return;

Object.assign(updAccount, {
...(name && { name }),
...(introduction && { introduction }),
});

const updated: Account[] =
accounts?.map((a) =>
a.id !== accountId ? a : { ...a, name: accountName }
) || [];
accounts?.map((a) => (a.id === id ? updAccount : a)) || [];
mutate(updated, false);
const { data, errors } = await client.models.Account.update({
id: accountId,
name: accountName,
});

const newAccount = {
id,
name,
...(introduction
? {
introductionJson: JSON.stringify(introduction),
formatVersion: 2,
introduction: null,
}
: {}),
};

const { data, errors } = await client.models.Account.update(newAccount);

if (errors) handleApiErrors(errors, "Error updating account");
mutate(updated);
return data?.id;
Expand All @@ -140,7 +170,7 @@ export const AccountsContextProvider: FC<AccountsContextProviderProps> = ({
loadingAccounts,
createAccount,
getAccountById,
saveAccountName,
updateAccount,
}}
>
{children}
Expand Down
89 changes: 51 additions & 38 deletions api/ContextProjects.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { FC, ReactNode, createContext, useContext } from "react";
import { type Schema } from "@/amplify/data/resource";
import {
EditorJsonContent,
transformNotesVersion,
} from "@/components/ui-elements/notes-writer/NotesWriter";
import { Context } from "@/contexts/ContextContext";
import { addDaysToDate } from "@/helpers/functional";
import { SelectionSet, generateClient } from "aws-amplify/data";
import { FC, ReactNode, createContext, useContext } from "react";
import useSWR, { KeyedMutator } from "swr";
import { Context } from "@/contexts/ContextContext";
import { handleApiErrors } from "./globals";
import { addDaysToDate } from "@/helpers/functional";
import { EditorJsonContent, initialNotesJson, transformNotesVersion } from "@/components/ui-elements/notes-writer/NotesWriter";
const client = generateClient<Schema>();

interface ProjectsContextType {
Expand All @@ -22,8 +25,8 @@ interface ProjectsContextType {
) => Promise<string | undefined>;
saveNextActions: (
projectId: string,
myNextActions: EditorJsonContent,
othersNextActions: EditorJsonContent
myNextActions: EditorJsonContent | string,
othersNextActions: EditorJsonContent | string
) => Promise<string | undefined>;
saveProjectName: (
projectId: string,
Expand Down Expand Up @@ -57,8 +60,8 @@ export type Project = {
doneOn?: Date;
dueOn?: Date;
onHoldTill?: Date;
myNextActions: EditorJsonContent;
othersNextActions: EditorJsonContent;
myNextActions?: EditorJsonContent | string;
othersNextActions?: EditorJsonContent | string;
context: Context;
accountIds: string[];
activityIds: string[];
Expand Down Expand Up @@ -86,7 +89,10 @@ const selectionSet = [
"crmProjects.crmProject.id",
] as const;

type ProjectData = SelectionSet<Schema["Projects"]["type"], typeof selectionSet>;
type ProjectData = SelectionSet<
Schema["Projects"]["type"],
typeof selectionSet
>;

export const mapProject: (project: ProjectData) => Project = ({
id,
Expand Down Expand Up @@ -146,7 +152,7 @@ const fetchProjects = (context?: Context) => async () => {
filter: {
context: { eq: context },
or: [
{ done: { ne: true }},
{ done: { ne: true } },
{
doneOn: {
ge: addDaysToDate(-90)(new Date()).toISOString().split("T")[0],
Expand Down Expand Up @@ -187,8 +193,6 @@ export const ProjectsContextProvider: FC<ProjectsContextProviderProps> = ({
id: crypto.randomUUID(),
project: projectName,
done: false,
myNextActions: initialNotesJson,
othersNextActions: initialNotesJson,
context,
accountIds: [],
activityIds: [],
Expand All @@ -202,9 +206,6 @@ export const ProjectsContextProvider: FC<ProjectsContextProviderProps> = ({
context,
project: projectName,
done: false,
formatVersion: 2,
myNextActionsJson: initialNotesJson,
othersNextActionsJson: initialNotesJson,
});
if (errors) handleApiErrors(errors, "Error creating project");
mutateProjects(updatedProjects);
Expand All @@ -214,9 +215,15 @@ export const ProjectsContextProvider: FC<ProjectsContextProviderProps> = ({
const getProjectById = (projectId: string) =>
projects?.find((project) => project.id === projectId);

const createProjectActivity = async (projectId: string, notes?: EditorJsonContent) => {
const createProjectActivity = async (
projectId: string,
notes?: EditorJsonContent
) => {
const { data: activity, errors: errorsActivity } =
await client.models.Activity.create({ notesJson: notes, formatVersion: 2 });
await client.models.Activity.create({
notesJson: JSON.stringify(notes),
formatVersion: 2,
});
if (errorsActivity) {
handleApiErrors(errorsActivity, "Error creating activity");
return;
Expand Down Expand Up @@ -244,8 +251,8 @@ export const ProjectsContextProvider: FC<ProjectsContextProviderProps> = ({
dueOn?: Date;
doneOn?: Date | null;
onHoldTill?: Date;
myNextActions?: EditorJsonContent;
othersNextActions?: EditorJsonContent;
myNextActions?: EditorJsonContent | string;
othersNextActions?: EditorJsonContent | string;
done?: boolean;
};

Expand All @@ -259,30 +266,36 @@ export const ProjectsContextProvider: FC<ProjectsContextProviderProps> = ({
myNextActions,
othersNextActions,
}: UpdateProjectProps) => {
const updProject: Project | undefined = projects?.find(p => p.id === id);
const updProject: Project | undefined = projects?.find((p) => p.id === id);
if (!updProject) return;
if (!!project) updProject.project = project;
if (done !== undefined) updProject.done = done;
if (!!doneOn) updProject.doneOn = doneOn;
if (!!dueOn) updProject.dueOn = dueOn;
if (!!onHoldTill) updProject.onHoldTill = onHoldTill;
if (!!myNextActions) updProject.myNextActions = myNextActions;
if (!!othersNextActions) updProject.othersNextActions = othersNextActions;

const updated: Project[] = projects?.map((p) => p.id === id ? updProject : p) || [];
Object.assign(updProject, {
...(project && { project }),
...(done !== undefined && { done }),
...(doneOn && { doneOn }),
...(dueOn && { dueOn }),
...(onHoldTill && { onHoldTill }),
...(myNextActions && { myNextActions }),
...(othersNextActions && { othersNextActions }),
});

const updated: Project[] =
projects?.map((p) => (p.id === id ? updProject : p)) || [];
mutateProjects(updated, false);

const newProject = {
id,
project,
done,
...(myNextActions || othersNextActions ? {
myNextActions: null,
othersNextActions: null,
formatVersion: 2,
myNextActionsJson: updProject.myNextActions,
othersNextActionsJson: updProject.othersNextActions,
} : {}),
...(myNextActions || othersNextActions
? {
myNextActions: null,
othersNextActions: null,
formatVersion: 2,
myNextActionsJson: JSON.stringify(updProject.myNextActions),
othersNextActionsJson: JSON.stringify(updProject.othersNextActions),
}
: {}),
dueOn: dueOn ? dueOn.toISOString().split("T")[0] : undefined,
doneOn:
done === undefined
Expand All @@ -302,9 +315,9 @@ export const ProjectsContextProvider: FC<ProjectsContextProviderProps> = ({

const saveNextActions = (
projectId: string,
myNextActions: EditorJsonContent,
othersNextActions: EditorJsonContent
) => updateProject({ id: projectId, myNextActions, othersNextActions, });
myNextActions: EditorJsonContent | string,
othersNextActions: EditorJsonContent | string
) => updateProject({ id: projectId, myNextActions, othersNextActions });

const saveProjectName = (projectId: string, projectName: string) =>
updateProject({ id: projectId, project: projectName });
Expand Down
15 changes: 10 additions & 5 deletions api/useActivity.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { type Schema } from "@/amplify/data/resource";
import {
EditorJsonContent,
transformNotesVersion,
} from "@/components/ui-elements/notes-writer/NotesWriter";
import { SelectionSet, generateClient } from "aws-amplify/data";
import useSWR from "swr";
import { handleApiErrors } from "./globals";
import { EditorJsonContent, initialNotesJson, transformNotesVersion } from "@/components/ui-elements/notes-writer/NotesWriter";
const client = generateClient<Schema>();

export type Activity = {
id: string;
notes: EditorJsonContent;
notes?: EditorJsonContent | string;
meetingId?: string;
finishedOn: Date;
updatedAt: Date;
Expand All @@ -26,7 +29,10 @@ const selectionSet = [
"forProjects.projectsId",
] as const;

type ActivityData = SelectionSet<Schema["Activity"]["type"], typeof selectionSet>;
type ActivityData = SelectionSet<
Schema["Activity"]["type"],
typeof selectionSet
>;

export const mapActivity: (activity: ActivityData) => Activity = ({
id,
Expand Down Expand Up @@ -96,7 +102,7 @@ const useActivity = (activityId?: string) => {
id: activity.id,
notes: null,
formatVersion: 2,
notesJson: notes,
notesJson: JSON.stringify(notes),
});
if (errors) handleApiErrors(errors, "Error updating activity notes");
mutateActivity(updated);
Expand All @@ -111,7 +117,6 @@ const useActivity = (activityId?: string) => {
if (activity?.projectIds.includes(projectId)) return;
const updated: Activity = {
id: activityId,
notes: initialNotesJson,
finishedOn: new Date(),
projectIds: [...(activity?.projectIds || []), projectId],
updatedAt: new Date(),
Expand Down
13 changes: 8 additions & 5 deletions api/useDayplans.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { type Schema } from "@/amplify/data/resource";
import { SelectionSet, generateClient } from "aws-amplify/data";
import { handleApiErrors } from "./globals";
import { Context } from "@/contexts/ContextContext";
import useSWR from "swr";
import { sortByDate } from "@/helpers/functional";
import { SelectionSet, generateClient } from "aws-amplify/data";
import { useEffect, useState } from "react";
import useSWR from "swr";
import { handleApiErrors } from "./globals";
const client = generateClient<Schema>();

type DayNonProjectTask = {
Expand Down Expand Up @@ -65,7 +65,10 @@ const dayplanSelectionSet = [
"todos.project.id",
] as const;

type DayPlanData = SelectionSet<Schema["DayPlan"]["type"], typeof dayplanSelectionSet>;
type DayPlanData = SelectionSet<
Schema["DayPlan"]["type"],
typeof dayplanSelectionSet
>;

const mapDayPlan: (dayplan: DayPlanData) => DayPlan = ({
id,
Expand Down Expand Up @@ -264,7 +267,7 @@ const useDayPlans = (context?: Context) => {
context,
});
if (errors) handleApiErrors(errors, "Error creating day plan");
if (!data) throw new Error("createDayPlan didn't return result data")
if (!data) throw new Error("createDayPlan didn't return result data");
mutate([{ ...newDayPlan, id: data.id }, ...(dayPlans || [])]);
};

Expand Down
Loading

0 comments on commit 107a809

Please sign in to comment.