diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 29c0462..1c7b814 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -598,6 +598,8 @@ dependencies = [ [[package]] name = "process_mining" version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f8f33a1cb64dbeb61858689d143b419c92df5ebf2bc03d946375766d5451c44" dependencies = [ "chrono", "flate2", diff --git a/backend/shared/src/lib.rs b/backend/shared/src/lib.rs index ce63b80..e564b44 100644 --- a/backend/shared/src/lib.rs +++ b/backend/shared/src/lib.rs @@ -12,8 +12,6 @@ pub mod preprocessing { pub mod tests; } - - #[derive(Debug, Serialize, Deserialize)] pub struct OCELInfo { pub num_objects: usize, @@ -32,4 +30,3 @@ impl From<&OCEL> for OCELInfo { } } } - diff --git a/backend/web-server/src/main.rs b/backend/web-server/src/main.rs index 5bf018a..3ca29c6 100644 --- a/backend/web-server/src/main.rs +++ b/backend/web-server/src/main.rs @@ -15,9 +15,8 @@ use itertools::Itertools; use ocedeclare_shared::{ constraints::{check_with_tree, CheckWithTreeRequest, ViolationsWithoutID}, discovery::{ - auto_discover_constraints_with_options, auto_discover_count_constraints, - auto_discover_eventually_follows, auto_discover_or_constraints, get_obj_types_per_ev_type, - AutoDiscoverConstraintsRequest, AutoDiscoverConstraintsResponse, + auto_discover_constraints_with_options, AutoDiscoverConstraintsRequest, + AutoDiscoverConstraintsResponse, }, ocel_qualifiers::qualifiers::{ get_qualifiers_for_event_types, QualifierAndObjectType, QualifiersForEventType, diff --git a/frontend/public/favicon.png b/frontend/public/favicon.png new file mode 100644 index 0000000..9ef84a8 Binary files /dev/null and b/frontend/public/favicon.png differ diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/frontend/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 2a07d4d..ecbf256 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -70,24 +70,19 @@ function App() {
-
-

- OCED -

-

- DECLARE -

-
+
{ocelInfo !== undefined && ( - - {ocelInfo.num_events} Events + + OCEL loaded + {ocelInfo.num_events} Events + {ocelInfo.num_objects} Objects )} {ocelInfo !== undefined && ( <> - View OCEL Info - Open Beta + OCEL Info + Constraints )}
@@ -98,16 +93,7 @@ function App() { )}
-
-
-

- OCED -

-

- DECLARE -

