Skip to content

Commit

Permalink
Utilize new moddle for simulation model element creation - closes INS…
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonBein committed Aug 9, 2023
1 parent 686518e commit 506f0f2
Show file tree
Hide file tree
Showing 15 changed files with 74 additions and 121 deletions.
92 changes: 14 additions & 78 deletions dataModel/DataModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,16 @@ export default function SimulationModelModdle(extensionPackages, options) {
});
});
}
SimulationModelModdle.prototype = Object.create(Moddle.prototype);


SimulationModelModdle.setInstance = function() {
//TODO
// Utility function to initialize singleton, e.g., in a non-default way with extensions
SimulationModelModdle.setInstance = function(instance) {
if (!SimulationModelModdle._instance) {
SimulationModelModdle._instance = instance;
} else {
throw new Error('SimulationModelModdle singleton instance already set.')
}
}

SimulationModelModdle.getInstance = function() {
Expand All @@ -31,7 +38,6 @@ SimulationModelModdle.getInstance = function() {
return SimulationModelModdle._instance;
}

SimulationModelModdle.prototype = Object.create(Moddle.prototype);

//TODO resolve double recursion between create and moddlefy

Expand Down Expand Up @@ -106,80 +112,10 @@ SimulationModelModdle.prototype.isValidForEnum = function (object, enumTypeName)
return Object.values(descriptor.values).includes(object) || (object === null && descriptor.isNullable /* Accepts only null, not undefined */); //TODO what about equal but not identical?
}



export function scenario(scenarioName) {
return {
scenarioName: scenarioName,
startingDate: "01-01-0000",
startingTime: "00:00",
numberOfInstances: 1,
currency: Currencies.EURO,
resourceParameters: {
roles: [],
resources: [],
timeTables: []
},
models: []
}
}

//TODO role
//TODO resource
//TODO timetables

export function model(modelName, bpmnXml) {
return {
BPMN : bpmnXml,
name : modelName,
modelParameter : {
activities : [],
events : [],
gateways : [],
}
}
}

export function activity(elementId) {
return {
id : elementId,
resources: [],
cost: 0,
duration: distribution()
}
}

export function event(elementId) {
return {
id : elementId,
interArrivalTime: distribution()
}
}

export function gateway(elementId) {
return {
id : elementId,
probabilities : {}
}
}

export function distribution() {
return {
distributionType: undefined,
timeUnit : TimeUnits.MINUTES,
values: []
}
}

// Eg. limitToDataScheme(myScenario)
export function limitToDataScheme(object, DEPRECATED_dataScheme) {
if (DEPRECATED_dataScheme) console.log(`Deprecated parameter data scheme ${DEPRECATED_dataScheme} provided to limit to data scheme`)
if (!object?.$descriptor) {
return object
} else {
return Object.fromEntries(Object.entries(object)
.filter(([key, value]) => object.$descriptor.properties.some(prop => parseNameNS(prop.name).localName === key))
.map(([key, value]) => [key, Array.isArray(value) ? value.map(limitToDataScheme) : limitToDataScheme(value)])
);
}
export function limitToDataScheme(object, ) {
return Object.fromEntries(Object.entries(object)
.filter(([key, value]) => object.$descriptor.properties.some(prop => parseNameNS(prop.name).localName === key))
.map(([key, value]) => [key, Array.isArray(value) ? value.map(limitToDataScheme) : limitToDataScheme(value)])
);
}
5 changes: 3 additions & 2 deletions dataModel/SimulationModelDescriptor.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ export const SimulationModelDescriptor = {
{
"name" : "Resource",
"properties": [
{ "name": "id", "type": "String"}
//TODO override attributes!
{ "name": "id", "type": "String"},
{ "name": "schedule", "type": "String", default : null }, //TODO could be done with isReference and type Timetable
{ "name": "costHour", "type": "Real", default : null },
]
},

Expand Down
9 changes: 6 additions & 3 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ import TimetableOverview from './components/ResourceParameters/TimeTable/Timetab
import ResourceOverview from './components/ResourceParameters/Resources/ResourceOverview';
import { Routes, Route, Navigate, useLocation } from 'react-router-dom';
import ProgressPage from './components/StartView/ProgressPage';
import { deleteFile, getScenarioFileName, getScenarios, setFile, updateProject } from './util/Storage';
import { getScenarios } from './util/Storage';
import BpmnView from './components/ModelbasedParameters/BpmnView';
import SimulationModelModdle from 'simulation-bridge-datamodel/DataModel';
import ModelBasedOverview from './components/TablesOverviewComparison/ModelBasedOverview';
import { ModelData, ScenarioData } from './util/DataHandles';


const { compare } = require('js-deep-equals')

const patchModdleClasses = [ScenarioData, ModelData]

function App() {

// State is used for changing / adding a project projectName, it firest checks if project is already set as current in the session storage
Expand Down Expand Up @@ -127,9 +130,9 @@ function App() {
setCurrentBpmnByIndex(index) { setBpmn(index); }//TODO remove

async addScenario(scenario) {
//scenario.__proto__ = new ScenarioData();
scenario.parentProject = this;
await scenario.save();
scenario = SimulationModelModdle.getInstance().create('simulationmodel:Scenario', scenario);
await scenario.save(); //TODO this implicitly requires a reload of data so the scenario appears in the data variable
}

setCurrentScenario(scenario) {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/CreateEmptyScenarioButton.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Button } from "@chakra-ui/react";
import { scenario } from "simulation-bridge-datamodel/DataModel";
import SimulationModelModdle from "simulation-bridge-datamodel/DataModel";

export default ({getData, toast, label='Add new empty scenario', ...props}) => {
return (<Button {...props} onClick={() => {
let scenarioName = window.prompt('Please enter scenario name');
if (scenarioName) {
if (!getData().getScenario(scenarioName)) {
getData().addScenario(scenario(scenarioName));
getData().addScenario(SimulationModelModdle.getInstance().create('simulationmodel:TimeDistribution', { scenarioName}));
} else {
toast({
title: 'Scenario with that name already exist',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
debounce
} from 'min-dash';

// TODO replace emptyconfig with moddle type name
export default function AbstractModelElementEditor({type, typeName, state, setState, currentElement, getData, emptyConfig, children, setSave}) {

function getExistingElementConfiguration() {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/EditorSidebar/Modelbased/Activity.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { CloseIcon } from '@chakra-ui/icons';
import DistributionEditor from '../../DistributionEditor';
import { distributionToState, stateToDistribution } from '../../../util/Distributions';
import AbstractModelElementEditor from './AbstractModelElementEditor';
import { activity } from 'simulation-bridge-datamodel/DataModel';
import SimulationModelModdle from 'simulation-bridge-datamodel/DataModel';

const Activity = ({ getData, currentElement }) => {

Expand Down Expand Up @@ -61,7 +61,7 @@ const Activity = ({ getData, currentElement }) => {
setState : setActivityConfiguration,
currentElement,
getData,
emptyConfig : activity(currentElement.id),
emptyConfig : SimulationModelModdle.getInstance().create('simulationmodel:Activity', {id : currentElement.id}),
setSave
}}>

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/EditorSidebar/Modelbased/Event.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { useState } from 'react';
import DistributionEditor from '../../DistributionEditor';
import { distributionToState, stateToDistribution } from '../../../util/Distributions';
import AbstractModelElementEditor from './AbstractModelElementEditor';
import { event } from 'simulation-bridge-datamodel/DataModel';
import SimulationModelModdle from 'simulation-bridge-datamodel/DataModel';

const Event = ({ getData, currentElement }) => {

Expand All @@ -28,7 +28,7 @@ const Event = ({ getData, currentElement }) => {
setState : setEventConfiguration,
currentElement,
getData,
emptyConfig : event(currentElement.id),
emptyConfig : SimulationModelModdle.getInstance().create('simulationmodel:Event', {id : currentElement.id}),
setSave
}}>{
eventConfiguration && (
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/EditorSidebar/Modelbased/Gateway.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Input, FormControl, FormLabel, Text } from "@chakra-ui/react";
import { React, useState } from "react";
import { getElementLabel } from "../../../util/BpmnUtil";
import { gateway } from "simulation-bridge-datamodel/DataModel";
import AbstractModelElementEditor from "./AbstractModelElementEditor";
import SimulationModelModdle from "simulation-bridge-datamodel/DataModel";


const Gateway = ({ currentElement, getData}) => {
Expand Down Expand Up @@ -42,7 +42,7 @@ const Gateway = ({ currentElement, getData}) => {
setState: setGatewayConfiguration,
currentElement,
getData,
emptyConfig: withDefaultProbabilities(gateway(currentElement.id)),
emptyConfig : SimulationModelModdle.getInstance().create('simulationmodel:Gateway', {id : currentElement.id}),
setSave
}}>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { useState } from 'react'
import { Button, Input, FormControl, FormLabel, Select, Switch, Stack, Box, Divider,CheckboxGroup, Checkbox } from '@chakra-ui/react';
import SimulationModelModdle from 'simulation-bridge-datamodel/DataModel';

// TODO delete this class and integrate into EditResource
const AddResource = ({ getData, setCurrent }) => {
const [state, setState] = useState({
id: "",
Expand Down Expand Up @@ -46,10 +48,10 @@ const AddResource = ({ getData, setCurrent }) => {
const onSubmit = (event) => {
event.preventDefault();

let obj = {
let obj = SimulationModelModdle.getInstance().create('simulationmodel:Resource', {
id: state.id,
costHour: state.costHour,
}
costHour: state.costHour || null,
});

getData().getCurrentScenario().resourceParameters.resources.push(obj);

Expand Down
3 changes: 1 addition & 2 deletions frontend/src/components/Navigation/Navigation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ import {
FiCornerLeftUp
} from 'react-icons/fi';

import saveAs from 'file-saver';
import { scenario } from 'simulation-bridge-datamodel/DataModel';
import saveAs from 'file-saver';

function Navigation({setCurrent, getData, current, selectProject}) {

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Overview/ScenarioOverview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default function ScenarioOverview({getData}) {
const fileName = await uploadFileToProject(getData().getProjectName()); //TODO potentially do not create an additional file for this?
if (fileName) {
const fileData = (await getFile(getData().getProjectName(), fileName)).data;
getData().getCurrentScenario().addModel(model(fileName, fileData));
getData().getCurrentScenario().addModel(fileName, fileData);
}
}}> Upload one</Button>.
</CardBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { useEffect, useState } from 'react'
import { Box, Heading, Text, Grid, Card, CardBody } from "@chakra-ui/react";
import { EditorSidebarAlternate } from '../../EditorSidebar/EditorSidebar';
import EditTimetableItem from '../../EditorSidebar/Timetable/EditTimetableItem';
import SimulationModelModdle from 'simulation-bridge-datamodel/DataModel';

const { compare } = require('js-deep-equals')

Expand Down Expand Up @@ -48,12 +49,12 @@ function TimeTable({currentTimetable, setCurrentRightSideBar, getData}) {
}

function addTimeTableItem(startDay, startHour) {
const newItem = {
const newItem = SimulationModelModdle.getInstance().create('simulationmodel:TimetableItem', {
"startWeekday": startDay,
"startTime": startHour,
"endWeekday": startDay,
"endTime": startHour+1
}
});
currentTimetable.timeTableItems.push(newItem);
setCurrentTimetableItem(newItem);
getData().saveCurrentScenario();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Box, Card, CardBody, Stack, Tabs, TabList, Tab, IconButton } from "@cha
import { DeleteIcon, EditIcon, PlusSquareIcon } from '@chakra-ui/icons'
import TimeTable from './TimeTable';
import ResourceNavigation from '../ResourceNavigation';
import SimulationModelModdle from 'simulation-bridge-datamodel/DataModel';

const TimetableOverview = ({getData, setCurrentRightSideBar }) => {
// State to hold selected timetable index in the list
Expand All @@ -28,10 +29,10 @@ const TimetableOverview = ({getData, setCurrentRightSideBar }) => {


function addTimetable() {
getData().getCurrentScenario().resourceParameters.timeTables.push({
getData().getCurrentScenario().resourceParameters.timeTables.push(SimulationModelModdle.getInstance().create('simulationmodel:Timetable', {
"id": "NewTimetable",
"timeTableItems" : []
});
}));
getData().saveCurrentScenario();
setSelectedTimeTable(getData().getCurrentScenario().resourceParameters.timeTables.length - 1);
}
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/util/DataHandles.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,11 @@ export class ScenarioData {
await this.parentProject.initializeData();
}

async addModel(model) {
// model.__proto__ = new ModelData();
async addModel(modelName, bpmnXml) {
const model = SimulationModelModdle.getInstance().create('simulationmodel:Model', {
BPMN : bpmnXml,
name : modelName
});
model.$parent = this;
this.models.push(model);
await this.save();
Expand Down
Loading

0 comments on commit 506f0f2

Please sign in to comment.