@adminide-stack/yantra-mobile 12.0.39-alpha.9 → 12.0.39

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 (37) hide show
  1. package/lib/components/AppsMenu/AppsMenu.js +285 -0
  2. package/lib/components/AppsMenu/AppsMenu.js.map +1 -0
  3. package/lib/components/GatewayConnector/GatewayConnector.js +5 -2
  4. package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -1
  5. package/lib/components/GatewayToolbarButtonMobile.js +25 -53
  6. package/lib/components/GatewayToolbarButtonMobile.js.map +1 -1
  7. package/lib/components/NavigationHeader/NavigationHeader.js +19 -11
  8. package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -1
  9. package/lib/compute.js +2 -0
  10. package/lib/compute.js.map +1 -1
  11. package/lib/config/constants.js +2 -2
  12. package/lib/config/constants.js.map +1 -1
  13. package/lib/contexts/GatewayContext.js +1 -1
  14. package/lib/features/apps/mobileAppCatalog.js +153 -0
  15. package/lib/features/apps/mobileAppCatalog.js.map +1 -0
  16. package/lib/features/templates/__tests__/buildTemplateCards.test.ts +57 -0
  17. package/lib/features/templates/buildTemplateCards.js +28 -2
  18. package/lib/features/templates/buildTemplateCards.js.map +1 -1
  19. package/lib/features/templates/buildTemplateCards.ts +44 -1
  20. package/lib/hooks/useMarketplaceTemplateCards.js +5 -2
  21. package/lib/hooks/useMarketplaceTemplateCards.js.map +1 -1
  22. package/lib/hooks/useMarketplaceTemplateGroups.js +9 -2
  23. package/lib/hooks/useMarketplaceTemplateGroups.js.map +1 -1
  24. package/lib/routes.json +2 -0
  25. package/lib/screens/Home/HomeScreen.js +44 -150
  26. package/lib/screens/Home/HomeScreen.js.map +1 -1
  27. package/lib/screens/Home/components/BuildTemplatesSection.js +142 -87
  28. package/lib/screens/Home/components/BuildTemplatesSection.js.map +1 -1
  29. package/lib/screens/Home/components/ChooseTemplateModal.js +261 -0
  30. package/lib/screens/Home/components/ChooseTemplateModal.js.map +1 -0
  31. package/lib/screens/Home/components/HomeSuggestions.js +109 -0
  32. package/lib/screens/Home/components/HomeSuggestions.js.map +1 -0
  33. package/lib/screens/Home/components/TemplateBrowserModal.js +237 -0
  34. package/lib/screens/Home/components/TemplateBrowserModal.js.map +1 -0
  35. package/lib/theme/mobileTokens.js +0 -5
  36. package/lib/theme/mobileTokens.js.map +1 -1
  37. package/package.json +4 -4