-
- +
{/* */} {isAtRoot && (
diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index 2c78984..6e70692 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -4,25 +4,13 @@ import OuterVisualEditor from "./routes/visual-editor/outer-visual-editor/OuterV import OcelInfoViewer from "./routes/ocel-info/OcelInfoViewer.tsx"; import ErrorPage from "./ErrorPage.tsx"; -// export const router = createBrowserRouter([ -// { -// path: "/", -// element: , -// errorElement: , -// children: [ -// { path: "/beta", element: }, -// { path: "/ocel-info", element: }, -// ], -// }, -// ]); - const router = createBrowserRouter([ { path: "/", element: , errorElement: , children: [ - { path: "/beta", element: }, + { path: "/constraints", element: }, { path: "/ocel-info", element: }, ], }, diff --git a/frontend/src/routes/visual-editor/constraint-container/ConstraintContainer.tsx b/frontend/src/routes/visual-editor/constraint-container/ConstraintContainer.tsx index 1b951b8..d283e74 100644 --- a/frontend/src/routes/visual-editor/constraint-container/ConstraintContainer.tsx +++ b/frontend/src/routes/visual-editor/constraint-container/ConstraintContainer.tsx @@ -134,17 +134,12 @@ export default function ConstraintContainer({ // const valWithCorrectCaps = ocelInfo.object_types.find( // (o) => o.name.toLowerCase() === val, // )?.name; - console.log({ valWithCorrectCaps }); if ( valWithCorrectCaps == null || valWithCorrectCaps === "" ) { return; } - console.log( - { valWithCorrectCaps }, - ocelInfo.object_types, - ); if ( editMetaInfoData.name === "" || editMetaInfoData.name.match( diff --git a/frontend/src/routes/visual-editor/outer-visual-editor/OuterVisualEditor.tsx b/frontend/src/routes/visual-editor/outer-visual-editor/OuterVisualEditor.tsx index a06649b..e9b7faa 100644 --- a/frontend/src/routes/visual-editor/outer-visual-editor/OuterVisualEditor.tsx +++ b/frontend/src/routes/visual-editor/outer-visual-editor/OuterVisualEditor.tsx @@ -1,5 +1,12 @@ import { OcelInfoContext } from "@/App"; +import { BackendProviderContext } from "@/BackendProviderContext"; import AlertHelper from "@/components/AlertHelper"; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components/ui/accordion"; import { Button } from "@/components/ui/button"; import { Combobox } from "@/components/ui/combobox"; import { Input } from "@/components/ui/input"; @@ -15,7 +22,7 @@ import toast from "react-hot-toast"; import { CgTrash } from "react-icons/cg"; import { LuDelete, LuSave } from "react-icons/lu"; import { RiRobot2Line } from "react-icons/ri"; -import { RxCrossCircled } from "react-icons/rx"; +import { RxCrossCircled, RxPlusCircled } from "react-icons/rx"; import { type ReactFlowInstance, type ReactFlowJsonObject } from "reactflow"; import ConstraintContainer from "../constraint-container/ConstraintContainer"; import { FlowContext } from "../helper/FlowContext"; @@ -27,7 +34,6 @@ import { import type { DiscoverConstraintsRequest, DiscoverConstraintsRequestWrapper, - DiscoverConstraintsResponse, EventTypeLinkData, EventTypeNodeData, GateLinkData, @@ -35,13 +41,6 @@ import type { ObjectVariable, ViolationsPerNodes, } from "../helper/types"; -import { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, -} from "@/components/ui/accordion"; -import { BackendProviderContext } from "@/BackendProviderContext"; const LOCALSTORAGE_SAVE_KEY_DATA = "oced-declare-data"; const LOCALSTORAGE_SAVE_KEY_CONSTRAINTS_META = "oced-declare-meta"; @@ -49,9 +48,9 @@ function parse(s: string) { return json5.parse(s); } export default function VisualEditorOuter() { - const [qualifiers, setQualifiers] = useState(); + const [qualifiers, setQualifiers] = useState({}); const [objectQualifiers, setObjectQualifiers] = - useState(); + useState({}); const ocelInfo = useContext(OcelInfoContext); const [constraints, setConstraints] = useState< { name: string; description: string }[] @@ -187,13 +186,6 @@ export default function VisualEditorOuter() { ...ci, instance: i, })); - // if (activeIndex !== undefined && i !== undefined) { - // const prevData = prevDataRef.current[activeIndex]; - // console.log({i},activeIndex,i,prevData?.flowJson?.nodes); - // i.setNodes(prevData?.flowJson?.nodes ?? []); - // i.setEdges(prevData?.flowJson?.edges ?? []); - // i.setViewport(prevData?.flowJson?.viewport ?? {}); - // } }, registerOtherDataGetter: (getter) => { setCurrentInstanceAndData((ci) => ({ ...ci, getter })); @@ -222,585 +214,606 @@ export default function VisualEditorOuter() { : "justify-center" }`} > -
+
- + } - title={"Automatic Constraint Discovery"} - initialData={ - { - countConstraints: { - coverFraction: 0.9, - objectTypes: [ocelInfo.object_types[0].name], - enabled: true, - }, - eventuallyFollowsConstraints: { - objectTypes: [ocelInfo.object_types[0].name], - coverFraction: 0.9, - enabled: true, - }, - orConstraints: { - objectTypes: [ocelInfo.object_types[0].name], - enabled: true, - }, - } satisfies DiscoverConstraintsRequestWrapper as DiscoverConstraintsRequestWrapper - } - content={({ data, setData }) => { - return ( -
- v.enabled) - .map(([k, v]) => k)} - > - - -

- Count Constraints - { - ev.preventDefault(); - const newData = { ...data }; - newData.countConstraints.enabled = - !newData.countConstraints.enabled; - if (newData.countConstraints.enabled) { - const d = - ev.currentTarget.parentElement - ?.parentElement; + title={"Delete All Constraints"} + initialData={undefined} + content={() => ( +

Are you sure? This will delete all constraints.

+ )} + submitAction={"Delete All"} + onSubmit={() => { + prevDataRef.current = []; + setConstraints([]); + }} + /> +
+ + + Auto-Discovery + + } + title={"Automatic Constraint Discovery"} + initialData={ + { + countConstraints: { + coverFraction: 0.9, + objectTypes: [ocelInfo.object_types[0].name], + enabled: true, + }, + eventuallyFollowsConstraints: { + objectTypes: [ocelInfo.object_types[0].name], + coverFraction: 0.9, + enabled: true, + }, + orConstraints: { + objectTypes: [ocelInfo.object_types[0].name], + enabled: true, + }, + } satisfies DiscoverConstraintsRequestWrapper as DiscoverConstraintsRequestWrapper + } + content={({ data, setData }) => { + return ( +
+ v.enabled) + .map(([k, v]) => k)} + > + + +

+ Count Constraints + { + ev.preventDefault(); + const newData = { ...data }; + newData.countConstraints.enabled = + !newData.countConstraints.enabled; if ( - d !== null && - d?.dataset.state === "closed" + newData.countConstraints.enabled ) { - d.click(); + const d = + ev.currentTarget.parentElement + ?.parentElement; + if ( + d !== null && + d?.dataset.state === "closed" + ) { + d.click(); + } } - } - setData(newData); - }} - /> -

-
- -
- - { - setData({ - ...data, - countConstraints: { - ...data.countConstraints, - coverFraction: - ev.currentTarget.valueAsNumber, - }, - }); - }} - /> - -
    - {data.countConstraints.objectTypes.map( - (ot, i) => ( -
  • -
    - {ot} - -
    -
  • - ), + setData(newData); + }} + /> +

+
+ +
- - !data.countConstraints.objectTypes.includes( - ot.name, - ), - ) - .map((ot) => ({ - value: ot.name, - label: ot.name, - }))} - onChange={(value) => { - setData({ - ...data, - countConstraints: { - ...data.countConstraints, - objectTypes: [ - ...data.countConstraints - .objectTypes, - value, - ], - }, - }); - }} - name={"Add object type..."} - value={""} - /> -
-
-
+ > + + { + setData({ + ...data, + countConstraints: { + ...data.countConstraints, + coverFraction: + ev.currentTarget.valueAsNumber, + }, + }); + }} + /> + +
    + {data.countConstraints.objectTypes.map( + (ot, i) => ( +
  • +
    + {ot} + +
    +
  • + ), + )} +
