windmill-components 1.305.6 → 1.306.8
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/package/assets/app.css +21 -0
- package/package/components/apps/components/buttons/AppButton.svelte +7 -3
- package/package/components/apps/components/display/AppDownload.svelte +12 -8
- package/package/components/apps/components/display/AppHtml.svelte +6 -23
- package/package/components/apps/components/display/AppHtml.svelte.d.ts +0 -2
- package/package/components/apps/components/display/AppMap.svelte +62 -70
- package/package/components/apps/components/display/AppMap.svelte.d.ts +1 -0
- package/package/components/apps/components/display/AppMenu.svelte +13 -9
- package/package/components/apps/components/display/AppStatCard.svelte +6 -4
- package/package/components/apps/components/display/table/AppAggridTable.svelte +110 -9
- package/package/components/apps/components/display/table/AppAggridTable.svelte.d.ts +2 -0
- package/package/components/apps/components/display/table/AppAggridTableActions.svelte +232 -0
- package/package/components/apps/components/display/table/AppAggridTableActions.svelte.d.ts +30 -0
- package/package/components/apps/components/display/table/AppAggridTableEe.svelte +10 -1
- package/package/components/apps/components/display/table/AppAggridTableEe.svelte.d.ts +2 -0
- package/package/components/apps/components/display/table/AppTable.svelte +0 -1
- package/package/components/apps/components/helpers/eval.js +1 -1
- package/package/components/apps/components/icon.js +0 -2
- package/package/components/apps/components/inputs/AppCheckbox.svelte +1 -0
- package/package/components/apps/components/inputs/AppTextInput.svelte +27 -11
- package/package/components/apps/editor/AppEditorHeader.svelte +4 -0
- package/package/components/apps/editor/AppInputs.svelte +11 -0
- package/package/components/apps/editor/SettingsPanel.svelte +22 -3
- package/package/components/apps/editor/appUtils.js +30 -0
- package/package/components/apps/editor/component/Component.svelte +2 -0
- package/package/components/apps/editor/component/ComponentCallbacks.svelte +4 -0
- package/package/components/apps/editor/component/components.d.ts +25 -2
- package/package/components/apps/editor/component/components.js +12 -0
- package/package/components/apps/editor/contextPanel/components/OutputHeader.svelte +13 -0
- package/package/components/apps/editor/contextPanel/components/TableActionsOutput.svelte +7 -0
- package/package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelWithTable.svelte +14 -0
- package/package/components/apps/editor/inlineScriptsPanel/utils.js +8 -0
- package/package/components/apps/editor/settingsPanel/ComponentPanel.svelte +3 -0
- package/package/components/apps/editor/settingsPanel/TableActions.svelte +86 -72
- package/package/components/apps/editor/settingsPanel/TableActions.svelte.d.ts +1 -1
- package/package/components/apps/editor/settingsPanel/inputEditor/IconSelectInput.svelte +1 -0
- package/package/components/apps/utils.js +9 -0
- package/package/components/common/fileInput/FileInput.svelte +16 -0
- package/package/components/common/fileUpload/FileUpload.svelte +19 -19
- package/package/user.js +1 -1
- package/package/utils.js +1 -1
- package/package.json +8 -1
package/package/assets/app.css
CHANGED
|
@@ -117,3 +117,24 @@
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
+
|
|
121
|
+
.grid-cell-centered {
|
|
122
|
+
display: flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
justify-content: center;
|
|
125
|
+
}
|
|
126
|
+
.grid-cell-centered .svelte-select {
|
|
127
|
+
height: 32px !important;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.grid-cell-centered .selected-item {
|
|
131
|
+
margin-top: -4px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.ol-overlaycontainer-stopevent {
|
|
135
|
+
@apply flex flex-col justify-start items-end;
|
|
136
|
+
}
|
|
137
|
+
.ol-control button {
|
|
138
|
+
@apply w-7 h-7 center-center bg-surface border text-secondary
|
|
139
|
+
rounded mt-1 mr-1 shadow duration-200 hover:bg-surface-hover focus:bg-surface-hover;
|
|
140
|
+
}
|
|
@@ -43,11 +43,11 @@ if (controls) {
|
|
|
43
43
|
$componentControl[id] = controls;
|
|
44
44
|
}
|
|
45
45
|
let runnableComponent;
|
|
46
|
+
let confirmedCallback = undefined;
|
|
46
47
|
let beforeIconComponent;
|
|
47
48
|
let afterIconComponent;
|
|
48
49
|
$: resolvedConfig.beforeIcon && beforeIconComponent && handleBeforeIcon();
|
|
49
50
|
$: resolvedConfig.afterIcon && afterIconComponent && handleAfterIcon();
|
|
50
|
-
let confirmedCallback = undefined;
|
|
51
51
|
async function handleBeforeIcon() {
|
|
52
52
|
if (resolvedConfig.beforeIcon) {
|
|
53
53
|
beforeIconComponent = await loadIcon(resolvedConfig.beforeIcon, beforeIconComponent, 14, undefined, undefined);
|
|
@@ -180,13 +180,17 @@ let css = initCss($app.css?.buttoncomponent, customCss);
|
|
|
180
180
|
{loading}
|
|
181
181
|
>
|
|
182
182
|
{#if resolvedConfig.beforeIcon}
|
|
183
|
-
|
|
183
|
+
{#key resolvedConfig.beforeIcon}
|
|
184
|
+
<div class="min-w-4" bind:this={beforeIconComponent} />
|
|
185
|
+
{/key}
|
|
184
186
|
{/if}
|
|
185
187
|
{#if resolvedConfig.label?.toString() && resolvedConfig.label?.toString()?.length > 0}
|
|
186
188
|
<div>{resolvedConfig.label.toString()}</div>
|
|
187
189
|
{/if}
|
|
188
190
|
{#if resolvedConfig.afterIcon}
|
|
189
|
-
|
|
191
|
+
{#key resolvedConfig.afterIcon}
|
|
192
|
+
<div class="min-w-4" bind:this={afterIconComponent} />
|
|
193
|
+
{/key}
|
|
190
194
|
{/if}
|
|
191
195
|
</Button>
|
|
192
196
|
{/key}
|
|
@@ -23,16 +23,16 @@ const { app, worldStore } = getContext('AppViewerContext');
|
|
|
23
23
|
initOutput($worldStore, id, {});
|
|
24
24
|
let beforeIconComponent;
|
|
25
25
|
let afterIconComponent;
|
|
26
|
-
$: resolvedConfig.beforeIcon && handleBeforeIcon();
|
|
27
|
-
$: resolvedConfig.afterIcon && handleAfterIcon();
|
|
26
|
+
$: resolvedConfig.beforeIcon && beforeIconComponent && handleBeforeIcon();
|
|
27
|
+
$: resolvedConfig.afterIcon && afterIconComponent && handleAfterIcon();
|
|
28
28
|
async function handleBeforeIcon() {
|
|
29
29
|
if (resolvedConfig.beforeIcon) {
|
|
30
|
-
beforeIconComponent = await loadIcon(resolvedConfig.beforeIcon);
|
|
30
|
+
beforeIconComponent = await loadIcon(resolvedConfig.beforeIcon, beforeIconComponent, 14, undefined, undefined);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
async function handleAfterIcon() {
|
|
34
34
|
if (resolvedConfig.afterIcon) {
|
|
35
|
-
afterIconComponent = await loadIcon(resolvedConfig.afterIcon);
|
|
35
|
+
afterIconComponent = await loadIcon(resolvedConfig.afterIcon, afterIconComponent, 14, undefined, undefined);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
let css = initCss($app.css?.downloadcomponent, customCss);
|
|
@@ -87,14 +87,18 @@ let css = initCss($app.css?.downloadcomponent, customCss);
|
|
|
87
87
|
nonCaptureEvent
|
|
88
88
|
>
|
|
89
89
|
<span class="truncate inline-flex gap-2 items-center">
|
|
90
|
-
{#if resolvedConfig.beforeIcon
|
|
91
|
-
|
|
90
|
+
{#if resolvedConfig.beforeIcon}
|
|
91
|
+
{#key resolvedConfig.beforeIcon}
|
|
92
|
+
<div class="min-w-4" bind:this={beforeIconComponent} />
|
|
93
|
+
{/key}
|
|
92
94
|
{/if}
|
|
93
95
|
{#if resolvedConfig.label && resolvedConfig.label?.length > 0}
|
|
94
96
|
<div>{resolvedConfig.label}</div>
|
|
95
97
|
{/if}
|
|
96
|
-
{#if resolvedConfig.afterIcon
|
|
97
|
-
|
|
98
|
+
{#if resolvedConfig.afterIcon}
|
|
99
|
+
{#key resolvedConfig.afterIcon}
|
|
100
|
+
<div class="min-w-4" bind:this={afterIconComponent} />
|
|
101
|
+
{/key}
|
|
98
102
|
{/if}
|
|
99
103
|
</span>
|
|
100
104
|
</Button>
|
|
@@ -2,21 +2,18 @@
|
|
|
2
2
|
import { initOutput } from '../../editor/appUtils';
|
|
3
3
|
import { initCss } from '../../utils';
|
|
4
4
|
import RunnableWrapper from '../helpers/RunnableWrapper.svelte';
|
|
5
|
-
import { twMerge } from 'tailwind-merge';
|
|
6
5
|
import ResolveStyle from '../helpers/ResolveStyle.svelte';
|
|
7
6
|
export let id;
|
|
8
7
|
export let componentInput;
|
|
9
8
|
export let initializing = undefined;
|
|
10
9
|
export let customCss = undefined;
|
|
11
10
|
export let render;
|
|
12
|
-
const { app, worldStore
|
|
11
|
+
const { app, worldStore } = getContext('AppViewerContext');
|
|
13
12
|
const outputs = initOutput($worldStore, id, {
|
|
14
13
|
result: undefined,
|
|
15
14
|
loading: false
|
|
16
15
|
});
|
|
17
16
|
let result = undefined;
|
|
18
|
-
let h = undefined;
|
|
19
|
-
let w = undefined;
|
|
20
17
|
let css = initCss($app.css?.htmlcomponent, customCss);
|
|
21
18
|
</script>
|
|
22
19
|
|
|
@@ -35,8 +32,6 @@ let css = initCss($app.css?.htmlcomponent, customCss);
|
|
|
35
32
|
e?.preventDefault()
|
|
36
33
|
}}
|
|
37
34
|
class="h-full w-full"
|
|
38
|
-
bind:clientHeight={h}
|
|
39
|
-
bind:clientWidth={w}
|
|
40
35
|
>
|
|
41
36
|
<RunnableWrapper
|
|
42
37
|
{outputs}
|
|
@@ -47,22 +42,10 @@ let css = initCss($app.css?.htmlcomponent, customCss);
|
|
|
47
42
|
bind:initializing
|
|
48
43
|
bind:result
|
|
49
44
|
>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
title="sandbox"
|
|
56
|
-
srcdoc={result
|
|
57
|
-
? '<base target="_parent" /><scr' +
|
|
58
|
-
`ipt type="application/javascript" src="/tailwind.js"></script>` +
|
|
59
|
-
result
|
|
60
|
-
: ''}
|
|
61
|
-
/>
|
|
62
|
-
{/key}
|
|
63
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
64
|
-
{#if $mode == 'dnd'}
|
|
65
|
-
<div on:click|stopPropagation class="absolute top-0 h-full w-full" />
|
|
66
|
-
{/if}
|
|
45
|
+
<div class="w-full h-full overflow-auto">
|
|
46
|
+
{#key result}
|
|
47
|
+
{@html result}
|
|
48
|
+
{/key}
|
|
49
|
+
</div>
|
|
67
50
|
</RunnableWrapper>
|
|
68
51
|
</div>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script>import { getContext } from 'svelte';
|
|
2
2
|
import { initCss } from '../../utils';
|
|
3
|
-
import { InputValue } from '../helpers';
|
|
4
3
|
import { twMerge } from 'tailwind-merge';
|
|
5
4
|
import { Map, View, Feature } from 'ol';
|
|
6
5
|
import { useGeographic } from 'ol/proj';
|
|
@@ -8,9 +7,12 @@ import { OSM, Vector as VectorSource } from 'ol/source';
|
|
|
8
7
|
import { Vector as VectorLayer, Tile as TileLayer } from 'ol/layer';
|
|
9
8
|
import { Point } from 'ol/geom';
|
|
10
9
|
import { defaults as defaultControls } from 'ol/control';
|
|
11
|
-
import { findGridItem, initOutput } from '../../editor/appUtils';
|
|
10
|
+
import { findGridItem, initConfig, initOutput } from '../../editor/appUtils';
|
|
12
11
|
import InitializeComponent from '../helpers/InitializeComponent.svelte';
|
|
13
12
|
import ResolveStyle from '../helpers/ResolveStyle.svelte';
|
|
13
|
+
import { components } from '../../editor/component';
|
|
14
|
+
import ResolveConfig from '../helpers/ResolveConfig.svelte';
|
|
15
|
+
import { Style, Circle, Fill, Stroke, Text } from 'ol/style';
|
|
14
16
|
const LAYER_NAME = {
|
|
15
17
|
MARKER: 'Marker'
|
|
16
18
|
};
|
|
@@ -18,7 +20,9 @@ export let id;
|
|
|
18
20
|
export let configuration;
|
|
19
21
|
export let customCss = undefined;
|
|
20
22
|
export let render;
|
|
23
|
+
export let extraKey = undefined;
|
|
21
24
|
const { app, worldStore, selectedComponent, connectingInput, focusedGrid, mode } = getContext('AppViewerContext');
|
|
25
|
+
const resolvedConfig = initConfig(components['mapcomponent'].initialData.configuration, configuration);
|
|
22
26
|
let outputs = initOutput($worldStore, id, {
|
|
23
27
|
mapRegion: {
|
|
24
28
|
topLeft: { lat: 0, lon: 0 },
|
|
@@ -27,18 +31,13 @@ let outputs = initOutput($worldStore, id, {
|
|
|
27
31
|
});
|
|
28
32
|
let map = undefined;
|
|
29
33
|
let mapElement = undefined;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
let zoom = undefined;
|
|
33
|
-
// If string, it's a JSON file read as text
|
|
34
|
-
let markers = undefined;
|
|
35
|
-
$: if (map && longitude && latitude) {
|
|
36
|
-
map.getView().setCenter([longitude, latitude]);
|
|
34
|
+
$: if (map && resolvedConfig.longitude && resolvedConfig.latitude) {
|
|
35
|
+
map.getView().setCenter([resolvedConfig.longitude, resolvedConfig.latitude]);
|
|
37
36
|
}
|
|
38
|
-
$: if (map && zoom) {
|
|
39
|
-
map.getView().setZoom(zoom);
|
|
37
|
+
$: if (map && resolvedConfig.zoom) {
|
|
38
|
+
map.getView().setZoom(resolvedConfig.zoom);
|
|
40
39
|
}
|
|
41
|
-
$: if (map && markers) {
|
|
40
|
+
$: if (map && resolvedConfig.markers) {
|
|
42
41
|
updateMarkers();
|
|
43
42
|
}
|
|
44
43
|
function selectComponent() {
|
|
@@ -56,12 +55,12 @@ function getLayersByName(name) {
|
|
|
56
55
|
function getMarkerArray() {
|
|
57
56
|
let array = undefined;
|
|
58
57
|
try {
|
|
59
|
-
if (typeof markers === 'string') {
|
|
60
|
-
const json = JSON.parse(markers);
|
|
58
|
+
if (typeof resolvedConfig.markers === 'string') {
|
|
59
|
+
const json = JSON.parse(resolvedConfig.markers);
|
|
61
60
|
array = Array.isArray(json) ? json : [json];
|
|
62
61
|
}
|
|
63
62
|
else {
|
|
64
|
-
array = markers;
|
|
63
|
+
array = resolvedConfig.markers;
|
|
65
64
|
}
|
|
66
65
|
return array?.filter((m) => !isNaN(+m.lat) && !isNaN(+m.lon));
|
|
67
66
|
}
|
|
@@ -73,24 +72,34 @@ function getMarkerArray() {
|
|
|
73
72
|
function createMarkerLayers() {
|
|
74
73
|
const markerArray = getMarkerArray();
|
|
75
74
|
return markerArray?.map((m) => {
|
|
75
|
+
const feature = new Feature({
|
|
76
|
+
geometry: new Point([+m.lon, +m.lat]),
|
|
77
|
+
name: m.title
|
|
78
|
+
});
|
|
79
|
+
feature.setStyle(new Style({
|
|
80
|
+
image: new Circle({
|
|
81
|
+
radius: m.radius ?? 7,
|
|
82
|
+
fill: new Fill({ color: m.color ?? '#dc2626' }),
|
|
83
|
+
stroke: new Stroke({ width: m.strokeWidth ?? 3, color: m.strokeColor ?? '#fca5a5' })
|
|
84
|
+
}),
|
|
85
|
+
text: new Text({
|
|
86
|
+
text: m.title,
|
|
87
|
+
font: '12px Calibri,sans-serif',
|
|
88
|
+
fill: new Fill({ color: '#000' }),
|
|
89
|
+
stroke: new Stroke({
|
|
90
|
+
color: '#fff',
|
|
91
|
+
width: 2
|
|
92
|
+
}),
|
|
93
|
+
offsetY: -15
|
|
94
|
+
})
|
|
95
|
+
}));
|
|
76
96
|
return new VectorLayer({
|
|
77
97
|
properties: {
|
|
78
98
|
name: LAYER_NAME.MARKER
|
|
79
99
|
},
|
|
80
100
|
source: new VectorSource({
|
|
81
|
-
features: [
|
|
82
|
-
|
|
83
|
-
geometry: new Point([+m.lon, +m.lat]),
|
|
84
|
-
name: m.title
|
|
85
|
-
})
|
|
86
|
-
]
|
|
87
|
-
}),
|
|
88
|
-
style: {
|
|
89
|
-
'circle-radius': m.radius ?? 7,
|
|
90
|
-
'circle-fill-color': m.color ?? '#dc2626',
|
|
91
|
-
'circle-stroke-width': m.strokeWidth ?? 3,
|
|
92
|
-
'circle-stroke-color': m.strokeColor ?? '#fca5a5'
|
|
93
|
-
}
|
|
101
|
+
features: [feature]
|
|
102
|
+
})
|
|
94
103
|
});
|
|
95
104
|
});
|
|
96
105
|
}
|
|
@@ -116,8 +125,8 @@ $: if (!map && mapElement) {
|
|
|
116
125
|
...(createMarkerLayers() || [])
|
|
117
126
|
],
|
|
118
127
|
view: new View({
|
|
119
|
-
center: [longitude ?? 0, latitude ?? 0],
|
|
120
|
-
zoom: zoom ?? 2
|
|
128
|
+
center: [resolvedConfig.longitude ?? 0, resolvedConfig.latitude ?? 0],
|
|
129
|
+
zoom: resolvedConfig.zoom ?? 2
|
|
121
130
|
}),
|
|
122
131
|
controls: defaultControls({
|
|
123
132
|
attribution: false
|
|
@@ -125,9 +134,21 @@ $: if (!map && mapElement) {
|
|
|
125
134
|
});
|
|
126
135
|
updateRegionOutput();
|
|
127
136
|
}
|
|
137
|
+
let previousLock = undefined;
|
|
138
|
+
function updateInteractions(map) {
|
|
139
|
+
if (previousLock === resolvedConfig.lock) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
previousLock = resolvedConfig.lock;
|
|
143
|
+
map.getInteractions().forEach((i) => {
|
|
144
|
+
i.setActive(!resolvedConfig.lock);
|
|
145
|
+
});
|
|
146
|
+
map.changed();
|
|
147
|
+
}
|
|
148
|
+
$: map && resolvedConfig && updateInteractions(map);
|
|
128
149
|
let css = initCss($app.css?.mapcomponent, customCss);
|
|
129
150
|
function updateRegionOutput() {
|
|
130
|
-
if (map) {
|
|
151
|
+
if (map && !resolvedConfig.lock) {
|
|
131
152
|
let extent = map.getView().calculateExtent(map.getSize());
|
|
132
153
|
const [left, bottom, right, top] = extent;
|
|
133
154
|
if (outputs?.mapRegion) {
|
|
@@ -162,10 +183,16 @@ function handleSyncRegion() {
|
|
|
162
183
|
}
|
|
163
184
|
</script>
|
|
164
185
|
|
|
165
|
-
|
|
166
|
-
<
|
|
167
|
-
|
|
168
|
-
|
|
186
|
+
{#each Object.entries(components['mapcomponent'].initialData.configuration) as [key, initialConfig] (key)}
|
|
187
|
+
<ResolveConfig
|
|
188
|
+
{id}
|
|
189
|
+
{extraKey}
|
|
190
|
+
{key}
|
|
191
|
+
bind:resolvedConfig={resolvedConfig[key]}
|
|
192
|
+
configuration={configuration[key]}
|
|
193
|
+
{initialConfig}
|
|
194
|
+
/>
|
|
195
|
+
{/each}
|
|
169
196
|
|
|
170
197
|
<InitializeComponent {id} />
|
|
171
198
|
|
|
@@ -201,38 +228,3 @@ function handleSyncRegion() {
|
|
|
201
228
|
{/if}
|
|
202
229
|
</div>
|
|
203
230
|
{/if}
|
|
204
|
-
|
|
205
|
-
<style global>
|
|
206
|
-
:global(.ol-overlaycontainer-stopevent) {
|
|
207
|
-
display: flex;
|
|
208
|
-
flex-direction: column;
|
|
209
|
-
align-items: flex-end;
|
|
210
|
-
justify-content: flex-start
|
|
211
|
-
}
|
|
212
|
-
:global(.ol-control) :global(button) {
|
|
213
|
-
margin-top: 0.25rem;
|
|
214
|
-
margin-right: 0.25rem;
|
|
215
|
-
height: 1.75rem;
|
|
216
|
-
width: 1.75rem;
|
|
217
|
-
border-radius: 0.25rem;
|
|
218
|
-
border-width: 1px;
|
|
219
|
-
--tw-bg-opacity: 1;
|
|
220
|
-
background-color: rgb(var(--color-surface) / var(--tw-bg-opacity));
|
|
221
|
-
--tw-text-opacity: 1;
|
|
222
|
-
color: rgb(var(--color-text-secondary) / var(--tw-text-opacity));
|
|
223
|
-
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
|
224
|
-
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
|
225
|
-
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
226
|
-
transition-duration: 200ms;
|
|
227
|
-
display: flex;
|
|
228
|
-
justify-content: center;
|
|
229
|
-
align-items: center
|
|
230
|
-
}
|
|
231
|
-
:global(.ol-control) :global(button:hover) {
|
|
232
|
-
--tw-bg-opacity: 1;
|
|
233
|
-
background-color: rgb(var(--color-surface-hover) / var(--tw-bg-opacity))
|
|
234
|
-
}
|
|
235
|
-
:global(.ol-control) :global(button:focus) {
|
|
236
|
-
--tw-bg-opacity: 1;
|
|
237
|
-
background-color: rgb(var(--color-surface-hover) / var(--tw-bg-opacity))
|
|
238
|
-
}</style>
|
|
@@ -25,19 +25,19 @@ let outputs = initOutput($worldStore, id, {
|
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
27
|
const resolvedConfig = initConfig(components['menucomponent'].initialData.configuration, configuration);
|
|
28
|
+
let css = initCss($app.css?.menucomponent, customCss);
|
|
28
29
|
let beforeIconComponent;
|
|
29
30
|
let afterIconComponent;
|
|
30
|
-
|
|
31
|
-
$: resolvedConfig.
|
|
32
|
-
$: resolvedConfig.afterIcon && handleAfterIcon();
|
|
31
|
+
$: resolvedConfig.beforeIcon && beforeIconComponent && handleBeforeIcon();
|
|
32
|
+
$: resolvedConfig.afterIcon && afterIconComponent && handleAfterIcon();
|
|
33
33
|
async function handleBeforeIcon() {
|
|
34
34
|
if (resolvedConfig.beforeIcon) {
|
|
35
|
-
beforeIconComponent = await loadIcon(resolvedConfig.beforeIcon);
|
|
35
|
+
beforeIconComponent = await loadIcon(resolvedConfig.beforeIcon, beforeIconComponent, 14, undefined, undefined);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
async function handleAfterIcon() {
|
|
39
39
|
if (resolvedConfig.afterIcon) {
|
|
40
|
-
afterIconComponent = await loadIcon(resolvedConfig.afterIcon);
|
|
40
|
+
afterIconComponent = await loadIcon(resolvedConfig.afterIcon, afterIconComponent, 14, undefined, undefined);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
</script>
|
|
@@ -86,14 +86,18 @@ async function handleAfterIcon() {
|
|
|
86
86
|
nonCaptureEvent
|
|
87
87
|
>
|
|
88
88
|
<span class="truncate inline-flex gap-2 items-center">
|
|
89
|
-
{#if resolvedConfig.beforeIcon
|
|
90
|
-
|
|
89
|
+
{#if resolvedConfig.beforeIcon}
|
|
90
|
+
{#key resolvedConfig.beforeIcon}
|
|
91
|
+
<div class="min-w-4" bind:this={beforeIconComponent} />
|
|
92
|
+
{/key}
|
|
91
93
|
{/if}
|
|
92
94
|
{#if resolvedConfig.label && resolvedConfig.label?.length > 0}
|
|
93
95
|
<div>{resolvedConfig.label}</div>
|
|
94
96
|
{/if}
|
|
95
|
-
{#if resolvedConfig.afterIcon
|
|
96
|
-
|
|
97
|
+
{#if resolvedConfig.afterIcon}
|
|
98
|
+
{#key resolvedConfig.afterIcon}
|
|
99
|
+
<div class="min-w-4" bind:this={afterIconComponent} />
|
|
100
|
+
{/key}
|
|
97
101
|
{/if}
|
|
98
102
|
</span>
|
|
99
103
|
</Button>
|
|
@@ -18,10 +18,10 @@ let resolvedConfig = initConfig(components['statcomponent'].initialData.configur
|
|
|
18
18
|
initOutput($worldStore, id, {});
|
|
19
19
|
let css = initCss($app.css?.statcomponent, customCss);
|
|
20
20
|
let iconComponent;
|
|
21
|
-
$: isIcon && resolvedConfig?.media?.configuration?.icon?.icon && handleIcon();
|
|
21
|
+
$: isIcon && resolvedConfig?.media?.configuration?.icon?.icon && iconComponent && handleIcon();
|
|
22
22
|
async function handleIcon() {
|
|
23
23
|
if (resolvedConfig?.media?.configuration?.icon?.icon) {
|
|
24
|
-
iconComponent = await loadIcon(resolvedConfig
|
|
24
|
+
iconComponent = await loadIcon(resolvedConfig?.media?.configuration?.icon?.icon, iconComponent, 34, undefined, undefined);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
$: isIcon = resolvedConfig.media?.selected == 'icon';
|
|
@@ -66,8 +66,10 @@ $: isIcon = resolvedConfig.media?.selected == 'icon';
|
|
|
66
66
|
style={css?.media?.style}
|
|
67
67
|
>
|
|
68
68
|
{#if isIcon}
|
|
69
|
-
{#if resolvedConfig?.media
|
|
70
|
-
|
|
69
|
+
{#if resolvedConfig?.media}
|
|
70
|
+
{#key resolvedConfig.media}
|
|
71
|
+
<div class="min-w-4 text-primary" bind:this={iconComponent} />
|
|
72
|
+
{/key}
|
|
71
73
|
{/if}
|
|
72
74
|
{:else}
|
|
73
75
|
<Loader loading={resolvedConfig?.media?.configuration?.image?.source == undefined}>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>import { GridApi, createGrid } from 'ag-grid-community';
|
|
2
2
|
import { isObject, sendUserToast } from '../../../../../utils';
|
|
3
|
-
import { getContext } from 'svelte';
|
|
3
|
+
import { SvelteComponent, getContext, onDestroy } from 'svelte';
|
|
4
4
|
import RunnableWrapper from '../../helpers/RunnableWrapper.svelte';
|
|
5
5
|
import { initConfig, initOutput } from '../../../editor/appUtils';
|
|
6
6
|
import { components } from '../../../editor/component';
|
|
@@ -13,6 +13,7 @@ import { Loader2 } from 'lucide-svelte';
|
|
|
13
13
|
import { twMerge } from 'tailwind-merge';
|
|
14
14
|
import { initCss } from '../../../utils';
|
|
15
15
|
import ResolveStyle from '../../helpers/ResolveStyle.svelte';
|
|
16
|
+
import AppAggridTableActions from './AppAggridTableActions.svelte';
|
|
16
17
|
// import 'ag-grid-community/dist/styles/ag-theme-alpine-dark.css'
|
|
17
18
|
export let id;
|
|
18
19
|
export let componentInput;
|
|
@@ -20,7 +21,11 @@ export let configuration;
|
|
|
20
21
|
export let initializing = undefined;
|
|
21
22
|
export let render;
|
|
22
23
|
export let customCss = undefined;
|
|
23
|
-
|
|
24
|
+
export let actions = undefined;
|
|
25
|
+
const context = getContext('AppViewerContext');
|
|
26
|
+
const iterContext = getContext('ListWrapperContext');
|
|
27
|
+
const listInputs = getContext('ListInputs');
|
|
28
|
+
const { app, worldStore, selectedComponent, componentControl, darkMode } = context;
|
|
24
29
|
const rowHeights = {
|
|
25
30
|
normal: 40,
|
|
26
31
|
compact: 30,
|
|
@@ -59,6 +64,7 @@ let outputs = initOutput($worldStore, id, {
|
|
|
59
64
|
page: 0,
|
|
60
65
|
newChange: { row: 0, column: '', value: undefined },
|
|
61
66
|
ready: undefined,
|
|
67
|
+
inputs: {},
|
|
62
68
|
filters: {},
|
|
63
69
|
displayedRowCount: 0
|
|
64
70
|
});
|
|
@@ -75,8 +81,14 @@ function toggleRow(row) {
|
|
|
75
81
|
if (!deepEqual(outputs?.selectedRow?.peak(), data)) {
|
|
76
82
|
outputs?.selectedRow.set(data);
|
|
77
83
|
}
|
|
84
|
+
if (iterContext && listInputs) {
|
|
85
|
+
listInputs.set(id, { selectedRow: data, selectedRowIndex: selectedRowIndex });
|
|
86
|
+
}
|
|
78
87
|
}
|
|
79
88
|
}
|
|
89
|
+
onDestroy(() => {
|
|
90
|
+
listInputs?.remove(id);
|
|
91
|
+
});
|
|
80
92
|
function toggleRows(rows) {
|
|
81
93
|
if (rows.length === 0) {
|
|
82
94
|
outputs?.selectedRows.set([]);
|
|
@@ -111,16 +123,93 @@ function onCellValueChanged(event) {
|
|
|
111
123
|
let extraConfig = resolvedConfig.extraConfig;
|
|
112
124
|
let api = undefined;
|
|
113
125
|
let eGui;
|
|
114
|
-
$: loaded && eGui && mountGrid();
|
|
115
126
|
let state = undefined;
|
|
127
|
+
$: loaded && eGui && mountGrid();
|
|
128
|
+
const cachedDivs = new Map();
|
|
129
|
+
function refreshActions(actions) {
|
|
130
|
+
if (!deepEqual(actions, lastActions)) {
|
|
131
|
+
lastActions = [...actions];
|
|
132
|
+
cachedDivs.forEach((cachedDiv) => {
|
|
133
|
+
cachedDiv.svelteComponent.$destroy();
|
|
134
|
+
cachedDiv.div.remove();
|
|
135
|
+
});
|
|
136
|
+
cachedDivs.clear();
|
|
137
|
+
updateOptions();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
let lastActions = undefined;
|
|
141
|
+
$: actions && refreshActions(actions);
|
|
142
|
+
let inputs = {};
|
|
143
|
+
function actionRenderer(params) {
|
|
144
|
+
const { rowIndex, data: row } = params;
|
|
145
|
+
if (rowIndex === -1 || actions == undefined || actions?.length == 0) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
if (cachedDivs.has(rowIndex)) {
|
|
149
|
+
return cachedDivs.get(rowIndex)?.div;
|
|
150
|
+
}
|
|
151
|
+
const div = document.createElement('div');
|
|
152
|
+
div.classList.add('flex', 'flex-row', 'items-center', 'w-full', 'h-full');
|
|
153
|
+
const svelteComponent = new AppAggridTableActions({
|
|
154
|
+
target: div,
|
|
155
|
+
props: {
|
|
156
|
+
id: id,
|
|
157
|
+
actions,
|
|
158
|
+
rowIndex,
|
|
159
|
+
row,
|
|
160
|
+
render,
|
|
161
|
+
wrapActions: resolvedConfig.wrapActions,
|
|
162
|
+
onSet: (id, value) => {
|
|
163
|
+
if (!inputs[id]) {
|
|
164
|
+
inputs[id] = { [rowIndex]: value };
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
inputs[id] = { ...inputs[id], [rowIndex]: value };
|
|
168
|
+
}
|
|
169
|
+
outputs?.inputs.set(inputs, true);
|
|
170
|
+
},
|
|
171
|
+
onRemove: (id) => {
|
|
172
|
+
if (inputs?.[id] == undefined) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
delete inputs[id][rowIndex];
|
|
176
|
+
inputs[id] = { ...inputs[id] };
|
|
177
|
+
if (Object.keys(inputs?.[id] ?? {}).length == 0) {
|
|
178
|
+
delete inputs[id];
|
|
179
|
+
inputs = { ...inputs };
|
|
180
|
+
}
|
|
181
|
+
outputs?.inputs.set(inputs, true);
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
context: new Map([['AppViewerContext', context]])
|
|
185
|
+
});
|
|
186
|
+
cachedDivs.set(rowIndex, {
|
|
187
|
+
div,
|
|
188
|
+
actions,
|
|
189
|
+
svelteComponent
|
|
190
|
+
});
|
|
191
|
+
return div;
|
|
192
|
+
}
|
|
116
193
|
function mountGrid() {
|
|
117
194
|
if (eGui) {
|
|
118
195
|
try {
|
|
196
|
+
let columnDefs = Array.isArray(resolvedConfig?.columnDefs) && resolvedConfig.columnDefs.every(isObject)
|
|
197
|
+
? [...resolvedConfig?.columnDefs] // Clone to avoid direct mutation
|
|
198
|
+
: [];
|
|
199
|
+
// Add the action column if actions are defined
|
|
200
|
+
if (actions && actions.length > 0) {
|
|
201
|
+
columnDefs.push({
|
|
202
|
+
headerName: 'Actions',
|
|
203
|
+
cellRenderer: actionRenderer,
|
|
204
|
+
autoHeight: true,
|
|
205
|
+
cellStyle: { textAlign: 'center' },
|
|
206
|
+
cellClass: 'grid-cell-centered',
|
|
207
|
+
...(!resolvedConfig?.wrapActions ? { minWidth: 130 * actions?.length } : {})
|
|
208
|
+
});
|
|
209
|
+
}
|
|
119
210
|
createGrid(eGui, {
|
|
120
211
|
rowData: value,
|
|
121
|
-
columnDefs:
|
|
122
|
-
? resolvedConfig?.columnDefs
|
|
123
|
-
: [],
|
|
212
|
+
columnDefs: columnDefs,
|
|
124
213
|
pagination: resolvedConfig?.pagination,
|
|
125
214
|
paginationAutoPageSize: resolvedConfig?.pagination,
|
|
126
215
|
defaultColDef: {
|
|
@@ -215,11 +304,23 @@ function updateValue() {
|
|
|
215
304
|
}
|
|
216
305
|
function updateOptions() {
|
|
217
306
|
try {
|
|
307
|
+
const columnDefs = Array.isArray(resolvedConfig?.columnDefs) && resolvedConfig.columnDefs.every(isObject)
|
|
308
|
+
? [...resolvedConfig?.columnDefs] // Clone to avoid direct mutation
|
|
309
|
+
: [];
|
|
310
|
+
// Add the action column if actions are defined
|
|
311
|
+
if (actions && actions.length > 0) {
|
|
312
|
+
columnDefs.push({
|
|
313
|
+
headerName: 'Actions',
|
|
314
|
+
cellRenderer: actionRenderer,
|
|
315
|
+
autoHeight: true,
|
|
316
|
+
cellStyle: { textAlign: 'center' },
|
|
317
|
+
cellClass: 'grid-cell-centered',
|
|
318
|
+
...(!resolvedConfig?.wrapActions ? { minWidth: 130 * actions?.length } : {})
|
|
319
|
+
});
|
|
320
|
+
}
|
|
218
321
|
api?.updateGridOptions({
|
|
219
322
|
rowData: value,
|
|
220
|
-
columnDefs:
|
|
221
|
-
? resolvedConfig?.columnDefs
|
|
222
|
-
: undefined,
|
|
323
|
+
columnDefs: columnDefs,
|
|
223
324
|
pagination: resolvedConfig?.pagination,
|
|
224
325
|
paginationAutoPageSize: resolvedConfig?.pagination,
|
|
225
326
|
defaultColDef: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SvelteComponent } from "svelte";
|
|
2
2
|
import type { AppInput } from '../../../inputType';
|
|
3
3
|
import type { ComponentCustomCSS, RichConfigurations } from '../../../types';
|
|
4
|
+
import { type TableAction } from '../../../editor/component';
|
|
4
5
|
import 'ag-grid-community/styles/ag-grid.css';
|
|
5
6
|
import 'ag-grid-community/styles/ag-theme-alpine.css';
|
|
6
7
|
declare const __propDef: {
|
|
@@ -11,6 +12,7 @@ declare const __propDef: {
|
|
|
11
12
|
initializing?: boolean | undefined;
|
|
12
13
|
render: boolean;
|
|
13
14
|
customCss?: ComponentCustomCSS<'aggridcomponent'> | undefined;
|
|
15
|
+
actions?: TableAction[] | undefined;
|
|
14
16
|
};
|
|
15
17
|
events: {
|
|
16
18
|
[evt: string]: CustomEvent<any>;
|