@@ -0,0 +1,285 @@
1
+ import {jsxs,Fragment,jsx}from'react/jsx-runtime';import {useState,useCallback,useMemo}from'react';import {Pressable,StyleSheet,Text,useWindowDimensions,Modal,View,TextInput,ScrollView}from'react-native';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {useSafeAreaInsets}from'react-native-safe-area-context';import {v4}from'uuid';import {groupMobileApps,MOBILE_APP_CATALOG}from'../../features/apps/mobileAppCatalog.js';import {useChatMutations}from'../../hooks/useChatApi.js';import {mobileTokens}from'../../theme/mobileTokens.js';var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ function buildChannelTitle(channelId) {
21
+ return `chat-channel-${channelId}`;
22
+ }
23
+ function AppsMenuTrigger({
24
+ isDark,
25
+ compact,
26
+ onPress
27
+ }) {
28
+ const ink = isDark ? "#e2e8f0" : mobileTokens.color.text;
29
+ const muted = isDark ? "#94a3b8" : mobileTokens.color.textMuted;
30
+ return /* @__PURE__ */ jsxs(Pressable, { onPress, accessibilityRole: "button", accessibilityLabel: "Apps", hitSlop: 6, style: ({
31
+ pressed
32
+ }) => [styles.trigger, pressed && styles.triggerPressed], children: [
33
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "view-grid-outline", size: 18, color: ink }),
34
+ compact ? null : /* @__PURE__ */ jsx(Text, { style: [styles.triggerLabel, {
35
+ color: ink
36
+ }], numberOfLines: 1, children: "Apps" }),
37
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-down", size: 14, color: muted })
38
+ ] });
39
+ }
40
+ function AppsMenuSheet({
41
+ isDark,
42
+ orgName: orgNameProp,
43
+ onClose
44
+ }) {
45
+ var _a;
46
+ const navigation = useNavigation();
47
+ const route = useRoute();
48
+ const insets = useSafeAreaInsets();
49
+ const {
50
+ height: windowHeight
51
+ } = useWindowDimensions();
52
+ const {
53
+ createChannel
54
+ } = useChatMutations();
55
+ const [query, setQuery] = useState("");
56
+ const orgName = useMemo(() => {
57
+ var _a2, _b;
58
+ if (typeof orgNameProp === "string" && orgNameProp.trim()) return orgNameProp.trim();
59
+ const raw = (_b = (_a2 = route == null ? void 0 : route.params) == null ? void 0 : _a2.orgName) != null ? _b : "";
60
+ return typeof raw === "string" && raw.trim() ? raw.trim() : null;
61
+ }, [orgNameProp, (_a = route == null ? void 0 : route.params) == null ? void 0 : _a.orgName]);
62
+ const grouped = useMemo(() => groupMobileApps(MOBILE_APP_CATALOG, query), [query]);
63
+ const muted = isDark ? "#94a3b8" : mobileTokens.color.textMuted;
64
+ const foreground = isDark ? "#e2e8f0" : mobileTokens.color.text;
65
+ const surface = isDark ? "#111827" : mobileTokens.color.surface;
66
+ const sheetBg = isDark ? "#0f172a" : mobileTokens.color.surface;
67
+ const borderColor = isDark ? "rgba(148,163,184,0.22)" : mobileTokens.color.border;
68
+ const fieldBg = isDark ? "#1e293b" : mobileTokens.color.surfaceMuted;
69
+ const accent = isDark ? "#a5b4fc" : mobileTokens.color.primary;
70
+ const accentSoft = isDark ? "rgba(99,102,241,0.18)" : mobileTokens.color.primarySoft;
71
+ const openApp = useCallback((app) => {
72
+ onClose();
73
+ const channelId = v4();
74
+ const params = {
75
+ orgName: orgName != null ? orgName : void 0,
76
+ channelId
77
+ };
78
+ if (app.nativeRoute === "webbuilder") {
79
+ navigation.dispatch(CommonActions.navigate({
80
+ name: "MainStack.WebBuilder",
81
+ params
82
+ }));
83
+ return;
84
+ }
85
+ void createChannel({
86
+ id: channelId,
87
+ title: buildChannelTitle(channelId),
88
+ isShared: false,
89
+ sharedSlug: null,
90
+ isArchived: false,
91
+ isPinned: false,
92
+ model: null,
93
+ systemPrompt: null,
94
+ orgName
95
+ }).catch((err) => {
96
+ console.error("[AppsMenu] createChannel failed:", err);
97
+ });
98
+ navigation.dispatch(CommonActions.navigate({
99
+ name: "MainStack.Chat",
100
+ params: __spreadProps(__spreadValues({}, params), {
101
+ initialQuery: app.prompt,
102
+ initialMode: "chat"
103
+ })
104
+ }));
105
+ }, [createChannel, navigation, onClose, orgName]);
106
+ return /* @__PURE__ */ jsx(Modal, { visible: true, animationType: "slide", transparent: true, onRequestClose: onClose, children: /* @__PURE__ */ jsxs(View, { style: styles.modalRoot, children: [
107
+ /* @__PURE__ */ jsx(Pressable, { style: styles.backdrop, onPress: onClose, accessibilityLabel: "Close apps" }),
108
+ /* @__PURE__ */ jsxs(View, { style: [styles.sheet, {
109
+ backgroundColor: sheetBg,
110
+ maxHeight: Math.round(windowHeight * 0.86),
111
+ paddingBottom: Math.max(insets.bottom, 12)
112
+ }], children: [
113
+ /* @__PURE__ */ jsx(View, { style: styles.handleWrap, children: /* @__PURE__ */ jsx(View, { style: [styles.handle, {
114
+ backgroundColor: borderColor
115
+ }] }) }),
116
+ /* @__PURE__ */ jsxs(View, { style: styles.header, children: [
117
+ /* @__PURE__ */ jsx(Text, { style: [styles.title, {
118
+ color: foreground
119
+ }], children: "Apps" }),
120
+ /* @__PURE__ */ jsx(Pressable, { onPress: onClose, hitSlop: 10, accessibilityLabel: "Close", accessibilityRole: "button", children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "close", size: 22, color: muted }) })
121
+ ] }),
122
+ /* @__PURE__ */ jsxs(View, { style: [styles.searchWrap, {
123
+ backgroundColor: fieldBg,
124
+ borderColor
125
+ }], children: [
126
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "magnify", size: 18, color: muted }),
127
+ /* @__PURE__ */ jsx(TextInput, { value: query, onChangeText: setQuery, placeholder: "Search apps", placeholderTextColor: muted, autoCorrect: false, autoCapitalize: "none", style: [styles.searchInput, {
128
+ color: foreground
129
+ }] })
130
+ ] }),
131
+ /* @__PURE__ */ jsx(ScrollView, { keyboardShouldPersistTaps: "handled", contentContainerStyle: styles.list, children: grouped.length === 0 ? /* @__PURE__ */ jsx(Text, { style: [styles.empty, {
132
+ color: muted
133
+ }], children: "No apps match that search." }) : grouped.map((group) => /* @__PURE__ */ jsxs(View, { style: styles.group, children: [
134
+ /* @__PURE__ */ jsx(Text, { style: [styles.groupLabel, {
135
+ color: muted
136
+ }], children: group.label }),
137
+ /* @__PURE__ */ jsx(View, { style: styles.groupGrid, children: group.items.map((app) => /* @__PURE__ */ jsxs(Pressable, { onPress: () => openApp(app), accessibilityRole: "button", accessibilityLabel: app.label, style: ({
138
+ pressed
139
+ }) => [styles.appTile, {
140
+ backgroundColor: surface,
141
+ borderColor
142
+ }, pressed && {
143
+ backgroundColor: accentSoft
144
+ }], children: [
145
+ /* @__PURE__ */ jsx(View, { style: [styles.appIcon, {
146
+ backgroundColor: accentSoft
147
+ }], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: app.icon, size: 18, color: accent }) }),
148
+ /* @__PURE__ */ jsx(Text, { style: [styles.appLabel, {
149
+ color: foreground
150
+ }], numberOfLines: 2, children: app.label })
151
+ ] }, app.key)) })
152
+ ] }, group.label)) })
153
+ ] })
154
+ ] }) });
155
+ }
156
+ function AppsMenu({
157
+ isDark,
158
+ compact = false,
159
+ orgName
160
+ }) {
161
+ const [open, setOpen] = useState(false);
162
+ const close = useCallback(() => setOpen(false), []);
163
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
164
+ /* @__PURE__ */ jsx(AppsMenuTrigger, { isDark, compact, onPress: () => setOpen(true) }),
165
+ open ? /* @__PURE__ */ jsx(AppsMenuSheet, { isDark, orgName, onClose: close }) : null
166
+ ] });
167
+ }
168
+ const styles = StyleSheet.create({
169
+ trigger: {
170
+ flexDirection: "row",
171
+ alignItems: "center",
172
+ flexShrink: 0,
173
+ gap: 4,
174
+ height: 36,
175
+ paddingHorizontal: 8,
176
+ borderRadius: 10
177
+ },
178
+ triggerPressed: {
179
+ opacity: 0.7
180
+ },
181
+ triggerLabel: {
182
+ fontSize: 15,
183
+ fontWeight: "600",
184
+ letterSpacing: -0.2
185
+ },
186
+ modalRoot: {
187
+ flex: 1,
188
+ justifyContent: "flex-end"
189
+ },
190
+ backdrop: __spreadProps(__spreadValues({}, StyleSheet.absoluteFillObject), {
191
+ backgroundColor: "rgba(15, 23, 42, 0.36)"
192
+ }),
193
+ sheet: {
194
+ borderTopLeftRadius: 18,
195
+ borderTopRightRadius: 18,
196
+ width: "100%",
197
+ overflow: "hidden"
198
+ },
199
+ handleWrap: {
200
+ alignItems: "center",
201
+ paddingTop: 8,
202
+ paddingBottom: 4
203
+ },
204
+ handle: {
205
+ width: 36,
206
+ height: 4,
207
+ borderRadius: 999
208
+ },
209
+ header: {
210
+ flexDirection: "row",
211
+ alignItems: "center",
212
+ justifyContent: "space-between",
213
+ paddingHorizontal: 16,
214
+ paddingBottom: 8
215
+ },
216
+ title: {
217
+ fontSize: 20,
218
+ fontWeight: "700",
219
+ letterSpacing: -0.4
220
+ },
221
+ searchWrap: {
222
+ flexDirection: "row",
223
+ alignItems: "center",
224
+ gap: 8,
225
+ marginHorizontal: 16,
226
+ marginBottom: 8,
227
+ borderWidth: 1,
228
+ borderRadius: 12,
229
+ paddingHorizontal: 12,
230
+ minHeight: 42
231
+ },
232
+ searchInput: {
233
+ flex: 1,
234
+ fontSize: 15,
235
+ paddingVertical: 8
236
+ },
237
+ list: {
238
+ paddingHorizontal: 16,
239
+ paddingTop: 8,
240
+ paddingBottom: 20,
241
+ gap: 16
242
+ },
243
+ group: {
244
+ gap: 8
245
+ },
246
+ groupLabel: {
247
+ fontSize: 11,
248
+ fontWeight: "600",
249
+ letterSpacing: 0.7,
250
+ textTransform: "uppercase"
251
+ },
252
+ groupGrid: {
253
+ flexDirection: "row",
254
+ flexWrap: "wrap",
255
+ gap: 8
256
+ },
257
+ appTile: {
258
+ width: "31%",
259
+ flexGrow: 1,
260
+ minWidth: 96,
261
+ maxWidth: "32.5%",
262
+ borderWidth: 1,
263
+ borderRadius: 14,
264
+ paddingHorizontal: 10,
265
+ paddingVertical: 12,
266
+ gap: 8
267
+ },
268
+ appIcon: {
269
+ width: 32,
270
+ height: 32,
271
+ borderRadius: 10,
272
+ alignItems: "center",
273
+ justifyContent: "center"
274
+ },
275
+ appLabel: {
276
+ fontSize: 13,
277
+ fontWeight: "600",
278
+ lineHeight: 17
279
+ },
280
+ empty: {
281
+ textAlign: "center",
282
+ paddingVertical: 28,
283
+ fontSize: 14
284
+ }
285
+ });export{AppsMenu,AppsMenu as default};//# sourceMappingURL=AppsMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppsMenu.js","sources":["../../../src/components/AppsMenu/AppsMenu.tsx"],"sourcesContent":["/**\n * Apps launcher for the mobile header. Mirrors the browser ChatTopBar Apps menu:\n * one trigger, grouped catalog, search, then navigate into a native surface or chat.\n *\n * The trigger is a separate component so Apollo/chat hooks cannot prevent the\n * header control from mounting.\n */\nimport React, { useCallback, useMemo, useState } from 'react';\nimport { Modal, Pressable, ScrollView, StyleSheet, Text, TextInput, View, useWindowDimensions } from 'react-native';\nimport { CommonActions, useNavigation, useRoute } from '@react-navigation/native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { v4 as uuidv4 } from 'uuid';\nimport { groupMobileApps, MOBILE_APP_CATALOG, type MobileAppItem } from '../../features/apps/mobileAppCatalog';\nimport { useChatMutations } from '../../hooks/useChatApi';\nimport { mobileTokens } from '../../theme/mobileTokens';\n\nexport type AppsMenuProps = {\n isDark: boolean;\n compact?: boolean;\n orgName?: string | null;\n};\n\nfunction buildChannelTitle(channelId: string): string {\n return `chat-channel-${channelId}`;\n}\n\nfunction AppsMenuTrigger({ isDark, compact, onPress }: { isDark: boolean; compact: boolean; onPress: () => void }) {\n const ink = isDark ? '#e2e8f0' : mobileTokens.color.text;\n const muted = isDark ? '#94a3b8' : mobileTokens.color.textMuted;\n\n return (\n <Pressable\n onPress={onPress}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Apps\"\n hitSlop={6}\n style={({ pressed }) => [styles.trigger, pressed && styles.triggerPressed]}\n >\n <MaterialCommunityIcons name=\"view-grid-outline\" size={18} color={ink} />\n {compact ? null : (\n <Text style={[styles.triggerLabel, { color: ink }]} numberOfLines={1}>\n Apps\n </Text>\n )}\n <MaterialCommunityIcons name=\"chevron-down\" size={14} color={muted} />\n </Pressable>\n );\n}\n\nfunction AppsMenuSheet({\n isDark,\n orgName: orgNameProp,\n onClose,\n}: {\n isDark: boolean;\n orgName?: string | null;\n onClose: () => void;\n}) {\n const navigation = useNavigation<any>();\n const route = useRoute<any>();\n const insets = useSafeAreaInsets();\n const { height: windowHeight } = useWindowDimensions();\n const { createChannel } = useChatMutations();\n const [query, setQuery] = useState('');\n\n const orgName = useMemo(() => {\n if (typeof orgNameProp === 'string' && orgNameProp.trim()) return orgNameProp.trim();\n const raw = (route?.params?.orgName as string | undefined) ?? '';\n return typeof raw === 'string' && raw.trim() ? raw.trim() : null;\n }, [orgNameProp, route?.params?.orgName]);\n\n const grouped = useMemo(() => groupMobileApps(MOBILE_APP_CATALOG, query), [query]);\n\n const muted = isDark ? '#94a3b8' : mobileTokens.color.textMuted;\n const foreground = isDark ? '#e2e8f0' : mobileTokens.color.text;\n const surface = isDark ? '#111827' : mobileTokens.color.surface;\n const sheetBg = isDark ? '#0f172a' : mobileTokens.color.surface;\n const borderColor = isDark ? 'rgba(148,163,184,0.22)' : mobileTokens.color.border;\n const fieldBg = isDark ? '#1e293b' : mobileTokens.color.surfaceMuted;\n const accent = isDark ? '#a5b4fc' : mobileTokens.color.primary;\n const accentSoft = isDark ? 'rgba(99,102,241,0.18)' : mobileTokens.color.primarySoft;\n\n const openApp = useCallback(\n (app: MobileAppItem) => {\n onClose();\n const channelId = uuidv4();\n const params: Record<string, unknown> = {\n orgName: orgName ?? undefined,\n channelId,\n };\n\n if (app.nativeRoute === 'webbuilder') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilder',\n params,\n }),\n );\n return;\n }\n\n void createChannel({\n id: channelId,\n title: buildChannelTitle(channelId),\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: null,\n systemPrompt: null,\n orgName,\n } as any).catch((err) => {\n console.error('[AppsMenu] createChannel failed:', err);\n });\n\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.Chat',\n params: {\n ...params,\n initialQuery: app.prompt,\n initialMode: 'chat',\n },\n }),\n );\n },\n [createChannel, navigation, onClose, orgName],\n );\n\n return (\n <Modal visible animationType=\"slide\" transparent onRequestClose={onClose}>\n <View style={styles.modalRoot}>\n <Pressable style={styles.backdrop} onPress={onClose} accessibilityLabel=\"Close apps\" />\n <View\n style={[\n styles.sheet,\n {\n backgroundColor: sheetBg,\n maxHeight: Math.round(windowHeight * 0.86),\n paddingBottom: Math.max(insets.bottom, 12),\n },\n ]}\n >\n <View style={styles.handleWrap}>\n <View style={[styles.handle, { backgroundColor: borderColor }]} />\n </View>\n <View style={styles.header}>\n <Text style={[styles.title, { color: foreground }]}>Apps</Text>\n <Pressable onPress={onClose} hitSlop={10} accessibilityLabel=\"Close\" accessibilityRole=\"button\">\n <MaterialCommunityIcons name=\"close\" size={22} color={muted} />\n </Pressable>\n </View>\n <View style={[styles.searchWrap, { backgroundColor: fieldBg, borderColor }]}>\n <MaterialCommunityIcons name=\"magnify\" size={18} color={muted} />\n <TextInput\n value={query}\n onChangeText={setQuery}\n placeholder=\"Search apps\"\n placeholderTextColor={muted}\n autoCorrect={false}\n autoCapitalize=\"none\"\n style={[styles.searchInput, { color: foreground }]}\n />\n </View>\n <ScrollView keyboardShouldPersistTaps=\"handled\" contentContainerStyle={styles.list}>\n {grouped.length === 0 ? (\n <Text style={[styles.empty, { color: muted }]}>No apps match that search.</Text>\n ) : (\n grouped.map((group) => (\n <View key={group.label} style={styles.group}>\n <Text style={[styles.groupLabel, { color: muted }]}>{group.label}</Text>\n <View style={styles.groupGrid}>\n {group.items.map((app) => (\n <Pressable\n key={app.key}\n onPress={() => openApp(app)}\n accessibilityRole=\"button\"\n accessibilityLabel={app.label}\n style={({ pressed }) => [\n styles.appTile,\n {\n backgroundColor: surface,\n borderColor,\n },\n pressed && { backgroundColor: accentSoft },\n ]}\n >\n <View style={[styles.appIcon, { backgroundColor: accentSoft }]}>\n <MaterialCommunityIcons name={app.icon} size={18} color={accent} />\n </View>\n <Text\n style={[styles.appLabel, { color: foreground }]}\n numberOfLines={2}\n >\n {app.label}\n </Text>\n </Pressable>\n ))}\n </View>\n </View>\n ))\n )}\n </ScrollView>\n </View>\n </View>\n </Modal>\n );\n}\n\nexport function AppsMenu({ isDark, compact = false, orgName }: AppsMenuProps) {\n const [open, setOpen] = useState(false);\n const close = useCallback(() => setOpen(false), []);\n\n return (\n <>\n <AppsMenuTrigger isDark={isDark} compact={compact} onPress={() => setOpen(true)} />\n {open ? <AppsMenuSheet isDark={isDark} orgName={orgName} onClose={close} /> : null}\n </>\n );\n}\n\nconst styles = StyleSheet.create({\n trigger: {\n flexDirection: 'row',\n alignItems: 'center',\n flexShrink: 0,\n gap: 4,\n height: 36,\n paddingHorizontal: 8,\n borderRadius: 10,\n },\n triggerPressed: {\n opacity: 0.7,\n },\n triggerLabel: {\n fontSize: 15,\n fontWeight: '600',\n letterSpacing: -0.2,\n },\n modalRoot: {\n flex: 1,\n justifyContent: 'flex-end',\n },\n backdrop: {\n ...StyleSheet.absoluteFillObject,\n backgroundColor: 'rgba(15, 23, 42, 0.36)',\n },\n sheet: {\n borderTopLeftRadius: 18,\n borderTopRightRadius: 18,\n width: '100%',\n overflow: 'hidden',\n },\n handleWrap: {\n alignItems: 'center',\n paddingTop: 8,\n paddingBottom: 4,\n },\n handle: {\n width: 36,\n height: 4,\n borderRadius: 999,\n },\n header: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingBottom: 8,\n },\n title: {\n fontSize: 20,\n fontWeight: '700',\n letterSpacing: -0.4,\n },\n searchWrap: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n marginHorizontal: 16,\n marginBottom: 8,\n borderWidth: 1,\n borderRadius: 12,\n paddingHorizontal: 12,\n minHeight: 42,\n },\n searchInput: {\n flex: 1,\n fontSize: 15,\n paddingVertical: 8,\n },\n list: {\n paddingHorizontal: 16,\n paddingTop: 8,\n paddingBottom: 20,\n gap: 16,\n },\n group: {\n gap: 8,\n },\n groupLabel: {\n fontSize: 11,\n fontWeight: '600',\n letterSpacing: 0.7,\n textTransform: 'uppercase',\n },\n groupGrid: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: 8,\n },\n appTile: {\n width: '31%',\n flexGrow: 1,\n minWidth: 96,\n maxWidth: '32.5%',\n borderWidth: 1,\n borderRadius: 14,\n paddingHorizontal: 10,\n paddingVertical: 12,\n gap: 8,\n },\n appIcon: {\n width: 32,\n height: 32,\n borderRadius: 10,\n alignItems: 'center',\n justifyContent: 'center',\n },\n appLabel: {\n fontSize: 13,\n fontWeight: '600',\n lineHeight: 17,\n },\n empty: {\n textAlign: 'center',\n paddingVertical: 28,\n fontSize: 14,\n },\n});\n\nexport default AppsMenu;\n"],"names":["_a","uuidv4"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {jsx}from'react/jsx-runtime';import React,{useCallback}from'react';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {GatewayToolbarButtonMobile}from'../GatewayToolbarButtonMobile.js';function mapCdecliStatus(status) {
1
+ import {jsx}from'react/jsx-runtime';import React,{useCallback}from'react';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useGatewayContext}from'../../contexts/GatewayContext.js';import {GatewayToolbarButtonMobile}from'../GatewayToolbarButtonMobile.js';function mapCdecliStatus(status) {
2
2
  if (status === "connecting") return "connecting";
3
3
  if (status === "connected") return "connected";
4
4
  if (status === "error") return "error";
@@ -9,10 +9,13 @@ const GatewayConnector = ({
9
9
  disabled = false
10
10
  }) => {
11
11
  const cdecli = useCdecliConnection();
12
+ const {
13
+ selectedGateway
14
+ } = useGatewayContext();
12
15
  const gatewayStatus = mapCdecliStatus(cdecli.status);
13
16
  const gatewayLabel = cdecli.status === "connecting" ? "Checking..." : void 0;
14
17
  const handleToggleGateway = useCallback(() => {
15
18
  }, []);
16
- return /* @__PURE__ */ jsx(GatewayToolbarButtonMobile, { gatewayStatus, gatewayError: cdecli.error, onToggleGateway: handleToggleGateway, disabled, statusLabel: gatewayLabel, tone });
19
+ return /* @__PURE__ */ jsx(GatewayToolbarButtonMobile, { gatewayStatus, gatewayError: cdecli.error, onToggleGateway: handleToggleGateway, disabled, statusLabel: gatewayLabel, gatewayName: (selectedGateway == null ? void 0 : selectedGateway.name) || "Yantra", tone });
17
20
  };
18
21
  var GatewayConnector$1 = React.memo(GatewayConnector);export{GatewayConnector$1 as default};//# sourceMappingURL=GatewayConnector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GatewayConnector.js","sources":["../../../src/components/GatewayConnector/GatewayConnector.tsx"],"sourcesContent":["/**\n * Gateway connector pill.\n *\n * Renders the visual CDeCLI status pill (`GatewayToolbarButtonMobile`) using\n * the shared `CdecliConnectionContext`. It is purely a consumer — the actual\n * `useCdecliAutoConnect` lifecycle lives in `CdecliConnectionProvider`\n * mounted once at the app root.\n *\n * This separation is intentional: the Chat screen also binds its `channelId`\n * to the same shared connection. If this component called its own\n * `useCdecliAutoConnect`, the two hooks would race their `gatewayConnect`\n * mutations and the agent session would lose its chat binding, producing the\n * \"agent did not return a response / API key may be missing\" fallback.\n */\nimport React, { useCallback } from 'react';\nimport { useCdecliConnection } from '../../contexts/CdecliConnectionContext';\nimport { GatewayToolbarButtonMobile } from '../GatewayToolbarButtonMobile';\n\nexport type GatewayConnectorStatus = 'connecting' | 'connected' | 'disconnected' | 'error';\n\ninterface GatewayConnectorProps {\n /** Visual variant — defaults to the standard toolbar tone. */\n tone?: 'default' | 'provisioning' | 'workspace-error';\n /** Disable interaction (the pill itself is currently click-through). */\n disabled?: boolean;\n}\n\nfunction mapCdecliStatus(status: string | null | undefined): GatewayConnectorStatus {\n if (status === 'connecting') return 'connecting';\n if (status === 'connected') return 'connected';\n if (status === 'error') return 'error';\n return 'disconnected';\n}\n\nconst GatewayConnector: React.FC<GatewayConnectorProps> = ({ tone = 'default', disabled = false }) => {\n const cdecli = useCdecliConnection();\n\n const gatewayStatus = mapCdecliStatus(cdecli.status);\n const gatewayLabel = cdecli.status === 'connecting' ? 'Checking...' : undefined;\n\n const handleToggleGateway = useCallback(() => {\n /* CDeCLI selection is gateway-context driven elsewhere — no-op here. */\n }, []);\n\n return (\n <GatewayToolbarButtonMobile\n gatewayStatus={gatewayStatus}\n gatewayError={cdecli.error}\n onToggleGateway={handleToggleGateway}\n disabled={disabled}\n statusLabel={gatewayLabel}\n tone={tone}\n />\n );\n};\n\nexport default React.memo(GatewayConnector);\n"],"names":[],"mappings":"gOAwBA,SAAS,gBAAgB,MAA2D,EAAA;AAClF,EAAI,IAAA,MAAA,KAAW,cAAqB,OAAA,YAAA;AACpC,EAAI,IAAA,MAAA,KAAW,aAAoB,OAAA,WAAA;AACnC,EAAI,IAAA,MAAA,KAAW,SAAgB,OAAA,OAAA;AAC/B,EAAO,OAAA,cAAA;AACT;AACA,MAAM,mBAAoD,CAAC;AAAA,EACzD,IAAO,GAAA,SAAA;AAAA,EACP,QAAW,GAAA;AACb,CAAM,KAAA;AACJ,EAAA,MAAM,SAAS,mBAAoB,EAAA;AACnC,EAAM,MAAA,aAAA,GAAgB,eAAgB,CAAA,MAAA,CAAO,MAAM,CAAA;AACnD,EAAA,MAAM,YAAe,GAAA,MAAA,CAAO,MAAW,KAAA,YAAA,GAAe,aAAgB,GAAA,MAAA;AACtE,EAAM,MAAA,mBAAA,GAAsB,YAAY,MAAM;AAAA,GAE9C,EAAG,EAAE,CAAA;AACL,EAAO,uBAAA,GAAA,CAAC,0BAA2B,EAAA,EAAA,aAAA,EAA8B,YAAc,EAAA,MAAA,CAAO,KAAO,EAAA,eAAA,EAAiB,mBAAqB,EAAA,QAAA,EAAoB,WAAa,EAAA,YAAA,EAAc,IAAY,EAAA,CAAA;AAChM,CAAA;AACA,yBAAe,KAAA,CAAM,KAAK,gBAAgB,CAAA"}
1
+ {"version":3,"file":"GatewayConnector.js","sources":["../../../src/components/GatewayConnector/GatewayConnector.tsx"],"sourcesContent":["/**\n * Gateway connector pill.\n *\n * Renders the visual CDeCLI status pill (`GatewayToolbarButtonMobile`) using\n * the shared `CdecliConnectionContext`. It is purely a consumer — the actual\n * `useCdecliAutoConnect` lifecycle lives in `CdecliConnectionProvider`\n * mounted once at the app root.\n *\n * This separation is intentional: the Chat screen also binds its `channelId`\n * to the same shared connection. If this component called its own\n * `useCdecliAutoConnect`, the two hooks would race their `gatewayConnect`\n * mutations and the agent session would lose its chat binding, producing the\n * \"agent did not return a response / API key may be missing\" fallback.\n */\nimport React, { useCallback } from 'react';\nimport { useCdecliConnection } from '../../contexts/CdecliConnectionContext';\nimport { useGatewayContext } from '../../contexts/GatewayContext';\nimport { GatewayToolbarButtonMobile } from '../GatewayToolbarButtonMobile';\n\nexport type GatewayConnectorStatus = 'connecting' | 'connected' | 'disconnected' | 'error';\n\ninterface GatewayConnectorProps {\n /** Visual variant — defaults to the standard toolbar tone. */\n tone?: 'default' | 'provisioning' | 'workspace-error';\n /** Disable interaction (the pill itself is currently click-through). */\n disabled?: boolean;\n}\n\nfunction mapCdecliStatus(status: string | null | undefined): GatewayConnectorStatus {\n if (status === 'connecting') return 'connecting';\n if (status === 'connected') return 'connected';\n if (status === 'error') return 'error';\n return 'disconnected';\n}\n\nconst GatewayConnector: React.FC<GatewayConnectorProps> = ({ tone = 'default', disabled = false }) => {\n const cdecli = useCdecliConnection();\n const { selectedGateway } = useGatewayContext();\n\n const gatewayStatus = mapCdecliStatus(cdecli.status);\n const gatewayLabel = cdecli.status === 'connecting' ? 'Checking...' : undefined;\n\n const handleToggleGateway = useCallback(() => {\n /* CDeCLI selection is gateway-context driven elsewhere — no-op here. */\n }, []);\n\n return (\n <GatewayToolbarButtonMobile\n gatewayStatus={gatewayStatus}\n gatewayError={cdecli.error}\n onToggleGateway={handleToggleGateway}\n disabled={disabled}\n statusLabel={gatewayLabel}\n gatewayName={selectedGateway?.name || 'Yantra'}\n tone={tone}\n />\n );\n};\n\nexport default React.memo(GatewayConnector);\n"],"names":[],"mappings":"iSAyBA,SAAS,gBAAgB,MAA2D,EAAA;AAClF,EAAI,IAAA,MAAA,KAAW,cAAqB,OAAA,YAAA;AACpC,EAAI,IAAA,MAAA,KAAW,aAAoB,OAAA,WAAA;AACnC,EAAI,IAAA,MAAA,KAAW,SAAgB,OAAA,OAAA;AAC/B,EAAO,OAAA,cAAA;AACT;AACA,MAAM,mBAAoD,CAAC;AAAA,EACzD,IAAO,GAAA,SAAA;AAAA,EACP,QAAW,GAAA;AACb,CAAM,KAAA;AACJ,EAAA,MAAM,SAAS,mBAAoB,EAAA;AACnC,EAAM,MAAA;AAAA,IACJ;AAAA,MACE,iBAAkB,EAAA;AACtB,EAAM,MAAA,aAAA,GAAgB,eAAgB,CAAA,MAAA,CAAO,MAAM,CAAA;AACnD,EAAA,MAAM,YAAe,GAAA,MAAA,CAAO,MAAW,KAAA,YAAA,GAAe,aAAgB,GAAA,MAAA;AACtE,EAAM,MAAA,mBAAA,GAAsB,YAAY,MAAM;AAAA,GAE9C,EAAG,EAAE,CAAA;AACL,EAAA,uBAAQ,GAAA,CAAA,0BAAA,EAAA,EAA2B,aAA8B,EAAA,YAAA,EAAc,OAAO,KAAO,EAAA,eAAA,EAAiB,mBAAqB,EAAA,QAAA,EAAoB,aAAa,YAAc,EAAA,WAAA,EAAA,CAAa,eAAiB,IAAA,IAAA,GAAA,MAAA,GAAA,eAAA,CAAA,IAAA,KAAQ,UAAU,IAAY,EAAA,CAAA;AAChP,CAAA;AACA,yBAAe,KAAA,CAAM,KAAK,gBAAgB,CAAA"}
@@ -1,38 +1,10 @@
1
- import {jsx,jsxs}from'react/jsx-runtime';import {View,StyleSheet,Pressable,ActivityIndicator,Text}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {mobileTokens}from'../theme/mobileTokens.js';function toneStyles(status, tone) {
2
- if (tone === "provisioning") {
3
- return {
4
- bg: "#dbeafe",
5
- border: "#93c5fd",
6
- text: "#1d4ed8"
7
- };
8
- }
9
- if (tone === "workspace-error") {
10
- return {
11
- bg: mobileTokens.color.dangerSoft,
12
- border: "#fecaca",
13
- text: mobileTokens.color.dangerText
14
- };
15
- }
16
- if (status === "connected") return {
17
- bg: mobileTokens.color.successSoft,
18
- border: "#86efac",
19
- text: mobileTokens.color.successText
20
- };
21
- if (status === "connecting") return {
22
- bg: mobileTokens.color.warningSoft,
23
- border: "#fde68a",
24
- text: mobileTokens.color.warningText
25
- };
26
- if (status === "error") return {
27
- bg: mobileTokens.color.dangerSoft,
28
- border: "#fecaca",
29
- text: mobileTokens.color.dangerText
30
- };
31
- return {
32
- bg: mobileTokens.color.surfaceMuted,
33
- border: mobileTokens.color.border,
34
- text: mobileTokens.color.textMuted
35
- };
1
+ import {jsx,jsxs}from'react/jsx-runtime';import {useColorScheme,View,StyleSheet,Pressable,ActivityIndicator,Text}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {mobileTokens}from'../theme/mobileTokens.js';function iconColor(status, tone, isDark) {
2
+ if (tone === "provisioning") return "#2563eb";
3
+ if (tone === "workspace-error") return mobileTokens.color.dangerText;
4
+ if (status === "connected") return isDark ? "#4ade80" : "#16a34a";
5
+ if (status === "connecting") return isDark ? "#fbbf24" : "#ca8a04";
6
+ if (status === "error") return isDark ? "#f87171" : "#dc2626";
7
+ return isDark ? "#94a3b8" : "#64748b";
36
8
  }
37
9
  function GatewayToolbarButtonMobile({
38
10
  gatewayStatus,
@@ -40,45 +12,45 @@ function GatewayToolbarButtonMobile({
40
12
  onToggleGateway,
41
13
  disabled,
42
14
  statusLabel,
15
+ gatewayName = "Yantra",
43
16
  tone = "default"
44
17
  }) {
45
- const colors = toneStyles(gatewayStatus, tone);
46
- const mainTitle = gatewayStatus === "connected" ? "Disconnect gateway" : gatewayError || "Connect to workspace gateway";
18
+ const isDark = useColorScheme() === "dark";
19
+ const color = iconColor(gatewayStatus, tone, isDark);
20
+ const labelColor = isDark ? "#e2e8f0" : mobileTokens.color.text;
21
+ const mainTitle = gatewayStatus === "connected" ? "Disconnect Yantra" : gatewayError || "Connect to Yantra";
47
22
  return /* @__PURE__ */ jsx(View, { style: styles.wrap, children: /* @__PURE__ */ jsxs(Pressable, { onPress: onToggleGateway, disabled, accessibilityLabel: mainTitle, style: ({
48
23
  pressed
49
- }) => [styles.mainBtn, {
50
- backgroundColor: colors.bg,
51
- borderColor: colors.border
52
- }, pressed && styles.pressed, disabled && styles.disabled], children: [
53
- gatewayStatus === "connecting" ? /* @__PURE__ */ jsx(ActivityIndicator, { size: "small", color: colors.text }) : /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: gatewayStatus === "connected" ? "wifi" : "wifi-off", size: 18, color: colors.text }),
24
+ }) => [styles.mainBtn, pressed && styles.pressed, disabled && styles.disabled], children: [
25
+ gatewayStatus === "connecting" ? /* @__PURE__ */ jsx(ActivityIndicator, { size: "small", color }) : /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: gatewayStatus === "connected" ? "wifi" : "wifi-off", size: 16, color }),
54
26
  /* @__PURE__ */ jsx(Text, { style: [styles.label, {
55
- color: colors.text
56
- }], children: statusLabel != null ? statusLabel : "Gateway" })
27
+ color: labelColor
28
+ }], children: statusLabel != null ? statusLabel : gatewayName })
57
29
  ] }) });
