@adminide-stack/yantra-mobile 12.0.39-alpha.8 → 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.
- package/lib/components/AppsMenu/AppsMenu.js +285 -0
- package/lib/components/AppsMenu/AppsMenu.js.map +1 -0
- package/lib/components/GatewayConnector/GatewayConnector.js +5 -2
- package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -1
- package/lib/components/GatewayToolbarButtonMobile.js +25 -53
- package/lib/components/GatewayToolbarButtonMobile.js.map +1 -1
- package/lib/components/NavigationHeader/NavigationHeader.js +19 -11
- package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -1
- package/lib/compute.js +2 -0
- package/lib/compute.js.map +1 -1
- package/lib/config/constants.js +2 -2
- package/lib/config/constants.js.map +1 -1
- package/lib/contexts/GatewayContext.js +1 -1
- package/lib/features/apps/mobileAppCatalog.js +153 -0
- package/lib/features/apps/mobileAppCatalog.js.map +1 -0
- package/lib/features/templates/__tests__/buildTemplateCards.test.ts +57 -0
- package/lib/features/templates/buildTemplateCards.js +28 -2
- package/lib/features/templates/buildTemplateCards.js.map +1 -1
- package/lib/features/templates/buildTemplateCards.ts +44 -1
- package/lib/hooks/useMarketplaceTemplateCards.js +5 -2
- package/lib/hooks/useMarketplaceTemplateCards.js.map +1 -1
- package/lib/hooks/useMarketplaceTemplateGroups.js +9 -2
- package/lib/hooks/useMarketplaceTemplateGroups.js.map +1 -1
- package/lib/routes.json +2 -0
- package/lib/screens/Home/HomeScreen.js +44 -150
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/BuildTemplatesSection.js +142 -87
- package/lib/screens/Home/components/BuildTemplatesSection.js.map +1 -1
- package/lib/screens/Home/components/ChooseTemplateModal.js +261 -0
- package/lib/screens/Home/components/ChooseTemplateModal.js.map +1 -0
- package/lib/screens/Home/components/HomeSuggestions.js +109 -0
- package/lib/screens/Home/components/HomeSuggestions.js.map +1 -0
- package/lib/screens/Home/components/TemplateBrowserModal.js +237 -0
- package/lib/screens/Home/components/TemplateBrowserModal.js.map +1 -0
- package/lib/theme/mobileTokens.js +0 -5
- package/lib/theme/mobileTokens.js.map +1 -1
- package/package.json +4 -4
|
@@ -74,15 +74,41 @@ export function normalizeMarketplaceTemplatesPayload(payload: Record<string, unk
|
|
|
74
74
|
return { ...leanGroups, ...(grafted as Record<string, unknown>) };
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
const GRAFTED_NAMESPACE_KEYS = new Set(['marketplace', 'aisearch', 'credential', 'appSettings']);
|
|
78
|
+
|
|
79
|
+
/** Template entries (not groups) expose a `forms` map or credential-style ids. */
|
|
80
|
+
function isTemplateShapedEntry(value: Record<string, unknown>): boolean {
|
|
81
|
+
if (value.forms && typeof value.forms === 'object') return true;
|
|
82
|
+
if (typeof value.templateName === 'string' && (value.formId || value.formExtensionId)) return true;
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* After `marketplace.templates.<group>` loads, a shared settings cache can replace the
|
|
88
|
+
* group map with that group's contents (`aieditor-…` keys). Those must not render as groups.
|
|
89
|
+
*/
|
|
90
|
+
function payloadLooksLikeGroupContents(groupsMap: Record<string, unknown>): boolean {
|
|
91
|
+
const values = Object.entries(groupsMap).filter(
|
|
92
|
+
([key, value]) =>
|
|
93
|
+
value && typeof value === 'object' && !GRAFTED_NAMESPACE_KEYS.has(key) && key !== 'designSystems',
|
|
94
|
+
);
|
|
95
|
+
if (values.length === 0) return false;
|
|
96
|
+
const templateCount = values.filter(([, value]) => isTemplateShapedEntry(value as Record<string, unknown>)).length;
|
|
97
|
+
return templateCount > 0 && templateCount >= Math.ceil(values.length / 2);
|
|
98
|
+
}
|
|
99
|
+
|
|
77
100
|
export function extractMarketplaceTemplateGroups(payload: unknown): MarketplaceTemplateGroup[] {
|
|
78
101
|
const raw = unwrapSettingsPayload(payload);
|
|
79
102
|
if (!raw) return [];
|
|
80
103
|
const groupsMap = normalizeMarketplaceTemplatesPayload(raw);
|
|
104
|
+
if (payloadLooksLikeGroupContents(groupsMap)) return [];
|
|
105
|
+
|
|
81
106
|
const groups: MarketplaceTemplateGroup[] = [];
|
|
82
107
|
|
|
83
108
|
Object.entries(groupsMap).forEach(([groupKey, groupValue]) => {
|
|
84
109
|
if (!groupValue || typeof groupValue !== 'object') return;
|
|
85
|
-
if (groupKey === 'designSystems') return;
|
|
110
|
+
if (groupKey === 'designSystems' || GRAFTED_NAMESPACE_KEYS.has(groupKey)) return;
|
|
111
|
+
if (isTemplateShapedEntry(groupValue as Record<string, unknown>)) return;
|
|
86
112
|
groups.push({
|
|
87
113
|
id: groupKey,
|
|
88
114
|
label: humanizeGroupKey(groupKey),
|
|
@@ -94,6 +120,23 @@ export function extractMarketplaceTemplateGroups(payload: unknown): MarketplaceT
|
|
|
94
120
|
return groups.sort((a, b) => a.label.localeCompare(b.label));
|
|
95
121
|
}
|
|
96
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Cards fetch is scoped to `marketplace.templates.<group>`. If a shared cache still
|
|
125
|
+
* returns the full group map, lift the selected group so extraction stays correct.
|
|
126
|
+
*/
|
|
127
|
+
export function resolveGroupTemplatesPayload(payload: unknown, group: string): unknown {
|
|
128
|
+
const selectedGroup = group.trim();
|
|
129
|
+
if (!selectedGroup) return payload;
|
|
130
|
+
const raw = unwrapSettingsPayload(payload);
|
|
131
|
+
if (!raw) return payload;
|
|
132
|
+
const normalized = normalizeMarketplaceTemplatesPayload(raw);
|
|
133
|
+
const nested = normalized[selectedGroup];
|
|
134
|
+
if (nested && typeof nested === 'object' && !isTemplateShapedEntry(nested as Record<string, unknown>)) {
|
|
135
|
+
return nested;
|
|
136
|
+
}
|
|
137
|
+
return payload;
|
|
138
|
+
}
|
|
139
|
+
|
|
97
140
|
function resolveSettingsUrl(
|
|
98
141
|
form: Record<string, unknown>,
|
|
99
142
|
parentGroup: Record<string, unknown> | undefined,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {useSettings}from'@adminide-stack/platform-client';import {ConfigurationTarget,ContributionSchemaId}from'common';import {useMemo}from'react';import {extractGroupTemplateCards}from'../features/templates/buildTemplateCards.js';import {settingsUriForOrg}from'../utils/cdecodeUri.js';function useMarketplaceTemplateCards({
|
|
1
|
+
import {useSettings}from'@adminide-stack/platform-client';import {ConfigurationTarget,ContributionSchemaId}from'common';import {useMemo}from'react';import {extractGroupTemplateCards,resolveGroupTemplatesPayload}from'../features/templates/buildTemplateCards.js';import {settingsUriForOrg}from'../utils/cdecodeUri.js';function useMarketplaceTemplateCards({
|
|
2
2
|
group = "",
|
|
3
3
|
orgName,
|
|
4
4
|
enabled = true
|
|
@@ -23,7 +23,10 @@ import {useSettings}from'@adminide-stack/platform-client';import {ConfigurationT
|
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
const payload = data != null ? data : settings;
|
|
26
|
-
const cards = useMemo(() =>
|
|
26
|
+
const cards = useMemo(() => {
|
|
27
|
+
if (!canFetch) return [];
|
|
28
|
+
return extractGroupTemplateCards(resolveGroupTemplatesPayload(payload, selectedGroup));
|
|
29
|
+
}, [canFetch, payload, selectedGroup]);
|
|
27
30
|
return {
|
|
28
31
|
cards,
|
|
29
32
|
loading: canFetch ? loading : false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMarketplaceTemplateCards.js","sources":["../../src/hooks/useMarketplaceTemplateCards.ts"],"sourcesContent":["import { useSettings } from '@adminide-stack/platform-client';\nimport { ConfigurationTarget, ContributionSchemaId } from 'common';\nimport { useMemo } from 'react';\nimport {
|
|
1
|
+
{"version":3,"file":"useMarketplaceTemplateCards.js","sources":["../../src/hooks/useMarketplaceTemplateCards.ts"],"sourcesContent":["import { useSettings } from '@adminide-stack/platform-client';\nimport { ConfigurationTarget, ContributionSchemaId } from 'common';\nimport { useMemo } from 'react';\nimport {\n extractGroupTemplateCards,\n resolveGroupTemplatesPayload,\n type BuildTemplateCard,\n} from '../features/templates/buildTemplateCards';\nimport { settingsUriForOrg, type SettingsUriInput } from '../utils/cdecodeUri';\n\nexport type UseMarketplaceTemplateCardsOptions = {\n /** Selected marketplace group key (e.g. `codeAssistant`). */\n group?: string | null;\n orgName?: string | null;\n enabled?: boolean;\n};\n\nexport type UseMarketplaceTemplateCardsReturn = {\n cards: BuildTemplateCard[];\n loading: boolean;\n error: unknown;\n};\n\n/**\n * Cards under `marketplace.templates.<group>` for Build mode — browser\n * `useDefaultFormTemplateCards` parity (includes `snapshotId` for webbuilder remix).\n */\nexport function useMarketplaceTemplateCards({\n group = '',\n orgName,\n enabled = true,\n}: UseMarketplaceTemplateCardsOptions): UseMarketplaceTemplateCardsReturn {\n const selectedGroup = (group ?? '').trim();\n const slug = (orgName ?? '').trim();\n const canFetch = enabled && Boolean(selectedGroup) && Boolean(slug);\n\n const resourceUri: SettingsUriInput | undefined = useMemo(\n () => (canFetch ? settingsUriForOrg(slug) : undefined),\n [canFetch, slug],\n );\n\n const { data, settings, loading, error } = useSettings({\n resourceUri: resourceUri as never,\n skip: !canFetch || !resourceUri,\n options: {\n schemaId: ContributionSchemaId.UiLayout,\n configKey: `marketplace.templates.${selectedGroup}`,\n includeMarketplace: true,\n target: ConfigurationTarget.ORGANIZATION,\n },\n });\n\n // See useMarketplaceTemplateGroups — prefer scoped `data`, fall back to raw settings subtree.\n const payload = data ?? settings;\n\n const cards = useMemo(() => {\n if (!canFetch) return [];\n return extractGroupTemplateCards(resolveGroupTemplatesPayload(payload, selectedGroup));\n }, [canFetch, payload, selectedGroup]);\n\n return {\n cards,\n loading: canFetch ? loading : false,\n error: canFetch ? error : undefined,\n };\n}\n"],"names":[],"mappings":"4TAqBO,SAAS,2BAA4B,CAAA;AAAA,EAC1C,KAAQ,GAAA,EAAA;AAAA,EACR,OAAA;AAAA,EACA,OAAU,GAAA;AACZ,CAA0E,EAAA;AACxE,EAAM,MAAA,aAAA,GAAA,CAAiB,KAAS,IAAA,IAAA,GAAA,KAAA,GAAA,EAAA,EAAI,IAAK,EAAA;AACzC,EAAM,MAAA,IAAA,GAAA,CAAQ,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA,EAAA,EAAI,IAAK,EAAA;AAClC,EAAA,MAAM,WAAW,OAAW,IAAA,OAAA,CAAQ,aAAa,CAAA,IAAK,QAAQ,IAAI,CAAA;AAClE,EAAM,MAAA,WAAA,GAA4C,OAAQ,CAAA,MAAM,QAAW,GAAA,iBAAA,CAAkB,IAAI,CAAA,GAAI,MAAW,EAAA,CAAC,QAAU,EAAA,IAAI,CAAC,CAAA;AAChI,EAAM,MAAA;AAAA,IACJ,IAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,MACE,WAAY,CAAA;AAAA,IACd,WAAA;AAAA,IACA,IAAA,EAAM,CAAC,QAAA,IAAY,CAAC,WAAA;AAAA,IACpB,OAAS,EAAA;AAAA,MACP,UAAU,oBAAqB,CAAA,QAAA;AAAA,MAC/B,SAAA,EAAW,yBAAyB,aAAa,CAAA,CAAA;AAAA,MACjD,kBAAoB,EAAA,IAAA;AAAA,MACpB,QAAQ,mBAAoB,CAAA;AAAA;AAC9B,GACD,CAAA;AAGD,EAAA,MAAM,UAAU,IAAQ,IAAA,IAAA,GAAA,IAAA,GAAA,QAAA;AACxB,EAAM,MAAA,KAAA,GAAQ,QAAQ,MAAM;AAC1B,IAAI,IAAA,CAAC,QAAU,EAAA,OAAO,EAAC;AACvB,IAAA,OAAO,yBAA0B,CAAA,4BAAA,CAA6B,OAAS,EAAA,aAAa,CAAC,CAAA;AAAA,GACpF,EAAA,CAAC,QAAU,EAAA,OAAA,EAAS,aAAa,CAAC,CAAA;AACrC,EAAO,OAAA;AAAA,IACL,KAAA;AAAA,IACA,OAAA,EAAS,WAAW,OAAU,GAAA,KAAA;AAAA,IAC9B,KAAA,EAAO,WAAW,KAAQ,GAAA;AAAA,GAC5B;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {useSettings}from'@adminide-stack/platform-client';import {ConfigurationTarget,ContributionSchemaId}from'common';import {useMemo}from'react';import {extractMarketplaceTemplateGroups}from'../features/templates/buildTemplateCards.js';import {settingsUriForOrg}from'../utils/cdecodeUri.js';function useMarketplaceTemplateGroups({
|
|
1
|
+
import {useSettings}from'@adminide-stack/platform-client';import {ConfigurationTarget,ContributionSchemaId}from'common';import {useMemo,useRef}from'react';import {extractMarketplaceTemplateGroups}from'../features/templates/buildTemplateCards.js';import {settingsUriForOrg}from'../utils/cdecodeUri.js';function useMarketplaceTemplateGroups({
|
|
2
2
|
orgName,
|
|
3
3
|
enabled = true
|
|
4
4
|
}) {
|
|
@@ -23,7 +23,14 @@ import {useSettings}from'@adminide-stack/platform-client';import {ConfigurationT
|
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
const payload = data != null ? data : settings;
|
|
26
|
-
const
|
|
26
|
+
const groupsRef = useRef([]);
|
|
27
|
+
const groups = useMemo(() => {
|
|
28
|
+
if (!canFetch) return [];
|
|
29
|
+
const next = extractMarketplaceTemplateGroups(payload);
|
|
30
|
+
if (next.length === 0) return groupsRef.current;
|
|
31
|
+
groupsRef.current = next;
|
|
32
|
+
return next;
|
|
33
|
+
}, [canFetch, payload]);
|
|
27
34
|
return {
|
|
28
35
|
groups,
|
|
29
36
|
loading: canFetch ? loading : false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMarketplaceTemplateGroups.js","sources":["../../src/hooks/useMarketplaceTemplateGroups.ts"],"sourcesContent":["import { useSettings } from '@adminide-stack/platform-client';\nimport { ConfigurationTarget, ContributionSchemaId } from 'common';\nimport { useMemo } from 'react';\nimport {\n extractMarketplaceTemplateGroups,\n type MarketplaceTemplateGroup,\n} from '../features/templates/buildTemplateCards';\nimport { settingsUriForOrg, type SettingsUriInput } from '../utils/cdecodeUri';\n\nexport type UseMarketplaceTemplateGroupsOptions = {\n orgName?: string | null;\n enabled?: boolean;\n};\n\nexport type UseMarketplaceTemplateGroupsReturn = {\n groups: MarketplaceTemplateGroup[];\n loading: boolean;\n error: unknown;\n};\n\n/**\n * Lists marketplace template groups (`codeAssistant`, `mediaAssistant`, …)\n * for the Build-mode template picker — browser `useTemplates` parity.\n */\nexport function useMarketplaceTemplateGroups({\n orgName,\n enabled = true,\n}: UseMarketplaceTemplateGroupsOptions): UseMarketplaceTemplateGroupsReturn {\n const slug = (orgName ?? '').trim();\n const canFetch = enabled && Boolean(slug);\n const resourceUri: SettingsUriInput | undefined = useMemo(\n () => (canFetch ? settingsUriForOrg(slug) : undefined),\n [canFetch, slug],\n );\n\n const { data, settings, loading, error } = useSettings({\n resourceUri: resourceUri as never,\n skip: !canFetch || !resourceUri,\n options: {\n schemaId: ContributionSchemaId.UiLayout,\n configKey: 'marketplace.templates',\n includeMarketplace: true,\n // Group keys only — values collapse to `{}` (browser modal lists by key).\n depth: 1,\n target: ConfigurationTarget.ORGANIZATION,\n },\n });\n\n // `useSettings` does lodash get(settings, configKey). When pageSettings already returns the\n // configKey subtree as `settings` (depth comment: `{ codeAssistant: {} }`), that get is\n // undefined — fall back to the raw settings payload.\n const payload = data ?? settings;\n\n const groups = useMemo(() => (canFetch
|
|
1
|
+
{"version":3,"file":"useMarketplaceTemplateGroups.js","sources":["../../src/hooks/useMarketplaceTemplateGroups.ts"],"sourcesContent":["import { useSettings } from '@adminide-stack/platform-client';\nimport { ConfigurationTarget, ContributionSchemaId } from 'common';\nimport { useMemo, useRef } from 'react';\nimport {\n extractMarketplaceTemplateGroups,\n type MarketplaceTemplateGroup,\n} from '../features/templates/buildTemplateCards';\nimport { settingsUriForOrg, type SettingsUriInput } from '../utils/cdecodeUri';\n\nexport type UseMarketplaceTemplateGroupsOptions = {\n orgName?: string | null;\n enabled?: boolean;\n};\n\nexport type UseMarketplaceTemplateGroupsReturn = {\n groups: MarketplaceTemplateGroup[];\n loading: boolean;\n error: unknown;\n};\n\n/**\n * Lists marketplace template groups (`codeAssistant`, `mediaAssistant`, …)\n * for the Build-mode template picker — browser `useTemplates` parity.\n */\nexport function useMarketplaceTemplateGroups({\n orgName,\n enabled = true,\n}: UseMarketplaceTemplateGroupsOptions): UseMarketplaceTemplateGroupsReturn {\n const slug = (orgName ?? '').trim();\n const canFetch = enabled && Boolean(slug);\n const resourceUri: SettingsUriInput | undefined = useMemo(\n () => (canFetch ? settingsUriForOrg(slug) : undefined),\n [canFetch, slug],\n );\n\n const { data, settings, loading, error } = useSettings({\n resourceUri: resourceUri as never,\n skip: !canFetch || !resourceUri,\n options: {\n schemaId: ContributionSchemaId.UiLayout,\n configKey: 'marketplace.templates',\n includeMarketplace: true,\n // Group keys only — values collapse to `{}` (browser modal lists by key).\n depth: 1,\n target: ConfigurationTarget.ORGANIZATION,\n },\n });\n\n // `useSettings` does lodash get(settings, configKey). When pageSettings already returns the\n // configKey subtree as `settings` (depth comment: `{ codeAssistant: {} }`), that get is\n // undefined — fall back to the raw settings payload.\n const payload = data ?? settings;\n\n const groupsRef = useRef<MarketplaceTemplateGroup[]>([]);\n const groups = useMemo(() => {\n if (!canFetch) return [];\n const next = extractMarketplaceTemplateGroups(payload);\n // Shared cache can swap the group map for a group's contents after deselect/reopen.\n // Keep the last valid group list so the picker does not flip to nested templates.\n if (next.length === 0) return groupsRef.current;\n groupsRef.current = next;\n return next;\n }, [canFetch, payload]);\n\n return {\n groups,\n loading: canFetch ? loading : false,\n error: canFetch ? error : undefined,\n };\n}\n"],"names":[],"mappings":"6SAmBO,SAAS,4BAA6B,CAAA;AAAA,EAC3C,OAAA;AAAA,EACA,OAAU,GAAA;AACZ,CAA4E,EAAA;AAC1E,EAAM,MAAA,IAAA,GAAA,CAAQ,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA,EAAA,EAAI,IAAK,EAAA;AAClC,EAAM,MAAA,QAAA,GAAW,OAAW,IAAA,OAAA,CAAQ,IAAI,CAAA;AACxC,EAAM,MAAA,WAAA,GAA4C,OAAQ,CAAA,MAAM,QAAW,GAAA,iBAAA,CAAkB,IAAI,CAAA,GAAI,MAAW,EAAA,CAAC,QAAU,EAAA,IAAI,CAAC,CAAA;AAChI,EAAM,MAAA;AAAA,IACJ,IAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,MACE,WAAY,CAAA;AAAA,IACd,WAAA;AAAA,IACA,IAAA,EAAM,CAAC,QAAA,IAAY,CAAC,WAAA;AAAA,IACpB,OAAS,EAAA;AAAA,MACP,UAAU,oBAAqB,CAAA,QAAA;AAAA,MAC/B,SAAW,EAAA,uBAAA;AAAA,MACX,kBAAoB,EAAA,IAAA;AAAA;AAAA,MAEpB,KAAO,EAAA,CAAA;AAAA,MACP,QAAQ,mBAAoB,CAAA;AAAA;AAC9B,GACD,CAAA;AAKD,EAAA,MAAM,UAAU,IAAQ,IAAA,IAAA,GAAA,IAAA,GAAA,QAAA;AACxB,EAAM,MAAA,SAAA,GAAY,MAAmC,CAAA,EAAE,CAAA;AACvD,EAAM,MAAA,MAAA,GAAS,QAAQ,MAAM;AAC3B,IAAI,IAAA,CAAC,QAAU,EAAA,OAAO,EAAC;AACvB,IAAM,MAAA,IAAA,GAAO,iCAAiC,OAAO,CAAA;AAGrD,IAAA,IAAI,IAAK,CAAA,MAAA,KAAW,CAAG,EAAA,OAAO,SAAU,CAAA,OAAA;AACxC,IAAA,SAAA,CAAU,OAAU,GAAA,IAAA;AACpB,IAAO,OAAA,IAAA;AAAA,GACN,EAAA,CAAC,QAAU,EAAA,OAAO,CAAC,CAAA;AACtB,EAAO,OAAA;AAAA,IACL,MAAA;AAAA,IACA,OAAA,EAAS,WAAW,OAAU,GAAA,KAAA;AAAA,IAC9B,KAAA,EAAO,WAAW,KAAQ,GAAA;AAAA,GAC5B;AACF"}
|
package/lib/routes.json
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"showFilter": true,
|
|
23
23
|
"isSearchBack": false,
|
|
24
24
|
"showGateway": true,
|
|
25
|
+
"showApps": true,
|
|
25
26
|
"showHistory": true,
|
|
26
27
|
"showNewChat": true
|
|
27
28
|
}
|
|
@@ -71,6 +72,7 @@
|
|
|
71
72
|
"isSearchBack": false,
|
|
72
73
|
"showBack": true,
|
|
73
74
|
"showGateway": true,
|
|
75
|
+
"showApps": true,
|
|
74
76
|
"showHistory": false,
|
|
75
77
|
"showNewChat": true
|
|
76
78
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsx,jsxs}from'react/jsx-runtime';import React,{useRef,useState,useEffect,useCallback,useMemo}from'react';import {useWindowDimensions,useColorScheme,Platform,Keyboard,TouchableWithoutFeedback,View,StyleSheet
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import React,{useRef,useState,useEffect,useCallback,useMemo}from'react';import {useWindowDimensions,useColorScheme,Platform,Keyboard,TouchableWithoutFeedback,View,StyleSheet}from'react-native';import {getDefaultLeftItems,getDefaultRightItems,Box,Text,InputToolBar}from'@admin-layout/gluestack-ui-mobile';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {useDispatch,useSelector}from'react-redux';import {v4}from'uuid';import {usePrerequisiteIds}from'../../hooks/usePrerequisiteIds.js';import {syncMobileOrgRouteContext}from'../../utils/syncMobileOrgRouteContext.js';import {useChatMutations}from'../../hooks/useChatApi.js';import {AudioRecorderPanel}from'../../features/audio-input/AudioRecorderPanel.js';import {MicErrorBoundary}from'../../features/audio-input/MicErrorBoundary.js';import {requestMicPermission}from'../../features/audio-input/useAudioPermission.js';import {mobileTokens}from'../../theme/mobileTokens.js';import {useMarketplaceTemplateGroups}from'../../hooks/useMarketplaceTemplateGroups.js';import {BuildTemplatesSection}from'./components/BuildTemplatesSection.js';import {ChooseTemplateModal}from'./components/ChooseTemplateModal.js';import {HomeSuggestions}from'./components/HomeSuggestions.js';import {WebBuilderPrewarm}from'./components/WebBuilderPrewarm.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -27,57 +27,22 @@ const EmptyStateSection = React.memo(function EmptyStateSection2({
|
|
|
27
27
|
secondaryTextColor,
|
|
28
28
|
primaryTextColor,
|
|
29
29
|
activeMode,
|
|
30
|
-
onModeSwitch,
|
|
31
|
-
orgName,
|
|
32
30
|
selectedTemplateGroup,
|
|
33
31
|
selectedBuildTemplateId,
|
|
34
|
-
|
|
32
|
+
showSuggestions,
|
|
33
|
+
onInjectPrompt
|
|
35
34
|
}) {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
width: "100%"
|
|
40
|
-
}, contentContainerStyle: styles.emptyCenterTitleWrap, keyboardShouldPersistTaps: "handled", showsVerticalScrollIndicator: false, children: [
|
|
41
|
-
/* @__PURE__ */ jsx(Text, { style: [styles.emptyEyebrow, {
|
|
42
|
-
color: secondaryTextColor
|
|
43
|
-
}], children: "Choose your mode" }),
|
|
44
|
-
/* @__PURE__ */ jsxs(View, { style: [styles.emptyModePillRow, {
|
|
45
|
-
backgroundColor: isDark ? "rgba(30, 41, 59, 0.9)" : "#eef2ff",
|
|
46
|
-
borderColor: isDark ? "rgba(148, 163, 184, 0.26)" : "rgba(67, 56, 202, 0.15)"
|
|
47
|
-
}], children: [
|
|
48
|
-
/* @__PURE__ */ jsxs(Pressable, { onPress: () => onModeSwitch("chat"), style: [styles.emptyModePill, activeMode === "chat" && styles.emptyModePillActive, activeMode === "chat" && {
|
|
49
|
-
backgroundColor: isDark ? "#312e81" : "#4338ca"
|
|
50
|
-
}], accessibilityRole: "button", accessibilityLabel: "Switch to chat mode", children: [
|
|
51
|
-
/* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "magnify", size: 14, color: activeMode === "chat" ? "#ffffff" : secondaryTextColor }),
|
|
52
|
-
/* @__PURE__ */ jsx(Text, { style: [styles.emptyModePillLabel, {
|
|
53
|
-
color: activeMode === "chat" ? "#ffffff" : secondaryTextColor
|
|
54
|
-
}], children: "Chat" })
|
|
55
|
-
] }),
|
|
56
|
-
/* @__PURE__ */ jsxs(Pressable, { onPress: () => onModeSwitch("deep-search"), style: [styles.emptyModePill, activeMode === "deep-search" && styles.emptyModePillActive, activeMode === "deep-search" && {
|
|
57
|
-
backgroundColor: isDark ? "#312e81" : "#4338ca"
|
|
58
|
-
}], accessibilityRole: "button", accessibilityLabel: "Switch to deep-search mode", children: [
|
|
59
|
-
/* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "lightning-bolt-outline", size: 14, color: activeMode === "deep-search" ? "#ffffff" : secondaryTextColor }),
|
|
60
|
-
/* @__PURE__ */ jsx(Text, { style: [styles.emptyModePillLabel, {
|
|
61
|
-
color: activeMode === "deep-search" ? "#ffffff" : secondaryTextColor
|
|
62
|
-
}], children: "Deep Search" })
|
|
63
|
-
] }),
|
|
64
|
-
/* @__PURE__ */ jsxs(Pressable, { onPress: () => onModeSwitch("build"), style: [styles.emptyModePill, activeMode === "build" && styles.emptyModePillActive, activeMode === "build" && {
|
|
65
|
-
backgroundColor: isDark ? "#312e81" : "#4338ca"
|
|
66
|
-
}], accessibilityRole: "button", accessibilityLabel: "Switch to build mode", children: [
|
|
67
|
-
/* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "lightbulb-outline", size: 14, color: activeMode === "build" ? "#ffffff" : secondaryTextColor }),
|
|
68
|
-
/* @__PURE__ */ jsx(Text, { style: [styles.emptyModePillLabel, {
|
|
69
|
-
color: activeMode === "build" ? "#ffffff" : secondaryTextColor
|
|
70
|
-
}], children: "Build" })
|
|
71
|
-
] })
|
|
72
|
-
] }),
|
|
35
|
+
const title = activeMode === "build" ? "What should we build?" : activeMode === "deep-search" ? "What should we research?" : "Ask anything";
|
|
36
|
+
const subtitle = activeMode === "build" ? selectedBuildTemplateId ? "Describe the project, then send." : selectedTemplateGroup ? "Tap a starter below, then send." : "Tap Template to pick a group, then send." : activeMode === "deep-search" ? "Source-backed answers from the web." : "Chat, Deep Search, or Build from the composer.";
|
|
37
|
+
return /* @__PURE__ */ jsxs(View, { style: styles.emptyWrap, children: [
|
|
73
38
|
/* @__PURE__ */ jsx(Text, { style: [styles.emptyCenterTitle, {
|
|
74
39
|
color: primaryTextColor
|
|
75
|
-
}], children:
|
|
40
|
+
}], children: title }),
|
|
76
41
|
/* @__PURE__ */ jsx(Text, { style: [styles.emptySubtitle, {
|
|
77
42
|
color: secondaryTextColor
|
|
78
|
-
}], children:
|
|
79
|
-
|
|
80
|
-
] })
|
|
43
|
+
}], children: subtitle }),
|
|
44
|
+
activeMode === "chat" && showSuggestions ? /* @__PURE__ */ jsx(HomeSuggestions, { isDark, primaryTextColor, secondaryTextColor, onInjectPrompt }) : null
|
|
45
|
+
] });
|
|
81
46
|
});
|
|
82
47
|
function HomeScreenContent({
|
|
83
48
|
initialMode = "chat",
|
|
@@ -85,7 +50,7 @@ function HomeScreenContent({
|
|
|
85
50
|
isLoading: isLoadingProp = false,
|
|
86
51
|
disabled = false
|
|
87
52
|
}) {
|
|
88
|
-
var _a, _b, _c, _d;
|
|
53
|
+
var _a, _b, _c, _d, _e;
|
|
89
54
|
const {
|
|
90
55
|
width: screenWidth
|
|
91
56
|
} = useWindowDimensions();
|
|
@@ -166,9 +131,7 @@ function HomeScreenContent({
|
|
|
166
131
|
}, []);
|
|
167
132
|
const handleModeSwitch = useCallback((mode) => {
|
|
168
133
|
setActiveMode(mode);
|
|
169
|
-
if (mode
|
|
170
|
-
setShowTemplateModal(true);
|
|
171
|
-
} else {
|
|
134
|
+
if (mode !== "build") {
|
|
172
135
|
setShowTemplateModal(false);
|
|
173
136
|
setSelectedTemplateGroup(null);
|
|
174
137
|
setSelectedBuildTemplate(null);
|
|
@@ -233,9 +196,12 @@ function HomeScreenContent({
|
|
|
233
196
|
setShowTemplateModal(false);
|
|
234
197
|
}, []);
|
|
235
198
|
const handleClearBuildTemplate = useCallback(() => {
|
|
236
|
-
|
|
199
|
+
if (selectedBuildTemplate) {
|
|
200
|
+
setSelectedBuildTemplate(null);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
237
203
|
setSelectedTemplateGroup(null);
|
|
238
|
-
}, []);
|
|
204
|
+
}, [selectedBuildTemplate]);
|
|
239
205
|
const handleSubmit = useCallback(async (attachments) => {
|
|
240
206
|
var _a2;
|
|
241
207
|
if (!canSubmit || isLoading || disabled) return;
|
|
@@ -325,6 +291,10 @@ function HomeScreenContent({
|
|
|
325
291
|
const handleValueChange = useCallback((e) => {
|
|
326
292
|
setValue(e.nativeEvent.text);
|
|
327
293
|
}, []);
|
|
294
|
+
const handleInjectPrompt = useCallback((prompt, mode) => {
|
|
295
|
+
setValue(prompt);
|
|
296
|
+
if (mode) setActiveMode(mode);
|
|
297
|
+
}, []);
|
|
328
298
|
const handleMicPress = useCallback(() => {
|
|
329
299
|
if (hasQuery) return;
|
|
330
300
|
setVoiceError(null);
|
|
@@ -401,6 +371,7 @@ function HomeScreenContent({
|
|
|
401
371
|
title: "Choose Template"
|
|
402
372
|
};
|
|
403
373
|
}, [isBuildMode, showTemplateModal, templateModalItems, selectedTemplateGroup, handleSelectTemplateGroup]);
|
|
374
|
+
const renderTemplateModal = useCallback((config) => /* @__PURE__ */ jsx(ChooseTemplateModal, { isOpen: config.isOpen, onClose: config.onClose, templates: config.templates, selectedId: config.selectedId, onSelect: config.onSelect, suggestedId: config.suggestedId, title: config.title, isDark, loading: templateGroupsLoading }), [isDark, templateGroupsLoading]);
|
|
404
375
|
const rightItems = useMemo(() => getDefaultRightItems({
|
|
405
376
|
tag: {
|
|
406
377
|
enabled: false
|
|
@@ -436,12 +407,13 @@ function HomeScreenContent({
|
|
|
436
407
|
backgroundColor: surfaceColor
|
|
437
408
|
}, children: [
|
|
438
409
|
/* @__PURE__ */ jsx(WebBuilderPrewarm, { enabled: isBuildMode, orgName: effectiveOrgName, projectId: effectiveProjectId, tagId }),
|
|
439
|
-
/* @__PURE__ */ jsx(TouchableWithoutFeedback, { onPress: Keyboard.dismiss, accessible: false, children: /* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%",
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
410
|
+
/* @__PURE__ */ jsx(TouchableWithoutFeedback, { onPress: Keyboard.dismiss, accessible: false, children: /* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%", style: {
|
|
411
|
+
paddingBottom: Math.max(0, keyboardHeight - insets.bottom)
|
|
412
|
+
}, children: [
|
|
413
|
+
/* @__PURE__ */ jsx(EmptyStateSection, { isDark, secondaryTextColor, primaryTextColor, activeMode, selectedTemplateGroup, selectedBuildTemplateId: (_d = selectedBuildTemplate == null ? void 0 : selectedBuildTemplate.id) != null ? _d : null, showSuggestions: keyboardHeight === 0, onInjectPrompt: handleInjectPrompt }),
|
|
414
|
+
/* @__PURE__ */ jsx(View, { style: [styles.composerDock, {
|
|
415
|
+
paddingBottom: Math.max(insets.bottom - 6, 8)
|
|
416
|
+
}], children: /* @__PURE__ */ jsxs(View, { style: [styles.composerInner, {
|
|
445
417
|
width: contentMaxWidth
|
|
446
418
|
}], children: [
|
|
447
419
|
voiceError ? /* @__PURE__ */ jsx(View, { style: [styles.voiceErrorBanner, {
|
|
@@ -450,79 +422,40 @@ function HomeScreenContent({
|
|
|
450
422
|
}], children: /* @__PURE__ */ jsx(Text, { style: [styles.voiceErrorText, {
|
|
451
423
|
color: isDark ? "#fecaca" : "#991b1b"
|
|
452
424
|
}], children: voiceError }) }) : null,
|
|
453
|
-
showAudioRecorder ? (
|
|
454
|
-
|
|
455
|
-
* Render-time JS errors thrown by `useAudioRecorder`
|
|
456
|
-
* (e.g. expo-audio native module missing, recorder
|
|
457
|
-
* constructor throws in a release build) are caught
|
|
458
|
-
* by the boundary and converted into a soft cancel
|
|
459
|
-
* via the same handlers the panel itself uses on
|
|
460
|
-
* runtime errors. Without this, a throw during the
|
|
461
|
-
* panel's render phase kills the JS thread in
|
|
462
|
-
* release / TestFlight.
|
|
463
|
-
*/
|
|
464
|
-
/* @__PURE__ */ jsx(MicErrorBoundary, { onCancel: handleRecorderCancel, onError: handleRecorderError, children: /* @__PURE__ */ jsx(AudioRecorderPanel, { isDark, onTranscriptionComplete: handleTranscriptionComplete, onCancel: handleRecorderCancel, onError: handleRecorderError }) })
|
|
465
|
-
) : /* @__PURE__ */ jsx(InputToolBar, { inputConfig, leftItems, rightItems, templateButton, templateModalConfig, micSendButton })
|
|
425
|
+
showAudioRecorder ? /* @__PURE__ */ jsx(MicErrorBoundary, { onCancel: handleRecorderCancel, onError: handleRecorderError, children: /* @__PURE__ */ jsx(AudioRecorderPanel, { isDark, onTranscriptionComplete: handleTranscriptionComplete, onCancel: handleRecorderCancel, onError: handleRecorderError }) }) : /* @__PURE__ */ jsx(InputToolBar, { inputConfig, leftItems, rightItems, templateButton, templateModalConfig, templateModalRender: renderTemplateModal, micSendButton }),
|
|
426
|
+
isBuildMode ? /* @__PURE__ */ jsx(BuildTemplatesSection, { enabled: true, compact: keyboardHeight > 0, group: selectedTemplateGroup, orgName: effectiveOrgName, isDark, primaryTextColor, secondaryTextColor, selectedTemplateId: (_e = selectedBuildTemplate == null ? void 0 : selectedBuildTemplate.id) != null ? _e : null, onUseTemplate: handleUseBuildTemplate }) : null
|
|
466
427
|
] }) })
|
|
467
428
|
] }) })
|
|
468
429
|
] });
|
|
469
430
|
}
|
|
470
431
|
const styles = StyleSheet.create({
|
|
471
|
-
|
|
472
|
-
|
|
432
|
+
emptyWrap: {
|
|
433
|
+
flex: 1,
|
|
473
434
|
alignItems: "center",
|
|
474
|
-
justifyContent: "
|
|
475
|
-
paddingHorizontal:
|
|
476
|
-
|
|
477
|
-
paddingBottom: 160,
|
|
478
|
-
maxWidth: 520,
|
|
479
|
-
width: "100%",
|
|
480
|
-
alignSelf: "center"
|
|
481
|
-
},
|
|
482
|
-
emptyEyebrow: {
|
|
483
|
-
fontSize: 12,
|
|
484
|
-
fontWeight: "600",
|
|
485
|
-
letterSpacing: 0.4,
|
|
486
|
-
textTransform: "uppercase",
|
|
487
|
-
marginBottom: 10
|
|
435
|
+
justifyContent: "center",
|
|
436
|
+
paddingHorizontal: 28,
|
|
437
|
+
width: "100%"
|
|
488
438
|
},
|
|
489
439
|
emptyCenterTitle: {
|
|
490
|
-
|
|
491
|
-
fontSize: 30,
|
|
440
|
+
fontSize: 28,
|
|
492
441
|
fontWeight: "700",
|
|
493
442
|
textAlign: "center",
|
|
494
443
|
letterSpacing: -0.5
|
|
495
444
|
},
|
|
496
445
|
emptySubtitle: {
|
|
497
|
-
marginTop:
|
|
498
|
-
fontSize:
|
|
446
|
+
marginTop: 8,
|
|
447
|
+
fontSize: 15,
|
|
499
448
|
lineHeight: 22,
|
|
500
449
|
textAlign: "center",
|
|
501
|
-
|
|
502
|
-
maxWidth: 360
|
|
450
|
+
maxWidth: 320
|
|
503
451
|
},
|
|
504
|
-
|
|
505
|
-
position: "absolute",
|
|
452
|
+
composerDock: {
|
|
506
453
|
width: "100%",
|
|
507
|
-
|
|
508
|
-
right: 0,
|
|
509
|
-
bottom: 0,
|
|
510
|
-
alignItems: "center",
|
|
511
|
-
justifyContent: "flex-end",
|
|
512
|
-
shadowColor: "#0f172a",
|
|
513
|
-
shadowOpacity: 0.08,
|
|
514
|
-
shadowRadius: 8,
|
|
515
|
-
shadowOffset: {
|
|
516
|
-
width: 0,
|
|
517
|
-
height: -2
|
|
518
|
-
},
|
|
519
|
-
backgroundColor: "transparent",
|
|
520
|
-
elevation: 6
|
|
454
|
+
alignItems: "center"
|
|
521
455
|
},
|
|
522
|
-
|
|
456
|
+
composerInner: {
|
|
523
457
|
paddingHorizontal: 14,
|
|
524
|
-
paddingTop:
|
|
525
|
-
paddingBottom: 4
|
|
458
|
+
paddingTop: 4
|
|
526
459
|
},
|
|
527
460
|
voiceErrorBanner: {
|
|
528
461
|
marginBottom: 8,
|
|
@@ -534,45 +467,6 @@ const styles = StyleSheet.create({
|
|
|
534
467
|
voiceErrorText: {
|
|
535
468
|
fontSize: 12,
|
|
536
469
|
fontWeight: "500"
|
|
537
|
-
},
|
|
538
|
-
emptyModePillRow: {
|
|
539
|
-
flexDirection: "row",
|
|
540
|
-
alignItems: "center",
|
|
541
|
-
gap: 8,
|
|
542
|
-
marginBottom: 22,
|
|
543
|
-
borderRadius: 16,
|
|
544
|
-
padding: 6,
|
|
545
|
-
borderWidth: 1,
|
|
546
|
-
shadowColor: "#312e81",
|
|
547
|
-
shadowOpacity: 0.08,
|
|
548
|
-
shadowRadius: 8,
|
|
549
|
-
shadowOffset: {
|
|
550
|
-
width: 0,
|
|
551
|
-
height: 3
|
|
552
|
-
},
|
|
553
|
-
elevation: 3
|
|
554
|
-
},
|
|
555
|
-
emptyModePill: {
|
|
556
|
-
flexDirection: "row",
|
|
557
|
-
alignItems: "center",
|
|
558
|
-
gap: 4,
|
|
559
|
-
paddingHorizontal: 12,
|
|
560
|
-
paddingVertical: 7,
|
|
561
|
-
borderRadius: 11
|
|
562
|
-
},
|
|
563
|
-
emptyModePillActive: {
|
|
564
|
-
shadowColor: "#312e81",
|
|
565
|
-
shadowOpacity: 0.18,
|
|
566
|
-
shadowRadius: 6,
|
|
567
|
-
shadowOffset: {
|
|
568
|
-
width: 0,
|
|
569
|
-
height: 2
|
|
570
|
-
},
|
|
571
|
-
elevation: 2
|
|
572
|
-
},
|
|
573
|
-
emptyModePillLabel: {
|
|
574
|
-
fontSize: 12,
|
|
575
|
-
fontWeight: "600"
|
|
576
470
|
}
|
|
577
471
|
});
|
|
578
472
|
const HomeScreen = (props) => /* @__PURE__ */ jsx(HomeScreenContent, __spreadValues({}, props));export{HomeScreen as default};//# sourceMappingURL=HomeScreen.js.map
|