+ + !data.countConstraints.objectTypes.includes( + ot.name, + ), + ) + .map((ot) => ({ + value: ot.name, + label: ot.name, + }))} + onChange={(value) => { + setData({ + ...data, + countConstraints: { + ...data.countConstraints, + objectTypes: [ + ...data.countConstraints + .objectTypes, + value, + ], + }, + }); + }} + name={"Add object type..."} + value={""} + /> +
+ + - - -

- Eventually Follows Constraints - { - ev.preventDefault(); - const newData = { ...data }; - newData.eventuallyFollowsConstraints.enabled = - !newData.eventuallyFollowsConstraints - .enabled; - if ( - newData.eventuallyFollowsConstraints + + +

+ Eventually Follows Constraints + { + ev.preventDefault(); + const newData = { ...data }; + newData.eventuallyFollowsConstraints.enabled = + !newData + .eventuallyFollowsConstraints + .enabled; if ( - d !== null && - d?.dataset.state === "closed" + newData.eventuallyFollowsConstraints + .enabled ) { - d.click(); + const d = + ev.currentTarget.parentElement + ?.parentElement; + if ( + d !== null && + d?.dataset.state === "closed" + ) { + d.click(); + } } - } - setData(newData); - }} - /> -

-
- -
- - +

+
+ +
{ - setData({ - ...data, - eventuallyFollowsConstraints: { - ...data.eventuallyFollowsConstraints, - coverFraction: - ev.currentTarget.valueAsNumber, - }, - }); - }} - /> - -
    - {data.eventuallyFollowsConstraints.objectTypes.map( - (ot, i) => ( -
  • -
    - {ot} - -
    -
  • - ), + .enabled && "text-gray-400", )} -
