@meetreeve/module-team 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -2
- package/dist/client/index.d.mts +141 -0
- package/dist/client/index.d.ts +141 -0
- package/dist/client/index.js +100 -0
- package/dist/client/index.mjs +74 -0
- package/dist/config/index.d.mts +159 -0
- package/dist/config/index.d.ts +159 -0
- package/dist/config/index.js +770 -0
- package/dist/config/index.mjs +744 -0
- package/dist/index.d.mts +141 -0
- package/dist/index.d.ts +141 -0
- package/dist/index.js +102 -0
- package/dist/index.mjs +74 -0
- package/package.json +70 -4
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Roles the org-members router knows. `billing_manager` is a legacy alias
|
|
6
|
+
* the backend still accepts; no surface offers it from the invite dialog.
|
|
7
|
+
* Rows may still carry a role this union doesn't name, so row fields are
|
|
8
|
+
* typed `string` and the panel renders unknown roles verbatim.
|
|
9
|
+
*/
|
|
10
|
+
type TeamRole = "owner" | "admin" | "billing_manager" | "member" | "viewer";
|
|
11
|
+
/** A role the invite dialog and the role picker can hand out (never `owner`). */
|
|
12
|
+
type AssignableRole = Exclude<TeamRole, "owner" | "billing_manager">;
|
|
13
|
+
/** One live member of the org (`OrganizationMember` row). `GET /api/org/members`. */
|
|
14
|
+
interface TeamMember {
|
|
15
|
+
/** OrganizationMember.id — the id every member route takes. */
|
|
16
|
+
id: string;
|
|
17
|
+
user_id: string;
|
|
18
|
+
email: string | null;
|
|
19
|
+
role: string;
|
|
20
|
+
is_default: boolean;
|
|
21
|
+
/** ISO-8601. */
|
|
22
|
+
created_at: string;
|
|
23
|
+
}
|
|
24
|
+
/** One invitation record. `GET /api/org/invitations`. */
|
|
25
|
+
interface Invitation {
|
|
26
|
+
id: string;
|
|
27
|
+
email: string;
|
|
28
|
+
role: string;
|
|
29
|
+
invited_by_email: string | null;
|
|
30
|
+
/** pending | accepted | expired | revoked */
|
|
31
|
+
status: string;
|
|
32
|
+
/** ISO-8601. */
|
|
33
|
+
created_at: string;
|
|
34
|
+
/** ISO-8601. */
|
|
35
|
+
expires_at: string;
|
|
36
|
+
accepted_at: string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Spaces the invitee joins on accept (DEV-15988 / reeve-services DEV-15559).
|
|
39
|
+
* The backend always sends it; optional so a backend that predates it
|
|
40
|
+
* still type-checks as "no pre-set spaces".
|
|
41
|
+
*/
|
|
42
|
+
spaces?: InvitationSpace[];
|
|
43
|
+
}
|
|
44
|
+
/** A space role. */
|
|
45
|
+
type SpaceRole = "member" | "admin";
|
|
46
|
+
/** One pre-set space on an invitation (`GET /api/org/invitations` item). */
|
|
47
|
+
interface InvitationSpace {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
role: SpaceRole;
|
|
51
|
+
}
|
|
52
|
+
/** One space an invite (or a pending invitation) should land the invitee in. */
|
|
53
|
+
interface InviteSpace {
|
|
54
|
+
space_id: string;
|
|
55
|
+
role: SpaceRole;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* One of the org's spaces, as the invite dialog's Spaces picker lists it
|
|
59
|
+
* (reeve-frontend maps `GET /api/org/rbac/spaces` onto this). Every space is
|
|
60
|
+
* offered, the default one included: nobody joins a space automatically
|
|
61
|
+
* (DEV-16808). `can_manage: false` rows are shown disabled.
|
|
62
|
+
*/
|
|
63
|
+
interface SpaceOption {
|
|
64
|
+
id: string;
|
|
65
|
+
name: string;
|
|
66
|
+
kind?: string;
|
|
67
|
+
is_default: boolean;
|
|
68
|
+
can_manage: boolean;
|
|
69
|
+
}
|
|
70
|
+
/** `POST /api/org/invite`. */
|
|
71
|
+
interface InviteMemberResponse {
|
|
72
|
+
message: string;
|
|
73
|
+
email: string;
|
|
74
|
+
role: string;
|
|
75
|
+
invitation_id?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The data-access boundary the panel is built against. Every method takes
|
|
79
|
+
* the org it acts on: there is no ambient "current org" anywhere in this
|
|
80
|
+
* package, so a request can never be issued for an org other than the one
|
|
81
|
+
* the caller named (DEV-8592). `createTeamClient` is the reference
|
|
82
|
+
* implementation; a host may supply its own.
|
|
83
|
+
*/
|
|
84
|
+
interface TeamClient {
|
|
85
|
+
listMembers(orgId: string): Promise<TeamMember[]>;
|
|
86
|
+
updateMemberRole(orgId: string, memberId: string, role: string): Promise<void>;
|
|
87
|
+
removeMember(orgId: string, memberId: string): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* `spaces` goes in the body whenever it is passed, `[]` included (a
|
|
90
|
+
* one-space org sends `[]`, DEV-16808); omitted keeps the pre-DEV-15988
|
|
91
|
+
* request.
|
|
92
|
+
*/
|
|
93
|
+
inviteMember(orgId: string, email: string, role: string, spaces?: InviteSpace[]): Promise<InviteMemberResponse>;
|
|
94
|
+
listInvitations(orgId: string): Promise<Invitation[]>;
|
|
95
|
+
revokeInvitation(orgId: string, invitationId: string): Promise<void>;
|
|
96
|
+
resendInvitation(orgId: string, invitationId: string): Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
type TeamNotice = {
|
|
100
|
+
kind: "success" | "error";
|
|
101
|
+
message: string;
|
|
102
|
+
};
|
|
103
|
+
/** What `renderInvitationActions` gets besides the invitation. */
|
|
104
|
+
interface InvitationActionHelpers {
|
|
105
|
+
/** Refetch members and invitations, as Resend does after it lands. */
|
|
106
|
+
reload: () => Promise<void>;
|
|
107
|
+
}
|
|
108
|
+
interface TeamMembersPanelProps {
|
|
109
|
+
/**
|
|
110
|
+
* Data access. `createTeamClient({ fetch })` from `@meetreeve/module-team/client`.
|
|
111
|
+
* Pass a stable instance (module scope or `useMemo`): a new client refetches.
|
|
112
|
+
*/
|
|
113
|
+
client: TeamClient;
|
|
114
|
+
/**
|
|
115
|
+
* The org whose team this panel shows. Required: every request is issued
|
|
116
|
+
* for this org, and changing it resets the panel (DEV-8592).
|
|
117
|
+
*/
|
|
118
|
+
orgId: string;
|
|
119
|
+
/**
|
|
120
|
+
* Roles the invite dialog AND the per-member role picker offer, in order.
|
|
121
|
+
* Default admin/member/viewer. The operator cockpit (DEV-2439) passes
|
|
122
|
+
* `["admin", "member"]`.
|
|
123
|
+
*/
|
|
124
|
+
inviteRoles?: AssignableRole[];
|
|
125
|
+
/**
|
|
126
|
+
* The signed-in user's email: marks their row "you", and that row's role
|
|
127
|
+
* decides which role changes the picker offers (DEV-18190). Without it, or
|
|
128
|
+
* when no member matches, every role shows as a plain label.
|
|
129
|
+
*/
|
|
130
|
+
currentUserEmail?: string | null;
|
|
131
|
+
/**
|
|
132
|
+
* Host-owned per-member controls (Studio's Budget / Capabilities dialogs).
|
|
133
|
+
* Rendered at the end of every member row, owners included; the host
|
|
134
|
+
* decides per member what to show.
|
|
135
|
+
*/
|
|
136
|
+
renderMemberActions?: (member: TeamMember) => ReactNode;
|
|
137
|
+
/**
|
|
138
|
+
* Host-owned per-invitation controls, rendered next to Resend / Revoke on
|
|
139
|
+
* every pending invitation. Call `reload` after a change the row shows.
|
|
140
|
+
*/
|
|
141
|
+
renderInvitationActions?: (invitation: Invitation, helpers: InvitationActionHelpers) => ReactNode;
|
|
142
|
+
/**
|
|
143
|
+
* The org's spaces for the invite dialog's Spaces picker. When omitted the
|
|
144
|
+
* dialog has no picker and invites go out exactly as before. Called each
|
|
145
|
+
* time the dialog opens; until it answers, the invite is held, since an org
|
|
146
|
+
* with several spaces refuses an invite that names none (422
|
|
147
|
+
* `spaces_required`).
|
|
148
|
+
*/
|
|
149
|
+
loadSpaceOptions?: () => Promise<SpaceOption[]>;
|
|
150
|
+
/** Called with every success/error notice the panel shows inline. */
|
|
151
|
+
onNotice?: (notice: TeamNotice) => void;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Keyed on `orgId`: an org change remounts the body, which is what resets
|
|
155
|
+
* every piece of per-org state at once — no reset effect to forget.
|
|
156
|
+
*/
|
|
157
|
+
declare function TeamMembersPanel(props: TeamMembersPanelProps): react.JSX.Element;
|
|
158
|
+
|
|
159
|
+
export { type AssignableRole, type Invitation, type InvitationActionHelpers, type InvitationSpace, type InviteMemberResponse, type InviteSpace, type SpaceOption, type SpaceRole, type TeamClient, type TeamMember, TeamMembersPanel, type TeamMembersPanelProps, type TeamNotice, type TeamRole };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Roles the org-members router knows. `billing_manager` is a legacy alias
|
|
6
|
+
* the backend still accepts; no surface offers it from the invite dialog.
|
|
7
|
+
* Rows may still carry a role this union doesn't name, so row fields are
|
|
8
|
+
* typed `string` and the panel renders unknown roles verbatim.
|
|
9
|
+
*/
|
|
10
|
+
type TeamRole = "owner" | "admin" | "billing_manager" | "member" | "viewer";
|
|
11
|
+
/** A role the invite dialog and the role picker can hand out (never `owner`). */
|
|
12
|
+
type AssignableRole = Exclude<TeamRole, "owner" | "billing_manager">;
|
|
13
|
+
/** One live member of the org (`OrganizationMember` row). `GET /api/org/members`. */
|
|
14
|
+
interface TeamMember {
|
|
15
|
+
/** OrganizationMember.id — the id every member route takes. */
|
|
16
|
+
id: string;
|
|
17
|
+
user_id: string;
|
|
18
|
+
email: string | null;
|
|
19
|
+
role: string;
|
|
20
|
+
is_default: boolean;
|
|
21
|
+
/** ISO-8601. */
|
|
22
|
+
created_at: string;
|
|
23
|
+
}
|
|
24
|
+
/** One invitation record. `GET /api/org/invitations`. */
|
|
25
|
+
interface Invitation {
|
|
26
|
+
id: string;
|
|
27
|
+
email: string;
|
|
28
|
+
role: string;
|
|
29
|
+
invited_by_email: string | null;
|
|
30
|
+
/** pending | accepted | expired | revoked */
|
|
31
|
+
status: string;
|
|
32
|
+
/** ISO-8601. */
|
|
33
|
+
created_at: string;
|
|
34
|
+
/** ISO-8601. */
|
|
35
|
+
expires_at: string;
|
|
36
|
+
accepted_at: string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Spaces the invitee joins on accept (DEV-15988 / reeve-services DEV-15559).
|
|
39
|
+
* The backend always sends it; optional so a backend that predates it
|
|
40
|
+
* still type-checks as "no pre-set spaces".
|
|
41
|
+
*/
|
|
42
|
+
spaces?: InvitationSpace[];
|
|
43
|
+
}
|
|
44
|
+
/** A space role. */
|
|
45
|
+
type SpaceRole = "member" | "admin";
|
|
46
|
+
/** One pre-set space on an invitation (`GET /api/org/invitations` item). */
|
|
47
|
+
interface InvitationSpace {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
role: SpaceRole;
|
|
51
|
+
}
|
|
52
|
+
/** One space an invite (or a pending invitation) should land the invitee in. */
|
|
53
|
+
interface InviteSpace {
|
|
54
|
+
space_id: string;
|
|
55
|
+
role: SpaceRole;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* One of the org's spaces, as the invite dialog's Spaces picker lists it
|
|
59
|
+
* (reeve-frontend maps `GET /api/org/rbac/spaces` onto this). Every space is
|
|
60
|
+
* offered, the default one included: nobody joins a space automatically
|
|
61
|
+
* (DEV-16808). `can_manage: false` rows are shown disabled.
|
|
62
|
+
*/
|
|
63
|
+
interface SpaceOption {
|
|
64
|
+
id: string;
|
|
65
|
+
name: string;
|
|
66
|
+
kind?: string;
|
|
67
|
+
is_default: boolean;
|
|
68
|
+
can_manage: boolean;
|
|
69
|
+
}
|
|
70
|
+
/** `POST /api/org/invite`. */
|
|
71
|
+
interface InviteMemberResponse {
|
|
72
|
+
message: string;
|
|
73
|
+
email: string;
|
|
74
|
+
role: string;
|
|
75
|
+
invitation_id?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The data-access boundary the panel is built against. Every method takes
|
|
79
|
+
* the org it acts on: there is no ambient "current org" anywhere in this
|
|
80
|
+
* package, so a request can never be issued for an org other than the one
|
|
81
|
+
* the caller named (DEV-8592). `createTeamClient` is the reference
|
|
82
|
+
* implementation; a host may supply its own.
|
|
83
|
+
*/
|
|
84
|
+
interface TeamClient {
|
|
85
|
+
listMembers(orgId: string): Promise<TeamMember[]>;
|
|
86
|
+
updateMemberRole(orgId: string, memberId: string, role: string): Promise<void>;
|
|
87
|
+
removeMember(orgId: string, memberId: string): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* `spaces` goes in the body whenever it is passed, `[]` included (a
|
|
90
|
+
* one-space org sends `[]`, DEV-16808); omitted keeps the pre-DEV-15988
|
|
91
|
+
* request.
|
|
92
|
+
*/
|
|
93
|
+
inviteMember(orgId: string, email: string, role: string, spaces?: InviteSpace[]): Promise<InviteMemberResponse>;
|
|
94
|
+
listInvitations(orgId: string): Promise<Invitation[]>;
|
|
95
|
+
revokeInvitation(orgId: string, invitationId: string): Promise<void>;
|
|
96
|
+
resendInvitation(orgId: string, invitationId: string): Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
type TeamNotice = {
|
|
100
|
+
kind: "success" | "error";
|
|
101
|
+
message: string;
|
|
102
|
+
};
|
|
103
|
+
/** What `renderInvitationActions` gets besides the invitation. */
|
|
104
|
+
interface InvitationActionHelpers {
|
|
105
|
+
/** Refetch members and invitations, as Resend does after it lands. */
|
|
106
|
+
reload: () => Promise<void>;
|
|
107
|
+
}
|
|
108
|
+
interface TeamMembersPanelProps {
|
|
109
|
+
/**
|
|
110
|
+
* Data access. `createTeamClient({ fetch })` from `@meetreeve/module-team/client`.
|
|
111
|
+
* Pass a stable instance (module scope or `useMemo`): a new client refetches.
|
|
112
|
+
*/
|
|
113
|
+
client: TeamClient;
|
|
114
|
+
/**
|
|
115
|
+
* The org whose team this panel shows. Required: every request is issued
|
|
116
|
+
* for this org, and changing it resets the panel (DEV-8592).
|
|
117
|
+
*/
|
|
118
|
+
orgId: string;
|
|
119
|
+
/**
|
|
120
|
+
* Roles the invite dialog AND the per-member role picker offer, in order.
|
|
121
|
+
* Default admin/member/viewer. The operator cockpit (DEV-2439) passes
|
|
122
|
+
* `["admin", "member"]`.
|
|
123
|
+
*/
|
|
124
|
+
inviteRoles?: AssignableRole[];
|
|
125
|
+
/**
|
|
126
|
+
* The signed-in user's email: marks their row "you", and that row's role
|
|
127
|
+
* decides which role changes the picker offers (DEV-18190). Without it, or
|
|
128
|
+
* when no member matches, every role shows as a plain label.
|
|
129
|
+
*/
|
|
130
|
+
currentUserEmail?: string | null;
|
|
131
|
+
/**
|
|
132
|
+
* Host-owned per-member controls (Studio's Budget / Capabilities dialogs).
|
|
133
|
+
* Rendered at the end of every member row, owners included; the host
|
|
134
|
+
* decides per member what to show.
|
|
135
|
+
*/
|
|
136
|
+
renderMemberActions?: (member: TeamMember) => ReactNode;
|
|
137
|
+
/**
|
|
138
|
+
* Host-owned per-invitation controls, rendered next to Resend / Revoke on
|
|
139
|
+
* every pending invitation. Call `reload` after a change the row shows.
|
|
140
|
+
*/
|
|
141
|
+
renderInvitationActions?: (invitation: Invitation, helpers: InvitationActionHelpers) => ReactNode;
|
|
142
|
+
/**
|
|
143
|
+
* The org's spaces for the invite dialog's Spaces picker. When omitted the
|
|
144
|
+
* dialog has no picker and invites go out exactly as before. Called each
|
|
145
|
+
* time the dialog opens; until it answers, the invite is held, since an org
|
|
146
|
+
* with several spaces refuses an invite that names none (422
|
|
147
|
+
* `spaces_required`).
|
|
148
|
+
*/
|
|
149
|
+
loadSpaceOptions?: () => Promise<SpaceOption[]>;
|
|
150
|
+
/** Called with every success/error notice the panel shows inline. */
|
|
151
|
+
onNotice?: (notice: TeamNotice) => void;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Keyed on `orgId`: an org change remounts the body, which is what resets
|
|
155
|
+
* every piece of per-org state at once — no reset effect to forget.
|
|
156
|
+
*/
|
|
157
|
+
declare function TeamMembersPanel(props: TeamMembersPanelProps): react.JSX.Element;
|
|
158
|
+
|
|
159
|
+
export { type AssignableRole, type Invitation, type InvitationActionHelpers, type InvitationSpace, type InviteMemberResponse, type InviteSpace, type SpaceOption, type SpaceRole, type TeamClient, type TeamMember, TeamMembersPanel, type TeamMembersPanelProps, type TeamNotice, type TeamRole };
|