Skip to content

feat(FR-3154): add reusable BAIVFolderMountConfigInput component#7932

Open
nowgnuesLee wants to merge 3 commits into
06-16-docs_fr-3153_add_vfolder_mount_subpath_alias_config_component_specfrom
06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component
Open

feat(FR-3154): add reusable BAIVFolderMountConfigInput component#7932
nowgnuesLee wants to merge 3 commits into
06-16-docs_fr-3153_add_vfolder_mount_subpath_alias_config_component_specfrom
06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component

Conversation

@nowgnuesLee

@nowgnuesLee nowgnuesLee commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Stacked on #7931 · Part of FR-3059 (#7756) · Resolves FR-3154

Summary

  • Add BAIVFolderMountConfigInput, a reusable, schema-agnostic controlled input for configuring vfolder mounts (packages/backend.ai-ui/src/components/fragments/).
  • Composes BAIVFolderSelect (multiple) to pick folders; each selected folder renders as a row below the select with:
    • a mount destination (alias) input — path inside the container (empty falls back to /home/work/{name}),
    • an optional subpath free-text input — which subfolder of the vfolder to mount as the source (empty = root),
    • a remove (✕) button.
  • Emits a single VFolderMountConfigValue[] value via value / onChange, so it wraps in one Form.Item and the consumer maps it to any mount mutation input. No GraphQL/schema coupling.
  • Inline validation: alias format (^[a-zA-Z0-9_/.-]*$), alias overlap between folders, and relative-subpath / no-.. checks.
  • Adds BUI i18n keys (comp:BAIVFolderMountConfigInput) for en and ko.

Notes

  • Standalone component only. Wiring it into session creation / Deployment revision pages is a follow-up (out of scope for this stack, per the spec).

Verification (scripts/verify.sh)

  • Relay / Lint / Format: PASS
  • backend.ai-ui package tsc --noEmit: 0 errors
  • The single TypeScript failure reported by verify.sh is pre-existing on main (unrelated Relay input-type mismatch in react/src/pages/AdminDeploymentPresetSettingPage.tsx, service.port: number | null vs number) and is not introduced by this PR.

Test plan

  • Selecting multiple vfolders adds a row per folder with alias + subpath inputs
  • Remove (✕) clears the row and its alias/subpath values
  • Invalid alias format, overlapping mount paths, and invalid subpath show inline errors
  • Empty mount destination shows the effective default path as helper text

nowgnuesLee commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • flow:merge-queue - adds this PR to the back of the merge queue
  • flow:hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has required the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Coverage Report for backend-ai-ui-coverage (./packages/backend.ai-ui)

Status Category Percentage Covered / Total
🔵 Lines 10.77% 558 / 5181
🔵 Statements 9.09% 621 / 6830
🔵 Functions 11.81% 137 / 1160
🔵 Branches 7.58% 507 / 6688
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/backend.ai-ui/src/components/fragments/BAIVFolderMountConfigInput.tsx 0% 0% 0% 0% 52-438
packages/backend.ai-ui/src/components/fragments/BAIVFolderSelect.tsx 0% 0% 0% 0% 52-377
packages/backend.ai-ui/src/components/fragments/index.ts 100% 100% 100% 100%
Generated in workflow #2279 for commit 6ab430b by the Vitest Coverage Report Action

@github-actions github-actions Bot added size:XL 500~ LoC and removed size:L 100~500 LoC labels Jun 16, 2026
@nowgnuesLee nowgnuesLee force-pushed the 06-16-docs_fr-3153_add_vfolder_mount_subpath_alias_config_component_spec branch from 9ea409a to 5f9f5ab Compare June 16, 2026 07:19
@nowgnuesLee nowgnuesLee force-pushed the 06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component branch from 9bb3f20 to 80466ff Compare June 16, 2026 07:19
@nowgnuesLee nowgnuesLee marked this pull request as ready for review June 16, 2026 08:03
Copilot AI review requested due to automatic review settings June 16, 2026 08:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new reusable Backend.AI UI fragment component to configure vfolder mounts (alias/mount destination + optional subpath) as a single controlled VFolderMountConfigValue[] payload, intended to be schema-agnostic and embeddable in a single Form.Item.

Changes:

  • Added BAIVFolderMountConfigInput fragment component composing BAIVFolderSelect (multi) and per-folder alias/subpath inputs with inline validation UI.
  • Exported the new component + types from the fragments barrel.
  • Added comp:BAIVFolderMountConfigInput i18n keys across BUI locale JSONs (with localized strings for en/ko and English fallbacks elsewhere).

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/backend.ai-ui/src/locale/zh-TW.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/zh-CN.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/vi.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/tr.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/th.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/ru.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/pt.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/pt-BR.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/pl.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/ms.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/mn.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/ko.json Adds localized Korean strings for comp:BAIVFolderMountConfigInput.
packages/backend.ai-ui/src/locale/ja.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/it.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/id.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/fr.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/fi.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/es.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/en.json Adds English strings for comp:BAIVFolderMountConfigInput.
packages/backend.ai-ui/src/locale/el.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/locale/de.json Adds comp:BAIVFolderMountConfigInput strings (English fallback).
packages/backend.ai-ui/src/components/fragments/index.ts Re-exports BAIVFolderMountConfigInput and its public types.
packages/backend.ai-ui/src/components/fragments/BAIVFolderMountConfigInput.tsx Implements the reusable controlled mount-config input UI and validation display.

