@messenger-box/slack-ui-browser 10.0.3-alpha.176

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +21 -0
  3. package/lib/components/Home/Channels.js +62 -0
  4. package/lib/components/Home/Channels.js.map +1 -0
  5. package/lib/components/Home/DirectChannels.js +92 -0
  6. package/lib/components/Home/DirectChannels.js.map +1 -0
  7. package/lib/components/Home/InviteMembers.js +70 -0
  8. package/lib/components/Home/InviteMembers.js.map +1 -0
  9. package/lib/components/Home/Teams.js +62 -0
  10. package/lib/components/Home/Teams.js.map +1 -0
  11. package/lib/components/Home/TopCommonSlider.js +35 -0
  12. package/lib/components/Home/TopCommonSlider.js.map +1 -0
  13. package/lib/compute.js +223 -0
  14. package/lib/compute.js.map +1 -0
  15. package/lib/constants/routes.js +63 -0
  16. package/lib/constants/routes.js.map +1 -0
  17. package/lib/hooks/useOptimizedChannelsQueries.js +107 -0
  18. package/lib/hooks/useOptimizedChannelsQueries.js.map +1 -0
  19. package/lib/hooks/useRouteState.js +193 -0
  20. package/lib/hooks/useRouteState.js.map +1 -0
  21. package/lib/index.js +1 -0
  22. package/lib/index.js.map +1 -0
  23. package/lib/machines/routeMachine.js +804 -0
  24. package/lib/machines/routeMachine.js.map +1 -0
  25. package/lib/module.js +3 -0
  26. package/lib/module.js.map +1 -0
  27. package/lib/queries/slackuiQueries.js +144 -0
  28. package/lib/queries/slackuiQueries.js.map +1 -0
  29. package/lib/routes.json +260 -0
  30. package/lib/screens/Home/HomeScreen.js +664 -0
  31. package/lib/screens/Home/HomeScreen.js.map +1 -0
  32. package/lib/screens/Home/index.js +1 -0
  33. package/lib/screens/Home/index.js.map +1 -0
  34. package/package.json +52 -0
  35. package/rollup.config.mjs +41 -0
  36. package/src/components/Home/Channels.tsx +135 -0
  37. package/src/components/Home/DirectChannels.tsx +185 -0
  38. package/src/components/Home/InviteMembers.tsx +134 -0
  39. package/src/components/Home/Teams.tsx +129 -0
  40. package/src/components/Home/TopCommonSlider.tsx +70 -0
  41. package/src/components/Home/index.ts +5 -0
  42. package/src/components/index.ts +1 -0
  43. package/src/compute.ts +156 -0
  44. package/src/constants/index.ts +1 -0
  45. package/src/constants/routes.ts +92 -0
  46. package/src/hooks/index.ts +3 -0
  47. package/src/hooks/useOptimizedChannelsQueries.ts +165 -0
  48. package/src/hooks/useRouteState.ts +253 -0
  49. package/src/icons.ts +137 -0
  50. package/src/index.ts +11 -0
  51. package/src/machines/index.ts +9 -0
  52. package/src/machines/routeMachine.ts +682 -0
  53. package/src/module.tsx +6 -0
  54. package/src/queries/index.ts +1 -0
  55. package/src/queries/slackuiQueries.ts +227 -0
  56. package/src/screens/Home/HomeScreen.tsx +1308 -0
  57. package/src/screens/Home/index.ts +4 -0
  58. package/src/screens/NewChannel/NewChannelScreen.tsx +188 -0
  59. package/src/screens/NewChannel/index.ts +2 -0
  60. package/src/screens/index.ts +1 -0
  61. package/tsconfig.json +21 -0
