mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-04 16:03:06 +00:00
Merge remote-tracking branch 'upstream/main' into appeditor-multiselect-input-type
This commit is contained in:
@@ -1,5 +1,23 @@
|
||||
# Changelog
|
||||
|
||||
## [1.419.0](https://github.com/windmill-labs/windmill/compare/v1.418.0...v1.419.0) (2024-11-06)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add full-text search on windmill service logs ([#4576](https://github.com/windmill-labs/windmill/issues/4576)) ([77735d8](https://github.com/windmill-labs/windmill/commit/77735d859cfee9204f67a8e4f9885228d657a41d))
|
||||
* show path in flow script picker ([#4574](https://github.com/windmill-labs/windmill/issues/4574)) ([8e27392](https://github.com/windmill-labs/windmill/commit/8e27392afacbb725aaf9f9f892ab8a6171b59ce5))
|
||||
* websocket authentication ([#4635](https://github.com/windmill-labs/windmill/issues/4635)) ([4dda0fb](https://github.com/windmill-labs/windmill/commit/4dda0fb8cd8262ad3a2ab2b9d27e7043ac3bb891))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* clarify error messages when job timeout or cancelled with more details ([771d740](https://github.com/windmill-labs/windmill/commit/771d740701902166f8b4e3f77aa9c5579237cb15))
|
||||
* **cli:** improve handling of deleted items on windows ([9a8dcc9](https://github.com/windmill-labs/windmill/commit/9a8dcc9a250caefa0b7c9523e1321599b7471c8b))
|
||||
* display logs in native mode when script fails ([#4655](https://github.com/windmill-labs/windmill/issues/4655)) ([7578ceb](https://github.com/windmill-labs/windmill/commit/7578cebaf92e729a26fd665e4b6f8357d34f59eb))
|
||||
* **frontend:** arg input json handling when the value is not of the same type as schema ([#4479](https://github.com/windmill-labs/windmill/issues/4479)) ([8d8156b](https://github.com/windmill-labs/windmill/commit/8d8156bd0773da3ddec81c46ad5fda114ecd3dda))
|
||||
* **frontend:** improve flow prop picker design ([323912c](https://github.com/windmill-labs/windmill/commit/323912c73c18d3bb6d136f2e6458389270364a0e))
|
||||
|
||||
## [1.418.0](https://github.com/windmill-labs/windmill/compare/v1.417.3...v1.418.0) (2024-11-04)
|
||||
|
||||
|
||||
|
||||
Generated
+41
-41
@@ -166,9 +166,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.92"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13"
|
||||
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
@@ -966,9 +966,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-runtime-api"
|
||||
version = "1.7.2"
|
||||
version = "1.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e086682a53d3aa241192aa110fa8dfce98f2f5ac2ead0de84d41582c7e8fdb96"
|
||||
checksum = "92165296a47a812b267b4f41032ff8069ab7ff783696d217f0994a0d7ab585cd"
|
||||
dependencies = [
|
||||
"aws-smithy-async",
|
||||
"aws-smithy-types",
|
||||
@@ -983,9 +983,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aws-smithy-types"
|
||||
version = "1.2.8"
|
||||
version = "1.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07c9cdc179e6afbf5d391ab08c85eac817b51c87e1892a5edb5f7bbdc64314b4"
|
||||
checksum = "4fbd94a32b3a7d55d3806fe27d98d3ad393050439dd05eb53ece36ec5e3d3510"
|
||||
dependencies = [
|
||||
"base64-simd 0.8.0",
|
||||
"bytes",
|
||||
@@ -1599,9 +1599,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.34"
|
||||
version = "1.1.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9"
|
||||
checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
@@ -2554,7 +2554,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"sourcemap 9.0.0",
|
||||
"sourcemap 9.0.1",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
"swc_config",
|
||||
@@ -6537,9 +6537,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.5.6"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e346e016eacfff12233c243718197ca12f148c84e1e84268a896699b41c71780"
|
||||
checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da"
|
||||
dependencies = [
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
@@ -7173,9 +7173,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.38"
|
||||
version = "0.38.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a"
|
||||
checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"errno",
|
||||
@@ -8016,9 +8016,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sourcemap"
|
||||
version = "9.0.0"
|
||||
version = "9.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dab08a862c70980b8e23698b507e272317ae52a608a164a844111f5372374f1f"
|
||||
checksum = "86721155737d89818020dc35713595c6e7b21016073c101e6590c47ca58c2d16"
|
||||
dependencies = [
|
||||
"base64-simd 0.7.0",
|
||||
"bitvec",
|
||||
@@ -8506,7 +8506,7 @@ dependencies = [
|
||||
"rustc-hash 1.1.0",
|
||||
"serde",
|
||||
"siphasher",
|
||||
"sourcemap 9.0.0",
|
||||
"sourcemap 9.0.1",
|
||||
"swc_allocator",
|
||||
"swc_atoms",
|
||||
"swc_eq_ignore_macros",
|
||||
@@ -8570,7 +8570,7 @@ dependencies = [
|
||||
"num-bigint",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"sourcemap 9.0.0",
|
||||
"sourcemap 9.0.1",
|
||||
"swc_allocator",
|
||||
"swc_atoms",
|
||||
"swc_common",
|
||||
@@ -10563,7 +10563,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windmill"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
@@ -10605,7 +10605,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argon2",
|
||||
@@ -10690,7 +10690,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-api-client"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
@@ -10708,7 +10708,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-audit"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
@@ -10721,7 +10721,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-autoscaling"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"rsmq_async",
|
||||
@@ -10736,7 +10736,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-common"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@@ -10782,7 +10782,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-git-sync"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"rsmq_async",
|
||||
@@ -10797,7 +10797,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-indexer"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -10819,7 +10819,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-macros"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"itertools 0.13.0",
|
||||
"lazy_static",
|
||||
@@ -10831,7 +10831,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"serde",
|
||||
@@ -10840,7 +10840,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-bash"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -10852,7 +10852,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-go"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"gosyn",
|
||||
@@ -10864,7 +10864,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-graphql"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -10876,7 +10876,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-php"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.13.0",
|
||||
@@ -10887,7 +10887,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools 0.13.0",
|
||||
@@ -10898,7 +10898,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-py-imports"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -10916,7 +10916,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-rust"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"convert_case 0.6.0",
|
||||
@@ -10933,7 +10933,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-sql"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -10945,7 +10945,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-ts"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"lazy_static",
|
||||
@@ -10963,7 +10963,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-wasm"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"getrandom 0.2.15",
|
||||
@@ -10984,7 +10984,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-parser-yaml"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"serde_json",
|
||||
@@ -10994,7 +10994,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-queue"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
@@ -11027,7 +11027,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-sql-datatype-parser-wasm"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
@@ -11037,7 +11037,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windmill-worker"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "windmill"
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
@@ -29,7 +29,7 @@ members = [
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "1.418.0"
|
||||
version = "1.419.0"
|
||||
authors = ["Ruben Fiszel <ruben@windmill.dev>"]
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.418.0
|
||||
version: 1.419.0
|
||||
title: Windmill API
|
||||
|
||||
contact:
|
||||
|
||||
@@ -562,7 +562,7 @@ pub async fn resolve_job_timeout(
|
||||
_w_id: &str,
|
||||
_job_id: Uuid,
|
||||
custom_timeout_secs: Option<i32>,
|
||||
) -> (Duration, Option<String>) {
|
||||
) -> (Duration, Option<String>, bool) {
|
||||
let mut warn_msg: Option<String> = None;
|
||||
#[cfg(feature = "cloud")]
|
||||
let cloud_premium_workspace = *CLOUD_HOSTED
|
||||
@@ -587,12 +587,12 @@ pub async fn resolve_job_timeout(
|
||||
Some(timeout_secs)
|
||||
if Duration::from_secs(timeout_secs as u64) < global_max_timeout_duration =>
|
||||
{
|
||||
(Duration::from_secs(timeout_secs as u64), warn_msg)
|
||||
(Duration::from_secs(timeout_secs as u64), warn_msg, true)
|
||||
}
|
||||
Some(timeout_secs) => {
|
||||
warn_msg = Some(format!("WARNING: Custom job timeout of {timeout_secs} seconds was greater than the maximum timeout. It will be ignored and the max timeout will be used instead"));
|
||||
tracing::warn!(warn_msg);
|
||||
(global_max_timeout_duration, warn_msg)
|
||||
(global_max_timeout_duration, warn_msg, false)
|
||||
}
|
||||
None => {
|
||||
// fallback to default timeout or max if not set
|
||||
@@ -610,7 +610,7 @@ pub async fn resolve_job_timeout(
|
||||
global_max_timeout_duration
|
||||
}
|
||||
};
|
||||
(default_timeout, warn_msg)
|
||||
(default_timeout, warn_msg, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,15 +143,40 @@ pub async fn handle_child(
|
||||
occupancy_metrics,
|
||||
);
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum KillReason {
|
||||
TooManyLogs,
|
||||
Timeout,
|
||||
Cancelled,
|
||||
Timeout { is_job_specific: bool },
|
||||
Cancelled(Option<CanceledBy>),
|
||||
AlreadyCompleted,
|
||||
}
|
||||
|
||||
let (timeout_duration, timeout_warn_msg) =
|
||||
impl std::fmt::Debug for KillReason {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
KillReason::TooManyLogs => f.write_str("too many logs (max size: 2MB)"),
|
||||
KillReason::Timeout { is_job_specific } => f.write_str(if *is_job_specific {
|
||||
"timeout after exceeding job-specific duration limit"
|
||||
} else {
|
||||
"timeout after exceeding instance-wide job duration limit"
|
||||
}),
|
||||
KillReason::Cancelled(canceled_by) => {
|
||||
let mut reason = "cancelled".to_string();
|
||||
if let Some(canceled_by) = canceled_by {
|
||||
if let Some(by) = canceled_by.username.as_ref() {
|
||||
reason.push_str(&format!(" by {}", by));
|
||||
}
|
||||
if let Some(rsn) = canceled_by.reason.as_ref() {
|
||||
reason.push_str(&format!(" (reason: {})", rsn));
|
||||
}
|
||||
}
|
||||
f.write_str(&reason)
|
||||
}
|
||||
KillReason::AlreadyCompleted => f.write_str("already completed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let (timeout_duration, timeout_warn_msg, is_job_specific) =
|
||||
resolve_job_timeout(&db, w_id, job_id, custom_timeout).await;
|
||||
if let Some(msg) = timeout_warn_msg {
|
||||
append_logs(&job_id, w_id, msg.as_str(), db).await;
|
||||
@@ -165,9 +190,9 @@ pub async fn handle_child(
|
||||
biased;
|
||||
result = child.wait() => return result.map(Ok),
|
||||
Ok(()) = too_many_logs.changed() => KillReason::TooManyLogs,
|
||||
_ = sleep(timeout_duration) => KillReason::Timeout,
|
||||
_ = sleep(timeout_duration) => KillReason::Timeout { is_job_specific },
|
||||
ex = update_job, if job_id != Uuid::nil() => match ex {
|
||||
UpdateJobPollingExit::Done => KillReason::Cancelled,
|
||||
UpdateJobPollingExit::Done(canceled_by) => KillReason::Cancelled(canceled_by),
|
||||
UpdateJobPollingExit::AlreadyCompleted => KillReason::AlreadyCompleted,
|
||||
},
|
||||
};
|
||||
@@ -175,7 +200,7 @@ pub async fn handle_child(
|
||||
drop(tx);
|
||||
|
||||
let set_reason = async {
|
||||
if kill_reason == KillReason::Timeout {
|
||||
if matches!(kill_reason, KillReason::Timeout { .. }) {
|
||||
if let Err(err) = sqlx::query(
|
||||
r#"
|
||||
UPDATE queue
|
||||
@@ -402,7 +427,7 @@ pub async fn handle_child(
|
||||
Err(Error::AlreadyCompleted("Job already completed".to_string()))
|
||||
}
|
||||
_ => Err(Error::ExecutionErr(format!(
|
||||
"job process killed because {kill_reason:#?}"
|
||||
"job process terminated due to {kill_reason:#?}"
|
||||
))),
|
||||
},
|
||||
Err(err) => Err(Error::ExecutionErr(format!("job process io error: {err}"))),
|
||||
@@ -505,7 +530,10 @@ where
|
||||
})?,
|
||||
ex = update_job, if job_id != Uuid::nil() => {
|
||||
match ex {
|
||||
UpdateJobPollingExit::Done => Err(Error::ExecutionErr("Job cancelled".to_string())).map_err(to_anyhow)?,
|
||||
UpdateJobPollingExit::Done(canceled_by) => {
|
||||
let (by, reason) = canceled_by.as_ref().map_or(("unknown".to_string(), "unknown".to_string()), |x| (x.username.clone().unwrap_or("".to_string()), x.reason.clone().unwrap_or("".to_string())));
|
||||
Err(Error::ExecutionErr(format!("Job cancelled by {by} (reason: {reason})",))).map_err(to_anyhow)?
|
||||
},
|
||||
UpdateJobPollingExit::AlreadyCompleted => Err(Error::AlreadyCompleted("Job already completed".to_string())).map_err(to_anyhow)?,
|
||||
}
|
||||
}
|
||||
@@ -515,7 +543,7 @@ where
|
||||
}
|
||||
|
||||
pub enum UpdateJobPollingExit {
|
||||
Done,
|
||||
Done(Option<CanceledBy>),
|
||||
AlreadyCompleted,
|
||||
}
|
||||
|
||||
@@ -640,7 +668,7 @@ where
|
||||
}
|
||||
tracing::info!("job {job_id} finished");
|
||||
|
||||
UpdateJobPollingExit::Done
|
||||
UpdateJobPollingExit::Done(canceled_by_ref.clone())
|
||||
}
|
||||
|
||||
/// takes stdout and stderr from Child, panics if either are not present
|
||||
|
||||
+1
-1
@@ -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.418.0";
|
||||
export const VERSION = "v1.419.0";
|
||||
|
||||
export async function login(email: string, password: string): Promise<string> {
|
||||
return await windmill.UserService.login({
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ export {
|
||||
// }
|
||||
// });
|
||||
|
||||
export const VERSION = "1.418.0";
|
||||
export const VERSION = "1.419.0";
|
||||
|
||||
const command = new Command()
|
||||
.name("wmill")
|
||||
|
||||
+8
-7
@@ -1398,11 +1398,12 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
log.info(`Deleting ${typ} ${change.path}`);
|
||||
}
|
||||
const workspaceId = workspace.workspaceId;
|
||||
const target = change.path.replaceAll(SEP, "/");
|
||||
switch (typ) {
|
||||
case "script": {
|
||||
const script = await wmill.getScriptByPath({
|
||||
workspace: workspaceId,
|
||||
path: removeExtensionToPath(change.path),
|
||||
path: removeExtensionToPath(target),
|
||||
});
|
||||
await wmill.archiveScriptByHash({
|
||||
workspace: workspaceId,
|
||||
@@ -1419,37 +1420,37 @@ export async function push(opts: GlobalOptions & SyncOptions) {
|
||||
case "resource":
|
||||
await wmill.deleteResource({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(change.path, ".resource.json"),
|
||||
path: removeSuffix(target, ".resource.json"),
|
||||
});
|
||||
break;
|
||||
case "resource-type":
|
||||
await wmill.deleteResourceType({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(change.path, ".resource-type.json"),
|
||||
path: removeSuffix(target, ".resource-type.json"),
|
||||
});
|
||||
break;
|
||||
case "flow":
|
||||
await wmill.deleteFlowByPath({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(change.path, ".flow/flow.json"),
|
||||
path: removeSuffix(target, ".flow/flow.json"),
|
||||
});
|
||||
break;
|
||||
case "app":
|
||||
await wmill.deleteApp({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(change.path, ".app/app.json"),
|
||||
path: removeSuffix(target, ".app/app.json"),
|
||||
});
|
||||
break;
|
||||
case "schedule":
|
||||
await wmill.deleteSchedule({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(change.path, ".schedule.json"),
|
||||
path: removeSuffix(target, ".schedule.json"),
|
||||
});
|
||||
break;
|
||||
case "variable":
|
||||
await wmill.deleteVariable({
|
||||
workspace: workspaceId,
|
||||
path: removeSuffix(change.path, ".variable.json"),
|
||||
path: removeSuffix(target, ".variable.json"),
|
||||
});
|
||||
break;
|
||||
case "user": {
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.418.0",
|
||||
"version": "1.419.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "windmill-components",
|
||||
"version": "1.418.0",
|
||||
"version": "1.419.0",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@aws-crypto/sha256-js": "^4.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windmill-components",
|
||||
"version": "1.418.0",
|
||||
"version": "1.419.0",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
<script context="module">
|
||||
const dynamicTemplateRegexPairs = buildPrefixRegex([
|
||||
'flow_input',
|
||||
'results',
|
||||
'resource',
|
||||
'variable'
|
||||
])
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { Schema } from '$lib/common'
|
||||
import type { InputCat } from '$lib/utils'
|
||||
@@ -13,8 +22,9 @@
|
||||
import AnimatedButton from '$lib/components/common/button/AnimatedButton.svelte'
|
||||
import ToggleButtonGroup from '$lib/components/common/toggleButton-v2/ToggleButtonGroup.svelte'
|
||||
import ToggleButton from '$lib/components/common/toggleButton-v2/ToggleButton.svelte'
|
||||
import { tick } from 'svelte'
|
||||
import { fade } from 'svelte/transition'
|
||||
|
||||
import { buildPrefixRegex } from './flows/previousResults'
|
||||
import type VariableEditor from './VariableEditor.svelte'
|
||||
import type ItemPicker from './ItemPicker.svelte'
|
||||
import type { InputTransform } from '$lib/gen'
|
||||
@@ -43,6 +53,7 @@
|
||||
let monaco: SimpleEditor | undefined = undefined
|
||||
let monacoTemplate: TemplateEditor | undefined = undefined
|
||||
let argInput: ArgInput | undefined = undefined
|
||||
let focusedPrev = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
@@ -59,6 +70,9 @@
|
||||
const { shouldUpdatePropertyType, exprsToSet } =
|
||||
getContext<FlowCopilotContext | undefined>('FlowCopilotContext') || {}
|
||||
|
||||
const { inputMatches, focusProp, propPickerConfig } =
|
||||
getContext<PropPickerWrapperContext>('PropPickerWrapper')
|
||||
|
||||
function setExpr() {
|
||||
const newArg = $exprsToSet?.[argName]
|
||||
if (newArg) {
|
||||
@@ -133,6 +147,50 @@
|
||||
}
|
||||
}
|
||||
|
||||
let codeInjectionDetected = false
|
||||
|
||||
function checkCodeInjection(rawValue: string) {
|
||||
if (!arg || !rawValue || rawValue.length < 3 || !dynamicTemplateRegexPairs) {
|
||||
return undefined
|
||||
}
|
||||
if (rawValue.trim() !== rawValue) {
|
||||
return undefined
|
||||
}
|
||||
const matches = dynamicTemplateRegexPairs.filter(({ regex }) => regex.test(rawValue))
|
||||
if (matches.length > 0) {
|
||||
return matches.map((m) => ({ word: m.word, value: rawValue }))
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
async function setJavaScriptExpr(rawValue: string) {
|
||||
arg = {
|
||||
type: 'javascript',
|
||||
expr: rawValue
|
||||
}
|
||||
propertyType = 'javascript'
|
||||
monaco?.setCode('')
|
||||
monaco?.insertAtCursor(rawValue)
|
||||
await tick()
|
||||
monaco?.focus()
|
||||
await tick()
|
||||
monaco?.setCursorToEnd()
|
||||
}
|
||||
|
||||
function handleKeyUp(e: KeyboardEvent) {
|
||||
if (
|
||||
e.key === 'Tab' &&
|
||||
isStaticTemplate(inputCat) &&
|
||||
propertyType == 'static' &&
|
||||
!noDynamicToggle &&
|
||||
codeInjectionDetected
|
||||
) {
|
||||
setJavaScriptExpr(arg.value)
|
||||
} else {
|
||||
stepInputGen?.onKeyUp?.(e)
|
||||
}
|
||||
}
|
||||
|
||||
function isStaticTemplate(inputCat: InputCat) {
|
||||
return inputCat === 'string' || inputCat === 'sql' || inputCat == 'yaml'
|
||||
}
|
||||
@@ -166,9 +224,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
const { focusProp, propPickerConfig } = getContext<PropPickerWrapperContext>('PropPickerWrapper')
|
||||
$: updateStaticInput(inputCat, propertyType, arg)
|
||||
|
||||
$: isStaticTemplate(inputCat) && propertyType == 'static' && setPropertyType(arg?.value)
|
||||
function updateStaticInput(
|
||||
inputCat: InputCat,
|
||||
propertyType: 'static' | 'javascript',
|
||||
arg: InputTransform | any
|
||||
) {
|
||||
if (!isStaticTemplate(inputCat)) {
|
||||
return
|
||||
}
|
||||
if (propertyType == 'static') {
|
||||
setPropertyType(arg?.value)
|
||||
codeInjectionDetected = checkCodeInjection(arg?.value) != undefined
|
||||
} else if (propertyType == 'javascript' && focused) {
|
||||
setPropertyType(arg?.expr)
|
||||
$inputMatches = checkCodeInjection(arg?.expr)
|
||||
}
|
||||
}
|
||||
|
||||
function setDefaultCode() {
|
||||
if (!arg?.value) {
|
||||
@@ -176,6 +249,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
function updateFocused(newFocused: boolean) {
|
||||
if (focusedPrev && !newFocused) {
|
||||
$inputMatches = undefined
|
||||
}
|
||||
focusedPrev = focused
|
||||
}
|
||||
$: updateFocused(focused)
|
||||
|
||||
$: schema?.properties?.[argName].default && setDefaultCode()
|
||||
|
||||
let resourceTypes: string[] | undefined = undefined
|
||||
@@ -325,13 +406,27 @@
|
||||
<ToggleButton small label="Static" value="static" />
|
||||
{/if}
|
||||
|
||||
<ToggleButton
|
||||
small
|
||||
light
|
||||
tooltip="JavaScript expression ('flow_input' or 'results')."
|
||||
value="javascript"
|
||||
icon={FunctionSquare}
|
||||
/>
|
||||
{#if codeInjectionDetected && propertyType == 'static'}
|
||||
<Button
|
||||
size="xs2"
|
||||
color="light"
|
||||
btnClasses="font-normal text-xs w-fit bg-green-100 text-green-800 hover:bg-green-100 dark:text-green-300 dark:bg-green-700 dark:hover:bg-green-600"
|
||||
on:click={() => setJavaScriptExpr(arg.value)}
|
||||
>
|
||||
<span class="font-normal whitespace-nowrap flex gap-2 items-center"
|
||||
><FunctionSquare size={14} /> detected -
|
||||
<span class="font-bold">TAB</span>
|
||||
</span>
|
||||
</Button>
|
||||
{:else}
|
||||
<ToggleButton
|
||||
small
|
||||
light
|
||||
tooltip="JavaScript expression ('flow_input' or 'results')."
|
||||
value="javascript"
|
||||
icon={FunctionSquare}
|
||||
/>
|
||||
{/if}
|
||||
</ToggleButtonGroup>
|
||||
</div>
|
||||
|
||||
@@ -363,7 +458,7 @@
|
||||
|
||||
<div class="max-w-xs" />
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
<div class="relative" on:keyup={stepInputGen?.onKeyUp}>
|
||||
<div class="relative" on:keyup={handleKeyUp}>
|
||||
<!-- {#if $propPickerConfig?.propName == argName && $propPickerConfig?.insertionMode == 'connect'}
|
||||
<span
|
||||
class={'text-white z-50 px-1 text-2xs py-0.5 font-bold rounded-t-sm w-fit absolute top-0 right-0 bg-blue-500'}
|
||||
|
||||
@@ -405,6 +405,15 @@
|
||||
editor && editor.dispose()
|
||||
} catch (err) {}
|
||||
})
|
||||
|
||||
export function setCursorToEnd(): void {
|
||||
if (editor) {
|
||||
const lastLine = editor.getModel()?.getLineCount() ?? 1
|
||||
const lastColumn = editor.getModel()?.getLineMaxColumn(lastLine) ?? 1
|
||||
editor.setPosition({ lineNumber: lastLine, column: lastColumn })
|
||||
editor.focus()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<EditorTheme />
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
.filter(([i, f, m]) => f.length > 0)
|
||||
|
||||
setContext<PropPickerWrapperContext>('PropPickerWrapper', {
|
||||
inputMatches: writable(undefined),
|
||||
filteredPickableProperties: writable(undefined),
|
||||
focusProp: () => {},
|
||||
propPickerConfig: writable(undefined),
|
||||
clearFocus: () => {}
|
||||
|
||||
@@ -260,3 +260,40 @@ declare const approvers: string
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
export function buildPrefixRegex(words: string[]): Array<{ regex: RegExp; word: string }> {
|
||||
return words.map((word) => {
|
||||
const prefixes: string[] = []
|
||||
for (let i = 1; i <= word.length; i++) {
|
||||
prefixes.push(word.slice(0, i) + '$')
|
||||
}
|
||||
prefixes.push(word + '\\.')
|
||||
prefixes.push(word + '\\[')
|
||||
|
||||
return {
|
||||
regex: new RegExp(`^(${prefixes.join('|')}).*`),
|
||||
word
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function filterNestedObject(obj: any, nestedKeys: string[]) {
|
||||
if (nestedKeys.length === 0) return {}
|
||||
if (nestedKeys.length === 1) {
|
||||
if (nestedKeys[0] === '') {
|
||||
return obj
|
||||
}
|
||||
const regexes = buildPrefixRegex(Object.keys(obj))
|
||||
const matches = regexes.filter(({ regex }) => regex.test(nestedKeys[0]))
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj).filter(([key]) => matches.some(({ word }) => word === key))
|
||||
)
|
||||
}
|
||||
const [key, ...rest] = nestedKeys
|
||||
if (obj && typeof obj === 'object' && key in obj) {
|
||||
const result = {}
|
||||
result[key] = filterNestedObject(obj[key], rest)
|
||||
return result
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
export type PropPickerWrapperContext = {
|
||||
propPickerConfig: Writable<PropPickerConfig | undefined>
|
||||
inputMatches: Writable<{ word: string; value: string }[] | undefined>
|
||||
filteredPickableProperties: Writable<PickableProperties | undefined>
|
||||
focusProp: (propName: string, insertionMode: InsertionMode, onSelect: SelectCallback) => void
|
||||
clearFocus: () => void
|
||||
}
|
||||
@@ -37,10 +39,14 @@
|
||||
export let noPadding: boolean = false
|
||||
|
||||
const propPickerConfig = writable<PropPickerConfig | undefined>(undefined)
|
||||
const filteredPickableProperties = writable<PickableProperties | undefined>(undefined)
|
||||
const inputMatches = writable<{ word: string; value: string }[] | undefined>(undefined)
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
setContext<PropPickerWrapperContext>('PropPickerWrapper', {
|
||||
propPickerConfig,
|
||||
inputMatches,
|
||||
filteredPickableProperties,
|
||||
focusProp: (propName, insertionMode, onSelect) => {
|
||||
propPickerConfig.set({
|
||||
propName,
|
||||
|
||||
@@ -274,7 +274,7 @@ export const settings: Record<string, Setting[]> = {
|
||||
label: 'Keep job directories',
|
||||
key: 'keep_job_dir',
|
||||
fieldType: 'boolean',
|
||||
description: 'Keep Job directories after execution at /tmp/windmill/<worker>/<job_id>',
|
||||
description: 'Keep Job directories after execution at /tmp/windmill/WORKER/JOB_ID',
|
||||
storage: 'setting'
|
||||
},
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import { keepByKey } from './utils'
|
||||
import type { PickableProperties } from '../flows/previousResults'
|
||||
import ClearableInput from '../common/clearableInput/ClearableInput.svelte'
|
||||
import { filterNestedObject } from '../flows/previousResults'
|
||||
|
||||
export let pickableProperties: PickableProperties
|
||||
export let displayContext = true
|
||||
@@ -20,18 +21,31 @@
|
||||
let resources: Record<string, any> = {}
|
||||
let displayVariable = false
|
||||
let displayResources = false
|
||||
|
||||
let allResultsCollapsed = true
|
||||
let collapsableInitialState:
|
||||
| {
|
||||
allResultsCollapsed: boolean
|
||||
displayVariable: boolean
|
||||
displayResources: boolean
|
||||
}
|
||||
| undefined
|
||||
|
||||
let filterActive = false
|
||||
|
||||
const EMPTY_STRING = ''
|
||||
let search = ''
|
||||
|
||||
const { propPickerConfig } = getContext<PropPickerWrapperContext>('PropPickerWrapper')
|
||||
const { propPickerConfig, filteredPickableProperties, inputMatches } =
|
||||
getContext<PropPickerWrapperContext>('PropPickerWrapper')
|
||||
|
||||
$filteredPickableProperties = { ...pickableProperties }
|
||||
let flowInputsFiltered = pickableProperties.flow_input
|
||||
let resultByIdFiltered = pickableProperties.priorIds
|
||||
|
||||
let timeout: NodeJS.Timeout
|
||||
function onSearch(search: string) {
|
||||
filterActive = false
|
||||
clearTimeout(timeout)
|
||||
setTimeout(() => {
|
||||
flowInputsFiltered =
|
||||
@@ -72,29 +86,124 @@
|
||||
).map((resource) => [resource.path, resource.description ?? ''])
|
||||
)
|
||||
}
|
||||
|
||||
async function filterPickableProperties() {
|
||||
if (!filterActive) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!$inputMatches?.some((match) => match.word === 'flow_input')) {
|
||||
flowInputsFiltered = []
|
||||
}
|
||||
if (!$inputMatches?.some((match) => match.word === 'results')) {
|
||||
resultByIdFiltered = []
|
||||
}
|
||||
if ($inputMatches?.length == 1) {
|
||||
if ($inputMatches[0].word === 'flow_input') {
|
||||
flowInputsFiltered = pickableProperties.flow_input
|
||||
let [, ...nestedKeys] = $inputMatches[0].value.split('.')
|
||||
let filtered = filterNestedObject(flowInputsFiltered, nestedKeys)
|
||||
if (Object.keys(filtered).length > 0) {
|
||||
flowInputsFiltered = filtered
|
||||
}
|
||||
} else if ($inputMatches[0].word === 'results') {
|
||||
resultByIdFiltered = pickableProperties.priorIds
|
||||
let [, ...nestedKeys] = $inputMatches[0].value.split('.')
|
||||
let filtered = filterNestedObject(resultByIdFiltered, nestedKeys)
|
||||
if (Object.keys(filtered).length > 0) {
|
||||
resultByIdFiltered = filtered
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($filteredPickableProperties) {
|
||||
resultByIdFiltered && ($filteredPickableProperties.priorIds = resultByIdFiltered)
|
||||
flowInputsFiltered && ($filteredPickableProperties.flow_input = flowInputsFiltered)
|
||||
}
|
||||
}
|
||||
|
||||
async function updateCollapsable() {
|
||||
if (!$inputMatches || $inputMatches.length !== 1) {
|
||||
resetCollapsable()
|
||||
return
|
||||
}
|
||||
|
||||
if (!collapsableInitialState) {
|
||||
collapsableInitialState = { allResultsCollapsed, displayVariable, displayResources }
|
||||
}
|
||||
|
||||
if ($inputMatches[0].word === 'variable') {
|
||||
await loadVariables()
|
||||
displayVariable = true
|
||||
return
|
||||
}
|
||||
if ($inputMatches[0].word === 'resource') {
|
||||
await loadResources()
|
||||
displayResources = true
|
||||
return
|
||||
}
|
||||
if ($inputMatches[0].word === 'results') {
|
||||
allResultsCollapsed = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
function resetCollapsable() {
|
||||
if (!collapsableInitialState) {
|
||||
return
|
||||
}
|
||||
;({ allResultsCollapsed, displayVariable, displayResources } = collapsableInitialState)
|
||||
collapsableInitialState = undefined
|
||||
}
|
||||
|
||||
async function updateFilterActive() {
|
||||
const prev = filterActive
|
||||
|
||||
filterActive = Boolean(
|
||||
$inputMatches &&
|
||||
$inputMatches?.length > 0 &&
|
||||
$propPickerConfig?.insertionMode === 'insert' &&
|
||||
search === EMPTY_STRING
|
||||
)
|
||||
|
||||
if (prev && !filterActive) {
|
||||
flowInputsFiltered = pickableProperties.flow_input
|
||||
resultByIdFiltered = pickableProperties.priorIds
|
||||
}
|
||||
}
|
||||
|
||||
async function updateState() {
|
||||
await updateFilterActive()
|
||||
await filterPickableProperties()
|
||||
await updateCollapsable()
|
||||
}
|
||||
|
||||
$: search, $inputMatches, $propPickerConfig, updateState()
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col h-full rounded overflow-hidden">
|
||||
<div class="px-2 py-2">
|
||||
<ClearableInput bind:value={search} placeholder="Search prop..." />
|
||||
</div>
|
||||
<div class="overflow-y-auto px-2 pt-2 grow">
|
||||
<div class="flex justify-between items-center space-x-1">
|
||||
<span class="font-normal text-sm text-secondary">Flow Input</span>
|
||||
<div class="flex space-x-2 items-center" />
|
||||
</div>
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
json={flowInputsFiltered}
|
||||
prefix="flow_input"
|
||||
on:select
|
||||
/>
|
||||
</div>
|
||||
<div class="overflow-y-auto px-2 pt-2 grow" class:bg-surface-secondary={!$propPickerConfig}>
|
||||
{#if flowInputsFiltered && (Object.keys(flowInputsFiltered).length > 0 || !filterActive)}
|
||||
<div class="flex justify-between items-center space-x-1">
|
||||
<span class="font-normal text-sm text-secondary">Flow Input</span>
|
||||
<div class="flex space-x-2 items-center" />
|
||||
</div>
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
json={flowInputsFiltered}
|
||||
prefix="flow_input"
|
||||
on:select
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{#if error}
|
||||
<span class="font-normal text-sm text-secondary">Error</span>
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
@@ -112,7 +221,7 @@
|
||||
{#if Object.keys(pickableProperties.priorIds).length > 0}
|
||||
{#if suggestedPropsFiltered && Object.keys(suggestedPropsFiltered).length > 0}
|
||||
<span class="font-normal text-sm text-secondary">Suggested Results</span>
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
@@ -124,11 +233,11 @@
|
||||
</div>
|
||||
{/if}
|
||||
<span class="font-normal text-sm text-secondary">All Results</span>
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
collapsed={true}
|
||||
collapseLevel={allResultsCollapsed ? 1 : undefined}
|
||||
json={resultByIdFiltered}
|
||||
prefix="results"
|
||||
on:select
|
||||
@@ -136,9 +245,12 @@
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
{#if previousId}
|
||||
{@const json = Object.fromEntries(
|
||||
Object.entries(resultByIdFiltered).filter(([k, v]) => k == previousId)
|
||||
)}
|
||||
{#if previousId && Object.keys(json).length > 0}
|
||||
<span class="font-normal text-sm text-secondary">Previous Result</span>
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
@@ -152,7 +264,7 @@
|
||||
{/if}
|
||||
{#if pickableProperties.hasResume}
|
||||
<span class="font-normal text-sm text-secondary">Resume payloads</span>
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
@@ -166,9 +278,9 @@
|
||||
</div>
|
||||
{/if}
|
||||
{#if Object.keys(pickableProperties.priorIds).length > 0}
|
||||
{#if suggestedPropsFiltered && Object.keys(suggestedPropsFiltered).length > 0}
|
||||
{#if !filterActive && suggestedPropsFiltered && Object.keys(suggestedPropsFiltered).length > 0}
|
||||
<span class="font-normal text-sm text-secondary">Suggested Results</span>
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
@@ -179,112 +291,105 @@
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<span class="font-normal text-sm text-secondary">All Results</span>
|
||||
{#if !allResultsCollapsed}
|
||||
{#if Object.keys(resultByIdFiltered).length > 0}
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<span class="font-normal text-sm text-secondary">All Results</span>
|
||||
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
collapseLevel={allResultsCollapsed ? 1 : undefined}
|
||||
json={resultByIdFiltered}
|
||||
prefix="results"
|
||||
on:select
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{#if displayContext}
|
||||
{#if !filterActive || $inputMatches?.some((match) => match.word === 'variable')}
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<span class="font-normal text-sm text-secondary">Variables:</span>
|
||||
|
||||
{#if displayVariable}
|
||||
<Button
|
||||
color="light"
|
||||
size="xs2"
|
||||
variant="border"
|
||||
on:click={() => {
|
||||
allResultsCollapsed = true
|
||||
displayVariable = false
|
||||
}}
|
||||
wrapperClasses="inline-flex whitespace-nowrap w-fit"
|
||||
btnClasses="font-mono h-4 text-2xs font-thin px-1 rounded-[0.275rem]">-</Button
|
||||
>
|
||||
{/if}
|
||||
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
bind:collapsed={allResultsCollapsed}
|
||||
json={resultByIdFiltered}
|
||||
prefix="results"
|
||||
on:select
|
||||
/>
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
rawKey={true}
|
||||
json={variables}
|
||||
prefix="variable"
|
||||
on:select
|
||||
/>
|
||||
{:else}
|
||||
<Button
|
||||
color="light"
|
||||
size="xs2"
|
||||
variant="border"
|
||||
on:click={async () => {
|
||||
await loadVariables()
|
||||
displayVariable = true
|
||||
}}
|
||||
wrapperClasses="inline-flex w-fit"
|
||||
btnClasses="font-normal text-2xs rounded-[0.275rem] h-4 px-1"
|
||||
>
|
||||
{'{...}'}
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if !filterActive || $inputMatches?.some((match) => match.word === 'resource')}
|
||||
<div class="overflow-y-auto pb-2">
|
||||
<span class="font-normal text-sm text-secondary">Resources:</span>
|
||||
|
||||
{#if displayResources}
|
||||
<Button
|
||||
color="light"
|
||||
size="xs2"
|
||||
variant="border"
|
||||
on:click={() => {
|
||||
displayResources = false
|
||||
}}
|
||||
wrapperClasses="inline-flex whitespace-nowrap w-fit"
|
||||
btnClasses="font-mono h-4 text-2xs font-thin px-1 rounded-[0.275rem]">-</Button
|
||||
>
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
rawKey={true}
|
||||
json={resources}
|
||||
prefix="resource"
|
||||
on:select
|
||||
/>
|
||||
{:else}
|
||||
<Button
|
||||
color="light"
|
||||
size="xs2"
|
||||
variant="border"
|
||||
on:click={async () => {
|
||||
await loadResources()
|
||||
displayResources = true
|
||||
}}
|
||||
wrapperClasses="inline-flex whitespace-nowrap w-fit"
|
||||
btnClasses="font-normal text-2xs rounded-[0.275rem] h-4 px-1"
|
||||
>
|
||||
{'{...}'}
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{#if displayContext}
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<span class="font-normal text-sm text-secondary">Variables:</span>
|
||||
|
||||
{#if displayVariable}
|
||||
<Button
|
||||
color="light"
|
||||
size="xs2"
|
||||
variant="border"
|
||||
on:click={() => {
|
||||
displayVariable = false
|
||||
}}
|
||||
wrapperClasses="inline-flex whitespace-nowrap w-fit"
|
||||
btnClasses="font-mono h-4 text-2xs font-thin px-1 rounded-[0.275rem]">-</Button
|
||||
>
|
||||
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
rawKey={true}
|
||||
json={variables}
|
||||
prefix="variable"
|
||||
on:select
|
||||
/>
|
||||
{:else}
|
||||
<Button
|
||||
color="light"
|
||||
size="xs2"
|
||||
variant="border"
|
||||
on:click={async () => {
|
||||
await loadVariables()
|
||||
displayVariable = true
|
||||
}}
|
||||
wrapperClasses="inline-flex w-fit"
|
||||
btnClasses="font-normal text-2xs rounded-[0.275rem] h-4 px-1"
|
||||
>
|
||||
{'{...}'}
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="overflow-y-auto mb-2">
|
||||
<span class="font-normal text-sm text-secondary">Resources:</span>
|
||||
|
||||
{#if displayResources}
|
||||
<Button
|
||||
color="light"
|
||||
size="xs2"
|
||||
variant="border"
|
||||
on:click={() => {
|
||||
displayResources = false
|
||||
}}
|
||||
wrapperClasses="inline-flex whitespace-nowrap w-fit"
|
||||
btnClasses="font-mono h-4 text-2xs font-thin px-1 rounded-[0.275rem]">-</Button
|
||||
>
|
||||
<ObjectViewer
|
||||
{allowCopy}
|
||||
pureViewer={!$propPickerConfig}
|
||||
rawKey={true}
|
||||
json={resources}
|
||||
prefix="resource"
|
||||
on:select
|
||||
/>
|
||||
{:else}
|
||||
<Button
|
||||
color="light"
|
||||
size="xs2"
|
||||
variant="border"
|
||||
on:click={async () => {
|
||||
await loadResources()
|
||||
displayResources = true
|
||||
}}
|
||||
wrapperClasses="inline-flex whitespace-nowrap w-fit"
|
||||
btnClasses="font-normal text-2xs rounded-[0.275rem] h-4 px-1"
|
||||
>
|
||||
{'{...}'}
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,9 +32,11 @@
|
||||
<Tab value="routes" selectedClass="text-primary text-sm font-semibold">Routes</Tab>
|
||||
<Tab value="websockets" selectedClass="text-primary text-sm font-semibold">Websockets</Tab>
|
||||
<Tab value="emails" selectedClass="text-primary text-sm font-semibold">Email</Tab>
|
||||
<Tab value="scheduledPoll" selectedClass="text-primary text-sm font-semibold"
|
||||
>Scheduled Poll</Tab
|
||||
>
|
||||
{#if isFlow}
|
||||
<Tab value="scheduledPoll" selectedClass="text-primary text-sm font-semibold"
|
||||
>Scheduled Poll</Tab
|
||||
>
|
||||
{/if}
|
||||
|
||||
<svelte:fragment slot="content">
|
||||
{#if $selectedTrigger === 'webhooks'}
|
||||
|
||||
+2
-2
@@ -4,8 +4,8 @@ verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
[packages]
|
||||
wmill = ">=1.418.0"
|
||||
wmill_pg = ">=1.418.0"
|
||||
wmill = ">=1.419.0"
|
||||
wmill_pg = ">=1.419.0"
|
||||
sendgrid = "*"
|
||||
mysql-connector-python = "*"
|
||||
pymongo = "*"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: "3.0.3"
|
||||
|
||||
info:
|
||||
version: 1.418.0
|
||||
version: 1.419.0
|
||||
title: OpenFlow Spec
|
||||
contact:
|
||||
name: Ruben Fiszel
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
RootModule = 'WindmillClient.psm1'
|
||||
|
||||
# Version number of this module.
|
||||
ModuleVersion = '1.418.0'
|
||||
ModuleVersion = '1.419.0'
|
||||
|
||||
# Supported PSEditions
|
||||
# CompatiblePSEditions = @()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "wmill"
|
||||
version = "1.418.0"
|
||||
version = "1.419.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.418.0"
|
||||
version = "1.419.0"
|
||||
description = "An extension client for the wmill client library focused on pg"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://windmill.dev"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@windmill/windmill",
|
||||
"version": "1.418.0",
|
||||
"version": "1.419.0",
|
||||
"exports": "./src/index.ts",
|
||||
"publish": {
|
||||
"exclude": ["!src", "./s3Types.ts", "./client.ts"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "windmill-client",
|
||||
"description": "Windmill SDK client for browsers and Node.js",
|
||||
"version": "1.418.0",
|
||||
"version": "1.419.0",
|
||||
"author": "Ruben Fiszel",
|
||||
"license": "Apache 2.0",
|
||||
"devDependencies": {
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
1.418.0
|
||||
1.419.0
|
||||
|
||||
Reference in New Issue
Block a user