58
30
  }
59
31
  const styles = StyleSheet.create({
60
32
  wrap: {
61
- marginRight: 2
33
+ marginRight: 2,
34
+ flexShrink: 0
62
35
  },
63
36
  mainBtn: {
64
37
  flexDirection: "row",
65
38
  alignItems: "center",
66
39
  gap: 5,
67
- height: 34,
68
- paddingHorizontal: 10,
69
- borderRadius: 11,
70
- borderWidth: 1,
71
- minWidth: 88,
40
+ height: 36,
41
+ paddingHorizontal: 8,
42
+ borderRadius: 10,
72
43
  justifyContent: "flex-start"
73
44
  },
74
45
  pressed: {
75
- opacity: 0.75
46
+ opacity: 0.7
76
47
  },
77
48
  disabled: {
78
49
  opacity: 0.45
79
50
  },
80
51
  label: {
81
- fontSize: 12,
82
- fontWeight: "700"
52
+ fontSize: 15,
53
+ fontWeight: "600",
54
+ letterSpacing: -0.2
83
55
  }
84
56
  });export{GatewayToolbarButtonMobile};//# sourceMappingURL=GatewayToolbarButtonMobile.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GatewayToolbarButtonMobile.js","sources":["../../src/components/GatewayToolbarButtonMobile.tsx"],"sourcesContent":["/**\n * Connect/disconnect + gateway provider picker — mirrors web\n * `GatewayToolbarButton` for React Native header usage.\n */\n\nimport React from 'react';\nimport { ActivityIndicator, Pressable, StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { mobileTokens } from '../theme/mobileTokens';\n\nexport type GatewayToolbarMobileStatus = 'connected' | 'connecting' | 'disconnected' | 'error';\n\nexport interface GatewayToolbarButtonMobileProps {\n gatewayStatus: GatewayToolbarMobileStatus;\n gatewayError?: string | null;\n onToggleGateway: () => void;\n disabled?: boolean;\n /** Replaces the \"Gateway\" label, e.g. \"Setting up...\" */\n statusLabel?: string;\n /** Visual override when workspace (not link status) is provisioning / error */\n tone?: 'default' | 'provisioning' | 'workspace-error';\n}\n\nfunction toneStyles(status: GatewayToolbarMobileStatus, tone: GatewayToolbarButtonMobileProps['tone']) {\n if (tone === 'provisioning') {\n return { bg: '#dbeafe', border: '#93c5fd', text: '#1d4ed8' };\n }\n if (tone === 'workspace-error') {\n return { bg: mobileTokens.color.dangerSoft, border: '#fecaca', text: mobileTokens.color.dangerText };\n }\n if (status === 'connected')\n return { bg: mobileTokens.color.successSoft, border: '#86efac', text: mobileTokens.color.successText };\n if (status === 'connecting')\n return { bg: mobileTokens.color.warningSoft, border: '#fde68a', text: mobileTokens.color.warningText };\n if (status === 'error')\n return { bg: mobileTokens.color.dangerSoft, border: '#fecaca', text: mobileTokens.color.dangerText };\n return {\n bg: mobileTokens.color.surfaceMuted,\n border: mobileTokens.color.border,\n text: mobileTokens.color.textMuted,\n };\n}\n\nexport function GatewayToolbarButtonMobile({\n gatewayStatus,\n gatewayError,\n onToggleGateway,\n disabled,\n statusLabel,\n tone = 'default',\n}: GatewayToolbarButtonMobileProps) {\n const colors = toneStyles(gatewayStatus, tone);\n\n const mainTitle =\n gatewayStatus === 'connected' ? 'Disconnect gateway' : gatewayError || 'Connect to workspace gateway';\n\n return (\n <View style={styles.wrap}>\n <Pressable\n onPress={onToggleGateway}\n disabled={disabled}\n accessibilityLabel={mainTitle}\n style={({ pressed }) => [\n styles.mainBtn,\n { backgroundColor: colors.bg, borderColor: colors.border },\n pressed && styles.pressed,\n disabled && styles.disabled,\n ]}\n >\n {gatewayStatus === 'connecting' ? (\n <ActivityIndicator size=\"small\" color={colors.text} />\n ) : (\n <MaterialCommunityIcons\n name={gatewayStatus === 'connected' ? 'wifi' : 'wifi-off'}\n size={18}\n color={colors.text}\n />\n )}\n <Text style={[styles.label, { color: colors.text }]}>{statusLabel ?? 'Gateway'}</Text>\n </Pressable>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n wrap: { marginRight: 2 },\n mainBtn: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 5,\n height: 34,\n paddingHorizontal: 10,\n borderRadius: 11,\n borderWidth: 1,\n minWidth: 88,\n justifyContent: 'flex-start',\n },\n pressed: { opacity: 0.75 },\n disabled: { opacity: 0.45 },\n label: { fontSize: 12, fontWeight: '700' },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GatewayToolbarButtonMobile.js","sources":["../../src/components/GatewayToolbarButtonMobile.tsx"],"sourcesContent":["/**\n * Connect/disconnect + gateway provider picker — mirrors web\n * `GatewayToolbarButton` for React Native header usage.\n *\n * Connection state lives in the icon color (green / amber / red), not a filled\n * pill. The label is the selected gateway name (\"Yantra\"), same as the browser.\n */\n\nimport React from 'react';\nimport { ActivityIndicator, Pressable, StyleSheet, Text, View, useColorScheme } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { mobileTokens } from '../theme/mobileTokens';\n\nexport type GatewayToolbarMobileStatus = 'connected' | 'connecting' | 'disconnected' | 'error';\n\nexport interface GatewayToolbarButtonMobileProps {\n gatewayStatus: GatewayToolbarMobileStatus;\n gatewayError?: string | null;\n onToggleGateway: () => void;\n disabled?: boolean;\n /** Replaces the gateway name, e.g. \"Checking...\" */\n statusLabel?: string;\n /** Selected gateway display name from the registry. */\n gatewayName?: string;\n /** Visual override when workspace (not link status) is provisioning / error */\n tone?: 'default' | 'provisioning' | 'workspace-error';\n}\n\nfunction iconColor(status: GatewayToolbarMobileStatus, tone: GatewayToolbarButtonMobileProps['tone'], isDark: boolean) {\n if (tone === 'provisioning') return '#2563eb';\n if (tone === 'workspace-error') return mobileTokens.color.dangerText;\n if (status === 'connected') return isDark ? '#4ade80' : '#16a34a';\n if (status === 'connecting') return isDark ? '#fbbf24' : '#ca8a04';\n if (status === 'error') return isDark ? '#f87171' : '#dc2626';\n return isDark ? '#94a3b8' : '#64748b';\n}\n\nexport function GatewayToolbarButtonMobile({\n gatewayStatus,\n gatewayError,\n onToggleGateway,\n disabled,\n statusLabel,\n gatewayName = 'Yantra',\n tone = 'default',\n}: GatewayToolbarButtonMobileProps) {\n const isDark = useColorScheme() === 'dark';\n const color = iconColor(gatewayStatus, tone, isDark);\n const labelColor = isDark ? '#e2e8f0' : mobileTokens.color.text;\n\n const mainTitle = gatewayStatus === 'connected' ? 'Disconnect Yantra' : gatewayError || 'Connect to Yantra';\n\n return (\n <View style={styles.wrap}>\n <Pressable\n onPress={onToggleGateway}\n disabled={disabled}\n accessibilityLabel={mainTitle}\n style={({ pressed }) => [styles.mainBtn, pressed && styles.pressed, disabled && styles.disabled]}\n >\n {gatewayStatus === 'connecting' ? (\n <ActivityIndicator size=\"small\" color={color} />\n ) : (\n <MaterialCommunityIcons\n name={gatewayStatus === 'connected' ? 'wifi' : 'wifi-off'}\n size={16}\n color={color}\n />\n )}\n <Text style={[styles.label, { color: labelColor }]}>{statusLabel ?? gatewayName}</Text>\n </Pressable>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n wrap: { marginRight: 2, flexShrink: 0 },\n mainBtn: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 5,\n height: 36,\n paddingHorizontal: 8,\n borderRadius: 10,\n justifyContent: 'flex-start',\n },\n pressed: { opacity: 0.7 },\n disabled: { opacity: 0.45 },\n label: { fontSize: 15, fontWeight: '600', letterSpacing: -0.2 },\n});\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {jsx,jsxs,Fragment}from'react/jsx-runtime';import React,{useMemo,useCallback}from'react';import {useColorScheme,StyleSheet,View,Pressable}from'react-native';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {StatusBar}from'expo-status-bar';import {useNavigation,CommonActions,DrawerActions}from'@react-navigation/native';import {getHeaderTitle}from'@react-navigation/elements';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Text}from'@admin-layout/gluestack-ui-mobile';import GatewayConnector from'../GatewayConnector/GatewayConnector.js';import {mobileTokens}from'../../theme/mobileTokens.js';import {tryWebBuilderBack}from'../../screens/WebBuilder/webbuilderBackHandler.js';const ICON_SIZE = 22;