- - !data.eventuallyFollowsConstraints.objectTypes.includes( - ot.name, - ), - ) - .map((ot) => ({ - value: ot.name, - label: ot.name, - }))} - onChange={(value) => { - setData({ - ...data, - eventuallyFollowsConstraints: { - ...data.eventuallyFollowsConstraints, - objectTypes: [ - ...data - .eventuallyFollowsConstraints - .objectTypes, - value, - ], - }, - }); - }} - name={"Add object type..."} - value={""} - /> -
-
-
+ > + + { + setData({ + ...data, + eventuallyFollowsConstraints: { + ...data.eventuallyFollowsConstraints, + coverFraction: + ev.currentTarget.valueAsNumber, + }, + }); + }} + /> + +
    + {data.eventuallyFollowsConstraints.objectTypes.map( + (ot, i) => ( +
  • +
    + {ot} + +
    +
  • + ), + )} +
+ + !data.eventuallyFollowsConstraints.objectTypes.includes( + ot.name, + ), + ) + .map((ot) => ({ + value: ot.name, + label: ot.name, + }))} + onChange={(value) => { + setData({ + ...data, + eventuallyFollowsConstraints: { + ...data.eventuallyFollowsConstraints, + objectTypes: [ + ...data + .eventuallyFollowsConstraints + .objectTypes, + value, + ], + }, + }); + }} + name={"Add object type..."} + value={""} + /> +
+ + - - -

