@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.
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <Dialog :modal="true" @show="enableDisableMainMenu(false)" @hide="enableDisableMainMenu(true)">
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>
@@ -9,9 +9,3 @@ defineProps<{
9
9
  percent: number
10
10
  }>()
11
11
  </script>
12
-
13
- <style scoped>
14
- .no-animation :deep(.p-progressbar-value) {
15
- transition: none !important;
16
- }
17
- </style>
@@ -25,18 +25,21 @@
25
25
  <script setup lang="ts">
26
26
  import { type DataTableCellEditCompleteEvent } from 'primevue/datatable'
27
27
 
28
- interface IProps {
29
- name: string
30
- hasUnits?: boolean
31
- properties: {
32
- property: string
33
- value: number
34
- unit?: string
35
- }[]
36
- }
37
-
38
- const { hasUnits = true, name, properties } = defineProps<IProps>()
39
- const columnWidth = `width: calc(100% / ${hasUnits ? '3' : '2'})`
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 ? 'issues-scroll-panel-only' : 'issues-scroll-panel'">
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
- .issues-scroll-panel-only {
31
- height: calc(100vh - 4.75rem);
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
- .issues-scroll-panel {
35
- height: calc(100vh - var(--main-menu-height) - var(--file-tablist-height) - 4.75rem);
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-experiment-only' : 'simulation-experiment'}`">
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
- <Fieldset legend="Input parameters">
7
- <InputWidget
8
- v-for="(input, index) in (uiJson as any).input"
9
- v-model="inputValues[index]"
10
- v-show="showInput[index]"
11
- :key="`input_${index}`"
12
- :name="input.name"
13
- :maximumValue="input.maximumValue"
14
- :minimumValue="input.minimumValue"
15
- :possibleValues="input.possibleValues"
16
- :stepValue="input.stepValue"
17
- :class="index !== 0 ? 'mt-6' : ''"
18
- @change="updateUiAndSimulation"
19
- />
20
- </Fieldset>
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-experiment-only {
146
- height: 100vh;
147
+ .div-simulation-only {
148
+ height: var(--block-ui-height);
147
149
  }
148
150
 
149
- .simulation-experiment {
150
- height: calc(100vh - var(--main-menu-height) - var(--file-tablist-height));
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-experiment-only' : 'simulation-experiment'}`">
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
- <SimulationPropertyEditor :file="file" />
14
- <!--
13
+ <ScrollPanel class="h-full">
14
+ <SimulationPropertyEditor :file="file" />
15
+ <!--
15
16
  <SolversPropertyEditor />
16
17
  <GraphsPropertyEditor />
17
18
  <ParametersPropertyEditor />
18
19
  -->
19
- <Fieldset legend="X-axis">
20
- <Select
21
- v-model="xParameter"
22
- filter
23
- filterMode="lenient"
24
- :options="parameters"
25
- size="small"
26
- class="w-full"
27
- @change="updatePlot()"
28
- />
29
- </Fieldset>
30
- <Fieldset legend="Y-axis">
31
- <Select
32
- v-model="yParameter"
33
- filter
34
- filterMode="lenient"
35
- :options="parameters"
36
- size="small"
37
- class="w-full"
38
- @change="updatePlot()"
39
- />
40
- </Fieldset>
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-experiment-only {
206
- height: calc(100vh - var(--simulation-experiment-toolbar-height));
208
+ .div-simulation-only {
209
+ height: calc(var(--block-ui-height) - var(--simulation-experiment-toolbar-height));
207
210
  }
208
211
 
209
- .simulation-experiment {
212
+ .div-simulation {
210
213
  height: calc(
211
- 100vh - var(--main-menu-height) - var(--file-tablist-height) - var(--simulation-experiment-toolbar-height)
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
- interface IProps {
45
- plots: IGraphPanelPlot[]
46
- showMarker?: boolean
47
- }
48
-
49
- const { plots, showMarker = false } = defineProps<IProps>()
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>