From 9d3fbc8f4e06e072686cb73fb37bc86fff060f30 Mon Sep 17 00:00:00 2001 From: qweliant Date: Wed, 29 Nov 2023 14:35:42 -0500 Subject: [PATCH 1/3] order stages by constraint and workflow --- .../stages/dashboard/StageManagement.tsx | 3 +- .../stages/dashboard/StagesEditor.tsx | 173 +++++++++++++++++- .../[communitySlug]/stages/dashboard/page.tsx | 32 +++- core/lib/types.ts | 2 + 4 files changed, 204 insertions(+), 6 deletions(-) diff --git a/core/app/c/[communitySlug]/stages/dashboard/StageManagement.tsx b/core/app/c/[communitySlug]/stages/dashboard/StageManagement.tsx index 6d33480315..485890166c 100644 --- a/core/app/c/[communitySlug]/stages/dashboard/StageManagement.tsx +++ b/core/app/c/[communitySlug]/stages/dashboard/StageManagement.tsx @@ -6,7 +6,8 @@ import StagesEditor from "./StagesEditor"; type Props = { community: any; - stages: any; + stageWorkflows: StagePayload[][]; + stageIndex: StageIndex; }; export default function StageManagement(props: Props) { diff --git a/core/app/c/[communitySlug]/stages/dashboard/StagesEditor.tsx b/core/app/c/[communitySlug]/stages/dashboard/StagesEditor.tsx index 3bd1882d4c..d009dc0e6a 100644 --- a/core/app/c/[communitySlug]/stages/dashboard/StagesEditor.tsx +++ b/core/app/c/[communitySlug]/stages/dashboard/StagesEditor.tsx @@ -18,7 +18,12 @@ import { TabsTrigger, } from "ui"; import * as z from "zod"; +<<<<<<< HEAD import { StagePayload } from "~/lib/types"; +======= +import { zodResolver } from "@hookform/resolvers/zod"; +import { StagePayload, StageIndex } from "~/lib/types"; +>>>>>>> 3fcc8c6 (order stages by constraint and workflow) const schema = z.object({ stageName: z.string(), @@ -43,13 +48,14 @@ const schema = z.object({ }); type Props = { - stages: StagePayload[]; + stageWorkflows: StagePayload[][]; + stageIndex: StageIndex; }; const StagesEditor = (props: Props) => { - const [selectedStage, setSelectedStage] = useState(props.stages[0]); // Set the initial selected stage. + const [selectedStage, setSelectedStage] = useState(props.stageWorkflows[0][0]); // Set the initial selected stage. const sources = selectedStage.moveConstraintSources.map( - (stage) => props.stages.find((s) => s.id === stage.stageId)! + (stage) => props.stageIndex[stage.stageId] ); const handleStageChange = (newStage: StagePayload) => { setSelectedStage(newStage); @@ -76,6 +82,7 @@ const StagesEditor = (props: Props) => { }; return ( +<<<<<<< HEAD
{props.stages.map((stage) => { @@ -118,6 +125,166 @@ const StagesEditor = (props: Props) => {
+======= +
+
+ {/* Display a list of stages as tabs */} + {props.stageWorkflows.map((stages) => { + return( +
+ {stages.map((stage) => { + return ( + + ); + })} +
+ ); + })} +
+
+ +
+ {/* Display the selected stage for editing */} +
+ + + {selectedStage.name} Stage Settings + + This form contains fields used to edit your surrent stages. + + + + ( + + Stage Name + + + + Name of the stage + + + )} + /> + + + ( + + Stage Order + + + + Stage order + + + )} + /> + + + ( + +
+ + Moves to + + + These are stages {selectedStage.name} can + move to + +
+ {selectedStage.moveConstraints.map((stage) => { + return selectedStage.id === stage.id ? null : ( + { + console.log( + selectedStage.moveConstraints.some( + (constraint) => + field.value.includes( + constraint + ) + ) + ); + console.log( + field.value?.some( + (constarint) => + selectedStage.moveConstraints.includes( + constarint + ) + ) + ); + return ( + + + + + + {stage.destination.name} + + + ); + }} + /> + ); + })} + +
+ )} + /> +
+ +
Moves from
+
+ These are the stages {selectedStage.name} can move back from +
+ {sources.map((stage) => { + return ( +
+
handleStageChange(stage)} + > + {stage.name} +
+
+ ); + })} +
+ +
+ + + + handleStageChange(stage)} + > + {stage.name} + + ); })} -
- ); - })} -
- - -
- {/* Display the selected stage for editing */} -
- - - {selectedStage.name} Stage Settings - - This form contains fields used to edit your surrent stages. - - - - ( - - Stage Name - - - - Name of the stage - - - )} - /> - - - ( - - Stage Order - - - - Stage order - - - )} - /> - - - ( - -
- - Moves to - - - These are stages {selectedStage.name} can - move to - -
- {selectedStage.moveConstraints.map((stage) => { - return selectedStage.id === stage.id ? null : ( - { - console.log( - selectedStage.moveConstraints.some( - (constraint) => - field.value.includes( - constraint - ) - ) - ); - console.log( - field.value?.some( - (constarint) => - selectedStage.moveConstraints.includes( - constarint - ) - ) - ); - return ( - - - - - - {stage.destination.name} - - - ); - }} - /> - ); - })} - -
- )} - /> -
- -
Moves from
-
- These are the stages {selectedStage.name} can move back from -
- {sources.map((stage) => { - return ( -
-
handleStageChange(stage)} - > - {stage.name} -
-
- ); - })} -
- -
- - +
- ); - })} -
-
- - -
-
- - - - ); - })} - +
+ + + + ); + })} + +
+ ); + })} ); }; diff --git a/core/prisma/exampleCommunitySeeds/unjournal.ts b/core/prisma/exampleCommunitySeeds/unjournal.ts index 54ea2520d3..43d856205d 100644 --- a/core/prisma/exampleCommunitySeeds/unjournal.ts +++ b/core/prisma/exampleCommunitySeeds/unjournal.ts @@ -488,7 +488,7 @@ export default async function main(prisma: PrismaClient, communityUUID: string) }, }); - const stageIds = [...Array(7)].map((x) => uuidv4()); + const stageIds = [...Array(8)].map((x) => uuidv4()); await prisma.stage.createMany({ data: [ { @@ -497,6 +497,12 @@ export default async function main(prisma: PrismaClient, communityUUID: string) name: "Submitted", order: "aa", }, + { + id: stageIds[8], + communityId: communityUUID, + name: "Submitted to this lil bih", + order: "aa", + }, { id: stageIds[1], communityId: communityUUID, From 4ce05ac5847c7af43a04e964e34d2dac01f3c540 Mon Sep 17 00:00:00 2001 From: qweliant Date: Sun, 3 Dec 2023 12:01:58 -0500 Subject: [PATCH 3/3] use first workflow until we figure how we want to render multiple workflows, consolidate functions --- .../stages/components/StageList.tsx | 161 ++++--- .../stages/dashboard/StagesEditor.tsx | 407 +++++++++--------- .../[communitySlug]/stages/dashboard/page.tsx | 32 +- core/app/c/[communitySlug]/stages/page.tsx | 10 +- core/lib/pubStages.ts | 31 ++ 5 files changed, 345 insertions(+), 296 deletions(-) create mode 100644 core/lib/pubStages.ts diff --git a/core/app/c/[communitySlug]/stages/components/StageList.tsx b/core/app/c/[communitySlug]/stages/components/StageList.tsx index 169dc788ce..9381e86b44 100644 --- a/core/app/c/[communitySlug]/stages/components/StageList.tsx +++ b/core/app/c/[communitySlug]/stages/components/StageList.tsx @@ -5,86 +5,109 @@ import { Fragment } from "react"; import { Button } from "ui"; import PubRow from "~/app/components/PubRow"; import { getPubUsers } from "~/lib/permissions"; -import { StagePayload, UserLoginData } from "~/lib/types"; +import { StageIndex, StagePayload, UserLoginData } from "~/lib/types"; import { StagePubActions } from "./StagePubActions"; +import { stageSources } from "~/lib/pubStages"; -type Props = { stages: StagePayload[]; token: string; loginData: UserLoginData }; +type Props = { + stageWorkflows: StagePayload[][]; + stageIndex: StageIndex; + token: string; + loginData: UserLoginData; +}; type IntegrationAction = { text: string; href: string; kind?: "stage" }; -const StageList: React.FC = function ({ stages, token, loginData }) { +function StageList(props: Props) { return (
- {stages.map((stage) => { - const users = getPubUsers(stage.permissions); - const sources = stage.moveConstraintSources.map( - (stage) => stages.find((s) => s.id === stage.stageId)! - ); - const destinations = stage.moveConstraints.map((stage) => stage.destination); - return ( -
-
-

{stage.name}

- {stage.integrationInstances.map((instance) => { - if (!Array.isArray(instance.integration.actions)) { - return null; - } + { + props.stageWorkflows.map((stages) => { + return ( +
+ {stages.map((stage) => { + const users = getPubUsers(stage.permissions); + const sources = stageSources(stage, props.stageIndex); + const destinations = stage.moveConstraints.map( + (stage) => stage.destination + ); return ( - - {instance.integration.actions?.map( - (action: IntegrationAction) => { - if (action.kind === "stage") { - const href = new URL(action.href); - href.searchParams.set( - "instanceId", - instance.id - ); - href.searchParams.set("token", token); - return ( - - ); +
+
+

+ {stage.name} +

+ {stage.integrationInstances.map((instance) => { + if (!Array.isArray(instance.integration.actions)) { + return null; } - } - )} - + return ( + + {instance.integration.actions?.map( + (action: IntegrationAction) => { + if (action.kind === "stage") { + const href = new URL( + action.href + ); + href.searchParams.set( + "instanceId", + instance.id + ); + href.searchParams.set( + "token", + props.token + ); + return ( + + ); + } + } + )} + + ); + })} +
+ {stage.pubs.map((pub, index, list) => { + return ( + + + } + /> + {index < list.length - 1 &&
} +
+ ); + })} +
); })}
- {stage.pubs.map((pub, index, list) => { - return ( - - - } - /> - {index < list.length - 1 &&
} -
- ); - })} -
- ); - })} + ); + })[0] + }
); -}; +} export default StageList; diff --git a/core/app/c/[communitySlug]/stages/dashboard/StagesEditor.tsx b/core/app/c/[communitySlug]/stages/dashboard/StagesEditor.tsx index b593c805d7..47b9319b25 100644 --- a/core/app/c/[communitySlug]/stages/dashboard/StagesEditor.tsx +++ b/core/app/c/[communitySlug]/stages/dashboard/StagesEditor.tsx @@ -18,6 +18,7 @@ import { TabsTrigger, } from "ui"; import * as z from "zod"; +import { stageSources } from "~/lib/pubStages"; import { StageIndex, StagePayload } from "~/lib/types"; const schema = z.object({ @@ -49,9 +50,7 @@ type Props = { const StagesEditor = (props: Props) => { const [selectedStage, setSelectedStage] = useState(props.stageWorkflows[0][0]); // Set the initial selected stage. - const sources = selectedStage.moveConstraintSources.map( - (stage) => props.stageIndex[stage.stageId] - ); + const sources = stageSources(selectedStage, props.stageIndex); const handleStageChange = (newStage: StagePayload) => { setSelectedStage(newStage); }; @@ -78,209 +77,217 @@ const StagesEditor = (props: Props) => { return (
- {props.stageWorkflows.map((stages) => { - return ( -
- - {stages.map((stage) => { - return ( - - handleStageChange(stage)} - > - {stage.name} - - - ); - })} - {stages.map((stage) => { - return ( - -
- -
-
-

- {selectedStage.name} -

-

- Stage Settings This form contains fields - used to edit your surrent stages. -

-
- ( - -
- - Stage Name - - - - - - Name of the stage - - -
-
- )} - /> - ( - -
- - Stage Order - - - - - - Stage order - - -
-
- )} - /> - ( - -
- - Moves to - - - These are stages{" "} - {selectedStage.name} can - move to - + { + props.stageWorkflows.map((stages) => { + return ( +
+ + {stages.map((stage) => { + return ( + + handleStageChange(stage)} + > + {stage.name} + + + ); + })} + {stages.map((stage) => { + return ( + + + +
+
+

+ {selectedStage.name} +

+

+ Stage Settings This form contains + fields used to edit your surrent + stages. +

+
+ ( + +
+ + Stage Name + + + + + + Name of the stage + + +
+
+ )} + /> + ( + +
+ + Stage Order + + + + + + Stage order + + +
+
+ )} + /> + ( + +
+ + Moves to + + + These are stages{" "} + {selectedStage.name} can + move to + - {selectedStage.moveConstraints.map( - (stage) => { - return selectedStage.id === - stage.id ? null : ( - { - console.log( - selectedStage.moveConstraints.some( - ( - constraint - ) => - field.value.includes( + {selectedStage.moveConstraints.map( + (stage) => { + return selectedStage.id === + stage.id ? null : ( + { + console.log( + selectedStage.moveConstraints.some( + ( constraint - ) - ) - ); - console.log( - field.value?.some( - ( - constarint - ) => - selectedStage.moveConstraints.includes( + ) => + field.value.includes( + constraint + ) + ) + ); + console.log( + field.value?.some( + ( constarint - ) - ) - ); - return ( - - - - - - { - stage - .destination - .name + ) => + selectedStage.moveConstraints.includes( + constarint + ) + ) + ); + return ( + - - ); - }} - /> - ); - } - )} - -
-
- )} - /> -
-

- Moves from -

-

- These are the stages{" "} - {selectedStage.name} can move back from -

- {sources.map((stage) => { - return ( -
-

- handleStageChange(stage) - } - className="text-blue-500" - > - {stage.name} -

-
- ); - })} -
-
- -
+ )} - + /> +
+

+ Moves from +

+

+ These are the stages{" "} + {selectedStage.name} can move back + from +

+ {sources.map((stage) => { + return ( +
+

+ handleStageChange( + stage + ) + } + className="text-blue-500" + > + {stage.name} +

+
+ ); + })} +
+
+ + +
-
- - - - ); - })} - -
- ); - })} + + + + ); + })} + +
+ ); + })[0] + }
); }; diff --git a/core/app/c/[communitySlug]/stages/dashboard/page.tsx b/core/app/c/[communitySlug]/stages/dashboard/page.tsx index 49972e686e..4ac3ac83c7 100644 --- a/core/app/c/[communitySlug]/stages/dashboard/page.tsx +++ b/core/app/c/[communitySlug]/stages/dashboard/page.tsx @@ -1,17 +1,7 @@ import prisma from "~/prisma/db"; import StageManagement from "./StageManagement"; -import { StageIndex, StagePayload, stageInclude } from "~/lib/types"; - -function createStageList(stage: StagePayload, stages: StageIndex, visited: Array) { - if (visited.includes(stage)) { - return; - } - visited.push(stage); - for (const constraint of stage.moveConstraints) { - const nextStage = stages[constraint.destinationId]; - createStageList(nextStage, stages, visited); - } -} +import { stageInclude } from "~/lib/types"; +import { stageList } from "~/lib/pubStages"; export default async function Page({ params }: { params: { communitySlug: string } }) { const community = await prisma.community.findUnique({ @@ -25,22 +15,12 @@ export default async function Page({ params }: { params: { communitySlug: string where: { communityId: community.id }, include: stageInclude, }); - - // create look up table for stages so you dont iterate in O(n) - const stageIndex: StageIndex = {}; - for (const stage of stages) { - stageIndex[stage.id] = stage; - } - const stageRoots = stages.filter((stage) => stage.moveConstraintSources.length === 0); - const stageWorkflows = stageRoots.map((stage) => { - const visited: Array = []; - createStageList(stage, stageIndex, visited); - return visited; - }); - + const { stageWorkflows, stageIndex } = stageList(stages); return ( <> -

Workflow: {params.communitySlug}

+

+ Stages in {params.communitySlug} +

{ const community = await prisma.community.findUnique({ @@ -31,13 +32,20 @@ export default async function Page({ params }: Props) { if (!stages) { return null; } + const { stageWorkflows, stageIndex } = stageList(stages); + return ( <>

Stages

-{" "} {/* Manage Stages */}
- + ); } diff --git a/core/lib/pubStages.ts b/core/lib/pubStages.ts new file mode 100644 index 0000000000..a0fe529355 --- /dev/null +++ b/core/lib/pubStages.ts @@ -0,0 +1,31 @@ +import { StagePayload, StageIndex } from "./types"; + +function createStageList(stage: StagePayload, stages: StageIndex, visited: Array) { + if (visited.includes(stage)) { + return; + } + visited.push(stage); + for (const constraint of stage.moveConstraints) { + const nextStage = stages[constraint.destinationId]; + createStageList(nextStage, stages, visited); + } +} + +export function stageList(stages: StagePayload[]) { + // create look up table for stages so you dont iterate in O(n) during recursion + const stageIndex: StageIndex = {}; + for (const stage of stages) { + stageIndex[stage.id] = stage; + } + const stageRoots = stages.filter((stage) => stage.moveConstraintSources.length === 0); + const stageWorkflows = stageRoots.map((stage) => { + const visited: Array = []; + createStageList(stage, stageIndex, visited); + return visited; + }); + return { stageIndex, stageWorkflows }; +} + +export function stageSources(stage: StagePayload, stageIndex: StageIndex) { + return stage.moveConstraintSources.map((stage) => stageIndex[stage.stageId]); +}