fix(frontend): improve handling of optional enums

This commit is contained in:
Ruben Fiszel
2024-02-21 12:25:10 +01:00
parent bd439f9666
commit 77d66efa45
16 changed files with 67 additions and 34 deletions
+33 -12
View File
@@ -370,18 +370,27 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
TsType::TsUnionOrIntersectionType(TsUnionOrIntersectionType::TsUnionType(
TsUnionType { types, .. },
)) => {
if let Some(p) = if types.len() != 2 {
None
let (is_undefined_option, undefined_position) = if types.len() == 2 {
(true, find_undefined(types))
} else if types.into_iter().all(|x| {
x.as_ts_lit_type().is_some_and(|y| y.lit.as_str().is_some())
|| x.as_ts_keyword_type().is_some_and(|y| {
y.kind == TsKeywordTypeKind::TsUndefinedKeyword
|| y.kind == TsKeywordTypeKind::TsStringKeyword
|| y.kind == TsKeywordTypeKind::TsNullKeyword
})
}) {
(false, find_undefined(types))
} else {
types.into_iter().position(|x| match **x {
TsType::TsKeywordType(TsKeywordType { kind, .. }) => {
kind == TsKeywordTypeKind::TsUndefinedKeyword
|| kind == TsKeywordTypeKind::TsNullKeyword
}
_ => false,
})
} {
let other_p = if p == 0 { 1 } else { 0 };
(false, None)
};
if is_undefined_option && undefined_position.is_some() {
let other_p = if undefined_position.unwrap() == 0 {
1
} else {
0
};
(tstype_to_typ(&types[other_p]).0, true)
} else {
let literals = types
@@ -389,6 +398,8 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
.filter(|x| match ***x {
TsType::TsKeywordType(TsKeywordType { kind, .. }) => {
kind != TsKeywordTypeKind::TsStringKeyword
&& kind != TsKeywordTypeKind::TsUndefinedKeyword
&& kind != TsKeywordTypeKind::TsNullKeyword
}
_ => true,
})
@@ -404,7 +415,7 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
} else {
(
Typ::Str(Some(literals.into_iter().filter_map(|x| x).collect())),
false,
undefined_position.is_some(),
)
}
}
@@ -441,6 +452,16 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
}
}
fn find_undefined(types: &Vec<Box<TsType>>) -> Option<usize> {
types.into_iter().position(|x| match **x {
TsType::TsKeywordType(TsKeywordType { kind, .. }) => {
kind == TsKeywordTypeKind::TsUndefinedKeyword
|| kind == TsKeywordTypeKind::TsNullKeyword
}
_ => false,
})
}
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
extern "C" {
@@ -3,7 +3,7 @@
"collaborators": [
"Ruben Fiszel <ruben@windmill.dev>"
],
"version": "1.237.0",
"version": "1.274.0",
"files": [
"windmill_parser_wasm_bg.wasm",
"windmill_parser_wasm.js",
@@ -538,10 +538,6 @@ async function __wbg_load(module, imports) {
function __wbg_get_imports() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbg_eval_ff4183ac1495b791 = function(arg0, arg1) {
const ret = eval(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
@@ -593,6 +589,10 @@ function __wbg_get_imports() {
const ret = getObject(arg0) in getObject(arg1);
return ret;
};
imports.wbg.__wbg_eval_69b0e521a846e4c2 = function(arg0, arg1) {
const ret = eval(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) {
const ret = getObject(arg0) == getObject(arg1);
return ret;
@@ -10,7 +10,8 @@ export function main(test1?: string, test2: string = \"burkina\",
test3: wmill.Resource<'postgres'>, b64: Base64, ls: Base64[],
email: Email, literal: \"test\", literal_union: \"test\" | \"test2\",
opt_type?: string | null, opt_type_union: string | null, opt_type_union_union2: string | undefined,
min_object: {a: string, b: number}) {
min_object: {a: string, b: number},
literals_with_undefined: \"foo\" | \"bar\" | undefined) {
console.log(42)
}
";
@@ -106,6 +107,13 @@ export function main(test1?: string, test2: string = \"burkina\",
]),
default: None,
has_default: false
},
Arg {
otyp: None,
name: "literals_with_undefined".to_string(),
typ: Typ::Str(Some(vec!["foo".to_string(), "bar".to_string()])),
default: None,
has_default: true
}
]
}
@@ -113,7 +121,6 @@ export function main(test1?: string, test2: string = \"burkina\",
Ok(())
}
#[wasm_bindgen_test]
fn test_parse_deno_sig_implicit_types() -> anyhow::Result<()> {
let code = "
+4 -4
View File
@@ -51,7 +51,7 @@
"vscode-languageclient": "~9.0.1",
"vscode-uri": "~3.0.8",
"vscode-ws-jsonrpc": "~3.1.0",
"windmill-parser-wasm": "^1.237.0",
"windmill-parser-wasm": "^1.274.0",
"y-monaco": "^0.1.4",
"y-websocket": "^1.5.0",
"yaml": "^2.3.4",
@@ -10085,9 +10085,9 @@
}
},
"node_modules/windmill-parser-wasm": {
"version": "1.237.0",
"resolved": "https://registry.npmjs.org/windmill-parser-wasm/-/windmill-parser-wasm-1.237.0.tgz",
"integrity": "sha512-MGO9rkSnkFMOkkkEr/whFzkbyeHX4E6JwYLazlDgyprNNibpEi7GXcOeuz+QgbzDNrTLo/sYN6bYqcHt4Jk6dQ=="
"version": "1.274.0",
"resolved": "https://registry.npmjs.org/windmill-parser-wasm/-/windmill-parser-wasm-1.274.0.tgz",
"integrity": "sha512-p3fqgj/XIzcoJFGcIw/ss2kAvrACaCXdPkKuADVRkGjgz8hVuVpA795phFkKOZEydpXGByfq7vXTUZJ3mJp5eA=="
},
"node_modules/wordwrap": {
"version": "1.0.0",
+1 -1
View File
@@ -133,7 +133,7 @@
"vscode-languageclient": "~9.0.1",
"vscode-uri": "~3.0.8",
"vscode-ws-jsonrpc": "~3.1.0",
"windmill-parser-wasm": "^1.237.0",
"windmill-parser-wasm": "^1.274.0",
"y-monaco": "^0.1.4",
"y-websocket": "^1.5.0",
"yaml": "^2.3.4",
+3 -2
View File
@@ -6,7 +6,7 @@
export let disabled: boolean
export let value: any
export let enum_: string[] | undefined
export let autofocus: boolean
export let autofocus: boolean | null
export let defaultValue: string | undefined
export let valid: boolean
export let create: boolean
@@ -26,7 +26,7 @@
<div class="w-full flex-col">
<div class="w-full">
<AutoComplete
items={[...(enum_ ?? []), ...customItems]}
items={[...(required ? [] : ['']), ...(enum_ ?? []), ...customItems]}
bind:selectedItem={value}
inputClassName={twMerge(
'bg-surface-secondary flex',
@@ -36,6 +36,7 @@
)}
value={value ?? defaultValue}
hideArrow={true}
selectFirstIfEmpty={required}
dropdownClassName="!text-sm !py-2 !rounded-sm !border-gray-200 !border !shadow-md !bg-surface-primary"
className="w-full"
noInputStyles
+2 -2
View File
@@ -55,7 +55,7 @@
export let displayHeader = true
export let properties: { [name: string]: SchemaProperty } | undefined = undefined
export let nestedRequired: string[] | undefined = undefined
export let autofocus = false
export let autofocus: boolean | null = null
export let compact = false
export let password = false
export let pickForField: string | undefined = undefined
@@ -96,7 +96,7 @@
if (defaultValue === undefined || defaultValue === null) {
if (inputCat === 'string') {
value = ''
} else if (inputCat == 'enum') {
} else if (inputCat == 'enum' && required) {
value = enum_?.[0]
} else if (inputCat == 'boolean') {
value = false
@@ -4,7 +4,7 @@
export let value: string | undefined = undefined
export let autofocus: boolean = false
export let autofocus: boolean | null = false
export let useDropdown: boolean = false
let date: string | undefined = undefined
+1 -1
View File
@@ -671,7 +671,7 @@
}
)
} catch (err) {
console.error(err)
console.warn(err)
}
}
@@ -164,6 +164,7 @@
{#key ownerKind}
<AutoComplete
required
noInputStyles
items={ownerKind === 'user' ? usernames : groups}
bind:selectedItem={ownerItem}
@@ -205,7 +206,9 @@
{#if folderNotFound}
<Alert type="warning" title="Folder not found" size="xs">
The folder "{name}" does not exist in the workspace. You can create it by clicking the
button below. An item can seemingly be in a folder given its path without the folder existing. A windmill folder has settable permissions that its children inherit. If an item is within a non-existing folders, only admins will see it.
button below. An item can seemingly be in a folder given its path without the folder
existing. A windmill folder has settable permissions that its children inherit. If an item
is within a non-existing folders, only admins will see it.
</Alert>
<Button
color="light"
@@ -135,7 +135,7 @@
<h2>Members ({members?.length ?? 0})</h2>
{#if can_write}
<div class="flex items-start">
<AutoComplete noInputStyles items={usernames} bind:selectedItem={username} />
<AutoComplete required noInputStyles items={usernames} bind:selectedItem={username} />
<Button variant="contained" color="blue" size="sm" btnClasses="!ml-4" on:click={addToGroup}>
Add member
</Button>
@@ -139,7 +139,7 @@
if (defaultValue === undefined || defaultValue === null) {
if (inputCat === 'string') {
value = ''
} else if (inputCat == 'enum') {
} else if (inputCat == 'enum' && required) {
value = enum_?.[0]
} else if (inputCat == 'boolean') {
value = false
@@ -132,7 +132,7 @@
{disablePortal}
{resourceTypes}
{prettifyHeader}
autofocus={i == 0 && autofocus}
autofocus={i == 0 && autofocus ? true : null}
label={argName}
description={schema.properties[argName].description}
bind:value={args[argName]}
@@ -125,6 +125,7 @@
</div>
{#key ownerKind}
<AutoComplete
required
noInputStyles
items={ownerKind === 'user' ? usernames : groups}
bind:selectedItem={owner}