1
+ import {jsx,jsxs,Fragment}from'react/jsx-runtime';import React,{useMemo,useCallback}from'react';import {useColorScheme,StyleSheet,View,Pressable}from'react-native';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {StatusBar}from'expo-status-bar';import {useNavigation,CommonActions,DrawerActions}from'@react-navigation/native';import {getHeaderTitle}from'@react-navigation/elements';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Text}from'@admin-layout/gluestack-ui-mobile';import GatewayConnector from'../GatewayConnector/GatewayConnector.js';import {AppsMenu}from'../AppsMenu/AppsMenu.js';import {mobileTokens}from'../../theme/mobileTokens.js';import {tryWebBuilderBack}from'../../screens/WebBuilder/webbuilderBackHandler.js';const ICON_SIZE = 22;
2
2
  function resolveTitle(options, route) {
3
3
  var _a, _b;
4
4
  if (typeof (options == null ? void 0 : options.title) === "string" && options.title.trim()) {
@@ -21,10 +21,12 @@ const NavigationHeader = (props) => {
21
21
  showToggle = false,
22
22
  showBack = false,
23
23
  showGateway = false,
24
+ showApps = false,
24
25
  showHistory = false,
25
26
  showNewChat = false,
26
27
  headerBgColor
27
28
  } = props;
29
+ const showAppsLauncher = showGateway || showApps;
28
30
  const fallbackNav = useNavigation();
29
31
  const navigation = navProp != null ? navProp : fallbackNav;
30
32
  const colorScheme = useColorScheme();
@@ -99,12 +101,12 @@ const NavigationHeader = (props) => {
99
101
  }) => [styles.iconButton, pressed && styles.iconButtonPressed], hitSlop: 8, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-left", size: ICON_SIZE + 4, color: iconColor }) }) : showToggle ? /* @__PURE__ */ jsx(Pressable, { onPress: handleToggleDrawer, accessibilityLabel: "Open menu", accessibilityRole: "button", style: ({
100
102
  pressed
101
103
  }) => [styles.iconButton, pressed && styles.iconButtonPressed], hitSlop: 8, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "menu", size: ICON_SIZE, color: iconColor }) }) : null;