Comment thread packages/backend.ai-ui/src/components/fragments/BAIVFolderMountConfigInput.tsx Outdated
Comment thread packages/backend.ai-ui/src/components/fragments/BAIVFolderMountConfigInput.tsx Outdated
Comment thread packages/backend.ai-ui/src/components/fragments/BAIVFolderMountConfigInput.tsx Outdated
@nowgnuesLee nowgnuesLee force-pushed the 06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component branch from 80466ff to f1a62fc Compare June 16, 2026 08:15
@nowgnuesLee nowgnuesLee force-pushed the 06-16-docs_fr-3153_add_vfolder_mount_subpath_alias_config_component_spec branch from 5f9f5ab to 2bf1cdf Compare June 16, 2026 09:25
@nowgnuesLee nowgnuesLee force-pushed the 06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component branch from f1a62fc to ce162e0 Compare June 16, 2026 09:25
@nowgnuesLee nowgnuesLee force-pushed the 06-16-docs_fr-3153_add_vfolder_mount_subpath_alias_config_component_spec branch from 2bf1cdf to 8238fc4 Compare June 16, 2026 09:32
@nowgnuesLee nowgnuesLee force-pushed the 06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component branch from ce162e0 to 443fe8e Compare June 16, 2026 09:32
Reusable, schema-agnostic controlled input for configuring vfolder mounts.
Composes BAIVFolderSelect to pick folders; each selected folder appears as a
row with a mount destination (alias) input and an optional subpath input.
Emits a single VFolderMountConfigValue[] value so it can be wrapped in one
Form.Item and mapped to any mount mutation input by the consumer.
Reusable, schema-agnostic controlled input for configuring vfolder mounts.
Composes BAIVFolderSelect to pick folders; each selected folder appears as a
row with a mount destination (alias) input and an optional subpath input.
Emits a single VFolderMountConfigValue[] value so it can be wrapped in one
Form.Item and mapped to any mount mutation input by the consumer.

Adds comp:BAIVFolderMountConfigInput i18n keys across all locales (en/ko
translated, others English fallback) and uses BAIText for the folder name.
@nowgnuesLee nowgnuesLee force-pushed the 06-16-docs_fr-3153_add_vfolder_mount_subpath_alias_config_component_spec branch from 8238fc4 to 5a9eb17 Compare June 22, 2026 09:34
@nowgnuesLee nowgnuesLee force-pushed the 06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component branch from 443fe8e to 4d68a95 Compare June 22, 2026 09:34
agatha197 added a commit that referenced this pull request Jun 24, 2026

@agatha197 agatha197 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — actionable items

This is an additive BUI primitive with no consumer wired yet, so none of these block today. Listing what should be fixed before the first consumer wires it in.

