@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.
- package/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/lib/components/Home/Channels.js +62 -0
- package/lib/components/Home/Channels.js.map +1 -0
- package/lib/components/Home/DirectChannels.js +92 -0
- package/lib/components/Home/DirectChannels.js.map +1 -0
- package/lib/components/Home/InviteMembers.js +70 -0
- package/lib/components/Home/InviteMembers.js.map +1 -0
- package/lib/components/Home/Teams.js +62 -0
- package/lib/components/Home/Teams.js.map +1 -0
- package/lib/components/Home/TopCommonSlider.js +35 -0
- package/lib/components/Home/TopCommonSlider.js.map +1 -0
- package/lib/compute.js +223 -0
- package/lib/compute.js.map +1 -0
- package/lib/constants/routes.js +63 -0
- package/lib/constants/routes.js.map +1 -0
- package/lib/hooks/useOptimizedChannelsQueries.js +107 -0
- package/lib/hooks/useOptimizedChannelsQueries.js.map +1 -0
- package/lib/hooks/useRouteState.js +193 -0
- package/lib/hooks/useRouteState.js.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/machines/routeMachine.js +804 -0
- package/lib/machines/routeMachine.js.map +1 -0
- package/lib/module.js +3 -0
- package/lib/module.js.map +1 -0
- package/lib/queries/slackuiQueries.js +144 -0
- package/lib/queries/slackuiQueries.js.map +1 -0
- package/lib/routes.json +260 -0
- package/lib/screens/Home/HomeScreen.js +664 -0
- package/lib/screens/Home/HomeScreen.js.map +1 -0
- package/lib/screens/Home/index.js +1 -0
- package/lib/screens/Home/index.js.map +1 -0
- package/package.json +52 -0
- package/rollup.config.mjs +41 -0
- package/src/components/Home/Channels.tsx +135 -0
- package/src/components/Home/DirectChannels.tsx +185 -0
- package/src/components/Home/InviteMembers.tsx +134 -0
- package/src/components/Home/Teams.tsx +129 -0
- package/src/components/Home/TopCommonSlider.tsx +70 -0
- package/src/components/Home/index.ts +5 -0
- package/src/components/index.ts +1 -0
- package/src/compute.ts +156 -0
- package/src/constants/index.ts +1 -0
- package/src/constants/routes.ts +92 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useOptimizedChannelsQueries.ts +165 -0
- package/src/hooks/useRouteState.ts +253 -0
- package/src/icons.ts +137 -0
- package/src/index.ts +11 -0
- package/src/machines/index.ts +9 -0
- package/src/machines/routeMachine.ts +682 -0
- package/src/module.tsx +6 -0
- package/src/queries/index.ts +1 -0
- package/src/queries/slackuiQueries.ts +227 -0
- package/src/screens/Home/HomeScreen.tsx +1308 -0
- package/src/screens/Home/index.ts +4 -0
- package/src/screens/NewChannel/NewChannelScreen.tsx +188 -0
- package/src/screens/NewChannel/index.ts +2 -0
- package/src/screens/index.ts +1 -0
- 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 @@
|
|
|
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;
|