Skip to content

Commit 5fd3ec5

Browse files
Solidified Check Admin
1 parent 6c7050d commit 5fd3ec5

File tree

11 files changed

+179
-70
lines changed

11 files changed

+179
-70
lines changed

builder-api/src/main/java/org/acme/controller/DecisionResource.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,14 @@ private Map<String, Object> evaluateBenefitDmn(Benefit benefit, Map<String, Obje
139139
if (matchingCheckConfig.isEmpty()) {
140140
throw new Exception("Could not find CheckConfig for check " + check.getId());
141141
}
142-
Map<String, Object> checkInputData = new HashMap<String, Object>(inputData);
143-
checkInputData.put("parameters", matchingCheckConfig.get().getParameters());
144142

145143
String dmnFilepath = storageService.getCheckDmnModelPath(
146144
check.getModule(), check.getId(), check.getVersion()
147145
);
148-
Log.info(checkInputData);
149146
String dmnModelName = check.getId();
147+
150148
OptionalBoolean result = dmnService.evaluateSimpleDmn(
151-
dmnFilepath, dmnModelName, checkInputData
149+
dmnFilepath, dmnModelName, inputData, matchingCheckConfig.get().getParameters()
152150
);
153151
checkResultsList.add(result);
154152
checkResults.put(check.getId(), Map.of("name", check.getName(),"result", result));

builder-api/src/main/java/org/acme/controller/ScreenerResource.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -223,23 +223,16 @@ public Response publishScreener(@Context SecurityIdentity identity, PublishScree
223223
storageService.updatePublishedFormSchemaArtifact(screenerId);
224224
Log.info("Updated Screener " + screenerId + " to published.");
225225

226-
//update published dmn model
227-
String dmnXml = dmnService.compilePublishedDmnModel(screenerId);
228-
229226
Screener updateScreener = new Screener();
230227
updateScreener.setId(screenerId);
231228
updateScreener.setIsPublished(true);
232229
updateScreener.setLastPublishDate(Instant.now().toString());
233-
DmnParser dmnParser = new DmnParser(dmnXml);
234-
updateScreener.setPublishedDmnName(dmnParser.getName());
235-
updateScreener.setPublishedDmnNameSpace(dmnParser.getNameSpace());
236230
//update screener metadata
237231
screenerRepository.updateScreener(updateScreener);
238232

239233
Map<String, Object> responseData = new HashMap<>();
240234
responseData.put("screenerUrl", getScreenerUrl(screenerId));
241235
return Response.ok().entity(responseData).build();
242-
243236
} catch (Exception e){
244237
Log.error("Error: Error updating screener to published. Screener: " + screenerId);
245238
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();

builder-api/src/main/java/org/acme/service/DmnService.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,10 @@ public interface DmnService {
99
public Map<String, Object> evaluateDecision(Screener screener, Map<String, Object> inputs) throws IOException;
1010
public String compilePublishedDmnModel(String screenerId) throws Exception;
1111
public void compileWorkingDmnModel(Screener screener) throws Exception;
12-
public OptionalBoolean evaluateSimpleDmn(String dmnFilePath, String dmnModelName, Map<String, Object> inputs) throws Exception;
12+
public OptionalBoolean evaluateSimpleDmn(
13+
String dmnFilePath,
14+
String dmnModelName,
15+
Map<String, Object> inputs,
16+
Map<String, Object> parameters
17+
) throws Exception;
1318
}

builder-api/src/main/java/org/acme/service/KieDmnService.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,11 @@ private Optional<String> getWorkingDmnXml(String screenerId) {
232232
public OptionalBoolean evaluateSimpleDmn(
233233
String dmnFilePath,
234234
String dmnModelName,
235-
Map<String, Object> inputs
235+
Map<String, Object> inputs,
236+
Map<String, Object> parameters
236237
) throws Exception {
237238
Log.info("Evaluating Simple DMN: " + dmnFilePath + " Model: " + dmnModelName);
238239

239-
Map<String, Object> inputData = new HashMap<>();
240-
inputData.put("inputs", inputs);
241-
242240
Optional<String> dmnXmlOpt = storageService.getStringFromStorage(dmnFilePath);
243241
if (dmnXmlOpt.isEmpty()) {
244242
throw new RuntimeException("DMN file not found: " + dmnFilePath);
@@ -261,9 +259,8 @@ public OptionalBoolean evaluateSimpleDmn(
261259
// Prepare model and context using inputs
262260
DMNModel dmnModel = dmnModels.get(0);
263261
DMNContext context = dmnRuntime.newContext();
264-
for (String key : inputData.keySet()) {
265-
context.set(key, inputData.get(key));
266-
}
262+
context.set("inputs", inputs);
263+
context.set("parameters", parameters);
267264
DMNResult dmnResult = dmnRuntime.evaluateAll(dmnModel, context);
268265

269266
// Collect and interpret results

builder-frontend/src/components/homeScreen/eligibilityCheckList/EligibilityChecksList.tsx

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createSignal, For, Show } from "solid-js";
1+
import { createSignal, For, Setter, Show } from "solid-js";
22
import { useNavigate } from "@solidjs/router";
33

44
import Loading from "@/components/Loading";
@@ -14,6 +14,8 @@ const EligibilityChecksList = () => {
1414

1515
const [addingNewCheck, setAddingNewCheck] = createSignal<boolean>(false);
1616

17+
const [checkIdToRemove, setCheckIdToRemove] = createSignal<null | string>(null);
18+
1719
const navigateToCheck = (check: EligibilityCheck) => {
1820
navigate("/check/" + check.id);
1921
}
@@ -38,13 +40,11 @@ const EligibilityChecksList = () => {
3840
<div class="flex flex-wrap gap-4">
3941
<For each={checks()}>
4042
{(check) => (
41-
<div
42-
class="border-2 border-gray-200 rounded p-4 w-60 hover:shadow-lg hover:bg-gray-200 cursor-pointer"
43-
onClick={() => navigateToCheck(check)}
44-
>
45-
<div class="text-lg font-bold text-gray-800">{check.name}</div>
46-
<div class="mt-2 text-gray-700">{check.description || "No description provided."}</div>
47-
</div>
43+
<CheckCard
44+
eligibilityCheck={check}
45+
navigateToCheck={navigateToCheck}
46+
setCheckIdToRemove={setCheckIdToRemove}
47+
/>
4848
)}
4949
</For>
5050
</div>
@@ -59,4 +59,53 @@ const EligibilityChecksList = () => {
5959
)
6060
};
6161

62+
63+
const CheckCard = (
64+
{ eligibilityCheck, navigateToCheck, setCheckIdToRemove }:
65+
{
66+
eligibilityCheck: EligibilityCheck,
67+
navigateToCheck: (check: EligibilityCheck) => void,
68+
setCheckIdToRemove: Setter<string>
69+
}
70+
) => {
71+
return (
72+
<div class="w-full flex">
73+
<div
74+
class="
75+
max-w-lg flex-1 flex flex-col
76+
border-1 border-gray-300 rounded-lg"
77+
>
78+
<div
79+
id={"check-card-details-" + eligibilityCheck.id}
80+
class="p-4 border-bottom border-gray-300 flex-1"
81+
>
82+
<div class="text-2xl mb-2 font-bold">
83+
{eligibilityCheck.name}
84+
</div>
85+
<div>
86+
<span class="font-bold">Description:</span> {eligibilityCheck.description}
87+
</div>
88+
</div>
89+
<div
90+
id={"benefit-card-actions-" + eligibilityCheck.id}
91+
class="p-4 flex justify-end space-x-2"
92+
>
93+
<div
94+
class="btn-default btn-gray"
95+
onClick={() => { navigateToCheck(eligibilityCheck); } }
96+
>
97+
Edit
98+
</div>
99+
<div
100+
class="btn-default btn-red"
101+
onClick={() => { setCheckIdToRemove(eligibilityCheck.id); } }
102+
>
103+
Remove
104+
</div>
105+
</div>
106+
</div>
107+
</div>
108+
);
109+
}
110+
62111
export default EligibilityChecksList;

builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckDetail/EligibilityCheckDetail.tsx

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import KogitoDmnEditorView from "./KogitoDmnEditorView";
99
import eligibilityCheckDetailResource from "./eligibilityCheckDetailResource";
1010

1111
import type { EligibilityCheck, ParameterDefinition } from "@/types";
12+
import ConfirmationModal from "@/components/shared/ConfirmationModal";
1213

1314

1415
const EligibilityCheckDetail = () => {
1516
const { checkId } = useParams();
1617

17-
const [screenMode, setScreenMode] = createSignal<"inputs_params" | "dmn">("inputs_params");
18+
const [screenMode, setScreenMode] = createSignal<"params" | "dmn">("params");
1819
const [tmpDmnModel, setTmpDmnModel] = createSignal<string>("");
1920

2021
const { eligibilityCheck, actions, actionInProgress, initialLoadStatus } = (
@@ -29,8 +30,8 @@ const EligibilityCheckDetail = () => {
2930
<Header/>
3031
<div class="flex space-x-4 p-4 border-b-2 border-gray-200">
3132
<div
32-
class={`btn-default ${screenMode() === "inputs_params" ? "btn-blue" : "btn-gray"}`}
33-
onClick={() => setScreenMode("inputs_params")}
33+
class={`btn-default ${screenMode() === "params" ? "btn-blue" : "btn-gray"}`}
34+
onClick={() => setScreenMode("params")}
3435
>
3536
Inputs/Parameters
3637
</div>
@@ -52,8 +53,13 @@ const EligibilityCheckDetail = () => {
5253

5354
<Show when={eligibilityCheck().id !== undefined && !initialLoadStatus.loading()}>
5455
<Switch>
55-
<Match when={screenMode() === "inputs_params"}>
56-
<ParametersScreen eligibilityCheck={eligibilityCheck} addParameter={actions.addParameter}/>
56+
<Match when={screenMode() === "params"}>
57+
<ParametersScreen
58+
eligibilityCheck={eligibilityCheck}
59+
addParameter={actions.addParameter}
60+
editParameter={actions.updateParameter}
61+
removeParameter={actions.removeParameter}
62+
/>
5763
</Match>
5864
<Match when={screenMode() === "dmn"}>
5965
<KogitoDmnEditorView
@@ -68,10 +74,22 @@ const EligibilityCheckDetail = () => {
6874
};
6975

7076
const ParametersScreen = (
71-
{eligibilityCheck, addParameter}:
72-
{eligibilityCheck: Accessor<EligibilityCheck>; addParameter: (parameter: ParameterDefinition) => Promise<void>}
77+
{eligibilityCheck, addParameter, editParameter, removeParameter}:
78+
{
79+
eligibilityCheck: Accessor<EligibilityCheck>;
80+
addParameter: (parameter: ParameterDefinition) => Promise<void>;
81+
editParameter: (parameterIndex: number, parameter: ParameterDefinition) => Promise<void>;
82+
removeParameter: (parameterIndex: number) => Promise<void>;
83+
}
7384
) => {
7485
const [addingParameter, setAddingParameter] = createSignal<boolean>(false);
86+
const [parameterIndexToEdit, setParameterIndexToEdit] = createSignal<null | number>(null);
87+
const [parameterIndexToRemove, setParameterIndexToRemove] = createSignal<null | number>(null);
88+
89+
const handleProjectMenuClicked = (e, parameterIndex: number) => {
90+
e.stopPropagation();
91+
setParameterIndexToRemove(parameterIndex);
92+
};
7593

7694
return (
7795
<div class="p-12">
@@ -88,15 +106,21 @@ const ParametersScreen = (
88106
<Show when={eligibilityCheck().parameters.length > 0} fallback={<p>No parameters defined.</p>}>
89107
<div class="flex flex-wrap gap-4">
90108
<For each={eligibilityCheck().parameters}>
91-
{(param) => (
109+
{(param, parameterIndex) => (
92110
<div
93-
class="border-2 border-gray-200 rounded p-4 w-80 hover:shadow-lg hover:bg-gray-200 cursor-pointer"
94-
onClick={() => {}}
111+
class="relative border-2 border-gray-200 rounded p-4 w-80 hover:shadow-lg hover:bg-gray-200 cursor-pointer"
112+
onClick={() => { console.log("here"); setParameterIndexToEdit(parameterIndex()); }}
95113
>
96114
<div class="text-lg font-bold text-gray-800 mb-2">{param.key}</div>
97115
<div><span class="font-bold">Type:</span> {param.type}</div>
98116
<div><span class="font-bold">Label:</span> {param.label}</div>
99-
<div><span class="font-bold">Required:</span> {param.required.toString()}</div>
117+
<div><span class="font-bold">Required:</span> {param.required.toString()}</div>
118+
<div
119+
class="absolute px-2 top-2 right-2 hover:bg-gray-300 rounded-xl font-bold"
120+
onClick={(e) => handleProjectMenuClicked(e, parameterIndex())}
121+
>
122+
X
123+
</div>
100124
</div>
101125
)}
102126
</For>
@@ -111,6 +135,31 @@ const ParametersScreen = (
111135
modalAction={addParameter}
112136
/>
113137
}
138+
{
139+
parameterIndexToEdit() !== null &&
140+
<ParameterModal
141+
actionTitle="Edit Parameter"
142+
closeModal={() => setParameterIndexToEdit(null)}
143+
modalAction={async (parameter) => { editParameter(parameterIndexToEdit(), parameter); }}
144+
initialData={
145+
{
146+
key: eligibilityCheck().parameters[parameterIndexToEdit()].key,
147+
type: eligibilityCheck().parameters[parameterIndexToEdit()].type,
148+
label: eligibilityCheck().parameters[parameterIndexToEdit()].label,
149+
required: eligibilityCheck().parameters[parameterIndexToEdit()].required
150+
}
151+
}
152+
/>
153+
}
154+
{
155+
parameterIndexToRemove() !== null &&
156+
<ConfirmationModal
157+
confirmationTitle="Remove Parameter"
158+
confirmationText="Are you sure you want to remove this parameter? This action cannot be undone."
159+
callback={() => removeParameter(parameterIndexToRemove()) }
160+
closeModal={() => setParameterIndexToRemove(null) }
161+
/>
162+
}
114163
</div>
115164
);
116165
}

builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckDetail/eligibilityCheckDetailResource.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ export interface EligibilityCheckDetailResource {
1010
eligibilityCheck: () => EligibilityCheckDetail;
1111
actions: {
1212
addParameter: (parameterDef: ParameterDefinition) => Promise<void>;
13+
updateParameter: (parameterIndex: number, parameterDef: ParameterDefinition) => Promise<void>;
14+
removeParameter: (parameterIndex: number) => Promise<void>;
1315
saveDmnModel: (dmnString: string) => Promise<void>;
1416
};
1517
actionInProgress: Accessor<boolean>;
@@ -45,6 +47,37 @@ const eligibilityCheckDetailResource = (checkId: Accessor<string>): EligibilityC
4547
setActionInProgress(false);
4648
};
4749

50+
const updateParameter = async (parameterIndex: number, parameterDef: ParameterDefinition) => {
51+
const updatedParameters = [ ...eligibilityCheck.parameters ];
52+
updatedParameters[parameterIndex] = parameterDef;
53+
console.log("updatedParameters", updatedParameters);
54+
const updatedCheck: EligibilityCheckDetail = { ...eligibilityCheck, parameters: updatedParameters };
55+
56+
setActionInProgress(true);
57+
try {
58+
await updateCheck(updatedCheck);
59+
await refetch();
60+
} catch (e) {
61+
console.error("Failed to update parameter", e);
62+
}
63+
setActionInProgress(false);
64+
};
65+
66+
const removeParameter = async (parameterIndex: number) => {
67+
const updatedParameters = [ ...eligibilityCheck.parameters ];
68+
updatedParameters.splice(parameterIndex, 1);
69+
const updatedCheck: EligibilityCheckDetail = { ...eligibilityCheck, parameters: updatedParameters };
70+
71+
setActionInProgress(true);
72+
try {
73+
await updateCheck(updatedCheck);
74+
await refetch();
75+
} catch (e) {
76+
console.error("Failed to remove parameter", e);
77+
}
78+
setActionInProgress(false);
79+
};
80+
4881
const saveDmnModel = async (dmnString: string) => {
4982
setActionInProgress(true);
5083
try {
@@ -60,6 +93,8 @@ const eligibilityCheckDetailResource = (checkId: Accessor<string>): EligibilityC
6093
eligibilityCheck: () => eligibilityCheck,
6194
actions: {
6295
addParameter,
96+
updateParameter,
97+
removeParameter,
6398
saveDmnModel,
6499
},
65100
actionInProgress,

builder-frontend/src/components/homeScreen/eligibilityCheckList/eligibilityCheckDetail/modals/ParameterModal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ type ParamValues = {
1111
type: "string" | "number" | "boolean";
1212
}
1313
const ParameterModal = (
14-
{ actionTitle, modalAction, closeModal }:
15-
{ actionTitle: string, modalAction: (parameter: ParameterDefinition) => Promise<void>; closeModal: () => void }
14+
{ actionTitle, modalAction, closeModal, initialData }:
15+
{ actionTitle: string, modalAction: (parameter: ParameterDefinition) => Promise<void>; closeModal: () => void, initialData?: ParamValues }
1616
) => {
17-
const [newParam, setNewParam] = createStore<ParamValues>({ key: "", type: "string", label: "", required: undefined });
17+
const [newParam, setNewParam] = createStore<ParamValues>(initialData || { key: "", type: "string", label: "", required: undefined });
1818

1919
// Styling for the Add button based on whether fields are filled
2020
const isAddDisabled = () => {

builder-frontend/src/components/project/manageBenefits/benefitList/BenefitList.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,16 @@ const BenefitList = (
4949
<Show when={initialLoadStatus.loading() || actionInProgress()}>
5050
<Loading/>
5151
</Show>
52-
<Show when={!initialLoadStatus.loading() && screenerBenefits().length === 0}>
52+
<Show when={!initialLoadStatus.loading() && (screenerBenefits() === null || screenerBenefits().length === 0)}>
5353
<div class="w-full flex text-gray-600 font-bold">
5454
No benefits found. Please add a new benefit.
5555
</div>
5656
</Show>
5757
<For each={screenerBenefits()}>
58-
{(benefit, benefitIndex) => {
58+
{(benefit) => {
5959
return (
6060
<BenefitCard
6161
benefit={benefit}
62-
benefitIndex={benefitIndex}
6362
setBenefitIdToConfigure={setBenefitIdToConfigure}
6463
setBenefitIdToRemove={setBenefitIdToRemove}
6564
/>
@@ -95,10 +94,9 @@ const BenefitList = (
9594
};
9695

9796
const BenefitCard = (
98-
{ benefit, benefitIndex, setBenefitIdToConfigure, setBenefitIdToRemove }:
97+
{ benefit, setBenefitIdToConfigure, setBenefitIdToRemove }:
9998
{
10099
benefit: BenefitDetail,
101-
benefitIndex: Accessor<number>,
102100
setBenefitIdToConfigure: Setter<string>,
103101
setBenefitIdToRemove: Setter<string>
104102
}

0 commit comments

Comments
 (0)