Skip to content

Commit

Permalink
Merge pull request #6 from bcgov/dev
Browse files Browse the repository at this point in the history
Updated frontend to use our own API implementation
  • Loading branch information
timwekkenbc authored Jun 18, 2024
2 parents c9750e9 + 924685e commit 26bf0b3
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 94 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
build-args: |
"NEXT_PUBLIC_API_URL=${{ github.ref == 'refs/heads/main' && secrets.NEXT_PUBLIC_API_URL_PROD || secrets.NEXT_PUBLIC_API_URL_DEV }}"
"NEXT_PUBLIC_GO_RULES_PROJECT_ID=${{ secrets.NEXT_PUBLIC_GO_RULES_PROJECT_ID }}"
"NEXT_PUBLIC_GO_RULES_BEARER_PAT=${{ secrets.NEXT_PUBLIC_GO_RULES_BEARER_PAT }}"
"NEXT_PUBLIC_GO_RULES_ACCESS_TOKEN=${{ secrets.NEXT_PUBLIC_GO_RULES_ACCESS_TOKEN }}"
outputs:
image_tag: ${{ steps.meta.outputs.tags }}
Expand Down
6 changes: 0 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@ FROM registry.access.redhat.com/ubi9/nodejs-20:latest
# Set the environment variables
ARG NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
ARG NEXT_PUBLIC_GO_RULES_PROJECT_ID
ENV NEXT_PUBLIC_GO_RULES_PROJECT_ID=${NEXT_PUBLIC_GO_RULES_PROJECT_ID}
ARG NEXT_PUBLIC_GO_RULES_BEARER_PAT
ENV NEXT_PUBLIC_GO_RULES_BEARER_PAT=${NEXT_PUBLIC_GO_RULES_BEARER_PAT}
ARG NEXT_PUBLIC_GO_RULES_ACCESS_TOKEN
ENV NEXT_PUBLIC_GO_RULES_ACCESS_TOKEN=${NEXT_PUBLIC_GO_RULES_ACCESS_TOKEN}

# Set the working directory
WORKDIR /opt/app-root/src
Expand Down
35 changes: 25 additions & 10 deletions app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { useState, useEffect } from "react";
import Link from "next/link";
import { Table, Input, Button, Flex } from "antd";
import { ColumnsType } from "antd/es/table";
import { HomeOutlined } from "@ant-design/icons";
import { RuleInfo } from "../types/ruleInfo";
import { getAllRuleData, postRuleData, updateRuleData, deleteRuleData } from "../utils/api";
import { getAllRuleData, getAllRuleDocuments, postRuleData, updateRuleData, deleteRuleData } from "../utils/api";

