Skip to content

feat(v3): Spaces index screen#17

Merged
zjean merged 1 commit intomainfrom
feat/v3-spaces
Apr 23, 2026
Merged

feat(v3): Spaces index screen#17
zjean merged 1 commit intomainfrom
feat/v3-spaces

Conversation

@zjean
Copy link
Copy Markdown
Owner

@zjean zjean commented Apr 23, 2026

Summary

PR #2 of 9 in milestone 3. Replaces the `/v2/spaces` placeholder with a real Spaces index table backed by `SpacesService.listSpaces`.

Stacked on #16 — GitHub auto-retargets to `main` when #16 merges.

What's here

  • Toolbar with Refresh / Create space / More icon buttons and a right-aligned ` spaces` count.
  • Sticky column header (Name / Quota / Members / Modified) + row table sorted by `modifiedAt desc`.
  • Rows: indigo-soft box glyph + name + description; quota cell shows `usage / quota` via `ToBytesPipe` (falls back to usage-only when unlimited); members count aggregates users + groups from `SpaceModel.counts`; modified uses a violet pill with `TimeAgoPipe`.
  • Row click opens `/spaces/files/` (classic) so deep-linking into a space works even though the space browser itself isn't v2 yet.
  • Create button routes to classic `/spaces?new=1` so the existing Create Space flow stays reachable.

Scope adjustment

The v2-native Create Space modal was scoped to a follow-up PR to keep this one focused. The plan's §3 note permits this ("Settings tab is the minimum viable scope; Files/Members/Links tabs show their placeholder content … can be filled in follow-up work"). Tracking as `feat/v3-spaces-create-modal` — will open when the rest of milestone 3 has landed enough primitives (form inputs, modal shell) to make it cheap.

Test plan

  • `npm run lint` — clean
  • `npm run build --configuration production` — clean, no budget warnings
  • Reviewer smoke: `/v2/spaces` lists real spaces; loading/empty/error states render; Refresh re-fetches; Create button navigates to classic.

🤖 Generated with Claude Code

@zjean zjean mentioned this pull request Apr 23, 2026
3 tasks
Base automatically changed from feat/v3-browser-grid-gallery to main April 23, 2026 07:22
Replaces the /v2/spaces placeholder with a real spaces index table,
matching the handoff bundle's spaces.jsx.

- Toolbar: Refresh / Create space / More icon buttons + right-aligned
  "<n> spaces" count.
- Sticky column header (Name / Quota / Members / Modified) + row table
  sorted by modifiedAt desc.
- Rows: indigo-soft box glyph + space name + description; quota cell
  shows usage/quota via ToBytesPipe (falls back to usage-only when
  unlimited); members count aggregates users + groups from SpaceModel
  counts; modified uses a violet pill with TimeAgoPipe.
- Click opens /spaces/files/<alias> (classic) so deep-linking into a
  space works even though the browser itself isn't v2 yet.
- Create button routes to /spaces?new=1 so the existing classic Create
  Space flow is available end-to-end. The v2-native Create Space modal
  is scoped to a follow-up PR to keep this one tight.

Loading / empty / error states rendered inline, no invented data.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@zjean zjean merged commit c0ff653 into main Apr 23, 2026
1 check passed
@zjean zjean deleted the feat/v3-spaces branch April 23, 2026 08:00
zjean added a commit that referenced this pull request Apr 23, 2026
## Summary

