@opencor/opencor 0.20250814.4 → 0.20250822.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-tP7x8zIn.js → index-Bo9Lkhfn.js} +44037 -45095
- package/dist/opencor.css +1 -1
- package/dist/opencor.es.js +1 -1
- package/dist/opencor.umd.js +4510 -4765
- package/dist/{quill-DZsCWNRW.js → quill-BuRGxrCd.js} +1 -1
- package/package.json +13 -13
- package/src/App.vue +4 -22
- package/src/assets/base.css +4 -1
- package/src/common/vueCommon.ts +1 -6
- package/src/components/{LoadOpencorComponent.vue → BlockingMessageComponent.vue} +13 -12
- package/src/components/ContentsComponent.vue +27 -12
- package/src/components/DragNDropComponent.vue +9 -3
- package/src/components/MainMenu.vue +5 -0
- package/src/components/OpenCOR.vue +100 -59
- package/src/components/dialogs/BaseDialog.vue +48 -1
- package/src/components/dialogs/UpdateDownloadProgressDialog.vue +0 -6
- package/src/components/propertyEditors/PropertyEditor.vue +15 -16
- package/src/components/views/IssuesView.vue +19 -6
- package/src/components/views/SimulationExperimentUiView.vue +23 -21
- package/src/components/views/SimulationExperimentView.vue +37 -33
- package/src/components/widgets/GraphPanelWidget.vue +13 -10
- package/src/components/SpinningWheelComponent.vue +0 -15
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Dialog :modal="true" @show="
|
|
2
|
+
<Dialog :modal="true" appendTo="self" :pt:mask:style="{ position: 'absolute' }" @show="onShow" @hide="onHide">
|
|
3
3
|
<template v-for="(_event, slot) of $slots" #[slot]="scope">
|
|
4
4
|
<slot :name="slot" v-bind="scope" />
|
|
5
5
|
</template>
|
|
@@ -7,5 +7,52 @@
|
|
|
7
7
|
</template>
|
|
8
8
|
|
|
9
9
|
<script setup lang="ts">
|
|
10
|
+
import * as vue from 'vue'
|
|
11
|
+
|
|
10
12
|
import { enableDisableMainMenu } from '../../common/common'
|
|
13
|
+
|
|
14
|
+
let dialogElement: HTMLElement | null = null
|
|
15
|
+
let containerElement: HTMLElement | null | undefined = null
|
|
16
|
+
let mutationObserver: MutationObserver | null = null
|
|
17
|
+
|
|
18
|
+
function checkDialogPosition() {
|
|
19
|
+
if (dialogElement instanceof HTMLElement && containerElement instanceof HTMLElement) {
|
|
20
|
+
const dialogRect = dialogElement.getBoundingClientRect()
|
|
21
|
+
const containerRect = containerElement.getBoundingClientRect()
|
|
22
|
+
|
|
23
|
+
dialogElement.style.top = `${String(Math.max(Math.min(dialogRect.top, containerRect.bottom - dialogRect.height), containerRect.top))}px`
|
|
24
|
+
dialogElement.style.left = `${String(Math.max(Math.min(dialogRect.left, containerRect.right - dialogRect.width), containerRect.left))}px`
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function onShow() {
|
|
29
|
+
enableDisableMainMenu(false)
|
|
30
|
+
|
|
31
|
+
void vue.nextTick().then(() => {
|
|
32
|
+
dialogElement = document.querySelector('.p-dialog')
|
|
33
|
+
containerElement = dialogElement?.closest('[data-pc-section="mask"]')
|
|
34
|
+
|
|
35
|
+
if (dialogElement !== null && containerElement !== null) {
|
|
36
|
+
mutationObserver = new MutationObserver(() => {
|
|
37
|
+
checkDialogPosition()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
mutationObserver.observe(dialogElement, { attributes: true, attributeFilter: ['style'] })
|
|
41
|
+
|
|
42
|
+
checkDialogPosition()
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function onHide() {
|
|
48
|
+
enableDisableMainMenu(true)
|
|
49
|
+
|
|
50
|
+
void vue.nextTick().then(() => {
|
|
51
|
+
if (mutationObserver !== null) {
|
|
52
|
+
mutationObserver.disconnect()
|
|
53
|
+
|
|
54
|
+
mutationObserver = null
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
}
|
|
11
58
|
</script>
|
|
@@ -25,18 +25,21 @@
|
|
|
25
25
|
<script setup lang="ts">
|
|
26
26
|
import { type DataTableCellEditCompleteEvent } from 'primevue/datatable'
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
const props = withDefaults(
|
|
29
|
+
defineProps<{
|
|
30
|
+
name: string
|
|
31
|
+
hasUnits?: boolean
|
|
32
|
+
properties: {
|
|
33
|
+
property: string
|
|
34
|
+
value: number
|
|
35
|
+
unit?: string
|
|
36
|
+
}[]
|
|
37
|
+
}>(),
|
|
38
|
+
{
|
|
39
|
+
hasUnits: true
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
const columnWidth = `width: calc(100% / ${props.hasUnits ? '3' : '2'})`
|
|
40
43
|
const emit = defineEmits(['propertyUpdated'])
|
|
41
44
|
|
|
42
45
|
function onCellEditComplete(event: DataTableCellEditCompleteEvent): void {
|
|
@@ -49,10 +52,6 @@ function onCellEditComplete(event: DataTableCellEditCompleteEvent): void {
|
|
|
49
52
|
</script>
|
|
50
53
|
|
|
51
54
|
<style scoped>
|
|
52
|
-
:deep(.p-datatable-header-cell) {
|
|
53
|
-
transition: none;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
55
|
:deep(.p-inputnumber-input) {
|
|
57
56
|
padding: 0 2px !important;
|
|
58
57
|
margin: 0 !important;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Fieldset class="ml-4! mr-4! mb-4!" legend="Issues">
|
|
3
|
-
<ScrollPanel :class="simulationOnly ? '
|
|
2
|
+
<Fieldset :class="'ml-4! mr-4! mb-4! ' + (simulationOnly ? 'fieldset-simulation-only' : 'fieldset')" legend="Issues">
|
|
3
|
+
<ScrollPanel :class="simulationOnly ? 'scroll-panel-simulation-only' : 'scroll-panel'">
|
|
4
4
|
<div v-for="(issue, index) in issues" :key="`issue_${index}`" :class="`issue ${index > 0 ? 'mt-4!' : ''}`">
|
|
5
5
|
<Message v-if="issue.type === locApi.EIssueType.ERROR" severity="error" icon="pi pi-times-circle">
|
|
6
6
|
{{ issue.description }}
|
|
@@ -23,15 +23,28 @@ defineProps<{
|
|
|
23
23
|
</script>
|
|
24
24
|
|
|
25
25
|
<style scoped>
|
|
26
|
+
.fieldset,
|
|
27
|
+
.fieldset-simulation-only {
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.fieldset {
|
|
32
|
+
height: calc(var(--block-ui-height) - var(--main-menu-height) - var(--file-tablist-height) - 1rem);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.fieldset-simulation-only {
|
|
36
|
+
height: calc(var(--block-ui-height) - 1rem);
|
|
37
|
+
}
|
|
38
|
+
|
|
26
39
|
.issue {
|
|
27
40
|
user-select: text;
|
|
28
41
|
}
|
|
29
42
|
|
|
30
|
-
.
|
|
31
|
-
height: calc(
|
|
43
|
+
.scroll-panel {
|
|
44
|
+
height: calc(var(--block-ui-height) - var(--main-menu-height) - var(--file-tablist-height) - 4.75rem);
|
|
32
45
|
}
|
|
33
46
|
|
|
34
|
-
.
|
|
35
|
-
height: calc(
|
|
47
|
+
.scroll-panel-simulation-only {
|
|
48
|
+
height: calc(var(--block-ui-height) - 4.75rem);
|
|
36
49
|
}
|
|
37
50
|
</style>
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="`flex flex-row h-full ${simulationOnly ? 'simulation-
|
|
2
|
+
<div :class="`flex flex-row h-full ${simulationOnly ? 'div-simulation-only' : 'div-simulation'}`">
|
|
3
3
|
<IssuesView v-if="issues.length !== 0" class="grow" :issues="issues" :simulationOnly="simulationOnly" />
|
|
4
4
|
<div v-else class="flex flex-row grow">
|
|
5
5
|
<div class="ml-4 mr-4 mb-4">
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
6
|
+
<ScrollPanel class="h-full">
|
|
7
|
+
<Fieldset legend="Input parameters">
|
|
8
|
+
<InputWidget
|
|
9
|
+
v-for="(input, index) in (uiJson as any).input"
|
|
10
|
+
v-model="inputValues[index]"
|
|
11
|
+
v-show="showInput[index]"
|
|
12
|
+
:key="`input_${index}`"
|
|
13
|
+
:name="input.name"
|
|
14
|
+
:maximumValue="input.maximumValue"
|
|
15
|
+
:minimumValue="input.minimumValue"
|
|
16
|
+
:possibleValues="input.possibleValues"
|
|
17
|
+
:stepValue="input.stepValue"
|
|
18
|
+
:class="index !== 0 ? 'mt-6' : ''"
|
|
19
|
+
@change="updateUiAndSimulation"
|
|
20
|
+
/>
|
|
21
|
+
</Fieldset>
|
|
22
|
+
</ScrollPanel>
|
|
21
23
|
</div>
|
|
22
24
|
<div :id="plotsDivId" class="grow">
|
|
23
25
|
<GraphPanelWidget
|
|
@@ -46,7 +48,7 @@ const props = defineProps<{
|
|
|
46
48
|
uiJson: locApi.IUiJson
|
|
47
49
|
}>()
|
|
48
50
|
|
|
49
|
-
const math = mathjs.create(mathjs.all, {})
|
|
51
|
+
const math = mathjs.create(mathjs.all ?? {}, {})
|
|
50
52
|
const model = props.file.document().model(0)
|
|
51
53
|
const instance = props.file.instance()
|
|
52
54
|
const instanceTask = instance.task(0)
|
|
@@ -142,11 +144,11 @@ function updateUiAndSimulation() {
|
|
|
142
144
|
height: calc(100% / var(--graph-panel-widget-count));
|
|
143
145
|
}
|
|
144
146
|
|
|
145
|
-
.simulation-
|
|
146
|
-
height:
|
|
147
|
+
.div-simulation-only {
|
|
148
|
+
height: var(--block-ui-height);
|
|
147
149
|
}
|
|
148
150
|
|
|
149
|
-
.simulation
|
|
150
|
-
height: calc(
|
|
151
|
+
.div-simulation {
|
|
152
|
+
height: calc(var(--block-ui-height) - var(--main-menu-height) - var(--file-tablist-height));
|
|
151
153
|
}
|
|
152
154
|
</style>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div :class="`h-full ${simulationOnly ? 'simulation-
|
|
2
|
+
<div :class="`h-full ${simulationOnly ? 'div-simulation-only' : 'div-simulation'}`">
|
|
3
3
|
<Toolbar :id="toolbarId" class="p-1!">
|
|
4
4
|
<template #start>
|
|
5
5
|
<Button class="p-1!" icon="pi pi-play-circle" severity="secondary" text @click="onRun()" />
|
|
@@ -10,34 +10,36 @@
|
|
|
10
10
|
<SplitterPanel :size="simulationOnly ? 100 : 89">
|
|
11
11
|
<Splitter>
|
|
12
12
|
<SplitterPanel class="ml-4 mr-4 mb-4 min-w-fit" :size="25">
|
|
13
|
-
<
|
|
14
|
-
|
|
13
|
+
<ScrollPanel class="h-full">
|
|
14
|
+
<SimulationPropertyEditor :file="file" />
|
|
15
|
+
<!--
|
|
15
16
|
<SolversPropertyEditor />
|
|
16
17
|
<GraphsPropertyEditor />
|
|
17
18
|
<ParametersPropertyEditor />
|
|
18
19
|
-->
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
20
|
+
<Fieldset legend="X-axis">
|
|
21
|
+
<Select
|
|
22
|
+
v-model="xParameter"
|
|
23
|
+
filter
|
|
24
|
+
filterMode="lenient"
|
|
25
|
+
:options="parameters"
|
|
26
|
+
size="small"
|
|
27
|
+
class="w-full"
|
|
28
|
+
@change="updatePlot()"
|
|
29
|
+
/>
|
|
30
|
+
</Fieldset>
|
|
31
|
+
<Fieldset legend="Y-axis">
|
|
32
|
+
<Select
|
|
33
|
+
v-model="yParameter"
|
|
34
|
+
filter
|
|
35
|
+
filterMode="lenient"
|
|
36
|
+
:options="parameters"
|
|
37
|
+
size="small"
|
|
38
|
+
class="w-full"
|
|
39
|
+
@change="updatePlot()"
|
|
40
|
+
/>
|
|
41
|
+
</Fieldset>
|
|
42
|
+
</ScrollPanel>
|
|
41
43
|
</SplitterPanel>
|
|
42
44
|
<SplitterPanel :size="75">
|
|
43
45
|
<GraphPanelWidget :plots="plots" />
|
|
@@ -64,6 +66,7 @@ import * as locApi from '../../libopencor/locApi'
|
|
|
64
66
|
import { type IGraphPanelPlot } from '../widgets/GraphPanelWidget.vue'
|
|
65
67
|
|
|
66
68
|
const props = defineProps<{
|
|
69
|
+
uiEnabled: boolean
|
|
67
70
|
file: locApi.File
|
|
68
71
|
isActiveFile: boolean
|
|
69
72
|
simulationOnly?: boolean
|
|
@@ -154,6 +157,10 @@ vueCommon.trackElementHeight(toolbarId)
|
|
|
154
157
|
|
|
155
158
|
if (!common.isMobile()) {
|
|
156
159
|
vueusecore.onKeyStroke((event: KeyboardEvent) => {
|
|
160
|
+
if (!props.uiEnabled) {
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
|
|
157
164
|
if (props.isActiveFile && !event.ctrlKey && !event.shiftKey && !event.metaKey && event.code === 'F9') {
|
|
158
165
|
event.preventDefault()
|
|
159
166
|
|
|
@@ -164,10 +171,6 @@ if (!common.isMobile()) {
|
|
|
164
171
|
</script>
|
|
165
172
|
|
|
166
173
|
<style scoped>
|
|
167
|
-
:deep(.p-button) {
|
|
168
|
-
transition: none;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
174
|
:deep(.p-button-icon) {
|
|
172
175
|
font-size: 1.5rem;
|
|
173
176
|
}
|
|
@@ -202,13 +205,14 @@ if (!common.isMobile()) {
|
|
|
202
205
|
cursor: default;
|
|
203
206
|
}
|
|
204
207
|
|
|
205
|
-
.simulation-
|
|
206
|
-
height: calc(
|
|
208
|
+
.div-simulation-only {
|
|
209
|
+
height: calc(var(--block-ui-height) - var(--simulation-experiment-toolbar-height));
|
|
207
210
|
}
|
|
208
211
|
|
|
209
|
-
.simulation
|
|
212
|
+
.div-simulation {
|
|
210
213
|
height: calc(
|
|
211
|
-
|
|
214
|
+
var(--block-ui-height) - var(--main-menu-height) - var(--file-tablist-height) -
|
|
215
|
+
var(--simulation-experiment-toolbar-height)
|
|
212
216
|
);
|
|
213
217
|
}
|
|
214
218
|
</style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="h-full">
|
|
2
|
+
<div class="flex flex-row h-full">
|
|
3
3
|
<div v-if="showMarker" class="marker" />
|
|
4
|
-
<div ref="mainDiv" class="h-full" />
|
|
4
|
+
<div ref="mainDiv" class="grow h-full" />
|
|
5
5
|
</div>
|
|
6
6
|
</template>
|
|
7
7
|
|
|
@@ -41,12 +41,15 @@ export interface IGraphPanelPlot {
|
|
|
41
41
|
y: IGraphPanelPlotData
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
const props = withDefaults(
|
|
45
|
+
defineProps<{
|
|
46
|
+
plots: IGraphPanelPlot[]
|
|
47
|
+
showMarker?: boolean
|
|
48
|
+
}>(),
|
|
49
|
+
{
|
|
50
|
+
showMarker: false
|
|
51
|
+
}
|
|
52
|
+
)
|
|
50
53
|
|
|
51
54
|
const mainDiv = vue.ref<InstanceType<typeof Element> | null>(null)
|
|
52
55
|
|
|
@@ -84,11 +87,11 @@ function themeData() {
|
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
vue.watch(
|
|
87
|
-
() => [plots, vueCommon.useLightMode()],
|
|
90
|
+
() => [props.plots, vueCommon.useLightMode()],
|
|
88
91
|
() => {
|
|
89
92
|
Plotly.react(
|
|
90
93
|
mainDiv.value,
|
|
91
|
-
plots.map((plot) => ({
|
|
94
|
+
props.plots.map((plot) => ({
|
|
92
95
|
x: plot.x.data,
|
|
93
96
|
y: plot.y.data,
|
|
94
97
|
type: 'scattergl'
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<ProgressSpinner class="spinning-wheel" />
|
|
3
|
-
</template>
|
|
4
|
-
|
|
5
|
-
<style scoped>
|
|
6
|
-
.spinning-wheel {
|
|
7
|
-
width: 50% !important;
|
|
8
|
-
height: 50% !important;
|
|
9
|
-
position: fixed !important;
|
|
10
|
-
top: 50%;
|
|
11
|
-
left: 50%;
|
|
12
|
-
transform: translate(-50%, -50%);
|
|
13
|
-
z-index: 99999;
|
|
14
|
-
}
|
|
15
|
-
</style>
|