Skip to content

Commit 23133fe

Browse files
feat(platform-web): hide global agreements from the workspace agreements list (#37)
Global service agreements are managed on the admin surface and remain reachable when attaching to a service or adding a workspace default, so they no longer belong in a workspace's own /app/:slug/service-agreements list. Filter them out in workspace scope (admin surface unchanged), drop the now-constant Scope column, and reword the subtitle.
1 parent 891be4f commit 23133fe

2 files changed

Lines changed: 11 additions & 18 deletions

File tree

apps/platform-web/src/components/console/service-agreements/agreements-list.tsx

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ export function AgreementsList({ scope }: { scope: AgreementScope }) {
2121
// Workspace scope may still be resolving (empty id) → gate the query; global (null) is always ready.
2222
const ready = scope.kind === 'admin' || scope.workspaceId !== '';
2323
const { data: items = [] } = useQuery({ ...agreementsQueryOptions(workspaceId), enabled: ready });
24+
// Workspace scope lists only the workspace's OWN agreements — globals are managed on the admin
25+
// surface and reachable when attaching to a service / adding a default, not here (feature 150). The
26+
// admin surface (global-only) is unfiltered.
27+
const visible = scope.kind === 'admin' ? items : items.filter((item) => !item.isGlobal);
2428

2529
const goNew = () => {
2630
if (scope.kind === 'workspace') {
@@ -36,7 +40,7 @@ export function AgreementsList({ scope }: { scope: AgreementScope }) {
3640
<span className="text-sm text-muted-foreground">
3741
{scope.kind === 'admin'
3842
? 'Global consent documents shared across all workspaces.'
39-
: 'Consent documents in this workspace (plus global ones).'}
43+
: 'Consent documents in this workspace.'}
4044
</span>
4145
<Button size="sm" type="button" disabled={!ready} onClick={goNew}>
4246
<Plus className="size-4" aria-hidden />
@@ -49,18 +53,17 @@ export function AgreementsList({ scope }: { scope: AgreementScope }) {
4953
<TableRow>
5054
<TableHead>Title</TableHead>
5155
<TableHead>Status</TableHead>
52-
<TableHead>Scope</TableHead>
5356
</TableRow>
5457
</TableHeader>
5558
<TableBody>
56-
{items.length === 0 ? (
59+
{visible.length === 0 ? (
5760
<TableRow>
58-
<TableCell colSpan={3} className="py-10 text-center text-muted-foreground">
61+
<TableCell colSpan={2} className="py-10 text-center text-muted-foreground">
5962
No service agreements yet — create one with the New button.
6063
</TableCell>
6164
</TableRow>
6265
) : (
63-
items.map((item: ServiceAgreementSummary) => (
66+
visible.map((item: ServiceAgreementSummary) => (
6467
<TableRow key={item.id}>
6568
<TableCell>
6669
{scope.kind === 'workspace' ? (
@@ -84,13 +87,6 @@ export function AgreementsList({ scope }: { scope: AgreementScope }) {
8487
<TableCell>
8588
<Badge color={STATUS_COLOR[item.status]}>{item.status}</Badge>
8689
</TableCell>
87-
<TableCell>
88-
{item.isGlobal ? (
89-
<Badge color="grey">Global</Badge>
90-
) : (
91-
<span className="text-muted-foreground">Workspace</span>
92-
)}
93-
</TableCell>
9490
</TableRow>
9591
))
9692
)}

apps/platform-web/test/service-agreements-console.test.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,14 @@ function withAgreements(base: ReturnType<typeof mockAuth>) {
6363
}
6464

6565
describe('service agreements console', () => {
66-
it('lists a workspace’s agreements (plus global) with scope badges', async () => {
66+
it('lists a workspace’s OWN agreements only — globals are hidden here (feature 150)', async () => {
6767
withAgreements(mockAuth(authedUser, { workspaces: [riverton] }));
6868
renderApp('/app/riverton/service-agreements');
6969
expect(
7070
await screen.findByRole('link', { name: 'Terms of service' }, { timeout: 8000 }),
7171
).toBeInTheDocument();
72-
// The global agreement is visible too, badged "Global".
73-
expect(
74-
await screen.findByRole('link', { name: 'Privacy policy' }, { timeout: 8000 }),
75-
).toBeInTheDocument();
76-
expect(await screen.findByText('Global', undefined, { timeout: 8000 })).toBeInTheDocument();
72+
// The global agreement is filtered out of the workspace list (still attachable / defaultable).
73+
expect(screen.queryByRole('link', { name: 'Privacy policy' })).not.toBeInTheDocument();
7774
});
7875

7976
it('opens the New agreement modal (title + description) at /new', async () => {

0 commit comments

Comments
 (0)