@@ -0,0 +1,134 @@
1
+ import React, { useState, useCallback } from 'react';
2
+ import { useLocation, useNavigate } from '@remix-run/react';
3
+ import { FiShare2, FiUserPlus, FiMail, FiX } from '../../icons';
4
+ import { useTranslation } from 'react-i18next';
5
+
6
+ interface InviteMembersProps {
7
+ organizationName?: string;
8
+ sharableLink?: string;
9
+ }
10
+
11
+ export const InviteMembers: React.FC<InviteMembersProps> = ({
12
+ organizationName,
13
+ sharableLink
14
+ }) => {
15
+ const { t } = useTranslation();
16
+ const location = useLocation();
17
+ const navigate = useNavigate();
18
+ const [isModalOpen, setIsModalOpen] = useState(false);
19
+ const orgSlug = location.pathname.split('/')[2];
20
+
21
+ const handleShareLink = useCallback(async () => {
22
+ if (sharableLink) {
23
+ try {
24
+ if (navigator.share) {
25
+ await navigator.share({
26
+ title: `Join ${organizationName || 'our team'}`,
27
+ text: `Join us on the messenger platform`,
28
+ url: sharableLink,
29
+ });
30
+ } else {
31
+ // Fallback to copying to clipboard
32
+ await navigator.clipboard.writeText(sharableLink);
33
+ alert('Link copied to clipboard!');
34
+ }
35
+ } catch (error) {
36
+ console.error('Error sharing:', error);
37
+ }
38
+ }
39
+ setIsModalOpen(false);
40
+ }, [sharableLink, organizationName]);
41
+
42
+ const handleAddFromContacts = useCallback(() => {
43
+ navigate(`/o/${orgSlug}/home/invite/contacts`);
44
+ setIsModalOpen(false);
45
+ }, [navigate, orgSlug]);
46
+
47
+ const handleAddByEmail = useCallback(() => {
48
+ navigate(`/o/${orgSlug}/home/invite/email`);
49
+ setIsModalOpen(false);
50
+ }, [navigate, orgSlug]);
51
+
52
+ return (
53
+ <div className="py-2 px-4">
54
+ <button
55
+ onClick={() => setIsModalOpen(true)}
56
+ className="w-full flex items-center gap-3 py-3 px-3 hover:bg-gray-50 rounded-lg transition-colors"
57
+ >
58
+ <div className="p-2 bg-gray-100 rounded-full">
59
+ <FiUserPlus className="w-5 h-5 text-gray-600" />
60
+ </div>
61
+ <span className="text-gray-800 font-medium text-sm">Add teammates</span>
62
+ </button>
63
+
64
+ {/* Modal */}
65
+ {isModalOpen && (
66
+ <div className="fixed inset-0 z-50 flex items-center justify-center">
67
+ {/* Backdrop */}
68
+ <div
69
+ className="absolute inset-0 bg-black/50"
70
+ onClick={() => setIsModalOpen(false)}
71
+ />
72
+
73
+ {/* Modal Content */}
74
+ <div className="relative bg-white rounded-xl shadow-xl w-full max-w-md mx-4 overflow-hidden">
75
+ {/* Header */}
76
+ <div className="flex items-center justify-between px-6 py-4 border-b border-gray-200">
77
+ <h3 className="text-lg font-semibold text-gray-900">
78
+ Invite people to join your team
79
+ </h3>
80
+ <button
81
+ onClick={() => setIsModalOpen(false)}
82
+ className="p-2 hover:bg-gray-100 rounded-full transition-colors"
83
+ >
84
+ <FiX className="w-5 h-5 text-gray-500" />
85
+ </button>
86
+ </div>
87
+
88
+ {/* Actions */}
89
+ <div className="p-4 space-y-3">
90
+ {/* Share Link */}
91
+ <button
92
+ onClick={handleShareLink}
93
+ className="w-full flex items-center justify-center gap-2 py-3 px-4 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors font-medium"
94
+ >
95
+ <FiShare2 className="w-5 h-5" />
96
+ Share a Link
97
+ </button>
98
+
99
+ {/* Add from Contacts */}
100
+ <button
101
+ onClick={handleAddFromContacts}
102
+ className="w-full flex items-center justify-center gap-2 py-3 px-4 bg-gray-100 hover:bg-gray-200 text-gray-900 rounded-lg transition-colors font-medium"
103
+ >
104
+ <FiUserPlus className="w-5 h-5" />
105
+ Add from Contacts
106
+ </button>
107
+
108
+ {/* Add by Email */}
109
+ <button
110
+ onClick={handleAddByEmail}
111
+ className="w-full flex items-center justify-center gap-2 py-3 px-4 bg-gray-100 hover:bg-gray-200 text-gray-900 rounded-lg transition-colors font-medium"
112
+ >
113
+ <FiMail className="w-5 h-5" />
114
+ Add by Email
115
+ </button>
116
+ </div>
117
+
118
+ {/* Footer */}
119
+ <div className="px-6 py-4 border-t border-gray-200">
120
+ <button
121
+ onClick={() => setIsModalOpen(false)}
122
+ className="w-full py-2 text-gray-500 hover:text-gray-700 font-medium transition-colors"
123
+ >
124
+ Cancel
125
+ </button>
126
+ </div>
127
+ </div>
128
+ </div>
129
+ )}
130
+ </div>
131
+ );
132
+ };
133
+
134
+ export default React.memo(InviteMembers);
@@ -0,0 +1,129 @@
1
+ import React, { useState, useCallback, useContext } from 'react';
2
+ import { useLocation, useNavigate } from '@remix-run/react';
3
+ import { FiChevronDown, FiChevronRight, FiPlus, FiSearch, FiLock, FiRefreshCw } from '../../icons';
4
+ import { useTranslation } from 'react-i18next';
5
+
6
+ interface TeamsProps {
7
+ teams?: any[];
8
+ loading?: boolean;
9
+ error?: any;
10
+ onRefetch?: () => void;
11
+ }
12
+
13
+ export const Teams: React.FC<TeamsProps> = ({
14
+ teams = [],
15
+ loading = false,
16
+ error = null,
17
+ onRefetch
18
+ }) => {
19
+ const { t } = useTranslation();
20
+ const location = useLocation();
21
+ const navigate = useNavigate();
22
+ const [isExpanded, setIsExpanded] = useState(true);
23
+ const orgSlug = location.pathname.split('/')[2];
24
+
25
+ const handleTeamClick = useCallback((team: any) => {
26
+ navigate(`/o/${orgSlug}/home/team/${team.id}`, {
27
+ state: { team }
28
+ });
29
+ }, [navigate, orgSlug]);
30
+
31
+ const handleRefetch = useCallback(() => {
32
+ onRefetch?.();
33
+ }, [onRefetch]);
34
+
35
+ const ListEmptyComponent = () => {
36
+ if (error) {
37
+ return (
38
+ <div className="p-3">
39
+ <div className="p-2 bg-red-50 rounded">
40
+ <p className="text-red-600 text-sm mb-2 font-medium">
41
+ Team service is temporarily unavailable.
42
+ </p>
43
+ <button
44
+ onClick={handleRefetch}
45
+ className="flex items-center gap-1 text-blue-600 text-sm font-medium hover:underline"
46
+ >
47
+ <FiRefreshCw className="w-4 h-4" />
48
+ Retry
49
+ </button>
50
+ </div>
51
+ </div>
52
+ );
53
+ }
54
+
55
+ return (
56
+ <div className="flex flex-col items-center py-4 px-3">
57
+ <div className="p-3 mb-2 rounded-full bg-gray-100">
58
+ <FiLock className="w-5 h-5 text-gray-500" />
59
+ </div>
60
+ <p className="text-gray-500 text-sm text-center">No teams available</p>
61
+ </div>
62
+ );
63
+ };
64
+
65
+ return (
66
+ <div className="py-2">
67
+ {/* Section Header */}
68
+ <button
69
+ onClick={() => setIsExpanded(!isExpanded)}
70
+ className="w-full flex items-center justify-between px-4 py-2 hover:bg-gray-50"
71
+ >
72
+ <span className="font-semibold text-gray-900">Teams</span>
73
+ {isExpanded ? (
74
+ <FiChevronDown className="w-4 h-4 text-gray-600" />
75
+ ) : (
76
+ <FiChevronRight className="w-4 h-4 text-gray-600" />
77
+ )}
78
+ </button>
79
+
80
+ {/* Teams List */}
81
+ {isExpanded && (
82
+ <div className="mt-1">
83
+ {loading ? (
84
+ <div className="flex items-center justify-center py-4">
85
+ <div className="animate-spin rounded-full h-5 w-5 border-t-2 border-b-2 border-blue-500"></div>
86
+ </div>
87
+ ) : teams.length > 0 ? (
88
+ <>
89
+ {teams.map((team) => (
90
+ <button
91
+ key={team.id}
92
+ onClick={() => handleTeamClick(team)}
93
+ className="w-full flex items-center gap-3 px-4 py-2 hover:bg-gray-50 transition-colors"
94
+ >
95
+ <FiLock className="w-4 h-4 text-gray-500 flex-shrink-0" />
96
+ <span className="text-gray-900 text-sm truncate">{team.title}</span>
97
+ </button>
98
+ ))}
99
+
100
+ {/* Browse all teams */}
101
+ {teams.length >= 10 && (
102
+ <button
103
+ onClick={() => navigate(`/o/${orgSlug}/home/teams`)}
104
+ className="w-full flex items-center gap-3 px-4 py-2 hover:bg-gray-50 text-gray-500"
105
+ >
106
+ <FiSearch className="w-4 h-4" />
107
+ <span className="text-sm">Browse all Teams</span>
108
+ </button>
109
+ )}
110
+ </>
111
+ ) : (
112
+ <ListEmptyComponent />
113
+ )}
114
+
115
+ {/* Add Team */}
116
+ <button
117
+ onClick={() => navigate(`/o/${orgSlug}/home/teams/new`)}
118
+ className="w-full flex items-center gap-3 px-4 py-2 hover:bg-gray-50 text-gray-500"
119
+ >
120
+ <FiPlus className="w-4 h-4" />
121
+ <span className="text-sm">Add Team</span>
122
+ </button>
123
+ </div>
124
+ )}
125
+ </div>
126
+ );
127
+ };
128
+
129
+ export default React.memo(Teams);
@@ -0,0 +1,70 @@
1
+ import React from 'react';
2
+ import { useNavigate, useLocation } from '@remix-run/react';
3
+ import { FiMessageSquare, FiBookmark, FiSend } from '../../icons';
4
+
5
+ type SliderItem = {
6
+ id: number;
7
+ icon: React.ComponentType<{ className?: string }>;
8
+ title: string;
9
+ subTitle: string;
10
+ route: string | null;
11
+ };
12
+
13
+ const SLIDER_ITEMS: SliderItem[] = [
14
+ {
15
+ id: 1,
16
+ icon: FiMessageSquare,
17
+ title: 'Threads',
18
+ subTitle: '0 New',
19
+ route: 'threads',
20
+ },
21
+ {
22
+ id: 2,
23
+ icon: FiBookmark,
24
+ title: 'Later',
25
+ subTitle: '0 items',
26
+ route: null,
27
+ },
28
+ {
29
+ id: 3,
30
+ icon: FiSend,
31
+ title: 'Draft & Sent',
32
+ subTitle: '0 drafts',
33
+ route: null,
34
+ },
35
+ ];
36
+
37
+ export const TopCommonSlider: React.FC = () => {
38
+ const navigate = useNavigate();
39
+ const location = useLocation();
40
+ const orgSlug = location.pathname.split('/')[2];
41
+
42
+ const handleClick = (route: string | null) => {
43
+ if (route) {
44
+ navigate(`/o/${orgSlug}/home/${route}`);
45
+ }
46
+ };
47
+
48
+ return (
49
+ <div className="flex gap-3 px-4 py-3">
50
+ {SLIDER_ITEMS.map((item) => (
51
+ <button
52
+ key={item.id}
53
+ onClick={() => handleClick(item.route)}
54
+ disabled={!item.route}
55
+ className={`flex-1 flex flex-col items-center justify-center p-4 border border-gray-200 rounded-lg transition-all ${
56
+ item.route
57
+ ? 'hover:border-blue-400 hover:bg-blue-50 cursor-pointer'
58
+ : 'opacity-60 cursor-not-allowed'
59
+ }`}
60
+ >
61
+ <item.icon className="w-8 h-8 text-gray-700 mb-2" />
62
+ <span className="text-sm font-medium text-gray-800">{item.title}</span>
63
+ <span className="text-xs text-gray-500">{item.subTitle}</span>
64
+ </button>
65
+ ))}
66
+ </div>
67
+ );
68
+ };
69
+
70
+ export default React.memo(TopCommonSlider);
@@ -0,0 +1,5 @@
1
+ export { TopCommonSlider } from './TopCommonSlider';
2
+ export { Teams } from './Teams';
3
+ export { Channels } from './Channels';
4
+ export { DirectChannels } from './DirectChannels';
5
+ export { InviteMembers } from './InviteMembers';
@@ -0,0 +1 @@
1
+ export * from './Home';
package/src/compute.ts ADDED
@@ -0,0 +1,156 @@
1
+ import { getFilteredRoutes } from '@common-stack/client-react/lib/utils/filteredRoutes.js';
2
+ import type { IRouteModule } from '@common-stack/core';
3
+ import { IMenuPosition } from '@common-stack/client-react';
4
+ import { SLACK_UI_ROUTES, SLACK_UI_ROUTE_KEYS } from './constants/routes';
5
+
6
+ export const slackUiPageStore: IRouteModule[] = [
7
+ {
8
+ key: SLACK_UI_ROUTE_KEYS.HOME,
9
+ path: SLACK_UI_ROUTES.HOME,
10
+ name: 'Home',
11
+ exact: false,
12
+ position: IMenuPosition.Middle,
13
+ auth: true,
14
+ component: () => import('./screens/Home'),
15
+ icon: 'AiOutlineHome',
16
+ tab: 'Home',
17
+ },
18
+ // Channel routes
19
+ {
20
+ key: SLACK_UI_ROUTE_KEYS.CHANNELS,
21
+ path: SLACK_UI_ROUTES.CHANNELS,
22
+ name: 'Channel',
23
+ exact: true,
24
+ auth: true,
25
+ component: () => import('./screens/Home'),
26
+ },
27
+ {
28
+ key: SLACK_UI_ROUTE_KEYS.CHANNELS_NEW,
29
+ path: SLACK_UI_ROUTES.CHANNELS_NEW,
30
+ name: 'New Channel',
31
+ exact: true,
32
+ auth: true,
33
+ component: () => import('./screens/Home'),
34
+ },
35
+ // Message routes
36
+ {
37
+ key: SLACK_UI_ROUTE_KEYS.MESSAGES,
38
+ path: SLACK_UI_ROUTES.MESSAGES,
39
+ name: 'Direct Message',
40
+ exact: true,
41
+ auth: true,
42
+ component: () => import('./screens/Home'),
43
+ },
44
+ {
45
+ key: SLACK_UI_ROUTE_KEYS.MESSAGES_NEW,
46
+ path: SLACK_UI_ROUTES.MESSAGES_NEW,
47
+ name: 'New Message',
48
+ exact: true,
49
+ auth: true,
50
+ component: () => import('./screens/Home'),
51
+ },
52
+ // Team routes
53
+ {
54
+ key: SLACK_UI_ROUTE_KEYS.TEAMS,
55
+ path: SLACK_UI_ROUTES.TEAMS,
56
+ name: 'Team',
57
+ exact: true,
58
+ auth: true,
59
+ component: () => import('./screens/Home'),
60
+ },
61
+ {
62
+ key: SLACK_UI_ROUTE_KEYS.TEAMS_NEW,
63
+ path: SLACK_UI_ROUTES.TEAMS_NEW,
64
+ name: 'New Team',
65
+ exact: true,
66
+ auth: true,
67
+ component: () => import('./screens/Home'),
68
+ },
69
+ // Invite routes
70
+ {
71
+ key: SLACK_UI_ROUTE_KEYS.INVITE,
72
+ path: SLACK_UI_ROUTES.INVITE,
73
+ name: 'Invite Members',
74
+ exact: true,
75
+ auth: true,
76
+ component: () => import('./screens/Home'),
77
+ },
78
+ {
79
+ key: SLACK_UI_ROUTE_KEYS.INVITE_CONTACTS,
80
+ path: SLACK_UI_ROUTES.INVITE_CONTACTS,
81
+ name: 'Invite from Contacts',
82
+ exact: true,
83
+ auth: true,
84
+ component: () => import('./screens/Home'),
85
+ },
86
+ {
87
+ key: SLACK_UI_ROUTE_KEYS.INVITE_EMAIL,
88
+ path: SLACK_UI_ROUTES.INVITE_EMAIL,
89
+ name: 'Invite by Email',
90
+ exact: true,
91
+ auth: true,
92
+ component: () => import('./screens/Home'),
93
+ },
94
+ {
95
+ key: SLACK_UI_ROUTE_KEYS.INVITE_LINK,
96
+ path: SLACK_UI_ROUTES.INVITE_LINK,
97
+ name: 'Invite Link',
98
+ exact: true,
99
+ auth: true,
100
+ component: () => import('./screens/Home'),
101
+ },
102
+ // Other routes
103
+ {
104
+ key: SLACK_UI_ROUTE_KEYS.THREADS,
105
+ path: SLACK_UI_ROUTES.THREADS,
106
+ name: 'Threads',
107
+ exact: true,
108
+ auth: true,
109
+ component: () => import('./screens/Home'),
110
+ },
111
+ {
112
+ key: SLACK_UI_ROUTE_KEYS.ACTIVITY,
113
+ path: SLACK_UI_ROUTES.ACTIVITY,
114
+ name: 'Activity',
115
+ exact: true,
116
+ auth: true,
117
+ component: () => import('./screens/Home'),
118
+ },
119
+ {
120
+ key: SLACK_UI_ROUTE_KEYS.DRAFTS,
121
+ path: SLACK_UI_ROUTES.DRAFTS,
122
+ name: 'Drafts',
123
+ exact: true,
124
+ auth: true,
125
+ component: () => import('./screens/Home'),
126
+ },
127
+ {
128
+ key: SLACK_UI_ROUTE_KEYS.SAVED,
129
+ path: SLACK_UI_ROUTES.SAVED,
130
+ name: 'Saved Items',
131
+ exact: true,
132
+ auth: true,
133
+ component: () => import('./screens/Home'),
134
+ },
135
+ {
136
+ key: SLACK_UI_ROUTE_KEYS.FILES,
137
+ path: SLACK_UI_ROUTES.FILES,
138
+ name: 'Files',
139
+ exact: true,
140
+ auth: true,
141
+ component: () => import('./screens/Home'),
142
+ },
143
+ {
144
+ key: SLACK_UI_ROUTE_KEYS.SEARCH,
145
+ path: SLACK_UI_ROUTES.SEARCH,
146
+ name: 'Search',
147
+ exact: true,
148
+ auth: true,
149
+ component: () => import('./screens/Home'),
150
+ },
151
+ ];
152
+
153
+ // Get filtered routes
154
+ const filteredRoutes = getFilteredRoutes(slackUiPageStore);
155
+
156
+ export { filteredRoutes };
@@ -0,0 +1 @@
1
+ export * from './routes';
@@ -0,0 +1,92 @@
1
+ import { ORG_STD_ROUTES } from '@adminide-stack/core/lib/constants/urls.js';
2
+
3
+ /**
4
+ * Slack UI Routes Enum
5
+ * Centralized route definitions for the slack-ui browser package
6
+ */
7
+ export enum SLACK_UI_ROUTES {
8
+ // Base paths
9
+ HOME = '/o/:orgName/home',
10
+
11
+ // Channel routes
12
+ CHANNELS = '/o/:orgName/home/channels/:channelName',
13
+ CHANNELS_NEW = '/o/:orgName/home/channels/new',
14
+
15
+ // Direct message routes
16
+ MESSAGES = '/o/:orgName/home/messages/:channelName',
17
+ MESSAGES_NEW = '/o/:orgName/home/messages/new',
18
+
19
+ // Team routes
20
+ TEAMS = '/o/:orgName/home/teams/:teamName',
21
+ TEAMS_NEW = '/o/:orgName/home/teams/new',
22
+
23
+ // Invite routes
24
+ INVITE = '/o/:orgName/home/invite',
25
+ INVITE_CONTACTS = '/o/:orgName/home/invite/contacts',
26
+ INVITE_EMAIL = '/o/:orgName/home/invite/email',
27
+ INVITE_LINK = '/o/:orgName/home/invite/link',
28
+
29
+ // Other routes
30
+ THREADS = '/o/:orgName/home/threads',
31
+ ACTIVITY = '/o/:orgName/home/activity',
32
+ DRAFTS = '/o/:orgName/home/drafts',
33
+ SAVED = '/o/:orgName/home/saved',
34
+ FILES = '/o/:orgName/home/files',
35
+ SEARCH = '/o/:orgName/home/search',
36
+ }
37
+
38
+ /**
39
+ * Route path builders with type safety
40
+ */
41
+ export const slackUiRoutePaths = {
42
+ home: (orgName: string) => `/o/${orgName}/home`,
43
+
44
+ // Channels
45
+ channel: (orgName: string, channelName: string) => `/o/${orgName}/home/channels/${channelName}`,
46
+ channelNew: (orgName: string) => `/o/${orgName}/home/channels/new`,
47
+
48
+ // Direct Messages
49
+ message: (orgName: string, channelName: string) => `/o/${orgName}/home/messages/${channelName}`,
50
+ messageNew: (orgName: string) => `/o/${orgName}/home/messages/new`,
51
+
52
+ // Teams
53
+ team: (orgName: string, teamName: string) => `/o/${orgName}/home/teams/${teamName}`,
54
+ teamNew: (orgName: string) => `/o/${orgName}/home/teams/new`,
55
+
56
+ // Invite
57
+ invite: (orgName: string) => `/o/${orgName}/home/invite`,
58
+ inviteContacts: (orgName: string) => `/o/${orgName}/home/invite/contacts`,
59
+ inviteEmail: (orgName: string) => `/o/${orgName}/home/invite/email`,
60
+ inviteLink: (orgName: string) => `/o/${orgName}/home/invite/link`,
61
+
62
+ // Other
63
+ threads: (orgName: string) => `/o/${orgName}/home/threads`,
64
+ activity: (orgName: string) => `/o/${orgName}/home/activity`,
65
+ drafts: (orgName: string) => `/o/${orgName}/home/drafts`,
66
+ saved: (orgName: string) => `/o/${orgName}/home/saved`,
67
+ files: (orgName: string) => `/o/${orgName}/home/files`,
68
+ search: (orgName: string) => `/o/${orgName}/home/search`,
69
+ };
70
+
71
+ /**
72
+ * Route keys for route matching
73
+ */
74
+ export const SLACK_UI_ROUTE_KEYS = {
75
+ HOME: 'home',
76
+ CHANNELS: 'home-channels',
77
+ CHANNELS_NEW: 'home-channels-new',
78
+ MESSAGES: 'home-messages',
79
+ MESSAGES_NEW: 'home-messages-new',
80
+ TEAMS: 'home-teams',
81
+ TEAMS_NEW: 'home-teams-new',
82
+ INVITE: 'home-invite',
83
+ INVITE_CONTACTS: 'home-invite-contacts',
84
+ INVITE_EMAIL: 'home-invite-email',
85
+ INVITE_LINK: 'home-invite-link',
86
+ THREADS: 'home-threads',
87
+ ACTIVITY: 'home-activity',
88
+ DRAFTS: 'home-drafts',
89
+ SAVED: 'home-saved',
90
+ FILES: 'home-files',
91
+ SEARCH: 'home-search',
92
+ } as const;
@@ -0,0 +1,3 @@
1
+ export { useOptimizedChannelsQueries, useChannelTypeQuery } from './useOptimizedChannelsQueries';
2
+ export { useRouteState } from './useRouteState';
3
+ export type { UseRouteStateReturn } from './useRouteState';