@fayz-ai/admin 0.21.0 → 0.22.1
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/dist/SubscriptionPage-Y23PH6US.js +8 -0
- package/dist/{SubscriptionPage-KYMUCZRW.js.map → SubscriptionPage-Y23PH6US.js.map} +1 -1
- package/dist/app/AdminShell.d.ts +3 -2
- package/dist/app/AdminShell.d.ts.map +1 -1
- package/dist/app/config.d.ts +4 -2
- package/dist/app/config.d.ts.map +1 -1
- package/dist/app/contextual-nav.store.d.ts +9 -0
- package/dist/app/contextual-nav.store.d.ts.map +1 -1
- package/dist/billing/TrialWidget.d.ts +1 -1
- package/dist/billing/TrialWidget.d.ts.map +1 -1
- package/dist/billing/index.js +1 -1
- package/dist/{chunk-SHHWE7R2.js → chunk-CTCK5JUQ.js} +3 -3
- package/dist/{chunk-SHHWE7R2.js.map → chunk-CTCK5JUQ.js.map} +1 -1
- package/dist/{chunk-CRB4ZUFH.js → chunk-YBLLTHYP.js} +3 -3
- package/dist/{chunk-CRB4ZUFH.js.map → chunk-YBLLTHYP.js.map} +1 -1
- package/dist/components/RightRail.d.ts.map +1 -1
- package/dist/components/chat/ChatConversation.d.ts.map +1 -1
- package/dist/components/chat/ConfirmActionCard.d.ts +1 -0
- package/dist/components/chat/ConfirmActionCard.d.ts.map +1 -1
- package/dist/components/chat/TourCoachCard.d.ts +3 -0
- package/dist/components/chat/TourCoachCard.d.ts.map +1 -0
- package/dist/components/chat/markdown.d.ts.map +1 -1
- package/dist/crud/RecordMetaFooter.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderDetailRail.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderFormView.d.ts +3 -1
- package/dist/crud/archetypes/OrderFormView.d.ts.map +1 -1
- package/dist/handbook/NotebookPanel.d.ts.map +1 -1
- package/dist/hooks/useChat.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1079 -757
- package/dist/index.js.map +1 -1
- package/dist/lib/ai-tool-handlers.d.ts.map +1 -1
- package/dist/lib/attachments.d.ts +8 -0
- package/dist/lib/attachments.d.ts.map +1 -1
- package/dist/lib/core-ai-tools.d.ts.map +1 -1
- package/dist/onboarding/ActivationAgentSurface.d.ts.map +1 -1
- package/dist/onboarding/ActivationChecklistCard.d.ts.map +1 -1
- package/dist/onboarding/ActivationProvider.d.ts.map +1 -1
- package/dist/onboarding/GettingStartedWidget.d.ts.map +1 -1
- package/dist/setup/SetupAgentSurface.d.ts.map +1 -1
- package/dist/tasks/components/TasksFilterBar.d.ts.map +1 -1
- package/dist/types/plugins.d.ts +3 -0
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +6 -6
- package/dist/SubscriptionPage-KYMUCZRW.js +0 -8
package/dist/index.js
CHANGED
|
@@ -2,30 +2,30 @@ export { ImportWizard } from './chunk-UMRN6427.js';
|
|
|
2
2
|
export { getScheduleBlockConfig, setScheduleBlockConfig, subscribeScheduleBlockConfig } from './chunk-RKXZ7RUG.js';
|
|
3
3
|
import { getFayzSupabaseClientOptional, getFayzSupabaseClient, WorkspaceChooserGate, WorkspaceSwitchingHost, createFayzSupabaseClient, createSupabaseOrgAdapter, createMockOrgAdapter, useWorkspaceSwitchingStore, resolveAppId } from './chunk-ZKOWNGZT.js';
|
|
4
4
|
export { createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, getFayzSupabaseClient, getFayzSupabaseClientOptional } from './chunk-ZKOWNGZT.js';
|
|
5
|
-
import { useLimitGuard, invalidateLimit, useAccessOptional, useUpgradeModalStore, guardLimit, useLimit, checkAccess, featureDisplayName, PlanFeatureItem, AccessProvider, CORE_LIMIT_DECLARATIONS, entityDerivedLimitDeclarations, getPlanEntitlements, resolvePlanCurrency } from './chunk-
|
|
6
|
-
export { AccessProvider, UPGRADE_URL, agentDenial, checkAccess, getAccessSnapshot, guardLimit, invalidateLimit, isEntitledByPlan, resolveAccess, useAccess, useAccessOptional, useLimit, useLimitGuard, useModuleNavAccess, useUpgradeModalStore } from './chunk-
|
|
5
|
+
import { useLimitGuard, invalidateLimit, useAccessOptional, useUpgradeModalStore, guardLimit, useLimit, checkAccess, featureDisplayName, PlanFeatureItem, AccessProvider, CORE_LIMIT_DECLARATIONS, entityDerivedLimitDeclarations, getPlanEntitlements, resolvePlanCurrency } from './chunk-YBLLTHYP.js';
|
|
6
|
+
export { AccessProvider, UPGRADE_URL, agentDenial, checkAccess, getAccessSnapshot, guardLimit, invalidateLimit, isEntitledByPlan, resolveAccess, useAccess, useAccessOptional, useLimit, useLimitGuard, useModuleNavAccess, useUpgradeModalStore } from './chunk-YBLLTHYP.js';
|
|
7
7
|
import { useTranslation as useTranslation$1 } from './chunk-YUHCC7JY.js';
|
|
8
|
-
import { cn, useAdminPath, navigateTo, useBillingStore, normalizeAdminPath, resolvePlanBadge, routeScore, matchRoute, TrialWidget } from './chunk-
|
|
9
|
-
export { navigateTo as adminNavigateTo, useAdminPath, useBillingStore } from './chunk-
|
|
8
|
+
import { cn, useAdminPath, navigateTo, useBillingStore, normalizeAdminPath, resolvePlanBadge, routeScore, matchRoute, TrialWidget } from './chunk-CTCK5JUQ.js';
|
|
9
|
+
export { navigateTo as adminNavigateTo, useAdminPath, useBillingStore } from './chunk-CTCK5JUQ.js';
|
|
10
10
|
import { readOrgSnapshot, useTenantOptional, useOrgAdapter, useTenant, OrgProvider, useOrgAdapterOptional } from './chunk-NB6X5O5L.js';
|
|
11
11
|
export { ORG_CACHE_TTL_MS, OrgProvider, clearOrgSnapshot, readOrgSnapshot, useOrgAdapter, useOrgAdapterOptional, useTenant, useTenantOptional } from './chunk-NB6X5O5L.js';
|
|
12
12
|
import { usePermissionOptional, usePermissionsStore, PermissionsProvider } from './chunk-WJ3H3RJN.js';
|
|
13
13
|
export { PermissionsProvider, useHasPermission, usePermission, usePermissionOptional, usePermissions, usePermissionsStore } from './chunk-WJ3H3RJN.js';
|
|
14
14
|
import { useOrganizationStore } from './chunk-5GWUM4SM.js';
|
|
15
15
|
export { getPersistedOrgId, useOrganizationStore } from './chunk-5GWUM4SM.js';
|
|
16
|
-
import * as
|
|
17
|
-
import
|
|
18
|
-
import { createDebug, resetActiveUnit, setUnitMode, setActiveUnitId, setScopedResources, tl, EMPTY_APP_CONFIG, fetchAppConfig, getSupabaseClientOptional, createSafeDataProvider, isKnownMissing, rememberIfMissing, deriveEntityKey, registerEntity, getActiveTenantId, resolveDataProvider, bulkRemove, emitDomainEvent, entityEventKey, errorMessage, useTranslation, useDataChanged, emitDataChanged, exportCSV, formatDateTime as formatDateTime$1, formatDate as formatDate$1, formatCurrency as formatCurrency$1, bulkCreate, matchesRange, isConnectorCategory, usePluginRuntimeOptional, useDataVersion, reportAppError, getWidgetsForZone, resolvePluginComponent, setCurrentLocale, resolveLocale, resolvePluginRuntime, PluginRuntimeProvider, I18nProvider, getAllEntities, resolveIntegrationSurface, defineApp, registerScaffold, useActiveTenantId, invalidateAppConfig, toTenantPluginBindings, useConnectorsForPlugin, renderApp as renderApp$1, parseRangeFilter, isFilterObject, connectionKey, useManifest, registerEventSink, usePluginRuntime, installGlobalErrorHandlers, applyNavComposition, mergeTranslations, coreTranslations, attachPersistentCache, getPersistentCache, createMockProvider, listConnections, connectorPlanes, connectorPermissions, connectorEntities, preferredPlane, connectorDirection, countByTenant, searchEverything, getComponent, getPluginFactory, connectorSettings, groupedPermissions, invocationPlane, missingRequiredSettings, isSettingSet, getEntityByKey, connectorSubscribesTo, eventKeyMatches, formatPostalCode, isValidPostalCode, lookupPostalCode } from '@fayz-ai/core';
|
|
16
|
+
import * as React113 from 'react';
|
|
17
|
+
import React113__default, { createContext, useMemo, useState, useRef, useCallback, useEffect, useContext } from 'react';
|
|
18
|
+
import { createDebug, resetActiveUnit, setUnitMode, setActiveUnitId, setScopedResources, tl, EMPTY_APP_CONFIG, fetchAppConfig, getSupabaseClientOptional, createSafeDataProvider, isKnownMissing, rememberIfMissing, deriveEntityKey, registerEntity, getActiveTenantId, resolveDataProvider, bulkRemove, emitDomainEvent, entityEventKey, errorMessage, useTranslation, useDataChanged, emitDataChanged, exportCSV, formatDateTime as formatDateTime$1, formatDate as formatDate$1, formatCurrency as formatCurrency$1, bulkCreate, matchesRange, isConnectorCategory, usePluginRuntimeOptional, useDataVersion, reportAppError, getWidgetsForZone, resolvePluginComponent, setCurrentLocale, resolveLocale, resolvePluginRuntime, PluginRuntimeProvider, I18nProvider, getAllEntities, resolveIntegrationSurface, defineApp, registerScaffold, useActiveTenantId, invalidateAppConfig, toTenantPluginBindings, useConnectorsForPlugin, renderApp as renderApp$1, parseRangeFilter, isFilterObject, connectionKey, useManifest, registerEventSink, usePluginRuntime, installGlobalErrorHandlers, applyNavComposition, mergeTranslations, coreTranslations, attachPersistentCache, getPersistentCache, createMockProvider, listConnections, connectorPlanes, connectorPermissions, connectorEntities, preferredPlane, connectorDirection, countByTenant, getCurrentLocale, searchEverything, getComponent, getPluginFactory, connectorSettings, groupedPermissions, invocationPlane, missingRequiredSettings, isSettingSet, getEntityByKey, connectorSubscribesTo, eventKeyMatches, formatPostalCode, isValidPostalCode, lookupPostalCode } from '@fayz-ai/core';
|
|
19
19
|
export { ConnectorRuntimeTokenUnavailableError, createSafeDataProvider, formatDate, formatDateTime, getActiveLocale, getActiveTenantId, getConnectorRuntimeTokenSource, getCurrentLocale, getSupabaseClientOptional, preloadLocale, resolveBackendEnv, setConnectorRuntimeTokenSource, setCurrentLocale, tl, useActiveTenantId } from '@fayz-ai/core';
|
|
20
20
|
import { usePasswordSetupGate, SetPasswordPage, AuthGate, AuthProvider, createAuthRuntime } from '@fayz-ai/plugin-auth';
|
|
21
21
|
export { LoginPage } from '@fayz-ai/plugin-auth';
|
|
22
|
-
import { toast, usePageTrailParent, navigateToCrumb, Button, PageHeader, ConfirmDialog, useRowSelection, getLucideIcon, FilterChip, Dropdown, DropdownTrigger, Hint, cn as cn$1, DropdownContent, DropdownLabel, DropdownItem, DropdownSeparator, RefreshButton, PageHeaderActions, PageTabs, StatTiles, Card, BulkActionBar, DataTable, Modal, ModalContent, ModalHeader, ModalTitle, ModalDescription, ModalFooter, Badge, PageActionBar, ICON_MAP, Sheet, SheetContent, SheetBody, useIsWide, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Checkbox, useTourStore, setTourNavigator, TourSpotlight, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Wizard, SidebarOnboarding, OnboardingWidget, useLayoutStore, Skeleton, useSaveBar, useBackHandler, SubpageHeader, Separator, Tabs, TabsList, TabsTrigger, TabsContent, CardContent, ModalBody, ToastProvider, NavTransitionProvider, ListView, Thumbnail, ModalPortal, ModalOverlay, SearchSelect, CurrencyInput, SearchField, ChevronPager, Popover, PopoverTrigger, PopoverContent, useModuleLayout, PhoneLink, normalizePhone, SearchCombobox, HeaderTabs, usePageTrail, AppShellSkeleton, Switch, ModuleLayoutProvider, AppShell, PageTransition, MarkdownEditor, PhoneField, PageRail, RailNavItem, createFayzTheme, Avatar, AvatarImage, AvatarFallback, Markdown, PageTrail, RowActions, CardTitle, CardDescription, DropdownSub, DropdownSubTrigger, DropdownSubContent, DropdownRadioGroup, DropdownRadioItem, CardHeader, CardFooter, SegmentedControl } from '@fayz-ai/ui';
|
|
22
|
+
import { toast, usePageTrailParent, navigateToCrumb, Button, PageHeader, ConfirmDialog, useRowSelection, getLucideIcon, FilterChip, Dropdown, DropdownTrigger, Hint, cn as cn$1, DropdownContent, DropdownLabel, DropdownItem, DropdownSeparator, RefreshButton, PageHeaderActions, PageTabs, StatTiles, Card, BulkActionBar, DataTable, Modal, ModalContent, ModalHeader, ModalTitle, ModalDescription, ModalFooter, Badge, PageActionBar, ICON_MAP, Sheet, SheetContent, SheetBody, useIsWide, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Checkbox, useTourStore, setTourNavigator, TourSpotlight, PracticeOverlay, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Wizard, SidebarOnboarding, OnboardingWidget, useLayoutStore, Skeleton, useSaveBar, useBackHandler, SubpageHeader, Separator, Tabs, TabsList, TabsTrigger, TabsContent, CardContent, ModalBody, ToastProvider, NavTransitionProvider, ListView, Thumbnail, ModalPortal, ModalOverlay, SearchSelect, CurrencyInput, SearchField, ChevronPager, Popover, PopoverTrigger, PopoverContent, useModuleLayout, PhoneLink, normalizePhone, SearchCombobox, HeaderTabs, usePageTrail, AppShellSkeleton, usePracticeStore, Switch, ModuleLayoutProvider, AppShell, PageTransition, MarkdownEditor, PhoneField, PageRail, RailNavItem, createFayzTheme, Avatar, AvatarImage, AvatarFallback, Markdown, PageTrail, RowActions, CardTitle, CardDescription, DropdownSub, DropdownSubTrigger, DropdownSubContent, DropdownRadioGroup, DropdownRadioItem, CardHeader, CardFooter, SegmentedControl } from '@fayz-ai/ui';
|
|
23
23
|
export { createFayzTheme, fayzThemePresets } from '@fayz-ai/ui';
|
|
24
24
|
import { useAuthStore, useAuth, buildAppHandoffUrl } from '@fayz-ai/auth';
|
|
25
25
|
export { useAuth } from '@fayz-ai/auth';
|
|
26
26
|
import { create, useStore as useStore$1 } from 'zustand';
|
|
27
27
|
import * as LucideIcons3 from 'lucide-react';
|
|
28
|
-
import { Trash2, Upload, Search, ArrowDown, ArrowUp, ArrowUpDown, Check, Download, ChevronLeft, ChevronRight, AlertTriangle, Pencil, Inbox, Package, Sparkles, Plug, DollarSign, Clock, X, WandSparkles, Loader2, ArrowDownToLine, ArrowUpFromLine, CheckCircle2, Crown, ArrowRight, History, SquarePen, Settings2, Mic, User, Plus, Minus, ListChecks, ChevronDown, ArrowLeft, Calendar, ClipboardList, CheckSquare, BookOpen, Lock, PinOff, Pin, Eye, Users, StickyNote, CheckSquare2, Square, Building2, RotateCcw, Copy, Globe, LayoutTemplate, Store, ChevronsUpDown, ExternalLink, PenSquare, RefreshCw, XCircle, Camera, Edit, Star, Link2Off, Layers, ShoppingBag, ChevronUp, List, LayoutGrid, CircleDollarSign, Receipt, Settings, Mail, MessageCircle, Cake, HelpCircle, Wrench, TableProperties, ShieldCheck, MessageSquare, Paperclip, Infinity, CheckCheck, Play, MapPin, ArrowUpRight, Pause, CalendarDays, CircleCheckBig, UserX, Ban, CircleAlert, CircleEllipsis, FileText, CircleDashed, Power, ArrowRightLeft, File as File$1, FileImage, FileSpreadsheet, AlertCircle, CreditCard, SlidersHorizontal, Puzzle, Shield, Palette, ShieldAlert, UserCog, LogOut, Bell, ImagePlus, Database, Radio, Zap, Save, UserPlus, Contact, UserMinus, Send, Sun, Moon, Monitor, Languages, Info, LocateFixed, Link2, KeyRound, Bug, Heart, Briefcase, BarChart3, Tag, Truck, CalendarCheck, CalendarOff } from 'lucide-react';
|
|
28
|
+
import { Trash2, Upload, Search, ArrowDown, ArrowUp, ArrowUpDown, Check, Download, ChevronLeft, ChevronRight, AlertTriangle, Pencil, Inbox, Package, Sparkles, Plug, DollarSign, Clock, X, WandSparkles, Loader2, ArrowDownToLine, ArrowUpFromLine, CheckCircle2, Crown, ArrowRight, History, SquarePen, Settings2, Mic, User, Plus, Minus, ListChecks, ChevronDown, ArrowLeft, Calendar, ClipboardList, CheckSquare, BookOpen, Lock, PinOff, Pin, Eye, Users, StickyNote, CheckSquare2, Square, Building2, RotateCcw, Copy, Globe, LayoutTemplate, Store, ChevronsUpDown, ExternalLink, PenSquare, RefreshCw, XCircle, Camera, Edit, Star, Link2Off, Layers, ShoppingBag, ChevronUp, List, LayoutGrid, CircleDollarSign, Receipt, Settings, Mail, MessageCircle, Cake, HelpCircle, Wrench, TableProperties, ShieldCheck, MessageSquare, Paperclip, Infinity, CheckCheck, PartyPopper, Compass, Play, MapPin, ArrowUpRight, Pause, CalendarDays, CircleCheckBig, UserX, Ban, CircleAlert, CircleEllipsis, FileText, CircleDashed, Power, ArrowRightLeft, File as File$1, FileImage, FileSpreadsheet, AlertCircle, CreditCard, SlidersHorizontal, Puzzle, Shield, Palette, ShieldAlert, UserCog, LogOut, Bell, ImagePlus, Database, Radio, Zap, Save, UserPlus, Contact, UserMinus, Send, Sun, Moon, Monitor, Languages, Info, LocateFixed, Link2, KeyRound, Bug, Heart, Briefcase, BarChart3, Tag, Truck, CalendarCheck, CalendarOff } from 'lucide-react';
|
|
29
29
|
import { createPortal } from 'react-dom';
|
|
30
30
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
31
31
|
import { profileHasSystemPermission, mergeLimitDeclarations } from '@fayz-ai/core/access';
|
|
@@ -70,7 +70,7 @@ function useWorkspaceSetupGate(enabled) {
|
|
|
70
70
|
const close = useWorkspaceSetupStore((s) => s.close);
|
|
71
71
|
const path = useAdminPath();
|
|
72
72
|
const onRoute = path === WORKSPACE_SETUP_ROUTE;
|
|
73
|
-
const exitDeliberate =
|
|
73
|
+
const exitDeliberate = React113.useCallback(() => {
|
|
74
74
|
close();
|
|
75
75
|
if (onRoute) navigateTo("/");
|
|
76
76
|
}, [close, onRoute]);
|
|
@@ -639,7 +639,11 @@ function buildDataPrimitiveTools(input) {
|
|
|
639
639
|
for (const registry4 of defs) {
|
|
640
640
|
if (registry4.readOnly) continue;
|
|
641
641
|
const key = `${pluginId}:${registry4.id}`;
|
|
642
|
-
options.push({
|
|
642
|
+
options.push({
|
|
643
|
+
key,
|
|
644
|
+
label: registry4.entity.namePlural ?? registry4.entity.name,
|
|
645
|
+
...registry4.agentHint ? { hint: registry4.agentHint } : {}
|
|
646
|
+
});
|
|
643
647
|
schema.push({ key, fields: registry4.entity.fields ?? [] });
|
|
644
648
|
}
|
|
645
649
|
}
|
|
@@ -650,7 +654,7 @@ function buildDataPrimitiveTools(input) {
|
|
|
650
654
|
}
|
|
651
655
|
if (!options.length) return [];
|
|
652
656
|
const keys = options.map((o) => o.key);
|
|
653
|
-
const catalogLine = options.map((o) => `${o.key} (${o.label.toLowerCase()})`).join(", ");
|
|
657
|
+
const catalogLine = options.map((o) => `${o.key} (${o.label.toLowerCase()}${o.hint ? ` \u2014 ${o.hint}` : ""})`).join(", ");
|
|
654
658
|
return [
|
|
655
659
|
{
|
|
656
660
|
id: "data.find-anything",
|
|
@@ -1100,6 +1104,9 @@ async function readAllRows(digest) {
|
|
|
1100
1104
|
function listAttachmentNames() {
|
|
1101
1105
|
return [...registry.values()].map((e) => e.parsed).filter((d) => !!d?.headers?.length).map((d) => d.name);
|
|
1102
1106
|
}
|
|
1107
|
+
function nonTabularAttachmentNames() {
|
|
1108
|
+
return [...registry.values()].map((e) => e.parsed).filter((d) => !!d && !d.headers?.length && !d.sheets?.length).map((d) => d.name);
|
|
1109
|
+
}
|
|
1103
1110
|
var SPREADSHEET_EXT = /\.(xlsx|xlsm|xls)$/i;
|
|
1104
1111
|
var CSV_EXT = /\.(csv|tsv)$/i;
|
|
1105
1112
|
var TEXT_EXT = /\.(txt|md|markdown|json|log)$/i;
|
|
@@ -1860,7 +1867,7 @@ function getServerVersion() {
|
|
|
1860
1867
|
return 0;
|
|
1861
1868
|
}
|
|
1862
1869
|
function useAssistantActivity() {
|
|
1863
|
-
|
|
1870
|
+
React113.useSyncExternalStore(subscribe, getVersion, getServerVersion);
|
|
1864
1871
|
return pickActivity(activities);
|
|
1865
1872
|
}
|
|
1866
1873
|
var STATE_RANK = {
|
|
@@ -1876,22 +1883,22 @@ function pickActivity(list) {
|
|
|
1876
1883
|
return pool.find((a) => a.kind === "recording") ?? pool[0];
|
|
1877
1884
|
}
|
|
1878
1885
|
function useAssistantLaunchers() {
|
|
1879
|
-
|
|
1886
|
+
React113.useSyncExternalStore(subscribe, getVersion, getServerVersion);
|
|
1880
1887
|
return launchers;
|
|
1881
1888
|
}
|
|
1882
1889
|
function useLaunchersForRole(role) {
|
|
1883
1890
|
const all = useAssistantLaunchers();
|
|
1884
|
-
return
|
|
1891
|
+
return React113.useMemo(() => all.filter((l) => !l.role || l.role === role), [all, role]);
|
|
1885
1892
|
}
|
|
1886
1893
|
function usePublishAssistantActivity(activity) {
|
|
1887
1894
|
const id = activity?.id;
|
|
1888
1895
|
const key = activity ? `${activity.id}|${activity.kind}|${activity.label}|${activity.state}|${activity.elapsedMs ?? ""}|${(activity.actions ?? []).map((a) => a.intent).join(",")}|${activity.confirm?.acknowledge ?? ""}` : null;
|
|
1889
|
-
const ref =
|
|
1896
|
+
const ref = React113.useRef(activity);
|
|
1890
1897
|
ref.current = activity;
|
|
1891
|
-
|
|
1898
|
+
React113.useEffect(() => {
|
|
1892
1899
|
if (ref.current) publishAssistantActivity(ref.current);
|
|
1893
1900
|
}, [key]);
|
|
1894
|
-
|
|
1901
|
+
React113.useEffect(() => {
|
|
1895
1902
|
if (!id) return;
|
|
1896
1903
|
return () => withdrawAssistantActivity(id);
|
|
1897
1904
|
}, [id]);
|
|
@@ -1899,12 +1906,12 @@ function usePublishAssistantActivity(activity) {
|
|
|
1899
1906
|
function useRegisterAssistantLauncher(launcher) {
|
|
1900
1907
|
const id = launcher?.id;
|
|
1901
1908
|
const key = launcher ? `${launcher.id}|${launcher.label}|${launcher.disabled ? "1" : "0"}|${launcher.role ?? ""}` : null;
|
|
1902
|
-
const ref =
|
|
1909
|
+
const ref = React113.useRef(launcher);
|
|
1903
1910
|
ref.current = launcher;
|
|
1904
|
-
|
|
1911
|
+
React113.useEffect(() => {
|
|
1905
1912
|
if (ref.current) registerAssistantLauncher(ref.current);
|
|
1906
1913
|
}, [key]);
|
|
1907
|
-
|
|
1914
|
+
React113.useEffect(() => {
|
|
1908
1915
|
if (!id) return;
|
|
1909
1916
|
return () => unregisterAssistantLauncher(id);
|
|
1910
1917
|
}, [id]);
|
|
@@ -2002,42 +2009,42 @@ function useRightRailPanel(panel) {
|
|
|
2002
2009
|
const sublabel = panel?.sublabel;
|
|
2003
2010
|
const badgeCount = panel?.badge?.count;
|
|
2004
2011
|
const badgeTone = panel?.badge?.tone;
|
|
2005
|
-
const initial =
|
|
2006
|
-
|
|
2012
|
+
const initial = React113.useRef({ label: label2, icon });
|
|
2013
|
+
React113.useEffect(() => {
|
|
2007
2014
|
if (!id || !Component2) return;
|
|
2008
2015
|
register({ id, label: initial.current.label ?? id, order, Component: Component2, icon: initial.current.icon });
|
|
2009
2016
|
return () => unregister(id);
|
|
2010
2017
|
}, [id, order, Component2, register, unregister]);
|
|
2011
|
-
|
|
2018
|
+
React113.useEffect(() => {
|
|
2012
2019
|
if (!id) return;
|
|
2013
2020
|
updateMeta(id, { label: label2, icon, iconBare, trailing, sublabel });
|
|
2014
2021
|
}, [id, label2, icon, iconBare, trailing, sublabel, updateMeta]);
|
|
2015
|
-
|
|
2022
|
+
React113.useEffect(() => {
|
|
2016
2023
|
if (!id) return;
|
|
2017
2024
|
updateBadge(id, badgeCount !== void 0 ? { count: badgeCount, tone: badgeTone } : void 0);
|
|
2018
2025
|
}, [id, badgeCount, badgeTone, updateBadge]);
|
|
2019
2026
|
}
|
|
2020
|
-
var RightRailActionsSlotContext =
|
|
2027
|
+
var RightRailActionsSlotContext = React113.createContext(null);
|
|
2021
2028
|
var RightRailActionsSlotProvider = RightRailActionsSlotContext.Provider;
|
|
2022
2029
|
function RightRailActions({ children }) {
|
|
2023
|
-
const slot =
|
|
2030
|
+
const slot = React113.useContext(RightRailActionsSlotContext);
|
|
2024
2031
|
if (slot) return createPortal(children, slot);
|
|
2025
2032
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-end gap-0.5 px-2 pt-1.5", children });
|
|
2026
2033
|
}
|
|
2027
|
-
var RightRailLeadingSlotContext =
|
|
2034
|
+
var RightRailLeadingSlotContext = React113.createContext(null);
|
|
2028
2035
|
var RightRailLeadingSlotProvider = RightRailLeadingSlotContext.Provider;
|
|
2029
2036
|
function RightRailLeading({ children }) {
|
|
2030
|
-
const slot =
|
|
2037
|
+
const slot = React113.useContext(RightRailLeadingSlotContext);
|
|
2031
2038
|
if (slot) return createPortal(children, slot);
|
|
2032
2039
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 px-2 pt-1.5", children });
|
|
2033
2040
|
}
|
|
2034
2041
|
function useRightRailReselect(id, handler) {
|
|
2035
2042
|
const reselects = useRightRailStore((s) => s.reselects);
|
|
2036
2043
|
const reselectId = useRightRailStore((s) => s.reselectId);
|
|
2037
|
-
const ref =
|
|
2044
|
+
const ref = React113.useRef(handler);
|
|
2038
2045
|
ref.current = handler;
|
|
2039
|
-
const seen =
|
|
2040
|
-
|
|
2046
|
+
const seen = React113.useRef(reselects);
|
|
2047
|
+
React113.useEffect(() => {
|
|
2041
2048
|
if (reselects === seen.current) return;
|
|
2042
2049
|
seen.current = reselects;
|
|
2043
2050
|
if (reselectId === id) ref.current();
|
|
@@ -2053,9 +2060,9 @@ function useRightRailDrill(drill) {
|
|
|
2053
2060
|
const keepActions = drill?.keepActions;
|
|
2054
2061
|
const avatarName = drill?.avatar?.name;
|
|
2055
2062
|
const avatarSrc = drill?.avatar?.src;
|
|
2056
|
-
const backRef =
|
|
2063
|
+
const backRef = React113.useRef(drill?.back);
|
|
2057
2064
|
backRef.current = drill?.back;
|
|
2058
|
-
|
|
2065
|
+
React113.useEffect(() => {
|
|
2059
2066
|
if (!title) return;
|
|
2060
2067
|
setDrill({
|
|
2061
2068
|
title,
|
|
@@ -2170,7 +2177,7 @@ function buildPersonaGuidance() {
|
|
|
2170
2177
|
}
|
|
2171
2178
|
function useRegisterStaff(staff) {
|
|
2172
2179
|
const setAgent = useAgentStore((s) => s.setAgent);
|
|
2173
|
-
|
|
2180
|
+
React113__default.useEffect(() => {
|
|
2174
2181
|
if (staff && staff.length > 1) {
|
|
2175
2182
|
console.warn(
|
|
2176
2183
|
`[fayz] chat.staff lists ${staff.length} agents; an app has one. Using "${soleAgent(staff)?.name}" and ignoring the rest \u2014 see chat.agent.`
|
|
@@ -2203,7 +2210,7 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2203
2210
|
const { id, persona, headline, pitch, description, placeholder, auto } = def;
|
|
2204
2211
|
const suggestions = def.suggestions;
|
|
2205
2212
|
const suggestionKey = JSON.stringify(suggestions ?? []);
|
|
2206
|
-
|
|
2213
|
+
React113.useEffect(() => {
|
|
2207
2214
|
if (!hasAssistant) return;
|
|
2208
2215
|
setInvite({
|
|
2209
2216
|
id,
|
|
@@ -2217,11 +2224,11 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2217
2224
|
});
|
|
2218
2225
|
return () => setInvite(null, id);
|
|
2219
2226
|
}, [hasAssistant, id, persona, headline, pitch, description, placeholder, auto, suggestionKey, setInvite]);
|
|
2220
|
-
const anchorRef =
|
|
2221
|
-
const [box, setBox] =
|
|
2227
|
+
const anchorRef = React113.useRef(null);
|
|
2228
|
+
const [box, setBox] = React113.useState(null);
|
|
2222
2229
|
const docked = stage === "dock" && !railOpen && hasAssistant;
|
|
2223
2230
|
const showing = hasAssistant && (stage === "hero" || docked);
|
|
2224
|
-
|
|
2231
|
+
React113.useEffect(() => {
|
|
2225
2232
|
if (!showing) return;
|
|
2226
2233
|
const el = anchorRef.current;
|
|
2227
2234
|
if (!el) return;
|
|
@@ -2242,7 +2249,7 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2242
2249
|
}, [showing]);
|
|
2243
2250
|
const setDockBox = useAssistantInviteStore((s) => s.setDockBox);
|
|
2244
2251
|
const wide = useWideViewport();
|
|
2245
|
-
|
|
2252
|
+
React113.useEffect(() => {
|
|
2246
2253
|
if (!docked || !wide || !box) {
|
|
2247
2254
|
setDockBox(null);
|
|
2248
2255
|
return;
|
|
@@ -2256,7 +2263,7 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2256
2263
|
function useAsk() {
|
|
2257
2264
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
2258
2265
|
const dismiss = useAssistantInviteStore((s) => s.dismiss);
|
|
2259
|
-
return
|
|
2266
|
+
return React113.useCallback(
|
|
2260
2267
|
(text2) => {
|
|
2261
2268
|
const trimmed = text2.trim();
|
|
2262
2269
|
if (!trimmed) return;
|
|
@@ -2274,9 +2281,9 @@ function InviteHero({
|
|
|
2274
2281
|
const { t } = useTranslation$1();
|
|
2275
2282
|
const user = useAuthStore((s) => s.user);
|
|
2276
2283
|
const ask = useAsk();
|
|
2277
|
-
const [draft, setDraft] =
|
|
2284
|
+
const [draft, setDraft] = React113.useState("");
|
|
2278
2285
|
const name = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
2279
|
-
|
|
2286
|
+
React113.useEffect(() => {
|
|
2280
2287
|
const onKey = (event) => {
|
|
2281
2288
|
if (event.key === "Escape") onDismiss();
|
|
2282
2289
|
};
|
|
@@ -2338,8 +2345,8 @@ function InviteHero({
|
|
|
2338
2345
|
);
|
|
2339
2346
|
}
|
|
2340
2347
|
function useMorphIn(skip = false) {
|
|
2341
|
-
const [entered, setEntered] =
|
|
2342
|
-
|
|
2348
|
+
const [entered, setEntered] = React113.useState(() => skip || prefersReducedMotion());
|
|
2349
|
+
React113.useEffect(() => {
|
|
2343
2350
|
if (entered) return;
|
|
2344
2351
|
let second = 0;
|
|
2345
2352
|
const first = requestAnimationFrame(() => {
|
|
@@ -2358,10 +2365,10 @@ function prefersReducedMotion() {
|
|
|
2358
2365
|
var lastDockExit = null;
|
|
2359
2366
|
var RESUME_WINDOW_MS = 700;
|
|
2360
2367
|
function useWideViewport() {
|
|
2361
|
-
const [wide, setWide] =
|
|
2368
|
+
const [wide, setWide] = React113.useState(
|
|
2362
2369
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
2363
2370
|
);
|
|
2364
|
-
|
|
2371
|
+
React113.useEffect(() => {
|
|
2365
2372
|
const query = window.matchMedia?.("(min-width: 768px)");
|
|
2366
2373
|
if (!query) return;
|
|
2367
2374
|
const sync = () => setWide(query.matches);
|
|
@@ -2392,18 +2399,18 @@ function InviteDock({ def, left, maxWidth }) {
|
|
|
2392
2399
|
const setOpen = useChatStore((s) => s.setOpen);
|
|
2393
2400
|
const railOpen = useRightRailStore((s) => s.open);
|
|
2394
2401
|
const railWidth = useRightRailStore((s) => s.width);
|
|
2395
|
-
const [draft, setDraft] =
|
|
2396
|
-
const resumed =
|
|
2402
|
+
const [draft, setDraft] = React113.useState("");
|
|
2403
|
+
const resumed = React113.useRef(
|
|
2397
2404
|
!!lastDockExit && lastDockExit.id === def.id && Date.now() - lastDockExit.at < RESUME_WINDOW_MS
|
|
2398
2405
|
).current;
|
|
2399
|
-
|
|
2406
|
+
React113.useEffect(() => () => {
|
|
2400
2407
|
lastDockExit = { id: def.id, at: Date.now() };
|
|
2401
2408
|
}, [def.id]);
|
|
2402
2409
|
const entered = useMorphIn(resumed);
|
|
2403
2410
|
const width = Math.min(maxWidth, DOCK_MAX_WIDTH);
|
|
2404
2411
|
const morph = morphStyles({ left, width }, railOpen, railWidth);
|
|
2405
|
-
const [settled, setSettled] =
|
|
2406
|
-
|
|
2412
|
+
const [settled, setSettled] = React113.useState(resumed);
|
|
2413
|
+
React113.useEffect(() => {
|
|
2407
2414
|
if (!entered || settled) return;
|
|
2408
2415
|
const id = setTimeout(() => setSettled(true), MORPH_MS + 60);
|
|
2409
2416
|
return () => clearTimeout(id);
|
|
@@ -2537,7 +2544,7 @@ function MorphBackPill() {
|
|
|
2537
2544
|
const railWidth = useRightRailStore((s) => s.width);
|
|
2538
2545
|
const { t } = useTranslation$1();
|
|
2539
2546
|
const collapsed = useMorphIn();
|
|
2540
|
-
|
|
2547
|
+
React113.useEffect(() => {
|
|
2541
2548
|
if (prefersReducedMotion()) {
|
|
2542
2549
|
endLeave();
|
|
2543
2550
|
return;
|
|
@@ -3353,9 +3360,10 @@ registerAIToolHandler("proposeImport", async (args, ctx) => {
|
|
|
3353
3360
|
const digest = resolveAttachmentDigest(fileName);
|
|
3354
3361
|
if (!digest) {
|
|
3355
3362
|
const names = listAttachmentNames();
|
|
3363
|
+
const other = nonTabularAttachmentNames();
|
|
3356
3364
|
return {
|
|
3357
3365
|
error: "no_file",
|
|
3358
|
-
message: names.length ? `No readable file called "${fileName ?? ""}". Attached right now: ${names.join(", ")}.` : "There is no
|
|
3366
|
+
message: names.length ? `No readable file called "${fileName ?? ""}". Attached right now: ${names.join(", ")}.` : other.length ? `${other.join(", ")} is attached, but it has no columns \u2014 importing is for spreadsheets and CSVs. If it is a photo or a scan, READ IT: it is in front of you, so answer from what is written on it and use the tool that matches what the user asked for. Do not ask for a CSV.` : "There is no file attached to this conversation. Ask the user to attach a CSV or a spreadsheet."
|
|
3359
3367
|
};
|
|
3360
3368
|
}
|
|
3361
3369
|
const headers = (digest.headers ?? []).filter((h) => h.trim());
|
|
@@ -4500,12 +4508,12 @@ function detectActivePluginId(runtime) {
|
|
|
4500
4508
|
function useAITools() {
|
|
4501
4509
|
const runtime = usePluginRuntimeOptional();
|
|
4502
4510
|
const access = useAccessOptional();
|
|
4503
|
-
const surfaceVersion =
|
|
4511
|
+
const surfaceVersion = React113.useSyncExternalStore(subscribeSurfaces, getSurfaceVersion, getSurfaceVersion);
|
|
4504
4512
|
const features = usePermissionsStore((s) => s.features);
|
|
4505
4513
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
4506
4514
|
const hasSystem = useSystemPermission();
|
|
4507
4515
|
const canManagePermissions = hasSystem("manage_permissions");
|
|
4508
|
-
return
|
|
4516
|
+
return React113.useMemo(() => {
|
|
4509
4517
|
const hasPermission = runtime?.context.hasPermission;
|
|
4510
4518
|
const can = access.can;
|
|
4511
4519
|
const verticalId = runtime?.context.tenant?.verticalId;
|
|
@@ -5513,8 +5521,8 @@ function loadCatalog() {
|
|
|
5513
5521
|
return catalogPromise;
|
|
5514
5522
|
}
|
|
5515
5523
|
function useConnectorCatalog() {
|
|
5516
|
-
const [catalog, setCatalog] =
|
|
5517
|
-
|
|
5524
|
+
const [catalog, setCatalog] = React113__default.useState(null);
|
|
5525
|
+
React113__default.useEffect(() => {
|
|
5518
5526
|
let cancelled = false;
|
|
5519
5527
|
void loadCatalog().then((list) => {
|
|
5520
5528
|
if (!cancelled) setCatalog(list);
|
|
@@ -5538,7 +5546,7 @@ function refreshConnectors() {
|
|
|
5538
5546
|
_revisionListeners.forEach((listener) => listener());
|
|
5539
5547
|
}
|
|
5540
5548
|
function useConnectorsRevision() {
|
|
5541
|
-
return
|
|
5549
|
+
return React113__default.useSyncExternalStore(
|
|
5542
5550
|
(listener) => {
|
|
5543
5551
|
_revisionListeners.add(listener);
|
|
5544
5552
|
return () => _revisionListeners.delete(listener);
|
|
@@ -5557,11 +5565,11 @@ function loadGrants(key, fetcher) {
|
|
|
5557
5565
|
}
|
|
5558
5566
|
function useInstalledModuleIds() {
|
|
5559
5567
|
const runtime = usePluginRuntimeOptional();
|
|
5560
|
-
return
|
|
5568
|
+
return React113__default.useMemo(() => (runtime?.plugins ?? []).map((p) => p.id), [runtime]);
|
|
5561
5569
|
}
|
|
5562
5570
|
function useInstalledDefinitions(hostPluginId) {
|
|
5563
5571
|
const runtime = usePluginRuntimeOptional();
|
|
5564
|
-
return
|
|
5572
|
+
return React113__default.useMemo(() => {
|
|
5565
5573
|
const byHost = runtime?.connectorsByHost;
|
|
5566
5574
|
if (!byHost) return [];
|
|
5567
5575
|
if (hostPluginId) return byHost.get(hostPluginId) ?? [];
|
|
@@ -5574,12 +5582,12 @@ function useConnectors(options = {}) {
|
|
|
5574
5582
|
const catalog = useConnectorCatalog();
|
|
5575
5583
|
const tenant = useTenantOptional();
|
|
5576
5584
|
const tenantId2 = tenant?.org?.id;
|
|
5577
|
-
const connection =
|
|
5578
|
-
const [installed, setInstalled] =
|
|
5579
|
-
const [grants, setGrants] =
|
|
5580
|
-
const [error, setError] =
|
|
5585
|
+
const connection = React113__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
5586
|
+
const [installed, setInstalled] = React113__default.useState(null);
|
|
5587
|
+
const [grants, setGrants] = React113__default.useState(null);
|
|
5588
|
+
const [error, setError] = React113__default.useState(null);
|
|
5581
5589
|
const nonce = useConnectorsRevision();
|
|
5582
|
-
const call2 =
|
|
5590
|
+
const call2 = React113__default.useCallback(
|
|
5583
5591
|
async (path, init) => {
|
|
5584
5592
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
5585
5593
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -5599,7 +5607,7 @@ function useConnectors(options = {}) {
|
|
|
5599
5607
|
},
|
|
5600
5608
|
[connection]
|
|
5601
5609
|
);
|
|
5602
|
-
|
|
5610
|
+
React113__default.useEffect(() => {
|
|
5603
5611
|
let cancelled = false;
|
|
5604
5612
|
void loadConnectorStatuses(definitions, tenantId2).then((list) => {
|
|
5605
5613
|
if (!cancelled) setInstalled(list);
|
|
@@ -5608,7 +5616,7 @@ function useConnectors(options = {}) {
|
|
|
5608
5616
|
cancelled = true;
|
|
5609
5617
|
};
|
|
5610
5618
|
}, [definitions, tenantId2, nonce]);
|
|
5611
|
-
|
|
5619
|
+
React113__default.useEffect(() => {
|
|
5612
5620
|
if (!includeGrants || !connection || !tenantId2) {
|
|
5613
5621
|
setGrants(includeGrants ? null : []);
|
|
5614
5622
|
return;
|
|
@@ -5632,7 +5640,7 @@ function useConnectors(options = {}) {
|
|
|
5632
5640
|
cancelled = true;
|
|
5633
5641
|
};
|
|
5634
5642
|
}, [call2, tenantId2, includeGrants, connection, nonce]);
|
|
5635
|
-
const revokeGrant =
|
|
5643
|
+
const revokeGrant = React113__default.useCallback(
|
|
5636
5644
|
async (connector) => {
|
|
5637
5645
|
const response = await call2(`/${connector.id}`, { method: "DELETE" });
|
|
5638
5646
|
if (!response.ok) {
|
|
@@ -5645,7 +5653,7 @@ function useConnectors(options = {}) {
|
|
|
5645
5653
|
[call2]
|
|
5646
5654
|
);
|
|
5647
5655
|
const waitingGrants = includeGrants && !!connection && !!tenantId2 && grants === null;
|
|
5648
|
-
const connectors =
|
|
5656
|
+
const connectors = React113__default.useMemo(() => {
|
|
5649
5657
|
if (installed === null || waitingGrants) return null;
|
|
5650
5658
|
return buildConnectorList({
|
|
5651
5659
|
installed,
|
|
@@ -5887,9 +5895,9 @@ function ConnectorMark({
|
|
|
5887
5895
|
connector,
|
|
5888
5896
|
size = "md"
|
|
5889
5897
|
}) {
|
|
5890
|
-
const candidates =
|
|
5891
|
-
const [attempt, setAttempt] =
|
|
5892
|
-
|
|
5898
|
+
const candidates = React113__default.useMemo(() => markCandidates(connector), [connector.logoUrl, connector.name]);
|
|
5899
|
+
const [attempt, setAttempt] = React113__default.useState(0);
|
|
5900
|
+
React113__default.useEffect(() => setAttempt(0), [connector.id]);
|
|
5893
5901
|
const box = size === "sm" ? "h-9 w-9" : "h-10 w-10";
|
|
5894
5902
|
const glyph = size === "sm" ? "h-4 w-4" : "h-5 w-5";
|
|
5895
5903
|
if (connector.builtIn) {
|
|
@@ -7133,6 +7141,14 @@ function useChat(options) {
|
|
|
7133
7141
|
const d = new Date(Date.now() + (i + 1) * 864e5);
|
|
7134
7142
|
return `${d.toLocaleDateString("pt-BR", { weekday: "long" })}=${d.toISOString().slice(0, 10)}`;
|
|
7135
7143
|
}).join(", ");
|
|
7144
|
+
const seenCalls = /* @__PURE__ */ new Map();
|
|
7145
|
+
const callKey = (call2) => `${call2.name}:${JSON.stringify(call2.arguments ?? {})}`;
|
|
7146
|
+
const repeatResult = (previous) => JSON.stringify({
|
|
7147
|
+
ok: true,
|
|
7148
|
+
alreadyDone: true,
|
|
7149
|
+
previousResult: previous.slice(0, 1500),
|
|
7150
|
+
message: "THIS EXACT CALL ALREADY RAN in this turn and its result is above \u2014 it was NOT run again, and nothing new was written. Do not call it a third time. Use what it returned (ids included) and answer the person."
|
|
7151
|
+
});
|
|
7136
7152
|
const collectRecordLinks = (content2) => {
|
|
7137
7153
|
rememberRecordRefs(content2);
|
|
7138
7154
|
const links = extractRecordLinks(content2);
|
|
@@ -7250,13 +7266,19 @@ ${JSON.stringify(snapshot.length === 1 ? snapshot[0] : snapshot)}` : void 0
|
|
|
7250
7266
|
}
|
|
7251
7267
|
useChatStore.getState().setActiveTools(response.toolCalls.map((c) => c.name));
|
|
7252
7268
|
try {
|
|
7253
|
-
toolResults =
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7269
|
+
toolResults = [];
|
|
7270
|
+
for (const call2 of response.toolCalls) {
|
|
7271
|
+
const key = callKey(call2);
|
|
7272
|
+
const previous = seenCalls.get(key);
|
|
7273
|
+
if (previous !== void 0) {
|
|
7274
|
+
toolResults.push({ toolCallId: call2.id, content: repeatResult(previous) });
|
|
7275
|
+
continue;
|
|
7276
|
+
}
|
|
7277
|
+
const content2 = await executeGuarded(call2, toolByName.get(call2.name), toolContext);
|
|
7278
|
+
seenCalls.set(key, content2);
|
|
7279
|
+
collectRecordLinks(content2);
|
|
7280
|
+
toolResults.push({ toolCallId: call2.id, content: content2 });
|
|
7281
|
+
}
|
|
7260
7282
|
const autoApproved = new Set(useChatStore.getState().autoApprovedTools);
|
|
7261
7283
|
useChatStore.getState().appendToolCallsToLastAssistant(
|
|
7262
7284
|
response.toolCalls.map((call2, i) => {
|
|
@@ -7282,15 +7304,23 @@ ${JSON.stringify(snapshot.length === 1 ? snapshot[0] : snapshot)}` : void 0
|
|
|
7282
7304
|
async (content) => {
|
|
7283
7305
|
stopSpeaking();
|
|
7284
7306
|
const attachments = useChatStore.getState().consumePendingAttachments();
|
|
7285
|
-
const
|
|
7286
|
-
|
|
7307
|
+
const queuedToRead = useChatStore.getState().consumeQueuedFilesToRead();
|
|
7308
|
+
const attachedToRead = attachments.map((a) => getAttachmentFile(a.id)).filter((f) => !!f && (f.type.startsWith("image/") || f.type === "application/pdf"));
|
|
7309
|
+
const filesToRead = (queuedToRead?.length ? queuedToRead : attachedToRead).slice(0, 1);
|
|
7310
|
+
if (!content.trim() && !attachments.length && !filesToRead.length) return;
|
|
7287
7311
|
const shown = [
|
|
7288
|
-
...attachments.map((a) =>
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7312
|
+
...attachments.map((a) => {
|
|
7313
|
+
const file = a.kind === "image" ? getAttachmentFile(a.id) : void 0;
|
|
7314
|
+
return {
|
|
7315
|
+
name: a.name,
|
|
7316
|
+
kind: a.kind,
|
|
7317
|
+
...a.rowCount === void 0 ? {} : { rowCount: a.rowCount },
|
|
7318
|
+
...file && typeof URL !== "undefined" ? { previewUrl: URL.createObjectURL(file) } : {}
|
|
7319
|
+
};
|
|
7320
|
+
}),
|
|
7321
|
+
// Só o que veio de uma TELA: a foto anexada pelo composer já está na
|
|
7322
|
+
// linha acima, e listá-la nas duas mostraria o mesmo recibo duas vezes.
|
|
7323
|
+
...(queuedToRead ?? []).map((f) => ({
|
|
7294
7324
|
name: f.name,
|
|
7295
7325
|
kind: detectKind(f),
|
|
7296
7326
|
// A miniatura é feita do arquivo ORIGINAL: o que se manda para o
|
|
@@ -7496,9 +7526,9 @@ function prefersReducedMotion2() {
|
|
|
7496
7526
|
return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
7497
7527
|
}
|
|
7498
7528
|
function TypewriterText({ text: text2, speed = 26, onDone }) {
|
|
7499
|
-
const [displayed, setDisplayed] =
|
|
7500
|
-
const indexRef =
|
|
7501
|
-
|
|
7529
|
+
const [displayed, setDisplayed] = React113.useState("");
|
|
7530
|
+
const indexRef = React113.useRef(0);
|
|
7531
|
+
React113.useEffect(() => {
|
|
7502
7532
|
if (prefersReducedMotion2()) {
|
|
7503
7533
|
setDisplayed(text2);
|
|
7504
7534
|
onDone?.();
|
|
@@ -7575,11 +7605,11 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7575
7605
|
const { contextualSuggestions } = useAITools();
|
|
7576
7606
|
const { sendMessage } = useChat({ apiEndpoint, systemPrompt, agent });
|
|
7577
7607
|
const { t } = useTranslation$1();
|
|
7578
|
-
const [phase, setPhase] =
|
|
7579
|
-
const [activeSuggestion, setActiveSuggestion] =
|
|
7580
|
-
const timersRef =
|
|
7581
|
-
const prevSuggestionRef =
|
|
7582
|
-
|
|
7608
|
+
const [phase, setPhase] = React113.useState("idle");
|
|
7609
|
+
const [activeSuggestion, setActiveSuggestion] = React113.useState(null);
|
|
7610
|
+
const timersRef = React113.useRef([]);
|
|
7611
|
+
const prevSuggestionRef = React113.useRef(null);
|
|
7612
|
+
React113.useEffect(ensureStyles, []);
|
|
7583
7613
|
const clearTimers = () => {
|
|
7584
7614
|
timersRef.current.forEach(clearTimeout);
|
|
7585
7615
|
timersRef.current = [];
|
|
@@ -7592,10 +7622,10 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7592
7622
|
const invited = useAssistantInviteStore((s) => !!s.invite && s.stage === "dock");
|
|
7593
7623
|
const dockOnScreen = useAssistantInviteStore((s) => !!s.dockBox);
|
|
7594
7624
|
const morphingBack = useAssistantInviteStore((s) => !!s.leaving);
|
|
7595
|
-
const [wide, setWide] =
|
|
7625
|
+
const [wide, setWide] = React113.useState(
|
|
7596
7626
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
7597
7627
|
);
|
|
7598
|
-
|
|
7628
|
+
React113.useEffect(() => {
|
|
7599
7629
|
const query = window.matchMedia?.("(min-width: 768px)");
|
|
7600
7630
|
if (!query) return;
|
|
7601
7631
|
const sync = () => setWide(query.matches);
|
|
@@ -7604,7 +7634,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7604
7634
|
return () => query.removeEventListener("change", sync);
|
|
7605
7635
|
}, []);
|
|
7606
7636
|
const teaserAllowed = !hasMessages && !activity && !invited && !teaserDismissed() && teaserShownCount() < TEASER_MAX_PER_SESSION;
|
|
7607
|
-
|
|
7637
|
+
React113.useEffect(() => {
|
|
7608
7638
|
if (expanded || !topSuggestion || !topLabel || !teaserAllowed || teaserSeen().includes(topLabel)) {
|
|
7609
7639
|
if (phase !== "idle") {
|
|
7610
7640
|
clearTimers();
|
|
@@ -7635,14 +7665,14 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7635
7665
|
}, 9e3);
|
|
7636
7666
|
return clearTimers;
|
|
7637
7667
|
}, [topLabel, expanded, teaserAllowed]);
|
|
7638
|
-
|
|
7668
|
+
React113.useEffect(() => {
|
|
7639
7669
|
if (expanded && phase !== "idle") {
|
|
7640
7670
|
clearTimers();
|
|
7641
7671
|
setPhase("idle");
|
|
7642
7672
|
}
|
|
7643
7673
|
}, [expanded]);
|
|
7644
|
-
const [entrance, setEntrance] =
|
|
7645
|
-
|
|
7674
|
+
const [entrance, setEntrance] = React113.useState("pending");
|
|
7675
|
+
React113.useEffect(() => {
|
|
7646
7676
|
if (!currentOrg || entrance !== "pending") return;
|
|
7647
7677
|
if (prefersReducedMotion2()) {
|
|
7648
7678
|
setEntrance("done");
|
|
@@ -7652,9 +7682,9 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7652
7682
|
const timer = setTimeout(() => setEntrance("done"), 1600);
|
|
7653
7683
|
return () => clearTimeout(timer);
|
|
7654
7684
|
}, [currentOrg, entrance]);
|
|
7655
|
-
const [poppingBack, setPoppingBack] =
|
|
7656
|
-
const wasMorphing =
|
|
7657
|
-
|
|
7685
|
+
const [poppingBack, setPoppingBack] = React113.useState(false);
|
|
7686
|
+
const wasMorphing = React113.useRef(false);
|
|
7687
|
+
React113.useEffect(() => {
|
|
7658
7688
|
const was = wasMorphing.current;
|
|
7659
7689
|
wasMorphing.current = morphingBack;
|
|
7660
7690
|
if (!was || morphingBack || prefersReducedMotion2()) return;
|
|
@@ -7908,7 +7938,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7908
7938
|
var MAX_SUGGESTIONS = 5;
|
|
7909
7939
|
function ChatSuggestions({ suggestions, onSelect, onDismiss, compact }) {
|
|
7910
7940
|
const { t } = useTranslation$1();
|
|
7911
|
-
const [open, setOpen] =
|
|
7941
|
+
const [open, setOpen] = React113.useState(true);
|
|
7912
7942
|
const visible = suggestions.slice(0, compact ? 3 : MAX_SUGGESTIONS);
|
|
7913
7943
|
if (!visible.length) return null;
|
|
7914
7944
|
return /* @__PURE__ */ jsxs(
|
|
@@ -7987,8 +8017,8 @@ function SuggestionRow({
|
|
|
7987
8017
|
detail,
|
|
7988
8018
|
onSelect
|
|
7989
8019
|
}) {
|
|
7990
|
-
const labelRef =
|
|
7991
|
-
const [showDetail, setShowDetail] =
|
|
8020
|
+
const labelRef = React113.useRef(null);
|
|
8021
|
+
const [showDetail, setShowDetail] = React113.useState(false);
|
|
7992
8022
|
const evaluate = () => {
|
|
7993
8023
|
const el = labelRef.current;
|
|
7994
8024
|
const clipped = !!el && el.scrollWidth > el.clientWidth + 1;
|
|
@@ -8082,8 +8112,8 @@ function ChatToolsPanel({ toolGroups, onClose }) {
|
|
|
8082
8112
|
}
|
|
8083
8113
|
function AutoApprovalsSection() {
|
|
8084
8114
|
const { t } = useTranslation$1();
|
|
8085
|
-
const [rules, setRules] =
|
|
8086
|
-
|
|
8115
|
+
const [rules, setRules] = React113.useState(() => listAutoApprovals());
|
|
8116
|
+
React113.useEffect(() => subscribeAutoApprovals(() => setRules(listAutoApprovals())), []);
|
|
8087
8117
|
if (!rules.length) return null;
|
|
8088
8118
|
return /* @__PURE__ */ jsxs("div", { className: "border-b border-border/40 px-3 py-2.5", children: [
|
|
8089
8119
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 px-1 pb-1.5", children: [
|
|
@@ -8136,14 +8166,14 @@ function bucketOf(iso) {
|
|
|
8136
8166
|
var ORDER = ["today", "yesterday", "week", "older"];
|
|
8137
8167
|
function ChatHistory({ conversations, activeId, onSelect }) {
|
|
8138
8168
|
const { t } = useTranslation$1();
|
|
8139
|
-
const [query, setQuery] =
|
|
8169
|
+
const [query, setQuery] = React113.useState("");
|
|
8140
8170
|
const mine = conversations;
|
|
8141
|
-
const filtered =
|
|
8171
|
+
const filtered = React113.useMemo(() => {
|
|
8142
8172
|
const needle = query.trim().toLowerCase();
|
|
8143
8173
|
if (!needle) return mine;
|
|
8144
8174
|
return mine.filter((c) => (c.title ?? "").toLowerCase().includes(needle));
|
|
8145
8175
|
}, [mine, query]);
|
|
8146
|
-
const groups =
|
|
8176
|
+
const groups = React113.useMemo(() => {
|
|
8147
8177
|
const map = /* @__PURE__ */ new Map();
|
|
8148
8178
|
for (const conversation of filtered) {
|
|
8149
8179
|
const bucket = bucketOf(conversation.updatedAt);
|
|
@@ -8222,14 +8252,127 @@ function formatWhen(iso) {
|
|
|
8222
8252
|
const sameDay = (/* @__PURE__ */ new Date()).toDateString() === date.toDateString();
|
|
8223
8253
|
return sameDay ? date.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" }) : date.toLocaleDateString(void 0, { day: "2-digit", month: "short" });
|
|
8224
8254
|
}
|
|
8255
|
+
function StepChecklist({ items }) {
|
|
8256
|
+
return /* @__PURE__ */ jsx("ol", { className: "border-t border-border/60 px-3 py-2", children: items.map((it, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2 py-1 text-[12px]", children: [
|
|
8257
|
+
/* @__PURE__ */ jsx(
|
|
8258
|
+
"span",
|
|
8259
|
+
{
|
|
8260
|
+
className: "mt-[1px] flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-[10px] font-semibold tabular-nums " + (it.done ? "bg-primary text-primary-foreground" : it.current ? "bg-primary/15 text-primary ring-1 ring-primary" : "bg-muted text-muted-foreground"),
|
|
8261
|
+
children: it.done ? /* @__PURE__ */ jsx(Check, { className: "h-2.5 w-2.5" }) : i + 1
|
|
8262
|
+
}
|
|
8263
|
+
),
|
|
8264
|
+
/* @__PURE__ */ jsx(
|
|
8265
|
+
"span",
|
|
8266
|
+
{
|
|
8267
|
+
className: "leading-snug " + (it.done ? "text-muted-foreground line-through decoration-muted-foreground/40" : it.current ? "font-medium text-foreground" : "text-muted-foreground"),
|
|
8268
|
+
children: it.label
|
|
8269
|
+
}
|
|
8270
|
+
)
|
|
8271
|
+
] }, i)) });
|
|
8272
|
+
}
|
|
8273
|
+
function CoachCard({
|
|
8274
|
+
icon,
|
|
8275
|
+
title,
|
|
8276
|
+
subtitle,
|
|
8277
|
+
items,
|
|
8278
|
+
actions
|
|
8279
|
+
}) {
|
|
8280
|
+
return /* @__PURE__ */ jsxs("div", { className: "mx-3 mb-2 overflow-hidden rounded-xl border border-border bg-muted/40", children: [
|
|
8281
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 px-3 py-2", children: [
|
|
8282
|
+
icon,
|
|
8283
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
8284
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-[12px] font-semibold text-foreground", children: title }),
|
|
8285
|
+
/* @__PURE__ */ jsx("p", { className: "truncate text-[11px] text-muted-foreground", children: subtitle })
|
|
8286
|
+
] }),
|
|
8287
|
+
actions
|
|
8288
|
+
] }),
|
|
8289
|
+
/* @__PURE__ */ jsx(StepChecklist, { items })
|
|
8290
|
+
] });
|
|
8291
|
+
}
|
|
8292
|
+
var LiveDot = /* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2 shrink-0", children: [
|
|
8293
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-primary/60" }),
|
|
8294
|
+
/* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-primary" })
|
|
8295
|
+
] });
|
|
8296
|
+
function TourCoachCard() {
|
|
8297
|
+
const tour = useTourStore((s) => s.tour);
|
|
8298
|
+
const index = useTourStore((s) => s.index);
|
|
8299
|
+
const lastTour = useTourStore((s) => s.lastTour);
|
|
8300
|
+
const lastOutcome = useTourStore((s) => s.lastOutcome);
|
|
8301
|
+
const stop = useTourStore((s) => s.stop);
|
|
8302
|
+
const restart = useTourStore((s) => s.restart);
|
|
8303
|
+
const [dismissedId, setDismissedId] = React113.useState(null);
|
|
8304
|
+
const pTitle = usePracticeStore((s) => s.title);
|
|
8305
|
+
const pSteps = usePracticeStore((s) => s.steps);
|
|
8306
|
+
const pDone = usePracticeStore((s) => s.done);
|
|
8307
|
+
if (pTitle && pSteps.length > 0) {
|
|
8308
|
+
const doneCount = pSteps.filter((s) => pDone.includes(s.anchor)).length;
|
|
8309
|
+
const nextIdx = pSteps.findIndex((s) => !pDone.includes(s.anchor));
|
|
8310
|
+
return /* @__PURE__ */ jsx(
|
|
8311
|
+
CoachCard,
|
|
8312
|
+
{
|
|
8313
|
+
icon: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5 shrink-0 text-primary" }),
|
|
8314
|
+
title: pTitle,
|
|
8315
|
+
subtitle: `${tl("Now you try \u2014 fill it in", "Agora \xE9 voc\xEA \u2014 preencha")} \xB7 ${doneCount}/${pSteps.length}`,
|
|
8316
|
+
items: pSteps.map((s, i) => ({
|
|
8317
|
+
label: s.label,
|
|
8318
|
+
done: pDone.includes(s.anchor),
|
|
8319
|
+
current: i === nextIdx
|
|
8320
|
+
}))
|
|
8321
|
+
}
|
|
8322
|
+
);
|
|
8323
|
+
}
|
|
8324
|
+
const running = !!tour;
|
|
8325
|
+
const shown = tour ?? lastTour;
|
|
8326
|
+
if (!shown) return null;
|
|
8327
|
+
if (!running && shown.id === dismissedId) return null;
|
|
8328
|
+
if (!running && shown.practice?.length && lastOutcome?.tourId === shown.id) return null;
|
|
8329
|
+
const total = shown.stops.length;
|
|
8330
|
+
const completed = !running && lastOutcome?.tourId === shown.id && lastOutcome.completed;
|
|
8331
|
+
const doneThrough = running ? index : completed ? total : lastOutcome?.tourId === shown.id ? index : 0;
|
|
8332
|
+
return /* @__PURE__ */ jsx(
|
|
8333
|
+
CoachCard,
|
|
8334
|
+
{
|
|
8335
|
+
icon: completed ? /* @__PURE__ */ jsx(PartyPopper, { className: "h-3.5 w-3.5 shrink-0 text-primary" }) : running ? LiveDot : /* @__PURE__ */ jsx(Compass, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
8336
|
+
title: shown.title ?? tl("Guided tour", "Tour guiado"),
|
|
8337
|
+
subtitle: completed ? tl("Done \u2014 nice work!", "Conclu\xEDdo \u2014 mandou bem!") : `${Math.min(doneThrough, total)}/${total} ${tl("steps", "passos")}`,
|
|
8338
|
+
items: shown.stops.map((s, i) => ({
|
|
8339
|
+
label: s.title,
|
|
8340
|
+
done: i < doneThrough,
|
|
8341
|
+
current: running && i === index
|
|
8342
|
+
})),
|
|
8343
|
+
actions: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8344
|
+
/* @__PURE__ */ jsx(
|
|
8345
|
+
"button",
|
|
8346
|
+
{
|
|
8347
|
+
type: "button",
|
|
8348
|
+
onClick: restart,
|
|
8349
|
+
title: tl("Restart tour", "Reiniciar tour"),
|
|
8350
|
+
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
8351
|
+
children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-3.5 w-3.5" })
|
|
8352
|
+
}
|
|
8353
|
+
),
|
|
8354
|
+
/* @__PURE__ */ jsx(
|
|
8355
|
+
"button",
|
|
8356
|
+
{
|
|
8357
|
+
type: "button",
|
|
8358
|
+
onClick: () => running ? stop(false) : setDismissedId(shown.id),
|
|
8359
|
+
title: running ? tl("End tour", "Encerrar tour") : tl("Dismiss", "Dispensar"),
|
|
8360
|
+
className: "rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
8361
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
8362
|
+
}
|
|
8363
|
+
)
|
|
8364
|
+
] })
|
|
8365
|
+
}
|
|
8366
|
+
);
|
|
8367
|
+
}
|
|
8225
8368
|
function AssistantRecordingView({ activity }) {
|
|
8226
8369
|
const { t } = useTranslation$1();
|
|
8227
8370
|
const pending2 = activity.state === "pending";
|
|
8228
8371
|
const live = activity.state === "running" || activity.state === "paused";
|
|
8229
8372
|
const running = activity.state === "running";
|
|
8230
8373
|
const actions = activity.actions ?? [];
|
|
8231
|
-
const [acknowledged, setAcknowledged] =
|
|
8232
|
-
|
|
8374
|
+
const [acknowledged, setAcknowledged] = React113.useState(false);
|
|
8375
|
+
React113.useEffect(() => setAcknowledged(false), [activity.id, activity.state]);
|
|
8233
8376
|
const withheld = pending2 && !!activity.confirm && !acknowledged;
|
|
8234
8377
|
const primary = actions.filter((a) => a.intent !== "discard");
|
|
8235
8378
|
const discard = actions.find((a) => a.intent === "discard");
|
|
@@ -8445,10 +8588,10 @@ function RightRailPage({
|
|
|
8445
8588
|
const closePage = useRightRailStore((s) => s.closePage);
|
|
8446
8589
|
const active2 = hosted && open;
|
|
8447
8590
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
8448
|
-
const onCloseRef =
|
|
8591
|
+
const onCloseRef = React113.useRef(onClose);
|
|
8449
8592
|
onCloseRef.current = onClose;
|
|
8450
|
-
const claimed =
|
|
8451
|
-
|
|
8593
|
+
const claimed = React113.useRef(false);
|
|
8594
|
+
React113.useEffect(() => {
|
|
8452
8595
|
if (!active2) return;
|
|
8453
8596
|
showPage();
|
|
8454
8597
|
claimed.current = true;
|
|
@@ -8457,7 +8600,7 @@ function RightRailPage({
|
|
|
8457
8600
|
closePage();
|
|
8458
8601
|
};
|
|
8459
8602
|
}, [active2, showPage, closePage]);
|
|
8460
|
-
|
|
8603
|
+
React113.useEffect(() => {
|
|
8461
8604
|
if (!claimed.current) return;
|
|
8462
8605
|
if (!useRightRailStore.getState().pageOpen) onCloseRef.current();
|
|
8463
8606
|
}, [pageOpen]);
|
|
@@ -8660,15 +8803,15 @@ function ConnectorSyncActions({
|
|
|
8660
8803
|
actions,
|
|
8661
8804
|
onRan
|
|
8662
8805
|
}) {
|
|
8663
|
-
const [running, setRunning] =
|
|
8664
|
-
const [open, setOpen] =
|
|
8665
|
-
const [pending2, setPending] =
|
|
8666
|
-
const [hidden, setHidden] =
|
|
8667
|
-
const [queued, setQueued] =
|
|
8668
|
-
const [nonce, setNonce] =
|
|
8669
|
-
const [expanded, setExpanded] =
|
|
8670
|
-
const [resolved, setResolved] =
|
|
8671
|
-
|
|
8806
|
+
const [running, setRunning] = React113__default.useState(null);
|
|
8807
|
+
const [open, setOpen] = React113__default.useState(null);
|
|
8808
|
+
const [pending2, setPending] = React113__default.useState(null);
|
|
8809
|
+
const [hidden, setHidden] = React113__default.useState(() => /* @__PURE__ */ new Set());
|
|
8810
|
+
const [queued, setQueued] = React113__default.useState({});
|
|
8811
|
+
const [nonce, setNonce] = React113__default.useState(0);
|
|
8812
|
+
const [expanded, setExpanded] = React113__default.useState(false);
|
|
8813
|
+
const [resolved, setResolved] = React113__default.useState(false);
|
|
8814
|
+
React113__default.useEffect(() => {
|
|
8672
8815
|
let cancelled = false;
|
|
8673
8816
|
setResolved(false);
|
|
8674
8817
|
void Promise.all(
|
|
@@ -8853,10 +8996,10 @@ function formatRelative(iso, t) {
|
|
|
8853
8996
|
}
|
|
8854
8997
|
function useConnectorRuns(connector) {
|
|
8855
8998
|
const listRuns = connector.definition?.listRuns;
|
|
8856
|
-
const [runs, setRuns] =
|
|
8857
|
-
const [loading, setLoading] =
|
|
8858
|
-
const [nonce, setNonce] =
|
|
8859
|
-
|
|
8999
|
+
const [runs, setRuns] = React113__default.useState([]);
|
|
9000
|
+
const [loading, setLoading] = React113__default.useState(!!listRuns);
|
|
9001
|
+
const [nonce, setNonce] = React113__default.useState(0);
|
|
9002
|
+
React113__default.useEffect(() => {
|
|
8860
9003
|
if (!listRuns) {
|
|
8861
9004
|
setRuns([]);
|
|
8862
9005
|
setLoading(false);
|
|
@@ -8878,7 +9021,7 @@ function useConnectorRuns(connector) {
|
|
|
8878
9021
|
return {
|
|
8879
9022
|
runs,
|
|
8880
9023
|
loading,
|
|
8881
|
-
reload:
|
|
9024
|
+
reload: React113__default.useCallback(() => setNonce((n) => n + 1), []),
|
|
8882
9025
|
failing: isFailing(runs)
|
|
8883
9026
|
};
|
|
8884
9027
|
}
|
|
@@ -8978,7 +9121,7 @@ function RunFailure({ run }) {
|
|
|
8978
9121
|
),
|
|
8979
9122
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t("connectors.runs.seeDetails") })
|
|
8980
9123
|
] }),
|
|
8981
|
-
facts.length > 0 && /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 border-t border-border px-2 py-2 text-[11px] leading-relaxed", children: facts.map(([label2, value]) => /* @__PURE__ */ jsxs(
|
|
9124
|
+
facts.length > 0 && /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 border-t border-border px-2 py-2 text-[11px] leading-relaxed", children: facts.map(([label2, value]) => /* @__PURE__ */ jsxs(React113__default.Fragment, { children: [
|
|
8982
9125
|
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: label2 }),
|
|
8983
9126
|
/* @__PURE__ */ jsx("dd", { className: "min-w-0 break-words font-mono text-foreground/80", children: value })
|
|
8984
9127
|
] }, label2)) }),
|
|
@@ -9147,13 +9290,13 @@ function ConnectorSettingsPanel({
|
|
|
9147
9290
|
const { t } = useTranslation$1();
|
|
9148
9291
|
const def = connector.definition;
|
|
9149
9292
|
const settings = def ? connectorSettings(def) : [];
|
|
9150
|
-
const [values, setValues] =
|
|
9293
|
+
const [values, setValues] = React113__default.useState(
|
|
9151
9294
|
() => initialValues(settings, {})
|
|
9152
9295
|
);
|
|
9153
|
-
const [loaded2, setLoaded] =
|
|
9154
|
-
const [saving, setSaving] =
|
|
9155
|
-
const [dirty, setDirty] =
|
|
9156
|
-
|
|
9296
|
+
const [loaded2, setLoaded] = React113__default.useState(false);
|
|
9297
|
+
const [saving, setSaving] = React113__default.useState(false);
|
|
9298
|
+
const [dirty, setDirty] = React113__default.useState(false);
|
|
9299
|
+
React113__default.useEffect(() => {
|
|
9157
9300
|
if (settings.length === 0 || !def?.getSettings) return;
|
|
9158
9301
|
let cancelled = false;
|
|
9159
9302
|
setLoaded(false);
|
|
@@ -9404,13 +9547,13 @@ function ConnectorInstall({
|
|
|
9404
9547
|
}) {
|
|
9405
9548
|
const { t } = useTranslation$1();
|
|
9406
9549
|
const def = connector.definition;
|
|
9407
|
-
const [plane, setPlane] =
|
|
9550
|
+
const [plane, setPlane] = React113__default.useState(
|
|
9408
9551
|
connector.planes.includes("agentic") ? "agentic" : connector.planes[0]
|
|
9409
9552
|
);
|
|
9410
|
-
const [values, setValues] =
|
|
9411
|
-
const secrets =
|
|
9412
|
-
const [busy, setBusy] =
|
|
9413
|
-
|
|
9553
|
+
const [values, setValues] = React113__default.useState({});
|
|
9554
|
+
const secrets = React113__default.useRef({});
|
|
9555
|
+
const [busy, setBusy] = React113__default.useState(null);
|
|
9556
|
+
React113__default.useEffect(() => {
|
|
9414
9557
|
setValues({});
|
|
9415
9558
|
secrets.current = {};
|
|
9416
9559
|
setBusy(null);
|
|
@@ -9451,15 +9594,15 @@ function ConnectorHome({
|
|
|
9451
9594
|
const needsSetup = connector.state === "needs_setup";
|
|
9452
9595
|
const settingsAvailable = hasOperatingSettings(connector);
|
|
9453
9596
|
const runsAvailable = hasRunHistory(connector);
|
|
9454
|
-
const [tab, setTab] =
|
|
9597
|
+
const [tab, setTab] = React113__default.useState(
|
|
9455
9598
|
needsSetup && settingsAvailable ? "settings" : "overview"
|
|
9456
9599
|
);
|
|
9457
|
-
const [busy, setBusy] =
|
|
9600
|
+
const [busy, setBusy] = React113__default.useState(null);
|
|
9458
9601
|
const run = useRunner(setBusy, onChanged);
|
|
9459
|
-
const [values, setValues] =
|
|
9460
|
-
const secrets =
|
|
9602
|
+
const [values, setValues] = React113__default.useState({});
|
|
9603
|
+
const secrets = React113__default.useRef({});
|
|
9461
9604
|
const runs = useConnectorRuns(connector);
|
|
9462
|
-
|
|
9605
|
+
React113__default.useEffect(() => {
|
|
9463
9606
|
setTab(needsSetup && settingsAvailable ? "settings" : "overview");
|
|
9464
9607
|
setBusy(null);
|
|
9465
9608
|
setValues({});
|
|
@@ -9549,7 +9692,7 @@ function ConnectorHome({
|
|
|
9549
9692
|
}
|
|
9550
9693
|
function useRunner(setBusy, onChanged) {
|
|
9551
9694
|
const { t } = useTranslation$1();
|
|
9552
|
-
return
|
|
9695
|
+
return React113__default.useCallback(
|
|
9553
9696
|
async (kind, fn, okMessage) => {
|
|
9554
9697
|
setBusy(kind);
|
|
9555
9698
|
try {
|
|
@@ -9665,7 +9808,7 @@ function ConnectPanel({
|
|
|
9665
9808
|
const sinkMissing = needsSink && !getConnectorCredentialSink();
|
|
9666
9809
|
const secretFieldCount = (def.fields ?? []).filter(isSecretField).length;
|
|
9667
9810
|
const hasStoredCredential = connector.state === "connected" || connector.state === "needs_setup";
|
|
9668
|
-
const [formKey, setFormKey] =
|
|
9811
|
+
const [formKey, setFormKey] = React113__default.useState(0);
|
|
9669
9812
|
if (def.authKind === "oauth") {
|
|
9670
9813
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
9671
9814
|
/* @__PURE__ */ jsx(Note, { children: t("connectors.authorize.oauthOnly") }),
|
|
@@ -9798,7 +9941,7 @@ function GrantRevoke({
|
|
|
9798
9941
|
onRevoke
|
|
9799
9942
|
}) {
|
|
9800
9943
|
const { t } = useTranslation$1();
|
|
9801
|
-
const [revoking, setRevoking] =
|
|
9944
|
+
const [revoking, setRevoking] = React113__default.useState(false);
|
|
9802
9945
|
if (connector.revocable === false) {
|
|
9803
9946
|
return /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("connectors.partOfApp") });
|
|
9804
9947
|
}
|
|
@@ -9837,14 +9980,14 @@ function ConnectorsPanel({ onClose }) {
|
|
|
9837
9980
|
const { connectors, reload, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
9838
9981
|
const selectedId = useConnectorsSurface((s) => s.selected);
|
|
9839
9982
|
const select = useConnectorsSurface((s) => s.select);
|
|
9840
|
-
const [query, setQuery] =
|
|
9841
|
-
const [failure, setFailure] =
|
|
9842
|
-
const [revoking, setRevoking] =
|
|
9843
|
-
const selected =
|
|
9983
|
+
const [query, setQuery] = React113__default.useState("");
|
|
9984
|
+
const [failure, setFailure] = React113__default.useState(null);
|
|
9985
|
+
const [revoking, setRevoking] = React113__default.useState(null);
|
|
9986
|
+
const selected = React113__default.useMemo(
|
|
9844
9987
|
() => (connectors ?? []).find((c) => c.id === selectedId) ?? null,
|
|
9845
9988
|
[connectors, selectedId]
|
|
9846
9989
|
);
|
|
9847
|
-
const filtered =
|
|
9990
|
+
const filtered = React113__default.useMemo(
|
|
9848
9991
|
() => filterConnectors(connectors ?? [], "outbound", query),
|
|
9849
9992
|
[connectors, query]
|
|
9850
9993
|
);
|
|
@@ -9855,9 +9998,9 @@ function ConnectorsPanel({ onClose }) {
|
|
|
9855
9998
|
back: onClose
|
|
9856
9999
|
} : null
|
|
9857
10000
|
);
|
|
9858
|
-
const closeRef =
|
|
10001
|
+
const closeRef = React113__default.useRef(onClose);
|
|
9859
10002
|
closeRef.current = onClose;
|
|
9860
|
-
|
|
10003
|
+
React113__default.useEffect(() => {
|
|
9861
10004
|
if (hosted && !selectedId) closeRef.current();
|
|
9862
10005
|
}, [hosted, selectedId]);
|
|
9863
10006
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [
|
|
@@ -9985,20 +10128,20 @@ function useDictation({
|
|
|
9985
10128
|
onInterim
|
|
9986
10129
|
}) {
|
|
9987
10130
|
const resolvedLocale = locale ?? (typeof navigator !== "undefined" ? navigator.language || "pt-BR" : "pt-BR");
|
|
9988
|
-
const [state, setState] =
|
|
9989
|
-
const [error, setError] =
|
|
9990
|
-
const sessionRef =
|
|
9991
|
-
const callbacks =
|
|
10131
|
+
const [state, setState] = React113.useState("idle");
|
|
10132
|
+
const [error, setError] = React113.useState(null);
|
|
10133
|
+
const sessionRef = React113.useRef(null);
|
|
10134
|
+
const callbacks = React113.useRef({ onTranscript, onInterim });
|
|
9992
10135
|
callbacks.current = { onTranscript, onInterim };
|
|
9993
|
-
const supported =
|
|
10136
|
+
const supported = React113.useMemo(
|
|
9994
10137
|
() => isDictationSupported(!!transcribeEndpoint),
|
|
9995
10138
|
[transcribeEndpoint]
|
|
9996
10139
|
);
|
|
9997
|
-
const finish =
|
|
10140
|
+
const finish = React113.useCallback(() => {
|
|
9998
10141
|
sessionRef.current = null;
|
|
9999
10142
|
setState("idle");
|
|
10000
10143
|
}, []);
|
|
10001
|
-
const start =
|
|
10144
|
+
const start = React113.useCallback(() => {
|
|
10002
10145
|
if (sessionRef.current || !supported) return;
|
|
10003
10146
|
stopSpeaking();
|
|
10004
10147
|
setError(null);
|
|
@@ -10019,28 +10162,28 @@ function useDictation({
|
|
|
10019
10162
|
}
|
|
10020
10163
|
);
|
|
10021
10164
|
}, [finish, resolvedLocale, supported, transcribeEndpoint]);
|
|
10022
|
-
const stop =
|
|
10165
|
+
const stop = React113.useCallback(() => {
|
|
10023
10166
|
if (!sessionRef.current) return;
|
|
10024
10167
|
if (transcribeEndpoint) setState("transcribing");
|
|
10025
10168
|
sessionRef.current.stop();
|
|
10026
10169
|
}, [transcribeEndpoint]);
|
|
10027
|
-
const cancel =
|
|
10170
|
+
const cancel = React113.useCallback(() => {
|
|
10028
10171
|
sessionRef.current?.cancel();
|
|
10029
10172
|
sessionRef.current = null;
|
|
10030
10173
|
setState("idle");
|
|
10031
10174
|
setError(null);
|
|
10032
10175
|
}, []);
|
|
10033
|
-
const toggle =
|
|
10176
|
+
const toggle = React113.useCallback(() => {
|
|
10034
10177
|
if (state === "listening" || state === "transcribing") stop();
|
|
10035
10178
|
else start();
|
|
10036
10179
|
}, [state, start, stop]);
|
|
10037
|
-
|
|
10180
|
+
React113.useEffect(() => () => sessionRef.current?.cancel(), []);
|
|
10038
10181
|
return { supported, state, error, start, stop, cancel, toggle, clearError: () => setError(null) };
|
|
10039
10182
|
}
|
|
10040
10183
|
function useMicLevels(active2, bandCount = 28, externalStream) {
|
|
10041
|
-
const levelsRef =
|
|
10042
|
-
const [available, setAvailable] =
|
|
10043
|
-
|
|
10184
|
+
const levelsRef = React113.useRef(new Float32Array(bandCount));
|
|
10185
|
+
const [available, setAvailable] = React113.useState(false);
|
|
10186
|
+
React113.useEffect(() => {
|
|
10044
10187
|
if (!active2) {
|
|
10045
10188
|
levelsRef.current.fill(0);
|
|
10046
10189
|
setAvailable(false);
|
|
@@ -10109,8 +10252,8 @@ var KIND_ICON = {
|
|
|
10109
10252
|
binary: File$1
|
|
10110
10253
|
};
|
|
10111
10254
|
function useFileDrop(enabled, onFiles) {
|
|
10112
|
-
const [dragging, setDragging] =
|
|
10113
|
-
const depth =
|
|
10255
|
+
const [dragging, setDragging] = React113.useState(false);
|
|
10256
|
+
const depth = React113.useRef(0);
|
|
10114
10257
|
const carriesFiles = (event) => Array.from(event.dataTransfer?.types ?? []).includes("Files");
|
|
10115
10258
|
const reset = () => {
|
|
10116
10259
|
depth.current = 0;
|
|
@@ -10170,7 +10313,7 @@ function AttachmentChips({
|
|
|
10170
10313
|
onRemove
|
|
10171
10314
|
}) {
|
|
10172
10315
|
const { t } = useTranslation$1();
|
|
10173
|
-
const [openId, setOpenId] =
|
|
10316
|
+
const [openId, setOpenId] = React113.useState(null);
|
|
10174
10317
|
if (!attachments.length) return null;
|
|
10175
10318
|
const opened = attachments.find((a) => a.id === openId);
|
|
10176
10319
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -10311,8 +10454,8 @@ function ChatComposer({
|
|
|
10311
10454
|
autoFocus
|
|
10312
10455
|
}) {
|
|
10313
10456
|
const { t } = useTranslation$1();
|
|
10314
|
-
const [input, setInput] =
|
|
10315
|
-
const textareaRef =
|
|
10457
|
+
const [input, setInput] = React113.useState("");
|
|
10458
|
+
const textareaRef = React113.useRef(null);
|
|
10316
10459
|
const voiceStartRequested = useChatStore((s) => s.voiceStartRequested);
|
|
10317
10460
|
const consumeVoiceStart = useChatStore((s) => s.consumeVoiceStart);
|
|
10318
10461
|
const draft = useChatStore((s) => s.draft);
|
|
@@ -10325,13 +10468,13 @@ function ChatComposer({
|
|
|
10325
10468
|
const removeAttachment = useChatStore((s) => s.removeAttachment);
|
|
10326
10469
|
const composerMedia = useChatStore((s) => s.composerMedia);
|
|
10327
10470
|
const clearComposerMedia = useChatStore((s) => s.clearComposerMedia);
|
|
10328
|
-
const fileInputRef =
|
|
10471
|
+
const fileInputRef = React113.useRef(null);
|
|
10329
10472
|
const autoSend = voice?.autoSend === true;
|
|
10330
10473
|
const micEnabled = voice?.input !== false;
|
|
10331
10474
|
const canAttach = isConfigured && !blocked && !isStreaming;
|
|
10332
10475
|
const parsing = attachments.some((a) => a.status === "parsing");
|
|
10333
10476
|
const readyAttachments = attachments.filter((a) => a.status === "ready").length;
|
|
10334
|
-
const submit =
|
|
10477
|
+
const submit = React113.useCallback(
|
|
10335
10478
|
(text2) => {
|
|
10336
10479
|
const trimmed = text2.trim();
|
|
10337
10480
|
const media = useChatStore.getState().composerMedia;
|
|
@@ -10361,7 +10504,7 @@ function ChatComposer({
|
|
|
10361
10504
|
}
|
|
10362
10505
|
}
|
|
10363
10506
|
});
|
|
10364
|
-
|
|
10507
|
+
React113.useEffect(() => {
|
|
10365
10508
|
if (!autoFocus) return;
|
|
10366
10509
|
const id = requestAnimationFrame(() => textareaRef.current?.focus());
|
|
10367
10510
|
return () => cancelAnimationFrame(id);
|
|
@@ -10373,7 +10516,7 @@ function ChatComposer({
|
|
|
10373
10516
|
const WAVEFORM_BANDS = 56;
|
|
10374
10517
|
const activity = useAssistantActivity();
|
|
10375
10518
|
const sessionRecording = activity?.kind === "recording" && activity.state === "running";
|
|
10376
|
-
const sessionStream =
|
|
10519
|
+
const sessionStream = React113.useMemo(
|
|
10377
10520
|
() => sessionRecording ? activity?.stream?.() ?? null : null,
|
|
10378
10521
|
[sessionRecording, activity]
|
|
10379
10522
|
);
|
|
@@ -10385,12 +10528,12 @@ function ChatComposer({
|
|
|
10385
10528
|
);
|
|
10386
10529
|
const sessionPause = activity?.actions?.find((a) => a.intent === "pause" || a.intent === "resume");
|
|
10387
10530
|
const sessionOwnsMic = activity?.kind === "recording" && (activity.state === "running" || activity.state === "paused");
|
|
10388
|
-
|
|
10531
|
+
React113.useEffect(() => {
|
|
10389
10532
|
if (!voiceStartRequested) return;
|
|
10390
10533
|
consumeVoiceStart();
|
|
10391
10534
|
if (showMic) dictation.start();
|
|
10392
10535
|
}, [voiceStartRequested, showMic]);
|
|
10393
|
-
|
|
10536
|
+
React113.useEffect(() => {
|
|
10394
10537
|
if (!focusRequested) return;
|
|
10395
10538
|
let frames = 0;
|
|
10396
10539
|
let raf = 0;
|
|
@@ -10407,7 +10550,7 @@ function ChatComposer({
|
|
|
10407
10550
|
raf = requestAnimationFrame(tick);
|
|
10408
10551
|
return () => cancelAnimationFrame(raf);
|
|
10409
10552
|
}, [focusRequested, consumeComposerFocus]);
|
|
10410
|
-
|
|
10553
|
+
React113.useEffect(() => {
|
|
10411
10554
|
if (!draft) return;
|
|
10412
10555
|
setInput(draft);
|
|
10413
10556
|
setDraft("");
|
|
@@ -10417,7 +10560,7 @@ function ChatComposer({
|
|
|
10417
10560
|
el.setSelectionRange(draft.length, draft.length);
|
|
10418
10561
|
}
|
|
10419
10562
|
}, [draft, setDraft]);
|
|
10420
|
-
|
|
10563
|
+
React113.useLayoutEffect(() => {
|
|
10421
10564
|
const el = textareaRef.current;
|
|
10422
10565
|
if (!el) return;
|
|
10423
10566
|
const style = getComputedStyle(el);
|
|
@@ -10620,8 +10763,8 @@ function UploadRequestCard() {
|
|
|
10620
10763
|
const removeUploadFile = useChatStore((s) => s.removeUploadFile);
|
|
10621
10764
|
const submitUpload = useChatStore((s) => s.submitUpload);
|
|
10622
10765
|
const clearUploadRequest = useChatStore((s) => s.clearUploadRequest);
|
|
10623
|
-
const cameraRef =
|
|
10624
|
-
const browseRef =
|
|
10766
|
+
const cameraRef = React113.useRef(null);
|
|
10767
|
+
const browseRef = React113.useRef(null);
|
|
10625
10768
|
if (!request) return null;
|
|
10626
10769
|
const working = request.status === "working";
|
|
10627
10770
|
const accept = request.accept ?? "image/*";
|
|
@@ -10763,8 +10906,8 @@ function LiveWaveform({
|
|
|
10763
10906
|
compact,
|
|
10764
10907
|
tone = "primary"
|
|
10765
10908
|
}) {
|
|
10766
|
-
const barsRef =
|
|
10767
|
-
|
|
10909
|
+
const barsRef = React113.useRef([]);
|
|
10910
|
+
React113.useEffect(() => {
|
|
10768
10911
|
if (!live) return;
|
|
10769
10912
|
let frame = 0;
|
|
10770
10913
|
const draw = () => {
|
|
@@ -10812,6 +10955,25 @@ function LiveWaveform({
|
|
|
10812
10955
|
)
|
|
10813
10956
|
);
|
|
10814
10957
|
}
|
|
10958
|
+
function MdLink({ href, children }) {
|
|
10959
|
+
const external = /^https?:\/\//.test(href);
|
|
10960
|
+
if (external) {
|
|
10961
|
+
return /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noreferrer", className: "underline underline-offset-2", children });
|
|
10962
|
+
}
|
|
10963
|
+
const path = href.startsWith("#") ? href.slice(1) : href;
|
|
10964
|
+
return /* @__PURE__ */ jsx(
|
|
10965
|
+
"a",
|
|
10966
|
+
{
|
|
10967
|
+
href: `#${path}`,
|
|
10968
|
+
onClick: (e) => {
|
|
10969
|
+
e.preventDefault();
|
|
10970
|
+
navigateTo(path);
|
|
10971
|
+
},
|
|
10972
|
+
className: "font-medium text-primary underline underline-offset-2 hover:text-primary/80",
|
|
10973
|
+
children
|
|
10974
|
+
}
|
|
10975
|
+
);
|
|
10976
|
+
}
|
|
10815
10977
|
function renderInline(text2, keyBase) {
|
|
10816
10978
|
const out = [];
|
|
10817
10979
|
const pattern = /(`[^`]+`)|(\*\*[^*]+\*\*)|(\*[^*]+\*)|(\[[^\]]+\]\([^)\s]+\))/g;
|
|
@@ -10834,7 +10996,7 @@ function renderInline(text2, keyBase) {
|
|
|
10834
10996
|
const link = /^\[([^\]]+)\]\(([^)\s]+)\)$/.exec(token);
|
|
10835
10997
|
if (link && /^(https?:\/\/|\/|#)/.test(link[2])) {
|
|
10836
10998
|
out.push(
|
|
10837
|
-
/* @__PURE__ */ jsx(
|
|
10999
|
+
/* @__PURE__ */ jsx(MdLink, { href: link[2], children: renderInline(link[1], key) }, key)
|
|
10838
11000
|
);
|
|
10839
11001
|
} else {
|
|
10840
11002
|
out.push(token);
|
|
@@ -10845,6 +11007,7 @@ function renderInline(text2, keyBase) {
|
|
|
10845
11007
|
if (last < text2.length) out.push(text2.slice(last));
|
|
10846
11008
|
return out;
|
|
10847
11009
|
}
|
|
11010
|
+
var LIST_RE = /^(\s*)([-*]|\d+[.)])\s+(.*)$/;
|
|
10848
11011
|
function ChatMarkdown({ content }) {
|
|
10849
11012
|
const blocks = [];
|
|
10850
11013
|
const lines = content.split("\n");
|
|
@@ -10858,28 +11021,64 @@ function ChatMarkdown({ content }) {
|
|
|
10858
11021
|
}
|
|
10859
11022
|
const heading = /^(#{1,4})\s+(.*)$/.exec(line);
|
|
10860
11023
|
if (heading) {
|
|
11024
|
+
const major = heading[1].length <= 2;
|
|
10861
11025
|
blocks.push(
|
|
10862
|
-
/* @__PURE__ */ jsx(
|
|
11026
|
+
/* @__PURE__ */ jsx(
|
|
11027
|
+
"p",
|
|
11028
|
+
{
|
|
11029
|
+
className: major ? "mt-3 text-[14px] font-bold first:mt-0" : "mt-3 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground first:mt-0",
|
|
11030
|
+
children: renderInline(heading[2], `h${key}`)
|
|
11031
|
+
},
|
|
11032
|
+
key++
|
|
11033
|
+
)
|
|
10863
11034
|
);
|
|
10864
11035
|
i++;
|
|
10865
11036
|
continue;
|
|
10866
11037
|
}
|
|
10867
|
-
|
|
11038
|
+
const listStart = LIST_RE.exec(line);
|
|
11039
|
+
if (listStart) {
|
|
11040
|
+
const baseIndent = listStart[1].length;
|
|
11041
|
+
const ordered = /^\d/.test(listStart[2]);
|
|
11042
|
+
const start = ordered ? parseInt(listStart[2], 10) : void 0;
|
|
10868
11043
|
const items = [];
|
|
10869
|
-
|
|
10870
|
-
|
|
10871
|
-
|
|
10872
|
-
|
|
11044
|
+
while (i < lines.length) {
|
|
11045
|
+
const m = LIST_RE.exec(lines[i]);
|
|
11046
|
+
if (!m) break;
|
|
11047
|
+
if (m[1].length > baseIndent) {
|
|
11048
|
+
const subOrdered = /^\d/.test(m[2]);
|
|
11049
|
+
const subStart = subOrdered ? parseInt(m[2], 10) : void 0;
|
|
11050
|
+
const subItems = [];
|
|
11051
|
+
while (i < lines.length) {
|
|
11052
|
+
const sm = LIST_RE.exec(lines[i]);
|
|
11053
|
+
if (!sm || sm[1].length <= baseIndent) break;
|
|
11054
|
+
subItems.push(/* @__PURE__ */ jsx("li", { children: renderInline(sm[3], `sli${key}-${subItems.length}`) }, subItems.length));
|
|
11055
|
+
i++;
|
|
11056
|
+
}
|
|
11057
|
+
const sub = subOrdered ? /* @__PURE__ */ jsx("ol", { start: subStart, className: "mt-0.5 space-y-0.5 pl-4 list-decimal", children: subItems }, `sub${items.length}`) : /* @__PURE__ */ jsx("ul", { className: "mt-0.5 space-y-0.5 pl-4 list-disc", children: subItems }, `sub${items.length}`);
|
|
11058
|
+
const prev = items.pop();
|
|
11059
|
+
if (prev && React113.isValidElement(prev)) {
|
|
11060
|
+
items.push(
|
|
11061
|
+
/* @__PURE__ */ jsxs("li", { children: [
|
|
11062
|
+
prev.props.children,
|
|
11063
|
+
sub
|
|
11064
|
+
] }, items.length)
|
|
11065
|
+
);
|
|
11066
|
+
} else {
|
|
11067
|
+
items.push(/* @__PURE__ */ jsx("li", { children: sub }, items.length));
|
|
11068
|
+
}
|
|
11069
|
+
continue;
|
|
11070
|
+
}
|
|
11071
|
+
items.push(/* @__PURE__ */ jsx("li", { children: renderInline(m[3], `li${key}-${items.length}`) }, items.length));
|
|
10873
11072
|
i++;
|
|
10874
11073
|
}
|
|
10875
11074
|
const listClass = "my-1 space-y-0.5 pl-4 first:mt-0 last:mb-0";
|
|
10876
11075
|
blocks.push(
|
|
10877
|
-
ordered ? /* @__PURE__ */ jsx("ol", { className: `${listClass} list-decimal`, children: items }, key++) : /* @__PURE__ */ jsx("ul", { className: `${listClass} list-disc`, children: items }, key++)
|
|
11076
|
+
ordered ? /* @__PURE__ */ jsx("ol", { start, className: `${listClass} list-decimal`, children: items }, key++) : /* @__PURE__ */ jsx("ul", { className: `${listClass} list-disc`, children: items }, key++)
|
|
10878
11077
|
);
|
|
10879
11078
|
continue;
|
|
10880
11079
|
}
|
|
10881
11080
|
const para = [];
|
|
10882
|
-
while (i < lines.length && lines[i].trim() &&
|
|
11081
|
+
while (i < lines.length && lines[i].trim() && !LIST_RE.test(lines[i]) && !/^#{1,4}\s+/.test(lines[i])) {
|
|
10883
11082
|
if (para.length) para.push(/* @__PURE__ */ jsx("br", {}, `br${key}-${para.length}`));
|
|
10884
11083
|
para.push(...renderInline(lines[i], `p${key}-${para.length}`));
|
|
10885
11084
|
i++;
|
|
@@ -10954,7 +11153,7 @@ var CARD_CTA = {
|
|
|
10954
11153
|
function useConnectorJourney(card) {
|
|
10955
11154
|
const panelAvailable = useConnectorsPanelAvailable();
|
|
10956
11155
|
useChatStore((s) => s.setOpen);
|
|
10957
|
-
return
|
|
11156
|
+
return React113.useCallback(() => {
|
|
10958
11157
|
if (panelAvailable && card.id) {
|
|
10959
11158
|
openConnectorsPanel({ id: card.id });
|
|
10960
11159
|
return;
|
|
@@ -11044,7 +11243,7 @@ function ConnectorSuggestionRow({ card }) {
|
|
|
11044
11243
|
] });
|
|
11045
11244
|
}
|
|
11046
11245
|
function ConnectorSuggestionGroup({ cards }) {
|
|
11047
|
-
const shelves =
|
|
11246
|
+
const shelves = React113.useMemo(() => shelveByCategory(cards), [cards]);
|
|
11048
11247
|
return /* @__PURE__ */ jsx("div", { className: "w-full max-w-[88%] overflow-hidden rounded-xl border border-border/60 bg-card/60 motion-safe:animate-zoom-in", children: shelves.map((shelf, shelfIndex) => /* @__PURE__ */ jsxs("div", { className: cn(shelfIndex > 0 && "border-t border-border/50"), children: [
|
|
11049
11248
|
shelf.label && /* @__PURE__ */ jsx("p", { className: "bg-background/40 px-2.5 py-1 text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: shelf.label }),
|
|
11050
11249
|
/* @__PURE__ */ jsx("div", { className: "divide-y divide-border/40", children: shelf.items.map((card) => /* @__PURE__ */ jsx(ConnectorSuggestionRow, { card }, card.slug ?? card.id ?? card.name)) })
|
|
@@ -11054,8 +11253,8 @@ function ChoiceCard({ card }) {
|
|
|
11054
11253
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
11055
11254
|
const isStreaming = useChatStore((s) => s.isStreaming);
|
|
11056
11255
|
const messages = useChatStore((s) => s.messages);
|
|
11057
|
-
const [optimistic, setOptimistic] =
|
|
11058
|
-
const answeredInThread =
|
|
11256
|
+
const [optimistic, setOptimistic] = React113.useState(null);
|
|
11257
|
+
const answeredInThread = React113.useMemo(
|
|
11059
11258
|
() => answeredOptionId(messages, card.options),
|
|
11060
11259
|
[messages, card.options]
|
|
11061
11260
|
);
|
|
@@ -11110,7 +11309,7 @@ function humanizeToolName(name) {
|
|
|
11110
11309
|
}
|
|
11111
11310
|
function ToolCallRow({ call: call2 }) {
|
|
11112
11311
|
const { t } = useTranslation$1();
|
|
11113
|
-
const [open, setOpen] =
|
|
11312
|
+
const [open, setOpen] = React113.useState(false);
|
|
11114
11313
|
const failed = call2.declined || /"error"\s*:/.test(call2.result ?? "");
|
|
11115
11314
|
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-xl border border-border/50 bg-muted/30", children: [
|
|
11116
11315
|
/* @__PURE__ */ jsxs(
|
|
@@ -11187,15 +11386,15 @@ function HandoffNotice({ notice }) {
|
|
|
11187
11386
|
}
|
|
11188
11387
|
function MessageBubble({ message, isPending }) {
|
|
11189
11388
|
const isUser = message.role === "user";
|
|
11190
|
-
const connectorCards =
|
|
11389
|
+
const connectorCards = React113.useMemo(
|
|
11191
11390
|
() => (message.cards ?? []).filter((card) => card.kind === "connector"),
|
|
11192
11391
|
[message.cards]
|
|
11193
11392
|
);
|
|
11194
|
-
const choiceCards =
|
|
11393
|
+
const choiceCards = React113.useMemo(
|
|
11195
11394
|
() => (message.cards ?? []).filter((card) => card.kind === "choice"),
|
|
11196
11395
|
[message.cards]
|
|
11197
11396
|
);
|
|
11198
|
-
const routedLinks =
|
|
11397
|
+
const routedLinks = React113.useMemo(
|
|
11199
11398
|
() => (message.links ?? []).filter(
|
|
11200
11399
|
(l) => !!l.path || !!resolveEntityRoute(l.archetype, l.kind, l.entityKey)
|
|
11201
11400
|
),
|
|
@@ -11286,9 +11485,9 @@ function ConfirmActionCard({
|
|
|
11286
11485
|
onResolveAll
|
|
11287
11486
|
}) {
|
|
11288
11487
|
const { t } = useTranslation$1();
|
|
11289
|
-
const schema =
|
|
11488
|
+
const schema = React113.useMemo(() => action.fields ?? [], [action.fields]);
|
|
11290
11489
|
const partial = action.partial === true;
|
|
11291
|
-
const seedValues =
|
|
11490
|
+
const seedValues = React113.useCallback(
|
|
11292
11491
|
(params) => {
|
|
11293
11492
|
if (partial) return { ...params };
|
|
11294
11493
|
const seeded = {};
|
|
@@ -11297,18 +11496,18 @@ function ConfirmActionCard({
|
|
|
11297
11496
|
},
|
|
11298
11497
|
[schema, partial]
|
|
11299
11498
|
);
|
|
11300
|
-
const [values, setValues] =
|
|
11301
|
-
const [showAll, setShowAll] =
|
|
11499
|
+
const [values, setValues] = React113.useState(() => seedValues(action.params));
|
|
11500
|
+
const [showAll, setShowAll] = React113.useState(false);
|
|
11302
11501
|
const batch = Math.max(0, sameToolQueued);
|
|
11303
|
-
|
|
11502
|
+
React113.useEffect(() => setValues(seedValues(action.params)), [action.params, seedValues]);
|
|
11304
11503
|
const isSet = (v) => v !== void 0 && v !== null && v !== "";
|
|
11305
|
-
const primaryKeys =
|
|
11504
|
+
const primaryKeys = React113.useMemo(() => {
|
|
11306
11505
|
const keys = Object.keys(action.params).filter((k) => isSet(action.params[k]));
|
|
11307
11506
|
if (partial) return keys;
|
|
11308
11507
|
for (const f of schema) if (f.required && !keys.includes(f.key)) keys.push(f.key);
|
|
11309
11508
|
return keys;
|
|
11310
11509
|
}, [action.params, schema, partial]);
|
|
11311
|
-
const extraKeys =
|
|
11510
|
+
const extraKeys = React113.useMemo(
|
|
11312
11511
|
() => schema.map((f) => f.key).filter((k) => !primaryKeys.includes(k) && k !== "id"),
|
|
11313
11512
|
[schema, primaryKeys]
|
|
11314
11513
|
);
|
|
@@ -11325,20 +11524,20 @@ function ConfirmActionCard({
|
|
|
11325
11524
|
const translatedTool = t(toolKey);
|
|
11326
11525
|
const heading = action.title ?? (translatedTool !== toolKey ? translatedTool : humanizeToolName(action.toolName));
|
|
11327
11526
|
const ruleLabel = action.scopeLabel ?? heading;
|
|
11328
|
-
const missingRequiredKeys =
|
|
11527
|
+
const missingRequiredKeys = React113.useMemo(
|
|
11329
11528
|
() => partial ? [] : schema.filter((f) => f.required && !isSet(values[f.key])).map((f) => f.key),
|
|
11330
11529
|
[schema, values, partial]
|
|
11331
11530
|
);
|
|
11332
11531
|
const canConfirm = missingRequiredKeys.length === 0;
|
|
11333
|
-
const submitted =
|
|
11532
|
+
const submitted = React113.useCallback(
|
|
11334
11533
|
() => partial ? Object.fromEntries(Object.entries(values).filter(([, v]) => isSet(v))) : values,
|
|
11335
11534
|
[partial, values]
|
|
11336
11535
|
);
|
|
11337
|
-
const approve =
|
|
11536
|
+
const approve = React113.useCallback(() => {
|
|
11338
11537
|
if (canConfirm) onResolve(true, submitted());
|
|
11339
11538
|
}, [canConfirm, onResolve, submitted]);
|
|
11340
|
-
const decline =
|
|
11341
|
-
const approveAlways =
|
|
11539
|
+
const decline = React113.useCallback(() => onResolve(false), [onResolve]);
|
|
11540
|
+
const approveAlways = React113.useCallback(() => {
|
|
11342
11541
|
if (!canConfirm) return;
|
|
11343
11542
|
grantAutoApproval({
|
|
11344
11543
|
toolName: action.toolName,
|
|
@@ -11348,7 +11547,7 @@ function ConfirmActionCard({
|
|
|
11348
11547
|
});
|
|
11349
11548
|
onResolve(true, submitted());
|
|
11350
11549
|
}, [canConfirm, action.toolName, action.scope, ruleLabel, destructive, onResolve, submitted]);
|
|
11351
|
-
|
|
11550
|
+
React113.useEffect(() => {
|
|
11352
11551
|
const handler = (event) => {
|
|
11353
11552
|
const target = event.target;
|
|
11354
11553
|
const typing = target?.tagName === "INPUT" || target?.tagName === "TEXTAREA" || target?.tagName === "SELECT";
|
|
@@ -11584,8 +11783,10 @@ function formatValue(value) {
|
|
|
11584
11783
|
}
|
|
11585
11784
|
return text2;
|
|
11586
11785
|
}
|
|
11786
|
+
var PLAIN_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
11587
11787
|
function toInputDate(value, type) {
|
|
11588
11788
|
if (typeof value !== "string" || !value) return "";
|
|
11789
|
+
if (PLAIN_DATE.test(value)) return type === "time" ? "" : value.slice(0, 10);
|
|
11589
11790
|
const parsed = new Date(value);
|
|
11590
11791
|
if (Number.isNaN(parsed.getTime())) return value;
|
|
11591
11792
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -11644,7 +11845,8 @@ function FieldInput({
|
|
|
11644
11845
|
onChange: (e) => {
|
|
11645
11846
|
const raw = e.target.value;
|
|
11646
11847
|
if (!raw) return onChange("");
|
|
11647
|
-
|
|
11848
|
+
if (type === "time" || type === "date") return onChange(raw);
|
|
11849
|
+
onChange(new Date(raw).toISOString());
|
|
11648
11850
|
},
|
|
11649
11851
|
className: base
|
|
11650
11852
|
}
|
|
@@ -11682,8 +11884,8 @@ var TYPE_MS = 620;
|
|
|
11682
11884
|
var MIN_CHAR_MS = 12;
|
|
11683
11885
|
var MAX_CHAR_MS = 34;
|
|
11684
11886
|
function usePrefersReducedMotion() {
|
|
11685
|
-
const [reduced, setReduced] =
|
|
11686
|
-
|
|
11887
|
+
const [reduced, setReduced] = React113.useState(false);
|
|
11888
|
+
React113.useEffect(() => {
|
|
11687
11889
|
if (typeof matchMedia !== "function") return;
|
|
11688
11890
|
const query = matchMedia("(prefers-reduced-motion: reduce)");
|
|
11689
11891
|
const sync = () => setReduced(query.matches);
|
|
@@ -11702,10 +11904,10 @@ function TypedText({
|
|
|
11702
11904
|
onDone
|
|
11703
11905
|
}) {
|
|
11704
11906
|
const reduced = usePrefersReducedMotion();
|
|
11705
|
-
const [count, setCount] =
|
|
11706
|
-
const done =
|
|
11907
|
+
const [count, setCount] = React113.useState(reduced ? text2.length : 0);
|
|
11908
|
+
const done = React113.useRef(onDone);
|
|
11707
11909
|
done.current = onDone;
|
|
11708
|
-
|
|
11910
|
+
React113.useEffect(() => {
|
|
11709
11911
|
if (!start) {
|
|
11710
11912
|
setCount(0);
|
|
11711
11913
|
return;
|
|
@@ -11745,9 +11947,9 @@ function RevealSequence({
|
|
|
11745
11947
|
children
|
|
11746
11948
|
}) {
|
|
11747
11949
|
const reduced = usePrefersReducedMotion();
|
|
11748
|
-
const items =
|
|
11749
|
-
const [shown, setShown] =
|
|
11750
|
-
|
|
11950
|
+
const items = React113.Children.toArray(children);
|
|
11951
|
+
const [shown, setShown] = React113.useState(0);
|
|
11952
|
+
React113.useEffect(() => {
|
|
11751
11953
|
if (!start) {
|
|
11752
11954
|
setShown(0);
|
|
11753
11955
|
return;
|
|
@@ -11809,7 +12011,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
11809
12011
|
const currentPlan = plans.find((p) => p.id === currentPlanId);
|
|
11810
12012
|
const currentPrice = currentPlan?.price ?? 0;
|
|
11811
12013
|
const currentPlanName = currentPlan?.name ?? tr("billing.free", "Free");
|
|
11812
|
-
const featureName =
|
|
12014
|
+
const featureName = React113.useMemo(() => {
|
|
11813
12015
|
if (!feature) return null;
|
|
11814
12016
|
const label2 = features.find((f) => f.id === feature)?.label;
|
|
11815
12017
|
if (label2) return featureDisplayName(label2);
|
|
@@ -11817,7 +12019,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
11817
12019
|
const named = t(key);
|
|
11818
12020
|
return named && named !== key ? named : featureDisplayName(feature);
|
|
11819
12021
|
}, [features, feature, t]);
|
|
11820
|
-
const unlockingPlans =
|
|
12022
|
+
const unlockingPlans = React113.useMemo(
|
|
11821
12023
|
() => plans.filter((p) => p.id !== currentPlanId && p.price > currentPrice && planUnlocks(p, feature)).sort((a, b) => a.price - b.price),
|
|
11822
12024
|
[plans, currentPlanId, currentPrice, feature]
|
|
11823
12025
|
);
|
|
@@ -11998,26 +12200,26 @@ function ChatConversation({
|
|
|
11998
12200
|
usable && !pendingAction && !isStreaming,
|
|
11999
12201
|
receiveFiles
|
|
12000
12202
|
);
|
|
12001
|
-
|
|
12002
|
-
const [view, setView] =
|
|
12203
|
+
React113.useEffect(ensureIntroStyles, []);
|
|
12204
|
+
const [view, setView] = React113.useState(
|
|
12003
12205
|
() => useChatStore.getState().messages.length > 0 ? "thread" : "list"
|
|
12004
12206
|
);
|
|
12005
|
-
const [drawer, setDrawer] =
|
|
12006
|
-
const [introStep, setIntroStep] =
|
|
12007
|
-
const [atBottom, setAtBottom] =
|
|
12008
|
-
const scrollRef =
|
|
12207
|
+
const [drawer, setDrawer] = React113.useState("none");
|
|
12208
|
+
const [introStep, setIntroStep] = React113.useState(0);
|
|
12209
|
+
const [atBottom, setAtBottom] = React113.useState(true);
|
|
12210
|
+
const scrollRef = React113.useRef(null);
|
|
12009
12211
|
const hasMessages = messages.length > 0;
|
|
12010
12212
|
const showThread = view === "thread" && hasMessages;
|
|
12011
12213
|
const totalTools = toolGroups.reduce((sum, g) => sum + g.tools.length, 0);
|
|
12012
|
-
const scrollToBottom =
|
|
12214
|
+
const scrollToBottom = React113.useCallback((behavior = "smooth") => {
|
|
12013
12215
|
const el = scrollRef.current;
|
|
12014
12216
|
if (!el) return;
|
|
12015
12217
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
12016
12218
|
}, []);
|
|
12017
|
-
|
|
12219
|
+
React113.useEffect(() => {
|
|
12018
12220
|
if (atBottom) scrollToBottom();
|
|
12019
12221
|
}, [messages, activeTools, pendingAction, atBottom, scrollToBottom]);
|
|
12020
|
-
|
|
12222
|
+
React113.useEffect(() => {
|
|
12021
12223
|
loadConversations();
|
|
12022
12224
|
setSuggestionsOpen(useChatStore.getState().messages.length === 0);
|
|
12023
12225
|
return () => stopSpeaking();
|
|
@@ -12034,7 +12236,7 @@ function ChatConversation({
|
|
|
12034
12236
|
};
|
|
12035
12237
|
const queuedPrompt = useChatStore((s) => s.queuedPrompt);
|
|
12036
12238
|
const consumeQueuedPrompt = useChatStore((s) => s.consumeQueuedPrompt);
|
|
12037
|
-
|
|
12239
|
+
React113.useEffect(() => {
|
|
12038
12240
|
if (!queuedPrompt) return;
|
|
12039
12241
|
const prompt = consumeQueuedPrompt();
|
|
12040
12242
|
if (prompt && usable) send(prompt);
|
|
@@ -12066,7 +12268,7 @@ function ChatConversation({
|
|
|
12066
12268
|
);
|
|
12067
12269
|
const connectorsPending = useConnectorsSurface((s) => s.pending);
|
|
12068
12270
|
const consumeConnectorsRequest = useConnectorsSurface((s) => s.consume);
|
|
12069
|
-
|
|
12271
|
+
React113.useEffect(() => {
|
|
12070
12272
|
if (!connectorsPending) return;
|
|
12071
12273
|
setDrawer("connectors");
|
|
12072
12274
|
consumeConnectorsRequest();
|
|
@@ -12074,7 +12276,7 @@ function ChatConversation({
|
|
|
12074
12276
|
const greetingName = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
12075
12277
|
const invite = useAssistantInviteStore((s) => s.invite);
|
|
12076
12278
|
const introKey = `${onDuty?.role ?? "solo"}:${invite?.id ?? ""}`;
|
|
12077
|
-
|
|
12279
|
+
React113.useEffect(() => setIntroStep(0), [introKey]);
|
|
12078
12280
|
const greeting = invite ? (invite.pitch ?? invite.headline).replace("{{name}}", greetingName) : onDuty?.greeting ? onDuty.greeting.replace("{{name}}", greetingName) : greetingName ? t("chat.greetingNamed", { name: greetingName }) : t("chat.greeting");
|
|
12079
12281
|
const greetingHint = invite?.description ?? onDuty?.goal ?? t("chat.greetingHint");
|
|
12080
12282
|
const openers = invite?.suggestions?.length ? invite.suggestions : onDuty?.suggestions?.length ? onDuty.suggestions : suggestions.length ? suggestions : [
|
|
@@ -12324,6 +12526,7 @@ function ChatConversation({
|
|
|
12324
12526
|
}
|
|
12325
12527
|
)
|
|
12326
12528
|
] }),
|
|
12529
|
+
drawer === "none" && /* @__PURE__ */ jsx(TourCoachCard, {}),
|
|
12327
12530
|
drawer === "none" && !pendingActivity && /* @__PURE__ */ jsx(
|
|
12328
12531
|
ChatComposer,
|
|
12329
12532
|
{
|
|
@@ -12394,7 +12597,7 @@ function AgentAvatar({
|
|
|
12394
12597
|
size = "md",
|
|
12395
12598
|
className
|
|
12396
12599
|
}) {
|
|
12397
|
-
const [failed, setFailed] =
|
|
12600
|
+
const [failed, setFailed] = React113.useState(false);
|
|
12398
12601
|
const { box, text: text2, px } = SIZES[size];
|
|
12399
12602
|
return /* @__PURE__ */ jsxs(
|
|
12400
12603
|
"span",
|
|
@@ -12876,37 +13079,43 @@ function TasksFilterBar() {
|
|
|
12876
13079
|
return void 0;
|
|
12877
13080
|
}
|
|
12878
13081
|
};
|
|
12879
|
-
return
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
13082
|
+
return (
|
|
13083
|
+
// h-10: a MESMA altura da faixa de abas da página, do outro lado da tela
|
|
13084
|
+
// (PageTabs, em header-tabs.tsx). Com padding em vez
|
|
13085
|
+
// de altura, cada painel do assistente media uma coisa — 41px aqui, 49 nas
|
|
13086
|
+
// Notas — e a linha embaixo da faixa pulava ao trocar de aba.
|
|
13087
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-10 shrink-0 items-center gap-1 overflow-x-auto border-b px-3", children: [
|
|
13088
|
+
FILTERS.map(({ key, labelKey }) => {
|
|
13089
|
+
const active2 = activeFilter === key;
|
|
13090
|
+
const count = getCount(key);
|
|
13091
|
+
return /* @__PURE__ */ jsxs(
|
|
13092
|
+
"button",
|
|
13093
|
+
{
|
|
13094
|
+
type: "button",
|
|
13095
|
+
onClick: () => setFilter(key),
|
|
13096
|
+
className: `${CHIP} ${active2 ? CHIP_ON : CHIP_OFF}`,
|
|
13097
|
+
children: [
|
|
13098
|
+
t(labelKey),
|
|
13099
|
+
count != null && /* @__PURE__ */ jsx("span", { className: `text-[10px] ${active2 ? "text-primary-foreground/80" : "text-muted-foreground"}`, children: count })
|
|
13100
|
+
]
|
|
13101
|
+
},
|
|
13102
|
+
key
|
|
13103
|
+
);
|
|
13104
|
+
}),
|
|
13105
|
+
currentUserId && /* @__PURE__ */ jsxs(
|
|
12884
13106
|
"button",
|
|
12885
13107
|
{
|
|
12886
13108
|
type: "button",
|
|
12887
|
-
onClick: () =>
|
|
12888
|
-
className: `${CHIP} ${
|
|
13109
|
+
onClick: () => setMine(!mine),
|
|
13110
|
+
className: `${CHIP} ml-auto ${mine ? CHIP_ON : CHIP_OFF}`,
|
|
12889
13111
|
children: [
|
|
12890
|
-
|
|
12891
|
-
|
|
13112
|
+
/* @__PURE__ */ jsx(User, { className: "h-3 w-3" }),
|
|
13113
|
+
t("tasks.filter.mine")
|
|
12892
13114
|
]
|
|
12893
|
-
}
|
|
12894
|
-
|
|
12895
|
-
|
|
12896
|
-
|
|
12897
|
-
currentUserId && /* @__PURE__ */ jsxs(
|
|
12898
|
-
"button",
|
|
12899
|
-
{
|
|
12900
|
-
type: "button",
|
|
12901
|
-
onClick: () => setMine(!mine),
|
|
12902
|
-
className: `${CHIP} ml-auto ${mine ? CHIP_ON : CHIP_OFF}`,
|
|
12903
|
-
children: [
|
|
12904
|
-
/* @__PURE__ */ jsx(User, { className: "h-3 w-3" }),
|
|
12905
|
-
t("tasks.filter.mine")
|
|
12906
|
-
]
|
|
12907
|
-
}
|
|
12908
|
-
)
|
|
12909
|
-
] });
|
|
13115
|
+
}
|
|
13116
|
+
)
|
|
13117
|
+
] })
|
|
13118
|
+
);
|
|
12910
13119
|
}
|
|
12911
13120
|
function TaskQuickAdd({ parentId }) {
|
|
12912
13121
|
const t = useTranslation();
|
|
@@ -13166,7 +13375,7 @@ function TaskStatusGroup({ status, tasks }) {
|
|
|
13166
13375
|
function useDelegateToAssistant() {
|
|
13167
13376
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
13168
13377
|
const openPanel = useRightRailStore((s) => s.openPanel);
|
|
13169
|
-
return
|
|
13378
|
+
return React113.useCallback(
|
|
13170
13379
|
(prompt) => {
|
|
13171
13380
|
queuePrompt(prompt);
|
|
13172
13381
|
openPanel("chat");
|
|
@@ -13403,12 +13612,12 @@ function TasksPanel() {
|
|
|
13403
13612
|
const fetchTasks = useTasksStore((s) => s.fetchTasks);
|
|
13404
13613
|
const fetchLabels = useTasksStore((s) => s.fetchLabels);
|
|
13405
13614
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13406
|
-
|
|
13615
|
+
React113__default.useEffect(() => {
|
|
13407
13616
|
void fetchTasks();
|
|
13408
13617
|
void fetchLabels();
|
|
13409
13618
|
void fetchSummary();
|
|
13410
13619
|
}, [fetchTasks, fetchLabels, fetchSummary]);
|
|
13411
|
-
const { onboarding, grouped } =
|
|
13620
|
+
const { onboarding, grouped } = React113__default.useMemo(() => {
|
|
13412
13621
|
const split = splitOnboardingTasks(tasks);
|
|
13413
13622
|
const map = /* @__PURE__ */ new Map();
|
|
13414
13623
|
for (const s of STATUS_ORDER) map.set(s, []);
|
|
@@ -13443,7 +13652,7 @@ function TasksPanel() {
|
|
|
13443
13652
|
function useTasksSummaryLine() {
|
|
13444
13653
|
const t = useTranslation();
|
|
13445
13654
|
const summary = useTasksStore((s) => s.summary);
|
|
13446
|
-
return
|
|
13655
|
+
return React113__default.useMemo(() => {
|
|
13447
13656
|
if (!summary) return "";
|
|
13448
13657
|
const parts = [];
|
|
13449
13658
|
if (summary.overdue > 0) parts.push(`${summary.overdue} ${t("tasks.summary.overdue")}`);
|
|
@@ -13468,16 +13677,16 @@ function TasksRailPanel() {
|
|
|
13468
13677
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13469
13678
|
const setCurrentUserId = useTasksStore((s) => s.setCurrentUserId);
|
|
13470
13679
|
const userId = useAuthStore6((s) => s.user?.id);
|
|
13471
|
-
|
|
13680
|
+
React113__default.useEffect(() => {
|
|
13472
13681
|
void fetchSummary();
|
|
13473
13682
|
}, [fetchSummary]);
|
|
13474
|
-
|
|
13683
|
+
React113__default.useEffect(() => {
|
|
13475
13684
|
setCurrentUserId(userId ?? null);
|
|
13476
13685
|
}, [userId, setCurrentUserId]);
|
|
13477
13686
|
const openCount = summary ? summary.todo + summary.inProgress : 0;
|
|
13478
13687
|
const defer = tasksSurfaceOwner() === "plugin";
|
|
13479
13688
|
useRightRailPanel(
|
|
13480
|
-
|
|
13689
|
+
React113__default.useMemo(
|
|
13481
13690
|
() => defer ? null : {
|
|
13482
13691
|
id: "tasks",
|
|
13483
13692
|
label: t("tasks.drawer.title") || "Tasks",
|
|
@@ -13501,15 +13710,15 @@ var useSettingsTabsStore = create((set, get) => ({
|
|
|
13501
13710
|
}));
|
|
13502
13711
|
function usePublishSettingsTabs(ids) {
|
|
13503
13712
|
const key = ids.join(",");
|
|
13504
|
-
|
|
13713
|
+
React113.useEffect(() => {
|
|
13505
13714
|
useSettingsTabsStore.getState().setIds(key ? key.split(",") : []);
|
|
13506
13715
|
}, [key]);
|
|
13507
13716
|
}
|
|
13508
13717
|
function useAgentSurface(contribution) {
|
|
13509
|
-
const ref =
|
|
13718
|
+
const ref = React113.useRef(contribution);
|
|
13510
13719
|
ref.current = contribution;
|
|
13511
13720
|
const id = contribution.id;
|
|
13512
|
-
|
|
13721
|
+
React113.useEffect(() => {
|
|
13513
13722
|
registerSurface({ id, get: () => ref.current });
|
|
13514
13723
|
const names = (ref.current.tools ?? []).map((t) => t.tool.name);
|
|
13515
13724
|
for (const name of names) {
|
|
@@ -14178,22 +14387,30 @@ var TOOLS = [
|
|
|
14178
14387
|
{
|
|
14179
14388
|
id: "onboarding.highlight",
|
|
14180
14389
|
name: "highlightFeature",
|
|
14181
|
-
description: 'Points at things on screen: dims the page
|
|
14390
|
+
description: 'Points at things on screen: dims the page, a big cursor travels to one control at a time, and a short note explains it. Use it to TEACH \u2014 "this is where a new order lands". Anchors must come from `anchorsOnScreen` OR from `featureMap` in the surface state; a featureMap anchor lives on another screen, so send its `route` along. Anything else points at nothing.',
|
|
14182
14391
|
icon: "Sparkles",
|
|
14183
14392
|
mode: "read",
|
|
14184
14393
|
parameters: {
|
|
14185
14394
|
type: "object",
|
|
14186
14395
|
properties: {
|
|
14396
|
+
title: {
|
|
14397
|
+
type: "string",
|
|
14398
|
+
description: 'Short name for the running-tour badge, e.g. "Contas a Pagar". Optional.'
|
|
14399
|
+
},
|
|
14187
14400
|
stops: {
|
|
14188
14401
|
type: "array",
|
|
14189
14402
|
description: "The stops, in order. One is fine.",
|
|
14190
14403
|
items: {
|
|
14191
14404
|
type: "object",
|
|
14192
14405
|
properties: {
|
|
14193
|
-
anchor: { type: "string", description: "An anchor id from anchorsOnScreen." },
|
|
14406
|
+
anchor: { type: "string", description: "An anchor id from anchorsOnScreen or featureMap." },
|
|
14194
14407
|
title: { type: "string", description: "Short label \u2014 what this control is." },
|
|
14195
14408
|
body: { type: "string", description: "One sentence on why it matters. Optional." },
|
|
14196
|
-
route: { type: "string", description: "Open this page first, when the anchor is on another screen." }
|
|
14409
|
+
route: { type: "string", description: "Open this page first, when the anchor is on another screen." },
|
|
14410
|
+
waitForUser: {
|
|
14411
|
+
type: "boolean",
|
|
14412
|
+
description: "Handover: no next button \u2014 the person is meant to CLICK the highlighted control, and the tour steps aside when they do. Use it on the stop where they act."
|
|
14413
|
+
}
|
|
14197
14414
|
},
|
|
14198
14415
|
required: ["anchor", "title"]
|
|
14199
14416
|
}
|
|
@@ -14272,10 +14489,18 @@ function anchorsOnScreen() {
|
|
|
14272
14489
|
}
|
|
14273
14490
|
return Array.from(seen).slice(0, 60);
|
|
14274
14491
|
}
|
|
14492
|
+
function featureMap() {
|
|
14493
|
+
return listSetupGuides().filter((g) => !!g.route).slice(0, 40).map((g) => ({
|
|
14494
|
+
feature: g.feature,
|
|
14495
|
+
title: g.title,
|
|
14496
|
+
route: g.route,
|
|
14497
|
+
anchors: (g.steps ?? []).filter((s) => !!s.anchor).map((s) => ({ anchor: s.anchor, route: s.route, do: s.do }))
|
|
14498
|
+
}));
|
|
14499
|
+
}
|
|
14275
14500
|
function ActivationAgentSurface({ programs }) {
|
|
14276
|
-
const programsRef =
|
|
14501
|
+
const programsRef = React113.useRef(programs);
|
|
14277
14502
|
programsRef.current = programs;
|
|
14278
|
-
const contribution =
|
|
14503
|
+
const contribution = React113.useMemo(
|
|
14279
14504
|
() => ({
|
|
14280
14505
|
id: "onboarding.activation",
|
|
14281
14506
|
pluginId: "onboarding",
|
|
@@ -14310,7 +14535,8 @@ function ActivationAgentSurface({ programs }) {
|
|
|
14310
14535
|
guide: getSetupGuideForStep(next.key)?.feature ?? null
|
|
14311
14536
|
} : null,
|
|
14312
14537
|
steps,
|
|
14313
|
-
anchorsOnScreen: anchorsOnScreen()
|
|
14538
|
+
anchorsOnScreen: anchorsOnScreen(),
|
|
14539
|
+
featureMap: featureMap()
|
|
14314
14540
|
}
|
|
14315
14541
|
};
|
|
14316
14542
|
},
|
|
@@ -14417,10 +14643,12 @@ function ActivationAgentSurface({ programs }) {
|
|
|
14417
14643
|
anchor: String(s["anchor"]),
|
|
14418
14644
|
title: String(s["title"]),
|
|
14419
14645
|
body: typeof s["body"] === "string" ? s["body"] : void 0,
|
|
14420
|
-
route: typeof s["route"] === "string" ? s["route"] : void 0
|
|
14646
|
+
route: typeof s["route"] === "string" ? s["route"] : void 0,
|
|
14647
|
+
waitForUser: s["waitForUser"] === true
|
|
14421
14648
|
}));
|
|
14422
14649
|
if (stops.length === 0) return { error: "no_stops", message: "Give me at least one anchor to point at." };
|
|
14423
|
-
|
|
14650
|
+
const title = typeof args["title"] === "string" ? args["title"] : void 0;
|
|
14651
|
+
useTourStore.getState().start({ id: `agent.${Date.now()}`, title, stops });
|
|
14424
14652
|
return { started: stops.length };
|
|
14425
14653
|
}
|
|
14426
14654
|
}
|
|
@@ -14540,7 +14768,7 @@ var TOOLS2 = [
|
|
|
14540
14768
|
{
|
|
14541
14769
|
id: "setup.start",
|
|
14542
14770
|
name: "startFeatureSetup",
|
|
14543
|
-
description:
|
|
14771
|
+
description: `Walks the person to a feature ON SCREEN: opens its page and runs a guided tour \u2014 a big cursor travels stop by stop through the feature's anchored steps \u2014 then returns the guide so you can narrate. THE tool for "me mostra", "como eu crio X", "onde fica X": showing beats describing. One tool for every feature \u2014 pass the feature id, never ask for a feature-specific tool.`,
|
|
14544
14772
|
icon: "Compass",
|
|
14545
14773
|
mode: "read",
|
|
14546
14774
|
parameters: {
|
|
@@ -14555,24 +14783,39 @@ var INSTRUCTIONS = tl(
|
|
|
14555
14783
|
`# Setting features up
|
|
14556
14784
|
Every feature in this product has a SETUP GUIDE \u2014 what it is for, what has to exist before it works, the steps, and where people get it wrong. \`setupGuides\` in the surface state is the catalog; \`readSetupGuide\` is the guide itself.
|
|
14557
14785
|
|
|
14786
|
+
## THE RULE, above everything else
|
|
14787
|
+
When the person asks HOW to do something that has a guide in \`setupGuides\` ("como crio/cadastro/lan\xE7o X", "como uso X", "me mostra", "onde fica X"), your FIRST action is \`startFeatureSetup({feature})\` \u2014 before writing ANY prose. It runs the on-screen tour (a big cursor walks them there, then footprints let them do it). NEVER answer such a question with a written list of steps when a guide exists: that is the one thing this product does better than a manual, and skipping it is the failure. Match the ask to a guide's \`title\`/\`answers\` in \`setupGuides\`; only if none matches do you fall back to prose. After the tour is running, add a SHORT note \u2014 do not re-list the steps the cursor is already showing.
|
|
14788
|
+
|
|
14558
14789
|
- Anything that sounds like "how do I start using X", "how does X work", "X is not doing anything" is a guide read FIRST. Never answer it from the screen alone: what is missing is usually on another screen entirely.
|
|
14559
14790
|
- Check the PREREQUISITES before the steps, using each one's "done when". Then say only what is genuinely still missing. Reading a list of five prerequisites back at somebody who has four of them is how a product feels like paperwork.
|
|
14560
14791
|
- Do the steps marked as yours \u2014 do not narrate a tool call you could just make. Hand the rest over: open the screen, point at the one control, say in one line what it wants, and stop.
|
|
14792
|
+
- "Show me", "how do I create/register X", "where is X" \u2192 call \`startFeatureSetup\` FIRST. It walks the person there on screen \u2014 a big cursor, stop by stop. Showing beats describing: never answer a "how do I" with a list of clicks when a tour exists for it. Use \`navigateTo\`/\`highlightFeature\` for one-off pointing; never ask for a feature-specific tool.
|
|
14793
|
+
- The \`feature\` id MUST come from \`setupGuides\` in the surface state (or \`findSetupGuide\`) \u2014 NEVER invent one like "resto:tables". If \`startFeatureSetup\` returns \`unknown_feature\`, its \`available\` list has the real ids; retry with the closest, or tell the person there is no tour for it yet.
|
|
14794
|
+
- \`startFeatureSetup\` ALREADY runs the whole tour (every step). Do NOT also call \`highlightFeature\` after it \u2014 a second tour replaces the first and truncates it to your improvised stops. \`highlightFeature\` is only for pointing at something with no guide of its own.
|
|
14795
|
+
- FORMAT long answers in sections with \`###\` headings (e.g. ### Configura\xE7\xF5es, ### Passo a passo, ### Dicas). Number steps continuously (1, 2, 3\u2026), sub-details as an indented list under their step.
|
|
14796
|
+
- Every screen you mention is a LINK, never a bare route: \`[Configura\xE7\xF5es \u203A Financeiro \u203A Plano de contas](/settings/financial/chart-of-accounts)\` \u2014 label from the guide's own menu path (\`where\`), URL from its \`route\`. A person clicks it and lands there with the chat still open.
|
|
14561
14797
|
- Say the warnings BEFORE the person spends an hour on one, not after.
|
|
14562
14798
|
- When a guide says the feature is unavailable or manual-only, say that plainly. Never route around it.
|
|
14563
14799
|
- Finish by naming what this unlocks and offering the next feature, once.`,
|
|
14564
14800
|
`# Colocando uma funcionalidade de p\xE9
|
|
14565
14801
|
Toda funcionalidade deste produto tem um GUIA DE IMPLANTA\xC7\xC3O \u2014 para que serve, o que precisa existir antes de funcionar, os passos, e onde as pessoas erram. \`setupGuides\` no estado da tela \xE9 o cat\xE1logo; \`readSetupGuide\` \xE9 o guia.
|
|
14566
14802
|
|
|
14803
|
+
## A REGRA, acima de tudo
|
|
14804
|
+
Quando a pessoa perguntar COMO fazer algo que tem guia em \`setupGuides\` ("como crio/cadastro/lan\xE7o X", "como uso X", "me mostra", "onde fica X"), sua PRIMEIRA a\xE7\xE3o \xE9 \`startFeatureSetup({feature})\` \u2014 antes de QUALQUER texto. Ele roda o tour na tela (um cursor grande leva a pessoa at\xE9 l\xE1 e depois marcadores deixam ela fazer). NUNCA responda esse tipo de pergunta com uma lista de passos escrita quando existe guia: \xE9 justamente o que este produto faz melhor que um manual, e pular isso \xE9 o erro. Case o pedido com o \`title\`/\`answers\` de um guia em \`setupGuides\`; s\xF3 cai no texto se NENHUM casar. Com o tour rodando, acrescente uma nota CURTA \u2014 n\xE3o re-liste os passos que o cursor j\xE1 est\xE1 mostrando.
|
|
14805
|
+
|
|
14567
14806
|
- Qualquer coisa do tipo "como eu come\xE7o a usar X", "como funciona X", "X n\xE3o est\xE1 fazendo nada" come\xE7a lendo o guia. Nunca responda s\xF3 pela tela: o que falta costuma estar em outra tela.
|
|
14568
14807
|
- Confira os PR\xC9-REQUISITOS antes dos passos, usando o "pronto quando" de cada um. Depois diga s\xF3 o que realmente falta. Recitar cinco pr\xE9-requisitos para quem j\xE1 tem quatro \xE9 o que faz um produto parecer burocracia.
|
|
14569
14808
|
- Fa\xE7a os passos que s\xE3o seus \u2014 n\xE3o narre uma chamada de ferramenta que voc\xEA poderia simplesmente fazer. O resto \xE9 da pessoa: abra a tela, aponte o \xFAnico controle, diga em uma linha o que ele quer, e pare.
|
|
14809
|
+
- "Me mostra", "como eu crio/cadastro X", "onde fica X" \u2192 chame \`startFeatureSetup\` PRIMEIRO. Ele leva a pessoa na tela \u2014 um cursor grande, parada por parada. Mostrar ganha de descrever: nunca responda um "como fa\xE7o" com uma lista de cliques quando existe tour para isso. Use \`navigateTo\`/\`highlightFeature\` para apontar algo avulso; nunca pe\xE7a uma ferramenta espec\xEDfica de feature.
|
|
14810
|
+
- \`startFeatureSetup\` J\xC1 roda o tour inteiro (todas as paradas). N\xC3O chame \`highlightFeature\` depois dele \u2014 um segundo tour substitui o primeiro e o corta nas suas paradas improvisadas. \`highlightFeature\` \xE9 s\xF3 para apontar algo que n\xE3o tem guia pr\xF3prio.
|
|
14811
|
+
- FORMATE respostas longas em se\xE7\xF5es com \`###\` (ex.: ### Configura\xE7\xF5es, ### Passo a passo, ### Dicas). Numere os passos de forma cont\xEDnua (1, 2, 3\u2026); detalhes de um passo v\xE3o como sublista indentada embaixo dele.
|
|
14812
|
+
- Toda tela citada \xE9 um LINK, nunca rota crua: \`[Configura\xE7\xF5es \u203A Financeiro \u203A Plano de contas](/settings/financial/chart-of-accounts)\` \u2014 o r\xF3tulo \xE9 o caminho de menu do guia (\`where\`), a URL \xE9 a \`route\`. A pessoa clica e cai l\xE1 com o chat aberto do lado.
|
|
14570
14813
|
- Diga os avisos ANTES de a pessoa perder uma hora com um deles, n\xE3o depois.
|
|
14571
14814
|
- Quando o guia disser que a funcionalidade n\xE3o existe ou n\xE3o d\xE1 para configurar, diga isso com todas as letras. Nunca contorne.
|
|
14572
14815
|
- Termine dizendo o que isso destrava e oferecendo a pr\xF3xima, uma vez s\xF3.`
|
|
14573
14816
|
);
|
|
14574
14817
|
function SetupAgentSurface() {
|
|
14575
|
-
const contribution =
|
|
14818
|
+
const contribution = React113.useMemo(
|
|
14576
14819
|
() => ({
|
|
14577
14820
|
id: "setup.guides",
|
|
14578
14821
|
pluginId: "setup",
|
|
@@ -14633,8 +14876,19 @@ function SetupAgentSurface() {
|
|
|
14633
14876
|
tool: TOOLS2[2],
|
|
14634
14877
|
execute: (args) => {
|
|
14635
14878
|
const feature = String(args["feature"] ?? "");
|
|
14636
|
-
|
|
14637
|
-
if (!guide)
|
|
14879
|
+
let guide = getSetupGuide(feature);
|
|
14880
|
+
if (!guide) {
|
|
14881
|
+
const normalized = feature.replace(/[:._-]+/g, " ").replace(/\bresto\b/gi, " ").trim();
|
|
14882
|
+
guide = searchSetupGuides(normalized, 1)[0];
|
|
14883
|
+
}
|
|
14884
|
+
if (!guide) {
|
|
14885
|
+
const available = listSetupGuides().map((g) => ({ feature: g.feature, title: g.title }));
|
|
14886
|
+
return {
|
|
14887
|
+
error: "unknown_feature",
|
|
14888
|
+
message: `No guide "${feature}". Pick a feature from this list (or say there is no tour for it):`,
|
|
14889
|
+
available
|
|
14890
|
+
};
|
|
14891
|
+
}
|
|
14638
14892
|
if (guide.status === "unavailable") {
|
|
14639
14893
|
return {
|
|
14640
14894
|
opened: null,
|
|
@@ -14643,8 +14897,23 @@ function SetupAgentSurface() {
|
|
|
14643
14897
|
};
|
|
14644
14898
|
}
|
|
14645
14899
|
if (guide.route) navigateTo(guide.route);
|
|
14646
|
-
const
|
|
14647
|
-
|
|
14900
|
+
const anchored = (guide.steps ?? []).filter((s) => s.anchor);
|
|
14901
|
+
const stops = anchored.map((s) => ({
|
|
14902
|
+
anchor: s.anchor,
|
|
14903
|
+
title: s.do,
|
|
14904
|
+
...s.why ? { body: s.why } : {},
|
|
14905
|
+
...s.route ? { route: s.route } : {},
|
|
14906
|
+
...s.handOver ? { waitForUser: true } : {}
|
|
14907
|
+
}));
|
|
14908
|
+
const practice = (guide.practice ?? []).map((p) => ({ anchor: p.anchor, label: p.label, final: p.final }));
|
|
14909
|
+
if (stops.length > 0) {
|
|
14910
|
+
useTourStore.getState().start({
|
|
14911
|
+
id: `setup.${guide.feature}`,
|
|
14912
|
+
title: guide.title,
|
|
14913
|
+
stops,
|
|
14914
|
+
...practice.length ? { practice } : {}
|
|
14915
|
+
});
|
|
14916
|
+
}
|
|
14648
14917
|
return {
|
|
14649
14918
|
opened: guide.route ?? null,
|
|
14650
14919
|
feature: guide.feature,
|
|
@@ -14662,7 +14931,7 @@ function SetupAgentSurface() {
|
|
|
14662
14931
|
}
|
|
14663
14932
|
var DEBOUNCE_MS = 1200;
|
|
14664
14933
|
function useActivationWatch() {
|
|
14665
|
-
|
|
14934
|
+
React113.useEffect(() => {
|
|
14666
14935
|
let timer = null;
|
|
14667
14936
|
let running = false;
|
|
14668
14937
|
const sweep = async () => {
|
|
@@ -14701,7 +14970,7 @@ function useActivationWatch() {
|
|
|
14701
14970
|
off();
|
|
14702
14971
|
};
|
|
14703
14972
|
}, []);
|
|
14704
|
-
|
|
14973
|
+
React113.useEffect(() => {
|
|
14705
14974
|
useActivationStore.setState({
|
|
14706
14975
|
onStepCompleted: (step, by) => {
|
|
14707
14976
|
const state = useActivationStore.getState();
|
|
@@ -15358,7 +15627,7 @@ function ActivationProvider() {
|
|
|
15358
15627
|
const programs = runtime?.onboardingPrograms ?? [];
|
|
15359
15628
|
const settingsIds = useSettingsTabsStore((s) => s.ids);
|
|
15360
15629
|
const routeKey = (runtime?.routes.length ?? 0) + ":" + settingsIds.join(",");
|
|
15361
|
-
const hasRoute =
|
|
15630
|
+
const hasRoute = React113.useMemo(() => {
|
|
15362
15631
|
const known = /* @__PURE__ */ new Set(["/", "/settings"]);
|
|
15363
15632
|
for (const route of runtime?.routes ?? []) known.add(route.path);
|
|
15364
15633
|
for (const id of settingsIds) known.add(`/settings/${id}`);
|
|
@@ -15366,14 +15635,14 @@ function ActivationProvider() {
|
|
|
15366
15635
|
}, [routeKey]);
|
|
15367
15636
|
const answers = useBusinessProfileStore((s) => s.profile?.answers);
|
|
15368
15637
|
const programKey = programs.map((p) => p.id).join(",");
|
|
15369
|
-
const catalog =
|
|
15638
|
+
const catalog = React113.useMemo(
|
|
15370
15639
|
() => buildActivationCatalog({ verticalId, programs, hasRoute, answers }),
|
|
15371
15640
|
[verticalId, programKey, hasRoute, answers]
|
|
15372
15641
|
);
|
|
15373
|
-
|
|
15642
|
+
React113.useEffect(() => {
|
|
15374
15643
|
setCatalog(catalog);
|
|
15375
15644
|
}, [catalog, setCatalog]);
|
|
15376
|
-
|
|
15645
|
+
React113.useEffect(() => {
|
|
15377
15646
|
if (!tenantId2) return;
|
|
15378
15647
|
let cancelled = false;
|
|
15379
15648
|
void (async () => {
|
|
@@ -15405,14 +15674,14 @@ function ActivationProvider() {
|
|
|
15405
15674
|
cancelled = true;
|
|
15406
15675
|
};
|
|
15407
15676
|
}, [tenantId2, catalog, answers, hasRoute, settingsIds, user?.id, load]);
|
|
15408
|
-
|
|
15677
|
+
React113.useEffect(() => {
|
|
15409
15678
|
if (!tenantId2) {
|
|
15410
15679
|
useBusinessProfileStore.getState().clear();
|
|
15411
15680
|
return;
|
|
15412
15681
|
}
|
|
15413
15682
|
void useBusinessProfileStore.getState().load(tenantId2, orgName);
|
|
15414
15683
|
}, [tenantId2, orgName]);
|
|
15415
|
-
|
|
15684
|
+
React113.useEffect(() => {
|
|
15416
15685
|
if (!tenantId2) return;
|
|
15417
15686
|
const key = `${GREETING_FLAG}:${tenantId2}`;
|
|
15418
15687
|
let pending2 = false;
|
|
@@ -15434,10 +15703,10 @@ function ActivationProvider() {
|
|
|
15434
15703
|
return () => window.clearTimeout(timer);
|
|
15435
15704
|
}, [tenantId2]);
|
|
15436
15705
|
const guides = runtime?.setupGuides;
|
|
15437
|
-
|
|
15706
|
+
React113.useEffect(() => {
|
|
15438
15707
|
setRuntimeSetupGuides(guides ?? []);
|
|
15439
15708
|
}, [guides]);
|
|
15440
|
-
|
|
15709
|
+
React113.useEffect(() => {
|
|
15441
15710
|
setTourNavigator(navigateTo);
|
|
15442
15711
|
return () => setTourNavigator(void 0);
|
|
15443
15712
|
}, []);
|
|
@@ -15460,7 +15729,8 @@ function ActivationProvider() {
|
|
|
15460
15729
|
)
|
|
15461
15730
|
}
|
|
15462
15731
|
}
|
|
15463
|
-
)
|
|
15732
|
+
),
|
|
15733
|
+
/* @__PURE__ */ jsx(PracticeOverlay, {})
|
|
15464
15734
|
] });
|
|
15465
15735
|
}
|
|
15466
15736
|
var useHandbookStore = create((set, get) => ({
|
|
@@ -15609,7 +15879,7 @@ Escrita:
|
|
|
15609
15879
|
E quando a coisa precisa ser FEITA em vez de lembrada, \xE9 tarefa e n\xE3o p\xE1gina \u2014 crie com createRecord na entidade Task.`
|
|
15610
15880
|
);
|
|
15611
15881
|
function HandbookAgentSurface() {
|
|
15612
|
-
const contribution =
|
|
15882
|
+
const contribution = React113.useMemo(
|
|
15613
15883
|
() => ({
|
|
15614
15884
|
id: "handbook",
|
|
15615
15885
|
pluginId: "handbook",
|
|
@@ -15720,18 +15990,18 @@ function NotebookPanel() {
|
|
|
15720
15990
|
const userId = useHandbookStore((s) => s.userId);
|
|
15721
15991
|
const write3 = useHandbookStore((s) => s.write);
|
|
15722
15992
|
const remove = useHandbookStore((s) => s.remove);
|
|
15723
|
-
const [filter, setFilter] =
|
|
15724
|
-
const [search, setSearch] =
|
|
15725
|
-
const [draft, setDraft] =
|
|
15726
|
-
const [preview, setPreview] =
|
|
15727
|
-
const [confirming, setConfirming] =
|
|
15728
|
-
const entries2 =
|
|
15993
|
+
const [filter, setFilter] = React113.useState("all");
|
|
15994
|
+
const [search, setSearch] = React113.useState("");
|
|
15995
|
+
const [draft, setDraft] = React113.useState(null);
|
|
15996
|
+
const [preview, setPreview] = React113.useState(false);
|
|
15997
|
+
const [confirming, setConfirming] = React113.useState(null);
|
|
15998
|
+
const entries2 = React113.useMemo(
|
|
15729
15999
|
() => (pages ?? []).map((p) => ({ page: p, entry: toEntry2(p) })),
|
|
15730
16000
|
[pages]
|
|
15731
16001
|
);
|
|
15732
|
-
const timer =
|
|
15733
|
-
const inFlight =
|
|
15734
|
-
const persist =
|
|
16002
|
+
const timer = React113.useRef(null);
|
|
16003
|
+
const inFlight = React113.useRef(false);
|
|
16004
|
+
const persist = React113.useCallback(async (d) => {
|
|
15735
16005
|
const title = titleFromBody(d.body);
|
|
15736
16006
|
if (!title && !d.body.trim()) return d.id;
|
|
15737
16007
|
const filed = d.folder !== null;
|
|
@@ -15753,7 +16023,7 @@ function NotebookPanel() {
|
|
|
15753
16023
|
});
|
|
15754
16024
|
return saved?.id ?? d.id;
|
|
15755
16025
|
}, [write3, userId]);
|
|
15756
|
-
const schedule =
|
|
16026
|
+
const schedule = React113.useCallback((next) => {
|
|
15757
16027
|
setDraft(next);
|
|
15758
16028
|
if (timer.current) clearTimeout(timer.current);
|
|
15759
16029
|
timer.current = setTimeout(() => {
|
|
@@ -15785,7 +16055,7 @@ function NotebookPanel() {
|
|
|
15785
16055
|
legacyId: null
|
|
15786
16056
|
});
|
|
15787
16057
|
};
|
|
15788
|
-
const folders =
|
|
16058
|
+
const folders = React113.useMemo(() => {
|
|
15789
16059
|
const set = /* @__PURE__ */ new Set();
|
|
15790
16060
|
for (const { page } of entries2) {
|
|
15791
16061
|
if (page.kind !== "doc" || !page.path) continue;
|
|
@@ -15822,7 +16092,7 @@ function NotebookPanel() {
|
|
|
15822
16092
|
(a, b) => a.page.pinned !== b.page.pinned ? a.page.pinned ? -1 : 1 : b.page.updatedAt.localeCompare(a.page.updatedAt)
|
|
15823
16093
|
);
|
|
15824
16094
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [
|
|
15825
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b border-border/40 px-3
|
|
16095
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-10 shrink-0 items-center gap-2 border-b border-border/40 px-3", children: [
|
|
15826
16096
|
/* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
|
|
15827
16097
|
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground/60" }),
|
|
15828
16098
|
/* @__PURE__ */ jsx(
|
|
@@ -16177,10 +16447,10 @@ ${body}`
|
|
|
16177
16447
|
}
|
|
16178
16448
|
function NoteTodosSection({ noteId, noteTitle }) {
|
|
16179
16449
|
const adapter = useNotesTasksBridge((s) => s.adapter);
|
|
16180
|
-
const [todos, setTodos] =
|
|
16181
|
-
const [draft, setDraft] =
|
|
16182
|
-
const [busy, setBusy] =
|
|
16183
|
-
|
|
16450
|
+
const [todos, setTodos] = React113.useState([]);
|
|
16451
|
+
const [draft, setDraft] = React113.useState("");
|
|
16452
|
+
const [busy, setBusy] = React113.useState(false);
|
|
16453
|
+
React113.useEffect(() => {
|
|
16184
16454
|
if (!adapter) return;
|
|
16185
16455
|
let alive = true;
|
|
16186
16456
|
adapter.listTodos(noteId).then((rows) => {
|
|
@@ -16310,7 +16580,7 @@ function NotebookRailPanel() {
|
|
|
16310
16580
|
const pages = useHandbookStore((s) => s.pages);
|
|
16311
16581
|
const count = pages?.length ?? 0;
|
|
16312
16582
|
useRightRailPanel(
|
|
16313
|
-
|
|
16583
|
+
React113.useMemo(
|
|
16314
16584
|
() => ({
|
|
16315
16585
|
id: "notes",
|
|
16316
16586
|
label: tl("Notes", "Notas"),
|
|
@@ -16329,10 +16599,10 @@ function HandbookProvider() {
|
|
|
16329
16599
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16330
16600
|
const load = useHandbookStore((s) => s.load);
|
|
16331
16601
|
const setUser = useHandbookStore((s) => s.setUser);
|
|
16332
|
-
|
|
16602
|
+
React113.useEffect(() => {
|
|
16333
16603
|
setUser(userId);
|
|
16334
16604
|
}, [userId, setUser]);
|
|
16335
|
-
|
|
16605
|
+
React113.useEffect(() => {
|
|
16336
16606
|
if (tenantId2) void load(tenantId2);
|
|
16337
16607
|
}, [tenantId2, load]);
|
|
16338
16608
|
useLocalNotesImport(tenantId2, userId);
|
|
@@ -16342,7 +16612,7 @@ function HandbookProvider() {
|
|
|
16342
16612
|
] });
|
|
16343
16613
|
}
|
|
16344
16614
|
function useLocalNotesImport(tenantId2, userId) {
|
|
16345
|
-
|
|
16615
|
+
React113.useEffect(() => {
|
|
16346
16616
|
if (!tenantId2 || !userId) return;
|
|
16347
16617
|
const source = `fayz.notes.${tenantId2}.${userId}`;
|
|
16348
16618
|
const flag = `fayz.notes.imported.${tenantId2}.${userId}`;
|
|
@@ -16390,7 +16660,7 @@ function useUnitBootstrap() {
|
|
|
16390
16660
|
const tenant = useTenantOptional();
|
|
16391
16661
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16392
16662
|
const orgId = tenant?.org?.id;
|
|
16393
|
-
|
|
16663
|
+
React113.useEffect(() => {
|
|
16394
16664
|
if (!orgId) return;
|
|
16395
16665
|
const { loadedFor, load, reset } = useUnitStore.getState();
|
|
16396
16666
|
if (loadedFor && loadedFor !== orgId) reset();
|
|
@@ -16429,19 +16699,19 @@ function UnitMembersTab({ item }) {
|
|
|
16429
16699
|
const orgMembers = useOrganizationStore((s) => s.members);
|
|
16430
16700
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
16431
16701
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
16432
|
-
const [rows, setRows] =
|
|
16433
|
-
const [activity, setActivity] =
|
|
16434
|
-
const [adding, setAdding] =
|
|
16435
|
-
const [busy, setBusy] =
|
|
16436
|
-
const reload =
|
|
16702
|
+
const [rows, setRows] = React113.useState(null);
|
|
16703
|
+
const [activity, setActivity] = React113.useState({});
|
|
16704
|
+
const [adding, setAdding] = React113.useState(false);
|
|
16705
|
+
const [busy, setBusy] = React113.useState(null);
|
|
16706
|
+
const reload = React113.useCallback(async () => {
|
|
16437
16707
|
if (!unitId) return;
|
|
16438
16708
|
setRows(await fetchUnitMembers(unitId));
|
|
16439
16709
|
}, [unitId]);
|
|
16440
16710
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
16441
|
-
|
|
16711
|
+
React113.useEffect(() => {
|
|
16442
16712
|
void reload();
|
|
16443
16713
|
}, [reload, version5]);
|
|
16444
|
-
|
|
16714
|
+
React113.useEffect(() => {
|
|
16445
16715
|
if (!orgId) return;
|
|
16446
16716
|
let alive = true;
|
|
16447
16717
|
void fetchMemberActivity(orgId).then((a) => {
|
|
@@ -16451,7 +16721,7 @@ function UnitMembersTab({ item }) {
|
|
|
16451
16721
|
alive = false;
|
|
16452
16722
|
};
|
|
16453
16723
|
}, [orgId]);
|
|
16454
|
-
const byUser =
|
|
16724
|
+
const byUser = React113.useMemo(() => {
|
|
16455
16725
|
const map = /* @__PURE__ */ new Map();
|
|
16456
16726
|
for (const m of orgMembers) {
|
|
16457
16727
|
map.set(m.userId, {
|
|
@@ -16463,7 +16733,7 @@ function UnitMembersTab({ item }) {
|
|
|
16463
16733
|
}
|
|
16464
16734
|
return map;
|
|
16465
16735
|
}, [orgMembers]);
|
|
16466
|
-
const available =
|
|
16736
|
+
const available = React113.useMemo(
|
|
16467
16737
|
() => orgMembers.filter((m) => !(rows ?? []).some((r) => r.userId === m.userId)),
|
|
16468
16738
|
[orgMembers, rows]
|
|
16469
16739
|
);
|
|
@@ -16669,15 +16939,15 @@ function MemberAccessBody({
|
|
|
16669
16939
|
const units = useUnitStore((s) => s.units);
|
|
16670
16940
|
const byId = useUnitStore((s) => s.byId);
|
|
16671
16941
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
16672
|
-
const [bindings, setBindings] =
|
|
16673
|
-
const [loading, setLoading] =
|
|
16674
|
-
const [adding, setAdding] =
|
|
16675
|
-
const branches =
|
|
16676
|
-
const unbound =
|
|
16942
|
+
const [bindings, setBindings] = React113.useState([]);
|
|
16943
|
+
const [loading, setLoading] = React113.useState(false);
|
|
16944
|
+
const [adding, setAdding] = React113.useState(false);
|
|
16945
|
+
const branches = React113.useMemo(() => units.filter((u) => u.isActive !== false), [units]);
|
|
16946
|
+
const unbound = React113.useMemo(
|
|
16677
16947
|
() => branches.filter((u) => !bindings.some((b) => b.locationId === u.id)),
|
|
16678
16948
|
[branches, bindings]
|
|
16679
16949
|
);
|
|
16680
|
-
const reload =
|
|
16950
|
+
const reload = React113.useCallback(async () => {
|
|
16681
16951
|
if (!userId) return;
|
|
16682
16952
|
setLoading(true);
|
|
16683
16953
|
try {
|
|
@@ -16687,7 +16957,7 @@ function MemberAccessBody({
|
|
|
16687
16957
|
}
|
|
16688
16958
|
}, [userId]);
|
|
16689
16959
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
16690
|
-
|
|
16960
|
+
React113.useEffect(() => {
|
|
16691
16961
|
void reload();
|
|
16692
16962
|
}, [reload, version5]);
|
|
16693
16963
|
async function add(unitId) {
|
|
@@ -17429,13 +17699,13 @@ function surveyTokenFromPath(pathname) {
|
|
|
17429
17699
|
return m ? decodeURIComponent(m[1]) : null;
|
|
17430
17700
|
}
|
|
17431
17701
|
function PublicSurveyPage({ token, appName }) {
|
|
17432
|
-
const [loaded2, setLoaded] =
|
|
17433
|
-
const [draft, setDraft] =
|
|
17434
|
-
const [name, setName] =
|
|
17435
|
-
const [sending, setSending] =
|
|
17436
|
-
const [sent, setSent] =
|
|
17437
|
-
const [failed, setFailed] =
|
|
17438
|
-
|
|
17702
|
+
const [loaded2, setLoaded] = React113__default.useState(null);
|
|
17703
|
+
const [draft, setDraft] = React113__default.useState({});
|
|
17704
|
+
const [name, setName] = React113__default.useState("");
|
|
17705
|
+
const [sending, setSending] = React113__default.useState(false);
|
|
17706
|
+
const [sent, setSent] = React113__default.useState(null);
|
|
17707
|
+
const [failed, setFailed] = React113__default.useState(null);
|
|
17708
|
+
React113__default.useEffect(() => {
|
|
17439
17709
|
let alive = true;
|
|
17440
17710
|
const client3 = getFayzSupabaseClientOptional();
|
|
17441
17711
|
if (!client3) {
|
|
@@ -17605,7 +17875,7 @@ function Closed({ status, message }) {
|
|
|
17605
17875
|
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: c.body })
|
|
17606
17876
|
] });
|
|
17607
17877
|
}
|
|
17608
|
-
var RouteErrorBoundary = class extends
|
|
17878
|
+
var RouteErrorBoundary = class extends React113.Component {
|
|
17609
17879
|
constructor() {
|
|
17610
17880
|
super(...arguments);
|
|
17611
17881
|
this.state = { crashed: false, report: null };
|
|
@@ -17647,7 +17917,7 @@ var RouteErrorBoundary = class extends React111.Component {
|
|
|
17647
17917
|
}
|
|
17648
17918
|
};
|
|
17649
17919
|
function RouteErrorScreen({ report, tr, onBack, onRetry, backLabel }) {
|
|
17650
|
-
const [copied, setCopied] =
|
|
17920
|
+
const [copied, setCopied] = React113.useState(false);
|
|
17651
17921
|
const copyDetails = () => {
|
|
17652
17922
|
if (!report || typeof navigator === "undefined" || !navigator.clipboard) return;
|
|
17653
17923
|
const details = [
|
|
@@ -17737,9 +18007,9 @@ function UnitSwitching({ unitName, isAll, onDone }) {
|
|
|
17737
18007
|
const v = t(key);
|
|
17738
18008
|
return !v || v === key ? fallback : v;
|
|
17739
18009
|
};
|
|
17740
|
-
const doneRef =
|
|
18010
|
+
const doneRef = React113.useRef(onDone);
|
|
17741
18011
|
doneRef.current = onDone;
|
|
17742
|
-
|
|
18012
|
+
React113.useEffect(() => {
|
|
17743
18013
|
const id = window.setTimeout(() => doneRef.current(), HOLD_MS);
|
|
17744
18014
|
return () => window.clearTimeout(id);
|
|
17745
18015
|
}, []);
|
|
@@ -17922,16 +18192,16 @@ function WorkspaceSetupFlow({
|
|
|
17922
18192
|
const user = useAuthStore((s) => s.user);
|
|
17923
18193
|
const { switchOrg } = useTenant();
|
|
17924
18194
|
const closeSetup = useWorkspaceSetupStore((s) => s.close);
|
|
17925
|
-
const uploadLogo =
|
|
18195
|
+
const uploadLogo = React113.useMemo(
|
|
17926
18196
|
() => user ? createLogoUploader(user.id) : void 0,
|
|
17927
18197
|
[user?.id]
|
|
17928
18198
|
);
|
|
17929
|
-
const country =
|
|
18199
|
+
const country = React113.useMemo(
|
|
17930
18200
|
() => currency === "BRL" || (locale ?? "").toLowerCase().startsWith("pt") ? "BR" : void 0,
|
|
17931
18201
|
[currency, locale]
|
|
17932
18202
|
);
|
|
17933
|
-
const stepsRef =
|
|
17934
|
-
const analyzeSite =
|
|
18203
|
+
const stepsRef = React113.useRef([]);
|
|
18204
|
+
const analyzeSite = React113.useMemo(
|
|
17935
18205
|
() => createSiteAnalyzer({
|
|
17936
18206
|
apiBaseUrl: resolveFayzApiBaseUrl(),
|
|
17937
18207
|
steps: () => stepsRef.current,
|
|
@@ -17939,7 +18209,7 @@ function WorkspaceSetupFlow({
|
|
|
17939
18209
|
}),
|
|
17940
18210
|
[locale]
|
|
17941
18211
|
);
|
|
17942
|
-
const steps =
|
|
18212
|
+
const steps = React113.useMemo(
|
|
17943
18213
|
() => buildWorkspaceSetupSteps({
|
|
17944
18214
|
verticalId,
|
|
17945
18215
|
uploadLogo,
|
|
@@ -17951,13 +18221,13 @@ function WorkspaceSetupFlow({
|
|
|
17951
18221
|
[verticalId, uploadLogo, media, country, analyzeSite]
|
|
17952
18222
|
);
|
|
17953
18223
|
stepsRef.current = steps;
|
|
17954
|
-
const initialValues2 =
|
|
18224
|
+
const initialValues2 = React113.useMemo(
|
|
17955
18225
|
// Seeding the contact email with the account's own is one field fewer to
|
|
17956
18226
|
// type, and it is right far more often than it is wrong.
|
|
17957
18227
|
() => user?.email ? { "workspace.email": user.email } : {},
|
|
17958
18228
|
[user?.email]
|
|
17959
18229
|
);
|
|
17960
|
-
const onSubmit =
|
|
18230
|
+
const onSubmit = React113.useCallback(
|
|
17961
18231
|
async (values) => {
|
|
17962
18232
|
if (!user) throw new Error(tl("You are signed out.", "Sua sess\xE3o terminou."));
|
|
17963
18233
|
const org = await submitWorkspaceSetup({
|
|
@@ -18074,16 +18344,16 @@ function GettingStartedWidget() {
|
|
|
18074
18344
|
const t = useTranslation();
|
|
18075
18345
|
const rows = useActivationStore((s) => s.rows);
|
|
18076
18346
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18077
|
-
const steps =
|
|
18347
|
+
const steps = React113.useMemo(
|
|
18078
18348
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18079
18349
|
[rows, catalog]
|
|
18080
18350
|
);
|
|
18081
|
-
const onNavigate =
|
|
18351
|
+
const onNavigate = React113.useCallback((path) => {
|
|
18082
18352
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18083
18353
|
navigateTo(path);
|
|
18084
18354
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18085
18355
|
}, []);
|
|
18086
|
-
const onAskAgent =
|
|
18356
|
+
const onAskAgent = React113.useCallback((step) => {
|
|
18087
18357
|
void startGuidedRun(step.id);
|
|
18088
18358
|
}, []);
|
|
18089
18359
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18094,7 +18364,9 @@ function GettingStartedWidget() {
|
|
|
18094
18364
|
steps,
|
|
18095
18365
|
onNavigate,
|
|
18096
18366
|
onAskAgent,
|
|
18097
|
-
askAgentLabel: tl("Set it up with the assistant", "Configurar com o assistente")
|
|
18367
|
+
askAgentLabel: tl("Set it up with the assistant", "Configurar com o assistente"),
|
|
18368
|
+
maxVisible: 5,
|
|
18369
|
+
seeAllLabel: tl("+{n} more later", "mais {n} depois")
|
|
18098
18370
|
}
|
|
18099
18371
|
);
|
|
18100
18372
|
}
|
|
@@ -18106,16 +18378,16 @@ function ActivationChecklistCard({
|
|
|
18106
18378
|
}) {
|
|
18107
18379
|
const rows = useActivationStore((s) => s.rows);
|
|
18108
18380
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18109
|
-
const steps =
|
|
18381
|
+
const steps = React113.useMemo(
|
|
18110
18382
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18111
18383
|
[rows, catalog]
|
|
18112
18384
|
);
|
|
18113
|
-
const onNavigate =
|
|
18385
|
+
const onNavigate = React113.useCallback((path) => {
|
|
18114
18386
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18115
18387
|
navigateTo(path);
|
|
18116
18388
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18117
18389
|
}, []);
|
|
18118
|
-
const onAskAgent =
|
|
18390
|
+
const onAskAgent = React113.useCallback((step) => {
|
|
18119
18391
|
void startGuidedRun(step.id);
|
|
18120
18392
|
}, []);
|
|
18121
18393
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18129,13 +18401,15 @@ function ActivationChecklistCard({
|
|
|
18129
18401
|
onAskAgent,
|
|
18130
18402
|
askAgentLabel: tl("Set it up with the assistant", "Configurar com o assistente"),
|
|
18131
18403
|
hideWhenComplete,
|
|
18404
|
+
maxVisible: 5,
|
|
18405
|
+
seeAllLabel: tl("+{n} more after these", "mais {n} depois destes"),
|
|
18132
18406
|
className
|
|
18133
18407
|
}
|
|
18134
18408
|
);
|
|
18135
18409
|
}
|
|
18136
|
-
var WidgetSurfaceContext =
|
|
18410
|
+
var WidgetSurfaceContext = React113.createContext("rail");
|
|
18137
18411
|
function useWidgetSurface() {
|
|
18138
|
-
return
|
|
18412
|
+
return React113.useContext(WidgetSurfaceContext);
|
|
18139
18413
|
}
|
|
18140
18414
|
function WidgetSlot({
|
|
18141
18415
|
zone,
|
|
@@ -18179,7 +18453,7 @@ function useNavContribution(id, entries2) {
|
|
|
18179
18453
|
const setContribution = useNavContributionsStore((s) => s.setContribution);
|
|
18180
18454
|
const clearContribution = useNavContributionsStore((s) => s.clearContribution);
|
|
18181
18455
|
const key = JSON.stringify(entries2);
|
|
18182
|
-
|
|
18456
|
+
React113.useEffect(() => {
|
|
18183
18457
|
setContribution(id, entries2);
|
|
18184
18458
|
return () => clearContribution(id);
|
|
18185
18459
|
}, [id, key]);
|
|
@@ -18249,7 +18523,7 @@ function useAppDirectory() {
|
|
|
18249
18523
|
const tenantId2 = useActiveTenantId();
|
|
18250
18524
|
const apps = useAppDirectoryStore((s) => s.apps);
|
|
18251
18525
|
const load = useAppDirectoryStore((s) => s.load);
|
|
18252
|
-
|
|
18526
|
+
React113.useEffect(() => {
|
|
18253
18527
|
if (tenantId2) void load(tenantId2, resolveAppId());
|
|
18254
18528
|
}, [tenantId2, load]);
|
|
18255
18529
|
return { apps };
|
|
@@ -18341,7 +18615,7 @@ var CSS2 = `
|
|
|
18341
18615
|
}
|
|
18342
18616
|
`;
|
|
18343
18617
|
function useWordmarkStyle() {
|
|
18344
|
-
|
|
18618
|
+
React113.useEffect(() => {
|
|
18345
18619
|
if (typeof document === "undefined") return;
|
|
18346
18620
|
const existing = document.getElementById(STYLE_ID2);
|
|
18347
18621
|
if (existing) {
|
|
@@ -18575,7 +18849,7 @@ var SWAP_CSS = `
|
|
|
18575
18849
|
}
|
|
18576
18850
|
`;
|
|
18577
18851
|
function useSwapStyle() {
|
|
18578
|
-
|
|
18852
|
+
React113.useEffect(() => {
|
|
18579
18853
|
if (typeof document === "undefined" || document.getElementById(SWAP_STYLE_ID)) return;
|
|
18580
18854
|
const el = document.createElement("style");
|
|
18581
18855
|
el.id = SWAP_STYLE_ID;
|
|
@@ -18584,9 +18858,9 @@ function useSwapStyle() {
|
|
|
18584
18858
|
}, []);
|
|
18585
18859
|
}
|
|
18586
18860
|
function AppSwitcherView({ apps, mark, logo, collapsed = false, label: label2, onSelect }) {
|
|
18587
|
-
const [hovered, setHovered] =
|
|
18588
|
-
const [open, setOpen] =
|
|
18589
|
-
const [pending2, setPending] =
|
|
18861
|
+
const [hovered, setHovered] = React113.useState(false);
|
|
18862
|
+
const [open, setOpen] = React113.useState(false);
|
|
18863
|
+
const [pending2, setPending] = React113.useState(null);
|
|
18590
18864
|
const active2 = hovered || open;
|
|
18591
18865
|
useSwapStyle();
|
|
18592
18866
|
const brand = /* @__PURE__ */ jsx(BrandFace, { mark, logo, collapsed });
|
|
@@ -18721,7 +18995,7 @@ function useContextualNav(nav) {
|
|
|
18721
18995
|
const setNav = useContextualNavStore((s) => s.setNav);
|
|
18722
18996
|
const clearNav = useContextualNavStore((s) => s.clearNav);
|
|
18723
18997
|
const key = nav ? JSON.stringify(nav) : null;
|
|
18724
|
-
|
|
18998
|
+
React113.useEffect(() => {
|
|
18725
18999
|
if (!nav) return;
|
|
18726
19000
|
setNav(nav);
|
|
18727
19001
|
return () => clearNav(nav.base);
|
|
@@ -18878,10 +19152,10 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
18878
19152
|
const load = useFayzProjectsStore((s) => s.load);
|
|
18879
19153
|
const loadedFor = useFayzProjectsStore((s) => s.loadedFor);
|
|
18880
19154
|
const collapsed = useLayoutStore((s) => s.sidebarCollapsed);
|
|
18881
|
-
const [selectedId, setSelectedId] =
|
|
18882
|
-
const [hovered, setHovered] =
|
|
18883
|
-
const [primed, setPrimed] =
|
|
18884
|
-
const closeTimer =
|
|
19155
|
+
const [selectedId, setSelectedId] = React113.useState(null);
|
|
19156
|
+
const [hovered, setHovered] = React113.useState(false);
|
|
19157
|
+
const [primed, setPrimed] = React113.useState(false);
|
|
19158
|
+
const closeTimer = React113.useRef(null);
|
|
18885
19159
|
const cancelClose = () => {
|
|
18886
19160
|
if (closeTimer.current) {
|
|
18887
19161
|
clearTimeout(closeTimer.current);
|
|
@@ -18897,8 +19171,8 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
18897
19171
|
cancelClose();
|
|
18898
19172
|
closeTimer.current = setTimeout(() => setHovered(false), 140);
|
|
18899
19173
|
};
|
|
18900
|
-
|
|
18901
|
-
|
|
19174
|
+
React113.useEffect(() => () => cancelClose(), []);
|
|
19175
|
+
React113.useEffect(() => {
|
|
18902
19176
|
if (loadedFor !== (currentOrgId ?? null)) void load(currentOrgId);
|
|
18903
19177
|
}, [currentOrgId, loadedFor, load]);
|
|
18904
19178
|
const active2 = projects.find((p) => p.id === selectedId) ?? defaultProjectOf(projects) ?? synthFromFallback(fallback);
|
|
@@ -19009,10 +19283,10 @@ function SitePreview({
|
|
|
19009
19283
|
onEdit,
|
|
19010
19284
|
tr
|
|
19011
19285
|
}) {
|
|
19012
|
-
const [nonce, setNonce] =
|
|
19013
|
-
const [loading, setLoading] =
|
|
19286
|
+
const [nonce, setNonce] = React113.useState(0);
|
|
19287
|
+
const [loading, setLoading] = React113.useState(true);
|
|
19014
19288
|
const url = previewSourceOf(project);
|
|
19015
|
-
|
|
19289
|
+
React113.useEffect(() => {
|
|
19016
19290
|
setLoading(true);
|
|
19017
19291
|
}, [nonce, url]);
|
|
19018
19292
|
const action = "flex items-center gap-1.5 rounded-button px-2 py-1 text-[11.5px] font-medium text-sidebar-foreground/80 transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground disabled:cursor-not-allowed disabled:opacity-40";
|
|
@@ -19122,10 +19396,10 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
19122
19396
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
19123
19397
|
const setPageSlot = useRightRailStore((s) => s.setPageSlot);
|
|
19124
19398
|
const setWidth = useRightRailStore((s) => s.setWidth);
|
|
19125
|
-
const rootRef =
|
|
19126
|
-
const [actionsSlot, setActionsSlot] =
|
|
19127
|
-
const [leadingSlot, setLeadingSlot] =
|
|
19128
|
-
|
|
19399
|
+
const rootRef = React113.useRef(null);
|
|
19400
|
+
const [actionsSlot, setActionsSlot] = React113.useState(null);
|
|
19401
|
+
const [leadingSlot, setLeadingSlot] = React113.useState(null);
|
|
19402
|
+
React113.useEffect(() => {
|
|
19129
19403
|
if (!open) return;
|
|
19130
19404
|
const el = rootRef.current;
|
|
19131
19405
|
if (!el) return;
|
|
@@ -19147,8 +19421,8 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
19147
19421
|
el.removeEventListener("transitionend", publish);
|
|
19148
19422
|
};
|
|
19149
19423
|
}, [open, setWidth]);
|
|
19150
|
-
const [narrow, setNarrow] =
|
|
19151
|
-
|
|
19424
|
+
const [narrow, setNarrow] = React113.useState(false);
|
|
19425
|
+
React113.useEffect(() => {
|
|
19152
19426
|
if (!open) return;
|
|
19153
19427
|
const el = rootRef.current;
|
|
19154
19428
|
if (!el) return;
|
|
@@ -19189,6 +19463,7 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
19189
19463
|
ref: rootRef,
|
|
19190
19464
|
role: "complementary",
|
|
19191
19465
|
"aria-label": current2.label,
|
|
19466
|
+
"data-tour-exempt": true,
|
|
19192
19467
|
className: cn(
|
|
19193
19468
|
// The page's own surface, not `card`. The rail is a COLUMN of the app,
|
|
19194
19469
|
// not a white panel laid over it: painted card it came out a shade
|
|
@@ -19208,18 +19483,33 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
19208
19483
|
// radius utilities do not survive a responsive variant in this build —
|
|
19209
19484
|
// the class emits nothing and the card comes out square. Verified.
|
|
19210
19485
|
//
|
|
19211
|
-
//
|
|
19212
|
-
//
|
|
19213
|
-
//
|
|
19214
|
-
//
|
|
19486
|
+
// Emoldurado, é cartão. Encostado, arredonda em três cantos: o
|
|
19487
|
+
// esquerdo de CIMA acompanha o do conteúdo, que agora nasce logo abaixo
|
|
19488
|
+
// da faixa escura do cabeçalho, e o de BAIXO fica reto — é ali que ele
|
|
19489
|
+
// encosta na página, e um canto redondo no pé abriria uma fresta entre
|
|
19490
|
+
// as duas colunas justamente onde elas se tocam. Solto, arredonda nos
|
|
19491
|
+
// quatro.
|
|
19215
19492
|
//
|
|
19216
19493
|
// The seam is 2px where the card border is 1px: at `--border` (89%
|
|
19217
19494
|
// lightness) a hairline between two panes of the same surface is not a
|
|
19218
19495
|
// division anyone can see.
|
|
19219
|
-
frame ? attached ? "md:rounded-
|
|
19496
|
+
frame ? attached ? "md:rounded-xl md:rounded-bl-none md:border md:border-l-2 md:border-border" : "md:rounded-xl md:border md:border-border" : "md:border-l-2 md:border-border"
|
|
19220
19497
|
),
|
|
19221
19498
|
children: [
|
|
19222
|
-
/* @__PURE__ */ jsxs("div", { className:
|
|
19499
|
+
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
19500
|
+
"relative flex min-h-14 shrink-0 items-center gap-2 border-b border-border px-3",
|
|
19501
|
+
// Altura TRAVADA na moldura, não mínima, e 48 e não 56: o que tem de
|
|
19502
|
+
// bater é a LINHA DE BAIXO desta faixa com a da barra da shell, que é
|
|
19503
|
+
// onde o cartão do conteúdo começa. A barra da shell mede 56px a
|
|
19504
|
+
// partir do topo da janela; este cartão começa 8px abaixo dele (a folga
|
|
19505
|
+
// da moldura, `md:py-2` no aside), então 48 + 8 = 56. Com `min-h` — e
|
|
19506
|
+
// são duas subárvores diferentes — bastava um controle mais alto aqui
|
|
19507
|
+
// dentro para esta linha descer sozinha.
|
|
19508
|
+
// `md:min-h-0` junto: sem ele o `min-h-14` acima vence o `h-12` — uma
|
|
19509
|
+
// altura mínima de 56 ganha de uma altura fixa de 48 — e a faixa voltava
|
|
19510
|
+
// a medir 56, oito pixels abaixo da barra da shell.
|
|
19511
|
+
frame && "md:h-12 md:min-h-0"
|
|
19512
|
+
), children: [
|
|
19223
19513
|
/* @__PURE__ */ jsx(
|
|
19224
19514
|
"div",
|
|
19225
19515
|
{
|
|
@@ -19466,9 +19756,9 @@ var TYPE_COLORS = {
|
|
|
19466
19756
|
fix: "text-success"
|
|
19467
19757
|
};
|
|
19468
19758
|
function ChangelogFeed({ changelogUrl, className }) {
|
|
19469
|
-
const [entries2, setEntries] =
|
|
19470
|
-
const [loading, setLoading] =
|
|
19471
|
-
|
|
19759
|
+
const [entries2, setEntries] = React113.useState([]);
|
|
19760
|
+
const [loading, setLoading] = React113.useState(false);
|
|
19761
|
+
React113.useEffect(() => {
|
|
19472
19762
|
if (!changelogUrl) return;
|
|
19473
19763
|
setLoading(true);
|
|
19474
19764
|
fetch(changelogUrl).then((r) => r.json()).then((data) => setEntries(data)).catch(() => setEntries([])).finally(() => setLoading(false));
|
|
@@ -19531,7 +19821,7 @@ function NotificationInbox({
|
|
|
19531
19821
|
changelogUrl,
|
|
19532
19822
|
className
|
|
19533
19823
|
}) {
|
|
19534
|
-
const [activeTab, setActiveTab] =
|
|
19824
|
+
const [activeTab, setActiveTab] = React113.useState("inbox");
|
|
19535
19825
|
const unreadCount = notifications.filter((n) => !n.read).length;
|
|
19536
19826
|
const inboxNotifications = notifications.filter((n) => n.category !== "changelog");
|
|
19537
19827
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex w-80 flex-col", className), children: [
|
|
@@ -19628,11 +19918,11 @@ function NotificationInbox({
|
|
|
19628
19918
|
}
|
|
19629
19919
|
function BrandAgentSurface() {
|
|
19630
19920
|
const org = useOrganizationStore((s) => s.currentOrg);
|
|
19631
|
-
const brand =
|
|
19921
|
+
const brand = React113__default.useMemo(
|
|
19632
19922
|
() => normalizeBrand(org?.settings?.branding, { name: org?.name, logoUrl: org?.logoUrl }),
|
|
19633
19923
|
[org?.settings, org?.name, org?.logoUrl]
|
|
19634
19924
|
);
|
|
19635
|
-
const surface =
|
|
19925
|
+
const surface = React113__default.useMemo(() => ({
|
|
19636
19926
|
id: "core.brand",
|
|
19637
19927
|
describe: () => ({
|
|
19638
19928
|
title: "Marca da casa",
|
|
@@ -19645,15 +19935,15 @@ function BrandAgentSurface() {
|
|
|
19645
19935
|
return null;
|
|
19646
19936
|
}
|
|
19647
19937
|
function ConnectConsentPage({ appName, logo }) {
|
|
19648
|
-
const [state, setState] =
|
|
19649
|
-
const [tenantId2, setTenantId] =
|
|
19650
|
-
const request =
|
|
19938
|
+
const [state, setState] = React113__default.useState({ status: "loading" });
|
|
19939
|
+
const [tenantId2, setTenantId] = React113__default.useState("");
|
|
19940
|
+
const request = React113__default.useMemo(
|
|
19651
19941
|
() => new URLSearchParams(window.location.search).get("request") ?? "",
|
|
19652
19942
|
[]
|
|
19653
19943
|
);
|
|
19654
|
-
const connection =
|
|
19944
|
+
const connection = React113__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
19655
19945
|
const product = appName ?? document.title ?? "este app";
|
|
19656
|
-
const authorizedFetch =
|
|
19946
|
+
const authorizedFetch = React113__default.useCallback(
|
|
19657
19947
|
async (path, init) => {
|
|
19658
19948
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
19659
19949
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -19677,7 +19967,7 @@ function ConnectConsentPage({ appName, logo }) {
|
|
|
19677
19967
|
},
|
|
19678
19968
|
[connection]
|
|
19679
19969
|
);
|
|
19680
|
-
|
|
19970
|
+
React113__default.useEffect(() => {
|
|
19681
19971
|
let cancelled = false;
|
|
19682
19972
|
(async () => {
|
|
19683
19973
|
if (!request) {
|
|
@@ -19921,7 +20211,7 @@ function Row2({ label: label2, value }) {
|
|
|
19921
20211
|
function PageActions({ actions, className }) {
|
|
19922
20212
|
const access = useAccessOptional();
|
|
19923
20213
|
const openUpgrade = useUpgradeModalStore((s) => s.open);
|
|
19924
|
-
const resolved =
|
|
20214
|
+
const resolved = React113__default.useMemo(
|
|
19925
20215
|
() => actions.map((a) => {
|
|
19926
20216
|
const { permission, limitKey, onSelect, ...rest } = a;
|
|
19927
20217
|
let hidden = false;
|
|
@@ -19951,25 +20241,25 @@ function AddConnectorPanel({
|
|
|
19951
20241
|
onSelect
|
|
19952
20242
|
}) {
|
|
19953
20243
|
const { t } = useTranslation$1();
|
|
19954
|
-
const [query, setQuery] =
|
|
20244
|
+
const [query, setQuery] = React113__default.useState("");
|
|
19955
20245
|
const modules = useInstalledModuleIds();
|
|
19956
20246
|
const catalog = useConnectorCatalog();
|
|
19957
20247
|
const scoped = !!categories?.length;
|
|
19958
|
-
const addable =
|
|
20248
|
+
const addable = React113__default.useMemo(
|
|
19959
20249
|
() => inCategories(addableConnectors(connectors ?? []), categories),
|
|
19960
20250
|
[connectors, categories]
|
|
19961
20251
|
);
|
|
19962
|
-
const shelf =
|
|
20252
|
+
const shelf = React113__default.useMemo(() => {
|
|
19963
20253
|
if (connectors === null) return [];
|
|
19964
20254
|
return inCategories(
|
|
19965
20255
|
shelfIntegrations({ present: connectors, installedModules: modules, catalog: catalog ?? [] }),
|
|
19966
20256
|
categories
|
|
19967
20257
|
);
|
|
19968
20258
|
}, [connectors, modules, catalog, categories]);
|
|
19969
|
-
const filtered =
|
|
19970
|
-
const filteredShelf =
|
|
19971
|
-
const soon =
|
|
19972
|
-
const elsewhere =
|
|
20259
|
+
const filtered = React113__default.useMemo(() => filterConnectors(addable, "all", query), [addable, query]);
|
|
20260
|
+
const filteredShelf = React113__default.useMemo(() => filterAvailable(shelf, query), [shelf, query]);
|
|
20261
|
+
const soon = React113__default.useMemo(() => comingSoonHere(filteredShelf), [filteredShelf]);
|
|
20262
|
+
const elsewhere = React113__default.useMemo(() => withAnotherModule(filteredShelf), [filteredShelf]);
|
|
19973
20263
|
const searchable = addable.length + shelf.length > 6;
|
|
19974
20264
|
return /* @__PURE__ */ jsx(Modal, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ModalContent, { size: "2xl", children: [
|
|
19975
20265
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
@@ -20128,22 +20418,22 @@ function AddConnectorButton({ onClick }) {
|
|
|
20128
20418
|
function ConnectorsTab() {
|
|
20129
20419
|
const { t } = useTranslation$1();
|
|
20130
20420
|
const { connectors, error, reload, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
20131
|
-
const [adding, setAdding] =
|
|
20132
|
-
const [selected, setSelected] =
|
|
20133
|
-
const [filter, setFilter] =
|
|
20134
|
-
const [failure, setFailure] =
|
|
20135
|
-
const [revoking, setRevoking] =
|
|
20421
|
+
const [adding, setAdding] = React113__default.useState(false);
|
|
20422
|
+
const [selected, setSelected] = React113__default.useState(null);
|
|
20423
|
+
const [filter, setFilter] = React113__default.useState("all");
|
|
20424
|
+
const [failure, setFailure] = React113__default.useState(null);
|
|
20425
|
+
const [revoking, setRevoking] = React113__default.useState(null);
|
|
20136
20426
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
20137
|
-
const openJourney =
|
|
20427
|
+
const openJourney = React113__default.useCallback(
|
|
20138
20428
|
(connector) => {
|
|
20139
20429
|
if (assistantAvailable) openConnectorsPanel(connector);
|
|
20140
20430
|
else setSelected(connector);
|
|
20141
20431
|
},
|
|
20142
20432
|
[assistantAvailable]
|
|
20143
20433
|
);
|
|
20144
|
-
const visible =
|
|
20145
|
-
const groups =
|
|
20146
|
-
|
|
20434
|
+
const visible = React113__default.useMemo(() => filterConnectors(connectors ?? [], filter), [connectors, filter]);
|
|
20435
|
+
const groups = React113__default.useMemo(() => groupConnectors(visible), [visible]);
|
|
20436
|
+
React113__default.useEffect(() => {
|
|
20147
20437
|
if (!selected || !connectors) return;
|
|
20148
20438
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
20149
20439
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -20178,7 +20468,7 @@ function ConnectorsTab() {
|
|
|
20178
20468
|
(connectors?.length ?? 0) > 4 && /* @__PURE__ */ jsx(Filters, { value: filter, onChange: setFilter }),
|
|
20179
20469
|
connectors === null && /* @__PURE__ */ jsx(ConnectionsSkeleton, {}),
|
|
20180
20470
|
connectors !== null && visible.length === 0 && /* @__PURE__ */ jsx(Empty2, { title: t("connectors.emptyTitle"), body: t("connectors.emptyBody") }),
|
|
20181
|
-
visible.length > 0 && /* @__PURE__ */ jsx("ul", { className: "fayz-glass-surface divide-y divide-border overflow-hidden rounded-card border bg-card text-card-foreground shadow-sm", children: groups.map((group) => /* @__PURE__ */ jsxs(
|
|
20471
|
+
visible.length > 0 && /* @__PURE__ */ jsx("ul", { className: "fayz-glass-surface divide-y divide-border overflow-hidden rounded-card border bg-card text-card-foreground shadow-sm", children: groups.map((group) => /* @__PURE__ */ jsxs(React113__default.Fragment, { children: [
|
|
20182
20472
|
groups.length > 1 && /* @__PURE__ */ jsx(
|
|
20183
20473
|
"li",
|
|
20184
20474
|
{
|
|
@@ -20316,7 +20606,7 @@ function oauthFailureMessage(t, result) {
|
|
|
20316
20606
|
function useConnectorOAuthReturn() {
|
|
20317
20607
|
const { t } = useTranslation$1();
|
|
20318
20608
|
const runtime = usePluginRuntimeOptional();
|
|
20319
|
-
|
|
20609
|
+
React113__default.useEffect(() => {
|
|
20320
20610
|
if (typeof window === "undefined") return;
|
|
20321
20611
|
const result = readConnectorOAuthReturn(window.location.search);
|
|
20322
20612
|
if (!result) return;
|
|
@@ -20351,8 +20641,8 @@ function ConnectorDeliveries({
|
|
|
20351
20641
|
limit = 10
|
|
20352
20642
|
}) {
|
|
20353
20643
|
const { t } = useTranslation$1();
|
|
20354
|
-
const [rows, setRows] =
|
|
20355
|
-
|
|
20644
|
+
const [rows, setRows] = React113__default.useState(null);
|
|
20645
|
+
React113__default.useEffect(() => {
|
|
20356
20646
|
let cancelled = false;
|
|
20357
20647
|
void load({ limit }).then((r) => {
|
|
20358
20648
|
if (!cancelled) setRows(r);
|
|
@@ -20426,11 +20716,11 @@ var CURRENCIES = [
|
|
|
20426
20716
|
function CompanySettings({ tenant, onSave }) {
|
|
20427
20717
|
const { t } = useTranslation$1();
|
|
20428
20718
|
const { locale: uiLocale, setLocale: setUiLocale } = useLocaleStore();
|
|
20429
|
-
const [name, setName] =
|
|
20430
|
-
const [timezone, setTimezone] =
|
|
20431
|
-
const [currency, setCurrency] =
|
|
20432
|
-
const [saving, setSaving] =
|
|
20433
|
-
|
|
20719
|
+
const [name, setName] = React113.useState(tenant?.name ?? "");
|
|
20720
|
+
const [timezone, setTimezone] = React113.useState(tenant?.settings?.timezone ?? "UTC");
|
|
20721
|
+
const [currency, setCurrency] = React113.useState(tenant?.settings?.currency ?? "USD");
|
|
20722
|
+
const [saving, setSaving] = React113.useState(false);
|
|
20723
|
+
React113.useEffect(() => {
|
|
20434
20724
|
if (tenant) {
|
|
20435
20725
|
setName(tenant.name);
|
|
20436
20726
|
setTimezone(tenant.settings?.timezone ?? "UTC");
|
|
@@ -20522,15 +20812,15 @@ function UnitModeCard() {
|
|
|
20522
20812
|
const units = useUnitStore((s) => s.units);
|
|
20523
20813
|
const setMode = useUnitStore((s) => s.setMode);
|
|
20524
20814
|
const load = useUnitStore((s) => s.load);
|
|
20525
|
-
const [unbound, setUnbound] =
|
|
20526
|
-
const [bindEveryone, setBindEveryone] =
|
|
20527
|
-
const [pending2, setPending] =
|
|
20528
|
-
const [saving, setSaving] =
|
|
20529
|
-
const headquarters =
|
|
20815
|
+
const [unbound, setUnbound] = React113.useState(null);
|
|
20816
|
+
const [bindEveryone, setBindEveryone] = React113.useState(true);
|
|
20817
|
+
const [pending2, setPending] = React113.useState(null);
|
|
20818
|
+
const [saving, setSaving] = React113.useState(false);
|
|
20819
|
+
const headquarters = React113.useMemo(
|
|
20530
20820
|
() => units.find((u) => u.isHeadquarters && u.kind !== "region") ?? units.find((u) => u.kind !== "region"),
|
|
20531
20821
|
[units]
|
|
20532
20822
|
);
|
|
20533
|
-
|
|
20823
|
+
React113.useEffect(() => {
|
|
20534
20824
|
if (!org?.id || unitMode) return;
|
|
20535
20825
|
let alive = true;
|
|
20536
20826
|
void countUnboundMembers(org.id).then((n) => {
|
|
@@ -20694,10 +20984,10 @@ function getInitials(name) {
|
|
|
20694
20984
|
}
|
|
20695
20985
|
function UserProfile({ user, onSave, onAvatarChange }) {
|
|
20696
20986
|
const { t } = useTranslation$1();
|
|
20697
|
-
const [fullName, setFullName] =
|
|
20698
|
-
const [saving, setSaving] =
|
|
20699
|
-
const fileInputRef =
|
|
20700
|
-
|
|
20987
|
+
const [fullName, setFullName] = React113.useState(user?.fullName ?? "");
|
|
20988
|
+
const [saving, setSaving] = React113.useState(false);
|
|
20989
|
+
const fileInputRef = React113.useRef(null);
|
|
20990
|
+
React113.useEffect(() => {
|
|
20701
20991
|
if (user) {
|
|
20702
20992
|
setFullName(user.fullName);
|
|
20703
20993
|
}
|
|
@@ -20837,8 +21127,8 @@ async function fetchMyPersonId(tenantId2, userId) {
|
|
|
20837
21127
|
function useMyPersonId(enabled = true) {
|
|
20838
21128
|
const orgId = useOrganizationStore((s) => s.currentOrg?.id);
|
|
20839
21129
|
const userId = useAuthStore((s) => s.user?.id);
|
|
20840
|
-
const [personId, setPersonId] =
|
|
20841
|
-
|
|
21130
|
+
const [personId, setPersonId] = React113.useState(void 0);
|
|
21131
|
+
React113.useEffect(() => {
|
|
20842
21132
|
if (!enabled || !orgId || !userId) return;
|
|
20843
21133
|
let alive = true;
|
|
20844
21134
|
void dedup(`self:person:${orgId}:${userId}`, () => fetchMyPersonId(orgId, userId)).then((id) => {
|
|
@@ -20898,18 +21188,18 @@ function MyWorkspaceCard() {
|
|
|
20898
21188
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
20899
21189
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
20900
21190
|
const entryReason = useUnitStore((s) => s.entryReason);
|
|
20901
|
-
const [person, setPerson] =
|
|
20902
|
-
const [candidate, setCandidate] =
|
|
20903
|
-
const [linking, setLinking] =
|
|
21191
|
+
const [person, setPerson] = React113.useState(void 0);
|
|
21192
|
+
const [candidate, setCandidate] = React113.useState(null);
|
|
21193
|
+
const [linking, setLinking] = React113.useState(false);
|
|
20904
21194
|
const orgId = currentOrg?.id;
|
|
20905
21195
|
const userId = user?.id;
|
|
20906
|
-
const load =
|
|
21196
|
+
const load = React113.useCallback(async () => {
|
|
20907
21197
|
if (!orgId || !userId) return;
|
|
20908
21198
|
const linked = await fetchMyPersonRecord(orgId, userId);
|
|
20909
21199
|
setPerson(linked);
|
|
20910
21200
|
setCandidate(linked ? null : await findMyPersonCandidate(orgId, user?.email, staffKinds));
|
|
20911
21201
|
}, [orgId, userId, user?.email, staffKinds]);
|
|
20912
|
-
|
|
21202
|
+
React113.useEffect(() => {
|
|
20913
21203
|
void load();
|
|
20914
21204
|
}, [load]);
|
|
20915
21205
|
if (!currentOrg) return null;
|
|
@@ -21003,10 +21293,10 @@ var useStore = create((set) => ({
|
|
|
21003
21293
|
function useHeaderAction(zone, action) {
|
|
21004
21294
|
const register = useStore((s) => s.register);
|
|
21005
21295
|
const unregister = useStore((s) => s.unregister);
|
|
21006
|
-
const latest =
|
|
21296
|
+
const latest = React113.useRef(action);
|
|
21007
21297
|
latest.current = action;
|
|
21008
21298
|
const id = action?.id;
|
|
21009
|
-
|
|
21299
|
+
React113.useEffect(() => {
|
|
21010
21300
|
if (!zone || !id) return;
|
|
21011
21301
|
const current2 = latest.current;
|
|
21012
21302
|
if (current2) register(zone, { ...current2, onSelect: () => latest.current?.onSelect() });
|
|
@@ -21015,7 +21305,7 @@ function useHeaderAction(zone, action) {
|
|
|
21015
21305
|
}
|
|
21016
21306
|
function useHeaderActions(zone) {
|
|
21017
21307
|
const byZone = useStore((s) => s.byZone);
|
|
21018
|
-
return
|
|
21308
|
+
return React113.useMemo(() => Object.values(byZone[zone] ?? {}), [byZone, zone]);
|
|
21019
21309
|
}
|
|
21020
21310
|
function useUserLabel(userId) {
|
|
21021
21311
|
const members = useOrganizationStore((s) => s.members);
|
|
@@ -21056,7 +21346,7 @@ function formatStamp(value) {
|
|
|
21056
21346
|
if (!value) return null;
|
|
21057
21347
|
const date = new Date(String(value));
|
|
21058
21348
|
if (Number.isNaN(date.getTime())) return null;
|
|
21059
|
-
return date.toLocaleString(
|
|
21349
|
+
return date.toLocaleString(getCurrentLocale(), {
|
|
21060
21350
|
day: "2-digit",
|
|
21061
21351
|
month: "2-digit",
|
|
21062
21352
|
year: "numeric",
|
|
@@ -21745,7 +22035,7 @@ function SubjectFormLayout({ fields, allFields, fieldGroups, values, onChange, r
|
|
|
21745
22035
|
const IconComponent = getLucideIcon(entityIcon ?? "Heart") ?? Heart;
|
|
21746
22036
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
21747
22037
|
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: "pt-5", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-5", children: [
|
|
21748
|
-
/* @__PURE__ */ jsx("div", { className: "flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary", children:
|
|
22038
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: React113__default.createElement(IconComponent, { className: "h-8 w-8" }) }),
|
|
21749
22039
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-4", children: [
|
|
21750
22040
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-4", children: [
|
|
21751
22041
|
nameField && /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-1.5", children: [
|
|
@@ -22213,14 +22503,14 @@ function ImageSlot({
|
|
|
22213
22503
|
onDraftFile
|
|
22214
22504
|
}) {
|
|
22215
22505
|
const t = useTranslation();
|
|
22216
|
-
const inputRef =
|
|
22217
|
-
const [url, setUrl] =
|
|
22218
|
-
const [busy, setBusy] =
|
|
22219
|
-
const [error, setError] =
|
|
22220
|
-
const draftUrlRef =
|
|
22506
|
+
const inputRef = React113__default.useRef(null);
|
|
22507
|
+
const [url, setUrl] = React113__default.useState(() => image.get(row));
|
|
22508
|
+
const [busy, setBusy] = React113__default.useState(false);
|
|
22509
|
+
const [error, setError] = React113__default.useState(null);
|
|
22510
|
+
const draftUrlRef = React113__default.useRef(null);
|
|
22221
22511
|
const currentUrl = image.get(row);
|
|
22222
22512
|
const draftFile = image.draftField ? row[image.draftField] : void 0;
|
|
22223
|
-
|
|
22513
|
+
React113__default.useEffect(() => {
|
|
22224
22514
|
if (draftFile) return;
|
|
22225
22515
|
if (draftUrlRef.current) {
|
|
22226
22516
|
URL.revokeObjectURL(draftUrlRef.current);
|
|
@@ -22228,7 +22518,7 @@ function ImageSlot({
|
|
|
22228
22518
|
}
|
|
22229
22519
|
setUrl(currentUrl);
|
|
22230
22520
|
}, [currentUrl, draftFile]);
|
|
22231
|
-
|
|
22521
|
+
React113__default.useEffect(() => () => {
|
|
22232
22522
|
if (draftUrlRef.current) URL.revokeObjectURL(draftUrlRef.current);
|
|
22233
22523
|
}, []);
|
|
22234
22524
|
const acceptsDraft = !canEdit && Boolean(image.draftField && onDraftFile);
|
|
@@ -22346,7 +22636,7 @@ function CrudFormPage({ entityDef, mode, initialData, onSubmit, onCancel, namePl
|
|
|
22346
22636
|
const [values, setValues] = useState(computeInit);
|
|
22347
22637
|
const [saving, setSaving] = useState(false);
|
|
22348
22638
|
const [invalidKeys, setInvalidKeys] = useState(EMPTY_KEYS);
|
|
22349
|
-
const initialRef =
|
|
22639
|
+
const initialRef = React113__default.useRef(JSON.stringify(values));
|
|
22350
22640
|
useEffect(() => {
|
|
22351
22641
|
const init = computeInit();
|
|
22352
22642
|
setValues(init);
|
|
@@ -22391,7 +22681,7 @@ function CrudFormPage({ entityDef, mode, initialData, onSubmit, onCancel, namePl
|
|
|
22391
22681
|
if (submitRef) submitRef.current = () => {
|
|
22392
22682
|
void submit();
|
|
22393
22683
|
};
|
|
22394
|
-
|
|
22684
|
+
React113__default.useEffect(() => () => {
|
|
22395
22685
|
if (submitRef) submitRef.current = null;
|
|
22396
22686
|
}, [submitRef]);
|
|
22397
22687
|
const dirty = JSON.stringify(values) !== initialRef.current;
|
|
@@ -22991,7 +23281,7 @@ function CrudListView({
|
|
|
22991
23281
|
if (onImport) {
|
|
22992
23282
|
createRoutes.push({ id: "import", label: t("crud.import.action"), description: t("crud.import.hint"), icon: "Upload", action: onImport });
|
|
22993
23283
|
}
|
|
22994
|
-
const createActions =
|
|
23284
|
+
const createActions = React113__default.useMemo(() => {
|
|
22995
23285
|
const out = createRoutes.map((qa, i) => ({
|
|
22996
23286
|
id: qa.id,
|
|
22997
23287
|
label: qa.label,
|
|
@@ -23388,9 +23678,9 @@ function buildCrudSurfaceContribution(read3) {
|
|
|
23388
23678
|
};
|
|
23389
23679
|
}
|
|
23390
23680
|
function CrudAgentSurface(props) {
|
|
23391
|
-
const ref =
|
|
23681
|
+
const ref = React113.useRef(props);
|
|
23392
23682
|
ref.current = props;
|
|
23393
|
-
const contribution =
|
|
23683
|
+
const contribution = React113.useMemo(
|
|
23394
23684
|
() => buildCrudSurfaceContribution(() => ref.current),
|
|
23395
23685
|
[]
|
|
23396
23686
|
);
|
|
@@ -23441,7 +23731,7 @@ function useFieldRules(entityKey) {
|
|
|
23441
23731
|
};
|
|
23442
23732
|
}, [entityKey, fieldRules]);
|
|
23443
23733
|
}
|
|
23444
|
-
var ImportWizard2 =
|
|
23734
|
+
var ImportWizard2 = React113__default.lazy(
|
|
23445
23735
|
() => import('./ImportWizard-CISHGNQC.js').then((m) => ({ default: m.ImportWizard }))
|
|
23446
23736
|
);
|
|
23447
23737
|
var PAGE_SIZE = 50;
|
|
@@ -23926,7 +24216,7 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
23926
24216
|
displayValue: deleteItem ? deleteItem[displayField] : void 0
|
|
23927
24217
|
}
|
|
23928
24218
|
),
|
|
23929
|
-
/* @__PURE__ */ jsx(
|
|
24219
|
+
/* @__PURE__ */ jsx(React113__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
23930
24220
|
ImportWizard2,
|
|
23931
24221
|
{
|
|
23932
24222
|
open: importOpen,
|
|
@@ -24232,7 +24522,7 @@ function columnOf(entity, key) {
|
|
|
24232
24522
|
function RelatedListTab({ item, related }) {
|
|
24233
24523
|
const parentId = item?.id;
|
|
24234
24524
|
const pathname = useHashPath();
|
|
24235
|
-
const Page =
|
|
24525
|
+
const Page = React113.useMemo(() => {
|
|
24236
24526
|
if (!parentId) return null;
|
|
24237
24527
|
const child = related.entity;
|
|
24238
24528
|
const fkColumn = columnOf(child, related.foreignKey);
|
|
@@ -24259,8 +24549,8 @@ function tabBasePath(pathname, tabId) {
|
|
|
24259
24549
|
}
|
|
24260
24550
|
function useHashPath() {
|
|
24261
24551
|
const read3 = () => typeof window === "undefined" ? "/" : window.location.hash.slice(1) || "/";
|
|
24262
|
-
const [path, setPath] =
|
|
24263
|
-
|
|
24552
|
+
const [path, setPath] = React113.useState(read3);
|
|
24553
|
+
React113.useEffect(() => {
|
|
24264
24554
|
const handler = () => setPath(read3());
|
|
24265
24555
|
window.addEventListener("hashchange", handler);
|
|
24266
24556
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -24650,30 +24940,30 @@ function AccessTab({ item }) {
|
|
|
24650
24940
|
const hasSystemPermission = useSystemPermission();
|
|
24651
24941
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
24652
24942
|
const guardSeats = useLimitGuard("users");
|
|
24653
|
-
const [access, setAccess] =
|
|
24654
|
-
const [email, setEmail] =
|
|
24655
|
-
const [roleId, setRoleId] =
|
|
24656
|
-
const [busy, setBusy] =
|
|
24657
|
-
const [confirmRemove, setConfirmRemove] =
|
|
24658
|
-
|
|
24943
|
+
const [access, setAccess] = React113.useState(void 0);
|
|
24944
|
+
const [email, setEmail] = React113.useState(person?.email ?? "");
|
|
24945
|
+
const [roleId, setRoleId] = React113.useState("");
|
|
24946
|
+
const [busy, setBusy] = React113.useState(false);
|
|
24947
|
+
const [confirmRemove, setConfirmRemove] = React113.useState(false);
|
|
24948
|
+
React113.useEffect(() => {
|
|
24659
24949
|
if (!roleId && profiles.length) setRoleId(profiles[1]?.id ?? profiles[0].id);
|
|
24660
24950
|
}, [profiles, roleId]);
|
|
24661
|
-
|
|
24951
|
+
React113.useEffect(() => {
|
|
24662
24952
|
setEmail(person?.email ?? "");
|
|
24663
24953
|
}, [person?.email]);
|
|
24664
|
-
const reload =
|
|
24954
|
+
const reload = React113.useCallback(async () => {
|
|
24665
24955
|
if (!personId) return;
|
|
24666
24956
|
setAccess(await fetchPersonAccess(personId));
|
|
24667
24957
|
}, [personId]);
|
|
24668
|
-
|
|
24958
|
+
React113.useEffect(() => {
|
|
24669
24959
|
void reload();
|
|
24670
24960
|
}, [reload]);
|
|
24671
|
-
|
|
24961
|
+
React113.useEffect(() => {
|
|
24672
24962
|
if (!adapter || !currentOrg || invites.length > 0) return;
|
|
24673
24963
|
adapter.listInvites(currentOrg.id).then(setInvites).catch(() => {
|
|
24674
24964
|
});
|
|
24675
24965
|
}, [adapter, currentOrg?.id]);
|
|
24676
|
-
const pendingInvite =
|
|
24966
|
+
const pendingInvite = React113.useMemo(() => {
|
|
24677
24967
|
const target = (person?.email ?? "").trim().toLowerCase();
|
|
24678
24968
|
if (!target) return void 0;
|
|
24679
24969
|
return invites.find((i) => i.status === "pending" && i.email.toLowerCase() === target);
|
|
@@ -24898,10 +25188,10 @@ async function setPersonBookable(personId, isBookable) {
|
|
|
24898
25188
|
}
|
|
24899
25189
|
function BookableToggle({ personId }) {
|
|
24900
25190
|
const t = useTranslation();
|
|
24901
|
-
const [value, setValue] =
|
|
24902
|
-
const [loading, setLoading] =
|
|
24903
|
-
const [saving, setSaving] =
|
|
24904
|
-
|
|
25191
|
+
const [value, setValue] = React113__default.useState(null);
|
|
25192
|
+
const [loading, setLoading] = React113__default.useState(true);
|
|
25193
|
+
const [saving, setSaving] = React113__default.useState(false);
|
|
25194
|
+
React113__default.useEffect(() => {
|
|
24905
25195
|
let cancelled = false;
|
|
24906
25196
|
setLoading(true);
|
|
24907
25197
|
getPersonBookable(personId).then((v) => {
|
|
@@ -24951,11 +25241,11 @@ function PersonUnitsTab({ item }) {
|
|
|
24951
25241
|
const units = useUnitStore((s) => s.units);
|
|
24952
25242
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
24953
25243
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
24954
|
-
const [userId, setUserId] =
|
|
24955
|
-
const [bindings, setBindings] =
|
|
24956
|
-
const [busy, setBusy] =
|
|
25244
|
+
const [userId, setUserId] = React113.useState(void 0);
|
|
25245
|
+
const [bindings, setBindings] = React113.useState({});
|
|
25246
|
+
const [busy, setBusy] = React113.useState(null);
|
|
24957
25247
|
const bindingsVersion = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
24958
|
-
|
|
25248
|
+
React113.useEffect(() => {
|
|
24959
25249
|
if (!personId) return;
|
|
24960
25250
|
let alive = true;
|
|
24961
25251
|
void fetchUserIdForPerson(personId).then((uid2) => {
|
|
@@ -24965,11 +25255,11 @@ function PersonUnitsTab({ item }) {
|
|
|
24965
25255
|
alive = false;
|
|
24966
25256
|
};
|
|
24967
25257
|
}, [personId]);
|
|
24968
|
-
const reload =
|
|
25258
|
+
const reload = React113.useCallback(async (uid2) => {
|
|
24969
25259
|
const rows = await fetchMemberUnits(uid2);
|
|
24970
25260
|
setBindings(Object.fromEntries(rows.map((r) => [r.locationId, r.role])));
|
|
24971
25261
|
}, []);
|
|
24972
|
-
|
|
25262
|
+
React113.useEffect(() => {
|
|
24973
25263
|
if (userId) void reload(userId);
|
|
24974
25264
|
}, [userId, reload, bindingsVersion]);
|
|
24975
25265
|
async function toggle(unitId, on) {
|
|
@@ -25064,7 +25354,7 @@ function PersonUnitsTab({ item }) {
|
|
|
25064
25354
|
] })
|
|
25065
25355
|
] }) });
|
|
25066
25356
|
}
|
|
25067
|
-
var ScheduleEditor =
|
|
25357
|
+
var ScheduleEditor = React113__default.lazy(
|
|
25068
25358
|
() => import('./ScheduleEditor-B7PLFGVM.js').then((m) => ({ default: m.ScheduleEditor }))
|
|
25069
25359
|
);
|
|
25070
25360
|
function ComingSoon({ icon: Icon, title, description }) {
|
|
@@ -25147,7 +25437,7 @@ function ScheduleTab({ item }) {
|
|
|
25147
25437
|
}
|
|
25148
25438
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
25149
25439
|
/* @__PURE__ */ jsx(BookableToggle, { personId: item.id }),
|
|
25150
|
-
/* @__PURE__ */ jsx(
|
|
25440
|
+
/* @__PURE__ */ jsx(React113__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(ScheduleEditor, { assigneeId: item.id }) })
|
|
25151
25441
|
] });
|
|
25152
25442
|
}
|
|
25153
25443
|
var PERSON_DETAIL_TABS = [
|
|
@@ -25528,7 +25818,7 @@ function InlineEditor({
|
|
|
25528
25818
|
}) {
|
|
25529
25819
|
const [draft, setDraft] = useState(value ?? "");
|
|
25530
25820
|
const [saving, setSaving] = useState(false);
|
|
25531
|
-
const inputRef =
|
|
25821
|
+
const inputRef = React113__default.useRef(null);
|
|
25532
25822
|
useEffect(() => {
|
|
25533
25823
|
inputRef.current?.focus();
|
|
25534
25824
|
if (inputRef.current instanceof HTMLInputElement) inputRef.current.select();
|
|
@@ -25805,7 +26095,7 @@ function CrudDetailPage({
|
|
|
25805
26095
|
const displayFieldDef = entityDef.fields.find((f) => f.key === displayField);
|
|
25806
26096
|
const nameEditable = Boolean(onFieldSave) && Boolean(displayFieldDef) && isInlineEditable(displayFieldDef);
|
|
25807
26097
|
const [editingName, setEditingName] = useState(false);
|
|
25808
|
-
const imageInputRef =
|
|
26098
|
+
const imageInputRef = React113__default.useRef(null);
|
|
25809
26099
|
const runtime = usePluginRuntimeOptional();
|
|
25810
26100
|
const archetypeTabs = getArchetypeTabs(entityDef.layout, entityDef.data?.archetypeKind);
|
|
25811
26101
|
const relatedTabs = (entityDef.relatedLists ?? []).map((related) => ({
|
|
@@ -25860,7 +26150,7 @@ function CrudDetailPage({
|
|
|
25860
26150
|
const base = `${basePath}/${item.id}/${selectedTab}`;
|
|
25861
26151
|
window.history.replaceState(null, "", `#${segments.length ? `${base}/${segments.join("/")}` : base}`);
|
|
25862
26152
|
}, [basePath, item.id, selectedTab, embedded]);
|
|
25863
|
-
const headerNode =
|
|
26153
|
+
const headerNode = React113__default.useMemo(
|
|
25864
26154
|
() => embedded ? null : /* @__PURE__ */ jsx(SubpageHeader, { title: displayValue, parentLabel: namePlural, onBack }),
|
|
25865
26155
|
[embedded, displayValue, namePlural, onBack]
|
|
25866
26156
|
);
|
|
@@ -25985,12 +26275,12 @@ function CrudDetailPage({
|
|
|
25985
26275
|
] }, tab.id);
|
|
25986
26276
|
})
|
|
25987
26277
|
] }),
|
|
25988
|
-
/* @__PURE__ */ jsx(TabsContent, { value: "overview", className: embedded ? "mt-2" : "mt-4", children: entityDef.overviewComponent ?
|
|
26278
|
+
/* @__PURE__ */ jsx(TabsContent, { value: "overview", className: embedded ? "mt-2" : "mt-4", children: entityDef.overviewComponent ? React113__default.createElement(entityDef.overviewComponent, { item, entityDef }) : /* @__PURE__ */ jsx(OverviewTab, { entityDef, item, compact: embedded, onFieldSave }) }),
|
|
25989
26279
|
customTabs.map((tab) => /* @__PURE__ */ jsx(TabsContent, { value: tab.id, className: "mt-4", children: tab.component ? (
|
|
25990
26280
|
// `tabPath` only to the tab the URL is actually addressing —
|
|
25991
26281
|
// handing it to every tab would have the documents tab trying to
|
|
25992
26282
|
// open a recording id when the user switches across.
|
|
25993
|
-
|
|
26283
|
+
React113__default.createElement(tab.component, {
|
|
25994
26284
|
item,
|
|
25995
26285
|
entityDef,
|
|
25996
26286
|
...tab.id === selectedTab ? { tabPath, setTabPath } : {},
|
|
@@ -26022,8 +26312,8 @@ function MyRecordPanel() {
|
|
|
26022
26312
|
const userId = useAuthStore((s) => s.user?.id);
|
|
26023
26313
|
const members = useOrganizationStore((s) => s.members);
|
|
26024
26314
|
const myRole = members.find((m) => m.userId === userId)?.profileName;
|
|
26025
|
-
const [state, setState] =
|
|
26026
|
-
const load =
|
|
26315
|
+
const [state, setState] = React113.useState({ status: "loading" });
|
|
26316
|
+
const load = React113.useCallback(async () => {
|
|
26027
26317
|
if (!orgId || !userId) return;
|
|
26028
26318
|
const person = await dedup(`self:record:${orgId}:${userId}`, () => fetchMyPersonRecord(orgId, userId));
|
|
26029
26319
|
if (!person) return setState({ status: "none" });
|
|
@@ -26040,10 +26330,10 @@ function MyRecordPanel() {
|
|
|
26040
26330
|
setState({ status: "none" });
|
|
26041
26331
|
}
|
|
26042
26332
|
}, [orgId, userId]);
|
|
26043
|
-
|
|
26333
|
+
React113.useEffect(() => {
|
|
26044
26334
|
void load();
|
|
26045
26335
|
}, [load]);
|
|
26046
|
-
const changePhoto =
|
|
26336
|
+
const changePhoto = React113.useCallback(async (file) => {
|
|
26047
26337
|
if (state.status !== "ready") return;
|
|
26048
26338
|
const supabase = getFayzSupabaseClientOptional();
|
|
26049
26339
|
if (!supabase) return;
|
|
@@ -26099,8 +26389,8 @@ function ConnectedUserProfile() {
|
|
|
26099
26389
|
const myPersonId = useMyPersonId();
|
|
26100
26390
|
const hasRecord = Boolean(myPersonId);
|
|
26101
26391
|
const setUser = useAuthStore((s) => s.setUser);
|
|
26102
|
-
const [profile, setProfile] =
|
|
26103
|
-
|
|
26392
|
+
const [profile, setProfile] = React113.useState(null);
|
|
26393
|
+
React113.useEffect(() => {
|
|
26104
26394
|
const supabase = getFayzSupabaseClientOptional();
|
|
26105
26395
|
if (!user || !supabase) return;
|
|
26106
26396
|
let cancelled = false;
|
|
@@ -26211,9 +26501,9 @@ function SecuritySettings({
|
|
|
26211
26501
|
onTenantSecurityChange
|
|
26212
26502
|
}) {
|
|
26213
26503
|
const { t } = useTranslation$1();
|
|
26214
|
-
const [resetting, setResetting] =
|
|
26215
|
-
const [resetSent, setResetSent] =
|
|
26216
|
-
const [savingTenant, setSavingTenant] =
|
|
26504
|
+
const [resetting, setResetting] = React113.useState(false);
|
|
26505
|
+
const [resetSent, setResetSent] = React113.useState(false);
|
|
26506
|
+
const [savingTenant, setSavingTenant] = React113.useState(false);
|
|
26217
26507
|
const handleResetPassword = async () => {
|
|
26218
26508
|
if (!onResetPassword) return;
|
|
26219
26509
|
setResetting(true);
|
|
@@ -26387,8 +26677,8 @@ function FileUploadField({
|
|
|
26387
26677
|
hint
|
|
26388
26678
|
}) {
|
|
26389
26679
|
const { t } = useTranslation$1();
|
|
26390
|
-
const inputRef =
|
|
26391
|
-
const [preview, setPreview] =
|
|
26680
|
+
const inputRef = React113.useRef(null);
|
|
26681
|
+
const [preview, setPreview] = React113.useState(null);
|
|
26392
26682
|
const handleChange = (e) => {
|
|
26393
26683
|
const file = e.target.files?.[0];
|
|
26394
26684
|
if (file) {
|
|
@@ -26554,13 +26844,13 @@ function BrandPreview({ brand, t }) {
|
|
|
26554
26844
|
}
|
|
26555
26845
|
function BrandingSettings({ brand, onSave }) {
|
|
26556
26846
|
const { t } = useTranslation$1();
|
|
26557
|
-
const [section, setSection] =
|
|
26558
|
-
const [saved, setSaved] =
|
|
26559
|
-
const [draft, setDraft] =
|
|
26560
|
-
const [logoFile, setLogoFile] =
|
|
26561
|
-
const [faviconFile, setFaviconFile] =
|
|
26562
|
-
const [saving, setSaving] =
|
|
26563
|
-
|
|
26847
|
+
const [section, setSection] = React113.useState("identity");
|
|
26848
|
+
const [saved, setSaved] = React113.useState(brand ?? EMPTY_BRAND);
|
|
26849
|
+
const [draft, setDraft] = React113.useState(brand ?? EMPTY_BRAND);
|
|
26850
|
+
const [logoFile, setLogoFile] = React113.useState(null);
|
|
26851
|
+
const [faviconFile, setFaviconFile] = React113.useState(null);
|
|
26852
|
+
const [saving, setSaving] = React113.useState(false);
|
|
26853
|
+
React113.useEffect(() => {
|
|
26564
26854
|
if (brand) {
|
|
26565
26855
|
setSaved(brand);
|
|
26566
26856
|
setDraft(brand);
|
|
@@ -26844,11 +27134,11 @@ function ConnectedBrandingSettings() {
|
|
|
26844
27134
|
toast.error("N\xE3o foi poss\xEDvel salvar a marca", { description: err?.message });
|
|
26845
27135
|
}
|
|
26846
27136
|
};
|
|
26847
|
-
const [brand, setBrand] =
|
|
27137
|
+
const [brand, setBrand] = React113.useState(() => normalizeBrand(
|
|
26848
27138
|
(currentOrg?.settings ?? {}).branding,
|
|
26849
27139
|
{ name: currentOrg?.name, logoUrl: currentOrg?.logoUrl }
|
|
26850
27140
|
));
|
|
26851
|
-
|
|
27141
|
+
React113.useEffect(() => {
|
|
26852
27142
|
let alive = true;
|
|
26853
27143
|
void (async () => {
|
|
26854
27144
|
try {
|
|
@@ -26969,12 +27259,12 @@ function ProjectsSettings() {
|
|
|
26969
27259
|
const projects = useFayzProjectsStore((s) => s.projects);
|
|
26970
27260
|
const load = useFayzProjectsStore((s) => s.load);
|
|
26971
27261
|
const refresh = useFayzProjectsStore((s) => s.refresh);
|
|
26972
|
-
const [linking, setLinking] =
|
|
27262
|
+
const [linking, setLinking] = React113.useState(false);
|
|
26973
27263
|
const connected = isPlatformConnected();
|
|
26974
|
-
|
|
27264
|
+
React113.useEffect(() => {
|
|
26975
27265
|
void load(currentOrgId);
|
|
26976
27266
|
}, [currentOrgId, load]);
|
|
26977
|
-
|
|
27267
|
+
React113.useEffect(() => {
|
|
26978
27268
|
if (!connected || projects.length === 0) return;
|
|
26979
27269
|
let cancelled = false;
|
|
26980
27270
|
void (async () => {
|
|
@@ -27046,7 +27336,7 @@ function SiteRow({
|
|
|
27046
27336
|
showDefaultAction,
|
|
27047
27337
|
onChanged
|
|
27048
27338
|
}) {
|
|
27049
|
-
const [busy, setBusy] =
|
|
27339
|
+
const [busy, setBusy] = React113.useState(false);
|
|
27050
27340
|
const editorUrl = editorUrlOf(project);
|
|
27051
27341
|
const run = async (action) => {
|
|
27052
27342
|
setBusy(true);
|
|
@@ -27117,7 +27407,7 @@ function SiteRow({
|
|
|
27117
27407
|
] });
|
|
27118
27408
|
}
|
|
27119
27409
|
function LinkSiteModal({ onClose, onLinked }) {
|
|
27120
|
-
const [mode, setMode] =
|
|
27410
|
+
const [mode, setMode] = React113.useState("import");
|
|
27121
27411
|
return /* @__PURE__ */ jsx(Modal, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs(ModalContent, { size: "lg", children: [
|
|
27122
27412
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
27123
27413
|
/* @__PURE__ */ jsx(ModalTitle, { children: "Vincular um site" }),
|
|
@@ -27153,11 +27443,11 @@ function ModeTab({
|
|
|
27153
27443
|
}
|
|
27154
27444
|
function ImportPane({ onLinked }) {
|
|
27155
27445
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
27156
|
-
const [search, setSearch] =
|
|
27157
|
-
const [remote, setRemote] =
|
|
27158
|
-
const [error, setError] =
|
|
27159
|
-
const [linkingId, setLinkingId] =
|
|
27160
|
-
|
|
27446
|
+
const [search, setSearch] = React113.useState("");
|
|
27447
|
+
const [remote, setRemote] = React113.useState(null);
|
|
27448
|
+
const [error, setError] = React113.useState(null);
|
|
27449
|
+
const [linkingId, setLinkingId] = React113.useState(null);
|
|
27450
|
+
React113.useEffect(() => {
|
|
27161
27451
|
let cancelled = false;
|
|
27162
27452
|
setError(null);
|
|
27163
27453
|
const timer = setTimeout(() => {
|
|
@@ -27239,9 +27529,9 @@ function ImportPane({ onLinked }) {
|
|
|
27239
27529
|
}
|
|
27240
27530
|
function CreatePane({ onLinked, onCancel }) {
|
|
27241
27531
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
27242
|
-
const [prompt, setPrompt] =
|
|
27243
|
-
const [busy, setBusy] =
|
|
27244
|
-
const [error, setError] =
|
|
27532
|
+
const [prompt, setPrompt] = React113.useState("");
|
|
27533
|
+
const [busy, setBusy] = React113.useState(false);
|
|
27534
|
+
const [error, setError] = React113.useState(null);
|
|
27245
27535
|
const tooShort = prompt.trim().length < PROMPT_MIN_CHARS;
|
|
27246
27536
|
const submit = async () => {
|
|
27247
27537
|
setBusy(true);
|
|
@@ -27294,7 +27584,7 @@ function useCoreSettingsTabs({
|
|
|
27294
27584
|
showBranding = true
|
|
27295
27585
|
} = {}) {
|
|
27296
27586
|
const { t } = useTranslation$1();
|
|
27297
|
-
return
|
|
27587
|
+
return React113.useMemo(() => [
|
|
27298
27588
|
...showCompany ? [{ id: "general", label: t("settings.general"), icon: /* @__PURE__ */ jsx(Building2, { className: "h-4 w-4" }), iconName: "Building2", component: /* @__PURE__ */ jsx(ConnectedCompanySettings, {}) }] : [],
|
|
27299
27589
|
{ id: "profile", label: t("settings.profile"), icon: /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }), iconName: "User", component: /* @__PURE__ */ jsx(ConnectedUserProfile, {}) },
|
|
27300
27590
|
{ id: "security", label: t("settings.security"), icon: /* @__PURE__ */ jsx(Shield, { className: "h-4 w-4" }), iconName: "Shield", component: /* @__PURE__ */ jsx(ConnectedSecuritySettings, {}) },
|
|
@@ -27335,10 +27625,10 @@ function SettingsPage({
|
|
|
27335
27625
|
}
|
|
27336
27626
|
return null;
|
|
27337
27627
|
}
|
|
27338
|
-
const [activeTab, setActiveTab] =
|
|
27628
|
+
const [activeTab, setActiveTab] = React113.useState(() => {
|
|
27339
27629
|
return getTabFromHash() ?? defaultTab ?? null;
|
|
27340
27630
|
});
|
|
27341
|
-
|
|
27631
|
+
React113.useEffect(() => {
|
|
27342
27632
|
const handler = () => {
|
|
27343
27633
|
const tab = getTabFromHash();
|
|
27344
27634
|
if (tab) setActiveTab(tab);
|
|
@@ -27361,7 +27651,7 @@ function SettingsPage({
|
|
|
27361
27651
|
setActiveTab(null);
|
|
27362
27652
|
window.location.hash = "/settings";
|
|
27363
27653
|
};
|
|
27364
|
-
const sections =
|
|
27654
|
+
const sections = React113.useMemo(() => {
|
|
27365
27655
|
const out = [];
|
|
27366
27656
|
for (const tab of resolvedTabs) {
|
|
27367
27657
|
const heading = tab.isPlugin ? tab.group ?? t("common.plugins") : null;
|
|
@@ -27432,14 +27722,14 @@ function InviteMemberDialog({ open, onOpenChange, defaultEmail }) {
|
|
|
27432
27722
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
27433
27723
|
const setInvites = useInviteStore((s) => s.setInvites);
|
|
27434
27724
|
const { user } = useAuthStore();
|
|
27435
|
-
const [emails, setEmails] =
|
|
27436
|
-
const [profileId, setProfileId] =
|
|
27437
|
-
const [sending, setSending] =
|
|
27438
|
-
const [sent, setSent] =
|
|
27439
|
-
|
|
27725
|
+
const [emails, setEmails] = React113.useState([defaultEmail ?? ""]);
|
|
27726
|
+
const [profileId, setProfileId] = React113.useState(profiles[1]?.id ?? profiles[0]?.id ?? "");
|
|
27727
|
+
const [sending, setSending] = React113.useState(false);
|
|
27728
|
+
const [sent, setSent] = React113.useState(false);
|
|
27729
|
+
React113.useEffect(() => {
|
|
27440
27730
|
if (open) setEmails([defaultEmail ?? ""]);
|
|
27441
27731
|
}, [open, defaultEmail]);
|
|
27442
|
-
|
|
27732
|
+
React113.useEffect(() => {
|
|
27443
27733
|
if (!profileId && profiles.length) setProfileId(profiles[1]?.id ?? profiles[0].id);
|
|
27444
27734
|
}, [profiles, profileId]);
|
|
27445
27735
|
const addEmail = () => setEmails((prev) => [...prev, ""]);
|
|
@@ -27607,7 +27897,7 @@ function UnitSwitcher({ collapsed = false }) {
|
|
|
27607
27897
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
27608
27898
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
27609
27899
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
27610
|
-
const [query, setQuery] =
|
|
27900
|
+
const [query, setQuery] = React113.useState("");
|
|
27611
27901
|
const singular = label(t, "unit.singular", "unidade");
|
|
27612
27902
|
const plural = label(t, "unit.plural", "unidades");
|
|
27613
27903
|
if (!unitMode) return null;
|
|
@@ -27632,13 +27922,13 @@ function UnitSwitcher({ collapsed = false }) {
|
|
|
27632
27922
|
}
|
|
27633
27923
|
const renderNode = (node, depth) => {
|
|
27634
27924
|
if (node.kind === "region") {
|
|
27635
|
-
return /* @__PURE__ */ jsxs(
|
|
27925
|
+
return /* @__PURE__ */ jsxs(React113.Fragment, { children: [
|
|
27636
27926
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
27637
27927
|
node.children.map((child) => renderNode(child, depth + 1))
|
|
27638
27928
|
] }, node.id);
|
|
27639
27929
|
}
|
|
27640
27930
|
if (!reachable.includes(node.id)) return null;
|
|
27641
|
-
return /* @__PURE__ */ jsxs(
|
|
27931
|
+
return /* @__PURE__ */ jsxs(React113.Fragment, { children: [
|
|
27642
27932
|
/* @__PURE__ */ jsxs(
|
|
27643
27933
|
DropdownItem,
|
|
27644
27934
|
{
|
|
@@ -27720,8 +28010,8 @@ function UnitSwitcher({ collapsed = false }) {
|
|
|
27720
28010
|
var SEARCH_THRESHOLD = 7;
|
|
27721
28011
|
function UnitMenuSection() {
|
|
27722
28012
|
useUnitBootstrap();
|
|
27723
|
-
const [query, setQuery] =
|
|
27724
|
-
const [locating, setLocating] =
|
|
28013
|
+
const [query, setQuery] = React113.useState("");
|
|
28014
|
+
const [locating, setLocating] = React113.useState(false);
|
|
27725
28015
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
27726
28016
|
const units = useUnitStore((s) => s.units);
|
|
27727
28017
|
const tree = useUnitStore((s) => s.tree);
|
|
@@ -27741,13 +28031,13 @@ function UnitMenuSection() {
|
|
|
27741
28031
|
(c) => (c.kind === "region" || reachable.includes(c.id)) && (matches2(node) || matches2(c))
|
|
27742
28032
|
);
|
|
27743
28033
|
if (visibleChildren.length === 0) return null;
|
|
27744
|
-
return /* @__PURE__ */ jsxs(
|
|
28034
|
+
return /* @__PURE__ */ jsxs(React113.Fragment, { children: [
|
|
27745
28035
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
27746
28036
|
visibleChildren.map((child) => renderNode(child, depth + 1))
|
|
27747
28037
|
] }, node.id);
|
|
27748
28038
|
}
|
|
27749
28039
|
if (!reachable.includes(node.id) || !matches2(node)) return null;
|
|
27750
|
-
return /* @__PURE__ */ jsxs(
|
|
28040
|
+
return /* @__PURE__ */ jsxs(React113.Fragment, { children: [
|
|
27751
28041
|
/* @__PURE__ */ jsxs(
|
|
27752
28042
|
DropdownItem,
|
|
27753
28043
|
{
|
|
@@ -27925,9 +28215,9 @@ function MemberUnitsCell({
|
|
|
27925
28215
|
const byId = useUnitStore((s) => s.byId);
|
|
27926
28216
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
27927
28217
|
const openUnit = useUnitPanel((s) => s.openUnit);
|
|
27928
|
-
const [unitIds, setUnitIds] =
|
|
28218
|
+
const [unitIds, setUnitIds] = React113.useState(null);
|
|
27929
28219
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
27930
|
-
|
|
28220
|
+
React113.useEffect(() => {
|
|
27931
28221
|
if (!userId) {
|
|
27932
28222
|
setUnitIds([]);
|
|
27933
28223
|
return;
|
|
@@ -27985,10 +28275,10 @@ function TeamTab() {
|
|
|
27985
28275
|
const { user } = useAuthStore();
|
|
27986
28276
|
const hasSystemPermission = useSystemPermission();
|
|
27987
28277
|
const personMode = teamPersonKinds.length > 0 && typeof adapter?.listTeam === "function";
|
|
27988
|
-
const [team, setTeam] =
|
|
27989
|
-
const [inviteOpen, setInviteOpen] =
|
|
28278
|
+
const [team, setTeam] = React113.useState(null);
|
|
28279
|
+
const [inviteOpen, setInviteOpen] = React113.useState(false);
|
|
27990
28280
|
const guardSeats = useLimitGuard("users");
|
|
27991
|
-
const [inviteEmail, setInviteEmail] =
|
|
28281
|
+
const [inviteEmail, setInviteEmail] = React113.useState(void 0);
|
|
27992
28282
|
const handleOpenInvite = async (row) => {
|
|
27993
28283
|
if (row && !row.email && row.personId && entityRouteHasDetail("person", row.kind)) {
|
|
27994
28284
|
openEntity(row.personId, "person", row.kind, "access");
|
|
@@ -27998,7 +28288,7 @@ function TeamTab() {
|
|
|
27998
28288
|
setInviteEmail(row?.email || void 0);
|
|
27999
28289
|
setInviteOpen(true);
|
|
28000
28290
|
};
|
|
28001
|
-
const reloadTeam =
|
|
28291
|
+
const reloadTeam = React113.useCallback(async () => {
|
|
28002
28292
|
if (!adapter || !currentOrg) return;
|
|
28003
28293
|
if (personMode && adapter.listTeam) {
|
|
28004
28294
|
setTeam(await adapter.listTeam(currentOrg.id, teamPersonKinds));
|
|
@@ -28006,12 +28296,12 @@ function TeamTab() {
|
|
|
28006
28296
|
setMembers(await adapter.listMembers(currentOrg.id));
|
|
28007
28297
|
}
|
|
28008
28298
|
}, [adapter, currentOrg?.id, personMode, teamPersonKinds, setMembers]);
|
|
28009
|
-
|
|
28299
|
+
React113.useEffect(() => {
|
|
28010
28300
|
if (personMode && adapter?.listTeam && currentOrg) {
|
|
28011
28301
|
dedup("team:people:" + currentOrg.id, () => adapter.listTeam(currentOrg.id, teamPersonKinds)).then(setTeam).catch(() => setTeam([]));
|
|
28012
28302
|
}
|
|
28013
28303
|
}, [personMode, adapter, currentOrg?.id, teamPersonKinds.join(",")]);
|
|
28014
|
-
|
|
28304
|
+
React113.useEffect(() => {
|
|
28015
28305
|
if (adapter && currentOrg) {
|
|
28016
28306
|
dedup("team:invites:" + currentOrg.id, () => adapter.listInvites(currentOrg.id)).then(setInvites).catch(() => {
|
|
28017
28307
|
});
|
|
@@ -28092,7 +28382,7 @@ function TeamTab() {
|
|
|
28092
28382
|
};
|
|
28093
28383
|
const { t } = useTranslation$1();
|
|
28094
28384
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
28095
|
-
const inviteActions =
|
|
28385
|
+
const inviteActions = React113.useMemo(() => [{
|
|
28096
28386
|
id: "invite",
|
|
28097
28387
|
label: t("organization.team.invite"),
|
|
28098
28388
|
icon: UserPlus,
|
|
@@ -28279,13 +28569,13 @@ var SYSTEM_PERMISSIONS = [
|
|
|
28279
28569
|
];
|
|
28280
28570
|
function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, isNew, parentLabel }) {
|
|
28281
28571
|
const { t } = useTranslation$1();
|
|
28282
|
-
const [name, setName] =
|
|
28283
|
-
const [description, setDescription] =
|
|
28284
|
-
const [systemPerms, setSystemPerms] =
|
|
28285
|
-
const [grants, setGrants] =
|
|
28286
|
-
const [collapsed, setCollapsed] =
|
|
28287
|
-
const [search, setSearch] =
|
|
28288
|
-
const initial =
|
|
28572
|
+
const [name, setName] = React113.useState(profile?.name ?? "");
|
|
28573
|
+
const [description, setDescription] = React113.useState(profile?.description ?? "");
|
|
28574
|
+
const [systemPerms, setSystemPerms] = React113.useState(profile?.systemPermissions ?? []);
|
|
28575
|
+
const [grants, setGrants] = React113.useState(profile?.grants ?? {});
|
|
28576
|
+
const [collapsed, setCollapsed] = React113.useState(/* @__PURE__ */ new Set());
|
|
28577
|
+
const [search, setSearch] = React113.useState("");
|
|
28578
|
+
const initial = React113.useRef({
|
|
28289
28579
|
name: profile?.name ?? "",
|
|
28290
28580
|
description: profile?.description ?? "",
|
|
28291
28581
|
systemPerms: JSON.stringify(profile?.systemPermissions ?? []),
|
|
@@ -28322,7 +28612,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
28322
28612
|
onDiscard: onCancel,
|
|
28323
28613
|
saveLabel: isNew ? t("organization.permissions.createProfile") : t("organization.permissions.updateProfile")
|
|
28324
28614
|
});
|
|
28325
|
-
const groups =
|
|
28615
|
+
const groups = React113.useMemo(() => {
|
|
28326
28616
|
const filtered = search ? features.filter((f) => f.label.toLowerCase().includes(search.toLowerCase())) : features;
|
|
28327
28617
|
const map = /* @__PURE__ */ new Map();
|
|
28328
28618
|
for (const f of filtered) {
|
|
@@ -28391,7 +28681,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
28391
28681
|
}
|
|
28392
28682
|
) }) })
|
|
28393
28683
|
] }, sp.id)),
|
|
28394
|
-
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(
|
|
28684
|
+
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(React113.Fragment, { children: [
|
|
28395
28685
|
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: 5, className: "p-2 px-3", children: /* @__PURE__ */ jsxs(
|
|
28396
28686
|
"button",
|
|
28397
28687
|
{
|
|
@@ -28463,12 +28753,12 @@ function PermissionProfilesTab() {
|
|
|
28463
28753
|
const startImpersonation = usePermissionsStore((s) => s.startImpersonation);
|
|
28464
28754
|
const canPreview = (realProfile?.systemPermissions ?? []).includes("manage_permissions") ?? false;
|
|
28465
28755
|
const { t } = useTranslation$1();
|
|
28466
|
-
const [editingProfile, setEditingProfile] =
|
|
28467
|
-
const [creating, setCreating] =
|
|
28468
|
-
const [duplicateSource, setDuplicateSource] =
|
|
28469
|
-
const [saving, setSaving] =
|
|
28470
|
-
const [error, setError] =
|
|
28471
|
-
const [deleting, setDeleting] =
|
|
28756
|
+
const [editingProfile, setEditingProfile] = React113.useState(null);
|
|
28757
|
+
const [creating, setCreating] = React113.useState(false);
|
|
28758
|
+
const [duplicateSource, setDuplicateSource] = React113.useState(null);
|
|
28759
|
+
const [saving, setSaving] = React113.useState(false);
|
|
28760
|
+
const [error, setError] = React113.useState(null);
|
|
28761
|
+
const [deleting, setDeleting] = React113.useState(null);
|
|
28472
28762
|
const handleDuplicate = (profile) => {
|
|
28473
28763
|
setEditingProfile(null);
|
|
28474
28764
|
setCreating(false);
|
|
@@ -28478,9 +28768,9 @@ function PermissionProfilesTab() {
|
|
|
28478
28768
|
isSystem: false
|
|
28479
28769
|
});
|
|
28480
28770
|
};
|
|
28481
|
-
const surfaceRef =
|
|
28771
|
+
const surfaceRef = React113.useRef({ features, profiles, adapter, currentOrg, setProfiles });
|
|
28482
28772
|
surfaceRef.current = { features, profiles, adapter, currentOrg, setProfiles };
|
|
28483
|
-
const agentSurface =
|
|
28773
|
+
const agentSurface = React113.useMemo(() => ({
|
|
28484
28774
|
id: "org.permissions",
|
|
28485
28775
|
instructions: PERMISSIONS_INSTRUCTIONS,
|
|
28486
28776
|
describe: () => {
|
|
@@ -28534,7 +28824,7 @@ function PermissionProfilesTab() {
|
|
|
28534
28824
|
}]
|
|
28535
28825
|
}), []);
|
|
28536
28826
|
useAgentSurface(agentSurface);
|
|
28537
|
-
const createActions =
|
|
28827
|
+
const createActions = React113.useMemo(() => [
|
|
28538
28828
|
{
|
|
28539
28829
|
id: "new",
|
|
28540
28830
|
label: t("organization.permissions.createProfile"),
|
|
@@ -28563,7 +28853,7 @@ function PermissionProfilesTab() {
|
|
|
28563
28853
|
})
|
|
28564
28854
|
}
|
|
28565
28855
|
], [t]);
|
|
28566
|
-
const memberCountByProfile =
|
|
28856
|
+
const memberCountByProfile = React113.useMemo(() => {
|
|
28567
28857
|
const counts = {};
|
|
28568
28858
|
for (const m of members) {
|
|
28569
28859
|
counts[m.profileId] = (counts[m.profileId] ?? 0) + 1;
|
|
@@ -28868,7 +29158,7 @@ function FieldRulesSettings({ entities, rules: initialRules, onSave }) {
|
|
|
28868
29158
|
const [saving, setSaving] = useState(false);
|
|
28869
29159
|
const [search, setSearch] = useState("");
|
|
28870
29160
|
const [showMore, setShowMore] = useState(false);
|
|
28871
|
-
|
|
29161
|
+
React113.useEffect(() => {
|
|
28872
29162
|
setDraft(initialRules);
|
|
28873
29163
|
}, [initialRules]);
|
|
28874
29164
|
const isDirty = useMemo(
|
|
@@ -29268,20 +29558,20 @@ function SoftLimitWidget() {
|
|
|
29268
29558
|
function LimitProbe({ limitKey }) {
|
|
29269
29559
|
const info = useLimit(limitKey);
|
|
29270
29560
|
const report = useSoftLimitStore((s) => s.report);
|
|
29271
|
-
|
|
29561
|
+
React113.useEffect(() => {
|
|
29272
29562
|
report(limitKey, info);
|
|
29273
29563
|
}, [limitKey, info, report]);
|
|
29274
29564
|
return null;
|
|
29275
29565
|
}
|
|
29276
29566
|
function SoftLimitProbes({ keys }) {
|
|
29277
|
-
const monitored =
|
|
29567
|
+
const monitored = React113.useMemo(() => Array.from(new Set(keys)), [keys]);
|
|
29278
29568
|
return /* @__PURE__ */ jsx(Fragment, { children: monitored.map((k) => /* @__PURE__ */ jsx(LimitProbe, { limitKey: k }, k)) });
|
|
29279
29569
|
}
|
|
29280
|
-
var CommandPalette =
|
|
29570
|
+
var CommandPalette = React113.lazy(
|
|
29281
29571
|
() => import('./CommandPalette-GQ6SPITD.js').then((m) => ({ default: m.CommandPalette }))
|
|
29282
29572
|
);
|
|
29283
|
-
var SubscriptionPage =
|
|
29284
|
-
() => import('./SubscriptionPage-
|
|
29573
|
+
var SubscriptionPage = React113.lazy(
|
|
29574
|
+
() => import('./SubscriptionPage-Y23PH6US.js').then((m) => ({ default: m.SubscriptionPage }))
|
|
29285
29575
|
);
|
|
29286
29576
|
function orgInitials(name) {
|
|
29287
29577
|
const words2 = name.trim().split(/\s+/).filter(Boolean);
|
|
@@ -29638,9 +29928,9 @@ function PluginHeaderControls() {
|
|
|
29638
29928
|
}
|
|
29639
29929
|
function AdminNotifications() {
|
|
29640
29930
|
const { notifications, unreadCount, fetchNotifications, markAsRead, markAllAsRead } = useNotifications();
|
|
29641
|
-
const [open, setOpen] =
|
|
29642
|
-
const fetchedRef =
|
|
29643
|
-
|
|
29931
|
+
const [open, setOpen] = React113.useState(false);
|
|
29932
|
+
const fetchedRef = React113.useRef(false);
|
|
29933
|
+
React113.useEffect(() => {
|
|
29644
29934
|
if (fetchedRef.current) return;
|
|
29645
29935
|
fetchedRef.current = true;
|
|
29646
29936
|
void fetchNotifications();
|
|
@@ -29775,7 +30065,7 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
29775
30065
|
// sidebar ICON_MAP, which made the settings rail fall back to Home.
|
|
29776
30066
|
icon: /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
|
|
29777
30067
|
iconName: "CreditCard",
|
|
29778
|
-
component: /* @__PURE__ */ jsx(
|
|
30068
|
+
component: /* @__PURE__ */ jsx(React113.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(SubscriptionPage, {}) })
|
|
29779
30069
|
});
|
|
29780
30070
|
}
|
|
29781
30071
|
if (showOrgSettings) {
|
|
@@ -29803,9 +30093,9 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
29803
30093
|
settingsTabs.push({
|
|
29804
30094
|
id: tab.id,
|
|
29805
30095
|
label: translated === labelKey ? tab.label : translated,
|
|
29806
|
-
icon:
|
|
30096
|
+
icon: React113.createElement(IconComp, { className: "h-4 w-4" }),
|
|
29807
30097
|
iconName,
|
|
29808
|
-
component:
|
|
30098
|
+
component: React113.createElement(tab.component),
|
|
29809
30099
|
// Flag plugin-contributed tabs so SettingsPage draws the core/plugins divider.
|
|
29810
30100
|
isPlugin: true,
|
|
29811
30101
|
group: tab.group
|
|
@@ -29813,13 +30103,13 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
29813
30103
|
}
|
|
29814
30104
|
return settingsTabs;
|
|
29815
30105
|
}
|
|
29816
|
-
function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages = [], showSettings = true, showOrgSettings = false, showBranding = true, hiddenSettingsTabs, settingsGroups, showOrgSwitcher = true, setup = "wizard", contentFrame = true, moduleNav, bottomNav, onBottomNavAction, mobileHeader, shellMounts = [], sidebarFooter, navChildConnector, site, locales }) {
|
|
30106
|
+
function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages = [], showSettings = true, showOrgSettings = false, showBranding = true, hiddenSettingsTabs, settingsGroups, showOrgSwitcher = true, setup = "wizard", contentFrame = true, moduleNav, bottomNav, onBottomNavAction, mobileHeader, shellMounts = [], sidebarFooter, navChildConnector, site, locales, trialDays }) {
|
|
29817
30107
|
const runtime = usePluginRuntime();
|
|
29818
30108
|
const t = useTranslation();
|
|
29819
30109
|
const can = usePermissionOptional();
|
|
29820
30110
|
const access = useAccessOptional();
|
|
29821
30111
|
const currentProfile = usePermissionsStore((s) => s.currentProfile);
|
|
29822
|
-
const hasSystem =
|
|
30112
|
+
const hasSystem = React113.useCallback(
|
|
29823
30113
|
(perm) => {
|
|
29824
30114
|
if (!currentProfile) return false;
|
|
29825
30115
|
if (currentProfile.id === "owner" || currentProfile.name?.toLowerCase() === "owner") return true;
|
|
@@ -29833,7 +30123,7 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
29833
30123
|
};
|
|
29834
30124
|
const path = useAdminPath();
|
|
29835
30125
|
const { user, signOut } = useAuth();
|
|
29836
|
-
|
|
30126
|
+
React113.useEffect(() => installGlobalErrorHandlers(), []);
|
|
29837
30127
|
const railOpen = useRightRailStore((s) => s.open);
|
|
29838
30128
|
const railHasPanels = useRightRailStore((s) => s.panels.length > 0);
|
|
29839
30129
|
const railActive = useRightRailStore((s) => s.active);
|
|
@@ -29841,15 +30131,15 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
29841
30131
|
const hasChatPanel = useRightRailStore((s) => s.panels.some((pn) => pn.id === "chat"));
|
|
29842
30132
|
const rightRail = railHasPanels ? /* @__PURE__ */ jsx(RightRail, { frame: contentFrame, attached: layout !== "topbar" }) : null;
|
|
29843
30133
|
const setRailMounted = useRightRailStore((s) => s.setMounted);
|
|
29844
|
-
|
|
30134
|
+
React113.useEffect(() => {
|
|
29845
30135
|
setRailMounted(true);
|
|
29846
30136
|
return () => setRailMounted(false);
|
|
29847
30137
|
}, [setRailMounted]);
|
|
29848
30138
|
useConnectorOAuthReturn();
|
|
29849
30139
|
const railWidthLive = useRightRailStore((s) => s.width);
|
|
29850
30140
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
29851
|
-
const railAutoCollapsedRef =
|
|
29852
|
-
|
|
30141
|
+
const railAutoCollapsedRef = React113.useRef(false);
|
|
30142
|
+
React113.useEffect(() => {
|
|
29853
30143
|
if (layout !== "sidebar") return;
|
|
29854
30144
|
const SIDEBAR_EXPANDED = 224;
|
|
29855
30145
|
const MIN_CONTENT = 620;
|
|
@@ -29871,22 +30161,22 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
29871
30161
|
window.addEventListener("resize", apply);
|
|
29872
30162
|
return () => window.removeEventListener("resize", apply);
|
|
29873
30163
|
}, [railOpen, railWidthLive, layout, setSidebarCollapsed]);
|
|
29874
|
-
const [railWidth] =
|
|
30164
|
+
const [railWidth] = React113.useState(() => readRightRailWidth());
|
|
29875
30165
|
const billingPlans = useBillingStore((s) => s.plans);
|
|
29876
30166
|
const hasBilling = billingPlans.length > 0;
|
|
29877
30167
|
const orgPlan = useTenantOptional()?.org?.plan;
|
|
29878
|
-
const planBadge =
|
|
30168
|
+
const planBadge = React113.useMemo(
|
|
29879
30169
|
() => hasBilling ? resolvePlanBadge(orgPlan, billingPlans) : null,
|
|
29880
30170
|
[hasBilling, orgPlan, billingPlans]
|
|
29881
30171
|
);
|
|
29882
|
-
const softLimitKeys =
|
|
30172
|
+
const softLimitKeys = React113.useMemo(() => {
|
|
29883
30173
|
const plan = billingPlans.find((p) => p.id === (orgPlan || "free"));
|
|
29884
30174
|
return Object.keys(getPlanEntitlements(plan)?.limits ?? {});
|
|
29885
30175
|
}, [billingPlans, orgPlan]);
|
|
29886
30176
|
const overshoots = useOvershoots();
|
|
29887
30177
|
const navContributions = useNavContributionsStore((s) => s.contributions);
|
|
29888
30178
|
const appConfigNav = useAppConfigStore((state) => state.config.nav);
|
|
29889
|
-
const navigation =
|
|
30179
|
+
const navigation = React113.useMemo(() => {
|
|
29890
30180
|
const contributed = Object.values(navContributions).flat();
|
|
29891
30181
|
const flat = [...runtime.navigation, ...contributed].map((entry) => ({ ...navEntryToItem(entry), position: entry.position, indexChild: entry.indexChild })).sort(compareNavigation);
|
|
29892
30182
|
const items = [];
|
|
@@ -29931,7 +30221,7 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
29931
30221
|
return { ...item, premium: dec.premium, children };
|
|
29932
30222
|
}).filter((item) => item !== null).sort(compareNavigation);
|
|
29933
30223
|
}, [runtime.navigation, navContributions, pages, access]);
|
|
29934
|
-
const composedNavigation =
|
|
30224
|
+
const composedNavigation = React113.useMemo(() => {
|
|
29935
30225
|
if (!appConfigNav.length) return navigation;
|
|
29936
30226
|
const keyed = navigation.map((item) => ({ ...item, key: item.route }));
|
|
29937
30227
|
return applyNavComposition(keyed, appConfigNav).map((item) => {
|
|
@@ -29945,13 +30235,13 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
29945
30235
|
};
|
|
29946
30236
|
});
|
|
29947
30237
|
}, [navigation, appConfigNav]);
|
|
29948
|
-
const resolvedBottomNav =
|
|
30238
|
+
const resolvedBottomNav = React113.useMemo(
|
|
29949
30239
|
() => deriveBottomNav(navigation, bottomNav, { assistant: hasChatPanel }),
|
|
29950
30240
|
[navigation, bottomNav, hasChatPanel]
|
|
29951
30241
|
);
|
|
29952
30242
|
const commandPaletteOpen = useLayoutStore((s) => s.commandPaletteOpen);
|
|
29953
30243
|
const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
|
|
29954
|
-
const commandItems =
|
|
30244
|
+
const commandItems = React113.useMemo(() => {
|
|
29955
30245
|
const navGroup = tr("layout.commandPalette.navigation", "Navigation");
|
|
29956
30246
|
const items = [];
|
|
29957
30247
|
for (const nav of navigation) {
|
|
@@ -29963,7 +30253,7 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
29963
30253
|
return items;
|
|
29964
30254
|
}, [navigation]);
|
|
29965
30255
|
const globalSearch = useGlobalSearch();
|
|
29966
|
-
const routes =
|
|
30256
|
+
const routes = React113.useMemo(() => {
|
|
29967
30257
|
const list = [];
|
|
29968
30258
|
const entityRouteMap = /* @__PURE__ */ new Map();
|
|
29969
30259
|
for (const r of runtime.routes) {
|
|
@@ -29986,14 +30276,14 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
29986
30276
|
setEntityRouteMap(entityRouteMap);
|
|
29987
30277
|
return list.sort((a, b) => routeScore(b.path) - routeScore(a.path));
|
|
29988
30278
|
}, [runtime.routes, pages, showSettings]);
|
|
29989
|
-
const match =
|
|
30279
|
+
const match = React113.useMemo(() => {
|
|
29990
30280
|
for (const r of routes) {
|
|
29991
30281
|
const params = matchRoute(r.path, path);
|
|
29992
30282
|
if (params) return { route: r, params };
|
|
29993
30283
|
}
|
|
29994
30284
|
return null;
|
|
29995
30285
|
}, [routes, path]);
|
|
29996
|
-
|
|
30286
|
+
React113.useEffect(() => {
|
|
29997
30287
|
if (!match && (path === "/" || path === "") && navigation.length > 0) {
|
|
29998
30288
|
navigateTo(navigation[0].route);
|
|
29999
30289
|
}
|
|
@@ -30001,11 +30291,11 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
30001
30291
|
const ActiveComponent = match?.route.Component;
|
|
30002
30292
|
const activeParams = match?.params ?? {};
|
|
30003
30293
|
const routeKey = (match?.route.path ?? path).replace(/\/\*$/, "");
|
|
30004
|
-
const settingsTabs =
|
|
30294
|
+
const settingsTabs = React113.useMemo(
|
|
30005
30295
|
() => buildSettingsTabs(runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling),
|
|
30006
30296
|
[runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling]
|
|
30007
30297
|
);
|
|
30008
|
-
const profileRoute =
|
|
30298
|
+
const profileRoute = React113.useMemo(() => {
|
|
30009
30299
|
const explicit = routes.find((r) => r.path === "/perfil" || r.path === "/profile");
|
|
30010
30300
|
if (explicit) return explicit.path;
|
|
30011
30301
|
return showSettings ? "/settings/profile" : null;
|
|
@@ -30013,7 +30303,7 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
30013
30303
|
const onProfile = profileRoute ? () => navigateTo(profileRoute) : void 0;
|
|
30014
30304
|
const onBilling = hasBilling && showSettings ? () => navigateTo("/settings/subscription") : void 0;
|
|
30015
30305
|
const coreSettingsTabs = useCoreSettingsTabs({ showCompany: showBranding, showBranding });
|
|
30016
|
-
const allSettingsTabs =
|
|
30306
|
+
const allSettingsTabs = React113.useMemo(
|
|
30017
30307
|
() => {
|
|
30018
30308
|
const hidden = new Set(hiddenSettingsTabs ?? []);
|
|
30019
30309
|
const visible = [...coreSettingsTabs, ...settingsTabs].filter((tab) => !hidden.has(tab.id));
|
|
@@ -30029,12 +30319,12 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
30029
30319
|
const moduleRail = !inSettings && layout === "sidebar" && contextualNav && (path === contextualNav.base || path.startsWith(contextualNav.base + "/")) ? contextualNav : null;
|
|
30030
30320
|
const settingsPathActive = showSettings && (path === "/settings" || path.startsWith("/settings/"));
|
|
30031
30321
|
const activeSettingsTab = settingsPathActive ? path === "/settings" ? null : path.slice("/settings/".length).split("/")[0] : void 0;
|
|
30032
|
-
const settingsTabDef =
|
|
30322
|
+
const settingsTabDef = React113.useMemo(() => {
|
|
30033
30323
|
if (!showSettings || !path.startsWith("/settings/")) return void 0;
|
|
30034
30324
|
const id = path.slice("/settings/".length).split("/")[0];
|
|
30035
30325
|
return allSettingsTabs.find((tab) => tab.id === id);
|
|
30036
30326
|
}, [showSettings, path, allSettingsTabs]);
|
|
30037
|
-
const settingsNavigation =
|
|
30327
|
+
const settingsNavigation = React113.useMemo(
|
|
30038
30328
|
() => allSettingsTabs.map((tab) => ({
|
|
30039
30329
|
id: `settings:${tab.id}`,
|
|
30040
30330
|
label: tab.label,
|
|
@@ -30052,10 +30342,10 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
30052
30342
|
const shellUser = user ? { fullName: user.fullName ?? user.email, email: user.email, avatarUrl: user.avatarUrl } : void 0;
|
|
30053
30343
|
const moduleVariant = moduleNav ?? (layout === "sidebar" ? "tabs" : "rail");
|
|
30054
30344
|
const setRailAvailable = useContextualNavStore((s) => s.setRailAvailable);
|
|
30055
|
-
|
|
30345
|
+
React113.useEffect(() => {
|
|
30056
30346
|
setRailAvailable(layout === "sidebar" && moduleVariant !== "rail");
|
|
30057
30347
|
}, [layout, moduleVariant, setRailAvailable]);
|
|
30058
|
-
const activePageTitle =
|
|
30348
|
+
const activePageTitle = React113.useMemo(() => {
|
|
30059
30349
|
if (settingsTabDef) return settingsTabDef.label;
|
|
30060
30350
|
if (path === "/settings" || path.startsWith("/settings/")) return tr("common.settings", "Settings");
|
|
30061
30351
|
if (match?.route.title) return match.route.title;
|
|
@@ -30064,9 +30354,12 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
30064
30354
|
const hit = candidates.find(
|
|
30065
30355
|
(n) => n.route === "/" ? path === "/" || path === "" : path === n.route || path.startsWith(n.route + "/") || path.startsWith(n.route)
|
|
30066
30356
|
);
|
|
30067
|
-
|
|
30068
|
-
|
|
30069
|
-
|
|
30357
|
+
if (hit) return hit.label;
|
|
30358
|
+
const hiddenHit = pages.filter((pg) => pg.nav === false && pg.label && pg.path).sort((a, b) => b.path.length - a.path.length).find((pg) => pg.path === path || path.startsWith(pg.path + "/"));
|
|
30359
|
+
if (hiddenHit?.label) return hiddenHit.label;
|
|
30360
|
+
return candidates.find((n) => n.route === "/")?.label ?? "";
|
|
30361
|
+
}, [navigation, pages, path, tr, match, settingsTabDef]);
|
|
30362
|
+
const parentBack = React113.useMemo(() => {
|
|
30070
30363
|
if (settingsTabDef) {
|
|
30071
30364
|
const first = allSettingsTabs[0]?.id;
|
|
30072
30365
|
return {
|
|
@@ -30096,6 +30389,30 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
30096
30389
|
]
|
|
30097
30390
|
}
|
|
30098
30391
|
);
|
|
30392
|
+
const [railQuery, setRailQuery] = React113.useState("");
|
|
30393
|
+
const railBase = moduleRail?.base ?? null;
|
|
30394
|
+
React113.useEffect(() => {
|
|
30395
|
+
setRailQuery("");
|
|
30396
|
+
}, [railBase]);
|
|
30397
|
+
const railSearch = (placeholder) => /* @__PURE__ */ jsxs("div", { className: "relative px-0.5 pt-1", children: [
|
|
30398
|
+
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-sidebar-foreground/40" }),
|
|
30399
|
+
/* @__PURE__ */ jsx(
|
|
30400
|
+
"input",
|
|
30401
|
+
{
|
|
30402
|
+
type: "search",
|
|
30403
|
+
value: railQuery,
|
|
30404
|
+
onChange: (e) => setRailQuery(e.target.value),
|
|
30405
|
+
placeholder,
|
|
30406
|
+
"aria-label": placeholder,
|
|
30407
|
+
className: "h-8 w-full rounded-button border border-sidebar-border/60 bg-sidebar-accent/30 pl-8 pr-2 text-[13px] text-sidebar-foreground outline-none transition-colors placeholder:text-sidebar-foreground/40 focus:border-sidebar-ring focus:bg-sidebar-accent/50"
|
|
30408
|
+
}
|
|
30409
|
+
)
|
|
30410
|
+
] });
|
|
30411
|
+
const filterRail = (entries2) => {
|
|
30412
|
+
const q = railQuery.trim().toLowerCase();
|
|
30413
|
+
if (!q) return entries2;
|
|
30414
|
+
return entries2.filter((e) => String(e.label ?? "").toLowerCase().includes(q));
|
|
30415
|
+
};
|
|
30099
30416
|
const contextualRail = inSettings ? {
|
|
30100
30417
|
key: "settings",
|
|
30101
30418
|
navigation: settingsNavigation,
|
|
@@ -30106,9 +30423,12 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
30106
30423
|
top: backLink(tr("settings.backToHome", "Back to home"), homeRoute)
|
|
30107
30424
|
} : moduleRail ? {
|
|
30108
30425
|
key: moduleRail.base,
|
|
30109
|
-
navigation: moduleRail.entries,
|
|
30426
|
+
navigation: filterRail(moduleRail.entries),
|
|
30110
30427
|
sectionLabels: { main: moduleRail.label },
|
|
30111
|
-
top:
|
|
30428
|
+
top: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
30429
|
+
backLink(moduleRail.backLabel ?? tr("settings.backToHome", "Back to home"), moduleRail.backTo ?? homeRoute),
|
|
30430
|
+
moduleRail.searchPlaceholder ? railSearch(moduleRail.searchPlaceholder) : null
|
|
30431
|
+
] })
|
|
30112
30432
|
} : null;
|
|
30113
30433
|
return /* @__PURE__ */ jsxs(ModuleLayoutProvider, { variant: moduleVariant, children: [
|
|
30114
30434
|
/* @__PURE__ */ jsxs(
|
|
@@ -30149,9 +30469,9 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
30149
30469
|
sidebarBeforeNav: contextualRail ? void 0 : /* @__PURE__ */ jsx(WidgetSlot, { zone: "shell.sidebar.before-nav" }),
|
|
30150
30470
|
sidebarFooterContent: contextualRail ? void 0 : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
30151
30471
|
/* @__PURE__ */ jsx(GettingStartedWidget, {}),
|
|
30152
|
-
/* @__PURE__ */ jsx(TrialWidget, {}),
|
|
30472
|
+
/* @__PURE__ */ jsx(TrialWidget, { totalDays: trialDays }),
|
|
30153
30473
|
/* @__PURE__ */ jsx(SoftLimitWidget, {}),
|
|
30154
|
-
overshoots.length === 0 && /* @__PURE__ */ jsx(
|
|
30474
|
+
overshoots.length === 0 && site !== false && /* @__PURE__ */ jsx(
|
|
30155
30475
|
SeuSiteWidget,
|
|
30156
30476
|
{
|
|
30157
30477
|
fallback: site,
|
|
@@ -30275,7 +30595,7 @@ function AdminShellInner({ appName, layout = "sidebar", logo, markLogo, pages =
|
|
|
30275
30595
|
]
|
|
30276
30596
|
}
|
|
30277
30597
|
),
|
|
30278
|
-
/* @__PURE__ */ jsx(
|
|
30598
|
+
/* @__PURE__ */ jsx(React113.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
30279
30599
|
CommandPalette,
|
|
30280
30600
|
{
|
|
30281
30601
|
commands: commandItems,
|
|
@@ -30471,7 +30791,7 @@ function buildI18nConfig(config) {
|
|
|
30471
30791
|
function BillingInitializer({ config }) {
|
|
30472
30792
|
const setPlans = useBillingStore((s) => s.setPlans);
|
|
30473
30793
|
const setCheckout = useBillingStore((s) => s.setCheckout);
|
|
30474
|
-
|
|
30794
|
+
React113.useEffect(() => {
|
|
30475
30795
|
if (config.billing?.plans) setPlans(config.billing.plans.map(normalizeBillingPlan));
|
|
30476
30796
|
setCheckout(config.billing?.onCheckout ?? null);
|
|
30477
30797
|
}, [config.billing, setPlans, setCheckout]);
|
|
@@ -30501,7 +30821,7 @@ function ThemeInitializer({ config }) {
|
|
|
30501
30821
|
const brandColor = useOrganizationStore(
|
|
30502
30822
|
(s) => normalizeBrand(s.currentOrg?.settings?.branding).tokens.color?.primary
|
|
30503
30823
|
);
|
|
30504
|
-
|
|
30824
|
+
React113.useEffect(() => {
|
|
30505
30825
|
const brand = brandColor ? hexToHslTriplet(brandColor) : null;
|
|
30506
30826
|
if (config.theme) {
|
|
30507
30827
|
const themed = brand ? { ...config.theme, brand } : config.theme;
|
|
@@ -30517,20 +30837,20 @@ function ThemeInitializer({ config }) {
|
|
|
30517
30837
|
return null;
|
|
30518
30838
|
}
|
|
30519
30839
|
function PersistentCacheInitializer() {
|
|
30520
|
-
|
|
30840
|
+
React113.useEffect(() => {
|
|
30521
30841
|
attachPersistentCache();
|
|
30522
30842
|
void getPersistentCache()?.hydrate();
|
|
30523
30843
|
}, []);
|
|
30524
30844
|
return null;
|
|
30525
30845
|
}
|
|
30526
30846
|
function FayzEventBridgeInitializer({ config }) {
|
|
30527
|
-
|
|
30847
|
+
React113.useEffect(() => startFayzEventBridge(config.chat?.agent), [config.chat?.agent]);
|
|
30528
30848
|
return null;
|
|
30529
30849
|
}
|
|
30530
30850
|
function TeamInitializer({ config }) {
|
|
30531
30851
|
const setTeamPersonKinds = useOrganizationStore((s) => s.setTeamPersonKinds);
|
|
30532
30852
|
const kinds = config.team?.personKinds;
|
|
30533
|
-
|
|
30853
|
+
React113.useEffect(() => {
|
|
30534
30854
|
setTeamPersonKinds(kinds ?? []);
|
|
30535
30855
|
}, [setTeamPersonKinds, kinds]);
|
|
30536
30856
|
return null;
|
|
@@ -30546,7 +30866,7 @@ function ChatRailPanel({ config }) {
|
|
|
30546
30866
|
const agent = config.chat?.agent;
|
|
30547
30867
|
const voice = config.chat?.voice;
|
|
30548
30868
|
const whatsapp = config.chat?.whatsapp;
|
|
30549
|
-
const Component2 =
|
|
30869
|
+
const Component2 = React113.useMemo(() => {
|
|
30550
30870
|
const Panel = () => /* @__PURE__ */ jsx(
|
|
30551
30871
|
ChatConversation,
|
|
30552
30872
|
{
|
|
@@ -30563,8 +30883,8 @@ function ChatRailPanel({ config }) {
|
|
|
30563
30883
|
const conversations = useChatStore((s) => s.conversations);
|
|
30564
30884
|
const setConversations = useChatStore((s) => s.setConversations);
|
|
30565
30885
|
const user = useAuthStore((s) => s.user);
|
|
30566
|
-
const connection =
|
|
30567
|
-
|
|
30886
|
+
const connection = React113.useMemo(() => resolveFayzAgentConnection(agent), [agent]);
|
|
30887
|
+
React113.useEffect(() => {
|
|
30568
30888
|
if (!connection) return;
|
|
30569
30889
|
getFayzAgentClient(connection).listConversations(user?.id).then(setConversations).catch(() => {
|
|
30570
30890
|
});
|
|
@@ -30573,14 +30893,14 @@ function ChatRailPanel({ config }) {
|
|
|
30573
30893
|
useAssistantInviteStore((s) => s.invite?.id === ASK_AI_HANDOFF_ID);
|
|
30574
30894
|
const activeAgent = useAgent();
|
|
30575
30895
|
const persona = activeAgent?.name ?? invitePersona;
|
|
30576
|
-
const icon =
|
|
30896
|
+
const icon = React113.useMemo(
|
|
30577
30897
|
() => activeAgent ? function AgentTabIcon() {
|
|
30578
30898
|
return /* @__PURE__ */ jsx(AgentAvatar, { name: activeAgent.name, avatar: activeAgent.avatar, size: "sm" });
|
|
30579
30899
|
} : Sparkles,
|
|
30580
30900
|
[activeAgent]
|
|
30581
30901
|
);
|
|
30582
30902
|
useRightRailPanel(
|
|
30583
|
-
|
|
30903
|
+
React113.useMemo(
|
|
30584
30904
|
() => ({
|
|
30585
30905
|
id: "chat",
|
|
30586
30906
|
label: persona ?? "Chat",
|
|
@@ -30594,17 +30914,17 @@ function ChatRailPanel({ config }) {
|
|
|
30594
30914
|
[Component2, conversations.length, persona, icon, activeAgent]
|
|
30595
30915
|
)
|
|
30596
30916
|
);
|
|
30597
|
-
|
|
30917
|
+
React113.useEffect(() => {
|
|
30598
30918
|
if (chatOpen) openPanel("chat");
|
|
30599
30919
|
}, [chatOpen, openPanel]);
|
|
30600
|
-
|
|
30920
|
+
React113.useEffect(() => {
|
|
30601
30921
|
if (!(railOpen && railActive === "chat")) setChatOpen(false);
|
|
30602
30922
|
}, [railOpen, railActive, setChatOpen]);
|
|
30603
30923
|
return null;
|
|
30604
30924
|
}
|
|
30605
30925
|
function AdminProviders({ config, children }) {
|
|
30606
30926
|
const currentOrg = useOrganizationStore((s) => s.currentOrg);
|
|
30607
|
-
const hasFayzAgent =
|
|
30927
|
+
const hasFayzAgent = React113.useMemo(
|
|
30608
30928
|
() => !!resolveFayzAgentConnection(config.chat?.agent),
|
|
30609
30929
|
[config.chat?.agent]
|
|
30610
30930
|
);
|
|
@@ -30613,7 +30933,7 @@ function AdminProviders({ config, children }) {
|
|
|
30613
30933
|
const surface = config.chat?.surface ?? "dock";
|
|
30614
30934
|
const onConsentScreen = typeof window !== "undefined" && window.location.pathname.replace(/\/+$/, "").endsWith("/connect");
|
|
30615
30935
|
const showFab = assistantEnabled && surface === "dock" && !onConsentScreen;
|
|
30616
|
-
const resolved =
|
|
30936
|
+
const resolved = React113.useMemo(() => {
|
|
30617
30937
|
if (config.supabaseUrl && config.supabaseAnonKey) {
|
|
30618
30938
|
createFayzSupabaseClient(config.supabaseUrl, config.supabaseAnonKey);
|
|
30619
30939
|
}
|
|
@@ -30629,7 +30949,7 @@ function AdminProviders({ config, children }) {
|
|
|
30629
30949
|
};
|
|
30630
30950
|
}, [config]);
|
|
30631
30951
|
const path = useAdminPath();
|
|
30632
|
-
const runtime =
|
|
30952
|
+
const runtime = React113.useMemo(
|
|
30633
30953
|
() => resolvePluginRuntime({
|
|
30634
30954
|
plugins: resolved.plugins,
|
|
30635
30955
|
context: {
|
|
@@ -30975,8 +31295,8 @@ function manifestToFayzConfig(manifest, surfaceName) {
|
|
|
30975
31295
|
};
|
|
30976
31296
|
}
|
|
30977
31297
|
function AdminScaffold({ manifest, surface }) {
|
|
30978
|
-
const config =
|
|
30979
|
-
const authShellProps =
|
|
31298
|
+
const config = React113.useMemo(() => manifestToFayzConfig(manifest, surface), [manifest, surface]);
|
|
31299
|
+
const authShellProps = React113.useMemo(() => getAuthShellProps(config.auth), [config.auth]);
|
|
30980
31300
|
return /* @__PURE__ */ jsx(AdminProviders, { config, children: /* @__PURE__ */ jsx(
|
|
30981
31301
|
AdminShell,
|
|
30982
31302
|
{
|
|
@@ -31373,12 +31693,12 @@ function CrudRecordModal({
|
|
|
31373
31693
|
essentialFirst,
|
|
31374
31694
|
notice
|
|
31375
31695
|
}) {
|
|
31376
|
-
const [record, setRecord] =
|
|
31377
|
-
const [loading, setLoading] =
|
|
31378
|
-
const [saving, setSaving] =
|
|
31379
|
-
const [error, setError] =
|
|
31380
|
-
const formId =
|
|
31381
|
-
|
|
31696
|
+
const [record, setRecord] = React113.useState(null);
|
|
31697
|
+
const [loading, setLoading] = React113.useState(false);
|
|
31698
|
+
const [saving, setSaving] = React113.useState(false);
|
|
31699
|
+
const [error, setError] = React113.useState(null);
|
|
31700
|
+
const formId = React113.useId();
|
|
31701
|
+
React113.useEffect(() => {
|
|
31382
31702
|
if (!open) return;
|
|
31383
31703
|
setError(null);
|
|
31384
31704
|
if (mode === "create" || !load) {
|
|
@@ -31454,9 +31774,9 @@ function LookupCreateInline({
|
|
|
31454
31774
|
className
|
|
31455
31775
|
}) {
|
|
31456
31776
|
const t = useTranslation();
|
|
31457
|
-
const [saving, setSaving] =
|
|
31458
|
-
const [error, setError] =
|
|
31459
|
-
const submitForm =
|
|
31777
|
+
const [saving, setSaving] = React113.useState(false);
|
|
31778
|
+
const [error, setError] = React113.useState(null);
|
|
31779
|
+
const submitForm = React113.useRef(null);
|
|
31460
31780
|
async function submit(data) {
|
|
31461
31781
|
setSaving(true);
|
|
31462
31782
|
setError(null);
|
|
@@ -31533,17 +31853,17 @@ function LookupCreateInline({
|
|
|
31533
31853
|
);
|
|
31534
31854
|
}
|
|
31535
31855
|
function useLookupCreate(lookup2, onCreated, options = {}) {
|
|
31536
|
-
const [draftName, setDraftName] =
|
|
31856
|
+
const [draftName, setDraftName] = React113.useState(null);
|
|
31537
31857
|
const can = usePermissionOptional();
|
|
31538
31858
|
const entityDef = lookup2?.entityDef;
|
|
31539
31859
|
const feature = entityDef?.permission?.feature;
|
|
31540
31860
|
const allowed = !feature || can(feature, "create");
|
|
31541
31861
|
const canCreate = !!lookup2?.create && allowed;
|
|
31542
|
-
const createByName =
|
|
31862
|
+
const createByName = React113.useCallback(async (name) => {
|
|
31543
31863
|
if (!lookup2?.create) return;
|
|
31544
31864
|
onCreated(await lookup2.create({ name }));
|
|
31545
31865
|
}, [lookup2, onCreated]);
|
|
31546
|
-
const onCreate =
|
|
31866
|
+
const onCreate = React113.useMemo(() => {
|
|
31547
31867
|
if (!canCreate) return void 0;
|
|
31548
31868
|
if (!entityDef) return (name) => {
|
|
31549
31869
|
void createByName(name);
|
|
@@ -31631,8 +31951,8 @@ function OrderFormItemRow({
|
|
|
31631
31951
|
const rawKindLabel = itemTypes.find((tp) => tp.value === itemKind)?.label ?? itemKind;
|
|
31632
31952
|
const kindLabel = !itemKind || itemKind === "other" ? null : rawKindLabel;
|
|
31633
31953
|
const hasAdjustments = (discount ?? 0) > 0 || (surcharge ?? 0) > 0;
|
|
31634
|
-
const [showAdjustments, setShowAdjustments] =
|
|
31635
|
-
const [openExtras, setOpenExtras] =
|
|
31954
|
+
const [showAdjustments, setShowAdjustments] = React113.useState(hasAdjustments);
|
|
31955
|
+
const [openExtras, setOpenExtras] = React113.useState(
|
|
31636
31956
|
() => (extraFieldGroups ?? []).filter((g) => g.filled).map((g) => g.id)
|
|
31637
31957
|
);
|
|
31638
31958
|
const lookup2 = entityLookups[itemKind];
|
|
@@ -31906,9 +32226,10 @@ function OrderFormItemsCard({
|
|
|
31906
32226
|
header,
|
|
31907
32227
|
emptyLabel = "Nenhum item adicionado",
|
|
31908
32228
|
emptyActionLabel = "Adicione o primeiro item",
|
|
31909
|
-
children
|
|
32229
|
+
children,
|
|
32230
|
+
"data-tour": dataTour
|
|
31910
32231
|
}) {
|
|
31911
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col overflow-hidden rounded-card border bg-card", children: [
|
|
32232
|
+
return /* @__PURE__ */ jsxs("div", { "data-tour": dataTour, className: "flex flex-col overflow-hidden rounded-card border bg-card", children: [
|
|
31912
32233
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b px-4 py-3", children: [
|
|
31913
32234
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: label2 }),
|
|
31914
32235
|
onAdd && /* @__PURE__ */ jsxs(
|
|
@@ -32275,7 +32596,7 @@ function OrderCreateScreen({
|
|
|
32275
32596
|
errorActions,
|
|
32276
32597
|
saveBar
|
|
32277
32598
|
}) {
|
|
32278
|
-
const subtotal =
|
|
32599
|
+
const subtotal = React113.useMemo(
|
|
32279
32600
|
() => lines.reduce((sum, line) => sum + line.unitPrice * line.quantity, 0),
|
|
32280
32601
|
[lines]
|
|
32281
32602
|
);
|
|
@@ -32426,7 +32747,7 @@ function mergeLines(current2, incoming) {
|
|
|
32426
32747
|
return merged;
|
|
32427
32748
|
}
|
|
32428
32749
|
function ItemPicker({ search, onPick }) {
|
|
32429
|
-
const [open, setOpen] =
|
|
32750
|
+
const [open, setOpen] = React113.useState(false);
|
|
32430
32751
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
32431
32752
|
/* @__PURE__ */ jsxs(
|
|
32432
32753
|
"button",
|
|
@@ -32485,8 +32806,8 @@ function KanbanBoard({
|
|
|
32485
32806
|
toolbarActions
|
|
32486
32807
|
}) {
|
|
32487
32808
|
const collapsible = !!onToggleColumn;
|
|
32488
|
-
const frameRef =
|
|
32489
|
-
const centerFocused =
|
|
32809
|
+
const frameRef = React113.useRef(null);
|
|
32810
|
+
const centerFocused = React113.useCallback((event) => {
|
|
32490
32811
|
const frame = frameRef.current;
|
|
32491
32812
|
const column = event.target?.closest("[data-kanban-column]");
|
|
32492
32813
|
if (!frame || !column || frame.scrollWidth <= frame.clientWidth) return;
|
|
@@ -32591,10 +32912,10 @@ function BoardFrame({
|
|
|
32591
32912
|
toolbarActions,
|
|
32592
32913
|
className = ""
|
|
32593
32914
|
}) {
|
|
32594
|
-
const [open, setOpen] =
|
|
32595
|
-
const inputRef =
|
|
32915
|
+
const [open, setOpen] = React113.useState(false);
|
|
32916
|
+
const inputRef = React113.useRef(null);
|
|
32596
32917
|
const expanded = open || !!search;
|
|
32597
|
-
|
|
32918
|
+
React113.useEffect(() => {
|
|
32598
32919
|
if (open) inputRef.current?.focus();
|
|
32599
32920
|
}, [open]);
|
|
32600
32921
|
function collapse() {
|
|
@@ -32673,14 +32994,14 @@ function OrderBoardView({
|
|
|
32673
32994
|
rowId,
|
|
32674
32995
|
selectedRowId
|
|
32675
32996
|
}) {
|
|
32676
|
-
const getId =
|
|
32997
|
+
const getId = React113.useCallback(
|
|
32677
32998
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
32678
32999
|
[rowId]
|
|
32679
33000
|
);
|
|
32680
|
-
const [lastClicked, setLastClicked] =
|
|
32681
|
-
const [advancing, setAdvancing] =
|
|
33001
|
+
const [lastClicked, setLastClicked] = React113.useState(null);
|
|
33002
|
+
const [advancing, setAdvancing] = React113.useState({});
|
|
32682
33003
|
const selected = selectedRowId !== void 0 ? selectedRowId : lastClicked;
|
|
32683
|
-
const grouped =
|
|
33004
|
+
const grouped = React113.useMemo(() => {
|
|
32684
33005
|
const map = /* @__PURE__ */ new Map();
|
|
32685
33006
|
for (const col of board.columns) map.set(col.id, []);
|
|
32686
33007
|
for (const row of rows) {
|
|
@@ -32804,24 +33125,24 @@ function OrderListView({
|
|
|
32804
33125
|
boards,
|
|
32805
33126
|
viewKey
|
|
32806
33127
|
}) {
|
|
32807
|
-
const [search, setSearch] =
|
|
32808
|
-
const [page, setPage] =
|
|
32809
|
-
const [rawSelection, setRawSelection] =
|
|
32810
|
-
const offered =
|
|
33128
|
+
const [search, setSearch] = React113.useState("");
|
|
33129
|
+
const [page, setPage] = React113.useState(1);
|
|
33130
|
+
const [rawSelection, setRawSelection] = React113.useState([]);
|
|
33131
|
+
const offered = React113.useMemo(
|
|
32811
33132
|
() => views && views.length > 0 ? views : ["list"],
|
|
32812
33133
|
[views]
|
|
32813
33134
|
);
|
|
32814
|
-
const customFor =
|
|
33135
|
+
const customFor = React113.useCallback(
|
|
32815
33136
|
(id) => boards?.[id]?.render ?? null,
|
|
32816
33137
|
[boards]
|
|
32817
33138
|
);
|
|
32818
|
-
const boardFor =
|
|
33139
|
+
const boardFor = React113.useCallback(
|
|
32819
33140
|
(id) => (id === "board" ? board : boards?.[id]?.config) ?? null,
|
|
32820
33141
|
[board, boards]
|
|
32821
33142
|
);
|
|
32822
33143
|
const canBoard = offered.length > 1 && offered.some((id) => id !== "list" && (!!boardFor(id) || !!customFor(id)));
|
|
32823
33144
|
const storageKey2 = viewKey ? `fayz.orderView.${viewKey}` : null;
|
|
32824
|
-
const [view, setView] =
|
|
33145
|
+
const [view, setView] = React113.useState(() => {
|
|
32825
33146
|
const fallback = offered.includes(defaultView) ? defaultView : offered[0];
|
|
32826
33147
|
if (!storageKey2) return fallback;
|
|
32827
33148
|
try {
|
|
@@ -32831,7 +33152,7 @@ function OrderListView({
|
|
|
32831
33152
|
return fallback;
|
|
32832
33153
|
}
|
|
32833
33154
|
});
|
|
32834
|
-
const viewTabs =
|
|
33155
|
+
const viewTabs = React113.useMemo(
|
|
32835
33156
|
() => offered.map((option) => ({
|
|
32836
33157
|
value: option,
|
|
32837
33158
|
label: option === "list" ? "Lista" : boards?.[option]?.label ?? "Quadro",
|
|
@@ -32839,7 +33160,7 @@ function OrderListView({
|
|
|
32839
33160
|
})),
|
|
32840
33161
|
[offered, boards]
|
|
32841
33162
|
);
|
|
32842
|
-
const chooseView =
|
|
33163
|
+
const chooseView = React113.useCallback((next) => {
|
|
32843
33164
|
setView(next);
|
|
32844
33165
|
if (!storageKey2) return;
|
|
32845
33166
|
try {
|
|
@@ -32857,7 +33178,7 @@ function OrderListView({
|
|
|
32857
33178
|
const activeBoard = view === "list" ? null : boardFor(view);
|
|
32858
33179
|
const activeCustom = view === "list" ? null : customFor(view);
|
|
32859
33180
|
const showingBoard = !!activeBoard || !!activeCustom;
|
|
32860
|
-
const cols =
|
|
33181
|
+
const cols = React113.useMemo(
|
|
32861
33182
|
() => columns.map((c) => ({
|
|
32862
33183
|
id: c.key,
|
|
32863
33184
|
header: () => /* @__PURE__ */ jsx("div", { className: c.align === "right" ? "text-right" : "", children: c.header }),
|
|
@@ -32865,25 +33186,25 @@ function OrderListView({
|
|
|
32865
33186
|
})),
|
|
32866
33187
|
[columns]
|
|
32867
33188
|
);
|
|
32868
|
-
const filtered =
|
|
33189
|
+
const filtered = React113.useMemo(() => {
|
|
32869
33190
|
const term = search.trim().toLowerCase();
|
|
32870
33191
|
if (!term || !searchText) return rows;
|
|
32871
33192
|
return rows.filter((row) => searchText(row).toLowerCase().includes(term));
|
|
32872
33193
|
}, [rows, search, searchText]);
|
|
32873
|
-
|
|
33194
|
+
React113.useEffect(() => {
|
|
32874
33195
|
setPage(1);
|
|
32875
33196
|
}, [search]);
|
|
32876
33197
|
const paged = pageSize > 0 ? filtered.slice((page - 1) * pageSize, page * pageSize) : filtered;
|
|
32877
|
-
const getId =
|
|
33198
|
+
const getId = React113.useCallback(
|
|
32878
33199
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
32879
33200
|
[rowId]
|
|
32880
33201
|
);
|
|
32881
|
-
const pageIds =
|
|
32882
|
-
const selectedIds =
|
|
33202
|
+
const pageIds = React113.useMemo(() => paged.map(getId), [paged, getId]);
|
|
33203
|
+
const selectedIds = React113.useMemo(
|
|
32883
33204
|
() => rawSelection.filter((id) => pageIds.includes(id)),
|
|
32884
33205
|
[rawSelection, pageIds]
|
|
32885
33206
|
);
|
|
32886
|
-
const selectedRows =
|
|
33207
|
+
const selectedRows = React113.useMemo(
|
|
32887
33208
|
() => paged.filter((row) => selectedIds.includes(getId(row))),
|
|
32888
33209
|
[paged, selectedIds, getId]
|
|
32889
33210
|
);
|
|
@@ -33033,13 +33354,13 @@ function PaymentStatusBadge({
|
|
|
33033
33354
|
receiveLabel = "Receber",
|
|
33034
33355
|
onOpenDetails
|
|
33035
33356
|
}) {
|
|
33036
|
-
const [open, setOpen] =
|
|
33037
|
-
const [lines, setLines] =
|
|
33038
|
-
const timer =
|
|
33039
|
-
|
|
33357
|
+
const [open, setOpen] = React113__default.useState(false);
|
|
33358
|
+
const [lines, setLines] = React113__default.useState(null);
|
|
33359
|
+
const timer = React113__default.useRef(null);
|
|
33360
|
+
React113__default.useEffect(() => {
|
|
33040
33361
|
setLines(null);
|
|
33041
33362
|
}, [status, paidAmount]);
|
|
33042
|
-
const load =
|
|
33363
|
+
const load = React113__default.useCallback(() => {
|
|
33043
33364
|
if (lines || !onLoadDetails) return;
|
|
33044
33365
|
void onLoadDetails().then(setLines).catch(() => setLines([]));
|
|
33045
33366
|
}, [lines, onLoadDetails]);
|
|
@@ -33174,13 +33495,13 @@ function invalidateOrdersPaymentStatus(orderId) {
|
|
|
33174
33495
|
else cache2.clear();
|
|
33175
33496
|
}
|
|
33176
33497
|
function useOrdersPaymentStatus(orderIds) {
|
|
33177
|
-
const key =
|
|
33498
|
+
const key = React113.useMemo(
|
|
33178
33499
|
() => Array.from(new Set(orderIds.filter(Boolean))).sort().join(","),
|
|
33179
33500
|
[orderIds]
|
|
33180
33501
|
);
|
|
33181
|
-
const [byOrder, setByOrder] =
|
|
33182
|
-
const [loading, setLoading] =
|
|
33183
|
-
const load =
|
|
33502
|
+
const [byOrder, setByOrder] = React113.useState(() => /* @__PURE__ */ new Map());
|
|
33503
|
+
const [loading, setLoading] = React113.useState(false);
|
|
33504
|
+
const load = React113.useCallback(async (force = false) => {
|
|
33184
33505
|
const ids = key ? key.split(",") : [];
|
|
33185
33506
|
if (ids.length === 0) {
|
|
33186
33507
|
setByOrder(/* @__PURE__ */ new Map());
|
|
@@ -33211,7 +33532,7 @@ function useOrdersPaymentStatus(orderIds) {
|
|
|
33211
33532
|
}
|
|
33212
33533
|
setByOrder(new Map(ids.map((id) => [id, cache2.get(id)]).filter(([, v]) => Boolean(v))));
|
|
33213
33534
|
}, [key]);
|
|
33214
|
-
|
|
33535
|
+
React113.useEffect(() => {
|
|
33215
33536
|
void load();
|
|
33216
33537
|
}, [load]);
|
|
33217
33538
|
return { byOrder, loading, reload: () => load(true) };
|
|
@@ -33278,12 +33599,12 @@ function money(value, currency) {
|
|
|
33278
33599
|
return value.toLocaleString("pt-BR", { style: "currency", currency: currency || "BRL" });
|
|
33279
33600
|
}
|
|
33280
33601
|
function useOrderDetail(orderId) {
|
|
33281
|
-
const [order, setOrder] =
|
|
33282
|
-
const [loading, setLoading] =
|
|
33283
|
-
const [error, setError] =
|
|
33284
|
-
const [nonce, setNonce] =
|
|
33285
|
-
const reload =
|
|
33286
|
-
|
|
33602
|
+
const [order, setOrder] = React113.useState(null);
|
|
33603
|
+
const [loading, setLoading] = React113.useState(false);
|
|
33604
|
+
const [error, setError] = React113.useState(null);
|
|
33605
|
+
const [nonce, setNonce] = React113.useState(0);
|
|
33606
|
+
const reload = React113.useCallback(() => setNonce((n) => n + 1), []);
|
|
33607
|
+
React113.useEffect(() => {
|
|
33287
33608
|
if (!orderId) {
|
|
33288
33609
|
setOrder(null);
|
|
33289
33610
|
setError(null);
|
|
@@ -33353,14 +33674,12 @@ var kindWord = (v) => v ? ORDER_KIND_LABELS[v] ?? v : void 0;
|
|
|
33353
33674
|
var channelWord = (v) => v ? ORDER_CHANNEL_LABELS[v] ?? v : void 0;
|
|
33354
33675
|
function OrderRailSkeleton() {
|
|
33355
33676
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-full flex-col", "aria-hidden": true, children: [
|
|
33356
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
33357
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-20 rounded-full" }),
|
|
33358
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-16 rounded-full" }),
|
|
33359
|
-
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-16 rounded-full" })
|
|
33360
|
-
] }),
|
|
33361
|
-
/* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
|
|
33677
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-10 items-center justify-between gap-3 px-4", children: [
|
|
33362
33678
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-40" }),
|
|
33363
|
-
/* @__PURE__ */
|
|
33679
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
33680
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-16 rounded-full" }),
|
|
33681
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-16 rounded-full" })
|
|
33682
|
+
] })
|
|
33364
33683
|
] }),
|
|
33365
33684
|
/* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
|
|
33366
33685
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-2.5 w-14" }),
|
|
@@ -33402,8 +33721,8 @@ function OrderDetailRail({
|
|
|
33402
33721
|
}) {
|
|
33403
33722
|
const { order, loading, error, reload } = useOrderDetail(orderId);
|
|
33404
33723
|
const { byOrder: paymentByOrder } = useOrdersPaymentStatus([orderId]);
|
|
33405
|
-
const [running, setRunning] =
|
|
33406
|
-
const [pending2, setPending] =
|
|
33724
|
+
const [running, setRunning] = React113.useState(null);
|
|
33725
|
+
const [pending2, setPending] = React113.useState(null);
|
|
33407
33726
|
const perform = async (action) => {
|
|
33408
33727
|
if (!order) return;
|
|
33409
33728
|
setRunning(action.id);
|
|
@@ -33437,14 +33756,13 @@ function OrderDetailRail({
|
|
|
33437
33756
|
loading && /* @__PURE__ */ jsx(OrderRailSkeleton, {}),
|
|
33438
33757
|
error && /* @__PURE__ */ jsx("p", { className: "px-4 py-3 text-sm text-destructive", children: error }),
|
|
33439
33758
|
order && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33440
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
33441
|
-
|
|
33442
|
-
|
|
33443
|
-
|
|
33444
|
-
|
|
33445
|
-
|
|
33446
|
-
|
|
33447
|
-
order.createdAt && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: new Date(order.createdAt).toLocaleString("pt-BR") })
|
|
33759
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-10 shrink-0 items-center justify-between gap-3 px-4", children: [
|
|
33760
|
+
/* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: order.partyName || "Consumidor n\xE3o identificado" }),
|
|
33761
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
33762
|
+
(statusLabel2?.(order) ?? statusWord(order.status)) && /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: statusLabel2?.(order) ?? statusWord(order.status) }),
|
|
33763
|
+
(kindLabel?.(order) ?? kindWord(order.kind)) && /* @__PURE__ */ jsx(Badge, { variant: "outline", children: kindLabel?.(order) ?? kindWord(order.kind) }),
|
|
33764
|
+
(channelLabel?.(order) ?? channelWord(order.channel)) && (channelLabel?.(order) ?? channelWord(order.channel)) !== (kindLabel?.(order) ?? kindWord(order.kind)) && /* @__PURE__ */ jsx(Badge, { variant: "outline", children: channelLabel?.(order) ?? channelWord(order.channel) })
|
|
33765
|
+
] })
|
|
33448
33766
|
] }),
|
|
33449
33767
|
/* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
|
|
33450
33768
|
/* @__PURE__ */ jsxs("p", { className: "pb-1.5 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/60", children: [
|
|
@@ -33496,6 +33814,10 @@ function OrderDetailRail({
|
|
|
33496
33814
|
}
|
|
33497
33815
|
),
|
|
33498
33816
|
verbs.filter((a) => a.variant === "destructive").map((action) => /* @__PURE__ */ jsx(RailAction, { action, running, onRun: run }, action.id))
|
|
33817
|
+
] }),
|
|
33818
|
+
order.createdAt && /* @__PURE__ */ jsxs("p", { className: "border-t border-border/40 px-4 py-1.5 text-[10px] text-muted-foreground/60", children: [
|
|
33819
|
+
"Criado em ",
|
|
33820
|
+
new Date(order.createdAt).toLocaleString("pt-BR")
|
|
33499
33821
|
] })
|
|
33500
33822
|
] })
|
|
33501
33823
|
] }),
|
|
@@ -33558,11 +33880,11 @@ function receivableTone(value) {
|
|
|
33558
33880
|
return "warning";
|
|
33559
33881
|
}
|
|
33560
33882
|
function useOrderReceivable(orderId) {
|
|
33561
|
-
const [receivable, setReceivable] =
|
|
33883
|
+
const [receivable, setReceivable] = React113.useState(
|
|
33562
33884
|
() => orderId ? cache3.get(orderId) ?? null : null
|
|
33563
33885
|
);
|
|
33564
|
-
const [loading, setLoading] =
|
|
33565
|
-
const reload =
|
|
33886
|
+
const [loading, setLoading] = React113.useState(() => Boolean(orderId) && !cache3.has(orderId));
|
|
33887
|
+
const reload = React113.useCallback(async (force = false) => {
|
|
33566
33888
|
if (!orderId) return;
|
|
33567
33889
|
const db2 = getSupabaseClientOptional();
|
|
33568
33890
|
if (!db2) {
|
|
@@ -33585,7 +33907,7 @@ function useOrderReceivable(orderId) {
|
|
|
33585
33907
|
setReceivable(next);
|
|
33586
33908
|
setLoading(false);
|
|
33587
33909
|
}, [orderId]);
|
|
33588
|
-
|
|
33910
|
+
React113.useEffect(() => {
|
|
33589
33911
|
void reload();
|
|
33590
33912
|
}, [reload]);
|
|
33591
33913
|
return { receivable, loading, reload };
|
|
@@ -33738,15 +34060,15 @@ function linesOf(order) {
|
|
|
33738
34060
|
}
|
|
33739
34061
|
function useOrderEditor(orderId) {
|
|
33740
34062
|
const { order, loading, error } = useOrderDetail(orderId);
|
|
33741
|
-
const [lines, setLines] =
|
|
33742
|
-
const [saving, setSaving] =
|
|
33743
|
-
const originalRef =
|
|
33744
|
-
|
|
34063
|
+
const [lines, setLines] = React113.useState([]);
|
|
34064
|
+
const [saving, setSaving] = React113.useState(false);
|
|
34065
|
+
const originalRef = React113.useRef([]);
|
|
34066
|
+
React113.useEffect(() => {
|
|
33745
34067
|
const seeded = linesOf(order);
|
|
33746
34068
|
originalRef.current = seeded;
|
|
33747
34069
|
setLines(seeded);
|
|
33748
34070
|
}, [order]);
|
|
33749
|
-
const dirty =
|
|
34071
|
+
const dirty = React113.useMemo(() => {
|
|
33750
34072
|
const before = originalRef.current;
|
|
33751
34073
|
if (before.length !== lines.length) return true;
|
|
33752
34074
|
return lines.some((line, i) => {
|
|
@@ -33754,7 +34076,7 @@ function useOrderEditor(orderId) {
|
|
|
33754
34076
|
return !was || was.key !== line.key || was.quantity !== line.quantity || was.unitPrice !== line.unitPrice;
|
|
33755
34077
|
});
|
|
33756
34078
|
}, [lines]);
|
|
33757
|
-
const save =
|
|
34079
|
+
const save = React113.useCallback(async () => {
|
|
33758
34080
|
if (!orderId || !order) return { ok: false, error: "Pedido n\xE3o carregado" };
|
|
33759
34081
|
const db2 = getSupabaseClientOptional();
|
|
33760
34082
|
if (!db2) return { ok: false, error: "Sem conex\xE3o" };
|
|
@@ -34246,11 +34568,11 @@ function PersonTimeline({
|
|
|
34246
34568
|
pageSize,
|
|
34247
34569
|
activeSourceIds
|
|
34248
34570
|
});
|
|
34249
|
-
const toneBySource =
|
|
34571
|
+
const toneBySource = React113__default.useMemo(
|
|
34250
34572
|
() => new Map(sources2.map((s) => [s.id, s.tone ?? "neutral"])),
|
|
34251
34573
|
[sources2]
|
|
34252
34574
|
);
|
|
34253
|
-
const hrefFor =
|
|
34575
|
+
const hrefFor = React113__default.useCallback(
|
|
34254
34576
|
(item) => {
|
|
34255
34577
|
if (item.href) return item.href;
|
|
34256
34578
|
if (!recordPath || !item.targetTab) return void 0;
|
|
@@ -34293,19 +34615,19 @@ function PersonTimeline({
|
|
|
34293
34615
|
}
|
|
34294
34616
|
function createPlaceholder(title, description) {
|
|
34295
34617
|
return function PlaceholderPage() {
|
|
34296
|
-
return
|
|
34618
|
+
return React113__default.createElement(
|
|
34297
34619
|
"div",
|
|
34298
34620
|
{ className: "mx-auto max-w-4xl" },
|
|
34299
|
-
|
|
34300
|
-
description ?
|
|
34301
|
-
|
|
34621
|
+
React113__default.createElement("h1", { className: "text-3xl font-bold text-foreground" }, title),
|
|
34622
|
+
description ? React113__default.createElement("p", { className: "mt-1 text-muted-foreground" }, description) : null,
|
|
34623
|
+
React113__default.createElement(
|
|
34302
34624
|
"div",
|
|
34303
34625
|
{ className: "mt-8 flex items-center justify-center rounded-card border border-dashed border-border bg-card p-16" },
|
|
34304
|
-
|
|
34626
|
+
React113__default.createElement(
|
|
34305
34627
|
"div",
|
|
34306
34628
|
{ className: "text-center" },
|
|
34307
|
-
|
|
34308
|
-
|
|
34629
|
+
React113__default.createElement("p", { className: "text-lg font-medium text-muted-foreground" }, "Coming Soon"),
|
|
34630
|
+
React113__default.createElement(
|
|
34309
34631
|
"p",
|
|
34310
34632
|
{ className: "mt-1 text-sm text-muted-foreground/70" },
|
|
34311
34633
|
"This module is being built as a plugin."
|
|
@@ -34386,7 +34708,7 @@ function ModuleActionBar({
|
|
|
34386
34708
|
trailing
|
|
34387
34709
|
}) {
|
|
34388
34710
|
const t = useTranslation();
|
|
34389
|
-
const actions =
|
|
34711
|
+
const actions = React113__default.useMemo(() => {
|
|
34390
34712
|
const out = (quickActions ?? []).map((qa, i) => ({
|
|
34391
34713
|
id: qa.id,
|
|
34392
34714
|
label: qa.label,
|
|
@@ -34418,9 +34740,9 @@ function ModuleActionBar({
|
|
|
34418
34740
|
] });
|
|
34419
34741
|
}
|
|
34420
34742
|
function createPluginContext(displayName) {
|
|
34421
|
-
const ConfigContext =
|
|
34422
|
-
const ProviderContext =
|
|
34423
|
-
const StoreContext =
|
|
34743
|
+
const ConfigContext = React113__default.createContext(null);
|
|
34744
|
+
const ProviderContext = React113__default.createContext(null);
|
|
34745
|
+
const StoreContext = React113__default.createContext(null);
|
|
34424
34746
|
const ContextProvider = ({
|
|
34425
34747
|
config,
|
|
34426
34748
|
provider: provider2,
|
|
@@ -34429,17 +34751,17 @@ function createPluginContext(displayName) {
|
|
|
34429
34751
|
}) => /* @__PURE__ */ jsx(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsx(ProviderContext.Provider, { value: provider2, children: /* @__PURE__ */ jsx(StoreContext.Provider, { value: store, children }) }) });
|
|
34430
34752
|
ContextProvider.displayName = `${displayName}ContextProvider`;
|
|
34431
34753
|
function useConfig() {
|
|
34432
|
-
const ctx =
|
|
34754
|
+
const ctx = React113__default.useContext(ConfigContext);
|
|
34433
34755
|
if (!ctx) throw new Error(`useConfig must be used within ${displayName}`);
|
|
34434
34756
|
return ctx;
|
|
34435
34757
|
}
|
|
34436
34758
|
function useProvider() {
|
|
34437
|
-
const ctx =
|
|
34759
|
+
const ctx = React113__default.useContext(ProviderContext);
|
|
34438
34760
|
if (!ctx) throw new Error(`useProvider must be used within ${displayName}`);
|
|
34439
34761
|
return ctx;
|
|
34440
34762
|
}
|
|
34441
34763
|
function useStore2(selector) {
|
|
34442
|
-
const store =
|
|
34764
|
+
const store = React113__default.useContext(StoreContext);
|
|
34443
34765
|
if (!store) throw new Error(`useStore must be used within ${displayName}`);
|
|
34444
34766
|
return useStore$1(store, selector);
|
|
34445
34767
|
}
|
|
@@ -34496,7 +34818,7 @@ function PluginRegistryManager({ registries, routeBase, className }) {
|
|
|
34496
34818
|
return registries[0]?.id ?? "";
|
|
34497
34819
|
};
|
|
34498
34820
|
const [activeTab, setActiveTab] = useState(getTabFromHash);
|
|
34499
|
-
|
|
34821
|
+
React113__default.useEffect(() => {
|
|
34500
34822
|
if (!routeBase) return;
|
|
34501
34823
|
const handler = () => setActiveTab(getTabFromHash());
|
|
34502
34824
|
window.addEventListener("hashchange", handler);
|
|
@@ -35391,10 +35713,10 @@ function useTeachMe(def) {
|
|
|
35391
35713
|
return useFeatureHelp(def).teach;
|
|
35392
35714
|
}
|
|
35393
35715
|
function useFeatureHelp(def) {
|
|
35394
|
-
const ref =
|
|
35716
|
+
const ref = React113.useRef(def);
|
|
35395
35717
|
ref.current = def;
|
|
35396
35718
|
const id = `teach.${def.feature}`;
|
|
35397
|
-
const contribution =
|
|
35719
|
+
const contribution = React113.useMemo(
|
|
35398
35720
|
() => ({
|
|
35399
35721
|
id,
|
|
35400
35722
|
pluginId: "teach-me",
|
|
@@ -35428,7 +35750,7 @@ function useFeatureHelp(def) {
|
|
|
35428
35750
|
[id]
|
|
35429
35751
|
);
|
|
35430
35752
|
useAgentSurface(contribution);
|
|
35431
|
-
return
|
|
35753
|
+
return React113.useMemo(
|
|
35432
35754
|
() => ({
|
|
35433
35755
|
help: () => helpWith(ref.current),
|
|
35434
35756
|
teach: () => teachMe(ref.current),
|
|
@@ -35594,21 +35916,21 @@ function ConnectorsHub({ hostPluginId }) {
|
|
|
35594
35916
|
const { t } = useTranslation$1();
|
|
35595
35917
|
const { connectors, reload } = useConnectors({ includeGrants: false });
|
|
35596
35918
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
35597
|
-
const [selected, setSelected] =
|
|
35598
|
-
const [adding, setAdding] =
|
|
35599
|
-
const hosted =
|
|
35919
|
+
const [selected, setSelected] = React113__default.useState(null);
|
|
35920
|
+
const [adding, setAdding] = React113__default.useState(false);
|
|
35921
|
+
const hosted = React113__default.useMemo(
|
|
35600
35922
|
() => (connectors ?? []).filter((c) => c.hostPluginId === hostPluginId),
|
|
35601
35923
|
[connectors, hostPluginId]
|
|
35602
35924
|
);
|
|
35603
|
-
const categories =
|
|
35925
|
+
const categories = React113__default.useMemo(
|
|
35604
35926
|
() => [...new Set(hosted.map((c) => c.category).filter((c) => !!c))],
|
|
35605
35927
|
[hosted]
|
|
35606
35928
|
);
|
|
35607
|
-
const scoped =
|
|
35929
|
+
const scoped = React113__default.useMemo(() => {
|
|
35608
35930
|
const siblings = inCategories(connectors ?? [], categories).filter((c) => c.hostPluginId !== hostPluginId);
|
|
35609
35931
|
return [...hosted, ...siblings];
|
|
35610
35932
|
}, [connectors, hosted, categories, hostPluginId]);
|
|
35611
|
-
|
|
35933
|
+
React113__default.useEffect(() => {
|
|
35612
35934
|
if (!selected || !connectors) return;
|
|
35613
35935
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
35614
35936
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -35743,7 +36065,7 @@ function PropertiesTab({ registries, routeBase, regLabel }) {
|
|
|
35743
36065
|
return registries[0]?.id ?? "";
|
|
35744
36066
|
}
|
|
35745
36067
|
const [active2, setActive] = useState(getActive);
|
|
35746
|
-
|
|
36068
|
+
React113__default.useEffect(() => {
|
|
35747
36069
|
const handler = () => setActive(getActive());
|
|
35748
36070
|
window.addEventListener("hashchange", handler);
|
|
35749
36071
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -35818,7 +36140,7 @@ function PluginSettingsPanel({ title, generalSettings, registries, customTabs, r
|
|
|
35818
36140
|
return tabs[0]?.id ?? "";
|
|
35819
36141
|
}
|
|
35820
36142
|
const [activeTab, setActiveTab] = useState(getActiveFromHash);
|
|
35821
|
-
|
|
36143
|
+
React113__default.useEffect(() => {
|
|
35822
36144
|
const handler = () => setActiveTab(getActiveFromHash());
|
|
35823
36145
|
window.addEventListener("hashchange", handler);
|
|
35824
36146
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -35845,6 +36167,6 @@ var renderApp = (...args) => {
|
|
|
35845
36167
|
return renderApp$1(...args);
|
|
35846
36168
|
};
|
|
35847
36169
|
|
|
35848
|
-
export { ALWAYS_ON_TOOLS, ActivationChecklistCard, ActivationProvider, AddConnectorButton, AddConnectorPanel, AdminProviders, AdminScaffold, AdminShell, AskAIButton, AskAIMenuItem, AssistantInvite, BoardFrame, ChatConversation, ClientOrdersTab, ConnectConsentPage, ConnectorDeliveries, ConnectorDetail, ConnectorMark, ConnectorRow, ConnectorSyncActions, ConnectorsHub, ConnectorsTab, ContactPicker, CredentialSinkMissingError, CrudCardGrid, CrudDetailPage, CrudDetailSkeleton, CrudFormPage, CrudFormSkeleton, CrudListView, CrudPage, CrudRecordModal, DeleteConfirmDialog, DetailTabHeader, EntitlementGate, EntityLink, GetStarted, GettingStartedWidget, NotebookPanel as HandbookPanel, HandbookProvider, NotebookRailPanel as HandbookRailPanel, KanbanBoard, LimitGate, LookupCreateInline, MemberAccessRailPage, ModuleActionBar, MultiSelectRow, NOTE_LABEL_PREFIX, NotebookPanel, NotebookRailPanel, ONBOARDING_TASK_SOURCE, ORDER_CHANNEL_LABELS, ORDER_KIND_LABELS, OTHER_CONNECTOR, OrderAmount, OrderBoardView, OrderCreateScreen, OrderDetailBlock, OrderDetailPage, OrderDetailRail, OrderDetailRow, OrderDetailSkeleton, OrderDetailView, OrderFormAddItemStep, OrderDetailBlock as OrderFormBlock, OrderFormItemRow, OrderFormItemsCard, OrderFormSkeleton, OrderFormView, OrderListView, OrderPaymentChip, PAYMENT_STATUS_CONFIG, PAYMENT_STATUS_LABEL, PageActions, PaymentStatusBadge, PermissionGate, PersonLink2 as PersonLink, PersonTimeline, PlatformError, PluginRegistryManager, PluginSettingsPanel, ProjectsSettings, QUESTION_PACKS, QuickActionsButton, RECEIVABLE_LABEL, RecordPickerModal, RegistryCrudView2 as RegistryCrudView, RightRailActions, RightRailLeading, RightRailPage, RouteErrorBoundary, RouteErrorScreen, SelectRow, SettingsGroup, SettingsTabs, SetupAgentSurface, SetupMeLink, SeuSiteWidget, StateChip, TASK_PRIORITIES, TASK_STATUSES, TaskCard, TaskDetail, TaskGroup, TaskLabelBadge, TaskLabelBadges, TaskPriorityBadge, TaskQuickAdd, TaskSourceBadge, TaskStatusGroup, TasksFilterBar, TasksPanel, TasksRailPanel, TeachMeLink, TextRow, ToggleRow, UnitSwitcher, UnitsSettingsPage, UpgradePrompt, WORKSPACE_SETUP_FLOW_ID, WORKSPACE_SETUP_FLOW_VERSION, WORKSPACE_SETUP_ROUTE, WidgetSlot, WorkspaceSetupFlow, WorkspaceSetupGate, activePluginIds, appendHandbookPage, askAI, beautyPack, brandMark, buildBusinessProfile, buildHandbookTree, buildWorkspaceSetupSteps, businessProfileBlock, categoryLabel, checkSlugAvailable, claimTasksSurface, connectorOptions, connectorRoute, connectorRows, createArchetypeLookup, createClientOrdersProvider, createCrudPage, createFayzApp, createFayzProject, createLogoUploader, createMockTasksProvider, createCrudPage as createNativeCrudPage, createPlaceholder, createPlatformProject, createPluginContext, createSupabaseTasksProvider, createViewRouter, currentBusinessProfileBlock, dedup, defaultProjectOf, defineSaas, deleteFayzProject, deriveAgentContract, duplicateWrite, ensureChecklist, exportToCSV, filterConnectors, foodPack, formatActivityElapsed, formatCurrency4 as formatCurrency, formatSetupGuide, getActiveAgent, getAgent, getDefaultFayzProject, getFayzAgentClient, getGenerationStatus, getHost, getPersonBookable, getPersonLookup, getPersonPath, getPreview, getQuestionPack, getRailPage, getSetupGuide, getSetupGuideForStep, getTasksProvider, getTimelineSources, hasPlugin, helpWith, humanizeWriteError, inferVerticalId, invalidateOrderReceivable, invalidateOrdersPaymentStatus, invalidateRelationOptions, isPlatformConnected, listFayzProjects, listHandbook, listPlatformProjects, listSetupGuides, loadArea, loadTools, loadedToolNames, mergeLines, needsCredentialSink, normalizePath, openAssistant, openAssistantAs, openConnectorsPanel, openEntity, orderChannelColumn, orderIsEditable, orderKindColumn, orientationTour, parseViewId, publishAssistantActivity, readAttachmentBytes, readHandbookPage, readSetupAnswers, receivableTone, recordOnboardingResponse, registerAdminScaffold, registerAssistantLauncher, registerEntityPath, registerNotesTasksAdapter, registerPersonLookup, registerRailPage, registerSetupGuides, registerTimelineSource, renderApp, renderHandbookOutline, requestChatUpload, requestProjectChange, resetLoadedTools, resolveEntityAnchor, resolveEntityHref, resolveFayzAgentConnection, resolveSetupMode, resolveVerticalId, retailPack, revealPage, runWelcome, searchHandbook, searchSetupGuides, setPersonBookable, setTasksProvider, setUpWithMe, slugify, soleAgent, splitConnectorValues, splitOnboardingTasks, startGuidedRun, startPreview, stopPreview, submitConnection, submitWorkspaceSetup, summariseSetupGuides, taskEntityDef, tasksSurfaceOwner, teachMe, toInlineFile, toOrderDetailReceivable, unregisterAssistantLauncher, unregisterTimelineSource, updateFayzProject, useActivationStore, useActiveAgent, useAgent, useAgentStore, useAgentSurface, useAppConfig, useAppConfigStore, useAssistantActivity, useAssistantInviteStore, useAssistantLaunchers, useBusinessProfileStore, useChatStore, useConnectors, useConnectorsPanelAvailable, useContextualNav, useContextualNavStore, useDelegateToAssistant, useFayzProjectsStore, useFeatureHelp, useFieldRules, useHandbookStore, useHasRightRail, useHeaderAction, useHeaderActions, useLaunchersForRole, useLookupCreate, useMemberAccessPanel, useModuleNavigation, useNavContribution, useNavContributionsStore, useNotesTasksBridge, useOrderDetail, useOrderEditor, useOrderReceivable, useOrdersPaymentStatus, usePersonTimeline, usePluginPrefs, usePublishAssistantActivity, useRegisterAssistantLauncher, useRightRailDrill, useRightRailHosted, useRightRailPanel, useRightRailStore, useSettingsTabsStore, useShellRailAvailable, useTasksStore, useTasksSummaryLine, useTeachMe, useTenantPluginSettings, useUnitBootstrap, useUnitStore, useWidgetSurface, useWorkspaceSetupBusy, useWorkspaceSetupGate, useWorkspaceSetupStore, validateSetupGuides, withdrawAssistantActivity, writeHandbookPage };
|
|
36170
|
+
export { ALWAYS_ON_TOOLS, ActivationChecklistCard, ActivationProvider, AddConnectorButton, AddConnectorPanel, AdminProviders, AdminScaffold, AdminShell, AskAIButton, AskAIMenuItem, AssistantInvite, BoardFrame, ChatConversation, ClientOrdersTab, ConnectConsentPage, ConnectorDeliveries, ConnectorDetail, ConnectorMark, ConnectorRow, ConnectorSyncActions, ConnectorsHub, ConnectorsTab, ContactPicker, CredentialSinkMissingError, CrudCardGrid, CrudDetailPage, CrudDetailSkeleton, CrudFormPage, CrudFormSkeleton, CrudListView, CrudPage, CrudRecordModal, DeleteConfirmDialog, DetailTabHeader, EntitlementGate, EntityLink, GetStarted, GettingStartedWidget, NotebookPanel as HandbookPanel, HandbookProvider, NotebookRailPanel as HandbookRailPanel, KanbanBoard, LimitGate, LookupCreateInline, MemberAccessRailPage, ModuleActionBar, MultiSelectRow, NOTE_LABEL_PREFIX, NotebookPanel, NotebookRailPanel, ONBOARDING_TASK_SOURCE, ORDER_CHANNEL_LABELS, ORDER_KIND_LABELS, OTHER_CONNECTOR, OrderAmount, OrderBoardView, OrderCreateScreen, OrderDetailBlock, OrderDetailPage, OrderDetailRail, OrderDetailRow, OrderDetailSkeleton, OrderDetailView, OrderFormAddItemStep, OrderDetailBlock as OrderFormBlock, OrderFormItemRow, OrderFormItemsCard, OrderFormSkeleton, OrderFormView, OrderListView, OrderPaymentChip, PAYMENT_STATUS_CONFIG, PAYMENT_STATUS_LABEL, PageActions, PaymentStatusBadge, PermissionGate, PersonLink2 as PersonLink, PersonTimeline, PlatformError, PluginRegistryManager, PluginSettingsPanel, ProjectsSettings, QUESTION_PACKS, QuickActionsButton, RECEIVABLE_LABEL, RecordPickerModal, RegistryCrudView2 as RegistryCrudView, RightRailActions, RightRailLeading, RightRailPage, RouteErrorBoundary, RouteErrorScreen, SelectRow, SettingsGroup, SettingsTabs, SetupAgentSurface, SetupMeLink, SeuSiteWidget, StateChip, TASK_PRIORITIES, TASK_STATUSES, TaskCard, TaskDetail, TaskGroup, TaskLabelBadge, TaskLabelBadges, TaskPriorityBadge, TaskQuickAdd, TaskSourceBadge, TaskStatusGroup, TasksFilterBar, TasksPanel, TasksRailPanel, TeachMeLink, TextRow, ToggleRow, UnitSwitcher, UnitsSettingsPage, UpgradePrompt, WORKSPACE_SETUP_FLOW_ID, WORKSPACE_SETUP_FLOW_VERSION, WORKSPACE_SETUP_ROUTE, WidgetSlot, WorkspaceSetupFlow, WorkspaceSetupGate, activePluginIds, appendHandbookPage, askAI, beautyPack, brandMark, buildBusinessProfile, buildHandbookTree, buildWorkspaceSetupSteps, businessProfileBlock, categoryLabel, checkSlugAvailable, claimTasksSurface, connectorOptions, connectorRoute, connectorRows, createArchetypeLookup, createClientOrdersProvider, createCrudPage, createFayzApp, createFayzProject, createLogoUploader, createMockTasksProvider, createCrudPage as createNativeCrudPage, createPlaceholder, createPlatformProject, createPluginContext, createSupabaseTasksProvider, createViewRouter, currentBusinessProfileBlock, dedup, defaultProjectOf, defineSaas, deleteFayzProject, deriveAgentContract, duplicateWrite, ensureChecklist, exportToCSV, filterConnectors, foodPack, formatActivityElapsed, formatCurrency4 as formatCurrency, formatSetupGuide, getActiveAgent, getAgent, getDefaultFayzProject, getFayzAgentClient, getGenerationStatus, getHost, getPersonBookable, getPersonLookup, getPersonPath, getPreview, getQuestionPack, getRailPage, getSetupGuide, getSetupGuideForStep, getTasksProvider, getTimelineSources, hasPlugin, helpWith, humanizeWriteError, inferVerticalId, invalidateOrderReceivable, invalidateOrdersPaymentStatus, invalidateRelationOptions, isPlatformConnected, listFayzProjects, listHandbook, listPlatformProjects, listSetupGuides, loadArea, loadTools, loadedToolNames, mergeLines, needsCredentialSink, normalizePath, openAssistant, openAssistantAs, openConnectorsPanel, openEntity, orderChannelColumn, orderIsEditable, orderKindColumn, orientationTour, parseViewId, publishAssistantActivity, readAttachmentBytes, readHandbookPage, readSetupAnswers, receivableTone, recordOnboardingResponse, registerAdminScaffold, registerAssistantLauncher, registerEntityPath, registerNotesTasksAdapter, registerPersonLookup, registerRailPage, registerSetupGuides, registerTimelineSource, renderApp, renderHandbookOutline, requestChatUpload, requestProjectChange, resetLoadedTools, resolveEntityAnchor, resolveEntityHref, resolveEntityRoute, resolveFayzAgentConnection, resolveSetupMode, resolveVerticalId, retailPack, revealPage, runWelcome, searchHandbook, searchSetupGuides, setPersonBookable, setTasksProvider, setUpWithMe, slugify, soleAgent, splitConnectorValues, splitOnboardingTasks, startGuidedRun, startPreview, stopPreview, submitConnection, submitWorkspaceSetup, summariseSetupGuides, taskEntityDef, tasksSurfaceOwner, teachMe, toInlineFile, toOrderDetailReceivable, unregisterAssistantLauncher, unregisterTimelineSource, updateFayzProject, useActivationStore, useActiveAgent, useAgent, useAgentStore, useAgentSurface, useAppConfig, useAppConfigStore, useAssistantActivity, useAssistantInviteStore, useAssistantLaunchers, useBusinessProfileStore, useChatStore, useConnectors, useConnectorsPanelAvailable, useContextualNav, useContextualNavStore, useDelegateToAssistant, useFayzProjectsStore, useFeatureHelp, useFieldRules, useHandbookStore, useHasRightRail, useHeaderAction, useHeaderActions, useLaunchersForRole, useLookupCreate, useMemberAccessPanel, useModuleNavigation, useNavContribution, useNavContributionsStore, useNotesTasksBridge, useOrderDetail, useOrderEditor, useOrderReceivable, useOrdersPaymentStatus, usePersonTimeline, usePluginPrefs, usePublishAssistantActivity, useRegisterAssistantLauncher, useRightRailDrill, useRightRailHosted, useRightRailPanel, useRightRailStore, useSettingsTabsStore, useShellRailAvailable, useTasksStore, useTasksSummaryLine, useTeachMe, useTenantPluginSettings, useUnitBootstrap, useUnitStore, useWidgetSurface, useWorkspaceSetupBusy, useWorkspaceSetupGate, useWorkspaceSetupStore, validateSetupGuides, withdrawAssistantActivity, writeHandbookPage };
|
|
35849
36171
|
//# sourceMappingURL=index.js.map
|
|
35850
36172
|
//# sourceMappingURL=index.js.map
|