- OR-Gate Constraints - { - ev.preventDefault(); - const newData = { ...data }; - newData.orConstraints.enabled = - !newData.orConstraints.enabled; + + +

+ OR-Gate Constraints + { + ev.preventDefault(); + const newData = { ...data }; + newData.orConstraints.enabled = + !newData.orConstraints.enabled; - if (newData.orConstraints.enabled) { - const d = - ev.currentTarget.parentElement - ?.parentElement; - if ( - d !== null && - d?.dataset.state === "closed" - ) { - d.click(); + if (newData.orConstraints.enabled) { + const d = + ev.currentTarget.parentElement + ?.parentElement; + if ( + d !== null && + d?.dataset.state === "closed" + ) { + d.click(); + } } - } - setData(newData); - }} - /> -

-
- -
- -
    - {data.orConstraints.objectTypes.map( - (ot, i) => ( -
  • -
    - {ot} - -
    -
  • - ), + setData(newData); + }} + /> +

+
+ +
- - !data.orConstraints.objectTypes.includes( - ot.name, - ), - ) - .map((ot) => ({ - value: ot.name, - label: ot.name, - }))} - onChange={(value) => { - setData({ - ...data, - orConstraints: { - ...data.orConstraints, - objectTypes: [ - ...data.orConstraints.objectTypes, - value, - ], - }, - }); - }} - name={"Add object type..."} - value={""} - /> -
-
-
- -
- ); - }} - submitAction={"Run Discovery"} - onSubmit={async (data, ev) => { - ev.preventDefault(); - const reqData: DiscoverConstraintsRequest = { ...data }; - for (const k of [ - "countConstraints", - "eventuallyFollowsConstraints", - "orConstraints", - ] as const) { - if (!data[k].enabled) { - reqData[k] = undefined; + > + +
    + {data.orConstraints.objectTypes.map( + (ot, i) => ( +
  • +
    + {ot} + +
    +
  • + ), + )} +
+ + !data.orConstraints.objectTypes.includes( + ot.name, + ), + ) + .map((ot) => ({ + value: ot.name, + label: ot.name, + }))} + onChange={(value) => { + setData({ + ...data, + orConstraints: { + ...data.orConstraints, + objectTypes: [ + ...data.orConstraints + .objectTypes, + value, + ], + }, + }); + }} + name={"Add object type..."} + value={""} + /> +
+ + + +
+ ); + }} + submitAction={"Run Discovery"} + onSubmit={async (data, ev) => { + ev.preventDefault(); + const reqData: DiscoverConstraintsRequest = { + ...data, + }; + for (const k of [ + "countConstraints", + "eventuallyFollowsConstraints", + "orConstraints", + ] as const) { + if (!data[k].enabled) { + reqData[k] = undefined; + } } - } - await toast - .promise( - backend["ocel/discover-constraints"](reqData) - .then(async (json) => { - console.log({ json }); - const updatedConstraints = [...constraints]; - let index = constraints.length; + await toast + .promise( + backend["ocel/discover-constraints"](reqData) + .then(async (json) => { + console.log({ json }); + const updatedConstraints = [...constraints]; + let index = constraints.length; - for (const c of json.countConstraints) { - const constructedCountConstraint = - constructDiscoveredCountConstraint( - c, - qualifiers, - ); - if ( - updatedConstraints.find( - (c) => - c.name === - constructedCountConstraint.name, - ) !== undefined - ) { - console.log( - "Skipping new constraint " + - constructedCountConstraint.name + - " bc. constraint with same name already exists", - ); - continue; + for (const c of json.countConstraints) { + const constructedCountConstraint = + constructDiscoveredCountConstraint( + c, + qualifiers, + ); + if ( + updatedConstraints.find( + (c) => + c.name === + constructedCountConstraint.name, + ) !== undefined + ) { + console.log( + "Skipping new constraint " + + constructedCountConstraint.name + + " bc. constraint with same name already exists", + ); + continue; + } + updatedConstraints.push({ + name: constructedCountConstraint.name, + description: + constructedCountConstraint.description, + }); + prevDataRef.current[index] = + constructedCountConstraint.constraint; + index++; } - updatedConstraints.push({ - name: constructedCountConstraint.name, - description: - constructedCountConstraint.description, - }); - prevDataRef.current[index] = - constructedCountConstraint.constraint; - index++; - } - for (const c of json.eventuallyFollowsConstraints) { - const constructedEFConstraint = - constructDiscoveredEFConstraint( - c, - qualifiers, - ); - if ( - updatedConstraints.find( - (c) => - c.name === constructedEFConstraint.name, - ) !== undefined - ) { - console.log( - "Skipping new constraint " + - constructedEFConstraint.name + - " bc. constraint with same name already exists", - ); - continue; + for (const c of json.eventuallyFollowsConstraints) { + const constructedEFConstraint = + constructDiscoveredEFConstraint( + c, + qualifiers, + ); + if ( + updatedConstraints.find( + (c) => + c.name === + constructedEFConstraint.name, + ) !== undefined + ) { + console.log( + "Skipping new constraint " + + constructedEFConstraint.name + + " bc. constraint with same name already exists", + ); + continue; + } + updatedConstraints.push({ + name: constructedEFConstraint.name, + description: + constructedEFConstraint.description, + }); + prevDataRef.current[index] = + constructedEFConstraint.constraint; + index++; } - updatedConstraints.push({ - name: constructedEFConstraint.name, - description: - constructedEFConstraint.description, - }); - prevDataRef.current[index] = - constructedEFConstraint.constraint; - index++; - } - for (const c of json.orConstraints) { - const constructedORConstraint = - constructDiscoveredORConstraint( - c, - qualifiers, - ); - if (constructedORConstraint === undefined) { - continue; - } - if ( - updatedConstraints.find( - (c) => - c.name === constructedORConstraint.name, - ) !== undefined - ) { - console.log( - "Skipping new constraint " + - constructedORConstraint.name + - " bc. constraint with same name already exists", - ); - continue; + for (const c of json.orConstraints) { + const constructedORConstraint = + constructDiscoveredORConstraint( + c, + qualifiers, + ); + if (constructedORConstraint === undefined) { + continue; + } + if ( + updatedConstraints.find( + (c) => + c.name === + constructedORConstraint.name, + ) !== undefined + ) { + console.log( + "Skipping new constraint " + + constructedORConstraint.name + + " bc. constraint with same name already exists", + ); + continue; + } + updatedConstraints.push({ + name: constructedORConstraint.name, + description: + constructedORConstraint.description, + }); + prevDataRef.current[index] = + constructedORConstraint.constraint; + index++; } - updatedConstraints.push({ - name: constructedORConstraint.name, - description: - constructedORConstraint.description, - }); - prevDataRef.current[index] = - constructedORConstraint.constraint; - index++; - } - setConstraints(updatedConstraints); - return json; - }) - .catch((err) => { - console.error(err); - return undefined; - }), - { - loading: "Executing Auto-Discovery...", - success: (s) => - `Discovered ${ - s!.countConstraints.length + - s!.eventuallyFollowsConstraints.length - } Constraints`, - error: "Failed to Discover Constraints", - }, - ) - .finally(() => {}); - }} - /> + setConstraints(updatedConstraints); + return json; + }) + .catch((err) => { + console.error(err); + return undefined; + }), + { + loading: "Executing Auto-Discovery...", + success: (s) => + `Discovered ${ + s!.countConstraints.length + + s!.eventuallyFollowsConstraints.length + } Constraints`, + error: "Failed to Discover Constraints", + }, + ) + .finally(() => {}); + }} + /> +
- - - - } - title={"Delete All Constraints"} - initialData={undefined} - content={() => ( -

Are you sure? This will delete all constraints.

- )} - submitAction={"Delete All"} - onSubmit={() => { - prevDataRef.current = []; - setConstraints([]); - }} - />
- - +