Correctness

  • Single source of truth for mountDestination. Display/validation recompute the destination every render (destinationByVFolderId, ~L197-205 / L307-313), but the emitted value uses the stored entry.mountDestination written across four handlers. These can diverge. Please settle on one — emit the recomputed value, or validate the stored one.
  • onChange updates name without recomputing mountDestination (~L267-270). The existing-entry branch returns { ...existing, name: resolvedName } while leaving mountDestination at ${basePath}${uuid}. Because onResolvedNamesChange is guarded by !entry.name, the UI self-corrects but the emitted value can still carry the UUID-based path. Recompute via inputToMountDestination(...) in that branch.
  • Alias inputs desync on external value re-drive (~L133-160). aliasInputs re-seeds only via the selectedIdsKey (id-set) effect and preserves existing ids verbatim. If a controlled parent re-drives value with the same vfolderId set but different mountDestinations (reset/discard, async setFieldsValue), the local alias text goes stale. Reconcile against a destinations digest, re-deriving next[id] when the stored mountDestination no longer matches the local alias (mirrors VFolderTable's aliasMap reconcile).

Parity / contract

  • Missing auto-mount collision check (destinationCounts, ~L193-198). Only within-selection overlap is detected. The legacy VFolderTable this component claims to mirror also rejects collisions with auto-mounted (dotfile) folders (FolderAliasOverlappingToAutoMount). Either accept the auto-mount folder names as a prop and include them in the overlap set, or document the limitation in the JSDoc.
  • Validation contract is advisory-only. The overlap/alias validators are module-private and the emitted VFolderMountConfigValue[] exposes no validity surface, so the JSDoc "wrap in one Form.Item" guidance is misleading (that wrapper gets no rules). Please either export the validators or expose a status / onValidityChange surface, and correct the JSDoc accordingly.

i18n

  • 19 locales were seeded with verbatim English (locale/{ja,th,de,…}.json, 11 keys × 19 = 209 English values). This diverges from the full-translation precedent (FR-3032). Please run fw:i18n before merge, or scope this PR to en + ko and let the translation flow backfill the rest — avoid committing English into non-en files.

UI / layout

  • Remove (✕) button vertical alignment. The row uses align="start", so when the alias column shows its helper text (the resolved /home/work/... path) the row grows taller and the ✕ button sticks to the top instead of lining up with the inputs. Please vertically center the ✕ with the input row (e.g. align it to the input height rather than the full, helper-text-inclusive row height).

    remove button alignment

Nit

  • Use named gap tokens. gap={token.sizeXXS} (L208, L289, L320) should be gap="xxs" to match the BUI convention (the file already mixes both).

@nowgnuesLee nowgnuesLee force-pushed the 06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component branch 2 times, most recently from ce2a9f2 to 3bac8a0 Compare June 25, 2026 05:56

Copy link
Copy Markdown
Contributor Author

Review — actionable items

This is an additive BUI primitive with no consumer wired yet, so none of these block today. Listing what should be fixed before the first consumer wires it in.

Correctness

  • Single source of truth for mountDestination. Display/validation recompute the destination every render (destinationByVFolderId, ~L197-205 / L307-313), but the emitted value uses the stored entry.mountDestination written across four handlers. These can diverge. Please settle on one — emit the recomputed value, or validate the stored one.
  • onChange updates name without recomputing mountDestination (~L267-270). The existing-entry branch returns { ...existing, name: resolvedName } while leaving mountDestination at ${basePath}${uuid}. Because onResolvedNamesChange is guarded by !entry.name, the UI self-corrects but the emitted value can still carry the UUID-based path. Recompute via inputToMountDestination(...) in that branch.
  • Alias inputs desync on external value re-drive (~L133-160). aliasInputs re-seeds only via the selectedIdsKey (id-set) effect and preserves existing ids verbatim. If a controlled parent re-drives value with the same vfolderId set but different mountDestinations (reset/discard, async setFieldsValue), the local alias text goes stale. Reconcile against a destinations digest, re-deriving next[id] when the stored mountDestination no longer matches the local alias (mirrors VFolderTable's aliasMap reconcile).

Parity / contract

  • Missing auto-mount collision check (destinationCounts, ~L193-198). Only within-selection overlap is detected. The legacy VFolderTable this component claims to mirror also rejects collisions with auto-mounted (dotfile) folders (FolderAliasOverlappingToAutoMount). Either accept the auto-mount folder names as a prop and include them in the overlap set, or document the limitation in the JSDoc.
  • Validation contract is advisory-only. The overlap/alias validators are module-private and the emitted VFolderMountConfigValue[] exposes no validity surface, so the JSDoc "wrap in one Form.Item" guidance is misleading (that wrapper gets no rules). Please either export the validators or expose a status / onValidityChange surface, and correct the JSDoc accordingly.

i18n

  • 19 locales were seeded with verbatim English (locale/{ja,th,de,…}.json, 11 keys × 19 = 209 English values). This diverges from the full-translation precedent (FR-3032). Please run fw:i18n before merge, or scope this PR to en + ko and let the translation flow backfill the rest — avoid committing English into non-en files.

UI / layout

  • Remove (✕) button vertical alignment. The row uses align="start", so when the alias column shows its helper text (the resolved /home/work/... path) the row grows taller and the ✕ button sticks to the top instead of lining up with the inputs. Please vertically center the ✕ with the input row (e.g. align it to the input height rather than the full, helper-text-inclusive row height).

    remove button alignment

Nit

  • Use named gap tokens. gap={token.sizeXXS} (L208, L289, L320) should be gap="xxs" to match the BUI convention (the file already mixes both).

​I applied. Thanks!

@nowgnuesLee nowgnuesLee requested a review from agatha197 June 25, 2026 06:03

@agatha197 agatha197 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of consistency nits on the columnLabel header helper — see the inline comment. Both are about reusing the existing shared help-icon component and dropping the hardcoded pixel size.

Comment thread packages/backend.ai-ui/src/components/fragments/BAIVFolderMountConfigInput.tsx Outdated

@agatha197 agatha197 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more nit on the remove-icon size — see inline.

Comment thread packages/backend.ai-ui/src/components/fragments/BAIVFolderMountConfigInput.tsx Outdated
@nowgnuesLee nowgnuesLee force-pushed the 06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component branch from 3bac8a0 to 87d5904 Compare June 26, 2026 04:25
@nowgnuesLee nowgnuesLee requested a review from agatha197 June 26, 2026 04:27
Comment thread packages/backend.ai-ui/src/components/fragments/BAIVFolderMountConfigInput.tsx Outdated
…derSelect

When a parent reduces the selection externally, the optimistic value lagged
behind during the deferred window and briefly re-displayed the removed chip.
Filter the optimistic value to the current value so removed items don't reappear.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nowgnuesLee nowgnuesLee force-pushed the 06-16-feat_fr-3154_add_reusable_baivfoldermountconfiginput_component branch from 87d5904 to 6ab430b Compare June 26, 2026 08:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500~ LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants