fix: address second round of review findings

- Remove bidirectional $effect sync in RawAppSidebar; bind FileExplorer
  directly to files prop with {} default
- Avoid creating new files object on every keystroke in FilesetEditor;
  merge editContent → args in a single effect without intermediate spread
- Simplify no-op `?? undefined` in addResourceType
- Add backend validation: reject create_resource_type when both
  is_fileset and format_extension are set
- Fix fileset alert title showing undefined format extension

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ruben Fiszel
2026-02-23 22:32:25 +00:00
co-authored by Claude Opus 4.6
parent 1b4489acac
commit 753c05a030
4 changed files with 24 additions and 31 deletions
+6
View File
@@ -1345,6 +1345,12 @@ async fn create_resource_type(
let is_fileset = resource_type.is_fileset.unwrap_or(false);
if is_fileset && resource_type.format_extension.is_some() {
return Err(Error::BadRequest(
"A fileset resource type cannot have a format_extension".to_string(),
));
}
sqlx::query!(
"INSERT INTO resource_type
(workspace_id, name, schema, description, created_by, format_extension, is_fileset, edited_at)
@@ -32,28 +32,30 @@
selectedFileKey?.replace(/^\//, '')
)
function flushEditContent() {
if (selectedFileKey != null && selectedFileKey in files && files[selectedFileKey] !== editContent) {
files = { ...files, [selectedFileKey]: editContent }
}
}
function handleSelectPath(path: string) {
flushEditContent()
selectedPath = path
if (!path.endsWith('/') && path !== '') {
editContent = files[path] ?? ''
}
}
// Sync editContent → files → args reactively
$effect(() => {
const key = selectedFileKey
const content = editContent
if (key != null && key in files && files[key] !== content) {
files = { ...files, [key]: content }
}
})
// Sync files → args (strip / prefix, skip folder entries)
// Sync files → args, overlaying current editContent for the active file.
// This avoids spreading a new files object on every keystroke.
$effect(() => {
const currentKey = selectedFileKey
const currentContent = editContent
const newArgs: Record<string, any> = {}
for (const [key, value] of Object.entries(files)) {
if (!key.endsWith('/')) {
newArgs[key.replace(/^\//, '')] = value
const argKey = key.replace(/^\//, '')
newArgs[argKey] = key === currentKey ? currentContent : value
}
}
args = newArgs
@@ -16,7 +16,7 @@
interface Props {
runnables: Record<string, Runnable>
selectedRunnable: string | undefined
files: Record<string, string> | undefined
files: Record<string, string>
modules?: Modules
onSelectFile?: (path: string) => void
selectedDocument: string | undefined
@@ -37,7 +37,7 @@
let {
runnables,
selectedRunnable = $bindable(),
files = $bindable(),
files = $bindable({}),
modules,
onSelectFile,
selectedDocument = $bindable(),
@@ -74,21 +74,6 @@
}
}
// Ensure files is always an object for FileExplorer binding
let explorerFiles: Record<string, string> = $state(files ?? {})
// Sync explorerFiles → files (parent binding)
$effect(() => {
files = explorerFiles
})
// Sync files → explorerFiles when files changes externally
$effect(() => {
if (files && files !== explorerFiles) {
explorerFiles = files
}
})
let fileExplorer: FileExplorer | undefined = $state()
function handleSelectPath(path: string) {
@@ -126,7 +111,7 @@
{/snippet}
<FileExplorer
bind:this={fileExplorer}
bind:files={explorerFiles}
bind:files
selectedPath={selectedDocument}
onSelectPath={handleSelectPath}
extraNodes={[{ name: 'wmill.ts', path: '/wmill.ts', isFolder: false }]}
@@ -247,7 +247,7 @@
schema: newResourceType.schema,
description: newResourceType.description,
format_extension: newResourceType.formatExtension,
is_fileset: newResourceType.isFileset ?? undefined
is_fileset: newResourceType.isFileset
}
})
resourceTypeDrawer?.closeDrawer?.()
@@ -658,7 +658,7 @@
>
<div>
{#if editResourceType.isFileset}
<Alert type="info" title="Fileset resource (.{editResourceType.formatExtension})">
<Alert type="info" title="Fileset resource type">
This resource type represents a collection of files. The schema cannot be edited.
</Alert>
{:else if editResourceType.formatExtension}