Compare commits
9 Commits
darkmode_n
...
fix-aggrid
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a655090c9 | ||
|
|
40a64a05d5 | ||
|
|
071c3cf04a | ||
|
|
c037117708 | ||
|
|
ade9734936 | ||
|
|
6e87e089ac | ||
|
|
62efbe11e7 | ||
|
|
7eca53f9e7 | ||
|
|
e9e6614486 |
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,5 +1,20 @@
|
||||
# Changelog
|
||||
|
||||
## [1.306.0](https://github.com/windmill-labs/windmill/compare/v1.305.3...v1.306.0) (2024-04-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **frontend:** add maplock + properly display marker title ([#3544](https://github.com/windmill-labs/windmill/issues/3544)) ([e9e6614](https://github.com/windmill-labs/windmill/commit/e9e66144860f2a390b58db1f5c0e2d09b46a777f))
|
||||
* **frontend:** Ag grid actions ([#3535](https://github.com/windmill-labs/windmill/issues/3535)) ([48ad095](https://github.com/windmill-labs/windmill/commit/48ad095633f3e83f16eccc15b1de534c4804d807))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** Correctly handle undefined actions ([#3545](https://github.com/windmill-labs/windmill/issues/3545)) ([7eca53f](https://github.com/windmill-labs/windmill/commit/7eca53f9e7f0640bd43fc37abbe6eb624d77430d))
|
||||
* **frontend:** Fix AgGrid action selection ([#3543](https://github.com/windmill-labs/windmill/issues/3543)) ([0672362](https://github.com/windmill-labs/windmill/commit/06723629caed3e152a9161ec3f1fee10710b4971))
|
||||
* **frontend:** Fix s3 uploader ([#3539](https://github.com/windmill-labs/windmill/issues/3539)) ([0afd68d](https://github.com/windmill-labs/windmill/commit/0afd68d474b65ce1d1026bdabb081d775e0dcaa3))
|
||||
|
||||
## [1.305.3](https://github.com/windmill-labs/windmill/compare/v1.305.2...v1.305.3) (2024-04-12)
|
||||
|
||||
|
||||
|
||||
40
backend/Cargo.lock
generated
40
backend/Cargo.lock
generated
@@ -100,9 +100,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.16"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
|
||||
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
@@ -9707,7 +9707,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windmill"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -9744,7 +9744,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -9821,7 +9821,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-client"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"chrono",
|
||||
@@ -9839,7 +9839,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-audit"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
@@ -9852,7 +9852,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-common"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"aws-config",
|
||||
@@ -9888,7 +9888,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-git-sync"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"rsmq_async",
|
||||
@@ -9903,7 +9903,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -9911,7 +9911,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-bash"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -9922,7 +9922,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-go"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gosyn",
|
||||
@@ -9934,7 +9934,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-graphql"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -9945,7 +9945,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.12.1",
|
||||
@@ -9956,7 +9956,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py-imports"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -9973,7 +9973,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-sql"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -9984,7 +9984,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ts"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"convert_case 0.6.0",
|
||||
@@ -10002,7 +10002,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-wasm"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"getrandom 0.2.14",
|
||||
@@ -10020,7 +10020,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-queue"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -10053,7 +10053,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-sql-datatype-parser-wasm"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
@@ -10064,7 +10064,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-worker"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "windmill"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -24,7 +24,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.305.3
|
||||
version: 1.306.0
|
||||
title: Windmill API
|
||||
|
||||
contact:
|
||||
|
||||
@@ -2,7 +2,7 @@ import { sleep } from "https://deno.land/x/sleep@v1.2.1/mod.ts";
|
||||
import * as windmill from "https://deno.land/x/windmill@v1.174.0/mod.ts";
|
||||
import * as api from "https://deno.land/x/windmill@v1.174.0/windmill-api/index.ts";
|
||||
|
||||
export const VERSION = "v1.305.3";
|
||||
export const VERSION = "v1.306.0";
|
||||
|
||||
export async function login(email: string, password: string): Promise<string> {
|
||||
return await windmill.UserService.login({
|
||||
|
||||
@@ -31,7 +31,7 @@ addEventListener("error", (event) => {
|
||||
}
|
||||
});
|
||||
|
||||
export const VERSION = "v1.305.3";
|
||||
export const VERSION = "v1.306.0";
|
||||
|
||||
let command: any = new Command()
|
||||
.name("wmill")
|
||||
|
||||
4
frontend/package-lock.json
generated
4
frontend/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.305.3",
|
||||
"version": "1.306.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "windmill-components",
|
||||
"version": "1.305.3",
|
||||
"version": "1.306.0",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha256-js": "^4.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.305.3",
|
||||
"version": "1.306.0",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
|
||||
@@ -130,3 +130,11 @@
|
||||
.grid-cell-centered .selected-item {
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
.ol-overlaycontainer-stopevent {
|
||||
@apply flex flex-col justify-start items-end;
|
||||
}
|
||||
.ol-control button {
|
||||
@apply w-7 h-7 center-center bg-surface border text-secondary
|
||||
rounded mt-1 mr-1 shadow duration-200 hover:bg-surface-hover focus:bg-surface-hover;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import { getContext } from 'svelte'
|
||||
import { initCss } from '../../utils'
|
||||
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
|
||||
import { InputValue } from '../helpers'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { Map, View, Feature } from 'ol'
|
||||
import { useGeographic } from 'ol/proj'
|
||||
@@ -10,10 +9,12 @@
|
||||
import { Vector as VectorLayer, Tile as TileLayer } from 'ol/layer'
|
||||
import { Point } from 'ol/geom'
|
||||
import { defaults as defaultControls } from 'ol/control'
|
||||
import { findGridItem, initOutput } from '../../editor/appUtils'
|
||||
import { findGridItem, initConfig, initOutput } from '../../editor/appUtils'
|
||||
import InitializeComponent from '../helpers/InitializeComponent.svelte'
|
||||
import ResolveStyle from '../helpers/ResolveStyle.svelte'
|
||||
|
||||
import { components } from '../../editor/component'
|
||||
import ResolveConfig from '../helpers/ResolveConfig.svelte'
|
||||
import { Style, Circle, Fill, Stroke, Text } from 'ol/style'
|
||||
interface Marker {
|
||||
lon: number
|
||||
lat: number
|
||||
@@ -32,10 +33,16 @@
|
||||
export let configuration: RichConfigurations
|
||||
export let customCss: ComponentCustomCSS<'mapcomponent'> | undefined = undefined
|
||||
export let render: boolean
|
||||
export let extraKey: string | undefined = undefined
|
||||
|
||||
const { app, worldStore, selectedComponent, connectingInput, focusedGrid, mode } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
const resolvedConfig = initConfig(
|
||||
components['mapcomponent'].initialData.configuration,
|
||||
configuration
|
||||
)
|
||||
|
||||
let outputs = initOutput($worldStore, id, {
|
||||
mapRegion: {
|
||||
topLeft: { lat: 0, lon: 0 },
|
||||
@@ -46,21 +53,15 @@
|
||||
let map: Map | undefined = undefined
|
||||
let mapElement: HTMLDivElement | undefined = undefined
|
||||
|
||||
let longitude: number | undefined = undefined
|
||||
let latitude: number | undefined = undefined
|
||||
let zoom: number | undefined = undefined
|
||||
// If string, it's a JSON file read as text
|
||||
let markers: Marker[] | string | undefined = undefined
|
||||
|
||||
$: if (map && longitude && latitude) {
|
||||
map.getView().setCenter([longitude, latitude])
|
||||
$: if (map && resolvedConfig.longitude && resolvedConfig.latitude) {
|
||||
map.getView().setCenter([resolvedConfig.longitude, resolvedConfig.latitude])
|
||||
}
|
||||
|
||||
$: if (map && zoom) {
|
||||
map.getView().setZoom(zoom)
|
||||
$: if (map && resolvedConfig.zoom) {
|
||||
map.getView().setZoom(resolvedConfig.zoom)
|
||||
}
|
||||
|
||||
$: if (map && markers) {
|
||||
$: if (map && resolvedConfig.markers) {
|
||||
updateMarkers()
|
||||
}
|
||||
|
||||
@@ -81,11 +82,11 @@
|
||||
function getMarkerArray(): Marker[] | undefined {
|
||||
let array: Marker[] | undefined = undefined
|
||||
try {
|
||||
if (typeof markers === 'string') {
|
||||
const json = JSON.parse(markers)
|
||||
if (typeof resolvedConfig.markers === 'string') {
|
||||
const json = JSON.parse(resolvedConfig.markers)
|
||||
array = Array.isArray(json) ? json : [json]
|
||||
} else {
|
||||
array = markers
|
||||
array = resolvedConfig.markers
|
||||
}
|
||||
return array?.filter((m) => !isNaN(+m.lat) && !isNaN(+m.lon))
|
||||
} catch (error) {
|
||||
@@ -97,28 +98,41 @@
|
||||
function createMarkerLayers() {
|
||||
const markerArray = getMarkerArray()
|
||||
return markerArray?.map((m) => {
|
||||
const feature = new Feature({
|
||||
geometry: new Point([+m.lon, +m.lat]),
|
||||
name: m.title
|
||||
})
|
||||
|
||||
feature.setStyle(
|
||||
new Style({
|
||||
image: new Circle({
|
||||
radius: m.radius ?? 7,
|
||||
fill: new Fill({ color: m.color ?? '#dc2626' }),
|
||||
stroke: new Stroke({ width: m.strokeWidth ?? 3, color: m.strokeColor ?? '#fca5a5' })
|
||||
}),
|
||||
text: new Text({
|
||||
text: m.title,
|
||||
font: '12px Calibri,sans-serif',
|
||||
fill: new Fill({ color: '#000' }),
|
||||
stroke: new Stroke({
|
||||
color: '#fff',
|
||||
width: 2
|
||||
}),
|
||||
offsetY: -15
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
return new VectorLayer({
|
||||
properties: {
|
||||
name: LAYER_NAME.MARKER
|
||||
},
|
||||
source: new VectorSource({
|
||||
features: [
|
||||
new Feature({
|
||||
geometry: new Point([+m.lon, +m.lat]),
|
||||
name: m.title
|
||||
})
|
||||
]
|
||||
}),
|
||||
style: {
|
||||
'circle-radius': m.radius ?? 7,
|
||||
'circle-fill-color': m.color ?? '#dc2626',
|
||||
'circle-stroke-width': m.strokeWidth ?? 3,
|
||||
'circle-stroke-color': m.strokeColor ?? '#fca5a5'
|
||||
}
|
||||
features: [feature]
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function updateMarkers() {
|
||||
const layers = getLayersByName('MARKER')
|
||||
if (layers?.length) {
|
||||
@@ -143,8 +157,8 @@
|
||||
...(createMarkerLayers() || [])
|
||||
],
|
||||
view: new View({
|
||||
center: [longitude ?? 0, latitude ?? 0],
|
||||
zoom: zoom ?? 2
|
||||
center: [resolvedConfig.longitude ?? 0, resolvedConfig.latitude ?? 0],
|
||||
zoom: resolvedConfig.zoom ?? 2
|
||||
}),
|
||||
controls: defaultControls({
|
||||
attribution: false
|
||||
@@ -153,10 +167,28 @@
|
||||
updateRegionOutput()
|
||||
}
|
||||
|
||||
let previousLock: boolean | undefined = undefined
|
||||
|
||||
function updateInteractions(map: Map) {
|
||||
if (previousLock === resolvedConfig.lock) {
|
||||
return
|
||||
}
|
||||
|
||||
previousLock = resolvedConfig.lock
|
||||
|
||||
map.getInteractions().forEach((i) => {
|
||||
i.setActive(!resolvedConfig.lock)
|
||||
})
|
||||
|
||||
map.changed()
|
||||
}
|
||||
|
||||
$: map && resolvedConfig && updateInteractions(map)
|
||||
|
||||
let css = initCss($app.css?.mapcomponent, customCss)
|
||||
|
||||
function updateRegionOutput() {
|
||||
if (map) {
|
||||
if (map && !resolvedConfig.lock) {
|
||||
let extent = map.getView().calculateExtent(map.getSize())
|
||||
const [left, bottom, right, top] = extent
|
||||
|
||||
@@ -197,10 +229,16 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<InputValue key="longitude" {id} input={configuration.longitude} bind:value={longitude} />
|
||||
<InputValue key="latitude" {id} input={configuration.latitude} bind:value={latitude} />
|
||||
<InputValue key="zoom" {id} input={configuration.zoom} bind:value={zoom} />
|
||||
<InputValue key="markers" {id} input={configuration.markers} bind:value={markers} />
|
||||
{#each Object.entries(components['mapcomponent'].initialData.configuration) as [key, initialConfig] (key)}
|
||||
<ResolveConfig
|
||||
{id}
|
||||
{extraKey}
|
||||
{key}
|
||||
bind:resolvedConfig={resolvedConfig[key]}
|
||||
configuration={configuration[key]}
|
||||
{initialConfig}
|
||||
/>
|
||||
{/each}
|
||||
|
||||
<InitializeComponent {id} />
|
||||
|
||||
@@ -236,13 +274,3 @@
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style global lang="postcss">
|
||||
.ol-overlaycontainer-stopevent {
|
||||
@apply flex flex-col justify-start items-end;
|
||||
}
|
||||
.ol-control button {
|
||||
@apply w-7 h-7 center-center bg-surface border text-secondary
|
||||
rounded mt-1 mr-1 shadow duration-200 hover:bg-surface-hover focus:bg-surface-hover;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
export let initializing: boolean | undefined = undefined
|
||||
export let render: boolean
|
||||
export let customCss: ComponentCustomCSS<'aggridcomponent'> | undefined = undefined
|
||||
export let actions: TableAction[] = []
|
||||
export let actions: TableAction[] | undefined = undefined
|
||||
|
||||
const context = getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
|
||||
function actionRenderer(params) {
|
||||
const { rowIndex, data: row } = params
|
||||
if (rowIndex === -1) {
|
||||
if (rowIndex === -1 || actions == undefined || actions?.length == 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@
|
||||
: []
|
||||
|
||||
// Add the action column if actions are defined
|
||||
if (actions.length > 0) {
|
||||
if (actions && actions.length > 0) {
|
||||
columnDefs.push({
|
||||
headerName: 'Actions',
|
||||
cellRenderer: actionRenderer,
|
||||
@@ -385,7 +385,7 @@
|
||||
: []
|
||||
|
||||
// Add the action column if actions are defined
|
||||
if (actions.length > 0) {
|
||||
if (actions && actions.length > 0) {
|
||||
columnDefs.push({
|
||||
headerName: 'Actions',
|
||||
cellRenderer: actionRenderer,
|
||||
|
||||
@@ -184,7 +184,10 @@
|
||||
if (c.type === 'tablecomponent') {
|
||||
r.push(...c.actionButtons.map((x) => ({ input: x.componentInput, id: x.id })))
|
||||
}
|
||||
if (c.type === 'aggridcomponent' || c.type === 'aggridcomponentee') {
|
||||
if (
|
||||
(c.type === 'aggridcomponent' || c.type === 'aggridcomponentee') &&
|
||||
Array.isArray(c.actions)
|
||||
) {
|
||||
r.push(...c.actions.map((x) => ({ input: x.componentInput, id: x.id })))
|
||||
}
|
||||
if (c.type === 'menucomponent') {
|
||||
|
||||
@@ -33,9 +33,11 @@
|
||||
<div>
|
||||
<AppComponentInput bind:component={gridItem.data} {resourceOnly} />
|
||||
<div class="ml-4 mt-4">
|
||||
{#each gridItem.data.actions as actionButton (actionButton.id)}
|
||||
<AppComponentInput bind:component={actionButton.data} {resourceOnly} />
|
||||
{/each}
|
||||
{#if Array.isArray(gridItem.data.actions)}
|
||||
{#each gridItem.data.actions as actionButton (actionButton.id)}
|
||||
<AppComponentInput bind:component={actionButton.data} {resourceOnly} />
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
|
||||
@@ -89,7 +89,10 @@
|
||||
)
|
||||
}
|
||||
|
||||
if (parent.data.type === 'aggridcomponent' || parent.data.type === 'aggridcomponentee') {
|
||||
if (
|
||||
(parent.data.type === 'aggridcomponent' || parent.data.type === 'aggridcomponentee') &&
|
||||
Array.isArray(parent.data.actions)
|
||||
) {
|
||||
parent.data.actions = parent.data.actions.filter(
|
||||
(x) => x.id !== tableActionSettings?.item.id
|
||||
)
|
||||
|
||||
@@ -74,7 +74,7 @@ export function dfs(
|
||||
return [item.id, id]
|
||||
} else if (
|
||||
(item.data.type == 'aggridcomponent' || item.data.type == 'aggridcomponentee') &&
|
||||
item.data.actions.find((x) => id == x.id)
|
||||
item.data.actions?.find((x) => id == x.id)
|
||||
) {
|
||||
return [item.id, id]
|
||||
} else {
|
||||
@@ -170,7 +170,10 @@ export function allsubIds(app: App, parentId: string): string[] {
|
||||
if (item.data.type === 'tablecomponent') {
|
||||
subIds.push(...item.data.actionButtons?.map((x) => x.id))
|
||||
}
|
||||
if (item.data.type === 'aggridcomponent' || item.data.type === 'aggridcomponentee') {
|
||||
if (
|
||||
item.data.type === 'aggridcomponent' ||
|
||||
(item.data.type === 'aggridcomponentee' && Array.isArray(item.data.actions))
|
||||
) {
|
||||
subIds.push(...item.data.actions?.map((x) => x.id))
|
||||
}
|
||||
if (item.data.type === 'menucomponent') {
|
||||
@@ -514,7 +517,10 @@ export function getAllGridItems(app: App): GridItem[] {
|
||||
.map((x) => {
|
||||
if (x?.data?.type === 'tablecomponent') {
|
||||
return [x, ...x?.data?.actionButtons?.map((x) => ({ data: x, id: x.id }))]
|
||||
} else if (x?.data?.type === 'aggridcomponent' || x?.data?.type === 'aggridcomponentee') {
|
||||
} else if (
|
||||
(x?.data?.type === 'aggridcomponent' || x?.data?.type === 'aggridcomponentee') &&
|
||||
Array.isArray(x?.data?.actions)
|
||||
) {
|
||||
return [x, ...x?.data?.actions?.map((x) => ({ data: x, id: x.id }))]
|
||||
} else if (x?.data?.type === 'menucomponent') {
|
||||
return [x, ...x?.data?.menuItems?.map((x) => ({ data: x, id: x.id }))]
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
bind:initializing
|
||||
componentInput={component.componentInput}
|
||||
customCss={component.customCss}
|
||||
actions={component.actions}
|
||||
actions={component.actions ?? []}
|
||||
{render}
|
||||
/>
|
||||
{:else if component.type === 'aggridcomponentee'}
|
||||
@@ -362,7 +362,7 @@
|
||||
bind:initializing
|
||||
componentInput={component.componentInput}
|
||||
customCss={component.customCss}
|
||||
actions={component.actions}
|
||||
actions={component.actions ?? []}
|
||||
{render}
|
||||
/>
|
||||
{:else if component.type === 'textcomponent'}
|
||||
|
||||
@@ -2858,7 +2858,13 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
|
||||
title: 'London'
|
||||
}
|
||||
]
|
||||
} as StaticAppInput
|
||||
} as StaticAppInput,
|
||||
lock: {
|
||||
fieldType: 'boolean',
|
||||
type: 'static',
|
||||
value: false,
|
||||
tooltip: 'Lock the map to prevent user interaction'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if (gridItem.data.type === 'aggridcomponent' || gridItem.data.type === 'aggridcomponentee') && gridItem.data.actions.length > 0}
|
||||
{#if (gridItem.data.type === 'aggridcomponent' || gridItem.data.type === 'aggridcomponentee') && gridItem.data.actions?.length > 0}
|
||||
<div class="ml-2 border-l">
|
||||
{#each gridItem.data.actions as action, index}
|
||||
<Output id={action.id} first={index === 0} label="Table action" />
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
{/each}
|
||||
{/if}
|
||||
|
||||
{#if gridItem?.data?.type === 'aggridcomponent' || gridItem?.data?.type === 'aggridcomponentee'}
|
||||
{#if (gridItem?.data?.type === 'aggridcomponent' || gridItem?.data?.type === 'aggridcomponentee') && Array.isArray(gridItem.data.actions)}
|
||||
{#each gridItem.data.actions as actionButton, index (index)}
|
||||
{#if actionButton?.id === $selectedComponentInEditor || actionButton?.id + '_transformer' === $selectedComponentInEditor}
|
||||
<InlineScriptEditorPanel
|
||||
|
||||
@@ -67,7 +67,7 @@ function processGridItemRunnable(gridItem: GridItem, list: AppScriptsList): AppS
|
||||
}
|
||||
|
||||
if (component.type === 'aggridcomponent' || component.type === 'aggridcomponentee') {
|
||||
component.actions.forEach((actionButton) => {
|
||||
component.actions?.forEach((actionButton) => {
|
||||
if (actionButton.componentInput?.type !== 'runnable') {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@
|
||||
bind:panes={componentSettings.item.data.panes}
|
||||
bind:component={componentSettings.item.data}
|
||||
/>
|
||||
{:else if componentSettings.item.data.type === 'aggridcomponent' && Array.isArray(componentSettings.item.data.actions)}
|
||||
{:else if componentSettings.item.data.type === 'aggridcomponent'}
|
||||
<TableActions id={component.id} bind:components={componentSettings.item.data.actions} />
|
||||
{:else if componentSettings.item.data.type === 'tablecomponent' && Array.isArray(componentSettings.item.data.actionButtons)}
|
||||
<TableActions id={component.id} bind:components={componentSettings.item.data.actionButtons} />
|
||||
|
||||
@@ -3,21 +3,34 @@
|
||||
import Button from '$lib/components/common/button/Button.svelte'
|
||||
import { getNextId } from '$lib/components/flows/idUtils'
|
||||
import { classNames } from '$lib/utils'
|
||||
import { getContext } from 'svelte'
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import type { AppViewerContext, BaseAppComponent } from '../../types'
|
||||
import { appComponentFromType } from '../appUtils'
|
||||
import type { ButtonComponent, CheckboxComponent, SelectComponent } from '../component'
|
||||
import PanelSection from './common/PanelSection.svelte'
|
||||
import { Inspect, List, ToggleRightIcon, Trash } from 'lucide-svelte'
|
||||
|
||||
export let components: (BaseAppComponent &
|
||||
(ButtonComponent | CheckboxComponent | SelectComponent))[]
|
||||
export let components:
|
||||
| (BaseAppComponent & (ButtonComponent | CheckboxComponent | SelectComponent))[]
|
||||
| undefined
|
||||
|
||||
// Migration code:
|
||||
onMount(() => {
|
||||
if (components === undefined) {
|
||||
components = []
|
||||
}
|
||||
})
|
||||
|
||||
export let id: string
|
||||
|
||||
const { selectedComponent, app, errorByComponent } =
|
||||
getContext<AppViewerContext>('AppViewerContext')
|
||||
|
||||
function addComponent(typ: 'buttoncomponent' | 'checkboxcomponent' | 'selectcomponent') {
|
||||
if (!components) {
|
||||
return
|
||||
}
|
||||
|
||||
const actionId = getNextId(components.map((x) => x.id.split('_')[1]))
|
||||
|
||||
const newComponent = {
|
||||
@@ -29,6 +42,9 @@
|
||||
}
|
||||
|
||||
function deleteComponent(cid: string) {
|
||||
if (!components) {
|
||||
return
|
||||
}
|
||||
components = components.filter((x) => x.id !== cid)
|
||||
|
||||
delete $errorByComponent[cid]
|
||||
@@ -38,77 +54,79 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<PanelSection title={`Table Actions`}>
|
||||
{#if components.length == 0}
|
||||
<span class="text-xs text-tertiary">No action buttons</span>
|
||||
{/if}
|
||||
{#each components as component}
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
class={classNames(
|
||||
'w-full text-xs font-bold gap-1 truncate py-1.5 px-2 cursor-pointer transition-all justify-between flex items-center border border-gray-3 rounded-md',
|
||||
'bg-surface hover:bg-surface-hover focus:border-primary text-secondary',
|
||||
$selectedComponent?.includes(component.id) ? 'outline outline-blue-500 bg-red-400' : ''
|
||||
)}
|
||||
on:click={() => {
|
||||
$selectedComponent = [component.id]
|
||||
}}
|
||||
on:keypress
|
||||
>
|
||||
<Badge color="dark-indigo">
|
||||
{component.id}
|
||||
</Badge>
|
||||
{#if components}
|
||||
<PanelSection title={`Table Actions`}>
|
||||
{#if components.length == 0}
|
||||
<span class="text-xs text-tertiary">No action buttons</span>
|
||||
{/if}
|
||||
{#each components as component}
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div
|
||||
class={classNames(
|
||||
'w-full text-xs font-bold gap-1 truncate py-1.5 px-2 cursor-pointer transition-all justify-between flex items-center border border-gray-3 rounded-md',
|
||||
'bg-surface hover:bg-surface-hover focus:border-primary text-secondary',
|
||||
$selectedComponent?.includes(component.id) ? 'outline outline-blue-500 bg-red-400' : ''
|
||||
)}
|
||||
on:click={() => {
|
||||
$selectedComponent = [component.id]
|
||||
}}
|
||||
on:keypress
|
||||
>
|
||||
<Badge color="dark-indigo">
|
||||
{component.id}
|
||||
</Badge>
|
||||
|
||||
<div>
|
||||
{#if component.type == 'buttoncomponent'}
|
||||
Button
|
||||
{:else if component.type == 'selectcomponent'}
|
||||
Select
|
||||
{:else if component.type == 'checkboxcomponent'}
|
||||
Toggle
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="border"
|
||||
color="red"
|
||||
on:click={() => deleteComponent(component.id)}
|
||||
startIcon={{ icon: Trash }}
|
||||
iconOnly
|
||||
/>
|
||||
<div>
|
||||
{#if component.type == 'buttoncomponent'}
|
||||
Button
|
||||
{:else if component.type == 'selectcomponent'}
|
||||
Select
|
||||
{:else if component.type == 'checkboxcomponent'}
|
||||
Toggle
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="border"
|
||||
color="red"
|
||||
on:click={() => deleteComponent(component.id)}
|
||||
startIcon={{ icon: Trash }}
|
||||
iconOnly
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="w-full flex gap-2">
|
||||
<Button
|
||||
btnClasses="gap-1 flex items-center text-sm text-tertiary"
|
||||
wrapperClasses="w-full"
|
||||
color="light"
|
||||
variant="border"
|
||||
on:click={() => addComponent('buttoncomponent')}
|
||||
title="Add Button"
|
||||
>
|
||||
+ <Inspect size={14} />
|
||||
</Button>
|
||||
<Button
|
||||
btnClasses="gap-1 flex items-center text-sm text-tertiary"
|
||||
wrapperClasses="w-full"
|
||||
color="light"
|
||||
variant="border"
|
||||
on:click={() => addComponent('checkboxcomponent')}
|
||||
title="Add Toggle"
|
||||
>
|
||||
+ <ToggleRightIcon size={14} />
|
||||
</Button>
|
||||
<Button
|
||||
btnClasses="gap-1 flex items-center text-sm text-tertiary"
|
||||
wrapperClasses="w-full"
|
||||
color="light"
|
||||
variant="border"
|
||||
on:click={() => addComponent('selectcomponent')}
|
||||
title="Add Select"
|
||||
>
|
||||
+ <List size={14} />
|
||||
</Button>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="w-full flex gap-2">
|
||||
<Button
|
||||
btnClasses="gap-1 flex items-center text-sm text-tertiary"
|
||||
wrapperClasses="w-full"
|
||||
color="light"
|
||||
variant="border"
|
||||
on:click={() => addComponent('buttoncomponent')}
|
||||
title="Add Button"
|
||||
>
|
||||
+ <Inspect size={14} />
|
||||
</Button>
|
||||
<Button
|
||||
btnClasses="gap-1 flex items-center text-sm text-tertiary"
|
||||
wrapperClasses="w-full"
|
||||
color="light"
|
||||
variant="border"
|
||||
on:click={() => addComponent('checkboxcomponent')}
|
||||
title="Add Toggle"
|
||||
>
|
||||
+ <ToggleRightIcon size={14} />
|
||||
</Button>
|
||||
<Button
|
||||
btnClasses="gap-1 flex items-center text-sm text-tertiary"
|
||||
wrapperClasses="w-full"
|
||||
color="light"
|
||||
variant="border"
|
||||
on:click={() => addComponent('selectcomponent')}
|
||||
title="Add Select"
|
||||
>
|
||||
+ <List size={14} />
|
||||
</Button>
|
||||
</div>
|
||||
</PanelSection>
|
||||
</PanelSection>
|
||||
{/if}
|
||||
|
||||
@@ -292,7 +292,7 @@ export function getAllScriptNames(app: App): string[] {
|
||||
}
|
||||
|
||||
if (gridItem.data.type === 'aggridcomponent' || gridItem.data.type === 'aggridcomponentee') {
|
||||
gridItem.data.actions.forEach((actionButton) => {
|
||||
gridItem.data.actions?.forEach((actionButton) => {
|
||||
if (actionButton.componentInput?.type === 'runnable') {
|
||||
if (actionButton.componentInput.runnable?.type === 'runnableByName') {
|
||||
acc.push(actionButton.componentInput.runnable.name)
|
||||
|
||||
@@ -4,8 +4,8 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
wmill = ">=1.305.3"
|
||||
wmill_pg = ">=1.305.3"
|
||||
wmill = ">=1.306.0"
|
||||
wmill_pg = ">=1.306.0"
|
||||
sendgrid = "*"
|
||||
mysql-connector-python = "*"
|
||||
pymongo = "*"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.305.3
|
||||
version: 1.306.0
|
||||
title: OpenFlow Spec
|
||||
contact:
|
||||
name: Ruben Fiszel
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
description = "A client library for accessing Windmill server wrapping the Windmill client API"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill-pg"
|
||||
version = "1.305.3"
|
||||
version = "1.306.0"
|
||||
description = "An extension client for the wmill client library focused on pg"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "windmill-client",
|
||||
"description": "Windmill SDK client for browsers and Node.js",
|
||||
"version": "1.305.3",
|
||||
"version": "1.306.0",
|
||||
"author": "Ruben Fiszel",
|
||||
"license": "Apache 2.0",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.305.3
|
||||
1.306.0
|
||||
|
||||
Reference in New Issue
Block a user