enum ACTION_STATUS {
NEW = "new",
Expand All @@ -18,9 +19,18 @@ export default function Admin() {
const [rules, setRules] = useState<RuleInfo[]>([]);

const getOrRefreshRuleList = async () => {
const data = await getAllRuleData();
setInitialRules(data);
setRules(JSON.parse(JSON.stringify(data))); // JSON.parse(JSON.stringify(data)) is a hacky way to deep copy the data - needed for comparison later
// Get rules that are already defined in the DB
const existingRules = await getAllRuleData();
setInitialRules(existingRules);
// Get rules that exist in the rules repository, but aren't yet defined in the DB
const existingRuleDocuments = await getAllRuleDocuments();
const undefinedRules = existingRuleDocuments
.filter((ruleJSON: string) => {
return !existingRules.find((rule: RuleInfo) => rule.goRulesJSONFilename === ruleJSON);
})
.map((ruleJSON: string) => ({ goRulesJSONFilename: ruleJSON }));
const ruleData = [...existingRules, ...undefinedRules];
setRules(JSON.parse(JSON.stringify(ruleData))); // JSON.parse(JSON.stringify(data)) is a hacky way to deep copy the data - needed for comparison later
setIsLoading(false);
};

Expand Down Expand Up @@ -82,19 +92,19 @@ export default function Admin() {
const entriesToUpdate = getRulesToUpdate();
await Promise.all(
entriesToUpdate.map(async ({ rule, action }) => {
if (rule?._id) {
try {
if (action === ACTION_STATUS.NEW) {
await postRuleData(rule);
} else if (action === ACTION_STATUS.UPDATE) {
await updateRuleData(rule._id, rule);
} else if (action === ACTION_STATUS.DELETE) {
await deleteRuleData(rule._id);
} else if (rule?._id) {
if (action === ACTION_STATUS.UPDATE) {
await updateRuleData(rule._id, rule);
} else if (action === ACTION_STATUS.DELETE) {
await deleteRuleData(rule._id);
}
}
} catch (error) {
console.error(`Error performing action ${action} on rule ${rule._id}: ${error}`);
}
}
})
);
getOrRefreshRuleList();
Expand All @@ -113,6 +123,7 @@ export default function Admin() {
title: "Title",
dataIndex: "title",
render: renderInputField("title"),
width: "220px"
},
{
title: "GoRules Id",
Expand All @@ -123,6 +134,7 @@ export default function Admin() {
title: "GoRules JSON Filename",
dataIndex: "goRulesJSONFilename",
render: renderInputField("goRulesJSONFilename"),
width: "260px"
},
{
title: "CHEFS Form Id",
Expand Down Expand Up @@ -155,6 +167,9 @@ export default function Admin() {
return (
<>
<Flex justify="space-between" align="center">
<Link href="/">
<HomeOutlined />
</Link>
<h1>Admin</h1>
{!isLoading && (
<Button type="primary" size="large" onClick={saveAllRuleUpdates}>
Expand Down
11 changes: 5 additions & 6 deletions app/components/RulesDecisionGraph/RulesDecisionGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,30 @@ import styles from "./RulesDecisionGraph.module.css";

interface RulesViewerProps {
jsonFile: string;
docId: string;
contextToSimulate?: SubmissionData | null;
setResultsOfSimulation: (results: Record<string, any>) => void;
}

export default function RulesDecisionGraph({
jsonFile,
docId,
contextToSimulate,
setResultsOfSimulation,
}: RulesViewerProps) {
const decisionGraphRef: any = useRef<DecisionGraphRef>();
const [graphJSON, setGraphJSON] = useState<DecisionGraphType>();


useEffect(() => {
const fetchData = async () => {
try {
const data = await getDocument(docId);
const data = await getDocument(jsonFile);
setGraphJSON(data);
} catch (error) {
console.error("Error fetching JSON:", error);
}
};
fetchData();
}, [docId]);
}, [jsonFile]);

// Can set additional react flow options here if we need to change how graph looks when it's loaded in
const reactFlowInit = (reactFlow: ReactFlowInstance) => {
Expand All @@ -47,10 +46,10 @@ export default function RulesDecisionGraph({
decisionGraphRef?.current?.runSimulator(contextToSimulate);
}, [contextToSimulate]);

const simulateRun = async ({ decisionGraph, context }: { decisionGraph: DecisionGraphType; context: unknown }) => {
const simulateRun = async ({ context }: { context: unknown }) => {
if (contextToSimulate) {
console.info("Simulate:", context);
const data = await postDecision(jsonFile, decisionGraph, context);
const data = await postDecision(jsonFile, context);
console.info("Simulation Results:", data, data?.result);
setResultsOfSimulation(data?.result);
return { result: data };
Expand Down
4 changes: 1 addition & 3 deletions app/components/SimulationViewer/SimulationViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ const RulesDecisionGraph = dynamic(() => import("../RulesDecisionGraph"), { ssr:

interface SimulationViewerProps {
jsonFile: string;
docId: string;
chefsFormId: string;
}

export default function SimulationViewer({ jsonFile, docId, chefsFormId }: SimulationViewerProps) {
export default function SimulationViewer({ jsonFile, chefsFormId }: SimulationViewerProps) {
const [selectedSubmissionInputs, setSelectedSubmissionInputs] = useState<SubmissionData>();
const [contextToSimulate, setContextToSimulate] = useState<SubmissionData | null>();
const [resultsOfSimulation, setResultsOfSimulation] = useState<Record<string, any> | null>();
Expand All @@ -43,7 +42,6 @@ export default function SimulationViewer({ jsonFile, docId, chefsFormId }: Simul
<div className={styles.rulesWrapper}>
<RulesDecisionGraph
jsonFile={jsonFile}
docId={docId}
contextToSimulate={contextToSimulate}
setResultsOfSimulation={setResultsOfSimulation}
/>
Expand Down
14 changes: 7 additions & 7 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ export default function Home() {
getRules();
}, []);

const mappedRules = rules.map(({ _id, title, chefsFormId }) => {
const mappedRules = rules.map(({ _id, title, goRulesJSONFilename, chefsFormId }) => {
return {
key: _id,
titleLink: (
<b>
<Link href={`/rule/${_id}`}>{title}</Link>
<Link href={`/rule/${_id}`}>{title || goRulesJSONFilename}</Link>
</b>
),
editRule: (
<a href={`https://sdpr.gorules.io/projects/${process.env.NEXT_PUBLIC_GO_RULES_PROJECT_ID}/documents/${_id}`}>
Edit
downloadRule: (
<a href={`/api/documents?ruleFileName=${encodeURIComponent(goRulesJSONFilename)}`}>
Download JSON
</a>
),
submissionFormLink: <a href={`https://submit.digital.gov.bc.ca/app/form/submit?f=${chefsFormId}`}>Submission</a>,
Expand All @@ -45,8 +45,8 @@ export default function Home() {
dataIndex: "titleLink",
},
{
title: "Edit Rule",
dataIndex: "editRule",
title: "Download Rule",
dataIndex: "downloadRule",
},
{
title: "Submission Form",
Expand Down
2 changes: 1 addition & 1 deletion app/rule/[ruleId]/embedded/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export default async function RuleEmbedded({ params: { ruleId } }: { params: { r
return <h1>Rule not found</h1>;
}

return <SimulationViewer jsonFile={goRulesJSONFilename} docId={_id} chefsFormId={chefsFormId} />;
return <SimulationViewer jsonFile={goRulesJSONFilename} chefsFormId={chefsFormId} />;
}
4 changes: 2 additions & 2 deletions app/rule/[ruleId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export default async function Rule({ params: { ruleId } }: { params: { ruleId: s
<Link href="/">
<HomeOutlined />
</Link>
<h1>{title}</h1>
<h1>{title || goRulesJSONFilename}</h1>
</Flex>
<SimulationViewer jsonFile={goRulesJSONFilename} docId={_id} chefsFormId={chefsFormId} />
<SimulationViewer jsonFile={goRulesJSONFilename} chefsFormId={chefsFormId} />
</>
);
}
Loading

0 comments on commit 26bf0b3

Please sign in to comment.