feat: extend get_draft overlay to flow, app, resource, variable, schedule, triggers

This commit is contained in:
Diego Imbert
2026-06-01 15:43:55 +02:00
parent b36cb76139
commit cc66ecd45b
24 changed files with 300 additions and 65 deletions
+26 -6
View File
@@ -20,6 +20,7 @@ use windmill_api_auth::{
};
use windmill_common::workspaces::{check_deploy_rules, RuleCheckResult};
use windmill_common::{
user_drafts::{maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery},
utils::{WithStarredInfoQuery, HTTP_CLIENT},
webhook::{WebhookMessage, WebhookShared},
DB,
@@ -1357,16 +1358,25 @@ async fn get_deployment_status(
Ok(Json(deployment_status))
}
#[derive(Deserialize)]
struct GetFlowByPathQuery {
#[serde(flatten)]
starred: WithStarredInfoQuery,
#[serde(flatten)]
draft: WithDraftQuery,
}
async fn get_flow_by_path(
authed: ApiAuthed,
Extension(user_db): Extension<UserDB>,
Extension(db): Extension<DB>,
Path((w_id, path)): Path<(String, StripPath)>,
Query(query): Query<WithStarredInfoQuery>,
) -> JsonResult<FlowWithStarred> {
Query(query): Query<GetFlowByPathQuery>,
) -> JsonResult<WithDraftOverlay> {
let path = path.to_path();
check_scopes(&authed, || format!("flows:read:{}", path))?;
let mut tx = user_db.begin(&authed).await?;
let flow_o = if query.with_starred_info.unwrap_or(false) {
let flow_o = if query.starred.with_starred_info.unwrap_or(false) {
sqlx::query_as::<_, FlowWithStarred>(
r#"
SELECT
@@ -1403,7 +1413,7 @@ async fn get_flow_by_path(
"#,
)
.bind(path)
.bind(w_id)
.bind(&w_id)
.bind(&authed.username)
.fetch_optional(&mut *tx)
.await?
@@ -1439,7 +1449,7 @@ async fn get_flow_by_path(
"#,
)
.bind(path)
.bind(w_id)
.bind(&w_id)
.fetch_optional(&mut *tx)
.await?
};
@@ -1447,7 +1457,17 @@ async fn get_flow_by_path(
tx.commit().await?;
let flow = not_found_if_none(flow_o, "Flow", path)?;
Ok(Json(flow))
let overlay = maybe_overlay_draft(
&db,
&w_id,
&authed.email,
UserDraftItemKind::Flow,
path,
query.draft.get_draft,
flow,
)
.await?;
Ok(Json(overlay))
}
async fn exists_flow_by_path(
+15 -2
View File
@@ -25,6 +25,7 @@ use windmill_common::{
db::UserDB,
error::{Error, JsonResult, Result},
schedule::Schedule,
user_drafts::{maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery},
utils::{
escape_ilike_pattern, not_found_if_none, paginate, Pagination, ScheduleType, StripPath,
},
@@ -808,8 +809,10 @@ async fn list_schedule_with_jobs(
async fn get_schedule(
authed: ApiAuthed,
Extension(user_db): Extension<UserDB>,
Extension(db): Extension<DB>,
Path((w_id, path)): Path<(String, StripPath)>,
) -> JsonResult<Schedule> {
Query(q): Query<WithDraftQuery>,
) -> JsonResult<WithDraftOverlay> {
let path = path.to_path();
check_scopes(&authed, || format!("schedules:read:{}", path))?;
let mut tx = user_db.begin(&authed).await?;
@@ -817,7 +820,17 @@ async fn get_schedule(
let schedule_o = windmill_queue::schedule::get_schedule_opt(&mut *tx, &w_id, path).await?;
let schedule = not_found_if_none(schedule_o, "Schedule", path)?;
tx.commit().await?;
Ok(Json(schedule))
let overlay = maybe_overlay_draft(
&db,
&w_id,
&authed.email,
UserDraftItemKind::TriggerSchedule,
path,
q.get_draft,
schedule,
)
.await?;
Ok(Json(overlay))
}
async fn exists_schedule(
+60 -15
View File
@@ -5324,13 +5324,16 @@ paths:
in: query
schema:
type: boolean
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: variable
content:
application/json:
schema:
$ref: "#/components/schemas/ListableVariable"
allOf:
- $ref: "#/components/schemas/ListableVariable"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/variables/get_value/{path}:
get:
@@ -6647,13 +6650,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: resource
content:
application/json:
schema:
$ref: "#/components/schemas/Resource"
allOf:
- $ref: "#/components/schemas/ListableResource"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/resources/get_value_interpolated/{path}:
get:
@@ -9676,13 +9682,16 @@ paths:
in: query
schema:
type: boolean
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: flow details
content:
application/json:
schema:
$ref: "#/components/schemas/Flow"
allOf:
- $ref: "#/components/schemas/Flow"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/flows/deployment_status/p/{path}:
get:
@@ -10459,13 +10468,16 @@ paths:
in: query
schema:
type: boolean
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: app details
content:
application/json:
schema:
$ref: "#/components/schemas/AppWithLastVersion"
allOf:
- $ref: "#/components/schemas/AppWithLastVersion"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/apps/get/lite/{path}:
get:
@@ -13604,13 +13616,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: schedule deleted
content:
application/json:
schema:
$ref: "#/components/schemas/Schedule"
allOf:
- $ref: "#/components/schemas/Schedule"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/schedules/exists/{path}:
get:
@@ -13893,13 +13908,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: http trigger deleted
content:
application/json:
schema:
$ref: "#/components/schemas/HttpTrigger"
allOf:
- $ref: "#/components/schemas/HttpTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/http_triggers/list:
get:
@@ -14099,13 +14117,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: websocket trigger deleted
content:
application/json:
schema:
$ref: "#/components/schemas/WebsocketTrigger"
allOf:
- $ref: "#/components/schemas/WebsocketTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/websocket_triggers/list:
get:
@@ -14304,13 +14325,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: kafka trigger deleted
content:
application/json:
schema:
$ref: "#/components/schemas/KafkaTrigger"
allOf:
- $ref: "#/components/schemas/KafkaTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/kafka_triggers/list:
get:
@@ -14550,13 +14574,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: nats trigger deleted
content:
application/json:
schema:
$ref: "#/components/schemas/NatsTrigger"
allOf:
- $ref: "#/components/schemas/NatsTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/nats_triggers/list:
get:
@@ -14750,13 +14777,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: sqs trigger deleted
content:
application/json:
schema:
$ref: "#/components/schemas/SqsTrigger"
allOf:
- $ref: "#/components/schemas/SqsTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/sqs_triggers/list:
get:
@@ -15543,13 +15573,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: mqtt trigger deleted
content:
application/json:
schema:
$ref: "#/components/schemas/MqttTrigger"
allOf:
- $ref: "#/components/schemas/MqttTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/mqtt_triggers/list:
get:
@@ -15743,13 +15776,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: gcp trigger deleted
content:
application/json:
schema:
$ref: "#/components/schemas/GcpTrigger"
allOf:
- $ref: "#/components/schemas/GcpTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/gcp_triggers/list:
get:
@@ -16010,13 +16046,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: azure trigger
content:
application/json:
schema:
$ref: "#/components/schemas/AzureTrigger"
allOf:
- $ref: "#/components/schemas/AzureTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/azure_triggers/list:
get:
@@ -16553,13 +16592,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: get postgres trigger
content:
application/json:
schema:
$ref: "#/components/schemas/PostgresTrigger"
allOf:
- $ref: "#/components/schemas/PostgresTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/postgres_triggers/list:
get:
@@ -16753,13 +16795,16 @@ paths:
parameters:
- $ref: "#/components/parameters/WorkspaceId"
- $ref: "#/components/parameters/Path"
- $ref: "#/components/parameters/GetDraft"
responses:
"200":
description: email trigger retrieved
content:
application/json:
schema:
$ref: "#/components/schemas/EmailTrigger"
allOf:
- $ref: "#/components/schemas/EmailTrigger"
- $ref: "#/components/schemas/UserDraftOverlay"
/w/{workspace}/email_triggers/list:
get:
+34 -7
View File
@@ -58,6 +58,7 @@ use windmill_common::{
get_payload_tag_from_prefixed_path, resolve_delete_after_secs, schedule_job_deletion,
JobPayload, RawCode,
},
user_drafts::{maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery},
users::username_to_permissioned_as,
utils::{
http_get_from_hub, not_found_if_none, paginate, query_elems_from_hub, require_admin,
@@ -535,17 +536,26 @@ async fn get_raw_app_data(
// Ok(Json(version))
// }
#[derive(Deserialize)]
struct GetAppQuery {
#[serde(flatten)]
starred: WithStarredInfoQuery,
#[serde(flatten)]
draft: WithDraftQuery,
}
async fn get_app(
authed: ApiAuthed,
Extension(user_db): Extension<UserDB>,
Extension(db): Extension<DB>,
Path((w_id, path)): Path<(String, StripPath)>,
Query(query): Query<WithStarredInfoQuery>,
) -> JsonResult<AppWithLastVersionAndStarred> {
Query(query): Query<GetAppQuery>,
) -> JsonResult<WithDraftOverlay> {
let path = path.to_path();
check_scopes(&authed, || format!("apps:read:{}", path))?;
let mut tx = user_db.begin(&authed).await?;
let app_o = if query.with_starred_info.unwrap_or(false) {
let app_o = if query.starred.with_starred_info.unwrap_or(false) {
sqlx::query_as::<_, AppWithLastVersionAndStarred>(
"SELECT app.id, app.path, app.summary, app.versions, app.policy, app.custom_path,
app.extra_perms, app_version.value,
@@ -554,9 +564,9 @@ async fn get_app(
JOIN app_version
ON app_version.id = app.versions[array_upper(app.versions, 1)]
LEFT JOIN favorite
ON favorite.favorite_kind = 'app'
AND favorite.workspace_id = app.workspace_id
AND favorite.path = app.path
ON favorite.favorite_kind = 'app'
AND favorite.workspace_id = app.workspace_id
AND favorite.path = app.path
AND favorite.usr = $3
WHERE app.path = $1 AND app.workspace_id = $2",
)
@@ -581,7 +591,24 @@ async fn get_app(
tx.commit().await?;
let app = not_found_if_none(app_o, "App", path)?;
Ok(Json(app))
// The same `app` table backs both regular apps and raw apps; the
// `raw_app` flag on the row picks which draft kind to look up.
let kind = if app.app.raw_app {
UserDraftItemKind::RawApp
} else {
UserDraftItemKind::App
};
let overlay = maybe_overlay_draft(
&db,
&w_id,
&authed.email,
kind,
path,
query.draft.get_draft,
app,
)
.await?;
Ok(Json(overlay))
}
async fn get_app_lite(
+14 -2
View File
@@ -43,6 +43,7 @@ use windmill_common::{
db::{DbWithOptAuthed, UserDB},
error::{self, Error, JsonResult, Result},
get_database_url,
user_drafts::{maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery},
utils::{not_found_if_none, paginate, require_admin, Pagination, StripPath},
variables,
worker::{CLOUD_HOSTED, WINDMILL_DIR},
@@ -360,7 +361,8 @@ async fn get_resource(
Extension(user_db): Extension<UserDB>,
Extension(db): Extension<DB>,
Path((w_id, path)): Path<(String, StripPath)>,
) -> JsonResult<ListableResource> {
Query(q): Query<WithDraftQuery>,
) -> JsonResult<WithDraftOverlay> {
let path = path.to_path();
check_scopes(&authed, || format!("resources:read:{}", path))?;
let mut tx = user_db.begin(&authed).await?;
@@ -391,7 +393,17 @@ async fn get_resource(
explain_resource_perm_error(&path, &w_id, &db, &authed).await?;
}
let resource = not_found_if_none(resource_o, "Resource", path)?;
Ok(Json(resource))
let overlay = maybe_overlay_draft(
&db,
&w_id,
&authed.email,
UserDraftItemKind::Resource,
path,
q.get_draft,
resource,
)
.await?;
Ok(Json(overlay))
}
async fn exists_resource(
+15 -2
View File
@@ -35,6 +35,7 @@ use windmill_common::{
db::{DbWithOptAuthed, UserDB},
error::{Error, JsonResult, Result},
scripts::ScriptHash,
user_drafts::{maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery},
utils::{not_found_if_none, paginate, Pagination, StripPath, WarnAfterExt},
variables::{
build_crypt, get_reserved_variables, ContextualVariable, CreateVariable, ListableVariable,
@@ -207,6 +208,8 @@ async fn list_variables(
struct GetVariableQuery {
decrypt_secret: Option<bool>,
include_encrypted: Option<bool>,
#[serde(flatten)]
draft: WithDraftQuery,
}
async fn get_variable(
@@ -215,7 +218,7 @@ async fn get_variable(
Extension(db): Extension<DB>,
Query(q): Query<GetVariableQuery>,
Path((w_id, path)): Path<(String, StripPath)>,
) -> JsonResult<ListableVariable> {
) -> JsonResult<WithDraftOverlay> {
let path = path.to_path();
check_scopes(&authed, || format!("variables:read:{}", path))?;
@@ -302,7 +305,17 @@ async fn get_variable(
variable
};
Ok(Json(r))
let overlay = maybe_overlay_draft(
&db,
&w_id,
&authed.email,
UserDraftItemKind::Variable,
path,
q.draft.get_draft,
r,
)
.await?;
Ok(Json(overlay))
}
#[derive(Deserialize)]
+38 -2
View File
@@ -16,6 +16,7 @@ use windmill_api_auth::{check_scopes, ApiAuthed};
use windmill_common::{
db::UserDB,
error::{Error, JsonResult, Result},
user_drafts::{maybe_overlay_draft, UserDraftItemKind, WithDraftOverlay, WithDraftQuery},
utils::{paginate, Pagination, StripPath},
worker::CLOUD_HOSTED,
DB,
@@ -106,6 +107,29 @@ pub trait TriggerCrud: Send + Sync + 'static {
&Self::ROUTE_PREFIX[1..]
}
/// `UserDraftItemKind` for the per-user `draft` table lookup. Defaults
/// to derive from `TRIGGER_TYPE` so each impl gets it for free as long
/// as the string matches the canonical kind (e.g. `"http"` →
/// `TriggerHttp`). Override only when the mapping isn't 1:1.
fn user_draft_item_kind() -> UserDraftItemKind {
match Self::TRIGGER_TYPE {
"http" => UserDraftItemKind::TriggerHttp,
"websocket" => UserDraftItemKind::TriggerWebsocket,
"kafka" => UserDraftItemKind::TriggerKafka,
"nats" => UserDraftItemKind::TriggerNats,
"sqs" => UserDraftItemKind::TriggerSqs,
"mqtt" => UserDraftItemKind::TriggerMqtt,
"gcp" => UserDraftItemKind::TriggerGcp,
"azure" => UserDraftItemKind::TriggerAzure,
"postgres" => UserDraftItemKind::TriggerPostgres,
"email" => UserDraftItemKind::TriggerEmail,
other => panic!(
"TriggerCrud impl with TRIGGER_TYPE = {:?} must override user_draft_item_kind()",
other
),
}
}
async fn create_trigger(
&self,
db: &DB,
@@ -551,8 +575,10 @@ async fn get_trigger<T: TriggerCrud>(
Extension(handler): Extension<Arc<T>>,
authed: ApiAuthed,
Extension(user_db): Extension<UserDB>,
Extension(db): Extension<DB>,
Path((workspace_id, path)): Path<(String, StripPath)>,
) -> JsonResult<T::Trigger> {
Query(q): Query<WithDraftQuery>,
) -> JsonResult<WithDraftOverlay> {
let path = path.to_path();
check_scopes(&authed, || {
format!("{}:read:{}", T::scope_domain_name(), &path)
@@ -565,7 +591,17 @@ async fn get_trigger<T: TriggerCrud>(
tx.commit().await?;
Ok(Json(trigger))
let overlay = maybe_overlay_draft(
&db,
&workspace_id,
&authed.email,
T::user_draft_item_kind(),
path,
q.get_draft,
trigger,
)
.await?;
Ok(Json(overlay))
}
async fn update_trigger<T: TriggerCrud>(
@@ -219,9 +219,7 @@
const s: ResourceState = {
path: '',
description: '',
args: (defaultValues && Object.keys(defaultValues).length > 0
? defaultValues
: {}) as any,
args: (defaultValues && Object.keys(defaultValues).length > 0 ? defaultValues : {}) as any,
labels: undefined,
wsSpecific: false
}
@@ -238,9 +236,12 @@
if (ws in states) return
untrack(() => {
Promise.all([
ResourceService.getResource({ workspace: ws, path: initialPath }),
ResourceService.getResource({ workspace: ws, path: initialPath, getDraft: true }),
getUserExt(ws)
]).then(([r, user]) => {
if (r.is_draft) {
sendUserToast('Loaded your saved draft')
}
fetchedResources[ws] = r
fetchedRev[ws] = r.edited_at
const s: ResourceState = {
@@ -154,9 +154,17 @@
if (ws in states) return
untrack(() => {
Promise.all([
VariableService.getVariable({ workspace: ws, path: p, decryptSecret: false }),
VariableService.getVariable({
workspace: ws,
path: p,
decryptSecret: false,
getDraft: true
}),
getUserExt(ws)
]).then(([v, user]) => {
if (v.is_draft) {
sendUserToast('Loaded your saved draft')
}
fetchedRev[ws] = v.edited_at
const s: VariableState = {
path: v.path,
@@ -1081,10 +1081,7 @@ async function readWorkspaceItem(
true
)
case 'resource':
return resourceToItem(
(await ResourceService.getResource({ workspace, path })) as ListableResource,
true
)
return resourceToItem(await ResourceService.getResource({ workspace, path }), true)
case 'variable':
// Never expose the value, even when read directly. Pass decryptSecret=false
// to avoid materializing secret values server-side.
@@ -2568,9 +2565,10 @@ async function patchAppFile(
}
async function recomputeAppPolicy(value: AppDraftValue): Promise<void> {
const policy = (await updateRawAppPolicy(value.runnables as any, value.policy as any)) as NonNullable<
AppDraftValue['policy']
>
const policy = (await updateRawAppPolicy(
value.runnables as any,
value.policy as any
)) as NonNullable<AppDraftValue['policy']>
if (!policy.execution_mode) {
policy.execution_mode = 'publisher'
}
@@ -3045,7 +3043,8 @@ export function prepareGlobalUserMessage(
(context) => context.type === 'workspace_script' || context.type === 'workspace_flow'
)
const activeEditor =
options.activeEditor ?? (options.workspace ? getActiveGlobalEditorContext(options.workspace) : undefined)
options.activeEditor ??
(options.workspace ? getActiveGlobalEditorContext(options.workspace) : undefined)
let content = ''
if (activeEditor) {
@@ -191,8 +191,12 @@
try {
const s = await AzureTriggerService.getAzureTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
loadTriggerConfig(s)
} catch (error) {
sendUserToast(`Could not load Azure trigger: ${error.body}`, true)
@@ -212,8 +212,12 @@
} else {
const s = await EmailTriggerService.getEmailTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
loadTriggerConfig(s)
}
@@ -195,8 +195,12 @@
try {
const s = await GcpTriggerService.getGcpTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
loadTriggerConfig(s)
} catch (error) {
sendUserToast(`Could not load GCP Pub/Sub trigger: ${error.body}`, true)
@@ -345,8 +345,12 @@
} else {
const s = await HttpTriggerService.getHttpTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
loadTriggerConfig(s)
}
@@ -251,8 +251,12 @@
} else {
const s = await KafkaTriggerService.getKafkaTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
loadTriggerConfig(s)
}
}
@@ -251,8 +251,12 @@
} else {
const s = await MqttTriggerService.getMqttTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
loadTriggerConfig(s)
}
} catch (error) {
@@ -233,8 +233,12 @@
} else {
const s = await NatsTriggerService.getNatsTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
loadTriggerConfig(s)
}
}
@@ -377,8 +377,12 @@
} else {
const s = await PostgresTriggerService.getPostgresTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
const publication_data = await PostgresTriggerService.getPostgresPublication({
path: s.postgres_resource_path,
@@ -285,10 +285,15 @@
try {
let s: Schedule | undefined
if (schedule_path) {
s = await ScheduleService.getSchedule({
const resp = await ScheduleService.getSchedule({
workspace: $workspaceStore!,
path: schedule_path
path: schedule_path,
getDraft: true
})
if (resp.is_draft) {
sendUserToast('Loaded your saved draft')
}
s = resp
initNewPath = true
} else if (defaultValues) {
s = defaultValues
@@ -451,8 +456,12 @@
try {
const s = await ScheduleService.getSchedule({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s.is_draft) {
sendUserToast('Loaded your saved draft')
}
await loadScheduleCfg(s)
} catch (err) {
sendUserToast(`Could not load schedule: ${err}`, true)
@@ -228,8 +228,12 @@
} else {
const s = await SqsTriggerService.getSqsTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
loadTriggerConfig(s)
}
} catch (error) {
@@ -308,8 +308,12 @@
} else {
const s = await WebsocketTriggerService.getWebsocketTrigger({
workspace: $workspaceStore!,
path: initialPath
path: initialPath,
getDraft: true
})
if (s?.is_draft) {
sendUserToast('Loaded your saved draft')
}
loadTriggerConfig(s)
}
}
@@ -90,9 +90,13 @@
const tok = ++loadAppToken
const backendApp = await AppService.getAppByPath({
path: page.params.path ?? '',
workspace: $workspaceStore!
workspace: $workspaceStore!,
getDraft: true
})
if (tok !== loadAppToken) return
if (backendApp.is_draft) {
sendUserToast('Loaded your saved draft')
}
const backendApp_ = structuredClone(stateSnapshot(backendApp))
savedApp = {
summary: backendApp_.summary,
@@ -177,9 +177,13 @@
const tok = ++loadAppToken
const backendApp = await AppService.getAppByPath({
path: page.params.path ?? '',
workspace: $workspaceStore!
workspace: $workspaceStore!,
getDraft: true
})
if (tok !== loadAppToken) return
if (backendApp.is_draft) {
sendUserToast('Loaded your saved draft')
}
const backendApp_ = structuredClone(stateSnapshot(backendApp))
savedApp = {
summary: backendApp_.summary,
@@ -145,9 +145,13 @@
const backendFlow = await FlowService.getFlowByPath({
workspace: $workspaceStore!,
path: page.params.path ?? ''
path: page.params.path ?? '',
getDraft: true
})
if (tok !== loadFlowToken) return
if (backendFlow.is_draft) {
sendUserToast('Loaded your saved draft')
}
savedFlow = structuredClone($state.snapshot(backendFlow)) as Flow
const localDraft = flowHandle.draft