102
- const titleSlot = showTitle ? /* @__PURE__ */ jsx(Text, { style: [styles.title, titleAlignLeft ? styles.titleAlignLeft : styles.titleAlignCenter, {
104
+ const hideBrandTitle = showAppsLauncher && title === "Yantra";
105
+ const titleSlot = showTitle && !hideBrandTitle ? /* @__PURE__ */ jsx(Text, { style: [styles.title, titleAlignLeft ? styles.titleAlignLeft : styles.titleAlignCenter, {
103
106
  color: titleColor
104
107
  }, optionTitleStyle], numberOfLines: 1, ellipsizeMode: "tail", children: title }) : null;
105
- const showRightSlot = showGateway || showHistory || showNewChat;
108
+ const showRightSlot = showHistory || showNewChat;
106
109
  const rightSlot = showRightSlot ? /* @__PURE__ */ jsxs(View, { style: styles.rightActions, children: [
107
- showGateway ? /* @__PURE__ */ jsx(GatewayConnector, {}) : null,
108
110
  showHistory ? /* @__PURE__ */ jsx(Pressable, { onPress: handleOpenChatHistory, style: ({
109
111
  pressed
110
112
  }) => [styles.actionButton, pressed && styles.actionButtonPressed], accessibilityLabel: "Chat history", accessibilityRole: "button", hitSlop: 8, children: /* @__PURE__ */ jsx(View, { style: [styles.actionButtonInner, isDark ? styles.actionButtonInnerDark : null], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "history", size: 19, color: accentColor }) }) }) : null,
@@ -121,7 +123,11 @@ const NavigationHeader = (props) => {
121
123
  borderBottomColor: dividerColor,
122
124
  paddingTop: insets.top > 0 ? 0 : 6
123
125
  }, (_c = options == null ? void 0 : options.headerStyle) != null ? _c : null], children: [
124
- /* @__PURE__ */ jsx(View, { style: styles.leftSlot, children: leftSlot }),
126
+ /* @__PURE__ */ jsxs(View, { style: styles.leftSlot, children: [
127
+ leftSlot,
128
+ showAppsLauncher ? /* @__PURE__ */ jsx(AppsMenu, { isDark, orgName }) : null,
129
+ showGateway ? /* @__PURE__ */ jsx(GatewayConnector, {}) : null
130
+ ] }),
125
131
  /* @__PURE__ */ jsx(View, { style: [styles.titleSlot, titleAlignLeft && styles.titleSlotLeft], children: titleSlot }),
126
132
  /* @__PURE__ */ jsx(View, { style: styles.rightSlot, children: rightSlot })
127
133
  ] }) })
@@ -131,15 +137,17 @@ const styles = StyleSheet.create({
131
137
  row: {
132
138
  flexDirection: "row",
133
139
  alignItems: "center",
134
- paddingHorizontal: 12,
135
- paddingVertical: 10,
140
+ paddingHorizontal: 8,
141
+ paddingVertical: 8,
136
142
  minHeight: 52,
137
- borderBottomWidth: StyleSheet.hairlineWidth
143
+ borderBottomWidth: StyleSheet.hairlineWidth,
144
+ overflow: "visible"
138
145
  },
139
146
  leftSlot: {
140
- minWidth: 40,
141
- alignItems: "flex-start",
142
- justifyContent: "center"
147
+ flexDirection: "row",
148
+ alignItems: "center",
149
+ flexShrink: 0,
150
+ gap: 0
143
151
  },
144
152
  titleSlot: {
145
153
  flex: 1,