Skip to content

Commit

Permalink
Merge pull request #59 from bcgov/feature/github-saving-scenarios
Browse files Browse the repository at this point in the history
GitHub saving scenarios
  • Loading branch information
timwekkenbc authored Jan 14, 2025
2 parents c9ad186 + 93af561 commit 543d614
Show file tree
Hide file tree
Showing 14 changed files with 679 additions and 166 deletions.
20 changes: 11 additions & 9 deletions app/components/RuleManager/RuleManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ const RuleViewerEditor = dynamic(() => import("../RuleViewerEditor"), { ssr: fal
interface RuleManagerProps {
ruleInfo: RuleInfo;
initialRuleContent?: DecisionGraphType;
editing?: string | boolean;
version: RULE_VERSION | boolean;
showAllScenarioTabs?: boolean;
}

export default function RuleManager({
ruleInfo,
initialRuleContent = DEFAULT_RULE_CONTENT,
editing = false,
version,
showAllScenarioTabs = true,
}: RuleManagerProps) {
const { _id: ruleId, filepath: jsonFile } = ruleInfo;
Expand All @@ -56,8 +56,8 @@ export default function RuleManager({
const [simulationContext, setSimulationContext] = useState<Record<string, any>>();
const [resultsOfSimulation, setResultsOfSimulation] = useState<Record<string, any> | null>();
const { setHasUnsavedChanges } = useLeaveScreenPopup();
const canEditGraph = editing === RULE_VERSION.draft || editing === true;
const canEditScenarios = editing === RULE_VERSION.draft || editing === RULE_VERSION.inReview || editing === true;
const canEditGraph = version === RULE_VERSION.draft || version === true;
const canEditScenarios = version === RULE_VERSION.draft || version === RULE_VERSION.inReview || version === true;

const updateRuleContent = (updatedRuleContent: DecisionGraphType) => {
if (ruleContent !== updatedRuleContent) {
Expand Down Expand Up @@ -146,21 +146,21 @@ export default function RuleManager({
);
}

const versionColour = getVersionColor(editing.toString());
const versionColour = getVersionColor(version.toString());

return (
<Flex gap="middle" vertical className={styles.rootLayout}>
<div
className={styles.rulesWrapper}
style={editing !== false ? ({ "--version-color": versionColour } as React.CSSProperties) : undefined}
style={version !== false ? ({ "--version-color": versionColour } as React.CSSProperties) : undefined}
>
{editing !== false && (
{version !== false && (
<Flex gap="small" justify="space-between" wrap className={styles.actionBar}>
<VersionBar ruleInfo={ruleInfo} version={editing.toString()} />
<VersionBar ruleInfo={ruleInfo} version={version.toString()} />
<SavePublish
ruleInfo={ruleInfo}
ruleContent={ruleContent}
version={editing}
version={version}
setHasSaved={() => setHasUnsavedChanges(false)}
/>
</Flex>
Expand Down Expand Up @@ -188,6 +188,7 @@ export default function RuleManager({
{scenarios && rulemap && (
<ScenariosManager
ruleId={ruleId}
ruleInfo={ruleInfo}
jsonFile={jsonFile}
ruleContent={ruleContent}
rulemap={rulemap}
Expand All @@ -200,6 +201,7 @@ export default function RuleManager({
simulationContext={simulationContext}
runSimulation={runSimulation}
resultsOfSimulation={resultsOfSimulation}
version={version}
/>
)}
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default function LinkRuleComponent({ specification, id, isSelected, name,
<RuleManager
ruleInfo={{ _id: id, filepath }}
initialRuleContent={selectedRuleContent}
editing={false}
version={false}
showAllScenarioTabs={false}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
.instructionsList {
list-style: none;
padding: 20px;
margin: 20px 0;
background-color: #f4f4f9;
border-radius: var(--border-radius);
border: 1px solid #eaeaea;
}

.instructionsList li {
margin-bottom: 15px;
padding: 10px;
background: #fff;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
font-size: 16px;
line-height: 1.5;
position: relative;
}

.instructionsList li::before {
content: counter(li);
counter-increment: li;
position: absolute;
left: -30px;
top: 50%;
transform: translateY(-50%);
background: var(--color-link-focus);
color: white;
border-radius: 50%;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}

.instructionsList a {
color: var(--color-link-focus);
text-decoration: none;
}

.instructionsList a:hover {
text-decoration: underline;
}

.instructionsList {
counter-reset: li;
max-width: calc(100% - 48px);
}

.upload {
margin-right: 10px;
}

.runButton {
margin-left: 10px;
}
132 changes: 132 additions & 0 deletions app/components/ScenariosManager/ScenarioCSV/NewScenarioCSV.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { useState, useEffect } from "react";
import { App, Modal, Button, Flex, Upload } from "antd";
import { UploadOutlined } from "@ant-design/icons";
import { DecisionGraphType } from "@gorules/jdm-editor";
import { logError } from "@/app/utils/logger";
import { getCSVForRuleRun } from "@/app/utils/api";
import styles from "./NewScenarioCSV.module.css";

interface NewScenarioCSVProps {
openNewCSVModal: boolean;
jsonFile: string;
ruleContent?: DecisionGraphType;
confirmAddingNewCSVFile: (file: File) => void;
cancelAddingCSVFile: () => void;
runCSVScenarios: (fileToRun: File | null, filename: string) => void;
existingFilenames: string[];
}

export default function NewScenarioCSV({
openNewCSVModal,
jsonFile,
ruleContent,
confirmAddingNewCSVFile,
cancelAddingCSVFile,
runCSVScenarios,
existingFilenames,
}: NewScenarioCSVProps) {
const { message } = App.useApp();

const [file, setFile] = useState<File | null>(null);
const [uploadedFile, setUploadedFile] = useState<boolean>(false);

const handleDownloadScenarios = async () => {
try {
const csvContent = await getCSVForRuleRun(jsonFile, ruleContent);
message.success(`Scenario Testing Template: ${csvContent}`);
} catch (error: unknown) {
message.error("Error downloading scenarios.");
logError("Error downloading scenarios:", error instanceof Error ? error : "Unknown error occurred.");
}
};

const deleteCurrentCSV = () => {
setFile(null);
setUploadedFile(false);
};

const handleOk = () => {
file && confirmAddingNewCSVFile(file);
};

const handleCancel = () => {
cancelAddingCSVFile();
};

useEffect(() => {
if (openNewCSVModal) {
deleteCurrentCSV();
}
}, [openNewCSVModal]);

return (
<Modal
title="Create new CSV test file"
open={openNewCSVModal}
onOk={handleOk}
onCancel={handleCancel}
footer={[
<Button key="back" onClick={handleCancel}>
Return
</Button>,
<Button key="ok" type="primary" onClick={handleOk} disabled={file == null}>
Add to table list
</Button>,
]}
>
<Flex gap="small">
<ol className={styles.instructionsList}>
<li>
Download a template CSV file:{" "}
<Button onClick={handleDownloadScenarios} size="large" type="primary">
Generate Scenarios/Template
</Button>
</li>
<li>Add additional scenarios to the CSV file</li>
<li>
Upload your edited CSV file with scenarios:{" "}
<label className="labelsmall">
<Upload
accept=".csv"
multiple={false}
maxCount={1}
customRequest={({ file, onSuccess, onError }) => {
const fileName = (file as File).name;
if (!existingFilenames.includes(fileName)) {
setFile(file as File);
message.success(`${fileName} file uploaded successfully.`);
onSuccess && onSuccess("ok");
setUploadedFile(true);
} else {
message.error("File name already exists");
onError && onError(new Error("File name already exists"));
}
}}
onRemove={deleteCurrentCSV}
showUploadList={true}
className={styles.upload}
>
<Button size="large" type="primary" icon={<UploadOutlined />}>
Upload Scenarios
</Button>
</Upload>
{!file ? `Select file for upload.` : `File Selected.`}
</label>
</li>
<li>
Run the uploaded scenarios against the rule (Optional):{" "}
<Button
disabled={!uploadedFile}
size="large"
type="primary"
onClick={() => runCSVScenarios(file, file?.name || "local-tests.csv")}
className={styles.runButton}
>
Run Upload Scenarios
</Button>
</li>
</ol>
</Flex>
</Modal>
);
}
60 changes: 6 additions & 54 deletions app/components/ScenariosManager/ScenarioCSV/ScenarioCSV.module.css
Original file line number Diff line number Diff line change
@@ -1,57 +1,9 @@
.instructionsList {
list-style: none;
padding: 20px;
margin: 20px 0;
background-color: #f4f4f9;
border-radius: var(--border-radius);
border: 1px solid #eaeaea;
.filenameColumn {
min-width: 400px;
word-break: break-all;
}

.instructionsList li {
margin-bottom: 15px;
padding: 10px;
background: #fff;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
font-size: 16px;
line-height: 1.5;
position: relative;
}

.instructionsList li::before {
content: counter(li);
counter-increment: li;
position: absolute;
left: -30px;
top: 50%;
transform: translateY(-50%);
background: var(--color-link-focus);
color: white;
border-radius: 50%;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}

.instructionsList a {
color: var(--color-link-focus);
text-decoration: none;
}

.instructionsList a:hover {
text-decoration: underline;
}

.instructionsList {
counter-reset: li;
}

.upload {
margin-right: 10px;
}

.runButton {
margin-left: 10px;
.runResultIcon {
display: block !important;
font-size: 20px;
}
Loading

0 comments on commit 543d614

Please sign in to comment.