Skip to content

feat(FR-2209): scope admin vfolders by project and add project-admin folders page#6654

Open
yomybaby wants to merge 1 commit intomainfrom
04-13-feat_fr-2209_scope_admin_vfolders_by_project_and_allow_folder_creation
Open

feat(FR-2209): scope admin vfolders by project and add project-admin folders page#6654
yomybaby wants to merge 1 commit intomainfrom
04-13-feat_fr-2209_scope_admin_vfolders_by_project_and_allow_folder_creation

Conversation

@yomybaby
Copy link
Copy Markdown
Member

@yomybaby yomybaby commented Apr 13, 2026

Resolves #NNN (FR-2209)

Summary

  • Scope AdminVFolderNodeListPage query by current project when the effective admin role is currentProjectAdmin; superadmins still see all folders.
  • Always filter to ownership_type == "group" so admins never see personal user folders.
  • Allow folder creation from admin mode via FolderCreateModal, locked to the current project (type/group fields hidden, defaulted to project + currentProject.id).
  • Add new project-admin-vfolders page that reuses AdminVFolderNodeListPage under /project-admin-vfolders, registered in PROJECT_ADMIN_PAGE_KEYS so project admins see a dedicated Folders entry in the admin menu.
  • Include admin-session in PROJECT_ADMIN_PAGE_KEYS so project admins can reach the admin Sessions view.
  • Fix a silent bug where effectiveAdminRole === 'projectAdmin' never matched the real enum value (currentProjectAdmin), so scoping was inactive for project admins.
  • Add webui.menu.ProjectFolders i18n key (en, ko).

Test plan

  • Log in as a superadmin: confirm /admin-data still lists folders across all projects; /project-admin-vfolders is not shown in the admin menu.
  • Log in as a project admin (non-super): confirm the admin menu shows Folders (project-admin-vfolders) and Users entries; /project-admin-vfolders lists only folders under the current project; switching the project re-scopes the list.
  • Create a folder from /project-admin-vfolders: confirm the modal hides the type/group fields and the folder is created under the current project.
  • Check translations render (en, ko).

Checklist: (if applicable)

  • Documentation
  • Minimum required manager version
  • Specific setting for review (eg., KB link, endpoint or how to setup)
  • Minimum requirements to check during review
  • Test case(s) to demonstrate the difference of before/after

Copilot AI review requested due to automatic review settings April 13, 2026 14:02
@github-actions github-actions Bot added the size:M 30~100 LoC label Apr 13, 2026
Copy link
Copy Markdown
Member Author

yomybaby commented Apr 13, 2026


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
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 13, 2026

Coverage report for ./react

Caution

An unexpected error occurred. For more details, check console

Error: The process '/usr/bin/git' failed with exit code 128
St.
Category Percentage Covered / Total
🔴 Statements
8.81% (+0.01% 🔼)
1736/19695
🔴 Branches 7.99% 1097/13729
🔴 Functions
5.31% (+0.02% 🔼)
284/5351
🔴 Lines
8.51% (+0.01% 🔼)
1628/19130

Test suite run success

847 tests passing in 38 suites.

Report generated by 🧪jest coverage report action from 2160733

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Admin VFolder list page to scope visible vfolders by the user’s effective admin role (project-scoped for project admins, unscoped for superadmins), hides personal/user-owned folders from the admin view, and adds an admin-side folder creation entrypoint.

Changes:

  • Add scope_id support to the admin vfolder_nodes Relay query and compute scope based on useEffectiveAdminRole() + current project.
  • Pin the admin list to project-owned folders via ownership_type == "group" and remove the ownership-type filter UI control.
  • Add a “Create Folder” button and wire FolderCreateModal to create a project folder for the currently selected project.

Comment on lines +132 to +144
// Determine the `scope_id` to apply to the `vfolder_nodes` query based on the
// user's effective admin role:
// - superadmin: no scope (sees all projects/domains)
// - projectAdmin: scope to the currently selected project
// - domainAdmin: TODO(needs-backend) — requires a `domain:<name>` scope argument
// that the core does not yet accept. For now, fall back to no scope, which
// matches the pre-FR-2556 behavior for domain admins.
// Personal (user-type) folders are always filtered out via `ownership_type == "group"`
// so that admins never see other users' private folders.
const scopeId: string | undefined =
effectiveAdminRole === 'projectAdmin' && currentProject?.id
? `project:${currentProject.id}`
: undefined;
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

For effectiveAdminRole === 'projectAdmin', scopeId falls back to undefined when currentProject.id is missing, which makes the vfolder_nodes query unscoped (potentially showing folders outside the intended project scope). Consider making currentProject.id mandatory in this role (e.g., block rendering/query until available or surface an error) and avoid issuing an unscoped admin query for project admins.

Copilot uses AI. Check for mistakes.
Comment on lines 69 to 85
@@ -75,6 +80,7 @@ const AdminVFolderNodeListPage: React.FC = (props) => {
Array<VFolderNodesType>
>([]);

const [isOpenCreateModal, { toggle: toggleCreateModal }] = useToggle(false);
const [isOpenDeleteModal, { toggle: toggleDeleteModal }] = useToggle(false);
const [isOpenRestoreModal, { toggle: toggleRestoreModal }] = useToggle(false);
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

Now that the admin folder list can be scoped by currentProject (for project admins), selected rows can become stale when the user switches projects. Without clearing selectedFolderList on currentProject.id change, bulk actions (delete/restore) may target folders from a previous project. Add an effect similar to VFolderNodeListPage to reset selection (and optionally pagination) when currentProject.id changes.

Copilot uses AI. Check for mistakes.
Comment on lines +535 to +545
// Admin view creates folders for the currently-scoped project only:
// the type radio group ("User"/"Project") and the project selector
// are hidden so an admin cannot create a personal folder or target a
// different project. The `group` field defaults to
// `currentProject.id` inside `FolderCreateModal`, so simply hiding
// the fields locks the folder to the current project.
initialValues={{
type: 'project',
group: currentProject?.id || undefined,
}}
hiddenFormItems={['type', 'group']}
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

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

initialValues always includes group, even when currentProject?.id is undefined. In FolderCreateModal, mergedInitialValues is {...INITIAL_FORM_VALUES, ...initialValuesFromProps}, so an explicit group: undefined from props overrides the modal's own default group value and can lead to submitting an invalid project folder (especially since the group field is hidden). Consider omitting the group key entirely when there is no currentProject.id, and/or disabling the Create button/modal until a project is selected.

Copilot uses AI. Check for mistakes.
@yomybaby yomybaby force-pushed the 04-13-feat_fr-2209_scope_admin_vfolders_by_project_and_allow_folder_creation branch from 86ff2d3 to 2160733 Compare April 15, 2026 07:45
@yomybaby yomybaby force-pushed the graphite-base/6654 branch from 4181d2d to 28bb644 Compare April 15, 2026 07:45
@yomybaby yomybaby changed the base branch from graphite-base/6654 to main April 15, 2026 07:45
@github-actions github-actions Bot added area:ux UI / UX issue. area:i18n Localization size:L 100~500 LoC and removed size:M 30~100 LoC labels Apr 15, 2026
@yomybaby yomybaby changed the title feat(FR-2209): scope admin vfolders by project and allow project folder creation in admin mode feat(FR-2209): scope admin vfolders by project and add project-admin folders page Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:i18n Localization area:ux UI / UX issue. size:L 100~500 LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants