Skip to content

Commit

Permalink
Merge pull request #289 from cabcookie:get-project-history
Browse files Browse the repository at this point in the history
Get-project-history
  • Loading branch information
cabcookie authored Feb 25, 2025
2 parents 55b65a9 + c85660f commit 5340b92
Show file tree
Hide file tree
Showing 14 changed files with 576 additions and 4 deletions.
6 changes: 4 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"eslint.format.enable": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always",
"source.organizeImports": "always",
"source.organizeImports": "never",
"source.fixAll.markdownlint": "explicit"
},
"typescript.validate.enable": true,
Expand All @@ -26,5 +26,7 @@
"[markdown]": {
"editor.formatOnSave": true,
"editor.formatOnPaste": true
}
},
"typescript.updateImportsOnPaste.enabled": false,
"javascript.updateImportsOnPaste.enabled": false
}
27 changes: 27 additions & 0 deletions components/history/learnings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { type FC } from "react";
import { AccountMapped } from "@/helpers/history/account";

interface Props {
account: AccountMapped;
}

const HistoryLearnings: FC<Props> = ({ account }) => (
<div className="flex flex-col gap-3">
<h2 className="text-lg font-semibold">
Learnings about the account and people
</h2>
{account.learnings.map(
(intro) =>
intro.learning && (
<div key={intro.id} className="flex flex-col gap-1">
<h3 className="font-semibold">{intro.label}</h3>
{intro.learning
?.split("\n")
.map((line, idx) => <p key={idx}>{line}</p>)}
</div>
)
)}
</div>
);

export default HistoryLearnings;
20 changes: 20 additions & 0 deletions components/history/notes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { type FC } from "react";
import { type Note } from "@/helpers/history/activity";

interface Props {
notes?: Note[] | null;
}

const HistoryNotes: FC<Props> = ({ notes }) => (
<div className="flex flex-col gap-3">
<h2 className="text-lg font-semibold">Project Notes</h2>
{notes?.map((n) => (
<div key={n.id} className="flex flex-col gap-1">
<h3 className="font-semibold">{n.label}</h3>
{n.notes?.split("\n").map((line, idx) => <p key={idx}>{line}</p>)}
</div>
))}
</div>
);

export default HistoryNotes;
24 changes: 24 additions & 0 deletions components/history/people-roles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { type FC } from "react";
import { Person } from "@/helpers/history/person";

interface Props {
people?: Person[] | null;
}

const HistoryPeopleRoles: FC<Props> = ({ people }) => (
<div className="flex flex-col gap-3">
<h2 className="text-lg font-semibold">People and their roles</h2>
{people?.map((p) => (
<div key={p.id}>
<div>{p.name}</div>
{p.positions.map((pos, idx) => (
<div key={idx} className="text-xs">
{pos.position}
</div>
))}
</div>
))}
</div>
);

export default HistoryPeopleRoles;
2 changes: 1 addition & 1 deletion components/ui-elements/editors/helpers/text-generation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const transformMentionsToText = (json: JSONContent): JSONContent =>
}
: !json.attrs?.label
? {}
: { type: "text", text: `@${json.attrs?.label}` };
: { type: "text", text: json.attrs?.label };

const transformTasksToText = (json: JSONContent): JSONContent =>
json.type !== "taskList"
Expand Down
2 changes: 1 addition & 1 deletion components/ui-elements/editors/helpers/transformers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface TransformNotesVersionType {
forProjects: ActivityData["forProjects"];
}

const createDocument = ({
export const createDocument = ({
formatVersion,
noteBlockIds,
noteBlocks,
Expand Down
7 changes: 7 additions & 0 deletions components/ui-elements/project-details/project-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Button } from "@/components/ui/button";
import { Context } from "@/contexts/ContextContext";
import { addDays } from "date-fns";
import { ArrowRightCircle, Loader2 } from "lucide-react";
import Link from "next/link";
import { FC, useEffect, useState } from "react";
import ButtonGroup from "../btn-group/btn-group";
import ContextWarning from "../context-warning/context-warning";
Expand Down Expand Up @@ -108,6 +109,12 @@ const ProjectDetails: FC<ProjectDetailsProps> = ({
projectName={project.project}
onUpdate={(name) => saveProjectName(project.id, name)}
/>

<Button asChild size="sm">
<Link href={`/projects/${project.id}/history`}>
Show Project History
</Link>
</Button>
</div>

{showContext && (
Expand Down
99 changes: 99 additions & 0 deletions helpers/history/account.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { union, unionBy } from "lodash";
import { flow, identity, sortBy, filter } from "lodash/fp";
import { getTextFromJsonContent } from "@/components/ui-elements/editors/helpers/text-generation";
import { type Person, mapPeopleLearnings } from "./person";
import { type Learning, getLocaleDateString, makeDate } from "./generals";

export type AccountMapped = {
id: string;
name: string;
shortName?: string | null;
learnings: Learning[];
};

export type AccountData = {
id: string;
name: string;
shortName?: string | null;
createdAt: string;
people: {
personId: string;
}[];
introduction?: string | null;
introductionJson: any;
learnings: {
id: string;
learnedOn?: string | null;
createdAt: string;
learning: any;
}[];
subsidiaries: AccountData[];
};

export const mapAccount = (
a: AccountData,
people: Person[]
): AccountMapped | null =>
!a
? null
: {
id: a.id,
name: a.name,
shortName: a.shortName,
learnings: mapLearning(a)(people),
};

const mapLearning = (a: AccountData) =>
flow(
identity<Person[]>,
mapPeopleLearnings,
(l) => unionBy(mapIntroduction(a), mapAccountLearning(a), l, "learnedOn"),
filter((l) => !!l.learning),
sortBy((a) => a.learnedOn.getTime())
);

const mapIntroduction = (a: AccountData): Learning[] =>
a &&
Boolean(
a.introduction ||
getTextFromJsonContent(JSON.parse(a.introductionJson as any))
)
? union<Learning>(
[
{
id: a.id,
label: getLocaleDateString(a.createdAt),
learnedOn: makeDate(a.createdAt),
learning: `${a.name}${!a.shortName ? "" : ` (${a.shortName})`}\n${
!a.introductionJson
? a.introduction
: getTextFromJsonContent(JSON.parse(a.introductionJson as any))
}`,
},
],
a.subsidiaries?.flatMap(mapIntroduction)
)
: [];

const mapAccountLearning = (a: AccountData): Learning[] =>
!a?.learnings
? []
: a.learnings.reduce(
(prev, curr) =>
unionBy<Learning>(
prev,
[
{
id: curr.id,
label: getLocaleDateString(curr.createdAt, curr.learnedOn),
learnedOn: makeDate(curr.createdAt, curr.learnedOn),
learning: !curr.learning
? ""
: getTextFromJsonContent(JSON.parse(curr.learning as any)),
},
],
a.subsidiaries?.flatMap(mapAccountLearning),
"id"
),
[] as Learning[]
);
33 changes: 33 additions & 0 deletions helpers/history/activity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { flow, get, map, identity, replace, sortBy } from "lodash/fp";
import { Project } from "./project";
import { makeDate, getLocaleDateString } from "./generals";
import { getTextFromJsonContent } from "@/components/ui-elements/editors/helpers/text-generation";
import { createDocument } from "@/components/ui-elements/editors/helpers/transformers";

export type Note = {
id: string;
date: Date;
label: string;
notes: string;
};

export const mapNotes = flow(
identity<Project>,
get("activities"),
map("activity"),
map(
(a): Note => ({
id: a.id,
date: makeDate(a.createdAt, a.finishedOn),
label: `${!a.forMeeting ? `On ${getLocaleDateString(a.createdAt, a.finishedOn)}` : `Meeting: ${a.forMeeting.topic} (${getLocaleDateString(a.createdAt, a.finishedOn)})`}`,
notes: flow(
identity<typeof a>,
createDocument,
getTextFromJsonContent,
replace(/\[\]\n\n/g, "[] "),
replace(/\[x\]\n\n/g, "[x] ")
)(a),
})
),
sortBy((a) => a.date.getTime())
);
14 changes: 14 additions & 0 deletions helpers/history/generals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { toLocaleDateString } from "@/helpers/functional";
import { flow } from "lodash/fp";

export const makeDate = (fallback: string, date?: string | null) =>
new Date(date || fallback);

export const getLocaleDateString = flow(makeDate, toLocaleDateString);

export type Learning = {
id: string;
label: string;
learnedOn: Date;
learning: string;
};
Loading

0 comments on commit 5340b92

Please sign in to comment.