@peers-app/peers-ui 0.25.2 → 0.25.4
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 +2 -1
- package/dist/components/markdown-editor/mention-node.d.ts +4 -0
- package/dist/components/markdown-editor/mention-node.js +4 -1
- package/dist/components/responsive-section-nav.d.ts +34 -0
- package/dist/components/responsive-section-nav.js +19 -0
- package/dist/components/responsive-section-nav.test.d.ts +1 -0
- package/dist/components/responsive-section-nav.test.js +45 -0
- package/dist/components/router.d.ts +2 -3
- package/dist/components/router.js +6 -9
- package/dist/globals-hash.test.d.ts +1 -0
- package/dist/globals-hash.test.js +16 -0
- package/dist/globals.d.ts +19 -0
- package/dist/globals.js +51 -12
- package/dist/hooks/use-host-contract.d.ts +18 -0
- package/dist/hooks/use-host-contract.js +53 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/peers-services-registration.d.ts +1 -5
- package/dist/peers-services-registration.js +6 -16
- package/dist/root-layout/root-layout-host.js +7 -4
- package/dist/root-layout/root-layout-host.test.js +3 -6
- package/dist/screens/account/account-screen.d.ts +1 -0
- package/dist/screens/account/account-screen.js +29 -53
- package/dist/screens/account/account-screen.test.d.ts +1 -0
- package/dist/screens/account/account-screen.test.js +47 -0
- package/dist/screens/contacts/contact-details.js +2 -23
- package/dist/screens/contacts/contact-list.d.ts +24 -1
- package/dist/screens/contacts/contact-list.js +128 -143
- package/dist/screens/contacts/contact-list.test.d.ts +1 -0
- package/dist/screens/contacts/contact-list.test.js +48 -0
- package/dist/screens/contacts/index.d.ts +0 -2
- package/dist/screens/contacts/index.js +0 -3
- package/dist/screens/device-pairing/device-pairing.js +17 -16
- package/dist/screens/device-pairing/device-pairing.test.js +4 -9
- package/dist/screens/device-pairing/identity-ipc.d.ts +11 -0
- package/dist/screens/device-pairing/identity-ipc.js +20 -0
- package/dist/screens/device-pairing/use-device-pairing-state.d.ts +2 -2
- package/dist/screens/device-pairing/use-device-pairing-state.js +7 -25
- package/dist/screens/devices/devices-list.d.ts +18 -0
- package/dist/screens/devices/devices-list.js +173 -0
- package/dist/screens/devices/devices-list.test.d.ts +1 -0
- package/dist/screens/devices/devices-list.test.js +53 -0
- package/dist/screens/devices/index.d.ts +1 -0
- package/dist/screens/devices/index.js +5 -0
- package/dist/screens/groups/group-details.d.ts +1 -0
- package/dist/screens/groups/group-details.js +4 -63
- package/dist/screens/groups/group-invite-panel.js +2 -2
- package/dist/screens/groups/group-list.d.ts +18 -1
- package/dist/screens/groups/group-list.js +107 -136
- package/dist/screens/groups/group-list.test.d.ts +1 -0
- package/dist/screens/groups/group-list.test.js +38 -0
- package/dist/screens/groups/group-members.d.ts +1 -0
- package/dist/screens/groups/group-members.js +2 -1
- package/dist/screens/groups/index.d.ts +0 -3
- package/dist/screens/groups/index.js +0 -4
- package/dist/screens/identity/identity-routes.d.ts +107 -0
- package/dist/screens/identity/identity-routes.js +245 -0
- package/dist/screens/identity/identity-routes.test.d.ts +1 -0
- package/dist/screens/identity/identity-routes.test.js +51 -0
- package/dist/screens/identity/identity-screen.d.ts +9 -0
- package/dist/screens/identity/identity-screen.js +143 -0
- package/dist/screens/identity/identity-screen.test.d.ts +1 -0
- package/dist/screens/identity/identity-screen.test.js +103 -0
- package/dist/screens/identity/index.d.ts +2 -0
- package/dist/screens/identity/index.js +6 -0
- package/dist/screens/identity/invite-contact-panel.d.ts +4 -0
- package/dist/screens/identity/invite-contact-panel.js +30 -0
- package/dist/screens/identity/profile-invite.d.ts +7 -0
- package/dist/screens/identity/profile-invite.js +62 -0
- package/dist/screens/invites/accept-invite.js +44 -2
- package/dist/screens/invites/accept-invite.test.d.ts +1 -0
- package/dist/screens/invites/accept-invite.test.js +103 -0
- package/dist/screens/invites/activity-view.d.ts +24 -0
- package/dist/screens/invites/activity-view.js +64 -0
- package/dist/screens/invites/activity-view.test.d.ts +1 -0
- package/dist/screens/invites/activity-view.test.js +108 -0
- package/dist/screens/invites/index.d.ts +1 -2
- package/dist/screens/invites/index.js +1 -3
- package/dist/screens/invites/invite-capture.d.ts +0 -2
- package/dist/screens/invites/invite-capture.js +1 -3
- package/dist/screens/invites/invite-classify.test.d.ts +1 -0
- package/dist/screens/invites/invite-classify.test.js +115 -0
- package/dist/screens/invites/invites-ipc.d.ts +1 -1
- package/dist/screens/invites/invites-ipc.js +5 -45
- package/dist/screens/invites/pending-invites-list.d.ts +35 -16
- package/dist/screens/invites/pending-invites-list.js +75 -30
- package/dist/screens/network-viewer/network-viewer-ipc.js +4 -59
- package/dist/screens/search/global-search.d.ts +1 -0
- package/dist/screens/search/global-search.js +2 -1
- package/dist/screens/settings/settings-page.js +25 -58
- package/dist/screens/setup-user.js +5 -5
- package/dist/screens/tools/tool-access-ipc.d.ts +2 -0
- package/dist/screens/tools/tool-access-ipc.js +8 -55
- package/dist/screens/welcome-modal.js +3 -2
- package/dist/system-apps/identity.app.d.ts +3 -0
- package/dist/system-apps/identity.app.js +10 -0
- package/dist/system-apps/index.d.ts +1 -4
- package/dist/system-apps/index.js +5 -17
- package/dist/tabs-layout/network-status-indicator.js +10 -3
- package/dist/tabs-layout/network-status-indicator.test.js +15 -0
- package/dist/tabs-layout/tabs-layout.js +3 -1
- package/dist/tabs-layout/tabs-state.d.ts +79 -1
- package/dist/tabs-layout/tabs-state.js +256 -79
- package/dist/tabs-layout/tabs-state.test.d.ts +1 -0
- package/dist/tabs-layout/tabs-state.test.js +110 -0
- package/package.json +3 -3
- package/src/components/markdown-editor/mention-node.ts +5 -1
- package/src/components/responsive-section-nav.test.tsx +88 -0
- package/src/components/responsive-section-nav.tsx +92 -0
- package/src/components/router.tsx +6 -9
- package/src/globals-hash.test.ts +19 -0
- package/src/globals.tsx +53 -13
- package/src/hooks/use-host-contract.ts +75 -0
- package/src/index.tsx +1 -0
- package/src/peers-services-registration.ts +6 -17
- package/src/root-layout/root-layout-host.test.tsx +4 -7
- package/src/root-layout/root-layout-host.tsx +9 -11
- package/src/screens/account/account-screen.test.tsx +61 -0
- package/src/screens/account/account-screen.tsx +116 -95
- package/src/screens/contacts/contact-details.tsx +4 -26
- package/src/screens/contacts/contact-list.test.tsx +59 -0
- package/src/screens/contacts/contact-list.tsx +246 -260
- package/src/screens/contacts/index.ts +0 -4
- package/src/screens/device-pairing/device-pairing.test.tsx +7 -9
- package/src/screens/device-pairing/device-pairing.tsx +19 -23
- package/src/screens/device-pairing/identity-ipc.ts +25 -0
- package/src/screens/device-pairing/use-device-pairing-state.ts +10 -33
- package/src/screens/devices/devices-list.test.tsx +68 -0
- package/src/screens/devices/devices-list.tsx +361 -0
- package/src/screens/devices/index.ts +1 -0
- package/src/screens/groups/group-details.tsx +8 -142
- package/src/screens/groups/group-invite-panel.tsx +2 -7
- package/src/screens/groups/group-list.test.tsx +44 -0
- package/src/screens/groups/group-list.tsx +227 -288
- package/src/screens/groups/group-members.tsx +3 -2
- package/src/screens/groups/index.ts +0 -5
- package/src/screens/identity/identity-routes.test.ts +70 -0
- package/src/screens/identity/identity-routes.ts +301 -0
- package/src/screens/identity/identity-screen.test.tsx +138 -0
- package/src/screens/identity/identity-screen.tsx +282 -0
- package/src/screens/identity/index.ts +2 -0
- package/src/screens/identity/invite-contact-panel.tsx +45 -0
- package/src/screens/identity/profile-invite.tsx +93 -0
- package/src/screens/invites/accept-invite.test.tsx +115 -0
- package/src/screens/invites/accept-invite.tsx +50 -3
- package/src/screens/invites/activity-view.test.tsx +127 -0
- package/src/screens/invites/activity-view.tsx +162 -0
- package/src/screens/invites/index.ts +1 -4
- package/src/screens/invites/invite-capture.ts +0 -3
- package/src/screens/invites/invite-classify.test.ts +129 -0
- package/src/screens/invites/invites-ipc.ts +6 -55
- package/src/screens/invites/pending-invites-list.tsx +94 -62
- package/src/screens/network-viewer/network-viewer-ipc.ts +8 -82
- package/src/screens/search/global-search.tsx +2 -1
- package/src/screens/settings/settings-page.tsx +53 -126
- package/src/screens/setup-user.tsx +5 -6
- package/src/screens/tools/tool-access-ipc.ts +13 -74
- package/src/screens/welcome-modal.tsx +3 -3
- package/src/system-apps/identity.app.ts +9 -0
- package/src/system-apps/index.ts +3 -12
- package/src/tabs-layout/network-status-indicator.test.tsx +22 -0
- package/src/tabs-layout/network-status-indicator.tsx +31 -0
- package/src/tabs-layout/tabs-layout.tsx +7 -1
- package/src/tabs-layout/tabs-state.test.ts +152 -0
- package/src/tabs-layout/tabs-state.ts +300 -83
- package/dist/screens/invites/invites-screen.d.ts +0 -9
- package/dist/screens/invites/invites-screen.js +0 -36
- package/dist/system-apps/account.app.d.ts +0 -2
- package/dist/system-apps/account.app.js +0 -8
- package/dist/system-apps/contacts.app.d.ts +0 -2
- package/dist/system-apps/contacts.app.js +0 -9
- package/dist/system-apps/groups.app.d.ts +0 -2
- package/dist/system-apps/groups.app.js +0 -9
- package/dist/system-apps/invites.app.d.ts +0 -2
- package/dist/system-apps/invites.app.js +0 -9
- package/src/screens/invites/invites-screen.tsx +0 -78
- package/src/system-apps/account.app.ts +0 -7
- package/src/system-apps/contacts.app.ts +0 -8
- package/src/system-apps/groups.app.ts +0 -8
- package/src/system-apps/invites.app.ts +0 -8
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
copyToClipboard,
|
|
3
2
|
Groups,
|
|
4
|
-
generateGroupShare,
|
|
5
3
|
getIconClassName,
|
|
6
4
|
getUserContext,
|
|
7
5
|
type IDoc,
|
|
@@ -10,22 +8,20 @@ import {
|
|
|
10
8
|
rpcServerCalls,
|
|
11
9
|
sleep,
|
|
12
10
|
} from "@peers-app/peers-sdk";
|
|
13
|
-
import { useState } from "react";
|
|
14
11
|
import { Checkbox } from "../../components/checkbox";
|
|
15
12
|
import { Input } from "../../components/input";
|
|
16
13
|
import { LoadingIndicator } from "../../components/loading-indicator";
|
|
17
14
|
import { MarkdownEditorInline } from "../../components/markdown-editor/editor-inline";
|
|
18
15
|
import { SaveButton } from "../../components/save-button";
|
|
19
|
-
import {
|
|
16
|
+
import { Tabs } from "../../components/tabs";
|
|
20
17
|
import { usePromise } from "../../hooks";
|
|
21
|
-
import { updateActiveTabTitle } from "../../tabs-layout/tabs-state";
|
|
22
|
-
import { registerInternalPeersUI } from "../../ui-router/ui-loader";
|
|
23
18
|
import { GroupMembersUI } from "./group-members";
|
|
24
19
|
|
|
25
20
|
interface IProps {
|
|
26
21
|
groupId: string;
|
|
27
22
|
}
|
|
28
23
|
|
|
24
|
+
/** Edit group metadata and manage members and invitations inside Identity. */
|
|
29
25
|
export const GroupDetails = (props: IProps) => {
|
|
30
26
|
const group = usePromise(
|
|
31
27
|
async () => {
|
|
@@ -35,7 +31,6 @@ export const GroupDetails = (props: IProps) => {
|
|
|
35
31
|
if (!group) {
|
|
36
32
|
throw new Error("Group not found");
|
|
37
33
|
}
|
|
38
|
-
updateActiveTabTitle(group.name || "Group");
|
|
39
34
|
const groupDoc = userGroupTable.initDoc(group);
|
|
40
35
|
// saves go to both the group and user db
|
|
41
36
|
groupDoc.save = async () => {
|
|
@@ -66,7 +61,7 @@ export const GroupDetails = (props: IProps) => {
|
|
|
66
61
|
}
|
|
67
62
|
|
|
68
63
|
return (
|
|
69
|
-
<div className="container-
|
|
64
|
+
<div className="container-xxl p-3">
|
|
70
65
|
<div className="d-flex">
|
|
71
66
|
<div>
|
|
72
67
|
<h4>
|
|
@@ -83,10 +78,7 @@ export const GroupDetails = (props: IProps) => {
|
|
|
83
78
|
/>
|
|
84
79
|
</h4>
|
|
85
80
|
</div>
|
|
86
|
-
<
|
|
87
|
-
<ShareButton groupId={props.groupId} />
|
|
88
|
-
<SaveButton key={group.groupId} doc={group} />
|
|
89
|
-
</div>
|
|
81
|
+
<SaveButton key={group.groupId} doc={group} />
|
|
90
82
|
</div>
|
|
91
83
|
|
|
92
84
|
<Tabs
|
|
@@ -95,17 +87,17 @@ export const GroupDetails = (props: IProps) => {
|
|
|
95
87
|
{
|
|
96
88
|
name: "Info",
|
|
97
89
|
content: (
|
|
98
|
-
<
|
|
90
|
+
<div>
|
|
99
91
|
<GroupInfo group={group} />
|
|
100
|
-
</
|
|
92
|
+
</div>
|
|
101
93
|
),
|
|
102
94
|
},
|
|
103
95
|
{
|
|
104
96
|
name: "Members",
|
|
105
97
|
content: (
|
|
106
|
-
<
|
|
98
|
+
<div>
|
|
107
99
|
<GroupMembersWrapper groupId={props.groupId} />
|
|
108
|
-
</
|
|
100
|
+
</div>
|
|
109
101
|
),
|
|
110
102
|
},
|
|
111
103
|
]}
|
|
@@ -160,135 +152,9 @@ const GroupInfo = (props: { group: IDoc<IGroup> }) => {
|
|
|
160
152
|
);
|
|
161
153
|
};
|
|
162
154
|
|
|
163
|
-
const ShareButton = ({ groupId }: { groupId: string }) => {
|
|
164
|
-
const [isSharing, setIsSharing] = useState(false);
|
|
165
|
-
const [shareResult, setShareResult] = useState<{
|
|
166
|
-
success: boolean;
|
|
167
|
-
message: string;
|
|
168
|
-
} | null>(null);
|
|
169
|
-
|
|
170
|
-
const handleShare = async () => {
|
|
171
|
-
setIsSharing(true);
|
|
172
|
-
setShareResult(null);
|
|
173
|
-
|
|
174
|
-
try {
|
|
175
|
-
// Generate the group share data
|
|
176
|
-
const groupShare = await generateGroupShare(groupId);
|
|
177
|
-
|
|
178
|
-
// Convert to JSON
|
|
179
|
-
const groupShareJson = JSON.stringify(groupShare, null, 2);
|
|
180
|
-
|
|
181
|
-
// Copy to clipboard
|
|
182
|
-
const copied = await copyToClipboard(groupShareJson);
|
|
183
|
-
|
|
184
|
-
if (copied) {
|
|
185
|
-
setShareResult({
|
|
186
|
-
success: true,
|
|
187
|
-
message: `Group share data copied to clipboard! (${groupShareJson.length} chars, ${groupShare.groupMembers.length} admin members)`,
|
|
188
|
-
});
|
|
189
|
-
} else {
|
|
190
|
-
setShareResult({
|
|
191
|
-
success: false,
|
|
192
|
-
message: "Failed to copy to clipboard. Please copy manually from the modal.",
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
} catch (error: unknown) {
|
|
196
|
-
setShareResult({
|
|
197
|
-
success: false,
|
|
198
|
-
message: `Error generating share: ${error instanceof Error ? error.message : String(error)}`,
|
|
199
|
-
});
|
|
200
|
-
} finally {
|
|
201
|
-
setIsSharing(false);
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
return (
|
|
206
|
-
<>
|
|
207
|
-
<button
|
|
208
|
-
className="btn btn-secondary btn-sm"
|
|
209
|
-
onClick={handleShare}
|
|
210
|
-
disabled={isSharing}
|
|
211
|
-
title="Share group with admin members"
|
|
212
|
-
>
|
|
213
|
-
{isSharing ? (
|
|
214
|
-
<>
|
|
215
|
-
<span
|
|
216
|
-
className="spinner-border spinner-border-sm me-1"
|
|
217
|
-
role="status"
|
|
218
|
-
aria-hidden="true"
|
|
219
|
-
></span>
|
|
220
|
-
Sharing...
|
|
221
|
-
</>
|
|
222
|
-
) : (
|
|
223
|
-
<>
|
|
224
|
-
<i className="bi-share me-1"></i>
|
|
225
|
-
Share
|
|
226
|
-
</>
|
|
227
|
-
)}
|
|
228
|
-
</button>
|
|
229
|
-
|
|
230
|
-
{shareResult && (
|
|
231
|
-
<div
|
|
232
|
-
className="position-fixed top-0 start-0 w-100 h-100 d-flex align-items-center justify-content-center"
|
|
233
|
-
style={{ backgroundColor: "rgba(0,0,0,0.5)", zIndex: 1050 }}
|
|
234
|
-
>
|
|
235
|
-
<div className="card" style={{ maxWidth: "500px", width: "90%" }}>
|
|
236
|
-
<div className="card-header d-flex justify-content-between align-items-center">
|
|
237
|
-
<h6 className="mb-0">
|
|
238
|
-
<i
|
|
239
|
-
className={`bi-${shareResult.success ? "check-circle text-success" : "exclamation-triangle text-warning"} me-2`}
|
|
240
|
-
></i>
|
|
241
|
-
Group Share {shareResult.success ? "Ready" : "Error"}
|
|
242
|
-
</h6>
|
|
243
|
-
<button
|
|
244
|
-
className="btn-close"
|
|
245
|
-
onClick={() => setShareResult(null)}
|
|
246
|
-
aria-label="Close"
|
|
247
|
-
></button>
|
|
248
|
-
</div>
|
|
249
|
-
<div className="card-body">
|
|
250
|
-
<p className="mb-3">{shareResult.message}</p>
|
|
251
|
-
|
|
252
|
-
<div className="text-end">
|
|
253
|
-
<button className="btn btn-secondary me-2" onClick={() => setShareResult(null)}>
|
|
254
|
-
Close
|
|
255
|
-
</button>
|
|
256
|
-
{shareResult.success && (
|
|
257
|
-
<button className="btn btn-primary" onClick={handleShare}>
|
|
258
|
-
Copy Again
|
|
259
|
-
</button>
|
|
260
|
-
)}
|
|
261
|
-
</div>
|
|
262
|
-
</div>
|
|
263
|
-
</div>
|
|
264
|
-
</div>
|
|
265
|
-
)}
|
|
266
|
-
</>
|
|
267
|
-
);
|
|
268
|
-
};
|
|
269
|
-
|
|
270
155
|
const GroupMembersWrapper = (props: { groupId: string }) => {
|
|
271
156
|
const userContext = usePromise(() => getUserContext());
|
|
272
157
|
if (!userContext) return null;
|
|
273
158
|
|
|
274
159
|
return <GroupMembersUI groupId={props.groupId} userContext={userContext} />;
|
|
275
160
|
};
|
|
276
|
-
|
|
277
|
-
registerInternalPeersUI({
|
|
278
|
-
peersUIId: "00group00details00component",
|
|
279
|
-
component: GroupDetails,
|
|
280
|
-
routes: [
|
|
281
|
-
{
|
|
282
|
-
isMatch: (props, context) => {
|
|
283
|
-
const match = context.path.match(/^groups\/([a-zA-Z0-9]{25})$/);
|
|
284
|
-
if (match) {
|
|
285
|
-
props.groupId = match[1];
|
|
286
|
-
return true;
|
|
287
|
-
}
|
|
288
|
-
return false;
|
|
289
|
-
},
|
|
290
|
-
uiCategory: "screen",
|
|
291
|
-
priority: 2,
|
|
292
|
-
},
|
|
293
|
-
],
|
|
294
|
-
});
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
} from "@peers-app/peers-sdk";
|
|
8
8
|
import { useState } from "react";
|
|
9
9
|
import { Typeahead, type TypeaheadItem } from "../../components/typeahead";
|
|
10
|
+
import { PendingWorkLink } from "../invites/activity-view";
|
|
10
11
|
import { InviteShare } from "../invites/invite-share";
|
|
11
12
|
import { inviteTools } from "../invites/invites-ipc";
|
|
12
|
-
import { PendingInvitesList } from "../invites/pending-invites-list";
|
|
13
13
|
|
|
14
14
|
/** Props for {@link GroupInvitePanel}. */
|
|
15
15
|
export interface GroupInvitePanelProps {
|
|
@@ -305,12 +305,7 @@ export function GroupInvitePanel(props: GroupInvitePanelProps) {
|
|
|
305
305
|
{tab === "contacts" ? <InviteContactsCard {...props} /> : <ShareLinkCard {...props} />}
|
|
306
306
|
</div>
|
|
307
307
|
</div>
|
|
308
|
-
<
|
|
309
|
-
type="group"
|
|
310
|
-
groupId={props.groupId}
|
|
311
|
-
hideWhenEmpty
|
|
312
|
-
title="Pending invites and join requests"
|
|
313
|
-
/>
|
|
308
|
+
<PendingWorkLink type="group" groupId={props.groupId} />
|
|
314
309
|
</>
|
|
315
310
|
);
|
|
316
311
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { GroupMemberRole } from "@peers-app/peers-sdk";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
import { GroupSummaryRow, type IGroupSummary } from "./group-list";
|
|
4
|
+
|
|
5
|
+
jest.mock("../../globals", () => ({
|
|
6
|
+
mainContentPath: jest.fn(),
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
jest.mock("../../hooks", () => ({
|
|
10
|
+
usePromise: jest.fn(),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock("../invites/activity-view", () => ({
|
|
14
|
+
PendingWorkLink: () => null,
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
const summary: IGroupSummary = {
|
|
18
|
+
group: {
|
|
19
|
+
groupId: "zyxwvutsrqponmlkjihgfedcb",
|
|
20
|
+
name: "Neighborhood",
|
|
21
|
+
description: "**Local** projects and shared plans",
|
|
22
|
+
founderUserId: "abcdefghijklmnopqrstuvwxy",
|
|
23
|
+
publicKey: "signing-key",
|
|
24
|
+
publicBoxKey: "box-key",
|
|
25
|
+
signature: "signature",
|
|
26
|
+
},
|
|
27
|
+
memberCount: 7,
|
|
28
|
+
myRole: GroupMemberRole.Admin,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
describe("GroupSummaryRow", () => {
|
|
32
|
+
it("shows description, member count, and local role in a clickable row", () => {
|
|
33
|
+
render(<GroupSummaryRow summary={summary} />);
|
|
34
|
+
|
|
35
|
+
expect(screen.getByText("Neighborhood")).toBeInTheDocument();
|
|
36
|
+
expect(screen.getByText("Local projects and shared plans")).toBeInTheDocument();
|
|
37
|
+
expect(screen.getByText("7 members")).toBeInTheDocument();
|
|
38
|
+
expect(screen.getByText("Admin")).toBeInTheDocument();
|
|
39
|
+
expect(screen.getByRole("link")).toHaveAttribute(
|
|
40
|
+
"href",
|
|
41
|
+
`#identity/groups/${summary.group.groupId}`,
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
});
|