+ {constraints.length} Constraints +

{constraints.length > 0 && ( { const newIndex = parseInt(newVal); @@ -822,8 +835,9 @@ export default function VisualEditorOuter() { ) != null && "bg-red-200/30 data-[state=on]:bg-red-300/80", )} + title={c.name} > - {c.name !== "" ? c.name : `Constraint ${i + 1}`} + {c.name !== "" ? c.name : `Constraint ${i + 1}`} )} + {constraints.map( (c, i) => activeIndex === i && ( diff --git a/tauri/public/favicon.png b/tauri/public/favicon.png new file mode 100644 index 0000000..9ef84a8 Binary files /dev/null and b/tauri/public/favicon.png differ diff --git a/tauri/public/vite.svg b/tauri/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/tauri/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/tauri/src-tauri/build.rs b/tauri/src-tauri/build.rs index 795b9b7..d860e1e 100644 --- a/tauri/src-tauri/build.rs +++ b/tauri/src-tauri/build.rs @@ -1,3 +1,3 @@ fn main() { - tauri_build::build() + tauri_build::build() } diff --git a/tauri/src-tauri/src/main.rs b/tauri/src-tauri/src/main.rs index 6d14bf4..88f846b 100644 --- a/tauri/src-tauri/src/main.rs +++ b/tauri/src-tauri/src/main.rs @@ -37,7 +37,7 @@ fn import_ocel(path: &str, state: tauri::State) -> Result) -> Result { let res: Result = match state.lock().unwrap().as_ref() { Some(ocel) => Ok(ocel.into()), - None => Err(format!("No OCEL loaded")), + None => Err("No OCEL loaded".to_string()), }; res } @@ -48,7 +48,7 @@ fn get_event_qualifiers( ) -> Result>, String> { match state.lock().unwrap().as_ref() { Some(ocel) => Ok(get_qualifiers_for_event_types(ocel)), - None => Err(format!("No OCEL loaded")), + None => Err("No OCEL loaded".to_string()), } } @@ -58,7 +58,7 @@ fn get_object_qualifiers( ) -> Result>, String> { match state.lock().unwrap().as_ref() { Some(ocel) => Ok(link_ocel_info(ocel).object_rels_per_type), - None => Err(format!("No OCEL loaded")), + None => Err("No OCEL loaded".to_string()), } } @@ -70,7 +70,7 @@ fn check_constraint_with_tree( ) -> Result<(Vec, Vec), String> { match state.lock().unwrap().as_ref() { Some(ocel) => Ok(check_with_tree(variables, nodes, ocel)), - None => Err(format!("No OCEL loaded")), + None => Err("No OCEL loaded".to_string()), } } @@ -81,7 +81,7 @@ fn auto_discover_constraints( ) -> Result { match state.lock().unwrap().as_ref() { Some(ocel) => Ok(auto_discover_constraints_with_options(ocel, options)), - None => Err(format!("No OCEL loaded")), + None => Err("No OCEL loaded".to_string()), } } diff --git a/tauri/src-tauri/tauri.conf.json b/tauri/src-tauri/tauri.conf.json index 09c55e8..10778fb 100644 --- a/tauri/src-tauri/tauri.conf.json +++ b/tauri/src-tauri/tauri.conf.json @@ -52,7 +52,11 @@ "windows": { "certificateThumbprint": null, "digestAlgorithm": "sha256", - "timestampUrl": "" + "timestampUrl": "", + "nsis": { + "installerIcon": "./icons/128x128.png", + "displayLanguageSelector": true + } } }, "security": {