@peers-app/peers-ui 0.14.0 → 0.15.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/.github/workflows/publish.yml +8 -5
- package/babel.config.js +4 -4
- package/biome.json +191 -0
- package/dist/command-palette/command-palette-ui.d.ts +1 -2
- package/dist/command-palette/command-palette-ui.js +175 -244
- package/dist/command-palette/command-palette.js +65 -64
- package/dist/components/chat-overlay.d.ts +2 -2
- package/dist/components/chat-overlay.js +160 -217
- package/dist/components/checkbox.d.ts +5 -4
- package/dist/components/checkbox.js +4 -7
- package/dist/components/group-switcher.d.ts +1 -2
- package/dist/components/group-switcher.js +119 -159
- package/dist/components/input-date.d.ts +3 -3
- package/dist/components/input-date.js +6 -6
- package/dist/components/input-number.d.ts +7 -6
- package/dist/components/input-number.js +25 -20
- package/dist/components/input.d.ts +5 -4
- package/dist/components/input.js +4 -7
- package/dist/components/inverse-lazy-list.d.ts +3 -3
- package/dist/components/inverse-lazy-list.js +13 -47
- package/dist/components/io-schema-values.d.ts +5 -6
- package/dist/components/io-schema-values.js +28 -65
- package/dist/components/io-schema.d.ts +4 -5
- package/dist/components/io-schema.js +42 -79
- package/dist/components/lazy-list.d.ts +3 -3
- package/dist/components/lazy-list.js +38 -58
- package/dist/components/list-screen.d.ts +3 -8
- package/dist/components/list-screen.js +28 -23
- package/dist/components/loading-indicator.d.ts +1 -2
- package/dist/components/loading-indicator.js +2 -6
- package/dist/components/markdown-editor/autolink-plugin.js +5 -8
- package/dist/components/markdown-editor/editor-inline.d.ts +2 -3
- package/dist/components/markdown-editor/editor-inline.js +2 -6
- package/dist/components/markdown-editor/editor.d.ts +6 -6
- package/dist/components/markdown-editor/editor.js +9 -19
- package/dist/components/markdown-editor/markdown-plugin.d.ts +1 -1
- package/dist/components/markdown-editor/markdown-plugin.js +20 -21
- package/dist/components/markdown-editor/mention-node.d.ts +2 -2
- package/dist/components/markdown-editor/mention-node.js +24 -24
- package/dist/components/markdown-editor/mentions-plugin.d.ts +2 -2
- package/dist/components/markdown-editor/mentions-plugin.js +61 -62
- package/dist/components/markdown-editor/theme.js +28 -28
- package/dist/components/markdown-editor/toolbar.d.ts +2 -3
- package/dist/components/markdown-editor/toolbar.js +32 -49
- package/dist/components/markdown-with-mentions.d.ts +1 -1
- package/dist/components/markdown-with-mentions.js +43 -43
- package/dist/components/message-logs/message-logs.d.ts +1 -2
- package/dist/components/message-logs/message-logs.js +91 -116
- package/dist/components/messages/avatar.d.ts +3 -4
- package/dist/components/messages/avatar.js +37 -46
- package/dist/components/messages/channel-message-list.d.ts +5 -6
- package/dist/components/messages/channel-message-list.js +34 -34
- package/dist/components/messages/channel-view.d.ts +1 -2
- package/dist/components/messages/channel-view.js +23 -57
- package/dist/components/messages/message-compose.d.ts +3 -4
- package/dist/components/messages/message-compose.js +27 -38
- package/dist/components/messages/message-display.d.ts +2 -3
- package/dist/components/messages/message-display.js +42 -95
- package/dist/components/messages/thread-message-list.d.ts +4 -5
- package/dist/components/messages/thread-message-list.js +29 -29
- package/dist/components/router.d.ts +1 -2
- package/dist/components/router.js +58 -66
- package/dist/components/save-button.d.ts +3 -3
- package/dist/components/save-button.js +23 -33
- package/dist/components/sortable-list.d.ts +11 -12
- package/dist/components/sortable-list.js +42 -22
- package/dist/components/tabs.d.ts +3 -3
- package/dist/components/tabs.js +16 -47
- package/dist/components/tooltip.d.ts +4 -4
- package/dist/components/tooltip.js +4 -9
- package/dist/components/trust-level-badge.d.ts +2 -3
- package/dist/components/trust-level-badge.js +16 -16
- package/dist/components/trust-level-dropdown.d.ts +3 -4
- package/dist/components/trust-level-dropdown.js +32 -55
- package/dist/components/typeahead.d.ts +3 -3
- package/dist/components/typeahead.js +48 -89
- package/dist/components/voice-indicator.d.ts +2 -2
- package/dist/components/voice-indicator.js +93 -106
- package/dist/components/voice-subscribe-events.d.ts +32 -0
- package/dist/components/voice-subscribe-events.js +2 -0
- package/dist/globals.d.ts +3 -5
- package/dist/globals.js +22 -33
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.js +22 -12
- package/dist/hooks.test.js +129 -145
- package/dist/index.d.ts +9 -8
- package/dist/index.js +13 -12
- package/dist/mention-configs.d.ts +2 -2
- package/dist/mention-configs.js +55 -42
- package/dist/screens/assistants/assistant-config.d.ts +2 -3
- package/dist/screens/assistants/assistant-config.js +9 -22
- package/dist/screens/assistants/assistant-details.d.ts +1 -2
- package/dist/screens/assistants/assistant-details.js +13 -28
- package/dist/screens/assistants/assistant-info.d.ts +2 -3
- package/dist/screens/assistants/assistant-info.js +3 -17
- package/dist/screens/assistants/assistant-list.d.ts +1 -2
- package/dist/screens/assistants/assistant-list.js +15 -56
- package/dist/screens/assistants/assistant-tools.d.ts +2 -3
- package/dist/screens/assistants/assistant-tools.js +10 -24
- package/dist/screens/console-logs/console-logs-list.d.ts +1 -2
- package/dist/screens/console-logs/console-logs-list.js +130 -134
- package/dist/screens/console-logs/log-display.d.ts +2 -3
- package/dist/screens/console-logs/log-display.js +40 -42
- package/dist/screens/console-logs/log-filters.d.ts +1 -2
- package/dist/screens/console-logs/log-filters.js +2 -24
- package/dist/screens/console-logs/mobile-log-card.d.ts +2 -3
- package/dist/screens/console-logs/mobile-log-card.js +64 -67
- package/dist/screens/console-logs/resizable-table-header.d.ts +1 -2
- package/dist/screens/console-logs/resizable-table-header.js +31 -67
- package/dist/screens/contacts/contact-details.d.ts +1 -2
- package/dist/screens/contacts/contact-details.js +16 -46
- package/dist/screens/contacts/contact-list.d.ts +1 -2
- package/dist/screens/contacts/contact-list.js +44 -103
- package/dist/screens/contacts/index.d.ts +4 -4
- package/dist/screens/contacts/index.js +1 -1
- package/dist/screens/contacts/user-connect.d.ts +1 -2
- package/dist/screens/contacts/user-connect.js +85 -186
- package/dist/screens/data-explorer/data-explorer.d.ts +1 -2
- package/dist/screens/data-explorer/data-explorer.js +61 -181
- package/dist/screens/data-explorer/index.d.ts +2 -2
- package/dist/screens/data-explorer/query-executor.d.ts +1 -2
- package/dist/screens/data-explorer/query-executor.js +56 -166
- package/dist/screens/groups/group-details.d.ts +1 -2
- package/dist/screens/groups/group-details.js +27 -122
- package/dist/screens/groups/group-invite-listener.d.ts +2 -3
- package/dist/screens/groups/group-invite-listener.js +8 -104
- package/dist/screens/groups/group-list.d.ts +1 -2
- package/dist/screens/groups/group-list.js +56 -133
- package/dist/screens/groups/group-members.d.ts +2 -3
- package/dist/screens/groups/group-members.js +62 -132
- package/dist/screens/groups/index.d.ts +4 -4
- package/dist/screens/groups/index.js +1 -1
- package/dist/screens/join-group/index.d.ts +2 -2
- package/dist/screens/join-group/join-group.d.ts +1 -2
- package/dist/screens/join-group/join-group.js +9 -109
- package/dist/screens/network-viewer/connection-troubleshooter.d.ts +2 -3
- package/dist/screens/network-viewer/connection-troubleshooter.js +89 -193
- package/dist/screens/network-viewer/cpu-usage-graph.d.ts +1 -2
- package/dist/screens/network-viewer/cpu-usage-graph.js +60 -99
- package/dist/screens/network-viewer/device-details-modal.d.ts +1 -2
- package/dist/screens/network-viewer/device-details-modal.js +25 -177
- package/dist/screens/network-viewer/group-details-modal.d.ts +1 -2
- package/dist/screens/network-viewer/group-details-modal.js +31 -142
- package/dist/screens/network-viewer/index.d.ts +4 -4
- package/dist/screens/network-viewer/index.js +3 -3
- package/dist/screens/network-viewer/network-viewer-ipc.d.ts +22 -0
- package/dist/screens/network-viewer/network-viewer-ipc.js +6 -0
- package/dist/screens/network-viewer/network-viewer.d.ts +1 -2
- package/dist/screens/network-viewer/network-viewer.js +91 -296
- package/dist/screens/network-viewer/usage-graph.d.ts +1 -2
- package/dist/screens/network-viewer/usage-graph.js +78 -110
- package/dist/screens/packages/package-details.d.ts +1 -2
- package/dist/screens/packages/package-details.js +35 -41
- package/dist/screens/packages/package-info.d.ts +2 -2
- package/dist/screens/packages/package-info.js +33 -86
- package/dist/screens/packages/package-list.d.ts +1 -2
- package/dist/screens/packages/package-list.js +42 -106
- package/dist/screens/packages/package-new-local.d.ts +1 -2
- package/dist/screens/packages/package-new-local.js +13 -19
- package/dist/screens/packages/package-versions.d.ts +2 -3
- package/dist/screens/packages/package-versions.js +29 -96
- package/dist/screens/peer-types/peer-type-details.d.ts +3 -4
- package/dist/screens/peer-types/peer-type-details.js +26 -78
- package/dist/screens/peer-types/peer-type-list.d.ts +1 -2
- package/dist/screens/peer-types/peer-type-list.js +13 -24
- package/dist/screens/search/global-search.d.ts +1 -2
- package/dist/screens/search/global-search.js +104 -182
- package/dist/screens/settings/color-mode-dropdown.d.ts +3 -4
- package/dist/screens/settings/color-mode-dropdown.js +18 -37
- package/dist/screens/settings/settings-page.d.ts +1 -1
- package/dist/screens/settings/settings-page.js +86 -213
- package/dist/screens/settings/voice-settings-agent.d.ts +1 -1
- package/dist/screens/settings/voice-settings-agent.js +7 -44
- package/dist/screens/settings/voice-settings-api-keys.d.ts +2 -2
- package/dist/screens/settings/voice-settings-api-keys.js +2 -29
- package/dist/screens/settings/voice-settings-output.d.ts +2 -2
- package/dist/screens/settings/voice-settings-output.js +2 -40
- package/dist/screens/settings/voice-settings-providers.d.ts +2 -2
- package/dist/screens/settings/voice-settings-providers.js +2 -19
- package/dist/screens/settings/voice-settings-types.d.ts +4 -4
- package/dist/screens/settings/voice-settings-types.js +31 -31
- package/dist/screens/settings/voice-settings-wake-word.d.ts +2 -2
- package/dist/screens/settings/voice-settings-wake-word.js +2 -33
- package/dist/screens/settings/voice-settings.d.ts +1 -1
- package/dist/screens/settings/voice-settings.js +35 -112
- package/dist/screens/setup-user.d.ts +1 -2
- package/dist/screens/setup-user.js +38 -116
- package/dist/screens/tools/tool-code.d.ts +2 -3
- package/dist/screens/tools/tool-code.js +9 -13
- package/dist/screens/tools/tool-details.d.ts +1 -2
- package/dist/screens/tools/tool-details.js +26 -39
- package/dist/screens/tools/tool-info.d.ts +2 -3
- package/dist/screens/tools/tool-info.js +9 -48
- package/dist/screens/tools/tool-list.d.ts +1 -2
- package/dist/screens/tools/tool-list.js +33 -65
- package/dist/screens/tools/tool-schema.d.ts +2 -3
- package/dist/screens/tools/tool-schema.js +2 -13
- package/dist/screens/tools/tool-test-details.d.ts +1 -2
- package/dist/screens/tools/tool-test-details.js +12 -28
- package/dist/screens/tools/tool-test-list.d.ts +1 -2
- package/dist/screens/tools/tool-test-list.js +17 -56
- package/dist/screens/variables/variable-details.d.ts +1 -2
- package/dist/screens/variables/variable-details.js +19 -86
- package/dist/screens/variables/variable-list.d.ts +1 -2
- package/dist/screens/variables/variable-list.js +16 -27
- package/dist/screens/welcome-modal.d.ts +1 -2
- package/dist/screens/welcome-modal.js +44 -111
- package/dist/screens/workflows/workflow-details.d.ts +1 -2
- package/dist/screens/workflows/workflow-details.js +17 -31
- package/dist/screens/workflows/workflow-info.d.ts +2 -3
- package/dist/screens/workflows/workflow-info.js +2 -9
- package/dist/screens/workflows/workflow-instructions.d.ts +2 -3
- package/dist/screens/workflows/workflow-instructions.js +23 -55
- package/dist/screens/workflows/workflow-list.d.ts +1 -2
- package/dist/screens/workflows/workflow-list.js +23 -62
- package/dist/setupTests.d.ts +1 -1
- package/dist/setupTests.js +10 -11
- package/dist/system-apps/assistants.app.d.ts +1 -1
- package/dist/system-apps/assistants.app.js +3 -3
- package/dist/system-apps/console-logs.app.d.ts +1 -1
- package/dist/system-apps/console-logs.app.js +3 -3
- package/dist/system-apps/contacts.app.d.ts +1 -1
- package/dist/system-apps/contacts.app.js +4 -4
- package/dist/system-apps/data-explorer.app.d.ts +1 -1
- package/dist/system-apps/data-explorer.app.js +4 -4
- package/dist/system-apps/groups.app.d.ts +1 -1
- package/dist/system-apps/groups.app.js +4 -4
- package/dist/system-apps/index.d.ts +17 -17
- package/dist/system-apps/index.js +52 -52
- package/dist/system-apps/join-group.app.d.ts +1 -1
- package/dist/system-apps/join-group.app.js +4 -4
- package/dist/system-apps/mobile-settings.app.d.ts +1 -1
- package/dist/system-apps/mobile-settings.app.js +3 -3
- package/dist/system-apps/network-viewer.app.d.ts +1 -1
- package/dist/system-apps/network-viewer.app.js +4 -4
- package/dist/system-apps/packages.app.d.ts +1 -1
- package/dist/system-apps/packages.app.js +3 -3
- package/dist/system-apps/search.app.d.ts +1 -1
- package/dist/system-apps/search.app.js +4 -4
- package/dist/system-apps/settings.app.d.ts +1 -1
- package/dist/system-apps/settings.app.js +3 -3
- package/dist/system-apps/threads.app.d.ts +1 -1
- package/dist/system-apps/threads.app.js +3 -3
- package/dist/system-apps/tools.app.d.ts +1 -1
- package/dist/system-apps/tools.app.js +3 -3
- package/dist/system-apps/types.app.d.ts +1 -1
- package/dist/system-apps/types.app.js +3 -3
- package/dist/system-apps/variables.app.d.ts +1 -1
- package/dist/system-apps/variables.app.js +3 -3
- package/dist/system-apps/workflows.app.d.ts +1 -1
- package/dist/system-apps/workflows.app.js +3 -3
- package/dist/tabs-layout/tabs-layout.d.ts +2 -3
- package/dist/tabs-layout/tabs-layout.js +215 -246
- package/dist/tabs-layout/tabs-state.d.ts +2 -2
- package/dist/tabs-layout/tabs-state.js +73 -61
- package/dist/ui-defaults/index.d.ts +2 -2
- package/dist/ui-defaults/list-screen.d.ts +2 -3
- package/dist/ui-defaults/list-screen.js +33 -37
- package/dist/ui-defaults/markdown-field.js +24 -56
- package/dist/ui-router/routes-loader.d.ts +1 -1
- package/dist/ui-router/routes-loader.js +17 -13
- package/dist/ui-router/ui-loader.d.ts +6 -6
- package/dist/ui-router/ui-loader.js +172 -268
- package/dist/utils.js +49 -39
- package/jest.config.js +16 -16
- package/package.json +16 -14
- package/src/command-palette/command-palette-ui.tsx +261 -237
- package/src/command-palette/command-palette.ts +81 -78
- package/src/components/chat-overlay.tsx +366 -261
- package/src/components/checkbox.tsx +15 -12
- package/src/components/group-switcher.tsx +150 -105
- package/src/components/input-date.tsx +17 -16
- package/src/components/input-number.tsx +47 -31
- package/src/components/input.tsx +15 -12
- package/src/components/inverse-lazy-list.tsx +14 -13
- package/src/components/io-schema-values.tsx +51 -69
- package/src/components/io-schema.tsx +94 -69
- package/src/components/lazy-list.tsx +51 -34
- package/src/components/list-screen.tsx +51 -35
- package/src/components/loading-indicator.tsx +2 -4
- package/src/components/markdown-editor/autolink-plugin.tsx +4 -11
- package/src/components/markdown-editor/editor-inline.tsx +3 -4
- package/src/components/markdown-editor/editor.tsx +53 -51
- package/src/components/markdown-editor/markdown-plugin.tsx +48 -40
- package/src/components/markdown-editor/mention-node.ts +39 -38
- package/src/components/markdown-editor/mentions-plugin.tsx +99 -101
- package/src/components/markdown-editor/theme.ts +28 -29
- package/src/components/markdown-editor/toolbar.tsx +53 -47
- package/src/components/markdown-with-mentions.tsx +56 -46
- package/src/components/message-logs/message-logs.tsx +225 -165
- package/src/components/messages/avatar.tsx +70 -52
- package/src/components/messages/channel-message-list.tsx +80 -68
- package/src/components/messages/channel-view.tsx +34 -33
- package/src/components/messages/message-compose.tsx +84 -67
- package/src/components/messages/message-display.tsx +103 -89
- package/src/components/messages/thread-message-list.tsx +53 -44
- package/src/components/router.tsx +42 -43
- package/src/components/save-button.tsx +43 -39
- package/src/components/sortable-list.tsx +77 -49
- package/src/components/tabs.tsx +31 -31
- package/src/components/tooltip.tsx +21 -28
- package/src/components/trust-level-badge.tsx +15 -11
- package/src/components/trust-level-dropdown.tsx +49 -19
- package/src/components/typeahead.tsx +57 -59
- package/src/components/voice-indicator.tsx +158 -141
- package/src/components/voice-subscribe-events.ts +20 -0
- package/src/globals.tsx +42 -40
- package/src/hooks.test.tsx +141 -134
- package/src/hooks.ts +80 -48
- package/src/index.tsx +17 -10
- package/src/mention-configs.ts +122 -68
- package/src/screens/assistants/assistant-config.tsx +28 -18
- package/src/screens/assistants/assistant-details.tsx +35 -36
- package/src/screens/assistants/assistant-info.tsx +16 -11
- package/src/screens/assistants/assistant-list.tsx +37 -34
- package/src/screens/assistants/assistant-tools.tsx +41 -20
- package/src/screens/console-logs/console-logs-list.tsx +173 -140
- package/src/screens/console-logs/log-display.tsx +65 -38
- package/src/screens/console-logs/log-filters.tsx +4 -3
- package/src/screens/console-logs/mobile-log-card.tsx +78 -71
- package/src/screens/console-logs/resizable-table-header.tsx +29 -21
- package/src/screens/contacts/contact-details.tsx +29 -30
- package/src/screens/contacts/contact-list.tsx +71 -60
- package/src/screens/contacts/index.ts +5 -5
- package/src/screens/contacts/user-connect.tsx +177 -171
- package/src/screens/data-explorer/data-explorer.tsx +134 -98
- package/src/screens/data-explorer/index.ts +2 -3
- package/src/screens/data-explorer/query-executor.tsx +90 -80
- package/src/screens/groups/group-details.tsx +120 -101
- package/src/screens/groups/group-invite-listener.tsx +34 -37
- package/src/screens/groups/group-list.tsx +119 -103
- package/src/screens/groups/group-members.tsx +225 -164
- package/src/screens/groups/index.ts +5 -6
- package/src/screens/join-group/index.ts +2 -2
- package/src/screens/join-group/join-group.tsx +41 -39
- package/src/screens/network-viewer/connection-troubleshooter.tsx +145 -104
- package/src/screens/network-viewer/cpu-usage-graph.tsx +39 -43
- package/src/screens/network-viewer/device-details-modal.tsx +46 -59
- package/src/screens/network-viewer/group-details-modal.tsx +68 -49
- package/src/screens/network-viewer/index.ts +4 -5
- package/src/screens/network-viewer/network-viewer-ipc.ts +23 -0
- package/src/screens/network-viewer/network-viewer.tsx +261 -236
- package/src/screens/network-viewer/usage-graph.tsx +57 -49
- package/src/screens/packages/package-details.tsx +43 -35
- package/src/screens/packages/package-info.tsx +107 -66
- package/src/screens/packages/package-list.tsx +175 -98
- package/src/screens/packages/package-new-local.tsx +28 -26
- package/src/screens/packages/package-versions.tsx +102 -77
- package/src/screens/peer-types/peer-type-details.tsx +60 -50
- package/src/screens/peer-types/peer-type-list.tsx +20 -30
- package/src/screens/search/global-search.tsx +153 -137
- package/src/screens/settings/color-mode-dropdown.tsx +52 -35
- package/src/screens/settings/settings-page.tsx +215 -141
- package/src/screens/settings/voice-settings-agent.tsx +13 -12
- package/src/screens/settings/voice-settings-api-keys.tsx +14 -12
- package/src/screens/settings/voice-settings-output.tsx +12 -11
- package/src/screens/settings/voice-settings-providers.tsx +7 -3
- package/src/screens/settings/voice-settings-types.ts +52 -49
- package/src/screens/settings/voice-settings-wake-word.tsx +25 -9
- package/src/screens/settings/voice-settings.tsx +66 -43
- package/src/screens/setup-user.tsx +88 -41
- package/src/screens/tools/tool-code.tsx +12 -17
- package/src/screens/tools/tool-details.tsx +28 -28
- package/src/screens/tools/tool-info.tsx +14 -19
- package/src/screens/tools/tool-list.tsx +58 -40
- package/src/screens/tools/tool-schema.tsx +16 -9
- package/src/screens/tools/tool-test-details.tsx +11 -22
- package/src/screens/tools/tool-test-list.tsx +29 -30
- package/src/screens/variables/variable-details.tsx +63 -51
- package/src/screens/variables/variable-list.tsx +29 -30
- package/src/screens/welcome-modal.tsx +68 -48
- package/src/screens/workflows/workflow-details.tsx +40 -30
- package/src/screens/workflows/workflow-info.tsx +4 -11
- package/src/screens/workflows/workflow-instructions.tsx +35 -28
- package/src/screens/workflows/workflow-list.tsx +50 -40
- package/src/setupTests.ts +14 -13
- package/src/system-apps/assistants.app.ts +5 -5
- package/src/system-apps/console-logs.app.ts +4 -4
- package/src/system-apps/contacts.app.ts +6 -6
- package/src/system-apps/data-explorer.app.ts +5 -5
- package/src/system-apps/groups.app.ts +6 -6
- package/src/system-apps/index.ts +49 -49
- package/src/system-apps/join-group.app.ts +5 -5
- package/src/system-apps/mobile-settings.app.ts +4 -5
- package/src/system-apps/network-viewer.app.ts +5 -5
- package/src/system-apps/packages.app.ts +5 -5
- package/src/system-apps/search.app.ts +6 -6
- package/src/system-apps/settings.app.ts +5 -5
- package/src/system-apps/threads.app.ts +5 -5
- package/src/system-apps/tools.app.ts +5 -5
- package/src/system-apps/types.app.ts +5 -5
- package/src/system-apps/variables.app.ts +5 -5
- package/src/system-apps/workflows.app.ts +5 -5
- package/src/tabs-layout/tabs-layout.tsx +345 -254
- package/src/tabs-layout/tabs-state.ts +100 -81
- package/src/ui-defaults/index.ts +2 -3
- package/src/ui-defaults/list-screen.tsx +45 -40
- package/src/ui-defaults/markdown-field.tsx +22 -26
- package/src/ui-router/routes-loader.ts +40 -24
- package/src/ui-router/ui-loader.tsx +312 -214
- package/src/utils.ts +68 -81
- package/tsconfig.json +5 -10
- package/dist/components/input-datetime.d.ts +0 -7
- package/dist/components/input-datetime.js +0 -35
- package/dist/components/lazy-sortable-list.d.ts +0 -29
- package/dist/components/lazy-sortable-list.js +0 -12
- package/dist/components/left-bar.d.ts +0 -5
- package/dist/components/left-bar.js +0 -207
- package/dist/components/main-content-container.d.ts +0 -2
- package/dist/components/main-content-container.js +0 -92
- package/dist/components/messages/thread-view.d.ts +0 -6
- package/dist/components/messages/thread-view.js +0 -174
- package/dist/components/off-canvas.d.ts +0 -13
- package/dist/components/off-canvas.js +0 -89
- package/dist/components/text-list-editor.tsx/text-list-editor.d.ts +0 -6
- package/dist/components/text-list-editor.tsx/text-list-editor.js +0 -13
- package/dist/components/top-bar.d.ts +0 -2
- package/dist/components/top-bar.js +0 -51
- package/dist/components/typeahead/mentions-plugin.d.ts +0 -7
- package/dist/components/typeahead/mentions-plugin.js +0 -203
- package/dist/components/typeahead/typeahead-editor.d.ts +0 -15
- package/dist/components/typeahead/typeahead-editor.js +0 -134
- package/dist/components/typeahead/typeahead.d.ts +0 -12
- package/dist/components/typeahead/typeahead.js +0 -94
- package/dist/screens/profile.d.ts +0 -2
- package/dist/screens/profile.js +0 -76
- package/src/components/input-datetime.tsx +0 -41
- package/src/components/lazy-sortable-list.tsx +0 -51
- package/src/components/left-bar.tsx +0 -322
- package/src/components/main-content-container.tsx +0 -79
- package/src/components/messages/thread-view.tsx +0 -214
- package/src/components/off-canvas.tsx +0 -83
- package/src/components/text-list-editor.tsx/text-list-editor.tsx +0 -13
- package/src/components/top-bar.tsx +0 -119
- package/src/components/typeahead/mentions-plugin.tsx +0 -265
- package/src/components/typeahead/typeahead-editor.tsx +0 -140
- package/src/components/typeahead/typeahead.tsx +0 -77
- package/src/screens/profile.tsx +0 -75
|
@@ -1,8 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
GroupMemberRole,
|
|
3
|
+
GroupMembers,
|
|
4
|
+
Groups,
|
|
5
|
+
getRoleLabel,
|
|
6
|
+
getUserById,
|
|
7
|
+
getUserContext,
|
|
8
|
+
getUserRole,
|
|
9
|
+
type IUser,
|
|
10
|
+
type IUserWithSource,
|
|
11
|
+
setUserTrustLevel,
|
|
12
|
+
TrustLevel,
|
|
13
|
+
type UserContext,
|
|
14
|
+
Users,
|
|
15
|
+
usersCursor,
|
|
16
|
+
} from "@peers-app/peers-sdk";
|
|
2
17
|
import React from "react";
|
|
3
18
|
import { LoadingIndicator } from "../../components/loading-indicator";
|
|
4
19
|
import { TrustLevelBadge } from "../../components/trust-level-badge";
|
|
5
|
-
import { Typeahead, TypeaheadItem } from "../../components/typeahead";
|
|
20
|
+
import { Typeahead, type TypeaheadItem } from "../../components/typeahead";
|
|
6
21
|
import { usePromise } from "../../hooks";
|
|
7
22
|
import { GroupInviteListener } from "./group-invite-listener";
|
|
8
23
|
|
|
@@ -13,108 +28,125 @@ interface GroupMembersUIProps {
|
|
|
13
28
|
|
|
14
29
|
export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
15
30
|
const { groupId, userContext } = props;
|
|
16
|
-
|
|
31
|
+
|
|
17
32
|
// Get the group's data context and tables
|
|
18
33
|
const groupDataContext = userContext.getDataContext(groupId);
|
|
19
34
|
const groupMembersTable = GroupMembers(groupDataContext);
|
|
20
35
|
const groupUsersTable = Users(groupDataContext);
|
|
21
|
-
|
|
36
|
+
|
|
22
37
|
// State for refreshing the component
|
|
23
38
|
const [refreshKey, setRefreshKey] = React.useState(0);
|
|
24
|
-
|
|
39
|
+
|
|
25
40
|
// Load group members with user details and check current user permissions
|
|
26
|
-
const membersData = usePromise(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
const membersData = usePromise(
|
|
42
|
+
async () => {
|
|
43
|
+
const members = await groupMembersTable.list({ deleted: { $ne: true } });
|
|
44
|
+
|
|
45
|
+
// Get user details for each member using the group context
|
|
46
|
+
const membersWithUsers = await Promise.all(
|
|
47
|
+
members.map(async (member) => {
|
|
48
|
+
const user = await getUserById(member.userId, {
|
|
49
|
+
currentDataContext: groupDataContext,
|
|
50
|
+
includeTrustLevel: true,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// If user found from external source, save to current group
|
|
54
|
+
if (user && user.source !== "currentDataContext") {
|
|
55
|
+
try {
|
|
56
|
+
const raw = { ...user } as Record<string, unknown>;
|
|
57
|
+
delete raw.source;
|
|
58
|
+
delete raw.trustLevel;
|
|
59
|
+
await groupUsersTable.save(raw as IUser);
|
|
60
|
+
|
|
61
|
+
// Set trust level for this user in the group context
|
|
62
|
+
await setUserTrustLevel(user.userId, TrustLevel.NewUser, groupDataContext);
|
|
63
|
+
|
|
64
|
+
// Update user reference to reflect it's now in current group
|
|
65
|
+
user.trustLevel = TrustLevel.NewUser;
|
|
66
|
+
user.source = "currentDataContext";
|
|
67
|
+
} catch (saveErr) {
|
|
68
|
+
console.error("Failed to save user to group context:", saveErr);
|
|
69
|
+
}
|
|
53
70
|
}
|
|
54
|
-
}
|
|
55
71
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
// TODO don't do it this way!!! Use group-specific trust level fetching
|
|
73
|
+
if (user && !user.trustLevel) {
|
|
74
|
+
const userCursor = await usersCursor(
|
|
75
|
+
{ userId: member.userId },
|
|
76
|
+
{ includeTrustLevel: true },
|
|
77
|
+
);
|
|
78
|
+
const _user = await userCursor.next();
|
|
79
|
+
user.trustLevel = _user?.trustLevel || user.trustLevel || TrustLevel.Unknown;
|
|
80
|
+
}
|
|
62
81
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
// // Fetch trust level for this user in the group context
|
|
83
|
+
// if (user) {
|
|
84
|
+
// try {
|
|
85
|
+
// const trustLevel = await getUserTrustLevel(groupDataContext, user.userId);
|
|
86
|
+
// user.trustLevel = trustLevel;
|
|
87
|
+
// } catch (err) {
|
|
88
|
+
// console.error('Failed to get trust level:', err);
|
|
89
|
+
// user.trustLevel = TrustLevel.Unknown;
|
|
90
|
+
// }
|
|
91
|
+
// }
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
member,
|
|
95
|
+
user: user || null,
|
|
96
|
+
};
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return membersWithUsers;
|
|
101
|
+
},
|
|
102
|
+
[],
|
|
103
|
+
[groupId, refreshKey],
|
|
104
|
+
);
|
|
83
105
|
|
|
84
106
|
// Check if current user has admin privileges in this group
|
|
85
|
-
const userPermissions = usePromise(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
107
|
+
const userPermissions = usePromise(
|
|
108
|
+
async () => {
|
|
109
|
+
const currentUserContext = await getUserContext();
|
|
110
|
+
const currentUserId = currentUserContext.userId;
|
|
111
|
+
const userRole = await getUserRole(groupId, currentUserId);
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
isMember: !!userRole,
|
|
115
|
+
canEdit: userRole >= GroupMemberRole.Admin,
|
|
116
|
+
userRole: userRole,
|
|
117
|
+
currentUserId: currentUserId,
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
undefined,
|
|
121
|
+
[groupId],
|
|
122
|
+
);
|
|
97
123
|
|
|
98
124
|
// Load group and founder information
|
|
99
|
-
const founderData = usePromise(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
currentDataContext: groupDataContext
|
|
110
|
-
});
|
|
125
|
+
const founderData = usePromise(
|
|
126
|
+
async () => {
|
|
127
|
+
const groupsTable = Groups(groupDataContext);
|
|
128
|
+
const group =
|
|
129
|
+
(await groupsTable.get(groupId)) ||
|
|
130
|
+
(await Groups(userContext.userDataContext).get(groupId));
|
|
131
|
+
|
|
132
|
+
if (!group) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
111
135
|
|
|
112
|
-
|
|
113
|
-
group,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
136
|
+
// Try to get founder user details
|
|
137
|
+
const founderUser = await getUserById(group.founderUserId, {
|
|
138
|
+
currentDataContext: groupDataContext,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
group,
|
|
143
|
+
founderUser,
|
|
144
|
+
founderUserId: group.founderUserId,
|
|
145
|
+
};
|
|
146
|
+
},
|
|
147
|
+
undefined,
|
|
148
|
+
[groupId, refreshKey],
|
|
149
|
+
);
|
|
118
150
|
|
|
119
151
|
const [newMemberRole, setNewMemberRole] = React.useState<GroupMemberRole>(GroupMemberRole.Reader);
|
|
120
152
|
const [addingMember, setAddingMember] = React.useState(false);
|
|
@@ -123,35 +155,36 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
123
155
|
// Search function for typeahead
|
|
124
156
|
const searchContacts = async (query: string): Promise<(IUserWithSource & TypeaheadItem)[]> => {
|
|
125
157
|
try {
|
|
126
|
-
const cursor = await usersCursor(
|
|
158
|
+
const cursor = await usersCursor(
|
|
159
|
+
{ name: { $matchWords: query } },
|
|
160
|
+
{ includeTrustLevel: true },
|
|
161
|
+
);
|
|
127
162
|
const results: IUserWithSource[] = [];
|
|
128
|
-
|
|
163
|
+
|
|
129
164
|
// Get first 10 results
|
|
130
165
|
for await (const contact of cursor) {
|
|
131
166
|
results.push(contact);
|
|
132
167
|
if (results.length >= 10) break;
|
|
133
168
|
}
|
|
134
|
-
|
|
169
|
+
|
|
135
170
|
// Filter out users who are already members
|
|
136
|
-
const currentMembers = membersData?.map(m => m.member.userId) || [];
|
|
137
|
-
const filteredResults = results.filter(contact =>
|
|
138
|
-
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
return filteredResults.map(contact => ({
|
|
171
|
+
const currentMembers = membersData?.map((m) => m.member.userId) || [];
|
|
172
|
+
const filteredResults = results.filter((contact) => !currentMembers.includes(contact.userId));
|
|
173
|
+
|
|
174
|
+
return filteredResults.map((contact) => ({
|
|
142
175
|
...contact,
|
|
143
|
-
id: contact.userId
|
|
176
|
+
id: contact.userId,
|
|
144
177
|
}));
|
|
145
178
|
} catch (error) {
|
|
146
|
-
console.error(
|
|
179
|
+
console.error("Error searching contacts:", error);
|
|
147
180
|
return [];
|
|
148
181
|
}
|
|
149
182
|
};
|
|
150
183
|
|
|
151
184
|
// Render function for typeahead results
|
|
152
|
-
const renderContactItem = (contact: IUserWithSource & TypeaheadItem,
|
|
185
|
+
const renderContactItem = (contact: IUserWithSource & TypeaheadItem, _isSelected: boolean) => (
|
|
153
186
|
<div className="d-flex align-items-center">
|
|
154
|
-
<i className="bi-person-circle me-2" style={{ fontSize:
|
|
187
|
+
<i className="bi-person-circle me-2" style={{ fontSize: "20px" }} />
|
|
155
188
|
<div className="flex-grow-1">
|
|
156
189
|
<div className="fw-semibold">{contact.name}</div>
|
|
157
190
|
<small className="text-muted">{contact.userId}</small>
|
|
@@ -168,25 +201,33 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
168
201
|
// Helper functions for contact sources
|
|
169
202
|
const getSourceLabel = (source: string) => {
|
|
170
203
|
switch (source) {
|
|
171
|
-
case
|
|
172
|
-
|
|
173
|
-
case
|
|
174
|
-
|
|
204
|
+
case "userDataContext":
|
|
205
|
+
return "Personal";
|
|
206
|
+
case "currentDataContext":
|
|
207
|
+
return "Current";
|
|
208
|
+
case "otherDataContexts":
|
|
209
|
+
return "Groups";
|
|
210
|
+
default:
|
|
211
|
+
return source;
|
|
175
212
|
}
|
|
176
213
|
};
|
|
177
214
|
|
|
178
215
|
const getSourceIcon = (source: string) => {
|
|
179
216
|
switch (source) {
|
|
180
|
-
case
|
|
181
|
-
|
|
182
|
-
case
|
|
183
|
-
|
|
217
|
+
case "userDataContext":
|
|
218
|
+
return "person-fill";
|
|
219
|
+
case "currentDataContext":
|
|
220
|
+
return "house-fill";
|
|
221
|
+
case "otherDataContexts":
|
|
222
|
+
return "people-fill";
|
|
223
|
+
default:
|
|
224
|
+
return "question-circle";
|
|
184
225
|
}
|
|
185
226
|
};
|
|
186
227
|
|
|
187
228
|
const addMember = async () => {
|
|
188
229
|
if (selectedContacts.length === 0) return;
|
|
189
|
-
|
|
230
|
+
|
|
190
231
|
setAddingMember(true);
|
|
191
232
|
try {
|
|
192
233
|
// Add all selected contacts with the chosen role
|
|
@@ -199,30 +240,28 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
199
240
|
member = await groupMembersTable.initRecord({
|
|
200
241
|
groupId: groupId,
|
|
201
242
|
userId: contact.userId,
|
|
202
|
-
role: newMemberRole
|
|
243
|
+
role: newMemberRole,
|
|
203
244
|
});
|
|
204
245
|
}
|
|
205
246
|
await groupMembersTable.signAndSave(member);
|
|
206
247
|
}
|
|
207
|
-
|
|
248
|
+
|
|
208
249
|
// Reset form
|
|
209
250
|
setSelectedContacts([]);
|
|
210
251
|
setNewMemberRole(GroupMemberRole.Reader);
|
|
211
252
|
|
|
212
253
|
// Refresh the members list
|
|
213
|
-
setRefreshKey(prev => prev + 1);
|
|
254
|
+
setRefreshKey((prev) => prev + 1);
|
|
214
255
|
} catch (err) {
|
|
215
|
-
console.error(
|
|
216
|
-
alert(
|
|
256
|
+
console.error("Failed to add member:", err);
|
|
257
|
+
alert("Failed to add member. They may already be in the group.");
|
|
217
258
|
} finally {
|
|
218
259
|
setAddingMember(false);
|
|
219
260
|
}
|
|
220
261
|
};
|
|
221
262
|
|
|
222
263
|
// Render function for contact badges
|
|
223
|
-
const renderContactBadge = (contact: IUserWithSource) =>
|
|
224
|
-
<span>{contact.name}</span>
|
|
225
|
-
);
|
|
264
|
+
const renderContactBadge = (contact: IUserWithSource) => <span>{contact.name}</span>;
|
|
226
265
|
|
|
227
266
|
const updateRole = async (memberId: string, newRole: GroupMemberRole) => {
|
|
228
267
|
try {
|
|
@@ -230,23 +269,23 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
230
269
|
if (member) {
|
|
231
270
|
member.role = newRole;
|
|
232
271
|
await groupMembersTable.signAndSave(member);
|
|
233
|
-
setRefreshKey(prev => prev + 1);
|
|
272
|
+
setRefreshKey((prev) => prev + 1);
|
|
234
273
|
}
|
|
235
274
|
} catch (err) {
|
|
236
|
-
console.error(
|
|
237
|
-
alert(
|
|
275
|
+
console.error("Failed to update role:", err);
|
|
276
|
+
alert("Failed to update member role.");
|
|
238
277
|
}
|
|
239
278
|
};
|
|
240
279
|
|
|
241
280
|
const removeMember = async (memberId: string) => {
|
|
242
|
-
if (!confirm(
|
|
243
|
-
|
|
281
|
+
if (!confirm("Remove this member from the group?")) return;
|
|
282
|
+
|
|
244
283
|
try {
|
|
245
284
|
await groupMembersTable.delete(memberId);
|
|
246
|
-
setRefreshKey(prev => prev + 1);
|
|
285
|
+
setRefreshKey((prev) => prev + 1);
|
|
247
286
|
} catch (err) {
|
|
248
|
-
console.error(
|
|
249
|
-
alert(
|
|
287
|
+
console.error("Failed to remove member:", err);
|
|
288
|
+
alert("Failed to remove member.");
|
|
250
289
|
}
|
|
251
290
|
};
|
|
252
291
|
|
|
@@ -261,16 +300,20 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
261
300
|
<div className="d-flex justify-content-between align-items-center mb-3">
|
|
262
301
|
<h6 className="mb-0">Group Members</h6>
|
|
263
302
|
<div className="d-flex align-items-center gap-2">
|
|
264
|
-
<div
|
|
265
|
-
|
|
303
|
+
<div
|
|
304
|
+
className={`alert alert-${userRole ? "primary" : "warning"} py-2 px-3 mb-0 d-flex align-items-center`}
|
|
305
|
+
>
|
|
306
|
+
<i
|
|
307
|
+
className={`bi ${userRole ? "bi-person-badge" : "bi-exclamation-triangle"} me-2`}
|
|
308
|
+
></i>
|
|
266
309
|
<strong>Your role: {getRoleLabel(userRole)}</strong>
|
|
267
310
|
</div>
|
|
268
311
|
{/* Founder info - only show if current user is NOT the founder */}
|
|
269
312
|
{founderData && founderData.founderUserId !== currentUserId && (
|
|
270
|
-
<a
|
|
313
|
+
<a
|
|
271
314
|
href={`#contacts/${founderData.founderUserId}`}
|
|
272
315
|
className="alert alert-warning py-2 px-3 mb-0 d-flex align-items-center text-decoration-none"
|
|
273
|
-
style={{ cursor:
|
|
316
|
+
style={{ cursor: "pointer" }}
|
|
274
317
|
>
|
|
275
318
|
<i className="bi bi-crown-fill me-2"></i>
|
|
276
319
|
<strong>Founder: {founderData.founderUser?.name || founderData.founderUserId}</strong>
|
|
@@ -278,11 +321,9 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
278
321
|
)}
|
|
279
322
|
</div>
|
|
280
323
|
</div>
|
|
281
|
-
|
|
324
|
+
|
|
282
325
|
{/* Group Invite Listener - Only for admins/owners */}
|
|
283
|
-
{canEdit &&
|
|
284
|
-
<GroupInviteListener groupId={groupId} userContext={userContext} />
|
|
285
|
-
)}
|
|
326
|
+
{canEdit && <GroupInviteListener groupId={groupId} userContext={userContext} />}
|
|
286
327
|
|
|
287
328
|
{/* Add New Member - Only for admins/owners */}
|
|
288
329
|
{canEdit && (
|
|
@@ -297,16 +338,21 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
297
338
|
onSelectionChange={(items) => setSelectedContacts(items as IUserWithSource[])}
|
|
298
339
|
renderItem={renderContactItem}
|
|
299
340
|
renderBadge={renderContactBadge}
|
|
300
|
-
selectedItems={selectedContacts.map(contact => ({
|
|
341
|
+
selectedItems={selectedContacts.map((contact) => ({
|
|
342
|
+
...contact,
|
|
343
|
+
id: contact.userId,
|
|
344
|
+
}))}
|
|
301
345
|
multiSelect={true}
|
|
302
346
|
disabled={addingMember}
|
|
303
347
|
/>
|
|
304
348
|
</div>
|
|
305
349
|
<div className="col-md-3">
|
|
306
|
-
<select
|
|
307
|
-
className="form-select"
|
|
350
|
+
<select
|
|
351
|
+
className="form-select"
|
|
308
352
|
value={newMemberRole}
|
|
309
|
-
onChange={(e) =>
|
|
353
|
+
onChange={(e) =>
|
|
354
|
+
setNewMemberRole(Number(e.target.value) || (0 as GroupMemberRole))
|
|
355
|
+
}
|
|
310
356
|
disabled={addingMember}
|
|
311
357
|
>
|
|
312
358
|
<option value={GroupMemberRole.None}>None</option>
|
|
@@ -317,14 +363,18 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
317
363
|
</select>
|
|
318
364
|
</div>
|
|
319
365
|
<div className="col-md-3">
|
|
320
|
-
<button
|
|
321
|
-
className="btn btn-primary w-100"
|
|
366
|
+
<button
|
|
367
|
+
className="btn btn-primary w-100"
|
|
322
368
|
onClick={addMember}
|
|
323
369
|
disabled={addingMember || selectedContacts.length === 0}
|
|
324
370
|
>
|
|
325
|
-
{addingMember
|
|
326
|
-
|
|
327
|
-
|
|
371
|
+
{addingMember
|
|
372
|
+
? "Adding..."
|
|
373
|
+
: selectedContacts.length === 1
|
|
374
|
+
? "Add Member"
|
|
375
|
+
: selectedContacts.length > 1
|
|
376
|
+
? `Add ${selectedContacts.length} Members`
|
|
377
|
+
: "Add"}
|
|
328
378
|
</button>
|
|
329
379
|
</div>
|
|
330
380
|
</div>
|
|
@@ -339,7 +389,6 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
339
389
|
</div>
|
|
340
390
|
)}
|
|
341
391
|
|
|
342
|
-
|
|
343
392
|
{/* Members List */}
|
|
344
393
|
{membersData.length === 0 ? (
|
|
345
394
|
<div className="alert alert-info">
|
|
@@ -357,16 +406,16 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
357
406
|
<div className="d-flex align-items-center">
|
|
358
407
|
<strong>
|
|
359
408
|
{user?.name || member.userId}
|
|
360
|
-
{member.userId === currentUserId &&
|
|
409
|
+
{member.userId === currentUserId && " (You)"}
|
|
361
410
|
</strong>
|
|
362
|
-
{user?.source ===
|
|
363
|
-
<span className="badge bg-info ms-2" style={{ fontSize:
|
|
411
|
+
{user?.source === "userDataContext" && (
|
|
412
|
+
<span className="badge bg-info ms-2" style={{ fontSize: "0.7rem" }}>
|
|
364
413
|
<i className="bi bi-person me-1"></i>
|
|
365
414
|
Personal
|
|
366
415
|
</span>
|
|
367
416
|
)}
|
|
368
|
-
{user?.source ===
|
|
369
|
-
<span className="badge bg-secondary ms-2" style={{ fontSize:
|
|
417
|
+
{user?.source === "otherDataContexts" && (
|
|
418
|
+
<span className="badge bg-secondary ms-2" style={{ fontSize: "0.7rem" }}>
|
|
370
419
|
<i className="bi bi-people me-1"></i>
|
|
371
420
|
Other Groups
|
|
372
421
|
</span>
|
|
@@ -378,26 +427,34 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
378
427
|
</div>
|
|
379
428
|
</div>
|
|
380
429
|
</div>
|
|
381
|
-
|
|
430
|
+
|
|
382
431
|
<div className="d-flex align-items-center">
|
|
383
432
|
<div className="me-2">
|
|
384
433
|
<TrustLevelBadge level={user?.trustLevel || TrustLevel.Unknown} />
|
|
385
434
|
</div>
|
|
386
435
|
|
|
387
436
|
{/* View button - Always visible */}
|
|
388
|
-
<a
|
|
437
|
+
<a
|
|
438
|
+
href={`#contacts/${member.userId}`}
|
|
439
|
+
className="btn btn-outline-primary btn-sm me-2"
|
|
440
|
+
>
|
|
389
441
|
<i className="bi-eye me-1" />
|
|
390
442
|
View
|
|
391
443
|
</a>
|
|
392
|
-
|
|
444
|
+
|
|
393
445
|
{canEdit ? (
|
|
394
446
|
<>
|
|
395
447
|
{/* Role Selector - Only for admins/owners */}
|
|
396
|
-
<select
|
|
397
|
-
className="form-select form-select-sm me-2"
|
|
398
|
-
style={{ width:
|
|
448
|
+
<select
|
|
449
|
+
className="form-select form-select-sm me-2"
|
|
450
|
+
style={{ width: "120px" }}
|
|
399
451
|
value={member.role}
|
|
400
|
-
onChange={(e) =>
|
|
452
|
+
onChange={(e) =>
|
|
453
|
+
updateRole(
|
|
454
|
+
member.groupMemberId,
|
|
455
|
+
Number(e.target.value) || (0 as GroupMemberRole),
|
|
456
|
+
)
|
|
457
|
+
}
|
|
401
458
|
>
|
|
402
459
|
<option value={GroupMemberRole.None}>None</option>
|
|
403
460
|
<option value={GroupMemberRole.Reader}>Reader</option>
|
|
@@ -405,9 +462,9 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
405
462
|
<option value={GroupMemberRole.Admin}>Admin</option>
|
|
406
463
|
<option value={GroupMemberRole.Owner}>Owner</option>
|
|
407
464
|
</select>
|
|
408
|
-
|
|
465
|
+
|
|
409
466
|
{/* Remove Button - Only for admins/owners */}
|
|
410
|
-
<button
|
|
467
|
+
<button
|
|
411
468
|
className="btn btn-outline-danger btn-sm"
|
|
412
469
|
onClick={() => removeMember(member.groupMemberId)}
|
|
413
470
|
title="Remove member"
|
|
@@ -431,13 +488,17 @@ export const GroupMembersUI = (props: GroupMembersUIProps) => {
|
|
|
431
488
|
{/* Role Descriptions */}
|
|
432
489
|
<div className="mt-4">
|
|
433
490
|
<small className="text-muted">
|
|
434
|
-
<strong>Roles:</strong
|
|
435
|
-
<
|
|
436
|
-
<strong>
|
|
437
|
-
<
|
|
491
|
+
<strong>Roles:</strong>
|
|
492
|
+
<br />
|
|
493
|
+
<strong>Reader:</strong> Can view group content
|
|
494
|
+
<br />
|
|
495
|
+
<strong>Writer:</strong> Can create and edit content
|
|
496
|
+
<br />
|
|
497
|
+
<strong>Admin:</strong> Can manage members and settings
|
|
498
|
+
<br />
|
|
438
499
|
<strong>Owner:</strong> Full control including group deletion
|
|
439
500
|
</small>
|
|
440
501
|
</div>
|
|
441
502
|
</div>
|
|
442
503
|
);
|
|
443
|
-
};
|
|
504
|
+
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
1
|
// Import all group screen components to ensure they register their routes
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
2
|
+
import "./group-list";
|
|
3
|
+
import "./group-details";
|
|
4
|
+
import "./group-members";
|
|
6
5
|
|
|
7
|
-
export * from "./group-list";
|
|
8
6
|
export * from "./group-details";
|
|
9
|
-
export * from "./group-
|
|
7
|
+
export * from "./group-list";
|
|
8
|
+
export * from "./group-members";
|