PR #3 of 9 in [milestone
3](../blob/main/docs/plans/2026-04-23-v3-ui-redesign-milestone3.md).
Replaces the three \`/v2/shared/*\` placeholders with a single
parameterized \`SharedComponent\` wired to \`SharesService.listShares\`.

**Stacked on [#17](../pull/17) — chain: \`feat/v3-shared\` →
\`feat/v3-spaces\` → \`feat/v3-browser-grid-gallery\` → \`main\`.
Auto-retargets as ancestors merge.**

## What's here

- Hero: \"Shared\" eyebrow + variant-specific h1 (\`With me\` / \`With
others\` / \`Via links\`) matching the design's editorial headers.
- Table columns: Name (FileGlyph via \`mimeToGlyph\` + title +
description) · Recipients (\`N users · M links\`) · Modified
(\`amTimeAgo\`) · row-more.
- **Variant filters** against the full shares list:
- \`with-me\` → shares where \`parent\` is set (you're a child-share
recipient)
- \`with-others\` → shares where \`parent\` is null (you own the share)
  - \`via-links\` → shares with at least one link
The backend doesn't split these into three endpoints; client-side
filtering keeps the service surface unchanged.
- Row click opens \`/spaces/shares/<alias>\` (classic) for m3; v2 shares
browser is a future PR.
- Breadcrumbs push \`Shared\` → variant label so the TitleBar reflects
the sub-view.

## Test plan

- [x] \`npm run lint\` — clean
- [x] \`npm run build --configuration production\` — clean, no budget
warnings
- [ ] Reviewer smoke: each of the three left-nav sub-items under Shared
loads the right title, the right filtered subset, and navigates into a
share on row click.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
zjean added a commit that referenced this pull request Apr 23, 2026
## Summary

PR #4 of 9 in [milestone
3](../blob/main/docs/plans/2026-04-23-v3-ui-redesign-milestone3.md).
Replaces the \`/v2/trash\` placeholder with a trash-bin list wired to
\`SpacesService.listTrashBins\`.

**Stacked on [#18](../pull/18) — chain through #17, #16 to \`main\`.**

## What's here

- Toolbar: \"Trash\" title + monoline summary (\`<total> items across
<bins> bins\`) + Restore / Empty trash buttons (both disabled for m3 —
per-item operations land with the v2 trash file-list) + Refresh.
- Columns: Space · Items · Last deletion · \`chevRight\` drill-in.
- Rose-soft glyph block; rows dim to \`opacity: 0.85\` to signal trashed
content, full opacity on hover.
- Click opens \`/spaces/trash/<alias>\` (classic) so users can actually
manage trashed files end-to-end today; the inline Restore / Empty ops
are a follow-up PR.

Also drops the now-unused \`placeholder()\` helper from \`v2.routes.ts\`
since every left-nav destination has a real component.
\`PlaceholderComponent\` stays co-located for remaining milestone-3
AppRail screens (Search / Settings / People) to reuse.

## Test plan

- [x] \`npm run lint\` — clean
- [x] \`npm run build --configuration production\` — clean, no budget
warnings
- [ ] Reviewer smoke: \`/v2/trash\` loads bin list with per-space trash
counts; clicking a row drills into the classic trash browser.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
zjean added a commit that referenced this pull request Apr 23, 2026
Closes the deferred follow-up flagged in [PR #17](../pull/17): replaces
the route-to-classic Create button on `/v2/spaces` with a v2-native
modal. Settings tab is fully functional; Files / Members / Links tabs
are placeholders per [milestone-3 plan
§3](../blob/main/docs/plans/2026-04-23-v3-ui-redesign-milestone3.md)
("Settings tab is the minimum viable scope").

With this merge, milestone 3 is feature-complete in spirit (every screen
in §1 of the plan now has a real v2 implementation, and the §3 deferral
is resolved).

## What's here

- New `create-space-modal.component.{ts,html,scss}` (~600 LOC) —
backdrop overlay, four tabs (Settings / Files / Members / Links), header
+ footer chrome, Esc + outside-click dismissal (same pattern as
`transfers-popover.component.ts`).
- **Settings tab**: name (required, 120 char max), description
(optional, 240 char max), storage quota in MB (optional, converted to
bytes for the DTO), manager picker (debounced 220 ms search via
`UserService.searchMembers({ onlyUsers: true, ignoreUserIds })` with a
results dropdown and removable chips above).
- **Submit**: Builds a `CreateOrUpdateSpaceDto` with `managers:
SpaceMemberDto[]` (each `{ id, type: MEMBER_TYPE.USER }`) and calls
`SpacesService.createSpace`. On success, parent refreshes the space list
and the modal resets + closes. On error, server message surfaces inline
above the footer.
- **Submit gating**: disabled until `name.trim() !== ''` &&
`managers.length > 0` && not currently submitting. Cancel + Esc +
backdrop click are blocked while submitting.
- `spaces.component.{ts,html}` — `createSpace()` now toggles a
`createOpen` signal; `<app-v2-create-space-modal>` mounted at the bottom
of the screen; `(created)` triggers `refresh()`.
- Files / Members / Links tabs render placeholder cards (icon + title +
lede) consistent with the editorial tone of the rest of the v2 chrome.

## Out of scope

- Editing managers and members beyond initial managers — handled by the
existing per-space settings flow in classic.
- Files / Members / Links tabs as functional surfaces — left as the
explicit "follow-up work if needed" the plan permits.

## Test plan

- [x] `npm run lint` — clean
- [x] `npm run build --configuration production` — clean, no budget
warnings (modal SCSS is comfortably under the 8 kB per-component budget)
- [ ] Reviewer smoke:
  - Click `+` on `/v2/spaces` → modal opens, name input auto-focused.
- Type a query in the manager search → results render in dropdown; click
adds a chip; chip × removes; the same user no longer appears in
subsequent search results.
  - Submit disabled until both name and at least one manager are set.
- Create with valid input → list refreshes, new space appears, modal
closes.
- Server validation error (e.g. duplicate name) surfaces inline; modal
stays open.
  - Esc and backdrop click dismiss; both blocked during submit.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant