@fayz-ai/admin 0.39.0 → 0.42.0
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/app/AdminShell.d.ts.map +1 -1
- package/dist/app/ConnectionBanner.d.ts +7 -0
- package/dist/app/ConnectionBanner.d.ts.map +1 -0
- package/dist/app/OfflineBoot.d.ts +32 -0
- package/dist/app/OfflineBoot.d.ts.map +1 -0
- package/dist/app/admin-app.d.ts.map +1 -1
- package/dist/app/config.d.ts +6 -0
- package/dist/app/config.d.ts.map +1 -1
- package/dist/components/shared/RecordPickerModal.d.ts.map +1 -1
- package/dist/crud/CrudListView.d.ts.map +1 -1
- package/dist/crud/CrudPage.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderDetailView.d.ts +2 -0
- package/dist/crud/archetypes/OrderDetailView.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderFormView.d.ts.map +1 -1
- package/dist/index.js +1027 -842
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-staff.d.ts +6 -1
- package/dist/lib/agent-staff.d.ts.map +1 -1
- package/dist/projects/ProjectsSettings.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -20,10 +20,13 @@ import { usePermissionOptional, usePermissionsStore, PermissionsProvider } from
|
|
|
20
20
|
export { PermissionsProvider, useHasPermission, usePermission, usePermissionOptional, usePermissions, usePermissionsStore } from './chunk-UQ2NTFQC.js';
|
|
21
21
|
import { cn, useOrganizationStore } from './chunk-QOS6UAQ4.js';
|
|
22
22
|
export { getPersistedOrgId, useOrganizationStore } from './chunk-QOS6UAQ4.js';
|
|
23
|
-
import * as
|
|
24
|
-
import
|
|
25
|
-
import
|
|
23
|
+
import * as React132 from 'react';
|
|
24
|
+
import React132__default, { createContext, useMemo, useState, useRef, useCallback, useEffect, useLayoutEffect, useContext, createElement } from 'react';
|
|
25
|
+
import * as LucideIcons from 'lucide-react';
|
|
26
|
+
import { RotateCcw, WifiOff, Pencil, Copy, Trash2, Upload, Search, ArrowDown, ArrowUp, ArrowUpDown, Check, Download, ChevronLeft, ChevronRight, AlertTriangle, Building2, 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, Globe, LayoutTemplate, Store, ChevronsUpDown, ExternalLink, PenSquare, RefreshCw, XCircle, Camera, Edit, Star, Link2Off, Layers, ShoppingBag, MoreHorizontal, ChevronUp, List, LayoutGrid, CircleDollarSign, Receipt, Settings, Mail, MessageCircle, Cake, HelpCircle, Wrench, ShieldCheck, MessageSquare, Paperclip, Infinity, CheckCheck, PartyPopper, Compass, Play, MapPin, Landmark, LocateFixed, ArrowUpCircle, ArrowUpRight, Pause, CalendarDays, CircleCheckBig, UserX, Ban, CircleAlert, CircleEllipsis, FileText, CircleDashed, Power, ArrowRightLeft, File as File$1, FileImage, FileSpreadsheet, AlertCircle, CreditCard, SlidersHorizontal, Puzzle, Shield, Palette, Blocks, ShieldAlert, UserCog, LogOut, Bell, Database, Radio, Zap, Save, ImagePlus, UserPlus, Contact, UserMinus, Send, Sun, Moon, Monitor, Languages, Info, Link2, KeyRound, Bug, Home, Heart, Briefcase, BarChart3, Tag, Truck, Globe2 } from 'lucide-react';
|
|
27
|
+
import { reportAppError, toDataError, tl, createDebug, resetActiveUnit, setUnitMode, setActiveUnitId, setScopedResources, fetchAppConfig, getSupabaseClientOptional, payeeAccountFields, maskCpfCnpj, recordRailFields, RECORD_GROUP, activeFacet, createSafeDataProvider, isKnownMissing, rememberIfMissing, deriveEntityKey, registerEntity, getActiveTenantId, resolveDataProvider, bulkRemove, emitDomainEvent, entityEventKey, errorMessage, useTranslation, describeError, useDataChanged, emitDataChanged, exportCSV, getScopedResource, formatDateTime as formatDateTime$1, formatDate as formatDate$1, formatCurrency as formatCurrency$1, bulkCreate, matchesRange, isConnectorCategory, usePluginRuntimeOptional, useDataVersion, getWidgetsForZone, resolvePluginComponent, useUnitMode, invalidateAppConfig, toTenantPluginBindings, setCurrentLocale, resolveLocale, resolvePluginRuntime, PluginRuntimeProvider, I18nProvider, getAllEntities, resolveIntegrationSurface, defineApp, registerScaffold, useActiveTenantId, onDataChanged, useConnectorsForPlugin, renderApp as renderApp$1, parseRangeFilter, isFilterObject, connectionKey, useManifest, registerEventSink, formatPostalCode, isValidPostalCode, lookupPostalCode, usePluginRuntime, useConnectivity, RECONNECTED_EVENT, installGlobalErrorHandlers, registerErrorReporter, getConnectivity, applyNavComposition, mergeTranslations, coreTranslations, attachPersistentCache, getPersistentCache, createMockProvider, listConnections, connectorPlanes, connectorPermissions, connectorEntities, preferredPlane, connectorDirection, countByTenant, isAddressIncomplete, isBankIncomplete, payeeMethodOf, getCurrentLocale, searchEverything, readImpersonation, getComponent, getPluginFactory, connectorSettings, groupedPermissions, invocationPlane, missingRequiredSettings, isBankEmpty, isAddressEmpty, writeImpersonation, isSettingSet, getEntityByKey, connectorSubscribesTo, eventKeyMatches } from '@fayz-ai/core';
|
|
26
28
|
export { ConnectorRuntimeTokenUnavailableError, createSafeDataProvider, formatDate, formatDateTime, getActiveLocale, getActiveTenantId, getConnectorRuntimeTokenSource, getCurrentLocale, getSupabaseClientOptional, preloadLocale, resolveBackendEnv, setConnectorRuntimeTokenSource, setCurrentLocale, tl, useActiveTenantId } from '@fayz-ai/core';
|
|
29
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
27
30
|
import { usePasswordSetupGate, SetPasswordPage, AuthGate, AuthProvider, createAuthRuntime } from '@fayz-ai/plugin-auth';
|
|
28
31
|
export { LoginPage } from '@fayz-ai/plugin-auth';
|
|
29
32
|
import { Input, SearchSelect, toast, usePageTrailParent, navigateToCrumb, Button, PageHeader, ConfirmDialog, RowActions, useRowSelection, getLucideIcon, ListFilterBar, 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, PersonAvatar, PageActionBar, ICON_MAP, Sheet, SheetContent, SheetBody, useIsWide, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Checkbox, useTourStore, setTourNavigator, TourSpotlight, PracticeOverlay, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Wizard, SidebarOnboarding, OnboardingWidget, Skeleton, useLayoutStore, ModalPortal, ModalOverlay, ModalBody, useSaveBar, useBackHandler, SubpageHeader, Separator, Tabs, TabsList, TabsTrigger, TabsContent, CardContent, ToastProvider, NavTransitionProvider, ListView, Thumbnail, CurrencyInput, SearchField, ChevronPager, Popover, PopoverTrigger, PopoverContent, useModuleLayout, PhoneLink, normalizePhone, SearchCombobox, HeaderTabs, usePageTrail, PageHeaderOutlet, AppShellSkeleton, usePracticeStore, ViewTabs, Switch, ModalTask, setPrintBrand, useModuleViewLabel, ModuleLayoutProvider, AppShell, PageTransition, PickerDialog, MarkdownEditor, PhoneField, isCreateRoute, PageSubNav, createFayzTheme, Avatar, AvatarImage, AvatarFallback, Markdown, PageTrail, CardTitle, CardDescription, DropdownSub, DropdownSubTrigger, DropdownSubContent, DropdownRadioGroup, DropdownRadioItem, BottomSheet, CardHeader, CardFooter, SegmentedControl, SheetCard, SheetRow, useSheetClose } from '@fayz-ai/ui';
|
|
@@ -31,9 +34,6 @@ export { createFayzTheme, fayzThemePresets } from '@fayz-ai/ui';
|
|
|
31
34
|
import { useAuthStore, useAuth, buildAppHandoffUrl } from '@fayz-ai/auth';
|
|
32
35
|
export { useAuth } from '@fayz-ai/auth';
|
|
33
36
|
import { create, useStore as useStore$1 } from 'zustand';
|
|
34
|
-
import * as LucideIcons from 'lucide-react';
|
|
35
|
-
import { Pencil, Copy, Trash2, Upload, Search, ArrowDown, ArrowUp, ArrowUpDown, Check, Download, ChevronLeft, ChevronRight, AlertTriangle, Building2, 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, RotateCcw, Globe, LayoutTemplate, Store, ChevronsUpDown, ExternalLink, PenSquare, RefreshCw, XCircle, Camera, Edit, Star, Link2Off, Layers, ShoppingBag, MoreHorizontal, ChevronUp, List, LayoutGrid, CircleDollarSign, Receipt, Settings, Mail, MessageCircle, Cake, HelpCircle, Wrench, ShieldCheck, MessageSquare, Paperclip, Infinity, CheckCheck, PartyPopper, Compass, Play, MapPin, Landmark, LocateFixed, ArrowUpCircle, ArrowUpRight, Pause, CalendarDays, CircleCheckBig, UserX, Ban, CircleAlert, CircleEllipsis, FileText, CircleDashed, Power, ArrowRightLeft, File as File$1, FileImage, FileSpreadsheet, AlertCircle, CreditCard, SlidersHorizontal, Puzzle, Shield, Palette, Blocks, ShieldAlert, UserCog, LogOut, Bell, Database, Radio, Zap, Save, ImagePlus, UserPlus, Contact, UserMinus, Send, Sun, Moon, Monitor, Languages, Info, Link2, KeyRound, Bug, Home, Heart, Briefcase, BarChart3, Tag, Truck, Globe2 } from 'lucide-react';
|
|
36
|
-
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
37
37
|
import { createPortal } from 'react-dom';
|
|
38
38
|
import { profileHasSystemPermission, mergeLimitDeclarations } from '@fayz-ai/core/access';
|
|
39
39
|
import { createFayzAgentClient } from '@fayz-ai/sdk/agent';
|
|
@@ -41,6 +41,101 @@ import { getConnectorCredentialSink, fayzPlatformOrigin, ConnectorOAuthStarterMi
|
|
|
41
41
|
export { ConnectorCredentialSinkError, ConnectorOAuthError, ConnectorOAuthStarterMissingError, createFayzConnectorAccountSource, createFayzConnectorCredentialSink, createFayzConnectorOAuthStarter, describeConnectorAccount, fayz, fayzConnectorOAuth, getConnectorAccountSource, getConnectorCredentialSink, getConnectorOAuthStarter, setConnectorAccountSource, setConnectorCredentialSink, setConnectorOAuthStarter, startConnectorOAuth } from '@fayz-ai/sdk';
|
|
42
42
|
import { createFayzEventsClient } from '@fayz-ai/sdk/events';
|
|
43
43
|
|
|
44
|
+
var shellMounted = false;
|
|
45
|
+
function ShellMountedMarker() {
|
|
46
|
+
React132__default.useEffect(() => {
|
|
47
|
+
shellMounted = true;
|
|
48
|
+
}, []);
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
function OfflineScreen({ onRetry }) {
|
|
52
|
+
return /* @__PURE__ */ jsxs(
|
|
53
|
+
"div",
|
|
54
|
+
{
|
|
55
|
+
role: "alert",
|
|
56
|
+
className: "fixed inset-0 z-[200] flex flex-col items-center justify-center gap-3 bg-background px-6 text-center",
|
|
57
|
+
"data-testid": "offline-boot",
|
|
58
|
+
children: [
|
|
59
|
+
/* @__PURE__ */ jsx(WifiOff, { className: "h-10 w-10 text-muted-foreground", "aria-hidden": true }),
|
|
60
|
+
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-foreground", children: tl("No internet connection", "Sem conex\xE3o com a internet") }),
|
|
61
|
+
/* @__PURE__ */ jsx("p", { className: "max-w-sm text-sm text-muted-foreground", children: tl(
|
|
62
|
+
"We could not open the app right now. It will open by itself as soon as the internet is back.",
|
|
63
|
+
"N\xE3o conseguimos abrir o sistema agora. Assim que a internet voltar, a tela abre sozinha."
|
|
64
|
+
) }),
|
|
65
|
+
/* @__PURE__ */ jsxs(
|
|
66
|
+
"button",
|
|
67
|
+
{
|
|
68
|
+
type: "button",
|
|
69
|
+
onClick: onRetry,
|
|
70
|
+
className: "mt-2 inline-flex items-center gap-1.5 rounded-button border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground hover:bg-muted",
|
|
71
|
+
children: [
|
|
72
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "h-4 w-4", "aria-hidden": true }),
|
|
73
|
+
tl("Try again", "Tentar de novo")
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
var reload = () => window.location.reload();
|
|
82
|
+
function OfflineBootGuard({ children }) {
|
|
83
|
+
const { online } = useConnectivity();
|
|
84
|
+
const blocked = !online && !shellMounted;
|
|
85
|
+
const wasBlocked = React132__default.useRef(false);
|
|
86
|
+
if (blocked) wasBlocked.current = true;
|
|
87
|
+
React132__default.useEffect(() => {
|
|
88
|
+
if (online && wasBlocked.current && !shellMounted) reload();
|
|
89
|
+
}, [online]);
|
|
90
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
91
|
+
children,
|
|
92
|
+
blocked && /* @__PURE__ */ jsx(OfflineScreen, { onRetry: reload })
|
|
93
|
+
] });
|
|
94
|
+
}
|
|
95
|
+
var AppErrorBoundary = class extends React132__default.Component {
|
|
96
|
+
constructor() {
|
|
97
|
+
super(...arguments);
|
|
98
|
+
this.state = { error: null };
|
|
99
|
+
this.onlineAgain = () => {
|
|
100
|
+
if (this.state.error) reload();
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
static getDerivedStateFromError(error) {
|
|
104
|
+
return { error };
|
|
105
|
+
}
|
|
106
|
+
componentDidCatch(error, info) {
|
|
107
|
+
reportAppError(error, { source: "render", componentStack: info.componentStack });
|
|
108
|
+
}
|
|
109
|
+
componentDidMount() {
|
|
110
|
+
window.addEventListener("online", this.onlineAgain);
|
|
111
|
+
}
|
|
112
|
+
componentWillUnmount() {
|
|
113
|
+
window.removeEventListener("online", this.onlineAgain);
|
|
114
|
+
}
|
|
115
|
+
render() {
|
|
116
|
+
const { error } = this.state;
|
|
117
|
+
if (!error) return this.props.children;
|
|
118
|
+
const offline = toDataError(error).kind === "offline" || typeof navigator !== "undefined" && navigator.onLine === false;
|
|
119
|
+
if (offline) return /* @__PURE__ */ jsx(OfflineScreen, { onRetry: reload });
|
|
120
|
+
return /* @__PURE__ */ jsxs("div", { role: "alert", className: "fixed inset-0 flex flex-col items-center justify-center gap-3 bg-background px-6 text-center", children: [
|
|
121
|
+
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold text-foreground", children: tl("Something went wrong", "Algo deu errado") }),
|
|
122
|
+
/* @__PURE__ */ jsx("p", { className: "max-w-sm text-sm text-muted-foreground", children: tl("Reload the page to continue.", "Recarregue a p\xE1gina para continuar.") }),
|
|
123
|
+
/* @__PURE__ */ jsxs(
|
|
124
|
+
"button",
|
|
125
|
+
{
|
|
126
|
+
type: "button",
|
|
127
|
+
onClick: reload,
|
|
128
|
+
className: "mt-2 inline-flex items-center gap-1.5 rounded-button border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground hover:bg-muted",
|
|
129
|
+
children: [
|
|
130
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "h-4 w-4", "aria-hidden": true }),
|
|
131
|
+
tl("Reload", "Recarregar")
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
] });
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
44
139
|
// src/onboarding/resolve.ts
|
|
45
140
|
function resolveSetupMode(org) {
|
|
46
141
|
if (org?.setup) return org.setup;
|
|
@@ -77,7 +172,7 @@ function useWorkspaceSetupGate(enabled) {
|
|
|
77
172
|
const close = useWorkspaceSetupStore((s) => s.close);
|
|
78
173
|
const path = useAdminPath();
|
|
79
174
|
const onRoute = path === WORKSPACE_SETUP_ROUTE;
|
|
80
|
-
const exitDeliberate =
|
|
175
|
+
const exitDeliberate = React132.useCallback(() => {
|
|
81
176
|
close();
|
|
82
177
|
if (onRoute) navigateTo("/");
|
|
83
178
|
}, [close, onRoute]);
|
|
@@ -186,10 +281,10 @@ function brandInstructions(brand) {
|
|
|
186
281
|
var UPDATE_EVENT = "fayz:update-ready";
|
|
187
282
|
function UpdateReady() {
|
|
188
283
|
const { t } = useTranslation$1();
|
|
189
|
-
const [pronta, setPronta] =
|
|
190
|
-
const [dispensada, setDispensada] =
|
|
191
|
-
const [aplicando, setAplicando] =
|
|
192
|
-
|
|
284
|
+
const [pronta, setPronta] = React132__default.useState(false);
|
|
285
|
+
const [dispensada, setDispensada] = React132__default.useState(false);
|
|
286
|
+
const [aplicando, setAplicando] = React132__default.useState(false);
|
|
287
|
+
React132__default.useEffect(() => {
|
|
193
288
|
const aviso = () => setPronta(true);
|
|
194
289
|
window.addEventListener(UPDATE_EVENT, aviso);
|
|
195
290
|
return () => window.removeEventListener(UPDATE_EVENT, aviso);
|
|
@@ -1940,7 +2035,7 @@ function getServerVersion() {
|
|
|
1940
2035
|
return 0;
|
|
1941
2036
|
}
|
|
1942
2037
|
function useAssistantActivity() {
|
|
1943
|
-
|
|
2038
|
+
React132.useSyncExternalStore(subscribe, getVersion, getServerVersion);
|
|
1944
2039
|
return pickActivity(activities);
|
|
1945
2040
|
}
|
|
1946
2041
|
var STATE_RANK = {
|
|
@@ -1956,22 +2051,22 @@ function pickActivity(list) {
|
|
|
1956
2051
|
return pool.find((a) => a.kind === "recording") ?? pool[0];
|
|
1957
2052
|
}
|
|
1958
2053
|
function useAssistantLaunchers() {
|
|
1959
|
-
|
|
2054
|
+
React132.useSyncExternalStore(subscribe, getVersion, getServerVersion);
|
|
1960
2055
|
return launchers;
|
|
1961
2056
|
}
|
|
1962
2057
|
function useLaunchersForRole(role) {
|
|
1963
2058
|
const all = useAssistantLaunchers();
|
|
1964
|
-
return
|
|
2059
|
+
return React132.useMemo(() => all.filter((l) => !l.role || l.role === role), [all, role]);
|
|
1965
2060
|
}
|
|
1966
2061
|
function usePublishAssistantActivity(activity) {
|
|
1967
2062
|
const id = activity?.id;
|
|
1968
2063
|
const key = activity ? `${activity.id}|${activity.kind}|${activity.label}|${activity.state}|${activity.elapsedMs ?? ""}|${(activity.actions ?? []).map((a) => a.intent).join(",")}|${activity.confirm?.acknowledge ?? ""}` : null;
|
|
1969
|
-
const ref =
|
|
2064
|
+
const ref = React132.useRef(activity);
|
|
1970
2065
|
ref.current = activity;
|
|
1971
|
-
|
|
2066
|
+
React132.useEffect(() => {
|
|
1972
2067
|
if (ref.current) publishAssistantActivity(ref.current);
|
|
1973
2068
|
}, [key]);
|
|
1974
|
-
|
|
2069
|
+
React132.useEffect(() => {
|
|
1975
2070
|
if (!id) return;
|
|
1976
2071
|
return () => withdrawAssistantActivity(id);
|
|
1977
2072
|
}, [id]);
|
|
@@ -1979,12 +2074,12 @@ function usePublishAssistantActivity(activity) {
|
|
|
1979
2074
|
function useRegisterAssistantLauncher(launcher) {
|
|
1980
2075
|
const id = launcher?.id;
|
|
1981
2076
|
const key = launcher ? `${launcher.id}|${launcher.label}|${launcher.disabled ? "1" : "0"}|${launcher.role ?? ""}` : null;
|
|
1982
|
-
const ref =
|
|
2077
|
+
const ref = React132.useRef(launcher);
|
|
1983
2078
|
ref.current = launcher;
|
|
1984
|
-
|
|
2079
|
+
React132.useEffect(() => {
|
|
1985
2080
|
if (ref.current) registerAssistantLauncher(ref.current);
|
|
1986
2081
|
}, [key]);
|
|
1987
|
-
|
|
2082
|
+
React132.useEffect(() => {
|
|
1988
2083
|
if (!id) return;
|
|
1989
2084
|
return () => unregisterAssistantLauncher(id);
|
|
1990
2085
|
}, [id]);
|
|
@@ -2082,42 +2177,42 @@ function useRightRailPanel(panel) {
|
|
|
2082
2177
|
const sublabel = panel?.sublabel;
|
|
2083
2178
|
const badgeCount = panel?.badge?.count;
|
|
2084
2179
|
const badgeTone = panel?.badge?.tone;
|
|
2085
|
-
const initial =
|
|
2086
|
-
|
|
2180
|
+
const initial = React132.useRef({ label: label3, icon });
|
|
2181
|
+
React132.useEffect(() => {
|
|
2087
2182
|
if (!id || !Component2) return;
|
|
2088
2183
|
register({ id, label: initial.current.label ?? id, order, Component: Component2, icon: initial.current.icon });
|
|
2089
2184
|
return () => unregister(id);
|
|
2090
2185
|
}, [id, order, Component2, register, unregister]);
|
|
2091
|
-
|
|
2186
|
+
React132.useEffect(() => {
|
|
2092
2187
|
if (!id) return;
|
|
2093
2188
|
updateMeta(id, { label: label3, icon, iconBare, trailing, sublabel });
|
|
2094
2189
|
}, [id, label3, icon, iconBare, trailing, sublabel, updateMeta]);
|
|
2095
|
-
|
|
2190
|
+
React132.useEffect(() => {
|
|
2096
2191
|
if (!id) return;
|
|
2097
2192
|
updateBadge(id, badgeCount !== void 0 ? { count: badgeCount, tone: badgeTone } : void 0);
|
|
2098
2193
|
}, [id, badgeCount, badgeTone, updateBadge]);
|
|
2099
2194
|
}
|
|
2100
|
-
var RightRailActionsSlotContext =
|
|
2195
|
+
var RightRailActionsSlotContext = React132.createContext(null);
|
|
2101
2196
|
var RightRailActionsSlotProvider = RightRailActionsSlotContext.Provider;
|
|
2102
2197
|
function RightRailActions({ children }) {
|
|
2103
|
-
const slot =
|
|
2198
|
+
const slot = React132.useContext(RightRailActionsSlotContext);
|
|
2104
2199
|
if (slot) return createPortal(children, slot);
|
|
2105
2200
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-end gap-0.5 px-2 pt-1.5", children });
|
|
2106
2201
|
}
|
|
2107
|
-
var RightRailLeadingSlotContext =
|
|
2202
|
+
var RightRailLeadingSlotContext = React132.createContext(null);
|
|
2108
2203
|
var RightRailLeadingSlotProvider = RightRailLeadingSlotContext.Provider;
|
|
2109
2204
|
function RightRailLeading({ children }) {
|
|
2110
|
-
const slot =
|
|
2205
|
+
const slot = React132.useContext(RightRailLeadingSlotContext);
|
|
2111
2206
|
if (slot) return createPortal(children, slot);
|
|
2112
2207
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 px-2 pt-1.5", children });
|
|
2113
2208
|
}
|
|
2114
2209
|
function useRightRailReselect(id, handler) {
|
|
2115
2210
|
const reselects = useRightRailStore((s) => s.reselects);
|
|
2116
2211
|
const reselectId = useRightRailStore((s) => s.reselectId);
|
|
2117
|
-
const ref =
|
|
2212
|
+
const ref = React132.useRef(handler);
|
|
2118
2213
|
ref.current = handler;
|
|
2119
|
-
const seen =
|
|
2120
|
-
|
|
2214
|
+
const seen = React132.useRef(reselects);
|
|
2215
|
+
React132.useEffect(() => {
|
|
2121
2216
|
if (reselects === seen.current) return;
|
|
2122
2217
|
seen.current = reselects;
|
|
2123
2218
|
if (reselectId === id) ref.current();
|
|
@@ -2134,9 +2229,9 @@ function useRightRailDrill(drill) {
|
|
|
2134
2229
|
const avatarName = drill?.avatar?.name;
|
|
2135
2230
|
const avatarSrc = drill?.avatar?.src;
|
|
2136
2231
|
const avatarFace = drill?.avatar?.Face;
|
|
2137
|
-
const backRef =
|
|
2232
|
+
const backRef = React132.useRef(drill?.back);
|
|
2138
2233
|
backRef.current = drill?.back;
|
|
2139
|
-
|
|
2234
|
+
React132.useEffect(() => {
|
|
2140
2235
|
if (!title) return;
|
|
2141
2236
|
setDrill({
|
|
2142
2237
|
title,
|
|
@@ -2262,16 +2357,31 @@ Voc\xEA cuida do sistema inteiro. As telas desta conta est\xE3o em \`pages\`, e
|
|
|
2262
2357
|
);
|
|
2263
2358
|
return lines.join("\n\n");
|
|
2264
2359
|
}
|
|
2265
|
-
function
|
|
2360
|
+
function agentForApps(apps, byApp) {
|
|
2361
|
+
if (!byApp) return null;
|
|
2362
|
+
for (const app of apps ?? []) {
|
|
2363
|
+
if (app.house || !app.id) continue;
|
|
2364
|
+
const agent = byApp[app.id];
|
|
2365
|
+
if (agent) return agent;
|
|
2366
|
+
}
|
|
2367
|
+
return null;
|
|
2368
|
+
}
|
|
2369
|
+
function useRegisterStaff(staff, staffByApp) {
|
|
2266
2370
|
const setAgent = useAgentStore((s) => s.setAgent);
|
|
2267
|
-
|
|
2371
|
+
const apps = useAppConfigStore((s) => s.config.apps);
|
|
2372
|
+
React132__default.useEffect(() => {
|
|
2373
|
+
const byTrade = agentForApps(apps, staffByApp);
|
|
2374
|
+
if (byTrade) {
|
|
2375
|
+
setAgent(byTrade);
|
|
2376
|
+
return;
|
|
2377
|
+
}
|
|
2268
2378
|
if (staff && staff.length > 1) {
|
|
2269
2379
|
console.warn(
|
|
2270
2380
|
`[fayz] chat.staff lists ${staff.length} agents; an app has one. Using "${soleAgent(staff)?.name}" and ignoring the rest \u2014 see chat.agent.`
|
|
2271
2381
|
);
|
|
2272
2382
|
}
|
|
2273
2383
|
setAgent(soleAgent(staff));
|
|
2274
|
-
}, [staff, setAgent]);
|
|
2384
|
+
}, [staff, staffByApp, apps, setAgent]);
|
|
2275
2385
|
}
|
|
2276
2386
|
function useAgent() {
|
|
2277
2387
|
return useAgentStore((s) => s.agent ?? void 0);
|
|
@@ -2297,7 +2407,7 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2297
2407
|
const { id, persona, headline, pitch, description, placeholder, auto } = def;
|
|
2298
2408
|
const suggestions = def.suggestions;
|
|
2299
2409
|
const suggestionKey = JSON.stringify(suggestions ?? []);
|
|
2300
|
-
|
|
2410
|
+
React132.useEffect(() => {
|
|
2301
2411
|
if (!hasAssistant) return;
|
|
2302
2412
|
setInvite({
|
|
2303
2413
|
id,
|
|
@@ -2311,11 +2421,11 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2311
2421
|
});
|
|
2312
2422
|
return () => setInvite(null, id);
|
|
2313
2423
|
}, [hasAssistant, id, persona, headline, pitch, description, placeholder, auto, suggestionKey, setInvite]);
|
|
2314
|
-
const anchorRef =
|
|
2315
|
-
const [box, setBox] =
|
|
2424
|
+
const anchorRef = React132.useRef(null);
|
|
2425
|
+
const [box, setBox] = React132.useState(null);
|
|
2316
2426
|
const docked = stage === "dock" && !railOpen && hasAssistant;
|
|
2317
2427
|
const showing = hasAssistant && (stage === "hero" || docked);
|
|
2318
|
-
|
|
2428
|
+
React132.useEffect(() => {
|
|
2319
2429
|
if (!showing) return;
|
|
2320
2430
|
const el = anchorRef.current;
|
|
2321
2431
|
if (!el) return;
|
|
@@ -2336,7 +2446,7 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2336
2446
|
}, [showing]);
|
|
2337
2447
|
const setDockBox = useAssistantInviteStore((s) => s.setDockBox);
|
|
2338
2448
|
const wide = useWideViewport();
|
|
2339
|
-
|
|
2449
|
+
React132.useEffect(() => {
|
|
2340
2450
|
if (!docked || !wide || !box) {
|
|
2341
2451
|
setDockBox(null);
|
|
2342
2452
|
return;
|
|
@@ -2350,7 +2460,7 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2350
2460
|
function useAsk() {
|
|
2351
2461
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
2352
2462
|
const dismiss = useAssistantInviteStore((s) => s.dismiss);
|
|
2353
|
-
return
|
|
2463
|
+
return React132.useCallback(
|
|
2354
2464
|
(text2) => {
|
|
2355
2465
|
const trimmed = text2.trim();
|
|
2356
2466
|
if (!trimmed) return;
|
|
@@ -2368,9 +2478,9 @@ function InviteHero({
|
|
|
2368
2478
|
const { t } = useTranslation$1();
|
|
2369
2479
|
const user = useAuthStore((s) => s.user);
|
|
2370
2480
|
const ask = useAsk();
|
|
2371
|
-
const [draft, setDraft] =
|
|
2481
|
+
const [draft, setDraft] = React132.useState("");
|
|
2372
2482
|
const name = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
2373
|
-
|
|
2483
|
+
React132.useEffect(() => {
|
|
2374
2484
|
const onKey = (event) => {
|
|
2375
2485
|
if (event.key === "Escape") onDismiss();
|
|
2376
2486
|
};
|
|
@@ -2432,8 +2542,8 @@ function InviteHero({
|
|
|
2432
2542
|
);
|
|
2433
2543
|
}
|
|
2434
2544
|
function useMorphIn(skip = false) {
|
|
2435
|
-
const [entered, setEntered] =
|
|
2436
|
-
|
|
2545
|
+
const [entered, setEntered] = React132.useState(() => skip || prefersReducedMotion());
|
|
2546
|
+
React132.useEffect(() => {
|
|
2437
2547
|
if (entered) return;
|
|
2438
2548
|
let second = 0;
|
|
2439
2549
|
const first = requestAnimationFrame(() => {
|
|
@@ -2452,10 +2562,10 @@ function prefersReducedMotion() {
|
|
|
2452
2562
|
var lastDockExit = null;
|
|
2453
2563
|
var RESUME_WINDOW_MS = 700;
|
|
2454
2564
|
function useWideViewport() {
|
|
2455
|
-
const [wide, setWide] =
|
|
2565
|
+
const [wide, setWide] = React132.useState(
|
|
2456
2566
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
2457
2567
|
);
|
|
2458
|
-
|
|
2568
|
+
React132.useEffect(() => {
|
|
2459
2569
|
const query = window.matchMedia?.("(min-width: 768px)");
|
|
2460
2570
|
if (!query) return;
|
|
2461
2571
|
const sync = () => setWide(query.matches);
|
|
@@ -2486,21 +2596,21 @@ function InviteDock({ def, left, maxWidth }) {
|
|
|
2486
2596
|
const setOpen = useChatStore((s) => s.setOpen);
|
|
2487
2597
|
const railOpen = useRightRailStore((s) => s.open);
|
|
2488
2598
|
const railWidth = useRightRailStore((s) => s.width);
|
|
2489
|
-
const [draft, setDraft] =
|
|
2490
|
-
const resumed =
|
|
2599
|
+
const [draft, setDraft] = React132.useState("");
|
|
2600
|
+
const resumed = React132.useRef(
|
|
2491
2601
|
!!lastDockExit && lastDockExit.id === def.id && Date.now() - lastDockExit.at < RESUME_WINDOW_MS
|
|
2492
2602
|
).current;
|
|
2493
|
-
|
|
2603
|
+
React132.useEffect(() => () => {
|
|
2494
2604
|
lastDockExit = { id: def.id, at: Date.now() };
|
|
2495
2605
|
}, [def.id]);
|
|
2496
2606
|
const entered = useMorphIn(resumed);
|
|
2497
2607
|
const width = Math.min(maxWidth, DOCK_MAX_WIDTH);
|
|
2498
|
-
const mountGeo =
|
|
2608
|
+
const mountGeo = React132.useRef({ left, width }).current;
|
|
2499
2609
|
const morph = morphStyles({ left: mountGeo.left, width: mountGeo.width }, railOpen, railWidth);
|
|
2500
|
-
const [settled, setSettled] =
|
|
2610
|
+
const [settled, setSettled] = React132.useState(resumed);
|
|
2501
2611
|
const geoLeft = settled ? left : mountGeo.left;
|
|
2502
2612
|
const geoWidth = settled ? width : mountGeo.width;
|
|
2503
|
-
|
|
2613
|
+
React132.useEffect(() => {
|
|
2504
2614
|
if (!entered || settled) return;
|
|
2505
2615
|
const id = setTimeout(() => setSettled(true), MORPH_MS + 60);
|
|
2506
2616
|
return () => clearTimeout(id);
|
|
@@ -2646,7 +2756,7 @@ function MorphBackPill() {
|
|
|
2646
2756
|
const railWidth = useRightRailStore((s) => s.width);
|
|
2647
2757
|
const { t } = useTranslation$1();
|
|
2648
2758
|
const collapsed = useMorphIn();
|
|
2649
|
-
|
|
2759
|
+
React132.useEffect(() => {
|
|
2650
2760
|
if (prefersReducedMotion()) {
|
|
2651
2761
|
endLeave();
|
|
2652
2762
|
return;
|
|
@@ -4562,12 +4672,12 @@ function detectActivePluginId(runtime) {
|
|
|
4562
4672
|
function useAITools() {
|
|
4563
4673
|
const runtime = usePluginRuntimeOptional();
|
|
4564
4674
|
const access = useAccessOptional();
|
|
4565
|
-
const surfaceVersion =
|
|
4675
|
+
const surfaceVersion = React132.useSyncExternalStore(subscribeSurfaces, getSurfaceVersion, getSurfaceVersion);
|
|
4566
4676
|
const features = usePermissionsStore((s) => s.features);
|
|
4567
4677
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
4568
4678
|
const hasSystem = useSystemPermission();
|
|
4569
4679
|
const canManagePermissions = hasSystem("manage_permissions");
|
|
4570
|
-
return
|
|
4680
|
+
return React132.useMemo(() => {
|
|
4571
4681
|
const hasPermission = runtime?.context.hasPermission;
|
|
4572
4682
|
const can = access.can;
|
|
4573
4683
|
const verticalId = runtime?.context.tenant?.verticalId;
|
|
@@ -5583,8 +5693,8 @@ function loadCatalog() {
|
|
|
5583
5693
|
return catalogPromise;
|
|
5584
5694
|
}
|
|
5585
5695
|
function useConnectorCatalog() {
|
|
5586
|
-
const [catalog, setCatalog] =
|
|
5587
|
-
|
|
5696
|
+
const [catalog, setCatalog] = React132__default.useState(null);
|
|
5697
|
+
React132__default.useEffect(() => {
|
|
5588
5698
|
let cancelled = false;
|
|
5589
5699
|
void loadCatalog().then((list) => {
|
|
5590
5700
|
if (!cancelled) setCatalog(list);
|
|
@@ -5608,7 +5718,7 @@ function refreshConnectors() {
|
|
|
5608
5718
|
_revisionListeners.forEach((listener) => listener());
|
|
5609
5719
|
}
|
|
5610
5720
|
function useConnectorsRevision() {
|
|
5611
|
-
return
|
|
5721
|
+
return React132__default.useSyncExternalStore(
|
|
5612
5722
|
(listener) => {
|
|
5613
5723
|
_revisionListeners.add(listener);
|
|
5614
5724
|
return () => _revisionListeners.delete(listener);
|
|
@@ -5627,11 +5737,11 @@ function loadGrants(key, fetcher) {
|
|
|
5627
5737
|
}
|
|
5628
5738
|
function useInstalledModuleIds() {
|
|
5629
5739
|
const runtime = usePluginRuntimeOptional();
|
|
5630
|
-
return
|
|
5740
|
+
return React132__default.useMemo(() => (runtime?.plugins ?? []).map((p) => p.id), [runtime]);
|
|
5631
5741
|
}
|
|
5632
5742
|
function useInstalledDefinitions(hostPluginId) {
|
|
5633
5743
|
const runtime = usePluginRuntimeOptional();
|
|
5634
|
-
return
|
|
5744
|
+
return React132__default.useMemo(() => {
|
|
5635
5745
|
const byHost = runtime?.connectorsByHost;
|
|
5636
5746
|
if (!byHost) return [];
|
|
5637
5747
|
if (hostPluginId) return byHost.get(hostPluginId) ?? [];
|
|
@@ -5644,12 +5754,12 @@ function useConnectors(options = {}) {
|
|
|
5644
5754
|
const catalog = useConnectorCatalog();
|
|
5645
5755
|
const tenant = useTenantOptional();
|
|
5646
5756
|
const tenantId2 = tenant?.org?.id;
|
|
5647
|
-
const connection =
|
|
5648
|
-
const [installed, setInstalled] =
|
|
5649
|
-
const [grants, setGrants] =
|
|
5650
|
-
const [error, setError] =
|
|
5757
|
+
const connection = React132__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
5758
|
+
const [installed, setInstalled] = React132__default.useState(null);
|
|
5759
|
+
const [grants, setGrants] = React132__default.useState(null);
|
|
5760
|
+
const [error, setError] = React132__default.useState(null);
|
|
5651
5761
|
const nonce = useConnectorsRevision();
|
|
5652
|
-
const call2 =
|
|
5762
|
+
const call2 = React132__default.useCallback(
|
|
5653
5763
|
async (path, init) => {
|
|
5654
5764
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
5655
5765
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -5669,7 +5779,7 @@ function useConnectors(options = {}) {
|
|
|
5669
5779
|
},
|
|
5670
5780
|
[connection]
|
|
5671
5781
|
);
|
|
5672
|
-
|
|
5782
|
+
React132__default.useEffect(() => {
|
|
5673
5783
|
let cancelled = false;
|
|
5674
5784
|
void loadConnectorStatuses(definitions, tenantId2).then((list) => {
|
|
5675
5785
|
if (!cancelled) setInstalled(list);
|
|
@@ -5678,7 +5788,7 @@ function useConnectors(options = {}) {
|
|
|
5678
5788
|
cancelled = true;
|
|
5679
5789
|
};
|
|
5680
5790
|
}, [definitions, tenantId2, nonce]);
|
|
5681
|
-
|
|
5791
|
+
React132__default.useEffect(() => {
|
|
5682
5792
|
if (!includeGrants || !connection || !tenantId2) {
|
|
5683
5793
|
setGrants(includeGrants ? null : []);
|
|
5684
5794
|
return;
|
|
@@ -5702,7 +5812,7 @@ function useConnectors(options = {}) {
|
|
|
5702
5812
|
cancelled = true;
|
|
5703
5813
|
};
|
|
5704
5814
|
}, [call2, tenantId2, includeGrants, connection, nonce]);
|
|
5705
|
-
const revokeGrant =
|
|
5815
|
+
const revokeGrant = React132__default.useCallback(
|
|
5706
5816
|
async (connector) => {
|
|
5707
5817
|
const response = await call2(`/${connector.id}`, { method: "DELETE" });
|
|
5708
5818
|
if (!response.ok) {
|
|
@@ -5715,7 +5825,7 @@ function useConnectors(options = {}) {
|
|
|
5715
5825
|
[call2]
|
|
5716
5826
|
);
|
|
5717
5827
|
const waitingGrants = includeGrants && !!connection && !!tenantId2 && grants === null;
|
|
5718
|
-
const connectors =
|
|
5828
|
+
const connectors = React132__default.useMemo(() => {
|
|
5719
5829
|
if (installed === null || waitingGrants) return null;
|
|
5720
5830
|
return buildConnectorList({
|
|
5721
5831
|
installed,
|
|
@@ -5956,9 +6066,9 @@ function ConnectorMark({
|
|
|
5956
6066
|
connector,
|
|
5957
6067
|
size = "md"
|
|
5958
6068
|
}) {
|
|
5959
|
-
const candidates =
|
|
5960
|
-
const [attempt, setAttempt] =
|
|
5961
|
-
|
|
6069
|
+
const candidates = React132__default.useMemo(() => markCandidates(connector), [connector.logoUrl, connector.name]);
|
|
6070
|
+
const [attempt, setAttempt] = React132__default.useState(0);
|
|
6071
|
+
React132__default.useEffect(() => setAttempt(0), [connector.id]);
|
|
5962
6072
|
const box = size === "sm" ? "h-9 w-9" : "h-10 w-10";
|
|
5963
6073
|
const glyph = size === "sm" ? "h-4 w-4" : "h-5 w-5";
|
|
5964
6074
|
if (connector.builtIn) {
|
|
@@ -7594,9 +7704,9 @@ function prefersReducedMotion2() {
|
|
|
7594
7704
|
return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
7595
7705
|
}
|
|
7596
7706
|
function TypewriterText({ text: text2, speed = 26, onDone }) {
|
|
7597
|
-
const [displayed, setDisplayed] =
|
|
7598
|
-
const indexRef =
|
|
7599
|
-
|
|
7707
|
+
const [displayed, setDisplayed] = React132.useState("");
|
|
7708
|
+
const indexRef = React132.useRef(0);
|
|
7709
|
+
React132.useEffect(() => {
|
|
7600
7710
|
if (prefersReducedMotion2()) {
|
|
7601
7711
|
setDisplayed(text2);
|
|
7602
7712
|
onDone?.();
|
|
@@ -7673,16 +7783,16 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7673
7783
|
const { contextualSuggestions } = useAITools();
|
|
7674
7784
|
const { sendMessage } = useChat({ apiEndpoint, systemPrompt, agent });
|
|
7675
7785
|
const { t } = useTranslation$1();
|
|
7676
|
-
const [phase, setPhase] =
|
|
7677
|
-
const [activeSuggestion, setActiveSuggestion] =
|
|
7678
|
-
const timersRef =
|
|
7679
|
-
const prevSuggestionRef =
|
|
7680
|
-
const [greeting, setGreeting] =
|
|
7681
|
-
const greetTimerRef =
|
|
7682
|
-
|
|
7786
|
+
const [phase, setPhase] = React132.useState("idle");
|
|
7787
|
+
const [activeSuggestion, setActiveSuggestion] = React132.useState(null);
|
|
7788
|
+
const timersRef = React132.useRef([]);
|
|
7789
|
+
const prevSuggestionRef = React132.useRef(null);
|
|
7790
|
+
const [greeting, setGreeting] = React132.useState(false);
|
|
7791
|
+
const greetTimerRef = React132.useRef(0);
|
|
7792
|
+
React132.useEffect(() => () => window.clearTimeout(greetTimerRef.current), []);
|
|
7683
7793
|
const hasFace = !!host?.AvatarComponent;
|
|
7684
|
-
|
|
7685
|
-
|
|
7794
|
+
React132.useEffect(ensureStyles, []);
|
|
7795
|
+
React132.useEffect(() => {
|
|
7686
7796
|
document.documentElement.classList.add("fz-has-fab");
|
|
7687
7797
|
return () => document.documentElement.classList.remove("fz-has-fab");
|
|
7688
7798
|
}, []);
|
|
@@ -7698,10 +7808,10 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7698
7808
|
const invited = useAssistantInviteStore((s) => !!s.invite && s.stage === "dock");
|
|
7699
7809
|
const dockOnScreen = useAssistantInviteStore((s) => !!s.dockBox);
|
|
7700
7810
|
const morphingBack = useAssistantInviteStore((s) => !!s.leaving);
|
|
7701
|
-
const [wide, setWide] =
|
|
7811
|
+
const [wide, setWide] = React132.useState(
|
|
7702
7812
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
7703
7813
|
);
|
|
7704
|
-
|
|
7814
|
+
React132.useEffect(() => {
|
|
7705
7815
|
const query = window.matchMedia?.("(min-width: 768px)");
|
|
7706
7816
|
if (!query) return;
|
|
7707
7817
|
const sync = () => setWide(query.matches);
|
|
@@ -7710,7 +7820,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7710
7820
|
return () => query.removeEventListener("change", sync);
|
|
7711
7821
|
}, []);
|
|
7712
7822
|
const teaserAllowed = !hasMessages && !activity && !invited && !teaserDismissed() && teaserShownCount() < TEASER_MAX_PER_SESSION;
|
|
7713
|
-
|
|
7823
|
+
React132.useEffect(() => {
|
|
7714
7824
|
if (expanded || !topSuggestion || !topLabel || !teaserAllowed || teaserSeen().includes(topLabel)) {
|
|
7715
7825
|
if (phase !== "idle") {
|
|
7716
7826
|
clearTimers();
|
|
@@ -7741,14 +7851,14 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7741
7851
|
}, 9e3);
|
|
7742
7852
|
return clearTimers;
|
|
7743
7853
|
}, [topLabel, expanded, teaserAllowed]);
|
|
7744
|
-
|
|
7854
|
+
React132.useEffect(() => {
|
|
7745
7855
|
if (expanded && phase !== "idle") {
|
|
7746
7856
|
clearTimers();
|
|
7747
7857
|
setPhase("idle");
|
|
7748
7858
|
}
|
|
7749
7859
|
}, [expanded]);
|
|
7750
|
-
const [entrance, setEntrance] =
|
|
7751
|
-
|
|
7860
|
+
const [entrance, setEntrance] = React132.useState("pending");
|
|
7861
|
+
React132.useEffect(() => {
|
|
7752
7862
|
if (!currentOrg || entrance !== "pending") return;
|
|
7753
7863
|
if (prefersReducedMotion2()) {
|
|
7754
7864
|
setEntrance("done");
|
|
@@ -7758,9 +7868,9 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7758
7868
|
const timer = setTimeout(() => setEntrance("done"), 1600);
|
|
7759
7869
|
return () => clearTimeout(timer);
|
|
7760
7870
|
}, [currentOrg, entrance]);
|
|
7761
|
-
const [poppingBack, setPoppingBack] =
|
|
7762
|
-
const wasMorphing =
|
|
7763
|
-
|
|
7871
|
+
const [poppingBack, setPoppingBack] = React132.useState(false);
|
|
7872
|
+
const wasMorphing = React132.useRef(false);
|
|
7873
|
+
React132.useEffect(() => {
|
|
7764
7874
|
const was = wasMorphing.current;
|
|
7765
7875
|
wasMorphing.current = morphingBack;
|
|
7766
7876
|
if (!was || morphingBack || prefersReducedMotion2()) return;
|
|
@@ -8058,7 +8168,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
8058
8168
|
var MAX_SUGGESTIONS = 5;
|
|
8059
8169
|
function ChatSuggestions({ suggestions, onSelect, onDismiss, compact }) {
|
|
8060
8170
|
const { t } = useTranslation$1();
|
|
8061
|
-
const [open, setOpen] =
|
|
8171
|
+
const [open, setOpen] = React132.useState(true);
|
|
8062
8172
|
const visible = suggestions.slice(0, compact ? 3 : MAX_SUGGESTIONS);
|
|
8063
8173
|
if (!visible.length) return null;
|
|
8064
8174
|
return /* @__PURE__ */ jsxs(
|
|
@@ -8137,8 +8247,8 @@ function SuggestionRow({
|
|
|
8137
8247
|
detail,
|
|
8138
8248
|
onSelect
|
|
8139
8249
|
}) {
|
|
8140
|
-
const labelRef =
|
|
8141
|
-
const [showDetail, setShowDetail] =
|
|
8250
|
+
const labelRef = React132.useRef(null);
|
|
8251
|
+
const [showDetail, setShowDetail] = React132.useState(false);
|
|
8142
8252
|
const evaluate = () => {
|
|
8143
8253
|
const el = labelRef.current;
|
|
8144
8254
|
const clipped = !!el && el.scrollWidth > el.clientWidth + 1;
|
|
@@ -8232,8 +8342,8 @@ function ChatToolsPanel({ toolGroups, onClose }) {
|
|
|
8232
8342
|
}
|
|
8233
8343
|
function AutoApprovalsSection() {
|
|
8234
8344
|
const { t } = useTranslation$1();
|
|
8235
|
-
const [rules, setRules] =
|
|
8236
|
-
|
|
8345
|
+
const [rules, setRules] = React132.useState(() => listAutoApprovals());
|
|
8346
|
+
React132.useEffect(() => subscribeAutoApprovals(() => setRules(listAutoApprovals())), []);
|
|
8237
8347
|
if (!rules.length) return null;
|
|
8238
8348
|
return /* @__PURE__ */ jsxs("div", { className: "border-b border-border/40 px-3 py-2.5", children: [
|
|
8239
8349
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 px-1 pb-1.5", children: [
|
|
@@ -8286,14 +8396,14 @@ function bucketOf(iso) {
|
|
|
8286
8396
|
var ORDER = ["today", "yesterday", "week", "older"];
|
|
8287
8397
|
function ChatHistory({ conversations, activeId, onSelect }) {
|
|
8288
8398
|
const { t } = useTranslation$1();
|
|
8289
|
-
const [query, setQuery] =
|
|
8399
|
+
const [query, setQuery] = React132.useState("");
|
|
8290
8400
|
const mine = conversations;
|
|
8291
|
-
const filtered =
|
|
8401
|
+
const filtered = React132.useMemo(() => {
|
|
8292
8402
|
const needle = query.trim().toLowerCase();
|
|
8293
8403
|
if (!needle) return mine;
|
|
8294
8404
|
return mine.filter((c) => (c.title ?? "").toLowerCase().includes(needle));
|
|
8295
8405
|
}, [mine, query]);
|
|
8296
|
-
const groups =
|
|
8406
|
+
const groups = React132.useMemo(() => {
|
|
8297
8407
|
const map = /* @__PURE__ */ new Map();
|
|
8298
8408
|
for (const conversation of filtered) {
|
|
8299
8409
|
const bucket = bucketOf(conversation.updatedAt);
|
|
@@ -8420,7 +8530,7 @@ function TourCoachCard() {
|
|
|
8420
8530
|
const lastOutcome = useTourStore((s) => s.lastOutcome);
|
|
8421
8531
|
const stop = useTourStore((s) => s.stop);
|
|
8422
8532
|
const restart = useTourStore((s) => s.restart);
|
|
8423
|
-
const [dismissedId, setDismissedId] =
|
|
8533
|
+
const [dismissedId, setDismissedId] = React132.useState(null);
|
|
8424
8534
|
const pTitle = usePracticeStore((s) => s.title);
|
|
8425
8535
|
const pSteps = usePracticeStore((s) => s.steps);
|
|
8426
8536
|
const pDone = usePracticeStore((s) => s.done);
|
|
@@ -8491,8 +8601,8 @@ function AssistantRecordingView({ activity }) {
|
|
|
8491
8601
|
const live = activity.state === "running" || activity.state === "paused";
|
|
8492
8602
|
const running = activity.state === "running";
|
|
8493
8603
|
const actions = activity.actions ?? [];
|
|
8494
|
-
const [acknowledged, setAcknowledged] =
|
|
8495
|
-
|
|
8604
|
+
const [acknowledged, setAcknowledged] = React132.useState(false);
|
|
8605
|
+
React132.useEffect(() => setAcknowledged(false), [activity.id, activity.state]);
|
|
8496
8606
|
const withheld = pending2 && !!activity.confirm && !acknowledged;
|
|
8497
8607
|
const primary = actions.filter((a) => a.intent !== "discard");
|
|
8498
8608
|
const discard = actions.find((a) => a.intent === "discard");
|
|
@@ -8708,10 +8818,10 @@ function RightRailPage({
|
|
|
8708
8818
|
const closePage = useRightRailStore((s) => s.closePage);
|
|
8709
8819
|
const active2 = hosted && open;
|
|
8710
8820
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
8711
|
-
const onCloseRef =
|
|
8821
|
+
const onCloseRef = React132.useRef(onClose);
|
|
8712
8822
|
onCloseRef.current = onClose;
|
|
8713
|
-
const claimed =
|
|
8714
|
-
|
|
8823
|
+
const claimed = React132.useRef(false);
|
|
8824
|
+
React132.useEffect(() => {
|
|
8715
8825
|
if (!active2) return;
|
|
8716
8826
|
showPage();
|
|
8717
8827
|
claimed.current = true;
|
|
@@ -8720,7 +8830,7 @@ function RightRailPage({
|
|
|
8720
8830
|
closePage();
|
|
8721
8831
|
};
|
|
8722
8832
|
}, [active2, showPage, closePage]);
|
|
8723
|
-
|
|
8833
|
+
React132.useEffect(() => {
|
|
8724
8834
|
if (!claimed.current) return;
|
|
8725
8835
|
if (!useRightRailStore.getState().pageOpen) onCloseRef.current();
|
|
8726
8836
|
}, [pageOpen]);
|
|
@@ -8923,15 +9033,15 @@ function ConnectorSyncActions({
|
|
|
8923
9033
|
actions,
|
|
8924
9034
|
onRan
|
|
8925
9035
|
}) {
|
|
8926
|
-
const [running, setRunning] =
|
|
8927
|
-
const [open, setOpen] =
|
|
8928
|
-
const [pending2, setPending] =
|
|
8929
|
-
const [hidden, setHidden] =
|
|
8930
|
-
const [queued, setQueued] =
|
|
8931
|
-
const [nonce, setNonce] =
|
|
8932
|
-
const [expanded, setExpanded] =
|
|
8933
|
-
const [resolved, setResolved] =
|
|
8934
|
-
|
|
9036
|
+
const [running, setRunning] = React132__default.useState(null);
|
|
9037
|
+
const [open, setOpen] = React132__default.useState(null);
|
|
9038
|
+
const [pending2, setPending] = React132__default.useState(null);
|
|
9039
|
+
const [hidden, setHidden] = React132__default.useState(() => /* @__PURE__ */ new Set());
|
|
9040
|
+
const [queued, setQueued] = React132__default.useState({});
|
|
9041
|
+
const [nonce, setNonce] = React132__default.useState(0);
|
|
9042
|
+
const [expanded, setExpanded] = React132__default.useState(false);
|
|
9043
|
+
const [resolved, setResolved] = React132__default.useState(false);
|
|
9044
|
+
React132__default.useEffect(() => {
|
|
8935
9045
|
let cancelled = false;
|
|
8936
9046
|
setResolved(false);
|
|
8937
9047
|
void Promise.all(
|
|
@@ -9116,10 +9226,10 @@ function formatRelative(iso, t) {
|
|
|
9116
9226
|
}
|
|
9117
9227
|
function useConnectorRuns(connector) {
|
|
9118
9228
|
const listRuns = connector.definition?.listRuns;
|
|
9119
|
-
const [runs, setRuns] =
|
|
9120
|
-
const [loading, setLoading] =
|
|
9121
|
-
const [nonce, setNonce] =
|
|
9122
|
-
|
|
9229
|
+
const [runs, setRuns] = React132__default.useState([]);
|
|
9230
|
+
const [loading, setLoading] = React132__default.useState(!!listRuns);
|
|
9231
|
+
const [nonce, setNonce] = React132__default.useState(0);
|
|
9232
|
+
React132__default.useEffect(() => {
|
|
9123
9233
|
if (!listRuns) {
|
|
9124
9234
|
setRuns([]);
|
|
9125
9235
|
setLoading(false);
|
|
@@ -9141,7 +9251,7 @@ function useConnectorRuns(connector) {
|
|
|
9141
9251
|
return {
|
|
9142
9252
|
runs,
|
|
9143
9253
|
loading,
|
|
9144
|
-
reload:
|
|
9254
|
+
reload: React132__default.useCallback(() => setNonce((n) => n + 1), []),
|
|
9145
9255
|
failing: isFailing(runs)
|
|
9146
9256
|
};
|
|
9147
9257
|
}
|
|
@@ -9164,12 +9274,12 @@ function ConnectorRuns({
|
|
|
9164
9274
|
}) {
|
|
9165
9275
|
const { t } = useTranslation$1();
|
|
9166
9276
|
const def = connector.definition;
|
|
9167
|
-
const { runs, loading, reload } = state;
|
|
9277
|
+
const { runs, loading, reload: reload2 } = state;
|
|
9168
9278
|
const firstLoad = def?.firstLoad;
|
|
9169
9279
|
const backfilling = !!firstLoad && runs.some((r) => r.status === "running");
|
|
9170
9280
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
9171
|
-
def?.syncActions?.length ? /* @__PURE__ */ jsx(ConnectorSyncActions, { actions: def.syncActions, onRan:
|
|
9172
|
-
def?.RunActions && /* @__PURE__ */ jsx(def.RunActions, { onRan:
|
|
9281
|
+
def?.syncActions?.length ? /* @__PURE__ */ jsx(ConnectorSyncActions, { actions: def.syncActions, onRan: reload2 }) : null,
|
|
9282
|
+
def?.RunActions && /* @__PURE__ */ jsx(def.RunActions, { onRan: reload2 }),
|
|
9173
9283
|
backfilling && /* @__PURE__ */ jsxs("p", { className: "flex items-start gap-2 text-xs text-muted-foreground", children: [
|
|
9174
9284
|
/* @__PURE__ */ jsx(Loader2, { className: "mt-px h-3.5 w-3.5 shrink-0 animate-spin" }),
|
|
9175
9285
|
/* @__PURE__ */ jsx("span", { children: t("connectors.runs.backfilling") })
|
|
@@ -9241,7 +9351,7 @@ function RunFailure({ run }) {
|
|
|
9241
9351
|
),
|
|
9242
9352
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t("connectors.runs.seeDetails") })
|
|
9243
9353
|
] }),
|
|
9244
|
-
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(([label3, value]) => /* @__PURE__ */ jsxs(
|
|
9354
|
+
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(([label3, value]) => /* @__PURE__ */ jsxs(React132__default.Fragment, { children: [
|
|
9245
9355
|
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: label3 }),
|
|
9246
9356
|
/* @__PURE__ */ jsx("dd", { className: "min-w-0 break-words font-mono text-foreground/80", children: value })
|
|
9247
9357
|
] }, label3)) }),
|
|
@@ -9410,13 +9520,13 @@ function ConnectorSettingsPanel({
|
|
|
9410
9520
|
const { t } = useTranslation$1();
|
|
9411
9521
|
const def = connector.definition;
|
|
9412
9522
|
const settings = def ? connectorSettings(def) : [];
|
|
9413
|
-
const [values, setValues] =
|
|
9523
|
+
const [values, setValues] = React132__default.useState(
|
|
9414
9524
|
() => initialValues(settings, {})
|
|
9415
9525
|
);
|
|
9416
|
-
const [loaded2, setLoaded] =
|
|
9417
|
-
const [saving, setSaving] =
|
|
9418
|
-
const [dirty, setDirty] =
|
|
9419
|
-
|
|
9526
|
+
const [loaded2, setLoaded] = React132__default.useState(false);
|
|
9527
|
+
const [saving, setSaving] = React132__default.useState(false);
|
|
9528
|
+
const [dirty, setDirty] = React132__default.useState(false);
|
|
9529
|
+
React132__default.useEffect(() => {
|
|
9420
9530
|
if (settings.length === 0 || !def?.getSettings) return;
|
|
9421
9531
|
let cancelled = false;
|
|
9422
9532
|
setLoaded(false);
|
|
@@ -9667,13 +9777,13 @@ function ConnectorInstall({
|
|
|
9667
9777
|
}) {
|
|
9668
9778
|
const { t } = useTranslation$1();
|
|
9669
9779
|
const def = connector.definition;
|
|
9670
|
-
const [plane, setPlane] =
|
|
9780
|
+
const [plane, setPlane] = React132__default.useState(
|
|
9671
9781
|
connector.planes.includes("agentic") ? "agentic" : connector.planes[0]
|
|
9672
9782
|
);
|
|
9673
|
-
const [values, setValues] =
|
|
9674
|
-
const secrets =
|
|
9675
|
-
const [busy, setBusy] =
|
|
9676
|
-
|
|
9783
|
+
const [values, setValues] = React132__default.useState({});
|
|
9784
|
+
const secrets = React132__default.useRef({});
|
|
9785
|
+
const [busy, setBusy] = React132__default.useState(null);
|
|
9786
|
+
React132__default.useEffect(() => {
|
|
9677
9787
|
setValues({});
|
|
9678
9788
|
secrets.current = {};
|
|
9679
9789
|
setBusy(null);
|
|
@@ -9714,15 +9824,15 @@ function ConnectorHome({
|
|
|
9714
9824
|
const needsSetup = connector.state === "needs_setup";
|
|
9715
9825
|
const settingsAvailable = hasOperatingSettings(connector);
|
|
9716
9826
|
const runsAvailable = hasRunHistory(connector);
|
|
9717
|
-
const [tab, setTab] =
|
|
9827
|
+
const [tab, setTab] = React132__default.useState(
|
|
9718
9828
|
needsSetup && settingsAvailable ? "settings" : "overview"
|
|
9719
9829
|
);
|
|
9720
|
-
const [busy, setBusy] =
|
|
9830
|
+
const [busy, setBusy] = React132__default.useState(null);
|
|
9721
9831
|
const run = useRunner(setBusy, onChanged);
|
|
9722
|
-
const [values, setValues] =
|
|
9723
|
-
const secrets =
|
|
9832
|
+
const [values, setValues] = React132__default.useState({});
|
|
9833
|
+
const secrets = React132__default.useRef({});
|
|
9724
9834
|
const runs = useConnectorRuns(connector);
|
|
9725
|
-
|
|
9835
|
+
React132__default.useEffect(() => {
|
|
9726
9836
|
setTab(needsSetup && settingsAvailable ? "settings" : "overview");
|
|
9727
9837
|
setBusy(null);
|
|
9728
9838
|
setValues({});
|
|
@@ -9812,7 +9922,7 @@ function ConnectorHome({
|
|
|
9812
9922
|
}
|
|
9813
9923
|
function useRunner(setBusy, onChanged) {
|
|
9814
9924
|
const { t } = useTranslation$1();
|
|
9815
|
-
return
|
|
9925
|
+
return React132__default.useCallback(
|
|
9816
9926
|
async (kind, fn, okMessage) => {
|
|
9817
9927
|
setBusy(kind);
|
|
9818
9928
|
try {
|
|
@@ -9928,7 +10038,7 @@ function ConnectPanel({
|
|
|
9928
10038
|
const sinkMissing = needsSink && !getConnectorCredentialSink();
|
|
9929
10039
|
const secretFieldCount = (def.fields ?? []).filter(isSecretField).length;
|
|
9930
10040
|
const hasStoredCredential = connector.state === "connected" || connector.state === "needs_setup";
|
|
9931
|
-
const [formKey, setFormKey] =
|
|
10041
|
+
const [formKey, setFormKey] = React132__default.useState(0);
|
|
9932
10042
|
if (def.authKind === "oauth") {
|
|
9933
10043
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
9934
10044
|
/* @__PURE__ */ jsx(Note, { children: t("connectors.authorize.oauthOnly") }),
|
|
@@ -10061,7 +10171,7 @@ function GrantRevoke({
|
|
|
10061
10171
|
onRevoke
|
|
10062
10172
|
}) {
|
|
10063
10173
|
const { t } = useTranslation$1();
|
|
10064
|
-
const [revoking, setRevoking] =
|
|
10174
|
+
const [revoking, setRevoking] = React132__default.useState(false);
|
|
10065
10175
|
if (connector.revocable === false) {
|
|
10066
10176
|
return /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("connectors.partOfApp") });
|
|
10067
10177
|
}
|
|
@@ -10097,17 +10207,17 @@ function useConnectorsPanelAvailable() {
|
|
|
10097
10207
|
}
|
|
10098
10208
|
function ConnectorsPanel({ onClose }) {
|
|
10099
10209
|
const { t } = useTranslation$1();
|
|
10100
|
-
const { connectors, reload, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
10210
|
+
const { connectors, reload: reload2, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
10101
10211
|
const selectedId = useConnectorsSurface((s) => s.selected);
|
|
10102
10212
|
const select = useConnectorsSurface((s) => s.select);
|
|
10103
|
-
const [query, setQuery] =
|
|
10104
|
-
const [failure, setFailure] =
|
|
10105
|
-
const [revoking, setRevoking] =
|
|
10106
|
-
const selected =
|
|
10213
|
+
const [query, setQuery] = React132__default.useState("");
|
|
10214
|
+
const [failure, setFailure] = React132__default.useState(null);
|
|
10215
|
+
const [revoking, setRevoking] = React132__default.useState(null);
|
|
10216
|
+
const selected = React132__default.useMemo(
|
|
10107
10217
|
() => (connectors ?? []).find((c) => c.id === selectedId) ?? null,
|
|
10108
10218
|
[connectors, selectedId]
|
|
10109
10219
|
);
|
|
10110
|
-
const filtered =
|
|
10220
|
+
const filtered = React132__default.useMemo(
|
|
10111
10221
|
() => filterConnectors(connectors ?? [], "outbound", query),
|
|
10112
10222
|
[connectors, query]
|
|
10113
10223
|
);
|
|
@@ -10118,9 +10228,9 @@ function ConnectorsPanel({ onClose }) {
|
|
|
10118
10228
|
back: onClose
|
|
10119
10229
|
} : null
|
|
10120
10230
|
);
|
|
10121
|
-
const closeRef =
|
|
10231
|
+
const closeRef = React132__default.useRef(onClose);
|
|
10122
10232
|
closeRef.current = onClose;
|
|
10123
|
-
|
|
10233
|
+
React132__default.useEffect(() => {
|
|
10124
10234
|
if (hosted && !selectedId) closeRef.current();
|
|
10125
10235
|
}, [hosted, selectedId]);
|
|
10126
10236
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [
|
|
@@ -10152,7 +10262,7 @@ function ConnectorsPanel({ onClose }) {
|
|
|
10152
10262
|
ConnectorJourney,
|
|
10153
10263
|
{
|
|
10154
10264
|
connector: selected,
|
|
10155
|
-
onChanged:
|
|
10265
|
+
onChanged: reload2,
|
|
10156
10266
|
onRevoke: (connector) => setRevoking(connector)
|
|
10157
10267
|
}
|
|
10158
10268
|
),
|
|
@@ -10248,20 +10358,20 @@ function useDictation({
|
|
|
10248
10358
|
onInterim
|
|
10249
10359
|
}) {
|
|
10250
10360
|
const resolvedLocale = locale ?? (typeof navigator !== "undefined" ? navigator.language || "pt-BR" : "pt-BR");
|
|
10251
|
-
const [state, setState] =
|
|
10252
|
-
const [error, setError] =
|
|
10253
|
-
const sessionRef =
|
|
10254
|
-
const callbacks =
|
|
10361
|
+
const [state, setState] = React132.useState("idle");
|
|
10362
|
+
const [error, setError] = React132.useState(null);
|
|
10363
|
+
const sessionRef = React132.useRef(null);
|
|
10364
|
+
const callbacks = React132.useRef({ onTranscript, onInterim });
|
|
10255
10365
|
callbacks.current = { onTranscript, onInterim };
|
|
10256
|
-
const supported =
|
|
10366
|
+
const supported = React132.useMemo(
|
|
10257
10367
|
() => isDictationSupported(!!transcribeEndpoint),
|
|
10258
10368
|
[transcribeEndpoint]
|
|
10259
10369
|
);
|
|
10260
|
-
const finish =
|
|
10370
|
+
const finish = React132.useCallback(() => {
|
|
10261
10371
|
sessionRef.current = null;
|
|
10262
10372
|
setState("idle");
|
|
10263
10373
|
}, []);
|
|
10264
|
-
const start =
|
|
10374
|
+
const start = React132.useCallback(() => {
|
|
10265
10375
|
if (sessionRef.current || !supported) return;
|
|
10266
10376
|
stopSpeaking();
|
|
10267
10377
|
setError(null);
|
|
@@ -10282,28 +10392,28 @@ function useDictation({
|
|
|
10282
10392
|
}
|
|
10283
10393
|
);
|
|
10284
10394
|
}, [finish, resolvedLocale, supported, transcribeEndpoint]);
|
|
10285
|
-
const stop =
|
|
10395
|
+
const stop = React132.useCallback(() => {
|
|
10286
10396
|
if (!sessionRef.current) return;
|
|
10287
10397
|
if (transcribeEndpoint) setState("transcribing");
|
|
10288
10398
|
sessionRef.current.stop();
|
|
10289
10399
|
}, [transcribeEndpoint]);
|
|
10290
|
-
const cancel =
|
|
10400
|
+
const cancel = React132.useCallback(() => {
|
|
10291
10401
|
sessionRef.current?.cancel();
|
|
10292
10402
|
sessionRef.current = null;
|
|
10293
10403
|
setState("idle");
|
|
10294
10404
|
setError(null);
|
|
10295
10405
|
}, []);
|
|
10296
|
-
const toggle =
|
|
10406
|
+
const toggle = React132.useCallback(() => {
|
|
10297
10407
|
if (state === "listening" || state === "transcribing") stop();
|
|
10298
10408
|
else start();
|
|
10299
10409
|
}, [state, start, stop]);
|
|
10300
|
-
|
|
10410
|
+
React132.useEffect(() => () => sessionRef.current?.cancel(), []);
|
|
10301
10411
|
return { supported, state, error, start, stop, cancel, toggle, clearError: () => setError(null) };
|
|
10302
10412
|
}
|
|
10303
10413
|
function useMicLevels(active2, bandCount = 28, externalStream) {
|
|
10304
|
-
const levelsRef =
|
|
10305
|
-
const [available, setAvailable] =
|
|
10306
|
-
|
|
10414
|
+
const levelsRef = React132.useRef(new Float32Array(bandCount));
|
|
10415
|
+
const [available, setAvailable] = React132.useState(false);
|
|
10416
|
+
React132.useEffect(() => {
|
|
10307
10417
|
if (!active2) {
|
|
10308
10418
|
levelsRef.current.fill(0);
|
|
10309
10419
|
setAvailable(false);
|
|
@@ -10372,8 +10482,8 @@ var KIND_ICON = {
|
|
|
10372
10482
|
binary: File$1
|
|
10373
10483
|
};
|
|
10374
10484
|
function useFileDrop(enabled, onFiles) {
|
|
10375
|
-
const [dragging, setDragging] =
|
|
10376
|
-
const depth =
|
|
10485
|
+
const [dragging, setDragging] = React132.useState(false);
|
|
10486
|
+
const depth = React132.useRef(0);
|
|
10377
10487
|
const carriesFiles = (event) => Array.from(event.dataTransfer?.types ?? []).includes("Files");
|
|
10378
10488
|
const reset = () => {
|
|
10379
10489
|
depth.current = 0;
|
|
@@ -10433,7 +10543,7 @@ function AttachmentChips({
|
|
|
10433
10543
|
onRemove
|
|
10434
10544
|
}) {
|
|
10435
10545
|
const { t } = useTranslation$1();
|
|
10436
|
-
const [openId, setOpenId] =
|
|
10546
|
+
const [openId, setOpenId] = React132.useState(null);
|
|
10437
10547
|
if (!attachments.length) return null;
|
|
10438
10548
|
const opened = attachments.find((a) => a.id === openId);
|
|
10439
10549
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -10574,8 +10684,8 @@ function ChatComposer({
|
|
|
10574
10684
|
autoFocus
|
|
10575
10685
|
}) {
|
|
10576
10686
|
const { t } = useTranslation$1();
|
|
10577
|
-
const [input, setInput] =
|
|
10578
|
-
const textareaRef =
|
|
10687
|
+
const [input, setInput] = React132.useState("");
|
|
10688
|
+
const textareaRef = React132.useRef(null);
|
|
10579
10689
|
const voiceStartRequested = useChatStore((s) => s.voiceStartRequested);
|
|
10580
10690
|
const consumeVoiceStart = useChatStore((s) => s.consumeVoiceStart);
|
|
10581
10691
|
const draft = useChatStore((s) => s.draft);
|
|
@@ -10588,13 +10698,13 @@ function ChatComposer({
|
|
|
10588
10698
|
const removeAttachment = useChatStore((s) => s.removeAttachment);
|
|
10589
10699
|
const composerMedia = useChatStore((s) => s.composerMedia);
|
|
10590
10700
|
const clearComposerMedia = useChatStore((s) => s.clearComposerMedia);
|
|
10591
|
-
const fileInputRef =
|
|
10701
|
+
const fileInputRef = React132.useRef(null);
|
|
10592
10702
|
const autoSend = voice?.autoSend === true;
|
|
10593
10703
|
const micEnabled = voice?.input !== false;
|
|
10594
10704
|
const canAttach = isConfigured && !blocked && !isStreaming;
|
|
10595
10705
|
const parsing = attachments.some((a) => a.status === "parsing");
|
|
10596
10706
|
const readyAttachments = attachments.filter((a) => a.status === "ready").length;
|
|
10597
|
-
const submit =
|
|
10707
|
+
const submit = React132.useCallback(
|
|
10598
10708
|
(text2) => {
|
|
10599
10709
|
const trimmed = text2.trim();
|
|
10600
10710
|
const media = useChatStore.getState().composerMedia;
|
|
@@ -10624,7 +10734,7 @@ function ChatComposer({
|
|
|
10624
10734
|
}
|
|
10625
10735
|
}
|
|
10626
10736
|
});
|
|
10627
|
-
|
|
10737
|
+
React132.useEffect(() => {
|
|
10628
10738
|
if (!autoFocus) return;
|
|
10629
10739
|
const id = requestAnimationFrame(() => textareaRef.current?.focus());
|
|
10630
10740
|
return () => cancelAnimationFrame(id);
|
|
@@ -10636,7 +10746,7 @@ function ChatComposer({
|
|
|
10636
10746
|
const WAVEFORM_BANDS = 56;
|
|
10637
10747
|
const activity = useAssistantActivity();
|
|
10638
10748
|
const sessionRecording = activity?.kind === "recording" && activity.state === "running";
|
|
10639
|
-
const sessionStream =
|
|
10749
|
+
const sessionStream = React132.useMemo(
|
|
10640
10750
|
() => sessionRecording ? activity?.stream?.() ?? null : null,
|
|
10641
10751
|
[sessionRecording, activity]
|
|
10642
10752
|
);
|
|
@@ -10648,12 +10758,12 @@ function ChatComposer({
|
|
|
10648
10758
|
);
|
|
10649
10759
|
const sessionPause = activity?.actions?.find((a) => a.intent === "pause" || a.intent === "resume");
|
|
10650
10760
|
const sessionOwnsMic = activity?.kind === "recording" && (activity.state === "running" || activity.state === "paused");
|
|
10651
|
-
|
|
10761
|
+
React132.useEffect(() => {
|
|
10652
10762
|
if (!voiceStartRequested) return;
|
|
10653
10763
|
consumeVoiceStart();
|
|
10654
10764
|
if (showMic) dictation.start();
|
|
10655
10765
|
}, [voiceStartRequested, showMic]);
|
|
10656
|
-
|
|
10766
|
+
React132.useEffect(() => {
|
|
10657
10767
|
if (!focusRequested) return;
|
|
10658
10768
|
let frames = 0;
|
|
10659
10769
|
let raf = 0;
|
|
@@ -10670,7 +10780,7 @@ function ChatComposer({
|
|
|
10670
10780
|
raf = requestAnimationFrame(tick);
|
|
10671
10781
|
return () => cancelAnimationFrame(raf);
|
|
10672
10782
|
}, [focusRequested, consumeComposerFocus]);
|
|
10673
|
-
|
|
10783
|
+
React132.useEffect(() => {
|
|
10674
10784
|
if (!draft) return;
|
|
10675
10785
|
setInput(draft);
|
|
10676
10786
|
setDraft("");
|
|
@@ -10680,7 +10790,7 @@ function ChatComposer({
|
|
|
10680
10790
|
el.setSelectionRange(draft.length, draft.length);
|
|
10681
10791
|
}
|
|
10682
10792
|
}, [draft, setDraft]);
|
|
10683
|
-
|
|
10793
|
+
React132.useLayoutEffect(() => {
|
|
10684
10794
|
const el = textareaRef.current;
|
|
10685
10795
|
if (!el) return;
|
|
10686
10796
|
const style = getComputedStyle(el);
|
|
@@ -10883,8 +10993,8 @@ function UploadRequestCard() {
|
|
|
10883
10993
|
const removeUploadFile = useChatStore((s) => s.removeUploadFile);
|
|
10884
10994
|
const submitUpload = useChatStore((s) => s.submitUpload);
|
|
10885
10995
|
const clearUploadRequest = useChatStore((s) => s.clearUploadRequest);
|
|
10886
|
-
const cameraRef =
|
|
10887
|
-
const browseRef =
|
|
10996
|
+
const cameraRef = React132.useRef(null);
|
|
10997
|
+
const browseRef = React132.useRef(null);
|
|
10888
10998
|
if (!request) return null;
|
|
10889
10999
|
const working = request.status === "working";
|
|
10890
11000
|
const accept = request.accept ?? "image/*";
|
|
@@ -11026,8 +11136,8 @@ function LiveWaveform({
|
|
|
11026
11136
|
compact,
|
|
11027
11137
|
tone = "primary"
|
|
11028
11138
|
}) {
|
|
11029
|
-
const barsRef =
|
|
11030
|
-
|
|
11139
|
+
const barsRef = React132.useRef([]);
|
|
11140
|
+
React132.useEffect(() => {
|
|
11031
11141
|
if (!live) return;
|
|
11032
11142
|
let frame = 0;
|
|
11033
11143
|
const draw = () => {
|
|
@@ -11176,7 +11286,7 @@ function ChatMarkdown({ content }) {
|
|
|
11176
11286
|
}
|
|
11177
11287
|
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}`);
|
|
11178
11288
|
const prev = items.pop();
|
|
11179
|
-
if (prev &&
|
|
11289
|
+
if (prev && React132.isValidElement(prev)) {
|
|
11180
11290
|
items.push(
|
|
11181
11291
|
/* @__PURE__ */ jsxs("li", { children: [
|
|
11182
11292
|
prev.props.children,
|
|
@@ -11273,7 +11383,7 @@ var CARD_CTA = {
|
|
|
11273
11383
|
function useConnectorJourney(card) {
|
|
11274
11384
|
const panelAvailable = useConnectorsPanelAvailable();
|
|
11275
11385
|
useChatStore((s) => s.setOpen);
|
|
11276
|
-
return
|
|
11386
|
+
return React132.useCallback(() => {
|
|
11277
11387
|
if (panelAvailable && card.id) {
|
|
11278
11388
|
openConnectorsPanel({ id: card.id });
|
|
11279
11389
|
return;
|
|
@@ -11363,7 +11473,7 @@ function ConnectorSuggestionRow({ card }) {
|
|
|
11363
11473
|
] });
|
|
11364
11474
|
}
|
|
11365
11475
|
function ConnectorSuggestionGroup({ cards }) {
|
|
11366
|
-
const shelves =
|
|
11476
|
+
const shelves = React132.useMemo(() => shelveByCategory(cards), [cards]);
|
|
11367
11477
|
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: [
|
|
11368
11478
|
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 }),
|
|
11369
11479
|
/* @__PURE__ */ jsx("div", { className: "divide-y divide-border/40", children: shelf.items.map((card) => /* @__PURE__ */ jsx(ConnectorSuggestionRow, { card }, card.slug ?? card.id ?? card.name)) })
|
|
@@ -11373,8 +11483,8 @@ function ChoiceCard({ card }) {
|
|
|
11373
11483
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
11374
11484
|
const isStreaming = useChatStore((s) => s.isStreaming);
|
|
11375
11485
|
const messages = useChatStore((s) => s.messages);
|
|
11376
|
-
const [optimistic, setOptimistic] =
|
|
11377
|
-
const answeredInThread =
|
|
11486
|
+
const [optimistic, setOptimistic] = React132.useState(null);
|
|
11487
|
+
const answeredInThread = React132.useMemo(
|
|
11378
11488
|
() => answeredOptionId(messages, card.options),
|
|
11379
11489
|
[messages, card.options]
|
|
11380
11490
|
);
|
|
@@ -11429,7 +11539,7 @@ function humanizeToolName(name) {
|
|
|
11429
11539
|
}
|
|
11430
11540
|
function ToolCallRow({ call: call2 }) {
|
|
11431
11541
|
const { t } = useTranslation$1();
|
|
11432
|
-
const [open, setOpen] =
|
|
11542
|
+
const [open, setOpen] = React132.useState(false);
|
|
11433
11543
|
const failed = call2.declined || /"error"\s*:/.test(call2.result ?? "");
|
|
11434
11544
|
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-xl border border-border/50 bg-muted/30", children: [
|
|
11435
11545
|
/* @__PURE__ */ jsxs(
|
|
@@ -11506,15 +11616,15 @@ function HandoffNotice({ notice }) {
|
|
|
11506
11616
|
}
|
|
11507
11617
|
function MessageBubble({ message, isPending }) {
|
|
11508
11618
|
const isUser = message.role === "user";
|
|
11509
|
-
const connectorCards =
|
|
11619
|
+
const connectorCards = React132.useMemo(
|
|
11510
11620
|
() => (message.cards ?? []).filter((card) => card.kind === "connector"),
|
|
11511
11621
|
[message.cards]
|
|
11512
11622
|
);
|
|
11513
|
-
const choiceCards =
|
|
11623
|
+
const choiceCards = React132.useMemo(
|
|
11514
11624
|
() => (message.cards ?? []).filter((card) => card.kind === "choice"),
|
|
11515
11625
|
[message.cards]
|
|
11516
11626
|
);
|
|
11517
|
-
const routedLinks =
|
|
11627
|
+
const routedLinks = React132.useMemo(
|
|
11518
11628
|
() => (message.links ?? []).filter(
|
|
11519
11629
|
(l) => !!l.path || !!resolveEntityRoute(l.archetype, l.kind, l.entityKey)
|
|
11520
11630
|
),
|
|
@@ -11605,9 +11715,9 @@ function ConfirmActionCard({
|
|
|
11605
11715
|
onResolveAll
|
|
11606
11716
|
}) {
|
|
11607
11717
|
const { t } = useTranslation$1();
|
|
11608
|
-
const schema =
|
|
11718
|
+
const schema = React132.useMemo(() => action.fields ?? [], [action.fields]);
|
|
11609
11719
|
const partial = action.partial === true;
|
|
11610
|
-
const seedValues =
|
|
11720
|
+
const seedValues = React132.useCallback(
|
|
11611
11721
|
(params) => {
|
|
11612
11722
|
if (partial) return { ...params };
|
|
11613
11723
|
const seeded = {};
|
|
@@ -11616,18 +11726,18 @@ function ConfirmActionCard({
|
|
|
11616
11726
|
},
|
|
11617
11727
|
[schema, partial]
|
|
11618
11728
|
);
|
|
11619
|
-
const [values, setValues] =
|
|
11620
|
-
const [showAll, setShowAll] =
|
|
11729
|
+
const [values, setValues] = React132.useState(() => seedValues(action.params));
|
|
11730
|
+
const [showAll, setShowAll] = React132.useState(false);
|
|
11621
11731
|
const batch = Math.max(0, sameToolQueued);
|
|
11622
|
-
|
|
11732
|
+
React132.useEffect(() => setValues(seedValues(action.params)), [action.params, seedValues]);
|
|
11623
11733
|
const isSet = (v) => v !== void 0 && v !== null && v !== "";
|
|
11624
|
-
const primaryKeys =
|
|
11734
|
+
const primaryKeys = React132.useMemo(() => {
|
|
11625
11735
|
const keys = Object.keys(action.params).filter((k) => isSet(action.params[k]));
|
|
11626
11736
|
if (partial) return keys;
|
|
11627
11737
|
for (const f of schema) if (f.required && !keys.includes(f.key)) keys.push(f.key);
|
|
11628
11738
|
return keys;
|
|
11629
11739
|
}, [action.params, schema, partial]);
|
|
11630
|
-
const extraKeys =
|
|
11740
|
+
const extraKeys = React132.useMemo(
|
|
11631
11741
|
() => schema.map((f) => f.key).filter((k) => !primaryKeys.includes(k) && k !== "id"),
|
|
11632
11742
|
[schema, primaryKeys]
|
|
11633
11743
|
);
|
|
@@ -11654,20 +11764,20 @@ function ConfirmActionCard({
|
|
|
11654
11764
|
if (sharedLabel !== shared) return sharedLabel;
|
|
11655
11765
|
return humanizeKey(key);
|
|
11656
11766
|
};
|
|
11657
|
-
const missingRequiredKeys =
|
|
11767
|
+
const missingRequiredKeys = React132.useMemo(
|
|
11658
11768
|
() => partial ? [] : schema.filter((f) => f.required && !isSet(values[f.key])).map((f) => f.key),
|
|
11659
11769
|
[schema, values, partial]
|
|
11660
11770
|
);
|
|
11661
11771
|
const canConfirm = missingRequiredKeys.length === 0;
|
|
11662
|
-
const submitted =
|
|
11772
|
+
const submitted = React132.useCallback(
|
|
11663
11773
|
() => partial ? Object.fromEntries(Object.entries(values).filter(([, v]) => isSet(v))) : values,
|
|
11664
11774
|
[partial, values]
|
|
11665
11775
|
);
|
|
11666
|
-
const approve =
|
|
11776
|
+
const approve = React132.useCallback(() => {
|
|
11667
11777
|
if (canConfirm) onResolve(true, submitted());
|
|
11668
11778
|
}, [canConfirm, onResolve, submitted]);
|
|
11669
|
-
const decline =
|
|
11670
|
-
const approveAlways =
|
|
11779
|
+
const decline = React132.useCallback(() => onResolve(false), [onResolve]);
|
|
11780
|
+
const approveAlways = React132.useCallback(() => {
|
|
11671
11781
|
if (!canConfirm) return;
|
|
11672
11782
|
grantAutoApproval({
|
|
11673
11783
|
toolName: action.toolName,
|
|
@@ -11677,7 +11787,7 @@ function ConfirmActionCard({
|
|
|
11677
11787
|
});
|
|
11678
11788
|
onResolve(true, submitted());
|
|
11679
11789
|
}, [canConfirm, action.toolName, action.scope, ruleLabel, destructive, onResolve, submitted]);
|
|
11680
|
-
|
|
11790
|
+
React132.useEffect(() => {
|
|
11681
11791
|
const handler = (event) => {
|
|
11682
11792
|
const target = event.target;
|
|
11683
11793
|
const typing = target?.tagName === "INPUT" || target?.tagName === "TEXTAREA" || target?.tagName === "SELECT";
|
|
@@ -12014,8 +12124,8 @@ var TYPE_MS = 620;
|
|
|
12014
12124
|
var MIN_CHAR_MS = 12;
|
|
12015
12125
|
var MAX_CHAR_MS = 34;
|
|
12016
12126
|
function usePrefersReducedMotion() {
|
|
12017
|
-
const [reduced, setReduced] =
|
|
12018
|
-
|
|
12127
|
+
const [reduced, setReduced] = React132.useState(false);
|
|
12128
|
+
React132.useEffect(() => {
|
|
12019
12129
|
if (typeof matchMedia !== "function") return;
|
|
12020
12130
|
const query = matchMedia("(prefers-reduced-motion: reduce)");
|
|
12021
12131
|
const sync = () => setReduced(query.matches);
|
|
@@ -12034,10 +12144,10 @@ function TypedText({
|
|
|
12034
12144
|
onDone
|
|
12035
12145
|
}) {
|
|
12036
12146
|
const reduced = usePrefersReducedMotion();
|
|
12037
|
-
const [count, setCount] =
|
|
12038
|
-
const done =
|
|
12147
|
+
const [count, setCount] = React132.useState(reduced ? text2.length : 0);
|
|
12148
|
+
const done = React132.useRef(onDone);
|
|
12039
12149
|
done.current = onDone;
|
|
12040
|
-
|
|
12150
|
+
React132.useEffect(() => {
|
|
12041
12151
|
if (!start) {
|
|
12042
12152
|
setCount(0);
|
|
12043
12153
|
return;
|
|
@@ -12077,9 +12187,9 @@ function RevealSequence({
|
|
|
12077
12187
|
children
|
|
12078
12188
|
}) {
|
|
12079
12189
|
const reduced = usePrefersReducedMotion();
|
|
12080
|
-
const items =
|
|
12081
|
-
const [shown, setShown] =
|
|
12082
|
-
|
|
12190
|
+
const items = React132.Children.toArray(children);
|
|
12191
|
+
const [shown, setShown] = React132.useState(0);
|
|
12192
|
+
React132.useEffect(() => {
|
|
12083
12193
|
if (!start) {
|
|
12084
12194
|
setShown(0);
|
|
12085
12195
|
return;
|
|
@@ -12141,7 +12251,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
12141
12251
|
const currentPlan = plans.find((p) => p.id === currentPlanId);
|
|
12142
12252
|
const currentPrice = currentPlan?.price ?? 0;
|
|
12143
12253
|
const currentPlanName = currentPlan?.name ?? tr("billing.free", "Free");
|
|
12144
|
-
const featureName =
|
|
12254
|
+
const featureName = React132.useMemo(() => {
|
|
12145
12255
|
if (!feature) return null;
|
|
12146
12256
|
const label3 = features.find((f) => f.id === feature)?.label;
|
|
12147
12257
|
if (label3) return featureDisplayName(label3);
|
|
@@ -12149,7 +12259,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
12149
12259
|
const named = t(key);
|
|
12150
12260
|
return named && named !== key ? named : featureDisplayName(feature);
|
|
12151
12261
|
}, [features, feature, t]);
|
|
12152
|
-
const unlockingPlans =
|
|
12262
|
+
const unlockingPlans = React132.useMemo(
|
|
12153
12263
|
() => plans.filter((p) => p.id !== currentPlanId && p.price > currentPrice && planUnlocks(p, feature)).sort((a, b) => a.price - b.price),
|
|
12154
12264
|
[plans, currentPlanId, currentPrice, feature]
|
|
12155
12265
|
);
|
|
@@ -12331,26 +12441,26 @@ function ChatConversation({
|
|
|
12331
12441
|
usable && !pendingAction && !isStreaming,
|
|
12332
12442
|
receiveFiles
|
|
12333
12443
|
);
|
|
12334
|
-
|
|
12335
|
-
const [view, setView] =
|
|
12444
|
+
React132.useEffect(ensureIntroStyles, []);
|
|
12445
|
+
const [view, setView] = React132.useState(
|
|
12336
12446
|
() => useChatStore.getState().messages.length > 0 ? "thread" : "list"
|
|
12337
12447
|
);
|
|
12338
|
-
const [drawer, setDrawer] =
|
|
12339
|
-
const [introStep, setIntroStep] =
|
|
12340
|
-
const [atBottom, setAtBottom] =
|
|
12341
|
-
const scrollRef =
|
|
12448
|
+
const [drawer, setDrawer] = React132.useState("none");
|
|
12449
|
+
const [introStep, setIntroStep] = React132.useState(0);
|
|
12450
|
+
const [atBottom, setAtBottom] = React132.useState(true);
|
|
12451
|
+
const scrollRef = React132.useRef(null);
|
|
12342
12452
|
const hasMessages = messages.length > 0;
|
|
12343
12453
|
const showThread = view === "thread" && hasMessages;
|
|
12344
12454
|
const totalTools = toolGroups.reduce((sum, g) => sum + g.tools.length, 0);
|
|
12345
|
-
const scrollToBottom =
|
|
12455
|
+
const scrollToBottom = React132.useCallback((behavior = "smooth") => {
|
|
12346
12456
|
const el = scrollRef.current;
|
|
12347
12457
|
if (!el) return;
|
|
12348
12458
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
12349
12459
|
}, []);
|
|
12350
|
-
|
|
12460
|
+
React132.useEffect(() => {
|
|
12351
12461
|
if (atBottom) scrollToBottom();
|
|
12352
12462
|
}, [messages, activeTools, pendingAction, atBottom, scrollToBottom]);
|
|
12353
|
-
|
|
12463
|
+
React132.useEffect(() => {
|
|
12354
12464
|
loadConversations();
|
|
12355
12465
|
setSuggestionsOpen(useChatStore.getState().messages.length === 0);
|
|
12356
12466
|
return () => stopSpeaking();
|
|
@@ -12367,7 +12477,7 @@ function ChatConversation({
|
|
|
12367
12477
|
};
|
|
12368
12478
|
const queuedPrompt = useChatStore((s) => s.queuedPrompt);
|
|
12369
12479
|
const consumeQueuedPrompt = useChatStore((s) => s.consumeQueuedPrompt);
|
|
12370
|
-
|
|
12480
|
+
React132.useEffect(() => {
|
|
12371
12481
|
if (!queuedPrompt) return;
|
|
12372
12482
|
const prompt = consumeQueuedPrompt();
|
|
12373
12483
|
if (prompt && usable) send(prompt);
|
|
@@ -12403,7 +12513,7 @@ function ChatConversation({
|
|
|
12403
12513
|
);
|
|
12404
12514
|
const connectorsPending = useConnectorsSurface((s) => s.pending);
|
|
12405
12515
|
const consumeConnectorsRequest = useConnectorsSurface((s) => s.consume);
|
|
12406
|
-
|
|
12516
|
+
React132.useEffect(() => {
|
|
12407
12517
|
if (!connectorsPending) return;
|
|
12408
12518
|
setDrawer("connectors");
|
|
12409
12519
|
consumeConnectorsRequest();
|
|
@@ -12411,7 +12521,7 @@ function ChatConversation({
|
|
|
12411
12521
|
const greetingName = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
12412
12522
|
const invite = useAssistantInviteStore((s) => s.invite);
|
|
12413
12523
|
const introKey = `${onDuty?.role ?? "solo"}:${invite?.id ?? ""}`;
|
|
12414
|
-
|
|
12524
|
+
React132.useEffect(() => setIntroStep(0), [introKey]);
|
|
12415
12525
|
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");
|
|
12416
12526
|
const greetingHint = invite?.description ?? onDuty?.goal ?? t("chat.greetingHint");
|
|
12417
12527
|
const openers2 = invite?.suggestions?.length ? invite.suggestions : onDuty?.suggestions?.length ? onDuty.suggestions : suggestions.length ? suggestions : [
|
|
@@ -12733,7 +12843,7 @@ function AgentAvatar({
|
|
|
12733
12843
|
size = "md",
|
|
12734
12844
|
className
|
|
12735
12845
|
}) {
|
|
12736
|
-
const [failed, setFailed] =
|
|
12846
|
+
const [failed, setFailed] = React132.useState(false);
|
|
12737
12847
|
const { box, text: text2, px } = SIZES[size];
|
|
12738
12848
|
if (Face) {
|
|
12739
12849
|
return /* @__PURE__ */ jsx(
|
|
@@ -13521,7 +13631,7 @@ function TaskStatusGroup({ status, tasks }) {
|
|
|
13521
13631
|
function useDelegateToAssistant() {
|
|
13522
13632
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
13523
13633
|
const openPanel = useRightRailStore((s) => s.openPanel);
|
|
13524
|
-
return
|
|
13634
|
+
return React132.useCallback(
|
|
13525
13635
|
(prompt) => {
|
|
13526
13636
|
queuePrompt(prompt);
|
|
13527
13637
|
openPanel("chat");
|
|
@@ -13758,12 +13868,12 @@ function TasksPanel() {
|
|
|
13758
13868
|
const fetchTasks = useTasksStore((s) => s.fetchTasks);
|
|
13759
13869
|
const fetchLabels = useTasksStore((s) => s.fetchLabels);
|
|
13760
13870
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13761
|
-
|
|
13871
|
+
React132__default.useEffect(() => {
|
|
13762
13872
|
void fetchTasks();
|
|
13763
13873
|
void fetchLabels();
|
|
13764
13874
|
void fetchSummary();
|
|
13765
13875
|
}, [fetchTasks, fetchLabels, fetchSummary]);
|
|
13766
|
-
const { onboarding, grouped } =
|
|
13876
|
+
const { onboarding, grouped } = React132__default.useMemo(() => {
|
|
13767
13877
|
const split = splitOnboardingTasks(tasks);
|
|
13768
13878
|
const map = /* @__PURE__ */ new Map();
|
|
13769
13879
|
for (const s of STATUS_ORDER) map.set(s, []);
|
|
@@ -13798,7 +13908,7 @@ function TasksPanel() {
|
|
|
13798
13908
|
function useTasksSummaryLine() {
|
|
13799
13909
|
const t = useTranslation();
|
|
13800
13910
|
const summary = useTasksStore((s) => s.summary);
|
|
13801
|
-
return
|
|
13911
|
+
return React132__default.useMemo(() => {
|
|
13802
13912
|
if (!summary) return "";
|
|
13803
13913
|
const parts = [];
|
|
13804
13914
|
if (summary.overdue > 0) parts.push(`${summary.overdue} ${t("tasks.summary.overdue")}`);
|
|
@@ -13823,16 +13933,16 @@ function TasksRailPanel() {
|
|
|
13823
13933
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13824
13934
|
const setCurrentUserId = useTasksStore((s) => s.setCurrentUserId);
|
|
13825
13935
|
const userId = useAuthStore6((s) => s.user?.id);
|
|
13826
|
-
|
|
13936
|
+
React132__default.useEffect(() => {
|
|
13827
13937
|
void fetchSummary();
|
|
13828
13938
|
}, [fetchSummary]);
|
|
13829
|
-
|
|
13939
|
+
React132__default.useEffect(() => {
|
|
13830
13940
|
setCurrentUserId(userId ?? null);
|
|
13831
13941
|
}, [userId, setCurrentUserId]);
|
|
13832
13942
|
const openCount = summary ? summary.todo + summary.inProgress : 0;
|
|
13833
13943
|
const defer = tasksSurfaceOwner() === "plugin";
|
|
13834
13944
|
useRightRailPanel(
|
|
13835
|
-
|
|
13945
|
+
React132__default.useMemo(
|
|
13836
13946
|
() => defer ? null : {
|
|
13837
13947
|
id: "tasks",
|
|
13838
13948
|
label: t("tasks.drawer.title") || "Tasks",
|
|
@@ -13856,15 +13966,15 @@ var useSettingsTabsStore = create((set, get) => ({
|
|
|
13856
13966
|
}));
|
|
13857
13967
|
function usePublishSettingsTabs(ids) {
|
|
13858
13968
|
const key = ids.join(",");
|
|
13859
|
-
|
|
13969
|
+
React132.useEffect(() => {
|
|
13860
13970
|
useSettingsTabsStore.getState().setIds(key ? key.split(",") : []);
|
|
13861
13971
|
}, [key]);
|
|
13862
13972
|
}
|
|
13863
13973
|
function useAgentSurface(contribution) {
|
|
13864
|
-
const ref =
|
|
13974
|
+
const ref = React132.useRef(contribution);
|
|
13865
13975
|
ref.current = contribution;
|
|
13866
13976
|
const id = contribution.id;
|
|
13867
|
-
|
|
13977
|
+
React132.useEffect(() => {
|
|
13868
13978
|
registerSurface({ id, get: () => ref.current });
|
|
13869
13979
|
const names = (ref.current.tools ?? []).map((t) => t.tool.name);
|
|
13870
13980
|
for (const name of names) {
|
|
@@ -14644,9 +14754,9 @@ function featureMap() {
|
|
|
14644
14754
|
}));
|
|
14645
14755
|
}
|
|
14646
14756
|
function ActivationAgentSurface({ programs }) {
|
|
14647
|
-
const programsRef =
|
|
14757
|
+
const programsRef = React132.useRef(programs);
|
|
14648
14758
|
programsRef.current = programs;
|
|
14649
|
-
const contribution =
|
|
14759
|
+
const contribution = React132.useMemo(
|
|
14650
14760
|
() => ({
|
|
14651
14761
|
id: "onboarding.activation",
|
|
14652
14762
|
pluginId: "onboarding",
|
|
@@ -14967,7 +15077,7 @@ Quando a pessoa perguntar COMO fazer algo que tem guia em \`setupGuides\` ("como
|
|
|
14967
15077
|
- Termine dizendo o que isso destrava e oferecendo a pr\xF3xima, uma vez s\xF3.`
|
|
14968
15078
|
);
|
|
14969
15079
|
function SetupAgentSurface() {
|
|
14970
|
-
const contribution =
|
|
15080
|
+
const contribution = React132.useMemo(
|
|
14971
15081
|
() => ({
|
|
14972
15082
|
id: "setup.guides",
|
|
14973
15083
|
pluginId: "setup",
|
|
@@ -15083,7 +15193,7 @@ function SetupAgentSurface() {
|
|
|
15083
15193
|
}
|
|
15084
15194
|
var DEBOUNCE_MS = 1200;
|
|
15085
15195
|
function useActivationWatch() {
|
|
15086
|
-
|
|
15196
|
+
React132.useEffect(() => {
|
|
15087
15197
|
let timer = null;
|
|
15088
15198
|
let running = false;
|
|
15089
15199
|
const sweep = async () => {
|
|
@@ -15122,7 +15232,7 @@ function useActivationWatch() {
|
|
|
15122
15232
|
off();
|
|
15123
15233
|
};
|
|
15124
15234
|
}, []);
|
|
15125
|
-
|
|
15235
|
+
React132.useEffect(() => {
|
|
15126
15236
|
useActivationStore.setState({
|
|
15127
15237
|
onStepCompleted: (step, by) => {
|
|
15128
15238
|
const state = useActivationStore.getState();
|
|
@@ -15779,7 +15889,7 @@ function ActivationProvider() {
|
|
|
15779
15889
|
const programs = runtime?.onboardingPrograms ?? [];
|
|
15780
15890
|
const settingsIds = useSettingsTabsStore((s) => s.ids);
|
|
15781
15891
|
const routeKey = (runtime?.routes.length ?? 0) + ":" + settingsIds.join(",");
|
|
15782
|
-
const hasRoute =
|
|
15892
|
+
const hasRoute = React132.useMemo(() => {
|
|
15783
15893
|
const known = /* @__PURE__ */ new Set(["/", "/settings"]);
|
|
15784
15894
|
for (const route of runtime?.routes ?? []) known.add(route.path);
|
|
15785
15895
|
for (const id of settingsIds) known.add(`/settings/${id}`);
|
|
@@ -15787,14 +15897,14 @@ function ActivationProvider() {
|
|
|
15787
15897
|
}, [routeKey]);
|
|
15788
15898
|
const answers = useBusinessProfileStore((s) => s.profile?.answers);
|
|
15789
15899
|
const programKey = programs.map((p) => p.id).join(",");
|
|
15790
|
-
const catalog =
|
|
15900
|
+
const catalog = React132.useMemo(
|
|
15791
15901
|
() => buildActivationCatalog({ verticalId, programs, hasRoute, answers }),
|
|
15792
15902
|
[verticalId, programKey, hasRoute, answers]
|
|
15793
15903
|
);
|
|
15794
|
-
|
|
15904
|
+
React132.useEffect(() => {
|
|
15795
15905
|
setCatalog(catalog);
|
|
15796
15906
|
}, [catalog, setCatalog]);
|
|
15797
|
-
|
|
15907
|
+
React132.useEffect(() => {
|
|
15798
15908
|
if (!tenantId2) return;
|
|
15799
15909
|
let cancelled = false;
|
|
15800
15910
|
void (async () => {
|
|
@@ -15826,14 +15936,14 @@ function ActivationProvider() {
|
|
|
15826
15936
|
cancelled = true;
|
|
15827
15937
|
};
|
|
15828
15938
|
}, [tenantId2, catalog, answers, hasRoute, settingsIds, user?.id, load]);
|
|
15829
|
-
|
|
15939
|
+
React132.useEffect(() => {
|
|
15830
15940
|
if (!tenantId2) {
|
|
15831
15941
|
useBusinessProfileStore.getState().clear();
|
|
15832
15942
|
return;
|
|
15833
15943
|
}
|
|
15834
15944
|
void useBusinessProfileStore.getState().load(tenantId2, orgName);
|
|
15835
15945
|
}, [tenantId2, orgName]);
|
|
15836
|
-
|
|
15946
|
+
React132.useEffect(() => {
|
|
15837
15947
|
if (!tenantId2) return;
|
|
15838
15948
|
const key = `${GREETING_FLAG}:${tenantId2}`;
|
|
15839
15949
|
let pending2 = false;
|
|
@@ -15855,10 +15965,10 @@ function ActivationProvider() {
|
|
|
15855
15965
|
return () => window.clearTimeout(timer);
|
|
15856
15966
|
}, [tenantId2]);
|
|
15857
15967
|
const guides = runtime?.setupGuides;
|
|
15858
|
-
|
|
15968
|
+
React132.useEffect(() => {
|
|
15859
15969
|
setRuntimeSetupGuides(guides ?? []);
|
|
15860
15970
|
}, [guides]);
|
|
15861
|
-
|
|
15971
|
+
React132.useEffect(() => {
|
|
15862
15972
|
setTourNavigator(navigateTo);
|
|
15863
15973
|
return () => setTourNavigator(void 0);
|
|
15864
15974
|
}, []);
|
|
@@ -16031,7 +16141,7 @@ Escrita:
|
|
|
16031
16141
|
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.`
|
|
16032
16142
|
);
|
|
16033
16143
|
function HandbookAgentSurface() {
|
|
16034
|
-
const contribution =
|
|
16144
|
+
const contribution = React132.useMemo(
|
|
16035
16145
|
() => ({
|
|
16036
16146
|
id: "handbook",
|
|
16037
16147
|
pluginId: "handbook",
|
|
@@ -16142,18 +16252,18 @@ function NotebookPanel() {
|
|
|
16142
16252
|
const userId = useHandbookStore((s) => s.userId);
|
|
16143
16253
|
const write3 = useHandbookStore((s) => s.write);
|
|
16144
16254
|
const remove = useHandbookStore((s) => s.remove);
|
|
16145
|
-
const [filter, setFilter] =
|
|
16146
|
-
const [search, setSearch] =
|
|
16147
|
-
const [draft, setDraft] =
|
|
16148
|
-
const [preview, setPreview] =
|
|
16149
|
-
const [confirming, setConfirming] =
|
|
16150
|
-
const entries2 =
|
|
16255
|
+
const [filter, setFilter] = React132.useState("all");
|
|
16256
|
+
const [search, setSearch] = React132.useState("");
|
|
16257
|
+
const [draft, setDraft] = React132.useState(null);
|
|
16258
|
+
const [preview, setPreview] = React132.useState(false);
|
|
16259
|
+
const [confirming, setConfirming] = React132.useState(null);
|
|
16260
|
+
const entries2 = React132.useMemo(
|
|
16151
16261
|
() => (pages ?? []).map((p) => ({ page: p, entry: toEntry2(p) })),
|
|
16152
16262
|
[pages]
|
|
16153
16263
|
);
|
|
16154
|
-
const timer =
|
|
16155
|
-
const inFlight =
|
|
16156
|
-
const persist =
|
|
16264
|
+
const timer = React132.useRef(null);
|
|
16265
|
+
const inFlight = React132.useRef(false);
|
|
16266
|
+
const persist = React132.useCallback(async (d) => {
|
|
16157
16267
|
const title = titleFromBody(d.body);
|
|
16158
16268
|
if (!title && !d.body.trim()) return d.id;
|
|
16159
16269
|
const filed = d.folder !== null;
|
|
@@ -16175,7 +16285,7 @@ function NotebookPanel() {
|
|
|
16175
16285
|
});
|
|
16176
16286
|
return saved?.id ?? d.id;
|
|
16177
16287
|
}, [write3, userId]);
|
|
16178
|
-
const schedule =
|
|
16288
|
+
const schedule = React132.useCallback((next) => {
|
|
16179
16289
|
setDraft(next);
|
|
16180
16290
|
if (timer.current) clearTimeout(timer.current);
|
|
16181
16291
|
timer.current = setTimeout(() => {
|
|
@@ -16207,7 +16317,7 @@ function NotebookPanel() {
|
|
|
16207
16317
|
legacyId: null
|
|
16208
16318
|
});
|
|
16209
16319
|
};
|
|
16210
|
-
const folders =
|
|
16320
|
+
const folders = React132.useMemo(() => {
|
|
16211
16321
|
const set = /* @__PURE__ */ new Set();
|
|
16212
16322
|
for (const { page } of entries2) {
|
|
16213
16323
|
if (page.kind !== "doc" || !page.path) continue;
|
|
@@ -16599,10 +16709,10 @@ ${body}`
|
|
|
16599
16709
|
}
|
|
16600
16710
|
function NoteTodosSection({ noteId, noteTitle }) {
|
|
16601
16711
|
const adapter = useNotesTasksBridge((s) => s.adapter);
|
|
16602
|
-
const [todos, setTodos] =
|
|
16603
|
-
const [draft, setDraft] =
|
|
16604
|
-
const [busy, setBusy] =
|
|
16605
|
-
|
|
16712
|
+
const [todos, setTodos] = React132.useState([]);
|
|
16713
|
+
const [draft, setDraft] = React132.useState("");
|
|
16714
|
+
const [busy, setBusy] = React132.useState(false);
|
|
16715
|
+
React132.useEffect(() => {
|
|
16606
16716
|
if (!adapter) return;
|
|
16607
16717
|
let alive = true;
|
|
16608
16718
|
adapter.listTodos(noteId).then((rows) => {
|
|
@@ -16732,7 +16842,7 @@ function NotebookRailPanel() {
|
|
|
16732
16842
|
const pages = useHandbookStore((s) => s.pages);
|
|
16733
16843
|
const count = pages?.length ?? 0;
|
|
16734
16844
|
useRightRailPanel(
|
|
16735
|
-
|
|
16845
|
+
React132.useMemo(
|
|
16736
16846
|
() => ({
|
|
16737
16847
|
id: "notes",
|
|
16738
16848
|
label: tl("Notes", "Notas"),
|
|
@@ -16751,10 +16861,10 @@ function HandbookProvider() {
|
|
|
16751
16861
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16752
16862
|
const load = useHandbookStore((s) => s.load);
|
|
16753
16863
|
const setUser = useHandbookStore((s) => s.setUser);
|
|
16754
|
-
|
|
16864
|
+
React132.useEffect(() => {
|
|
16755
16865
|
setUser(userId);
|
|
16756
16866
|
}, [userId, setUser]);
|
|
16757
|
-
|
|
16867
|
+
React132.useEffect(() => {
|
|
16758
16868
|
if (tenantId2) void load(tenantId2);
|
|
16759
16869
|
}, [tenantId2, load]);
|
|
16760
16870
|
useLocalNotesImport(tenantId2, userId);
|
|
@@ -16764,7 +16874,7 @@ function HandbookProvider() {
|
|
|
16764
16874
|
] });
|
|
16765
16875
|
}
|
|
16766
16876
|
function useLocalNotesImport(tenantId2, userId) {
|
|
16767
|
-
|
|
16877
|
+
React132.useEffect(() => {
|
|
16768
16878
|
if (!tenantId2 || !userId) return;
|
|
16769
16879
|
const source = `fayz.notes.${tenantId2}.${userId}`;
|
|
16770
16880
|
const flag = `fayz.notes.imported.${tenantId2}.${userId}`;
|
|
@@ -16812,7 +16922,7 @@ function useUnitBootstrap() {
|
|
|
16812
16922
|
const tenant = useTenantOptional();
|
|
16813
16923
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16814
16924
|
const orgId = tenant?.org?.id;
|
|
16815
|
-
|
|
16925
|
+
React132.useEffect(() => {
|
|
16816
16926
|
if (!orgId) return;
|
|
16817
16927
|
const { loadedFor, load, reset } = useUnitStore.getState();
|
|
16818
16928
|
if (loadedFor && loadedFor !== orgId) reset();
|
|
@@ -16851,19 +16961,19 @@ function UnitMembersTab({ item }) {
|
|
|
16851
16961
|
const orgMembers = useOrganizationStore((s) => s.members);
|
|
16852
16962
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
16853
16963
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
16854
|
-
const [rows, setRows] =
|
|
16855
|
-
const [activity, setActivity] =
|
|
16856
|
-
const [adding, setAdding] =
|
|
16857
|
-
const [busy, setBusy] =
|
|
16858
|
-
const
|
|
16964
|
+
const [rows, setRows] = React132.useState(null);
|
|
16965
|
+
const [activity, setActivity] = React132.useState({});
|
|
16966
|
+
const [adding, setAdding] = React132.useState(false);
|
|
16967
|
+
const [busy, setBusy] = React132.useState(null);
|
|
16968
|
+
const reload2 = React132.useCallback(async () => {
|
|
16859
16969
|
if (!unitId) return;
|
|
16860
16970
|
setRows(await fetchUnitMembers(unitId));
|
|
16861
16971
|
}, [unitId]);
|
|
16862
16972
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
16863
|
-
|
|
16864
|
-
void
|
|
16865
|
-
}, [
|
|
16866
|
-
|
|
16973
|
+
React132.useEffect(() => {
|
|
16974
|
+
void reload2();
|
|
16975
|
+
}, [reload2, version5]);
|
|
16976
|
+
React132.useEffect(() => {
|
|
16867
16977
|
if (!orgId) return;
|
|
16868
16978
|
let alive = true;
|
|
16869
16979
|
void fetchMemberActivity(orgId).then((a) => {
|
|
@@ -16873,7 +16983,7 @@ function UnitMembersTab({ item }) {
|
|
|
16873
16983
|
alive = false;
|
|
16874
16984
|
};
|
|
16875
16985
|
}, [orgId]);
|
|
16876
|
-
const byUser =
|
|
16986
|
+
const byUser = React132.useMemo(() => {
|
|
16877
16987
|
const map = /* @__PURE__ */ new Map();
|
|
16878
16988
|
for (const m of orgMembers) {
|
|
16879
16989
|
map.set(m.userId, {
|
|
@@ -16885,7 +16995,7 @@ function UnitMembersTab({ item }) {
|
|
|
16885
16995
|
}
|
|
16886
16996
|
return map;
|
|
16887
16997
|
}, [orgMembers]);
|
|
16888
|
-
const available =
|
|
16998
|
+
const available = React132.useMemo(
|
|
16889
16999
|
() => orgMembers.filter((m) => !(rows ?? []).some((r) => r.userId === m.userId)),
|
|
16890
17000
|
[orgMembers, rows]
|
|
16891
17001
|
);
|
|
@@ -16893,7 +17003,7 @@ function UnitMembersTab({ item }) {
|
|
|
16893
17003
|
setBusy(userId);
|
|
16894
17004
|
try {
|
|
16895
17005
|
await fn();
|
|
16896
|
-
await
|
|
17006
|
+
await reload2();
|
|
16897
17007
|
} catch (err) {
|
|
16898
17008
|
toast.error(failure, { description: err?.message });
|
|
16899
17009
|
} finally {
|
|
@@ -17091,15 +17201,15 @@ function MemberAccessBody({
|
|
|
17091
17201
|
const units = useUnitStore((s) => s.units);
|
|
17092
17202
|
const byId = useUnitStore((s) => s.byId);
|
|
17093
17203
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
17094
|
-
const [bindings, setBindings] =
|
|
17095
|
-
const [loading, setLoading] =
|
|
17096
|
-
const [adding, setAdding] =
|
|
17097
|
-
const branches =
|
|
17098
|
-
const unbound =
|
|
17204
|
+
const [bindings, setBindings] = React132.useState([]);
|
|
17205
|
+
const [loading, setLoading] = React132.useState(false);
|
|
17206
|
+
const [adding, setAdding] = React132.useState(false);
|
|
17207
|
+
const branches = React132.useMemo(() => units.filter((u) => u.isActive !== false), [units]);
|
|
17208
|
+
const unbound = React132.useMemo(
|
|
17099
17209
|
() => branches.filter((u) => !bindings.some((b) => b.locationId === u.id)),
|
|
17100
17210
|
[branches, bindings]
|
|
17101
17211
|
);
|
|
17102
|
-
const
|
|
17212
|
+
const reload2 = React132.useCallback(async () => {
|
|
17103
17213
|
if (!userId) return;
|
|
17104
17214
|
setLoading(true);
|
|
17105
17215
|
try {
|
|
@@ -17109,13 +17219,13 @@ function MemberAccessBody({
|
|
|
17109
17219
|
}
|
|
17110
17220
|
}, [userId]);
|
|
17111
17221
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
17112
|
-
|
|
17113
|
-
void
|
|
17114
|
-
}, [
|
|
17222
|
+
React132.useEffect(() => {
|
|
17223
|
+
void reload2();
|
|
17224
|
+
}, [reload2, version5]);
|
|
17115
17225
|
async function add(unitId) {
|
|
17116
17226
|
try {
|
|
17117
17227
|
await bindUserToUnit(unitId, userId, null);
|
|
17118
|
-
await
|
|
17228
|
+
await reload2();
|
|
17119
17229
|
setAdding(false);
|
|
17120
17230
|
} catch (err) {
|
|
17121
17231
|
toast.error("N\xE3o deu para dar o acesso", { description: err?.message });
|
|
@@ -17124,7 +17234,7 @@ function MemberAccessBody({
|
|
|
17124
17234
|
async function setRole(unitId, role) {
|
|
17125
17235
|
try {
|
|
17126
17236
|
await bindUserToUnit(unitId, userId, role === NO_EXTRA_ROLE2 ? null : role);
|
|
17127
|
-
await
|
|
17237
|
+
await reload2();
|
|
17128
17238
|
} catch (err) {
|
|
17129
17239
|
toast.error("N\xE3o deu para mudar a fun\xE7\xE3o", { description: err?.message });
|
|
17130
17240
|
}
|
|
@@ -17132,7 +17242,7 @@ function MemberAccessBody({
|
|
|
17132
17242
|
async function remove(unitId) {
|
|
17133
17243
|
try {
|
|
17134
17244
|
await unbindUserFromUnit(unitId, userId);
|
|
17135
|
-
await
|
|
17245
|
+
await reload2();
|
|
17136
17246
|
} catch (err) {
|
|
17137
17247
|
toast.error("N\xE3o deu para tirar o acesso", { description: err?.message });
|
|
17138
17248
|
}
|
|
@@ -17846,14 +17956,14 @@ function minutesLeft(expiresAt) {
|
|
|
17846
17956
|
}
|
|
17847
17957
|
function ImpersonationBanner() {
|
|
17848
17958
|
const { t } = useTranslation$1();
|
|
17849
|
-
const [state] =
|
|
17850
|
-
const [left, setLeft] =
|
|
17851
|
-
const [leaving, setLeaving] =
|
|
17852
|
-
const leave =
|
|
17959
|
+
const [state] = React132__default.useState(readImpersonation);
|
|
17960
|
+
const [left, setLeft] = React132__default.useState(() => state ? minutesLeft(state.expiresAt) : 0);
|
|
17961
|
+
const [leaving, setLeaving] = React132__default.useState(false);
|
|
17962
|
+
const leave = React132__default.useCallback(() => {
|
|
17853
17963
|
setLeaving(true);
|
|
17854
17964
|
void stopImpersonation();
|
|
17855
17965
|
}, []);
|
|
17856
|
-
|
|
17966
|
+
React132__default.useEffect(() => {
|
|
17857
17967
|
if (!state) return;
|
|
17858
17968
|
document.documentElement.classList.add("fz-has-top-strip");
|
|
17859
17969
|
const timer = window.setInterval(() => {
|
|
@@ -17897,12 +18007,55 @@ function ImpersonationBanner() {
|
|
|
17897
18007
|
}
|
|
17898
18008
|
);
|
|
17899
18009
|
}
|
|
18010
|
+
function ConnectionBanner() {
|
|
18011
|
+
const { t } = useTranslation$1();
|
|
18012
|
+
const { online } = useConnectivity();
|
|
18013
|
+
const wasOffline = React132__default.useRef(false);
|
|
18014
|
+
React132__default.useEffect(() => {
|
|
18015
|
+
if (!online) {
|
|
18016
|
+
wasOffline.current = true;
|
|
18017
|
+
document.documentElement.classList.add("fz-has-top-strip");
|
|
18018
|
+
return () => {
|
|
18019
|
+
if (!readImpersonation()) document.documentElement.classList.remove("fz-has-top-strip");
|
|
18020
|
+
};
|
|
18021
|
+
}
|
|
18022
|
+
if (wasOffline.current) {
|
|
18023
|
+
wasOffline.current = false;
|
|
18024
|
+
toast.success(t("connection.restored"), { description: t("connection.restoredDetail"), id: "connection-restored" });
|
|
18025
|
+
}
|
|
18026
|
+
return void 0;
|
|
18027
|
+
}, [online, t]);
|
|
18028
|
+
if (online) return null;
|
|
18029
|
+
return /* @__PURE__ */ jsxs(
|
|
18030
|
+
"div",
|
|
18031
|
+
{
|
|
18032
|
+
role: "status",
|
|
18033
|
+
"aria-live": "polite",
|
|
18034
|
+
className: "flex h-8 items-center justify-center gap-2 bg-warning px-3 text-xs font-medium text-warning-foreground",
|
|
18035
|
+
"data-testid": "connection-banner",
|
|
18036
|
+
children: [
|
|
18037
|
+
/* @__PURE__ */ jsx(WifiOff, { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": true }),
|
|
18038
|
+
/* @__PURE__ */ jsxs("span", { className: "truncate", children: [
|
|
18039
|
+
t("connection.offline"),
|
|
18040
|
+
/* @__PURE__ */ jsxs("span", { className: "hidden opacity-80 md:inline", children: [
|
|
18041
|
+
" ",
|
|
18042
|
+
t("connection.offlineDetail")
|
|
18043
|
+
] })
|
|
18044
|
+
] }),
|
|
18045
|
+
/* @__PURE__ */ jsxs("span", { className: "ml-1 hidden shrink-0 items-center gap-1 opacity-80 sm:inline-flex", children: [
|
|
18046
|
+
/* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 animate-spin", "aria-hidden": true }),
|
|
18047
|
+
t("connection.reconnecting")
|
|
18048
|
+
] })
|
|
18049
|
+
]
|
|
18050
|
+
}
|
|
18051
|
+
);
|
|
18052
|
+
}
|
|
17900
18053
|
function useWrongApp() {
|
|
17901
18054
|
const apps = useAppConfigStore((s) => s.config.apps);
|
|
17902
18055
|
const tenantId2 = useAppConfigStore((s) => s.tenantId);
|
|
17903
18056
|
const activeTenantId = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
17904
18057
|
const appId = resolveAppId();
|
|
17905
|
-
return
|
|
18058
|
+
return React132.useMemo(() => {
|
|
17906
18059
|
if (!appId || !activeTenantId || tenantId2 !== activeTenantId) return { app: null };
|
|
17907
18060
|
const list = (apps ?? []).filter((a) => !a.house);
|
|
17908
18061
|
if (!list.length) return { app: null };
|
|
@@ -18025,13 +18178,13 @@ function surveyTokenFromPath(pathname) {
|
|
|
18025
18178
|
return m ? decodeURIComponent(m[1]) : null;
|
|
18026
18179
|
}
|
|
18027
18180
|
function PublicSurveyPage({ token, appName }) {
|
|
18028
|
-
const [loaded2, setLoaded] =
|
|
18029
|
-
const [draft, setDraft] =
|
|
18030
|
-
const [name, setName] =
|
|
18031
|
-
const [sending, setSending] =
|
|
18032
|
-
const [sent, setSent] =
|
|
18033
|
-
const [failed, setFailed] =
|
|
18034
|
-
|
|
18181
|
+
const [loaded2, setLoaded] = React132__default.useState(null);
|
|
18182
|
+
const [draft, setDraft] = React132__default.useState({});
|
|
18183
|
+
const [name, setName] = React132__default.useState("");
|
|
18184
|
+
const [sending, setSending] = React132__default.useState(false);
|
|
18185
|
+
const [sent, setSent] = React132__default.useState(null);
|
|
18186
|
+
const [failed, setFailed] = React132__default.useState(null);
|
|
18187
|
+
React132__default.useEffect(() => {
|
|
18035
18188
|
let alive = true;
|
|
18036
18189
|
const client3 = getFayzSupabaseClientOptional();
|
|
18037
18190
|
if (!client3) {
|
|
@@ -18329,7 +18482,7 @@ function isServed2(route) {
|
|
|
18329
18482
|
function getPersonActions(kind) {
|
|
18330
18483
|
return ACTIONS.filter((a) => !a.kinds || (kind ? a.kinds.includes(kind) : false)).filter((a) => !a.requiresRoute || isServed2(a.requiresRoute)).sort((a, b) => (a.order ?? 100) - (b.order ?? 100));
|
|
18331
18484
|
}
|
|
18332
|
-
var RouteErrorBoundary = class extends
|
|
18485
|
+
var RouteErrorBoundary = class extends React132.Component {
|
|
18333
18486
|
constructor() {
|
|
18334
18487
|
super(...arguments);
|
|
18335
18488
|
this.state = { crashed: false, report: null };
|
|
@@ -18371,7 +18524,7 @@ var RouteErrorBoundary = class extends React130.Component {
|
|
|
18371
18524
|
}
|
|
18372
18525
|
};
|
|
18373
18526
|
function RouteErrorScreen({ report, tr, onBack, onRetry, backLabel }) {
|
|
18374
|
-
const [copied, setCopied] =
|
|
18527
|
+
const [copied, setCopied] = React132.useState(false);
|
|
18375
18528
|
const copyDetails = () => {
|
|
18376
18529
|
if (!report || typeof navigator === "undefined" || !navigator.clipboard) return;
|
|
18377
18530
|
const details = [
|
|
@@ -18476,9 +18629,9 @@ function UnitSwitching({ unitName, isAll, onDone }) {
|
|
|
18476
18629
|
const v = t(key);
|
|
18477
18630
|
return !v || v === key ? fallback : v;
|
|
18478
18631
|
};
|
|
18479
|
-
const doneRef =
|
|
18632
|
+
const doneRef = React132.useRef(onDone);
|
|
18480
18633
|
doneRef.current = onDone;
|
|
18481
|
-
|
|
18634
|
+
React132.useEffect(() => {
|
|
18482
18635
|
const id = window.setTimeout(() => doneRef.current(), HOLD_MS);
|
|
18483
18636
|
return () => window.clearTimeout(id);
|
|
18484
18637
|
}, []);
|
|
@@ -18535,11 +18688,11 @@ function UnitPickerDialog() {
|
|
|
18535
18688
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
18536
18689
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
18537
18690
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
18538
|
-
const reachable =
|
|
18691
|
+
const reachable = React132.useMemo(
|
|
18539
18692
|
() => myUnitIds.length > 0 ? myUnitIds : units.filter((u) => u.kind !== "region").map((u) => u.id),
|
|
18540
18693
|
[myUnitIds, units]
|
|
18541
18694
|
);
|
|
18542
|
-
const groups =
|
|
18695
|
+
const groups = React132.useMemo(() => {
|
|
18543
18696
|
const out = [];
|
|
18544
18697
|
if (reachable.length > 1) {
|
|
18545
18698
|
out.push({ id: "_all", options: [{ id: ALL_UNITS, label: "Todas as unidades" }] });
|
|
@@ -18738,16 +18891,16 @@ function WorkspaceSetupFlow({
|
|
|
18738
18891
|
const user = useAuthStore((s) => s.user);
|
|
18739
18892
|
const { switchOrg } = useTenant();
|
|
18740
18893
|
const closeSetup = useWorkspaceSetupStore((s) => s.close);
|
|
18741
|
-
const uploadLogo =
|
|
18894
|
+
const uploadLogo = React132.useMemo(
|
|
18742
18895
|
() => user ? createLogoUploader(user.id) : void 0,
|
|
18743
18896
|
[user?.id]
|
|
18744
18897
|
);
|
|
18745
|
-
const country =
|
|
18898
|
+
const country = React132.useMemo(
|
|
18746
18899
|
() => currency === "BRL" || (locale ?? "").toLowerCase().startsWith("pt") ? "BR" : void 0,
|
|
18747
18900
|
[currency, locale]
|
|
18748
18901
|
);
|
|
18749
|
-
const stepsRef =
|
|
18750
|
-
const analyzeSite =
|
|
18902
|
+
const stepsRef = React132.useRef([]);
|
|
18903
|
+
const analyzeSite = React132.useMemo(
|
|
18751
18904
|
() => createSiteAnalyzer({
|
|
18752
18905
|
apiBaseUrl: resolveFayzApiBaseUrl(),
|
|
18753
18906
|
steps: () => stepsRef.current,
|
|
@@ -18755,7 +18908,7 @@ function WorkspaceSetupFlow({
|
|
|
18755
18908
|
}),
|
|
18756
18909
|
[locale]
|
|
18757
18910
|
);
|
|
18758
|
-
const steps =
|
|
18911
|
+
const steps = React132.useMemo(
|
|
18759
18912
|
() => buildWorkspaceSetupSteps({
|
|
18760
18913
|
verticalId,
|
|
18761
18914
|
uploadLogo,
|
|
@@ -18767,13 +18920,13 @@ function WorkspaceSetupFlow({
|
|
|
18767
18920
|
[verticalId, uploadLogo, media, country, analyzeSite]
|
|
18768
18921
|
);
|
|
18769
18922
|
stepsRef.current = steps;
|
|
18770
|
-
const initialValues2 =
|
|
18923
|
+
const initialValues2 = React132.useMemo(
|
|
18771
18924
|
// Seeding the contact email with the account's own is one field fewer to
|
|
18772
18925
|
// type, and it is right far more often than it is wrong.
|
|
18773
18926
|
() => user?.email ? { "workspace.email": user.email } : {},
|
|
18774
18927
|
[user?.email]
|
|
18775
18928
|
);
|
|
18776
|
-
const onSubmit =
|
|
18929
|
+
const onSubmit = React132.useCallback(
|
|
18777
18930
|
async (values) => {
|
|
18778
18931
|
if (!user) throw new Error(tl("You are signed out.", "Sua sess\xE3o terminou."));
|
|
18779
18932
|
const org = await submitWorkspaceSetup({
|
|
@@ -18890,16 +19043,16 @@ function GettingStartedWidget() {
|
|
|
18890
19043
|
const t = useTranslation();
|
|
18891
19044
|
const rows = useActivationStore((s) => s.rows);
|
|
18892
19045
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18893
|
-
const steps =
|
|
19046
|
+
const steps = React132.useMemo(
|
|
18894
19047
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18895
19048
|
[rows, catalog]
|
|
18896
19049
|
);
|
|
18897
|
-
const onNavigate =
|
|
19050
|
+
const onNavigate = React132.useCallback((path) => {
|
|
18898
19051
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18899
19052
|
navigateTo(path);
|
|
18900
19053
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18901
19054
|
}, []);
|
|
18902
|
-
const onAskAgent =
|
|
19055
|
+
const onAskAgent = React132.useCallback((step) => {
|
|
18903
19056
|
void startGuidedRun(step.id);
|
|
18904
19057
|
}, []);
|
|
18905
19058
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18924,16 +19077,16 @@ function ActivationChecklistCard({
|
|
|
18924
19077
|
}) {
|
|
18925
19078
|
const rows = useActivationStore((s) => s.rows);
|
|
18926
19079
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18927
|
-
const steps =
|
|
19080
|
+
const steps = React132.useMemo(
|
|
18928
19081
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18929
19082
|
[rows, catalog]
|
|
18930
19083
|
);
|
|
18931
|
-
const onNavigate =
|
|
19084
|
+
const onNavigate = React132.useCallback((path) => {
|
|
18932
19085
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18933
19086
|
navigateTo(path);
|
|
18934
19087
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18935
19088
|
}, []);
|
|
18936
|
-
const onAskAgent =
|
|
19089
|
+
const onAskAgent = React132.useCallback((step) => {
|
|
18937
19090
|
void startGuidedRun(step.id);
|
|
18938
19091
|
}, []);
|
|
18939
19092
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18967,12 +19120,12 @@ function rememberCompleted(storageKey2) {
|
|
|
18967
19120
|
}
|
|
18968
19121
|
}
|
|
18969
19122
|
function usePluginOnboardingGate(storageKey2, checkExistingData) {
|
|
18970
|
-
const checkRef =
|
|
19123
|
+
const checkRef = React132.useRef(checkExistingData);
|
|
18971
19124
|
checkRef.current = checkExistingData;
|
|
18972
|
-
const [status, setStatus] =
|
|
19125
|
+
const [status, setStatus] = React132.useState(
|
|
18973
19126
|
() => wasCompleted(storageKey2) ? "complete" : "checking"
|
|
18974
19127
|
);
|
|
18975
|
-
|
|
19128
|
+
React132.useEffect(() => {
|
|
18976
19129
|
if (status !== "checking") return;
|
|
18977
19130
|
let cancelled = false;
|
|
18978
19131
|
void checkRef.current().then((hasData) => {
|
|
@@ -18986,7 +19139,7 @@ function usePluginOnboardingGate(storageKey2, checkExistingData) {
|
|
|
18986
19139
|
cancelled = true;
|
|
18987
19140
|
};
|
|
18988
19141
|
}, [status, storageKey2]);
|
|
18989
|
-
const complete =
|
|
19142
|
+
const complete = React132.useCallback(() => {
|
|
18990
19143
|
rememberCompleted(storageKey2);
|
|
18991
19144
|
setStatus("complete");
|
|
18992
19145
|
}, [storageKey2]);
|
|
@@ -19006,9 +19159,9 @@ function PluginOnboardingGateSkeleton() {
|
|
|
19006
19159
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-72 rounded-card" })
|
|
19007
19160
|
] });
|
|
19008
19161
|
}
|
|
19009
|
-
var WidgetSurfaceContext =
|
|
19162
|
+
var WidgetSurfaceContext = React132.createContext("rail");
|
|
19010
19163
|
function useWidgetSurface() {
|
|
19011
|
-
return
|
|
19164
|
+
return React132.useContext(WidgetSurfaceContext);
|
|
19012
19165
|
}
|
|
19013
19166
|
function WidgetSlot({
|
|
19014
19167
|
zone,
|
|
@@ -19052,7 +19205,7 @@ function useNavContribution(id, entries2) {
|
|
|
19052
19205
|
const setContribution = useNavContributionsStore((s) => s.setContribution);
|
|
19053
19206
|
const clearContribution = useNavContributionsStore((s) => s.clearContribution);
|
|
19054
19207
|
const key = JSON.stringify(entries2);
|
|
19055
|
-
|
|
19208
|
+
React132.useEffect(() => {
|
|
19056
19209
|
setContribution(id, entries2);
|
|
19057
19210
|
return () => clearContribution(id);
|
|
19058
19211
|
}, [id, key]);
|
|
@@ -19122,7 +19275,7 @@ function useAppDirectory() {
|
|
|
19122
19275
|
const tenantId2 = useActiveTenantId();
|
|
19123
19276
|
const apps = useAppDirectoryStore((s) => s.apps);
|
|
19124
19277
|
const load = useAppDirectoryStore((s) => s.load);
|
|
19125
|
-
|
|
19278
|
+
React132.useEffect(() => {
|
|
19126
19279
|
if (tenantId2) void load(tenantId2, resolveAppId());
|
|
19127
19280
|
}, [tenantId2, load]);
|
|
19128
19281
|
return { apps };
|
|
@@ -19214,7 +19367,7 @@ var CSS2 = `
|
|
|
19214
19367
|
}
|
|
19215
19368
|
`;
|
|
19216
19369
|
function useWordmarkStyle() {
|
|
19217
|
-
|
|
19370
|
+
React132.useEffect(() => {
|
|
19218
19371
|
if (typeof document === "undefined") return;
|
|
19219
19372
|
const existing = document.getElementById(STYLE_ID2);
|
|
19220
19373
|
if (existing) {
|
|
@@ -19448,7 +19601,7 @@ var SWAP_CSS = `
|
|
|
19448
19601
|
}
|
|
19449
19602
|
`;
|
|
19450
19603
|
function useSwapStyle() {
|
|
19451
|
-
|
|
19604
|
+
React132.useEffect(() => {
|
|
19452
19605
|
if (typeof document === "undefined" || document.getElementById(SWAP_STYLE_ID)) return;
|
|
19453
19606
|
const el = document.createElement("style");
|
|
19454
19607
|
el.id = SWAP_STYLE_ID;
|
|
@@ -19457,9 +19610,9 @@ function useSwapStyle() {
|
|
|
19457
19610
|
}, []);
|
|
19458
19611
|
}
|
|
19459
19612
|
function AppSwitcherView({ apps, mark, logo, collapsed = false, label: label3, onSelect, brandedByTenant = false }) {
|
|
19460
|
-
const [hovered, setHovered] =
|
|
19461
|
-
const [open, setOpen] =
|
|
19462
|
-
const [pending2, setPending] =
|
|
19613
|
+
const [hovered, setHovered] = React132.useState(false);
|
|
19614
|
+
const [open, setOpen] = React132.useState(false);
|
|
19615
|
+
const [pending2, setPending] = React132.useState(null);
|
|
19463
19616
|
const active2 = hovered || open;
|
|
19464
19617
|
useSwapStyle();
|
|
19465
19618
|
const brand = /* @__PURE__ */ jsx(BrandFace, { mark, logo, collapsed });
|
|
@@ -19606,7 +19759,7 @@ function useContextualNav(nav) {
|
|
|
19606
19759
|
const setNav = useContextualNavStore((s) => s.setNav);
|
|
19607
19760
|
const clearNav = useContextualNavStore((s) => s.clearNav);
|
|
19608
19761
|
const key = nav ? JSON.stringify(nav) : null;
|
|
19609
|
-
|
|
19762
|
+
React132.useEffect(() => {
|
|
19610
19763
|
if (!nav) return;
|
|
19611
19764
|
setNav(nav);
|
|
19612
19765
|
return () => clearNav(nav.base);
|
|
@@ -19678,7 +19831,7 @@ async function findNearestUnit(units, reachable) {
|
|
|
19678
19831
|
}
|
|
19679
19832
|
var UNIT_SEARCH_THRESHOLD = 8;
|
|
19680
19833
|
function WorkspaceUnitSheet({ onClose, canCreate = true }) {
|
|
19681
|
-
const [level, setLevel] =
|
|
19834
|
+
const [level, setLevel] = React132.useState("root");
|
|
19682
19835
|
return /* @__PURE__ */ jsxs(
|
|
19683
19836
|
BottomSheet,
|
|
19684
19837
|
{
|
|
@@ -19741,9 +19894,9 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19741
19894
|
const closeSheet = useSheetClose();
|
|
19742
19895
|
const beginSwitch = useWorkspaceSwitchingStore((s) => s.begin);
|
|
19743
19896
|
const openSetup = useWorkspaceSetupStore((s) => s.open);
|
|
19744
|
-
const [query, setQuery] =
|
|
19897
|
+
const [query, setQuery] = React132.useState("");
|
|
19745
19898
|
const org = tenant?.org ?? null;
|
|
19746
|
-
const options =
|
|
19899
|
+
const options = React132.useMemo(() => {
|
|
19747
19900
|
const list = tenant?.userOrgs ?? [];
|
|
19748
19901
|
if (list.length) return list;
|
|
19749
19902
|
return org ? [{ orgId: org.id, orgName: org.name, orgSlug: org.slug, orgLogoUrl: org.logoUrl }] : [];
|
|
@@ -19752,7 +19905,7 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19752
19905
|
const v = t.t(key);
|
|
19753
19906
|
return !v || v === key ? fallback : v;
|
|
19754
19907
|
};
|
|
19755
|
-
const search =
|
|
19908
|
+
const search = React132.useMemo(
|
|
19756
19909
|
() => searchWorkspaces(options, query, org?.id),
|
|
19757
19910
|
[options, query, org?.id]
|
|
19758
19911
|
);
|
|
@@ -19804,8 +19957,8 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19804
19957
|
function UnitLevel() {
|
|
19805
19958
|
useUnitBootstrap();
|
|
19806
19959
|
const closeSheet = useSheetClose();
|
|
19807
|
-
const [locating, setLocating] =
|
|
19808
|
-
const [query, setQuery] =
|
|
19960
|
+
const [locating, setLocating] = React132.useState(false);
|
|
19961
|
+
const [query, setQuery] = React132.useState("");
|
|
19809
19962
|
const units = useUnitStore((s) => s.units);
|
|
19810
19963
|
const tree = useUnitStore((s) => s.tree);
|
|
19811
19964
|
const byId = useUnitStore((s) => s.byId);
|
|
@@ -19842,7 +19995,7 @@ function UnitLevel() {
|
|
|
19842
19995
|
const leaves = node.children.filter((c) => c.kind !== "region" && reachable.includes(c.id));
|
|
19843
19996
|
const regions = node.children.filter((c) => c.kind === "region");
|
|
19844
19997
|
if (leaves.length === 0 && regions.length === 0) return null;
|
|
19845
|
-
return /* @__PURE__ */ jsxs(
|
|
19998
|
+
return /* @__PURE__ */ jsxs(React132.Fragment, { children: [
|
|
19846
19999
|
/* @__PURE__ */ jsx("p", { className: "px-4 pb-1 pt-3 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
19847
20000
|
leaves.length > 0 && /* @__PURE__ */ jsx(SheetCard, { children: leaves.map(leaf) }),
|
|
19848
20001
|
regions.map(group)
|
|
@@ -19912,7 +20065,7 @@ function UnitLevel() {
|
|
|
19912
20065
|
}
|
|
19913
20066
|
function WorkspaceUnitRow({ canCreate = true }) {
|
|
19914
20067
|
useUnitBootstrap();
|
|
19915
|
-
const [open, setOpen] =
|
|
20068
|
+
const [open, setOpen] = React132.useState(false);
|
|
19916
20069
|
const tenant = useTenantOptional();
|
|
19917
20070
|
const org = tenant?.org ?? null;
|
|
19918
20071
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
@@ -20099,10 +20252,10 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
20099
20252
|
const load = useFayzProjectsStore((s) => s.load);
|
|
20100
20253
|
const loadedFor = useFayzProjectsStore((s) => s.loadedFor);
|
|
20101
20254
|
const collapsed = useLayoutStore((s) => s.sidebarCollapsed);
|
|
20102
|
-
const [selectedId, setSelectedId] =
|
|
20103
|
-
const [hovered, setHovered] =
|
|
20104
|
-
const [primed, setPrimed] =
|
|
20105
|
-
const closeTimer =
|
|
20255
|
+
const [selectedId, setSelectedId] = React132.useState(null);
|
|
20256
|
+
const [hovered, setHovered] = React132.useState(false);
|
|
20257
|
+
const [primed, setPrimed] = React132.useState(false);
|
|
20258
|
+
const closeTimer = React132.useRef(null);
|
|
20106
20259
|
const cancelClose = () => {
|
|
20107
20260
|
if (closeTimer.current) {
|
|
20108
20261
|
clearTimeout(closeTimer.current);
|
|
@@ -20118,8 +20271,8 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
20118
20271
|
cancelClose();
|
|
20119
20272
|
closeTimer.current = setTimeout(() => setHovered(false), 140);
|
|
20120
20273
|
};
|
|
20121
|
-
|
|
20122
|
-
|
|
20274
|
+
React132.useEffect(() => () => cancelClose(), []);
|
|
20275
|
+
React132.useEffect(() => {
|
|
20123
20276
|
if (loadedFor !== (currentOrgId ?? null)) void load(currentOrgId);
|
|
20124
20277
|
}, [currentOrgId, loadedFor, load]);
|
|
20125
20278
|
const active2 = projects.find((p) => p.id === selectedId) ?? defaultProjectOf(projects) ?? synthFromFallback(fallback);
|
|
@@ -20230,10 +20383,10 @@ function SitePreview({
|
|
|
20230
20383
|
onEdit,
|
|
20231
20384
|
tr
|
|
20232
20385
|
}) {
|
|
20233
|
-
const [nonce, setNonce] =
|
|
20234
|
-
const [loading, setLoading] =
|
|
20386
|
+
const [nonce, setNonce] = React132.useState(0);
|
|
20387
|
+
const [loading, setLoading] = React132.useState(true);
|
|
20235
20388
|
const url = previewSourceOf(project);
|
|
20236
|
-
|
|
20389
|
+
React132.useEffect(() => {
|
|
20237
20390
|
setLoading(true);
|
|
20238
20391
|
}, [nonce, url]);
|
|
20239
20392
|
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";
|
|
@@ -20343,10 +20496,10 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
20343
20496
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
20344
20497
|
const setPageSlot = useRightRailStore((s) => s.setPageSlot);
|
|
20345
20498
|
const setWidth = useRightRailStore((s) => s.setWidth);
|
|
20346
|
-
const rootRef =
|
|
20347
|
-
const [actionsSlot, setActionsSlot] =
|
|
20348
|
-
const [leadingSlot, setLeadingSlot] =
|
|
20349
|
-
|
|
20499
|
+
const rootRef = React132.useRef(null);
|
|
20500
|
+
const [actionsSlot, setActionsSlot] = React132.useState(null);
|
|
20501
|
+
const [leadingSlot, setLeadingSlot] = React132.useState(null);
|
|
20502
|
+
React132.useEffect(() => {
|
|
20350
20503
|
if (!open) return;
|
|
20351
20504
|
const el = rootRef.current;
|
|
20352
20505
|
if (!el) return;
|
|
@@ -20368,8 +20521,8 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
20368
20521
|
el.removeEventListener("transitionend", publish);
|
|
20369
20522
|
};
|
|
20370
20523
|
}, [open, setWidth]);
|
|
20371
|
-
const [narrow, setNarrow] =
|
|
20372
|
-
|
|
20524
|
+
const [narrow, setNarrow] = React132.useState(false);
|
|
20525
|
+
React132.useEffect(() => {
|
|
20373
20526
|
if (!open) return;
|
|
20374
20527
|
const el = rootRef.current;
|
|
20375
20528
|
if (!el) return;
|
|
@@ -20732,9 +20885,9 @@ var TYPE_COLORS = {
|
|
|
20732
20885
|
fix: "text-success"
|
|
20733
20886
|
};
|
|
20734
20887
|
function ChangelogFeed({ changelogUrl, className }) {
|
|
20735
|
-
const [entries2, setEntries] =
|
|
20736
|
-
const [loading, setLoading] =
|
|
20737
|
-
|
|
20888
|
+
const [entries2, setEntries] = React132.useState([]);
|
|
20889
|
+
const [loading, setLoading] = React132.useState(false);
|
|
20890
|
+
React132.useEffect(() => {
|
|
20738
20891
|
if (!changelogUrl) return;
|
|
20739
20892
|
setLoading(true);
|
|
20740
20893
|
fetch(changelogUrl).then((r) => r.json()).then((data) => setEntries(data)).catch(() => setEntries([])).finally(() => setLoading(false));
|
|
@@ -20794,7 +20947,7 @@ function NotificationInbox({
|
|
|
20794
20947
|
changelogUrl,
|
|
20795
20948
|
className
|
|
20796
20949
|
}) {
|
|
20797
|
-
const [activeTab, setActiveTab] =
|
|
20950
|
+
const [activeTab, setActiveTab] = React132.useState("inbox");
|
|
20798
20951
|
const unreadCount = notifications.filter((n) => !n.read).length;
|
|
20799
20952
|
const inboxNotifications = notifications.filter((n) => n.category !== "changelog");
|
|
20800
20953
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex w-80 flex-col", className), children: [
|
|
@@ -20891,11 +21044,11 @@ function NotificationInbox({
|
|
|
20891
21044
|
}
|
|
20892
21045
|
function BrandAgentSurface() {
|
|
20893
21046
|
const org = useOrganizationStore((s) => s.currentOrg);
|
|
20894
|
-
const brand =
|
|
21047
|
+
const brand = React132__default.useMemo(
|
|
20895
21048
|
() => normalizeBrand(org?.settings?.branding, { name: org?.name, logoUrl: org?.logoUrl }),
|
|
20896
21049
|
[org?.settings, org?.name, org?.logoUrl]
|
|
20897
21050
|
);
|
|
20898
|
-
const surface =
|
|
21051
|
+
const surface = React132__default.useMemo(() => ({
|
|
20899
21052
|
id: "core.brand",
|
|
20900
21053
|
describe: () => ({
|
|
20901
21054
|
title: "Marca da casa",
|
|
@@ -20908,15 +21061,15 @@ function BrandAgentSurface() {
|
|
|
20908
21061
|
return null;
|
|
20909
21062
|
}
|
|
20910
21063
|
function ConnectConsentPage({ appName, logo }) {
|
|
20911
|
-
const [state, setState] =
|
|
20912
|
-
const [tenantId2, setTenantId] =
|
|
20913
|
-
const request =
|
|
21064
|
+
const [state, setState] = React132__default.useState({ status: "loading" });
|
|
21065
|
+
const [tenantId2, setTenantId] = React132__default.useState("");
|
|
21066
|
+
const request = React132__default.useMemo(
|
|
20914
21067
|
() => new URLSearchParams(window.location.search).get("request") ?? "",
|
|
20915
21068
|
[]
|
|
20916
21069
|
);
|
|
20917
|
-
const connection =
|
|
21070
|
+
const connection = React132__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
20918
21071
|
const product = appName ?? document.title ?? "este app";
|
|
20919
|
-
const authorizedFetch =
|
|
21072
|
+
const authorizedFetch = React132__default.useCallback(
|
|
20920
21073
|
async (path, init) => {
|
|
20921
21074
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
20922
21075
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -20940,7 +21093,7 @@ function ConnectConsentPage({ appName, logo }) {
|
|
|
20940
21093
|
},
|
|
20941
21094
|
[connection]
|
|
20942
21095
|
);
|
|
20943
|
-
|
|
21096
|
+
React132__default.useEffect(() => {
|
|
20944
21097
|
let cancelled = false;
|
|
20945
21098
|
(async () => {
|
|
20946
21099
|
if (!request) {
|
|
@@ -21184,7 +21337,7 @@ function Row2({ label: label3, value }) {
|
|
|
21184
21337
|
function PageActions({ actions, className }) {
|
|
21185
21338
|
const access = useAccessOptional();
|
|
21186
21339
|
const openUpgrade = useUpgradeModalStore((s) => s.open);
|
|
21187
|
-
const resolved =
|
|
21340
|
+
const resolved = React132__default.useMemo(
|
|
21188
21341
|
() => actions.map((a) => {
|
|
21189
21342
|
const { permission, limitKey, onSelect, ...rest } = a;
|
|
21190
21343
|
let hidden = false;
|
|
@@ -21214,25 +21367,25 @@ function AddConnectorPanel({
|
|
|
21214
21367
|
onSelect
|
|
21215
21368
|
}) {
|
|
21216
21369
|
const { t } = useTranslation$1();
|
|
21217
|
-
const [query, setQuery] =
|
|
21370
|
+
const [query, setQuery] = React132__default.useState("");
|
|
21218
21371
|
const modules = useInstalledModuleIds();
|
|
21219
21372
|
const catalog = useConnectorCatalog();
|
|
21220
21373
|
const scoped = !!categories?.length;
|
|
21221
|
-
const addable =
|
|
21374
|
+
const addable = React132__default.useMemo(
|
|
21222
21375
|
() => inCategories(addableConnectors(connectors ?? []), categories),
|
|
21223
21376
|
[connectors, categories]
|
|
21224
21377
|
);
|
|
21225
|
-
const shelf =
|
|
21378
|
+
const shelf = React132__default.useMemo(() => {
|
|
21226
21379
|
if (connectors === null) return [];
|
|
21227
21380
|
return inCategories(
|
|
21228
21381
|
shelfIntegrations({ present: connectors, installedModules: modules, catalog: catalog ?? [] }),
|
|
21229
21382
|
categories
|
|
21230
21383
|
);
|
|
21231
21384
|
}, [connectors, modules, catalog, categories]);
|
|
21232
|
-
const filtered =
|
|
21233
|
-
const filteredShelf =
|
|
21234
|
-
const soon =
|
|
21235
|
-
const elsewhere =
|
|
21385
|
+
const filtered = React132__default.useMemo(() => filterConnectors(addable, "all", query), [addable, query]);
|
|
21386
|
+
const filteredShelf = React132__default.useMemo(() => filterAvailable(shelf, query), [shelf, query]);
|
|
21387
|
+
const soon = React132__default.useMemo(() => comingSoonHere(filteredShelf), [filteredShelf]);
|
|
21388
|
+
const elsewhere = React132__default.useMemo(() => withAnotherModule(filteredShelf), [filteredShelf]);
|
|
21236
21389
|
const searchable = addable.length + shelf.length > 6;
|
|
21237
21390
|
return /* @__PURE__ */ jsx(Modal, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ModalContent, { size: "2xl", children: [
|
|
21238
21391
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
@@ -21390,23 +21543,23 @@ function AddConnectorButton({ onClick }) {
|
|
|
21390
21543
|
}
|
|
21391
21544
|
function ConnectorsTab() {
|
|
21392
21545
|
const { t } = useTranslation$1();
|
|
21393
|
-
const { connectors, error, reload, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
21394
|
-
const [adding, setAdding] =
|
|
21395
|
-
const [selected, setSelected] =
|
|
21396
|
-
const [filter, setFilter] =
|
|
21397
|
-
const [failure, setFailure] =
|
|
21398
|
-
const [revoking, setRevoking] =
|
|
21546
|
+
const { connectors, error, reload: reload2, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
21547
|
+
const [adding, setAdding] = React132__default.useState(false);
|
|
21548
|
+
const [selected, setSelected] = React132__default.useState(null);
|
|
21549
|
+
const [filter, setFilter] = React132__default.useState("all");
|
|
21550
|
+
const [failure, setFailure] = React132__default.useState(null);
|
|
21551
|
+
const [revoking, setRevoking] = React132__default.useState(null);
|
|
21399
21552
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
21400
|
-
const openJourney =
|
|
21553
|
+
const openJourney = React132__default.useCallback(
|
|
21401
21554
|
(connector) => {
|
|
21402
21555
|
if (assistantAvailable) openConnectorsPanel(connector);
|
|
21403
21556
|
else setSelected(connector);
|
|
21404
21557
|
},
|
|
21405
21558
|
[assistantAvailable]
|
|
21406
21559
|
);
|
|
21407
|
-
const visible =
|
|
21408
|
-
const groups =
|
|
21409
|
-
|
|
21560
|
+
const visible = React132__default.useMemo(() => filterConnectors(connectors ?? [], filter), [connectors, filter]);
|
|
21561
|
+
const groups = React132__default.useMemo(() => groupConnectors(visible), [visible]);
|
|
21562
|
+
React132__default.useEffect(() => {
|
|
21410
21563
|
if (!selected || !connectors) return;
|
|
21411
21564
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
21412
21565
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -21441,7 +21594,7 @@ function ConnectorsTab() {
|
|
|
21441
21594
|
(connectors?.length ?? 0) > 4 && /* @__PURE__ */ jsx(Filters, { value: filter, onChange: setFilter }),
|
|
21442
21595
|
connectors === null && /* @__PURE__ */ jsx(ConnectionsSkeleton, {}),
|
|
21443
21596
|
connectors !== null && visible.length === 0 && /* @__PURE__ */ jsx(Empty2, { title: t("connectors.emptyTitle"), body: t("connectors.emptyBody") }),
|
|
21444
|
-
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(
|
|
21597
|
+
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(React132__default.Fragment, { children: [
|
|
21445
21598
|
groups.length > 1 && /* @__PURE__ */ jsx(
|
|
21446
21599
|
"li",
|
|
21447
21600
|
{
|
|
@@ -21458,7 +21611,7 @@ function ConnectorsTab() {
|
|
|
21458
21611
|
connector: selected,
|
|
21459
21612
|
open: !!selected,
|
|
21460
21613
|
onOpenChange: (open) => !open && setSelected(null),
|
|
21461
|
-
onChanged:
|
|
21614
|
+
onChanged: reload2,
|
|
21462
21615
|
onRevoke: (connector) => setRevoking(connector)
|
|
21463
21616
|
}
|
|
21464
21617
|
),
|
|
@@ -21579,7 +21732,7 @@ function oauthFailureMessage(t, result) {
|
|
|
21579
21732
|
function useConnectorOAuthReturn() {
|
|
21580
21733
|
const { t } = useTranslation$1();
|
|
21581
21734
|
const runtime = usePluginRuntimeOptional();
|
|
21582
|
-
|
|
21735
|
+
React132__default.useEffect(() => {
|
|
21583
21736
|
if (typeof window === "undefined") return;
|
|
21584
21737
|
const result = readConnectorOAuthReturn(window.location.search);
|
|
21585
21738
|
if (!result) return;
|
|
@@ -21614,8 +21767,8 @@ function ConnectorDeliveries({
|
|
|
21614
21767
|
limit = 10
|
|
21615
21768
|
}) {
|
|
21616
21769
|
const { t } = useTranslation$1();
|
|
21617
|
-
const [rows, setRows] =
|
|
21618
|
-
|
|
21770
|
+
const [rows, setRows] = React132__default.useState(null);
|
|
21771
|
+
React132__default.useEffect(() => {
|
|
21619
21772
|
let cancelled = false;
|
|
21620
21773
|
void load({ limit }).then((r) => {
|
|
21621
21774
|
if (!cancelled) setRows(r);
|
|
@@ -21689,11 +21842,11 @@ var CURRENCIES = [
|
|
|
21689
21842
|
function CompanySettings({ tenant, onSave }) {
|
|
21690
21843
|
const { t } = useTranslation$1();
|
|
21691
21844
|
const { locale: uiLocale, setLocale: setUiLocale } = useLocaleStore();
|
|
21692
|
-
const [name, setName] =
|
|
21693
|
-
const [timezone, setTimezone] =
|
|
21694
|
-
const [currency, setCurrency] =
|
|
21695
|
-
const [saving, setSaving] =
|
|
21696
|
-
|
|
21845
|
+
const [name, setName] = React132.useState(tenant?.name ?? "");
|
|
21846
|
+
const [timezone, setTimezone] = React132.useState(tenant?.settings?.timezone ?? "UTC");
|
|
21847
|
+
const [currency, setCurrency] = React132.useState(tenant?.settings?.currency ?? "USD");
|
|
21848
|
+
const [saving, setSaving] = React132.useState(false);
|
|
21849
|
+
React132.useEffect(() => {
|
|
21697
21850
|
if (tenant) {
|
|
21698
21851
|
setName(tenant.name);
|
|
21699
21852
|
setTimezone(tenant.settings?.timezone ?? "UTC");
|
|
@@ -21785,15 +21938,15 @@ function UnitModeCard() {
|
|
|
21785
21938
|
const units = useUnitStore((s) => s.units);
|
|
21786
21939
|
const setMode = useUnitStore((s) => s.setMode);
|
|
21787
21940
|
const load = useUnitStore((s) => s.load);
|
|
21788
|
-
const [unbound, setUnbound] =
|
|
21789
|
-
const [bindEveryone, setBindEveryone] =
|
|
21790
|
-
const [pending2, setPending] =
|
|
21791
|
-
const [saving, setSaving] =
|
|
21792
|
-
const headquarters =
|
|
21941
|
+
const [unbound, setUnbound] = React132.useState(null);
|
|
21942
|
+
const [bindEveryone, setBindEveryone] = React132.useState(true);
|
|
21943
|
+
const [pending2, setPending] = React132.useState(null);
|
|
21944
|
+
const [saving, setSaving] = React132.useState(false);
|
|
21945
|
+
const headquarters = React132.useMemo(
|
|
21793
21946
|
() => units.find((u) => u.isHeadquarters && u.kind !== "region") ?? units.find((u) => u.kind !== "region"),
|
|
21794
21947
|
[units]
|
|
21795
21948
|
);
|
|
21796
|
-
|
|
21949
|
+
React132.useEffect(() => {
|
|
21797
21950
|
if (!org?.id || unitMode) return;
|
|
21798
21951
|
let alive = true;
|
|
21799
21952
|
void countUnboundMembers(org.id).then((n) => {
|
|
@@ -21957,10 +22110,10 @@ function getInitials(name) {
|
|
|
21957
22110
|
}
|
|
21958
22111
|
function UserProfile({ user, onSave, onAvatarChange }) {
|
|
21959
22112
|
const { t } = useTranslation$1();
|
|
21960
|
-
const [fullName, setFullName] =
|
|
21961
|
-
const [saving, setSaving] =
|
|
21962
|
-
const fileInputRef =
|
|
21963
|
-
|
|
22113
|
+
const [fullName, setFullName] = React132.useState(user?.fullName ?? "");
|
|
22114
|
+
const [saving, setSaving] = React132.useState(false);
|
|
22115
|
+
const fileInputRef = React132.useRef(null);
|
|
22116
|
+
React132.useEffect(() => {
|
|
21964
22117
|
if (user) {
|
|
21965
22118
|
setFullName(user.fullName);
|
|
21966
22119
|
}
|
|
@@ -22100,8 +22253,8 @@ async function fetchMyPersonId(tenantId2, userId) {
|
|
|
22100
22253
|
function useMyPersonId(enabled = true) {
|
|
22101
22254
|
const orgId = useOrganizationStore((s) => s.currentOrg?.id);
|
|
22102
22255
|
const userId = useAuthStore((s) => s.user?.id);
|
|
22103
|
-
const [personId, setPersonId] =
|
|
22104
|
-
|
|
22256
|
+
const [personId, setPersonId] = React132.useState(void 0);
|
|
22257
|
+
React132.useEffect(() => {
|
|
22105
22258
|
if (!enabled || !orgId || !userId) return;
|
|
22106
22259
|
let alive = true;
|
|
22107
22260
|
void dedup(`self:person:${orgId}:${userId}`, () => fetchMyPersonId(orgId, userId)).then((id) => {
|
|
@@ -22161,18 +22314,18 @@ function MyWorkspaceCard() {
|
|
|
22161
22314
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
22162
22315
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
22163
22316
|
const entryReason = useUnitStore((s) => s.entryReason);
|
|
22164
|
-
const [person, setPerson] =
|
|
22165
|
-
const [candidate, setCandidate] =
|
|
22166
|
-
const [linking, setLinking] =
|
|
22317
|
+
const [person, setPerson] = React132.useState(void 0);
|
|
22318
|
+
const [candidate, setCandidate] = React132.useState(null);
|
|
22319
|
+
const [linking, setLinking] = React132.useState(false);
|
|
22167
22320
|
const orgId = currentOrg?.id;
|
|
22168
22321
|
const userId = user?.id;
|
|
22169
|
-
const load =
|
|
22322
|
+
const load = React132.useCallback(async () => {
|
|
22170
22323
|
if (!orgId || !userId) return;
|
|
22171
22324
|
const linked = await fetchMyPersonRecord(orgId, userId);
|
|
22172
22325
|
setPerson(linked);
|
|
22173
22326
|
setCandidate(linked ? null : await findMyPersonCandidate(orgId, user?.email, staffKinds));
|
|
22174
22327
|
}, [orgId, userId, user?.email, staffKinds]);
|
|
22175
|
-
|
|
22328
|
+
React132.useEffect(() => {
|
|
22176
22329
|
void load();
|
|
22177
22330
|
}, [load]);
|
|
22178
22331
|
if (!currentOrg) return null;
|
|
@@ -22266,10 +22419,10 @@ var useStore = create((set) => ({
|
|
|
22266
22419
|
function useHeaderAction(zone, action) {
|
|
22267
22420
|
const register = useStore((s) => s.register);
|
|
22268
22421
|
const unregister = useStore((s) => s.unregister);
|
|
22269
|
-
const latest =
|
|
22422
|
+
const latest = React132.useRef(action);
|
|
22270
22423
|
latest.current = action;
|
|
22271
22424
|
const id = action?.id;
|
|
22272
|
-
|
|
22425
|
+
React132.useEffect(() => {
|
|
22273
22426
|
if (!zone || !id) return;
|
|
22274
22427
|
const current2 = latest.current;
|
|
22275
22428
|
if (current2) register(zone, { ...current2, onSelect: () => latest.current?.onSelect() });
|
|
@@ -22278,7 +22431,7 @@ function useHeaderAction(zone, action) {
|
|
|
22278
22431
|
}
|
|
22279
22432
|
function useHeaderActions(zone) {
|
|
22280
22433
|
const byZone = useStore((s) => s.byZone);
|
|
22281
|
-
return
|
|
22434
|
+
return React132.useMemo(() => Object.values(byZone[zone] ?? {}), [byZone, zone]);
|
|
22282
22435
|
}
|
|
22283
22436
|
function useUserLabel(userId) {
|
|
22284
22437
|
const members = useOrganizationStore((s) => s.members);
|
|
@@ -23285,12 +23438,12 @@ function CrudRecordModal({
|
|
|
23285
23438
|
essentialFirst,
|
|
23286
23439
|
notice
|
|
23287
23440
|
}) {
|
|
23288
|
-
const [record, setRecord] =
|
|
23289
|
-
const [loading, setLoading] =
|
|
23290
|
-
const [saving, setSaving] =
|
|
23291
|
-
const [error, setError] =
|
|
23292
|
-
const formId =
|
|
23293
|
-
|
|
23441
|
+
const [record, setRecord] = React132.useState(null);
|
|
23442
|
+
const [loading, setLoading] = React132.useState(false);
|
|
23443
|
+
const [saving, setSaving] = React132.useState(false);
|
|
23444
|
+
const [error, setError] = React132.useState(null);
|
|
23445
|
+
const formId = React132.useId();
|
|
23446
|
+
React132.useEffect(() => {
|
|
23294
23447
|
if (!open) return;
|
|
23295
23448
|
setError(null);
|
|
23296
23449
|
if (mode === "create" || !load) {
|
|
@@ -23468,10 +23621,10 @@ function resolveRelation(relation, row) {
|
|
|
23468
23621
|
}
|
|
23469
23622
|
return { ...relation, filter: { ...relation.filter ?? {}, ...extra } };
|
|
23470
23623
|
}
|
|
23471
|
-
var PendingChildrenContext =
|
|
23624
|
+
var PendingChildrenContext = React132.createContext(null);
|
|
23472
23625
|
function usePendingChildren() {
|
|
23473
|
-
const pending2 =
|
|
23474
|
-
const provider2 =
|
|
23626
|
+
const pending2 = React132.useRef(/* @__PURE__ */ new Set());
|
|
23627
|
+
const provider2 = React132.useMemo(() => ({
|
|
23475
23628
|
register: (f) => {
|
|
23476
23629
|
pending2.current.add(f);
|
|
23477
23630
|
return () => {
|
|
@@ -23479,7 +23632,7 @@ function usePendingChildren() {
|
|
|
23479
23632
|
};
|
|
23480
23633
|
}
|
|
23481
23634
|
}), []);
|
|
23482
|
-
const flush =
|
|
23635
|
+
const flush = React132.useCallback(async (parentId) => {
|
|
23483
23636
|
for (const f of [...pending2.current]) await f(parentId);
|
|
23484
23637
|
}, []);
|
|
23485
23638
|
return { provider: provider2, flush };
|
|
@@ -23495,7 +23648,7 @@ function money(value) {
|
|
|
23495
23648
|
}
|
|
23496
23649
|
}
|
|
23497
23650
|
function GridRelationCell({ field, value, row, onChange }) {
|
|
23498
|
-
const relation =
|
|
23651
|
+
const relation = React132.useMemo(() => resolveRelation(field.relation, row), [field.relation, row]);
|
|
23499
23652
|
const { labelFor: labelFor2 } = useRelationOptions(relation);
|
|
23500
23653
|
const label3 = value ? labelFor2(value) : "";
|
|
23501
23654
|
return /* @__PURE__ */ jsx(
|
|
@@ -23526,11 +23679,11 @@ function columnOf(entity, key) {
|
|
|
23526
23679
|
}
|
|
23527
23680
|
function RelatedSection({ parentId, related, compact }) {
|
|
23528
23681
|
const orfa = !parentId;
|
|
23529
|
-
const pendentes =
|
|
23682
|
+
const pendentes = React132.useContext(PendingChildrenContext);
|
|
23530
23683
|
const fkColumn = columnOf(related.entity, related.foreignKey);
|
|
23531
23684
|
const label3 = related.label ?? related.entity.namePlural ?? related.entity.name;
|
|
23532
23685
|
const Icon = related.icon ? ICON_MAP[related.icon] ?? null : null;
|
|
23533
|
-
const child =
|
|
23686
|
+
const child = React132.useMemo(() => ({
|
|
23534
23687
|
...related.entity,
|
|
23535
23688
|
fields: related.entity.fields.filter((f) => f.key !== related.foreignKey),
|
|
23536
23689
|
data: related.entity.data ? {
|
|
@@ -23539,13 +23692,13 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23539
23692
|
defaults: { ...related.entity.data.defaults ?? {}, [fkColumn]: parentId }
|
|
23540
23693
|
} : void 0
|
|
23541
23694
|
}), [related, parentId, fkColumn]);
|
|
23542
|
-
const provider2 =
|
|
23543
|
-
const [rows, setRows] =
|
|
23544
|
-
const [loading, setLoading] =
|
|
23545
|
-
const [error, setError] =
|
|
23546
|
-
const [adding, setAdding] =
|
|
23547
|
-
const [draft, setDraft] =
|
|
23548
|
-
const load =
|
|
23695
|
+
const provider2 = React132.useMemo(() => resolveDataProvider(child, [], { cache: false }), [child]);
|
|
23696
|
+
const [rows, setRows] = React132.useState([]);
|
|
23697
|
+
const [loading, setLoading] = React132.useState(true);
|
|
23698
|
+
const [error, setError] = React132.useState(null);
|
|
23699
|
+
const [adding, setAdding] = React132.useState(false);
|
|
23700
|
+
const [draft, setDraft] = React132.useState(null);
|
|
23701
|
+
const load = React132.useCallback(async () => {
|
|
23549
23702
|
if (orfa) {
|
|
23550
23703
|
setLoading(false);
|
|
23551
23704
|
return;
|
|
@@ -23561,12 +23714,12 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23561
23714
|
setLoading(false);
|
|
23562
23715
|
}
|
|
23563
23716
|
}, [provider2, orfa]);
|
|
23564
|
-
|
|
23717
|
+
React132.useEffect(() => {
|
|
23565
23718
|
void load();
|
|
23566
23719
|
}, [load]);
|
|
23567
|
-
const guardadas =
|
|
23720
|
+
const guardadas = React132.useRef([]);
|
|
23568
23721
|
guardadas.current = rows;
|
|
23569
|
-
|
|
23722
|
+
React132.useEffect(() => {
|
|
23570
23723
|
if (!orfa || !pendentes) return;
|
|
23571
23724
|
return pendentes.register(async (novoPai) => {
|
|
23572
23725
|
if (!guardadas.current.length) return;
|
|
@@ -23590,7 +23743,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23590
23743
|
}
|
|
23591
23744
|
const shown = child.fields.filter((f) => f.showInTable !== false);
|
|
23592
23745
|
const groupKey = related.duplicable ? child.fields.find((f) => f.type === "relation")?.key : void 0;
|
|
23593
|
-
const [lastEdit, setLastEdit] =
|
|
23746
|
+
const [lastEdit, setLastEdit] = React132.useState(null);
|
|
23594
23747
|
function siblingsToSync(row, key) {
|
|
23595
23748
|
if (!groupKey || key === groupKey || row[groupKey] == null) return [];
|
|
23596
23749
|
return rows.filter((r) => r.id !== row.id && r[groupKey] === row[groupKey] && r[key] !== row[key]);
|
|
@@ -23621,7 +23774,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23621
23774
|
if (orfa) return;
|
|
23622
23775
|
queueWrite(id, mudanca, antes);
|
|
23623
23776
|
}
|
|
23624
|
-
const escritas =
|
|
23777
|
+
const escritas = React132.useRef(/* @__PURE__ */ new Map());
|
|
23625
23778
|
function queueWrite(id, mudanca, antes) {
|
|
23626
23779
|
const atual = escritas.current.get(id);
|
|
23627
23780
|
const entry = atual ?? { mudanca: {}, antes, fila: Promise.resolve() };
|
|
@@ -23650,7 +23803,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23650
23803
|
if (e && e.fila === fila && !e.timer) escritas.current.delete(id);
|
|
23651
23804
|
});
|
|
23652
23805
|
}
|
|
23653
|
-
|
|
23806
|
+
React132.useEffect(() => () => {
|
|
23654
23807
|
for (const [id, e] of escritas.current) {
|
|
23655
23808
|
if (e.timer) {
|
|
23656
23809
|
clearTimeout(e.timer);
|
|
@@ -23659,7 +23812,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23659
23812
|
}
|
|
23660
23813
|
}, []);
|
|
23661
23814
|
const required = child.fields.filter((f) => f.required);
|
|
23662
|
-
const criando =
|
|
23815
|
+
const criando = React132.useRef(false);
|
|
23663
23816
|
async function commitDraft(key, next, price) {
|
|
23664
23817
|
const completo = { ...next, ...heranca(key, price, next) };
|
|
23665
23818
|
setDraft(completo);
|
|
@@ -24492,7 +24645,7 @@ function SubjectFormLayout({ fields, allFields, fieldGroups, values, onChange, r
|
|
|
24492
24645
|
const IconComponent = getLucideIcon(entityIcon ?? "Heart") ?? Heart;
|
|
24493
24646
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
24494
24647
|
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: "pt-5", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-5", children: [
|
|
24495
|
-
/* @__PURE__ */ jsx("div", { className: "flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary", children:
|
|
24648
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: React132__default.createElement(IconComponent, { className: "h-8 w-8" }) }),
|
|
24496
24649
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-4", children: [
|
|
24497
24650
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-4", children: [
|
|
24498
24651
|
nameField && /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-1.5", children: [
|
|
@@ -24974,7 +25127,7 @@ function getDefaultValues(fields) {
|
|
|
24974
25127
|
}
|
|
24975
25128
|
return values;
|
|
24976
25129
|
}
|
|
24977
|
-
var SetFieldValueContext =
|
|
25130
|
+
var SetFieldValueContext = React132__default.createContext(void 0);
|
|
24978
25131
|
function renderField(field, value, onChange, allValues = {}, selectPlaceholder, setValue) {
|
|
24979
25132
|
const baseClass = "flex h-9 w-full rounded-input border border-input bg-background px-3 py-1.5 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50";
|
|
24980
25133
|
switch (field.type) {
|
|
@@ -25221,14 +25374,14 @@ function ImageSlot({
|
|
|
25221
25374
|
onDraftFile
|
|
25222
25375
|
}) {
|
|
25223
25376
|
const t = useTranslation();
|
|
25224
|
-
const inputRef =
|
|
25225
|
-
const [url, setUrl] =
|
|
25226
|
-
const [busy, setBusy] =
|
|
25227
|
-
const [error, setError] =
|
|
25228
|
-
const draftUrlRef =
|
|
25377
|
+
const inputRef = React132__default.useRef(null);
|
|
25378
|
+
const [url, setUrl] = React132__default.useState(() => image.get(row));
|
|
25379
|
+
const [busy, setBusy] = React132__default.useState(false);
|
|
25380
|
+
const [error, setError] = React132__default.useState(null);
|
|
25381
|
+
const draftUrlRef = React132__default.useRef(null);
|
|
25229
25382
|
const currentUrl = image.get(row);
|
|
25230
25383
|
const draftFile = image.draftField ? row[image.draftField] : void 0;
|
|
25231
|
-
|
|
25384
|
+
React132__default.useEffect(() => {
|
|
25232
25385
|
if (draftFile) return;
|
|
25233
25386
|
if (draftUrlRef.current) {
|
|
25234
25387
|
URL.revokeObjectURL(draftUrlRef.current);
|
|
@@ -25236,7 +25389,7 @@ function ImageSlot({
|
|
|
25236
25389
|
}
|
|
25237
25390
|
setUrl(currentUrl);
|
|
25238
25391
|
}, [currentUrl, draftFile]);
|
|
25239
|
-
|
|
25392
|
+
React132__default.useEffect(() => () => {
|
|
25240
25393
|
if (draftUrlRef.current) URL.revokeObjectURL(draftUrlRef.current);
|
|
25241
25394
|
}, []);
|
|
25242
25395
|
const acceptsDraft = !canEdit && Boolean(image.draftField && onDraftFile);
|
|
@@ -25386,7 +25539,7 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25386
25539
|
const [values, setValues] = useState(computeInit);
|
|
25387
25540
|
const [saving, setSaving] = useState(false);
|
|
25388
25541
|
const [invalidKeys, setInvalidKeys] = useState(EMPTY_KEYS);
|
|
25389
|
-
const initialRef =
|
|
25542
|
+
const initialRef = React132__default.useRef(JSON.stringify(values));
|
|
25390
25543
|
useEffect(() => {
|
|
25391
25544
|
const init = computeInit();
|
|
25392
25545
|
setValues(init);
|
|
@@ -25446,7 +25599,7 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25446
25599
|
if (submitRef) submitRef.current = () => {
|
|
25447
25600
|
void submit();
|
|
25448
25601
|
};
|
|
25449
|
-
|
|
25602
|
+
React132__default.useEffect(() => () => {
|
|
25450
25603
|
if (submitRef) submitRef.current = null;
|
|
25451
25604
|
}, [submitRef]);
|
|
25452
25605
|
const dirty = JSON.stringify(values) !== initialRef.current;
|
|
@@ -26015,16 +26168,16 @@ function useUnitFilter(options = {}) {
|
|
|
26015
26168
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
26016
26169
|
const can = usePermissionOptional();
|
|
26017
26170
|
const canManageUnits = can("units", "manage");
|
|
26018
|
-
const reachable =
|
|
26019
|
-
const [local2, setLocal] =
|
|
26020
|
-
|
|
26171
|
+
const reachable = React132.useMemo(() => unitFilterOptions(units, myUnitIds), [units, myUnitIds]);
|
|
26172
|
+
const [local2, setLocal] = React132.useState(activeUnitId);
|
|
26173
|
+
React132.useEffect(() => {
|
|
26021
26174
|
setLocal(activeUnitId);
|
|
26022
26175
|
}, [activeUnitId]);
|
|
26023
26176
|
const raw = scope === "global" ? activeUnitId : local2;
|
|
26024
26177
|
const value = standableUnit(raw, reachable);
|
|
26025
26178
|
const filterLabel = label(t, "units.filterLabel", "Unidade");
|
|
26026
26179
|
const allLabel = label(t, "units.filterAll", "Todas as minhas unidades");
|
|
26027
|
-
const setValue =
|
|
26180
|
+
const setValue = React132.useCallback((next) => {
|
|
26028
26181
|
if (scope === "global") {
|
|
26029
26182
|
if (next === activeUnitId) return;
|
|
26030
26183
|
beginSwitch({ unitId: next, unitName: next ? byId[next]?.name ?? "" : allLabel });
|
|
@@ -26033,7 +26186,7 @@ function useUnitFilter(options = {}) {
|
|
|
26033
26186
|
setLocal(next);
|
|
26034
26187
|
}, [scope, activeUnitId, beginSwitch, byId, allLabel]);
|
|
26035
26188
|
const visible = unitFilterVisible(unitMode, reachable);
|
|
26036
|
-
const def =
|
|
26189
|
+
const def = React132.useMemo(() => visible ? {
|
|
26037
26190
|
id: "unit",
|
|
26038
26191
|
label: filterLabel,
|
|
26039
26192
|
icon: Building2,
|
|
@@ -26114,6 +26267,7 @@ function CrudListView({
|
|
|
26114
26267
|
// que está visível — o dropdown de ordenar ao lado da busca lista todos
|
|
26115
26268
|
// os campos e diz a direção com todas as letras.
|
|
26116
26269
|
enableSorting: false,
|
|
26270
|
+
meta: { truncate: true },
|
|
26117
26271
|
cell: ({ row }) => {
|
|
26118
26272
|
const value = row.original[col.key];
|
|
26119
26273
|
const rendered = col.render(value, row.original);
|
|
@@ -26175,7 +26329,7 @@ function CrudListView({
|
|
|
26175
26329
|
if (onImport) {
|
|
26176
26330
|
createRoutes.push({ id: "import", label: t("crud.import.action"), description: t("crud.import.hint"), icon: "Upload", action: onImport });
|
|
26177
26331
|
}
|
|
26178
|
-
const createActions =
|
|
26332
|
+
const createActions = React132__default.useMemo(() => {
|
|
26179
26333
|
const out = createRoutes.map((qa, i) => ({
|
|
26180
26334
|
id: qa.id,
|
|
26181
26335
|
label: qa.label,
|
|
@@ -26588,9 +26742,9 @@ function buildCrudSurfaceContribution(read3) {
|
|
|
26588
26742
|
};
|
|
26589
26743
|
}
|
|
26590
26744
|
function CrudAgentSurface(props) {
|
|
26591
|
-
const ref =
|
|
26745
|
+
const ref = React132.useRef(props);
|
|
26592
26746
|
ref.current = props;
|
|
26593
|
-
const contribution =
|
|
26747
|
+
const contribution = React132.useMemo(
|
|
26594
26748
|
() => buildCrudSurfaceContribution(() => ref.current),
|
|
26595
26749
|
[]
|
|
26596
26750
|
);
|
|
@@ -26643,7 +26797,7 @@ function useFieldRules(entityKey) {
|
|
|
26643
26797
|
};
|
|
26644
26798
|
}, [entityKey, fieldRules]);
|
|
26645
26799
|
}
|
|
26646
|
-
var ImportWizard2 =
|
|
26800
|
+
var ImportWizard2 = React132__default.lazy(
|
|
26647
26801
|
() => import('./ImportWizard-7UFB2PPF.js').then((m) => ({ default: m.ImportWizard }))
|
|
26648
26802
|
);
|
|
26649
26803
|
var PAGE_SIZE = 50;
|
|
@@ -26705,6 +26859,7 @@ function useCrudColumns(entityDef, options) {
|
|
|
26705
26859
|
// coluna transformava a linha de títulos numa fileira de botões e ainda
|
|
26706
26860
|
// só alcançava as colunas visíveis. Ver o dropdown em CrudListView.
|
|
26707
26861
|
enableSorting: false,
|
|
26862
|
+
meta: { truncate: true },
|
|
26708
26863
|
cell: ({ row }) => {
|
|
26709
26864
|
const value = row.original[col.key];
|
|
26710
26865
|
const rendered = col.render(value, row.original);
|
|
@@ -26859,7 +27014,7 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
26859
27014
|
toast.success(t("crud.list.duplicated", { entity: entityDef.name }));
|
|
26860
27015
|
setCrudHash(normalizedBasePath, created.id, "edit");
|
|
26861
27016
|
} catch (err) {
|
|
26862
|
-
toast.error(
|
|
27017
|
+
toast.error(describeError(err));
|
|
26863
27018
|
}
|
|
26864
27019
|
}, [entityDef, store, t, normalizedBasePath]);
|
|
26865
27020
|
const tanColumns = useCrudColumns(entityDef, {
|
|
@@ -27164,7 +27319,7 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
27164
27319
|
console.error("[crud] deactivate failed", err);
|
|
27165
27320
|
toast.error(t("crud.list.deleteFailed", {
|
|
27166
27321
|
entity: entityDef.name.toLowerCase(),
|
|
27167
|
-
reason:
|
|
27322
|
+
reason: describeError(err)
|
|
27168
27323
|
}));
|
|
27169
27324
|
} finally {
|
|
27170
27325
|
navigateToList();
|
|
@@ -27177,7 +27332,7 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
27177
27332
|
console.error("[crud] delete failed", err);
|
|
27178
27333
|
toast.error(t("crud.list.deleteFailed", {
|
|
27179
27334
|
entity: entityDef.name.toLowerCase(),
|
|
27180
|
-
reason:
|
|
27335
|
+
reason: describeError(err)
|
|
27181
27336
|
}));
|
|
27182
27337
|
} finally {
|
|
27183
27338
|
navigateToList();
|
|
@@ -27215,7 +27370,7 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
27215
27370
|
mode: softDelete ? "deactivate" : "delete"
|
|
27216
27371
|
}
|
|
27217
27372
|
),
|
|
27218
|
-
/* @__PURE__ */ jsx(
|
|
27373
|
+
/* @__PURE__ */ jsx(React132__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
27219
27374
|
ImportWizard2,
|
|
27220
27375
|
{
|
|
27221
27376
|
open: importOpen,
|
|
@@ -27556,7 +27711,7 @@ function columnOf2(entity, key) {
|
|
|
27556
27711
|
function RelatedListTab({ item, related, parentTabId }) {
|
|
27557
27712
|
const parentId = item?.id;
|
|
27558
27713
|
const pathname = useHashPath();
|
|
27559
|
-
const Page =
|
|
27714
|
+
const Page = React132.useMemo(() => {
|
|
27560
27715
|
if (!parentId) return null;
|
|
27561
27716
|
const child = related.entity;
|
|
27562
27717
|
const fkColumn = columnOf2(child, related.foreignKey);
|
|
@@ -27596,8 +27751,8 @@ function nestedBasePath(pathname, parentTabId, childId) {
|
|
|
27596
27751
|
}
|
|
27597
27752
|
function useHashPath() {
|
|
27598
27753
|
const read3 = () => typeof window === "undefined" ? "/" : window.location.hash.slice(1) || "/";
|
|
27599
|
-
const [path, setPath] =
|
|
27600
|
-
|
|
27754
|
+
const [path, setPath] = React132.useState(read3);
|
|
27755
|
+
React132.useEffect(() => {
|
|
27601
27756
|
const handler = () => setPath(read3());
|
|
27602
27757
|
window.addEventListener("hashchange", handler);
|
|
27603
27758
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -27677,7 +27832,7 @@ function RoleSummary({ roleId }) {
|
|
|
27677
27832
|
const profile = usePermissionsStore((s) => s.profiles.find((p) => p.id === roleId));
|
|
27678
27833
|
const features = usePermissionsStore((s) => s.features);
|
|
27679
27834
|
const canEditRoles = useSystemPermission()("manage_permissions");
|
|
27680
|
-
const groups =
|
|
27835
|
+
const groups = React132.useMemo(() => {
|
|
27681
27836
|
const map = /* @__PURE__ */ new Map();
|
|
27682
27837
|
for (const feature of features) {
|
|
27683
27838
|
const group = feature.group ?? t("crud.archetype.access.generalGroup");
|
|
@@ -27730,33 +27885,33 @@ function AccessTab({ item }) {
|
|
|
27730
27885
|
const hasSystemPermission = useSystemPermission();
|
|
27731
27886
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
27732
27887
|
const guardSeats = useLimitGuard("users");
|
|
27733
|
-
const [access, setAccess] =
|
|
27734
|
-
const [email, setEmail] =
|
|
27735
|
-
const [roleId, setRoleId] =
|
|
27736
|
-
const [busy, setBusy] =
|
|
27737
|
-
const [confirmRemove, setConfirmRemove] =
|
|
27888
|
+
const [access, setAccess] = React132.useState(void 0);
|
|
27889
|
+
const [email, setEmail] = React132.useState(person?.email ?? "");
|
|
27890
|
+
const [roleId, setRoleId] = React132.useState("");
|
|
27891
|
+
const [busy, setBusy] = React132.useState(false);
|
|
27892
|
+
const [confirmRemove, setConfirmRemove] = React132.useState(false);
|
|
27738
27893
|
const suggestedRoleId = person?.metadata?.access?.suggested_role_id;
|
|
27739
|
-
|
|
27894
|
+
React132.useEffect(() => {
|
|
27740
27895
|
if (roleId || !profiles.length) return;
|
|
27741
27896
|
const sugerido = suggestedRoleId ? profiles.find((p) => p.id === suggestedRoleId) : void 0;
|
|
27742
27897
|
setRoleId(sugerido ? sugerido.id : profiles[1]?.id ?? profiles[0].id);
|
|
27743
27898
|
}, [profiles, roleId, suggestedRoleId]);
|
|
27744
|
-
|
|
27899
|
+
React132.useEffect(() => {
|
|
27745
27900
|
setEmail(person?.email ?? "");
|
|
27746
27901
|
}, [person?.email]);
|
|
27747
|
-
const
|
|
27902
|
+
const reload2 = React132.useCallback(async () => {
|
|
27748
27903
|
if (!personId) return;
|
|
27749
27904
|
setAccess(await fetchPersonAccess(personId));
|
|
27750
27905
|
}, [personId]);
|
|
27751
|
-
|
|
27752
|
-
void
|
|
27753
|
-
}, [
|
|
27754
|
-
|
|
27906
|
+
React132.useEffect(() => {
|
|
27907
|
+
void reload2();
|
|
27908
|
+
}, [reload2]);
|
|
27909
|
+
React132.useEffect(() => {
|
|
27755
27910
|
if (!adapter || !currentOrg || invites.length > 0) return;
|
|
27756
27911
|
adapter.listInvites(currentOrg.id).then(setInvites).catch(() => {
|
|
27757
27912
|
});
|
|
27758
27913
|
}, [adapter, currentOrg?.id]);
|
|
27759
|
-
const pendingInvite =
|
|
27914
|
+
const pendingInvite = React132.useMemo(() => {
|
|
27760
27915
|
const target = (person?.email ?? "").trim().toLowerCase();
|
|
27761
27916
|
if (!target) return void 0;
|
|
27762
27917
|
return invites.find((i) => i.status === "pending" && i.email.toLowerCase() === target);
|
|
@@ -27793,7 +27948,7 @@ function AccessTab({ item }) {
|
|
|
27793
27948
|
setBusy(true);
|
|
27794
27949
|
try {
|
|
27795
27950
|
await adapter.updateMemberProfile(currentOrg.id, access.memberId, nextRole);
|
|
27796
|
-
await
|
|
27951
|
+
await reload2();
|
|
27797
27952
|
} catch (err) {
|
|
27798
27953
|
toast.error(t("crud.archetype.access.roleFailed"), { description: err?.message });
|
|
27799
27954
|
} finally {
|
|
@@ -27805,7 +27960,7 @@ function AccessTab({ item }) {
|
|
|
27805
27960
|
setBusy(true);
|
|
27806
27961
|
try {
|
|
27807
27962
|
await adapter.removeMember(currentOrg.id, access.memberId);
|
|
27808
|
-
await
|
|
27963
|
+
await reload2();
|
|
27809
27964
|
invalidateLimit("users");
|
|
27810
27965
|
toast.success(t("crud.archetype.access.removed"));
|
|
27811
27966
|
} catch (err) {
|
|
@@ -27971,11 +28126,11 @@ function PersonUnitsTab({ item }) {
|
|
|
27971
28126
|
const units = useUnitStore((s) => s.units);
|
|
27972
28127
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
27973
28128
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
27974
|
-
const [userId, setUserId] =
|
|
27975
|
-
const [bindings, setBindings] =
|
|
27976
|
-
const [busy, setBusy] =
|
|
28129
|
+
const [userId, setUserId] = React132.useState(void 0);
|
|
28130
|
+
const [bindings, setBindings] = React132.useState({});
|
|
28131
|
+
const [busy, setBusy] = React132.useState(null);
|
|
27977
28132
|
const bindingsVersion = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
27978
|
-
|
|
28133
|
+
React132.useEffect(() => {
|
|
27979
28134
|
if (!personId) return;
|
|
27980
28135
|
let alive = true;
|
|
27981
28136
|
void fetchUserIdForPerson(personId).then((uid2) => {
|
|
@@ -27985,20 +28140,20 @@ function PersonUnitsTab({ item }) {
|
|
|
27985
28140
|
alive = false;
|
|
27986
28141
|
};
|
|
27987
28142
|
}, [personId]);
|
|
27988
|
-
const
|
|
28143
|
+
const reload2 = React132.useCallback(async (uid2) => {
|
|
27989
28144
|
const rows = await fetchMemberUnits(uid2);
|
|
27990
28145
|
setBindings(Object.fromEntries(rows.map((r) => [r.locationId, r.role])));
|
|
27991
28146
|
}, []);
|
|
27992
|
-
|
|
27993
|
-
if (userId) void
|
|
27994
|
-
}, [userId,
|
|
28147
|
+
React132.useEffect(() => {
|
|
28148
|
+
if (userId) void reload2(userId);
|
|
28149
|
+
}, [userId, reload2, bindingsVersion]);
|
|
27995
28150
|
async function toggle(unitId, on) {
|
|
27996
28151
|
if (!userId) return;
|
|
27997
28152
|
setBusy(unitId);
|
|
27998
28153
|
try {
|
|
27999
28154
|
if (on) await bindUserToUnit(unitId, userId, null);
|
|
28000
28155
|
else await unbindUserFromUnit(unitId, userId);
|
|
28001
|
-
await
|
|
28156
|
+
await reload2(userId);
|
|
28002
28157
|
} catch (err) {
|
|
28003
28158
|
toast.error(on ? "N\xE3o deu para dar o acesso" : "N\xE3o deu para tirar o acesso", { description: err?.message });
|
|
28004
28159
|
} finally {
|
|
@@ -28010,7 +28165,7 @@ function PersonUnitsTab({ item }) {
|
|
|
28010
28165
|
setBusy(unitId);
|
|
28011
28166
|
try {
|
|
28012
28167
|
await bindUserToUnit(unitId, userId, role === NO_EXTRA_ROLE3 ? null : role);
|
|
28013
|
-
await
|
|
28168
|
+
await reload2(userId);
|
|
28014
28169
|
} catch (err) {
|
|
28015
28170
|
toast.error("N\xE3o deu para mudar a fun\xE7\xE3o", { description: err?.message });
|
|
28016
28171
|
} finally {
|
|
@@ -28087,13 +28242,13 @@ function PersonUnitsTab({ item }) {
|
|
|
28087
28242
|
function PersonAvailabilityTab({ item }) {
|
|
28088
28243
|
const person = item;
|
|
28089
28244
|
const personId = person?.id;
|
|
28090
|
-
const [units, setUnits] =
|
|
28091
|
-
const [selected, setSelected] =
|
|
28092
|
-
const [loading, setLoading] =
|
|
28093
|
-
const [busy, setBusy] =
|
|
28094
|
-
const [availabilityReady, setAvailabilityReady] =
|
|
28245
|
+
const [units, setUnits] = React132.useState([]);
|
|
28246
|
+
const [selected, setSelected] = React132.useState(/* @__PURE__ */ new Set());
|
|
28247
|
+
const [loading, setLoading] = React132.useState(true);
|
|
28248
|
+
const [busy, setBusy] = React132.useState(false);
|
|
28249
|
+
const [availabilityReady, setAvailabilityReady] = React132.useState(true);
|
|
28095
28250
|
const db2 = () => getSupabaseClientOptional();
|
|
28096
|
-
const load =
|
|
28251
|
+
const load = React132.useCallback(async () => {
|
|
28097
28252
|
const client3 = db2();
|
|
28098
28253
|
if (!client3 || !personId) {
|
|
28099
28254
|
setLoading(false);
|
|
@@ -28122,7 +28277,7 @@ function PersonAvailabilityTab({ item }) {
|
|
|
28122
28277
|
setLoading(false);
|
|
28123
28278
|
}
|
|
28124
28279
|
}, [personId]);
|
|
28125
|
-
|
|
28280
|
+
React132.useEffect(() => {
|
|
28126
28281
|
void load();
|
|
28127
28282
|
}, [load]);
|
|
28128
28283
|
async function makeOrganizationWide() {
|
|
@@ -28200,10 +28355,10 @@ function PersonAvailabilityTab({ item }) {
|
|
|
28200
28355
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Sem nenhuma sele\xE7\xE3o, o cadastro \xE9 da organiza\xE7\xE3o e aparece em todas as unidades. Com sele\xE7\xF5es, aparece somente nas unidades marcadas." })
|
|
28201
28356
|
] }) });
|
|
28202
28357
|
}
|
|
28203
|
-
var ScheduleEditor2 =
|
|
28358
|
+
var ScheduleEditor2 = React132__default.lazy(
|
|
28204
28359
|
() => import('./ScheduleEditor-ZEG6PG3Z.js').then((m) => ({ default: m.ScheduleEditor }))
|
|
28205
28360
|
);
|
|
28206
|
-
var PersonTimeline2 =
|
|
28361
|
+
var PersonTimeline2 = React132__default.lazy(
|
|
28207
28362
|
() => import('./timeline-LECYQ4IA.js').then((m) => ({ default: m.PersonTimeline }))
|
|
28208
28363
|
);
|
|
28209
28364
|
function ComingSoon({ icon: Icon, title, description }) {
|
|
@@ -28227,7 +28382,7 @@ function ActivityTab({ item, recordPath }) {
|
|
|
28227
28382
|
}
|
|
28228
28383
|
);
|
|
28229
28384
|
}
|
|
28230
|
-
return /* @__PURE__ */ jsx(
|
|
28385
|
+
return /* @__PURE__ */ jsx(React132__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(PersonTimeline2, { personId: item.id, recordPath }) });
|
|
28231
28386
|
}
|
|
28232
28387
|
function DocumentsTab({ item }) {
|
|
28233
28388
|
const t = useTranslation();
|
|
@@ -28339,7 +28494,7 @@ function ScheduleTab({ item }) {
|
|
|
28339
28494
|
return (
|
|
28340
28495
|
// O interruptor "Aparece na agenda" agora vem DENTRO do editor: era a
|
|
28341
28496
|
// única coisa que esta porta mostrava e a da agenda não.
|
|
28342
|
-
/* @__PURE__ */ jsx(
|
|
28497
|
+
/* @__PURE__ */ jsx(React132__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(ScheduleEditor2, { assigneeId: item.id }) })
|
|
28343
28498
|
);
|
|
28344
28499
|
}
|
|
28345
28500
|
var PERSON_DETAIL_TABS = [
|
|
@@ -28826,7 +28981,7 @@ function InlineEditor({
|
|
|
28826
28981
|
}) {
|
|
28827
28982
|
const [draft, setDraft] = useState(value ?? "");
|
|
28828
28983
|
const [saving, setSaving] = useState(false);
|
|
28829
|
-
const inputRef =
|
|
28984
|
+
const inputRef = React132__default.useRef(null);
|
|
28830
28985
|
useEffect(() => {
|
|
28831
28986
|
inputRef.current?.focus();
|
|
28832
28987
|
if (inputRef.current instanceof HTMLInputElement) inputRef.current.select();
|
|
@@ -29197,9 +29352,9 @@ function CrudDetailPage({
|
|
|
29197
29352
|
const t = useTranslation();
|
|
29198
29353
|
const [pending2, setPending] = useState({});
|
|
29199
29354
|
const [savingDraft, setSavingDraft] = useState(false);
|
|
29200
|
-
const pendingKeys =
|
|
29355
|
+
const pendingKeys = React132__default.useMemo(() => new Set(Object.keys(pending2)), [pending2]);
|
|
29201
29356
|
const dirty = pendingKeys.size > 0;
|
|
29202
|
-
const view =
|
|
29357
|
+
const view = React132__default.useMemo(
|
|
29203
29358
|
() => dirty ? { ...item, ...pending2 } : item,
|
|
29204
29359
|
[item, pending2, dirty]
|
|
29205
29360
|
);
|
|
@@ -29249,7 +29404,7 @@ function CrudDetailPage({
|
|
|
29249
29404
|
const isMyRecord = Boolean(myPersonId) && myPersonId === item.id;
|
|
29250
29405
|
const nameEditable = Boolean(onFieldSave || onFieldsSave) && Boolean(displayFieldDef) && isInlineEditable(displayFieldDef);
|
|
29251
29406
|
const [editingName, setEditingName] = useState(false);
|
|
29252
|
-
const imageInputRef =
|
|
29407
|
+
const imageInputRef = React132__default.useRef(null);
|
|
29253
29408
|
const runtime = usePluginRuntimeOptional();
|
|
29254
29409
|
const archetypeTabs = getArchetypeTabs(entityDef.layout, entityDef.data?.archetypeKind);
|
|
29255
29410
|
const relatedTabs = (entityDef.relatedLists ?? []).map((related) => ({
|
|
@@ -29259,7 +29414,7 @@ function CrudDetailPage({
|
|
|
29259
29414
|
component: (props) => /* @__PURE__ */ jsx(RelatedListTab, { ...props, related })
|
|
29260
29415
|
}));
|
|
29261
29416
|
const unitMode = useUnitMode();
|
|
29262
|
-
const fieldGroupTabs =
|
|
29417
|
+
const fieldGroupTabs = React132__default.useMemo(() => {
|
|
29263
29418
|
const groups = entityDef.fieldGroups ?? [];
|
|
29264
29419
|
if (!groups.some((g) => g.tab) || !item) return [];
|
|
29265
29420
|
const applicable = new Set(visibleDetailFields(entityDef, item).map((f) => f.group));
|
|
@@ -29342,7 +29497,7 @@ function CrudDetailPage({
|
|
|
29342
29497
|
window.history.replaceState(null, "", `#${segments.length ? `${base}/${segments.join("/")}` : base}`);
|
|
29343
29498
|
}, [basePath, item.id, selectedTab, embedded]);
|
|
29344
29499
|
const parentLabel = usePresetLabel(basePath, namePlural);
|
|
29345
|
-
const headerNode =
|
|
29500
|
+
const headerNode = React132__default.useMemo(
|
|
29346
29501
|
() => embedded ? null : /* @__PURE__ */ jsx(SubpageHeader, { title: displayValue, parentLabel, onBack }),
|
|
29347
29502
|
[embedded, displayValue, parentLabel, onBack]
|
|
29348
29503
|
);
|
|
@@ -29474,7 +29629,7 @@ function CrudDetailPage({
|
|
|
29474
29629
|
})
|
|
29475
29630
|
] }),
|
|
29476
29631
|
/* @__PURE__ */ jsxs(TabsContent, { value: "overview", className: embedded ? "mt-2" : "mt-4", children: [
|
|
29477
|
-
entityDef.overviewComponent ?
|
|
29632
|
+
entityDef.overviewComponent ? React132__default.createElement(entityDef.overviewComponent, { item, entityDef }) : /* @__PURE__ */ jsx(
|
|
29478
29633
|
OverviewTab,
|
|
29479
29634
|
{
|
|
29480
29635
|
entityDef,
|
|
@@ -29493,7 +29648,7 @@ function CrudDetailPage({
|
|
|
29493
29648
|
// `tabPath` only to the tab the URL is actually addressing —
|
|
29494
29649
|
// handing it to every tab would have the documents tab trying to
|
|
29495
29650
|
// open a recording id when the user switches across.
|
|
29496
|
-
|
|
29651
|
+
React132__default.createElement(tab.component, {
|
|
29497
29652
|
item,
|
|
29498
29653
|
entityDef,
|
|
29499
29654
|
// A rota DESTE registro. Uma aba que lista eventos precisa
|
|
@@ -29534,8 +29689,8 @@ function MyRecordPanel() {
|
|
|
29534
29689
|
const userId = useAuthStore((s) => s.user?.id);
|
|
29535
29690
|
const members = useOrganizationStore((s) => s.members);
|
|
29536
29691
|
const myRole = members.find((m) => m.userId === userId)?.profileName;
|
|
29537
|
-
const [state, setState] =
|
|
29538
|
-
const load =
|
|
29692
|
+
const [state, setState] = React132.useState({ status: "loading" });
|
|
29693
|
+
const load = React132.useCallback(async () => {
|
|
29539
29694
|
if (!orgId || !userId) return;
|
|
29540
29695
|
const person = await dedup(`self:record:${orgId}:${userId}`, () => fetchMyPersonRecord(orgId, userId));
|
|
29541
29696
|
if (!person) return setState({ status: "none" });
|
|
@@ -29552,10 +29707,10 @@ function MyRecordPanel() {
|
|
|
29552
29707
|
setState({ status: "none" });
|
|
29553
29708
|
}
|
|
29554
29709
|
}, [orgId, userId]);
|
|
29555
|
-
|
|
29710
|
+
React132.useEffect(() => {
|
|
29556
29711
|
void load();
|
|
29557
29712
|
}, [load]);
|
|
29558
|
-
const changePhoto =
|
|
29713
|
+
const changePhoto = React132.useCallback(async (file) => {
|
|
29559
29714
|
if (state.status !== "ready") return;
|
|
29560
29715
|
const supabase = getFayzSupabaseClientOptional();
|
|
29561
29716
|
if (!supabase) return;
|
|
@@ -29611,8 +29766,8 @@ function ConnectedUserProfile() {
|
|
|
29611
29766
|
const myPersonId = useMyPersonId();
|
|
29612
29767
|
const hasRecord = Boolean(myPersonId);
|
|
29613
29768
|
const setUser = useAuthStore((s) => s.setUser);
|
|
29614
|
-
const [profile, setProfile] =
|
|
29615
|
-
|
|
29769
|
+
const [profile, setProfile] = React132.useState(null);
|
|
29770
|
+
React132.useEffect(() => {
|
|
29616
29771
|
const supabase = getFayzSupabaseClientOptional();
|
|
29617
29772
|
if (!user || !supabase) return;
|
|
29618
29773
|
let cancelled = false;
|
|
@@ -29723,9 +29878,9 @@ function SecuritySettings({
|
|
|
29723
29878
|
onTenantSecurityChange
|
|
29724
29879
|
}) {
|
|
29725
29880
|
const { t } = useTranslation$1();
|
|
29726
|
-
const [resetting, setResetting] =
|
|
29727
|
-
const [resetSent, setResetSent] =
|
|
29728
|
-
const [savingTenant, setSavingTenant] =
|
|
29881
|
+
const [resetting, setResetting] = React132.useState(false);
|
|
29882
|
+
const [resetSent, setResetSent] = React132.useState(false);
|
|
29883
|
+
const [savingTenant, setSavingTenant] = React132.useState(false);
|
|
29729
29884
|
const handleResetPassword = async () => {
|
|
29730
29885
|
if (!onResetPassword) return;
|
|
29731
29886
|
setResetting(true);
|
|
@@ -29899,8 +30054,8 @@ function FileUploadField({
|
|
|
29899
30054
|
hint
|
|
29900
30055
|
}) {
|
|
29901
30056
|
const { t } = useTranslation$1();
|
|
29902
|
-
const inputRef =
|
|
29903
|
-
const [preview, setPreview] =
|
|
30057
|
+
const inputRef = React132.useRef(null);
|
|
30058
|
+
const [preview, setPreview] = React132.useState(null);
|
|
29904
30059
|
const handleChange = (e) => {
|
|
29905
30060
|
const file = e.target.files?.[0];
|
|
29906
30061
|
if (file) {
|
|
@@ -30122,13 +30277,13 @@ function SkinGate({ children }) {
|
|
|
30122
30277
|
}
|
|
30123
30278
|
function BrandingSettings({ brand, onSave }) {
|
|
30124
30279
|
const { t } = useTranslation$1();
|
|
30125
|
-
const [section, setSection] =
|
|
30126
|
-
const [saved, setSaved] =
|
|
30127
|
-
const [draft, setDraft] =
|
|
30128
|
-
const [logoFile, setLogoFile] =
|
|
30129
|
-
const [faviconFile, setFaviconFile] =
|
|
30130
|
-
const [saving, setSaving] =
|
|
30131
|
-
|
|
30280
|
+
const [section, setSection] = React132.useState("identity");
|
|
30281
|
+
const [saved, setSaved] = React132.useState(brand ?? EMPTY_BRAND);
|
|
30282
|
+
const [draft, setDraft] = React132.useState(brand ?? EMPTY_BRAND);
|
|
30283
|
+
const [logoFile, setLogoFile] = React132.useState(null);
|
|
30284
|
+
const [faviconFile, setFaviconFile] = React132.useState(null);
|
|
30285
|
+
const [saving, setSaving] = React132.useState(false);
|
|
30286
|
+
React132.useEffect(() => {
|
|
30132
30287
|
if (brand) {
|
|
30133
30288
|
setSaved(brand);
|
|
30134
30289
|
setDraft(brand);
|
|
@@ -30502,11 +30657,11 @@ function ConnectedBrandingSettings() {
|
|
|
30502
30657
|
toast.error("N\xE3o foi poss\xEDvel salvar a marca", { description: err?.message });
|
|
30503
30658
|
}
|
|
30504
30659
|
};
|
|
30505
|
-
const [brand, setBrand] =
|
|
30660
|
+
const [brand, setBrand] = React132.useState(() => normalizeBrand(
|
|
30506
30661
|
(currentOrg?.settings ?? {}).branding,
|
|
30507
30662
|
{ name: currentOrg?.name, logoUrl: currentOrg?.logoUrl }
|
|
30508
30663
|
));
|
|
30509
|
-
|
|
30664
|
+
React132.useEffect(() => {
|
|
30510
30665
|
let alive = true;
|
|
30511
30666
|
void (async () => {
|
|
30512
30667
|
try {
|
|
@@ -30627,12 +30782,12 @@ function ProjectsSettings() {
|
|
|
30627
30782
|
const projects = useFayzProjectsStore((s) => s.projects);
|
|
30628
30783
|
const load = useFayzProjectsStore((s) => s.load);
|
|
30629
30784
|
const refresh = useFayzProjectsStore((s) => s.refresh);
|
|
30630
|
-
const [linking, setLinking] =
|
|
30785
|
+
const [linking, setLinking] = React132.useState(false);
|
|
30631
30786
|
const connected = isPlatformConnected();
|
|
30632
|
-
|
|
30787
|
+
React132.useEffect(() => {
|
|
30633
30788
|
void load(currentOrgId);
|
|
30634
30789
|
}, [currentOrgId, load]);
|
|
30635
|
-
|
|
30790
|
+
React132.useEffect(() => {
|
|
30636
30791
|
if (!connected || projects.length === 0) return;
|
|
30637
30792
|
let cancelled = false;
|
|
30638
30793
|
void (async () => {
|
|
@@ -30704,7 +30859,7 @@ function SiteRow({
|
|
|
30704
30859
|
showDefaultAction,
|
|
30705
30860
|
onChanged
|
|
30706
30861
|
}) {
|
|
30707
|
-
const [busy, setBusy] =
|
|
30862
|
+
const [busy, setBusy] = React132.useState(false);
|
|
30708
30863
|
const editorUrl = editorUrlOf(project);
|
|
30709
30864
|
const run = async (action) => {
|
|
30710
30865
|
setBusy(true);
|
|
@@ -30775,7 +30930,7 @@ function SiteRow({
|
|
|
30775
30930
|
] });
|
|
30776
30931
|
}
|
|
30777
30932
|
function LinkSiteModal({ onClose, onLinked }) {
|
|
30778
|
-
const [mode, setMode] =
|
|
30933
|
+
const [mode, setMode] = React132.useState("import");
|
|
30779
30934
|
return /* @__PURE__ */ jsx(Modal, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs(ModalContent, { size: "lg", children: [
|
|
30780
30935
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
30781
30936
|
/* @__PURE__ */ jsx(ModalTitle, { children: "Vincular um site" }),
|
|
@@ -30811,11 +30966,11 @@ function ModeTab({
|
|
|
30811
30966
|
}
|
|
30812
30967
|
function ImportPane({ onLinked }) {
|
|
30813
30968
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
30814
|
-
const [search, setSearch] =
|
|
30815
|
-
const [remote, setRemote] =
|
|
30816
|
-
const [error, setError] =
|
|
30817
|
-
const [linkingId, setLinkingId] =
|
|
30818
|
-
|
|
30969
|
+
const [search, setSearch] = React132.useState("");
|
|
30970
|
+
const [remote, setRemote] = React132.useState(null);
|
|
30971
|
+
const [error, setError] = React132.useState(null);
|
|
30972
|
+
const [linkingId, setLinkingId] = React132.useState(null);
|
|
30973
|
+
React132.useEffect(() => {
|
|
30819
30974
|
let cancelled = false;
|
|
30820
30975
|
setError(null);
|
|
30821
30976
|
const timer = setTimeout(() => {
|
|
@@ -30850,7 +31005,7 @@ function ImportPane({ onLinked }) {
|
|
|
30850
31005
|
});
|
|
30851
31006
|
onLinked();
|
|
30852
31007
|
} catch (cause) {
|
|
30853
|
-
setError(cause
|
|
31008
|
+
setError(describeError(cause, "N\xE3o foi poss\xEDvel vincular"));
|
|
30854
31009
|
setLinkingId(null);
|
|
30855
31010
|
}
|
|
30856
31011
|
};
|
|
@@ -30897,9 +31052,9 @@ function ImportPane({ onLinked }) {
|
|
|
30897
31052
|
}
|
|
30898
31053
|
function CreatePane({ onLinked, onCancel }) {
|
|
30899
31054
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
30900
|
-
const [prompt, setPrompt] =
|
|
30901
|
-
const [busy, setBusy] =
|
|
30902
|
-
const [error, setError] =
|
|
31055
|
+
const [prompt, setPrompt] = React132.useState("");
|
|
31056
|
+
const [busy, setBusy] = React132.useState(false);
|
|
31057
|
+
const [error, setError] = React132.useState(null);
|
|
30903
31058
|
const tooShort = prompt.trim().length < PROMPT_MIN_CHARS;
|
|
30904
31059
|
const submit = async () => {
|
|
30905
31060
|
setBusy(true);
|
|
@@ -30919,7 +31074,7 @@ function CreatePane({ onLinked, onCancel }) {
|
|
|
30919
31074
|
});
|
|
30920
31075
|
onLinked();
|
|
30921
31076
|
} catch (cause) {
|
|
30922
|
-
setError(cause
|
|
31077
|
+
setError(describeError(cause, "N\xE3o foi poss\xEDvel criar o site"));
|
|
30923
31078
|
setBusy(false);
|
|
30924
31079
|
}
|
|
30925
31080
|
};
|
|
@@ -31088,10 +31243,10 @@ function ModuleCatalogSections({
|
|
|
31088
31243
|
onToggle,
|
|
31089
31244
|
busy
|
|
31090
31245
|
}) {
|
|
31091
|
-
const [query, setQuery] =
|
|
31246
|
+
const [query, setQuery] = React132.useState("");
|
|
31092
31247
|
const total = categories.reduce((n, c) => n + c.rows.length, 0);
|
|
31093
31248
|
const searchable = total > 6;
|
|
31094
|
-
const filtered =
|
|
31249
|
+
const filtered = React132.useMemo(() => filterCategories(categories, query), [categories, query]);
|
|
31095
31250
|
if (categories.length === 0) {
|
|
31096
31251
|
return /* @__PURE__ */ jsxs("div", { className: "py-8 text-center", children: [
|
|
31097
31252
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Nada a adicionar" }),
|
|
@@ -31133,7 +31288,7 @@ function CategorySection({
|
|
|
31133
31288
|
onToggle,
|
|
31134
31289
|
busy
|
|
31135
31290
|
}) {
|
|
31136
|
-
const [open, setOpen] =
|
|
31291
|
+
const [open, setOpen] = React132.useState(category.mine);
|
|
31137
31292
|
const expanded = open || forceOpen;
|
|
31138
31293
|
const Chevron = expanded ? ChevronDown : ChevronRight;
|
|
31139
31294
|
return /* @__PURE__ */ jsxs("section", { children: [
|
|
@@ -31264,8 +31419,8 @@ function buildCategories(catalog, rows) {
|
|
|
31264
31419
|
}
|
|
31265
31420
|
function useModuleCatalog() {
|
|
31266
31421
|
const tenantId2 = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
31267
|
-
const [catalog, setCatalog] =
|
|
31268
|
-
|
|
31422
|
+
const [catalog, setCatalog] = React132.useState([]);
|
|
31423
|
+
React132.useEffect(() => {
|
|
31269
31424
|
const supabase = getSupabaseClientOptional$1();
|
|
31270
31425
|
if (!supabase) return;
|
|
31271
31426
|
let alive = true;
|
|
@@ -31282,7 +31437,7 @@ function useModuleCatalog() {
|
|
|
31282
31437
|
function ModulesPreview() {
|
|
31283
31438
|
const runtime = usePluginRuntime();
|
|
31284
31439
|
const preset = useAppPreset();
|
|
31285
|
-
const rows =
|
|
31440
|
+
const rows = React132.useMemo(() => {
|
|
31286
31441
|
const flat = runtime.navigation.filter((entry) => entry.section !== "settings").map((entry) => toRailRow(entry, preset.labels));
|
|
31287
31442
|
return applyRailPreset(flat, preset.rail, preset.hide, preset.whole);
|
|
31288
31443
|
}, [runtime.navigation, preset.rail, preset.hide, preset.whole, preset.labels]);
|
|
@@ -31326,15 +31481,15 @@ function PreviewRow({ row, depth = 0 }) {
|
|
|
31326
31481
|
function ModulesSettings({ hidden = [], onToggle, permits, busy, catalog = [] }) {
|
|
31327
31482
|
const runtime = usePluginRuntime();
|
|
31328
31483
|
const offered = useOfferedPlugins();
|
|
31329
|
-
const [adding, setAdding] =
|
|
31330
|
-
const rows =
|
|
31484
|
+
const [adding, setAdding] = React132.useState(false);
|
|
31485
|
+
const rows = React132.useMemo(() => {
|
|
31331
31486
|
const known = catalog.length ? new Set(catalog.flatMap((app) => app.modules)) : new Set(offered);
|
|
31332
31487
|
const inCatalogue = known.size ? runtime.plugins.filter((p) => known.has(p.id) || p.isActive) : runtime.plugins;
|
|
31333
31488
|
return buildRows(inCatalogue, new Set(hidden), permits);
|
|
31334
31489
|
}, [runtime.plugins, hidden, permits, offered, catalog]);
|
|
31335
31490
|
const on = rows.filter((r) => r.plugin.isActive);
|
|
31336
|
-
const off =
|
|
31337
|
-
const categories =
|
|
31491
|
+
const off = React132.useMemo(() => rows.filter((r) => !r.plugin.isActive), [rows]);
|
|
31492
|
+
const categories = React132.useMemo(() => buildCategories(catalog, off), [catalog, off]);
|
|
31338
31493
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
|
|
31339
31494
|
/* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsxs(Button, { size: "sm", className: "shrink-0 gap-1.5", onClick: () => setAdding(true), children: [
|
|
31340
31495
|
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
|
|
@@ -31554,8 +31709,8 @@ function ConnectedModulesSettings({ hidden = SHELL_PLUGINS }) {
|
|
|
31554
31709
|
const access = useAccessOptional();
|
|
31555
31710
|
const catalog = useModuleCatalog();
|
|
31556
31711
|
const tenantId2 = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
31557
|
-
const [busy, setBusy] =
|
|
31558
|
-
const onToggle =
|
|
31712
|
+
const [busy, setBusy] = React132.useState(false);
|
|
31713
|
+
const onToggle = React132.useCallback(
|
|
31559
31714
|
async (plugin, status, facet) => {
|
|
31560
31715
|
const supabase = getSupabaseClientOptional$1();
|
|
31561
31716
|
if (!supabase) return;
|
|
@@ -31581,7 +31736,7 @@ function ConnectedModulesSettings({ hidden = SHELL_PLUGINS }) {
|
|
|
31581
31736
|
},
|
|
31582
31737
|
[refresh, tenantId2]
|
|
31583
31738
|
);
|
|
31584
|
-
const permits =
|
|
31739
|
+
const permits = React132.useCallback(
|
|
31585
31740
|
(plugin) => access ? access.can(plugin, "read").allowed || access.entitled(plugin) : true,
|
|
31586
31741
|
[access]
|
|
31587
31742
|
);
|
|
@@ -31592,7 +31747,7 @@ function useCoreSettingsTabs({
|
|
|
31592
31747
|
showBranding = true
|
|
31593
31748
|
} = {}) {
|
|
31594
31749
|
const { t } = useTranslation$1();
|
|
31595
|
-
return
|
|
31750
|
+
return React132.useMemo(() => [
|
|
31596
31751
|
...showCompany ? [{ id: "general", label: t("settings.general"), icon: /* @__PURE__ */ jsx(Building2, { className: "h-4 w-4" }), iconName: "Building2", component: /* @__PURE__ */ jsx(ConnectedCompanySettings, {}) }] : [],
|
|
31597
31752
|
{ id: "profile", label: t("settings.profile"), icon: /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }), iconName: "User", component: /* @__PURE__ */ jsx(ConnectedUserProfile, {}) },
|
|
31598
31753
|
{ id: "security", label: t("settings.security"), icon: /* @__PURE__ */ jsx(Shield, { className: "h-4 w-4" }), iconName: "Shield", component: /* @__PURE__ */ jsx(ConnectedSecuritySettings, {}) },
|
|
@@ -31637,10 +31792,10 @@ function SettingsPage({
|
|
|
31637
31792
|
}
|
|
31638
31793
|
return null;
|
|
31639
31794
|
}
|
|
31640
|
-
const [activeTab, setActiveTab] =
|
|
31795
|
+
const [activeTab, setActiveTab] = React132.useState(() => {
|
|
31641
31796
|
return getTabFromHash() ?? defaultTab ?? null;
|
|
31642
31797
|
});
|
|
31643
|
-
|
|
31798
|
+
React132.useEffect(() => {
|
|
31644
31799
|
const handler = () => {
|
|
31645
31800
|
const tab = getTabFromHash();
|
|
31646
31801
|
if (tab) setActiveTab(tab);
|
|
@@ -31667,8 +31822,8 @@ function SettingsPage({
|
|
|
31667
31822
|
setActiveTab(null);
|
|
31668
31823
|
window.location.hash = "/settings";
|
|
31669
31824
|
};
|
|
31670
|
-
const [query, setQuery] =
|
|
31671
|
-
const sections =
|
|
31825
|
+
const [query, setQuery] = React132.useState("");
|
|
31826
|
+
const sections = React132.useMemo(() => {
|
|
31672
31827
|
const q = query.trim().toLowerCase();
|
|
31673
31828
|
const out = [];
|
|
31674
31829
|
for (const tab of resolvedTabs) {
|
|
@@ -31753,14 +31908,14 @@ function InviteMemberDialog({ open, onOpenChange, defaultEmail }) {
|
|
|
31753
31908
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
31754
31909
|
const setInvites = useInviteStore((s) => s.setInvites);
|
|
31755
31910
|
const { user } = useAuthStore();
|
|
31756
|
-
const [emails, setEmails] =
|
|
31757
|
-
const [profileId, setProfileId] =
|
|
31758
|
-
const [sending, setSending] =
|
|
31759
|
-
const [sent, setSent] =
|
|
31760
|
-
|
|
31911
|
+
const [emails, setEmails] = React132.useState([defaultEmail ?? ""]);
|
|
31912
|
+
const [profileId, setProfileId] = React132.useState(profiles[1]?.id ?? profiles[0]?.id ?? "");
|
|
31913
|
+
const [sending, setSending] = React132.useState(false);
|
|
31914
|
+
const [sent, setSent] = React132.useState(false);
|
|
31915
|
+
React132.useEffect(() => {
|
|
31761
31916
|
if (open) setEmails([defaultEmail ?? ""]);
|
|
31762
31917
|
}, [open, defaultEmail]);
|
|
31763
|
-
|
|
31918
|
+
React132.useEffect(() => {
|
|
31764
31919
|
if (!profileId && profiles.length) setProfileId(profiles[1]?.id ?? profiles[0].id);
|
|
31765
31920
|
}, [profiles, profileId]);
|
|
31766
31921
|
const addEmail = () => setEmails((prev) => [...prev, ""]);
|
|
@@ -31864,7 +32019,7 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
31864
32019
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
31865
32020
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
31866
32021
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
31867
|
-
const [query, setQuery] =
|
|
32022
|
+
const [query, setQuery] = React132.useState("");
|
|
31868
32023
|
const singular = label2(t, "unit.singular", "unidade");
|
|
31869
32024
|
const plural = label2(t, "unit.plural", "unidades");
|
|
31870
32025
|
if (!unitMode) return null;
|
|
@@ -31889,13 +32044,13 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
31889
32044
|
}
|
|
31890
32045
|
const renderNode = (node, depth) => {
|
|
31891
32046
|
if (node.kind === "region") {
|
|
31892
|
-
return /* @__PURE__ */ jsxs(
|
|
32047
|
+
return /* @__PURE__ */ jsxs(React132.Fragment, { children: [
|
|
31893
32048
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
31894
32049
|
node.children.map((child) => renderNode(child, depth + 1))
|
|
31895
32050
|
] }, node.id);
|
|
31896
32051
|
}
|
|
31897
32052
|
if (!reachable.includes(node.id)) return null;
|
|
31898
|
-
return /* @__PURE__ */ jsxs(
|
|
32053
|
+
return /* @__PURE__ */ jsxs(React132.Fragment, { children: [
|
|
31899
32054
|
/* @__PURE__ */ jsxs(
|
|
31900
32055
|
DropdownItem,
|
|
31901
32056
|
{
|
|
@@ -31978,7 +32133,7 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
31978
32133
|
var MENU_LIST_CAP = 5;
|
|
31979
32134
|
function UnitMenuSection() {
|
|
31980
32135
|
useUnitBootstrap();
|
|
31981
|
-
const [locating, setLocating] =
|
|
32136
|
+
const [locating, setLocating] = React132.useState(false);
|
|
31982
32137
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
31983
32138
|
const units = useUnitStore((s) => s.units);
|
|
31984
32139
|
const tree = useUnitStore((s) => s.tree);
|
|
@@ -32029,13 +32184,13 @@ function UnitMenuSection() {
|
|
|
32029
32184
|
if (node.kind === "region") {
|
|
32030
32185
|
const visibleChildren = node.children.filter((c) => c.kind === "region" || reachable.includes(c.id));
|
|
32031
32186
|
if (visibleChildren.length === 0) return null;
|
|
32032
|
-
return /* @__PURE__ */ jsxs(
|
|
32187
|
+
return /* @__PURE__ */ jsxs(React132.Fragment, { children: [
|
|
32033
32188
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
32034
32189
|
visibleChildren.map((child) => renderNode(child, depth + 1))
|
|
32035
32190
|
] }, node.id);
|
|
32036
32191
|
}
|
|
32037
32192
|
if (!reachable.includes(node.id)) return null;
|
|
32038
|
-
return /* @__PURE__ */ jsxs(
|
|
32193
|
+
return /* @__PURE__ */ jsxs(React132.Fragment, { children: [
|
|
32039
32194
|
/* @__PURE__ */ jsxs(
|
|
32040
32195
|
DropdownItem,
|
|
32041
32196
|
{
|
|
@@ -32154,7 +32309,7 @@ var UNIT_DETAIL_TABS = [
|
|
|
32154
32309
|
{ id: "activity", label: "Activity", hidden: true }
|
|
32155
32310
|
];
|
|
32156
32311
|
function SuggestInput({ column, value, onChange, placeholder }) {
|
|
32157
|
-
const search =
|
|
32312
|
+
const search = React132__default.useCallback(async (query) => {
|
|
32158
32313
|
const supabase = getSupabaseClientOptional();
|
|
32159
32314
|
if (!supabase) return [];
|
|
32160
32315
|
const { data } = await supabase.from("v_units").select(column).not(column, "is", null).limit(500);
|
|
@@ -32431,9 +32586,9 @@ function MemberUnitsCell({
|
|
|
32431
32586
|
const byId = useUnitStore((s) => s.byId);
|
|
32432
32587
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
32433
32588
|
const openUnit = useUnitPanel((s) => s.openUnit);
|
|
32434
|
-
const [unitIds, setUnitIds] =
|
|
32589
|
+
const [unitIds, setUnitIds] = React132.useState(null);
|
|
32435
32590
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
32436
|
-
|
|
32591
|
+
React132.useEffect(() => {
|
|
32437
32592
|
if (!userId) {
|
|
32438
32593
|
setUnitIds([]);
|
|
32439
32594
|
return;
|
|
@@ -32479,10 +32634,10 @@ function MemberUnitsCell({
|
|
|
32479
32634
|
}
|
|
32480
32635
|
function ImpersonateDialog({ tenantId: tenantId2, target, onClose }) {
|
|
32481
32636
|
const { t } = useTranslation$1();
|
|
32482
|
-
const [reason, setReason] =
|
|
32483
|
-
const [busy, setBusy] =
|
|
32484
|
-
const [error, setError] =
|
|
32485
|
-
|
|
32637
|
+
const [reason, setReason] = React132.useState("");
|
|
32638
|
+
const [busy, setBusy] = React132.useState(false);
|
|
32639
|
+
const [error, setError] = React132.useState(null);
|
|
32640
|
+
React132.useEffect(() => {
|
|
32486
32641
|
if (target) {
|
|
32487
32642
|
setReason("");
|
|
32488
32643
|
setError(null);
|
|
@@ -32542,10 +32697,10 @@ function TeamTab() {
|
|
|
32542
32697
|
const { user } = useAuthStore();
|
|
32543
32698
|
const hasSystemPermission = useSystemPermission();
|
|
32544
32699
|
const personMode = teamPersonKinds.length > 0 && typeof adapter?.listTeam === "function";
|
|
32545
|
-
const [team, setTeam] =
|
|
32546
|
-
const [inviteOpen, setInviteOpen] =
|
|
32700
|
+
const [team, setTeam] = React132.useState(null);
|
|
32701
|
+
const [inviteOpen, setInviteOpen] = React132.useState(false);
|
|
32547
32702
|
const guardSeats = useLimitGuard("users");
|
|
32548
|
-
const [inviteEmail, setInviteEmail] =
|
|
32703
|
+
const [inviteEmail, setInviteEmail] = React132.useState(void 0);
|
|
32549
32704
|
const handleOpenInvite = async (row) => {
|
|
32550
32705
|
if (row && !row.email && row.personId && entityRouteHasDetail("person", row.kind)) {
|
|
32551
32706
|
openEntity(row.personId, "person", row.kind, "access");
|
|
@@ -32555,7 +32710,7 @@ function TeamTab() {
|
|
|
32555
32710
|
setInviteEmail(row?.email || void 0);
|
|
32556
32711
|
setInviteOpen(true);
|
|
32557
32712
|
};
|
|
32558
|
-
const reloadTeam =
|
|
32713
|
+
const reloadTeam = React132.useCallback(async () => {
|
|
32559
32714
|
if (!adapter || !currentOrg) return;
|
|
32560
32715
|
if (personMode && adapter.listTeam) {
|
|
32561
32716
|
setTeam(await adapter.listTeam(currentOrg.id, teamPersonKinds));
|
|
@@ -32563,12 +32718,12 @@ function TeamTab() {
|
|
|
32563
32718
|
setMembers(await adapter.listMembers(currentOrg.id));
|
|
32564
32719
|
}
|
|
32565
32720
|
}, [adapter, currentOrg?.id, personMode, teamPersonKinds, setMembers]);
|
|
32566
|
-
|
|
32721
|
+
React132.useEffect(() => {
|
|
32567
32722
|
if (personMode && adapter?.listTeam && currentOrg) {
|
|
32568
32723
|
dedup("team:people:" + currentOrg.id, () => adapter.listTeam(currentOrg.id, teamPersonKinds)).then(setTeam).catch(() => setTeam([]));
|
|
32569
32724
|
}
|
|
32570
32725
|
}, [personMode, adapter, currentOrg?.id, teamPersonKinds.join(",")]);
|
|
32571
|
-
|
|
32726
|
+
React132.useEffect(() => {
|
|
32572
32727
|
if (adapter && currentOrg) {
|
|
32573
32728
|
dedup("team:invites:" + currentOrg.id, () => adapter.listInvites(currentOrg.id)).then(setInvites).catch(() => {
|
|
32574
32729
|
});
|
|
@@ -32649,8 +32804,8 @@ function TeamTab() {
|
|
|
32649
32804
|
};
|
|
32650
32805
|
const { t } = useTranslation$1();
|
|
32651
32806
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
32652
|
-
const [viewAs, setViewAs] =
|
|
32653
|
-
const inviteActions =
|
|
32807
|
+
const [viewAs, setViewAs] = React132.useState(null);
|
|
32808
|
+
const inviteActions = React132.useMemo(() => [{
|
|
32654
32809
|
id: "invite",
|
|
32655
32810
|
label: t("organization.team.invite"),
|
|
32656
32811
|
icon: UserPlus,
|
|
@@ -32846,13 +33001,13 @@ var SYSTEM_PERMISSIONS2 = [
|
|
|
32846
33001
|
];
|
|
32847
33002
|
function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, isNew, parentLabel }) {
|
|
32848
33003
|
const { t } = useTranslation$1();
|
|
32849
|
-
const [name, setName] =
|
|
32850
|
-
const [description, setDescription] =
|
|
32851
|
-
const [systemPerms, setSystemPerms] =
|
|
32852
|
-
const [grants, setGrants] =
|
|
32853
|
-
const [collapsed, setCollapsed] =
|
|
32854
|
-
const [search, setSearch] =
|
|
32855
|
-
const initial =
|
|
33004
|
+
const [name, setName] = React132.useState(profile?.name ?? "");
|
|
33005
|
+
const [description, setDescription] = React132.useState(profile?.description ?? "");
|
|
33006
|
+
const [systemPerms, setSystemPerms] = React132.useState(profile?.systemPermissions ?? []);
|
|
33007
|
+
const [grants, setGrants] = React132.useState(profile?.grants ?? {});
|
|
33008
|
+
const [collapsed, setCollapsed] = React132.useState(/* @__PURE__ */ new Set());
|
|
33009
|
+
const [search, setSearch] = React132.useState("");
|
|
33010
|
+
const initial = React132.useRef({
|
|
32856
33011
|
name: profile?.name ?? "",
|
|
32857
33012
|
description: profile?.description ?? "",
|
|
32858
33013
|
systemPerms: JSON.stringify(profile?.systemPermissions ?? []),
|
|
@@ -32889,7 +33044,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
32889
33044
|
onDiscard: onCancel,
|
|
32890
33045
|
saveLabel: isNew ? t("organization.permissions.createProfile") : t("organization.permissions.updateProfile")
|
|
32891
33046
|
});
|
|
32892
|
-
const groups =
|
|
33047
|
+
const groups = React132.useMemo(() => {
|
|
32893
33048
|
const filtered = search ? features.filter((f) => f.label.toLowerCase().includes(search.toLowerCase())) : features;
|
|
32894
33049
|
const map = /* @__PURE__ */ new Map();
|
|
32895
33050
|
for (const f of filtered) {
|
|
@@ -32958,7 +33113,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
32958
33113
|
}
|
|
32959
33114
|
) }) })
|
|
32960
33115
|
] }, sp.id)),
|
|
32961
|
-
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(
|
|
33116
|
+
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(React132.Fragment, { children: [
|
|
32962
33117
|
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: 5, className: "p-2 px-3", children: /* @__PURE__ */ jsxs(
|
|
32963
33118
|
"button",
|
|
32964
33119
|
{
|
|
@@ -33030,12 +33185,12 @@ function PermissionProfilesTab() {
|
|
|
33030
33185
|
const startImpersonation2 = usePermissionsStore((s) => s.startImpersonation);
|
|
33031
33186
|
const canPreview = (realProfile?.systemPermissions ?? []).includes("manage_permissions") ?? false;
|
|
33032
33187
|
const { t } = useTranslation$1();
|
|
33033
|
-
const [editingProfile, setEditingProfile] =
|
|
33034
|
-
const [creating, setCreating] =
|
|
33035
|
-
const [duplicateSource, setDuplicateSource] =
|
|
33036
|
-
const [saving, setSaving] =
|
|
33037
|
-
const [error, setError] =
|
|
33038
|
-
const [deleting, setDeleting] =
|
|
33188
|
+
const [editingProfile, setEditingProfile] = React132.useState(null);
|
|
33189
|
+
const [creating, setCreating] = React132.useState(false);
|
|
33190
|
+
const [duplicateSource, setDuplicateSource] = React132.useState(null);
|
|
33191
|
+
const [saving, setSaving] = React132.useState(false);
|
|
33192
|
+
const [error, setError] = React132.useState(null);
|
|
33193
|
+
const [deleting, setDeleting] = React132.useState(null);
|
|
33039
33194
|
const handleDuplicate = (profile) => {
|
|
33040
33195
|
setEditingProfile(null);
|
|
33041
33196
|
setCreating(false);
|
|
@@ -33045,9 +33200,9 @@ function PermissionProfilesTab() {
|
|
|
33045
33200
|
isSystem: false
|
|
33046
33201
|
});
|
|
33047
33202
|
};
|
|
33048
|
-
const surfaceRef =
|
|
33203
|
+
const surfaceRef = React132.useRef({ features, profiles, adapter, currentOrg, setProfiles });
|
|
33049
33204
|
surfaceRef.current = { features, profiles, adapter, currentOrg, setProfiles };
|
|
33050
|
-
const agentSurface =
|
|
33205
|
+
const agentSurface = React132.useMemo(() => ({
|
|
33051
33206
|
id: "org.permissions",
|
|
33052
33207
|
instructions: PERMISSIONS_INSTRUCTIONS,
|
|
33053
33208
|
describe: () => {
|
|
@@ -33101,7 +33256,7 @@ function PermissionProfilesTab() {
|
|
|
33101
33256
|
}]
|
|
33102
33257
|
}), []);
|
|
33103
33258
|
useAgentSurface(agentSurface);
|
|
33104
|
-
const createActions =
|
|
33259
|
+
const createActions = React132.useMemo(() => [
|
|
33105
33260
|
{
|
|
33106
33261
|
id: "new",
|
|
33107
33262
|
label: t("organization.permissions.createProfile"),
|
|
@@ -33130,7 +33285,7 @@ function PermissionProfilesTab() {
|
|
|
33130
33285
|
})
|
|
33131
33286
|
}
|
|
33132
33287
|
], [t]);
|
|
33133
|
-
const memberCountByProfile =
|
|
33288
|
+
const memberCountByProfile = React132.useMemo(() => {
|
|
33134
33289
|
const counts = {};
|
|
33135
33290
|
for (const m of members) {
|
|
33136
33291
|
counts[m.profileId] = (counts[m.profileId] ?? 0) + 1;
|
|
@@ -33435,7 +33590,7 @@ function FieldRulesSettings({ entities, rules: initialRules, onSave }) {
|
|
|
33435
33590
|
const [saving, setSaving] = useState(false);
|
|
33436
33591
|
const [search, setSearch] = useState("");
|
|
33437
33592
|
const [showMore, setShowMore] = useState(false);
|
|
33438
|
-
|
|
33593
|
+
React132.useEffect(() => {
|
|
33439
33594
|
setDraft(initialRules);
|
|
33440
33595
|
}, [initialRules]);
|
|
33441
33596
|
const isDirty = useMemo(
|
|
@@ -33844,19 +33999,19 @@ function SoftLimitWidget() {
|
|
|
33844
33999
|
function LimitProbe({ limitKey }) {
|
|
33845
34000
|
const info = useLimit(limitKey);
|
|
33846
34001
|
const report = useSoftLimitStore((s) => s.report);
|
|
33847
|
-
|
|
34002
|
+
React132.useEffect(() => {
|
|
33848
34003
|
report(limitKey, info);
|
|
33849
34004
|
}, [limitKey, info, report]);
|
|
33850
34005
|
return null;
|
|
33851
34006
|
}
|
|
33852
34007
|
function SoftLimitProbes({ keys }) {
|
|
33853
|
-
const monitored =
|
|
34008
|
+
const monitored = React132.useMemo(() => Array.from(new Set(keys)), [keys]);
|
|
33854
34009
|
return /* @__PURE__ */ jsx(Fragment, { children: monitored.map((k) => /* @__PURE__ */ jsx(LimitProbe, { limitKey: k }, k)) });
|
|
33855
34010
|
}
|
|
33856
|
-
var CommandPalette =
|
|
34011
|
+
var CommandPalette = React132.lazy(
|
|
33857
34012
|
() => import('./CommandPalette-B5PMQFDG.js').then((m) => ({ default: m.CommandPalette }))
|
|
33858
34013
|
);
|
|
33859
|
-
var SubscriptionPage =
|
|
34014
|
+
var SubscriptionPage = React132.lazy(
|
|
33860
34015
|
() => import('./SubscriptionPage-VXZ37WZZ.js').then((m) => ({ default: m.SubscriptionPage }))
|
|
33861
34016
|
);
|
|
33862
34017
|
function WorkspaceSwitcher({
|
|
@@ -33906,8 +34061,8 @@ function WorkspaceSwitcher({
|
|
|
33906
34061
|
const v = t(key);
|
|
33907
34062
|
return !v || v === key ? fallback : v;
|
|
33908
34063
|
};
|
|
33909
|
-
const [query, setQuery] =
|
|
33910
|
-
const search =
|
|
34064
|
+
const [query, setQuery] = React132.useState("");
|
|
34065
|
+
const search = React132.useMemo(
|
|
33911
34066
|
() => searchWorkspaces(
|
|
33912
34067
|
options,
|
|
33913
34068
|
query,
|
|
@@ -34221,9 +34376,9 @@ function PluginHeaderControls() {
|
|
|
34221
34376
|
}
|
|
34222
34377
|
function AdminNotifications() {
|
|
34223
34378
|
const { notifications, unreadCount, fetchNotifications, markAsRead, markAllAsRead } = useNotifications();
|
|
34224
|
-
const [open, setOpen] =
|
|
34225
|
-
const fetchedRef =
|
|
34226
|
-
|
|
34379
|
+
const [open, setOpen] = React132.useState(false);
|
|
34380
|
+
const fetchedRef = React132.useRef(false);
|
|
34381
|
+
React132.useEffect(() => {
|
|
34227
34382
|
if (fetchedRef.current) return;
|
|
34228
34383
|
fetchedRef.current = true;
|
|
34229
34384
|
void fetchNotifications();
|
|
@@ -34369,7 +34524,7 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
34369
34524
|
// sidebar ICON_MAP, which made the settings rail fall back to Home.
|
|
34370
34525
|
icon: /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
|
|
34371
34526
|
iconName: "CreditCard",
|
|
34372
|
-
component: /* @__PURE__ */ jsx(
|
|
34527
|
+
component: /* @__PURE__ */ jsx(React132.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(SubscriptionPage, {}) })
|
|
34373
34528
|
});
|
|
34374
34529
|
}
|
|
34375
34530
|
if (showOrgSettings) {
|
|
@@ -34397,9 +34552,9 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
34397
34552
|
settingsTabs.push({
|
|
34398
34553
|
id: tab.id,
|
|
34399
34554
|
label: translated === labelKey ? tab.label : translated,
|
|
34400
|
-
icon:
|
|
34555
|
+
icon: React132.createElement(IconComp, { className: "h-4 w-4" }),
|
|
34401
34556
|
iconName,
|
|
34402
|
-
component:
|
|
34557
|
+
component: React132.createElement(tab.component),
|
|
34403
34558
|
// Flag plugin-contributed tabs so SettingsPage draws the core/plugins divider.
|
|
34404
34559
|
isPlugin: true,
|
|
34405
34560
|
group: tab.group,
|
|
@@ -34451,12 +34606,21 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34451
34606
|
profileKnown: !activeTenantId || profileKnownFor === activeTenantId
|
|
34452
34607
|
});
|
|
34453
34608
|
const navError = configError ?? tenantCtx?.loadError ?? null;
|
|
34454
|
-
const onNavRetry =
|
|
34609
|
+
const onNavRetry = React132.useCallback(() => {
|
|
34455
34610
|
if (tenantCtx?.loadError) tenantCtx.retryOrgs();
|
|
34456
34611
|
else window.location.reload();
|
|
34457
34612
|
}, [tenantCtx]);
|
|
34613
|
+
const { online } = useConnectivity();
|
|
34614
|
+
const navOffline = !!navError && (!online || toDataError(navError).kind === "offline");
|
|
34615
|
+
const lastGoodRail = React132.useRef(null);
|
|
34616
|
+
React132.useEffect(() => {
|
|
34617
|
+
if (!navError) return void 0;
|
|
34618
|
+
const retry = () => onNavRetry();
|
|
34619
|
+
window.addEventListener(RECONNECTED_EVENT, retry);
|
|
34620
|
+
return () => window.removeEventListener(RECONNECTED_EVENT, retry);
|
|
34621
|
+
}, [navError, onNavRetry]);
|
|
34458
34622
|
const currentProfile = usePermissionsStore((s) => s.currentProfile);
|
|
34459
|
-
const hasSystem =
|
|
34623
|
+
const hasSystem = React132.useCallback(
|
|
34460
34624
|
(perm) => {
|
|
34461
34625
|
if (!currentProfile) return false;
|
|
34462
34626
|
if (currentProfile.id === "owner" || currentProfile.name?.toLowerCase() === "owner") return true;
|
|
@@ -34470,9 +34634,10 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34470
34634
|
};
|
|
34471
34635
|
const path = useAdminPath();
|
|
34472
34636
|
const { user, signOut } = useAuth();
|
|
34473
|
-
|
|
34474
|
-
|
|
34637
|
+
React132.useEffect(() => installGlobalErrorHandlers(), []);
|
|
34638
|
+
React132.useEffect(() => registerErrorReporter((report) => {
|
|
34475
34639
|
if (report.source !== "data") return;
|
|
34640
|
+
if (report.offline || !getConnectivity().online) return;
|
|
34476
34641
|
const alvo = report.extra?.operation;
|
|
34477
34642
|
toast.error(
|
|
34478
34643
|
typeof alvo === "string" && alvo ? `N\xE3o foi poss\xEDvel carregar ${alvo}` : "N\xE3o foi poss\xEDvel carregar esta informa\xE7\xE3o",
|
|
@@ -34489,15 +34654,15 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34489
34654
|
const hasChatPanel = useRightRailStore((s) => s.panels.some((pn) => pn.id === "chat"));
|
|
34490
34655
|
const rightRail = railHasPanels ? /* @__PURE__ */ jsx(RightRail, { frame: contentFrame, attached: layout !== "topbar" }) : null;
|
|
34491
34656
|
const setRailMounted = useRightRailStore((s) => s.setMounted);
|
|
34492
|
-
|
|
34657
|
+
React132.useEffect(() => {
|
|
34493
34658
|
setRailMounted(true);
|
|
34494
34659
|
return () => setRailMounted(false);
|
|
34495
34660
|
}, [setRailMounted]);
|
|
34496
34661
|
useConnectorOAuthReturn();
|
|
34497
34662
|
const railWidthLive = useRightRailStore((s) => s.width);
|
|
34498
34663
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
34499
|
-
const railAutoCollapsedRef =
|
|
34500
|
-
|
|
34664
|
+
const railAutoCollapsedRef = React132.useRef(false);
|
|
34665
|
+
React132.useEffect(() => {
|
|
34501
34666
|
if (layout !== "sidebar") return;
|
|
34502
34667
|
const SIDEBAR_EXPANDED = 224;
|
|
34503
34668
|
const MIN_CONTENT = 620;
|
|
@@ -34519,22 +34684,22 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34519
34684
|
window.addEventListener("resize", apply);
|
|
34520
34685
|
return () => window.removeEventListener("resize", apply);
|
|
34521
34686
|
}, [railOpen, railWidthLive, layout, setSidebarCollapsed]);
|
|
34522
|
-
const [railWidth] =
|
|
34687
|
+
const [railWidth] = React132.useState(() => readRightRailWidth());
|
|
34523
34688
|
const billingPlans = useBillingStore((s) => s.plans);
|
|
34524
34689
|
const hasBilling = billingPlans.length > 0;
|
|
34525
34690
|
const orgPlan = useTenantOptional()?.org?.plan;
|
|
34526
|
-
const planBadge =
|
|
34691
|
+
const planBadge = React132.useMemo(
|
|
34527
34692
|
() => hasBilling ? resolvePlanBadge(orgPlan, billingPlans) : null,
|
|
34528
34693
|
[hasBilling, orgPlan, billingPlans]
|
|
34529
34694
|
);
|
|
34530
|
-
const softLimitKeys =
|
|
34695
|
+
const softLimitKeys = React132.useMemo(() => {
|
|
34531
34696
|
const plan = billingPlans.find((p) => p.id === (orgPlan || "free"));
|
|
34532
34697
|
return Object.keys(getPlanEntitlements(plan)?.limits ?? {});
|
|
34533
34698
|
}, [billingPlans, orgPlan]);
|
|
34534
34699
|
const overshoots = useOvershoots();
|
|
34535
34700
|
const navContributions = useNavContributionsStore((s) => s.contributions);
|
|
34536
34701
|
const appConfigNav = useAppConfigStore((state) => state.config.nav);
|
|
34537
|
-
const navigation =
|
|
34702
|
+
const navigation = React132.useMemo(() => {
|
|
34538
34703
|
const contributed = Object.values(navContributions).flat();
|
|
34539
34704
|
const flat = dedupeByRoute(
|
|
34540
34705
|
[...runtime.navigation, ...contributed].map((entry) => ({
|
|
@@ -34605,7 +34770,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34605
34770
|
}).filter((item) => item !== null).sort(compareNavigation);
|
|
34606
34771
|
return applyRailPreset(gated, presetRail, presetHide, presetWhole);
|
|
34607
34772
|
}, [runtime.navigation, runtime.routes, navContributions, pages, access, navWaiting, presetRail, presetHide, presetWhole, presetLabels]);
|
|
34608
|
-
const composedNavigation =
|
|
34773
|
+
const composedNavigation = React132.useMemo(() => {
|
|
34609
34774
|
if (!appConfigNav.length) return navigation;
|
|
34610
34775
|
const keyed = navigation.map((item) => ({ ...item, key: item.route }));
|
|
34611
34776
|
return applyNavComposition(keyed, appConfigNav).map((item) => {
|
|
@@ -34621,13 +34786,13 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34621
34786
|
};
|
|
34622
34787
|
});
|
|
34623
34788
|
}, [navigation, appConfigNav]);
|
|
34624
|
-
const resolvedBottomNav =
|
|
34789
|
+
const resolvedBottomNav = React132.useMemo(
|
|
34625
34790
|
() => deriveBottomNav(navigation, bottomNav, { assistant: hasChatPanel }),
|
|
34626
34791
|
[navigation, bottomNav, hasChatPanel]
|
|
34627
34792
|
);
|
|
34628
34793
|
const commandPaletteOpen = useLayoutStore((s) => s.commandPaletteOpen);
|
|
34629
34794
|
const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
|
|
34630
|
-
const commandItems =
|
|
34795
|
+
const commandItems = React132.useMemo(() => {
|
|
34631
34796
|
const navGroup = tr("layout.commandPalette.navigation", "Navigation");
|
|
34632
34797
|
const items = [];
|
|
34633
34798
|
for (const nav of navigation) {
|
|
@@ -34639,7 +34804,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34639
34804
|
return items;
|
|
34640
34805
|
}, [navigation]);
|
|
34641
34806
|
const globalSearch = useGlobalSearch();
|
|
34642
|
-
const routes =
|
|
34807
|
+
const routes = React132.useMemo(() => {
|
|
34643
34808
|
const list = [];
|
|
34644
34809
|
const entityRouteMap = /* @__PURE__ */ new Map();
|
|
34645
34810
|
for (const r of runtime.routes) {
|
|
@@ -34662,14 +34827,14 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34662
34827
|
setEntityRouteMap(entityRouteMap);
|
|
34663
34828
|
return list.sort((a, b) => routeScore(b.path) - routeScore(a.path));
|
|
34664
34829
|
}, [runtime.routes, pages, showSettings]);
|
|
34665
|
-
const match =
|
|
34830
|
+
const match = React132.useMemo(() => {
|
|
34666
34831
|
for (const r of routes) {
|
|
34667
34832
|
const params = matchRoute(r.path, path);
|
|
34668
34833
|
if (params) return { route: r, params };
|
|
34669
34834
|
}
|
|
34670
34835
|
return null;
|
|
34671
34836
|
}, [routes, path]);
|
|
34672
|
-
|
|
34837
|
+
React132.useEffect(() => {
|
|
34673
34838
|
if (!match && (path === "/" || path === "") && navigation.length > 0) {
|
|
34674
34839
|
navigateTo(navigation[0].route);
|
|
34675
34840
|
}
|
|
@@ -34677,11 +34842,11 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34677
34842
|
const ActiveComponent = match?.route.Component;
|
|
34678
34843
|
const activeParams = match?.params ?? {};
|
|
34679
34844
|
const routeKey = (match?.route.path ?? path).replace(/\/\*$/, "");
|
|
34680
|
-
const settingsTabs =
|
|
34845
|
+
const settingsTabs = React132.useMemo(
|
|
34681
34846
|
() => buildSettingsTabs(runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling),
|
|
34682
34847
|
[runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling]
|
|
34683
34848
|
);
|
|
34684
|
-
const profileRoute =
|
|
34849
|
+
const profileRoute = React132.useMemo(() => {
|
|
34685
34850
|
const explicit = routes.find((r) => r.path === "/perfil" || r.path === "/profile");
|
|
34686
34851
|
if (explicit) return explicit.path;
|
|
34687
34852
|
return showSettings ? "/settings/profile" : null;
|
|
@@ -34690,8 +34855,8 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34690
34855
|
const onBilling = hasBilling && showSettings ? () => navigateTo("/settings/subscription") : void 0;
|
|
34691
34856
|
const coreSettingsTabs = useCoreSettingsTabs({ showCompany: showBranding, showBranding });
|
|
34692
34857
|
const catalog = useModuleCatalog();
|
|
34693
|
-
const verticalByPlugin =
|
|
34694
|
-
const allSettingsTabs =
|
|
34858
|
+
const verticalByPlugin = React132.useMemo(() => pluginVerticalIndex(catalog), [catalog]);
|
|
34859
|
+
const allSettingsTabs = React132.useMemo(
|
|
34695
34860
|
() => {
|
|
34696
34861
|
const hidden = new Set(hiddenSettingsTabs ?? []);
|
|
34697
34862
|
const visible = [...coreSettingsTabs, ...settingsTabs].filter((tab) => !hidden.has(tab.id));
|
|
@@ -34714,7 +34879,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34714
34879
|
[coreSettingsTabs, settingsTabs, hiddenSettingsTabs, settingsGroups, verticalByPlugin]
|
|
34715
34880
|
);
|
|
34716
34881
|
usePublishSettingsTabs(allSettingsTabs.map((tab) => tab.id));
|
|
34717
|
-
const navWithSettings =
|
|
34882
|
+
const navWithSettings = React132.useMemo(() => {
|
|
34718
34883
|
if (!showSettings || allSettingsTabs.length === 0) return composedNavigation;
|
|
34719
34884
|
if (composedNavigation.some((item) => item.route === "/settings")) return composedNavigation;
|
|
34720
34885
|
return [...composedNavigation, {
|
|
@@ -34732,7 +34897,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34732
34897
|
const moduleRail = !inSettings && layout === "sidebar" && contextualNav && (path === contextualNav.base || path.startsWith(contextualNav.base + "/")) ? contextualNav : null;
|
|
34733
34898
|
const settingsPathActive = showSettings && (path === "/settings" || path.startsWith("/settings/"));
|
|
34734
34899
|
const activeSettingsTab = settingsPathActive ? path === "/settings" ? null : path.slice("/settings/".length).split("/")[0] : void 0;
|
|
34735
|
-
const settingsTabDef =
|
|
34900
|
+
const settingsTabDef = React132.useMemo(() => {
|
|
34736
34901
|
if (!showSettings || !path.startsWith("/settings/")) return void 0;
|
|
34737
34902
|
const id = path.slice("/settings/".length).split("/")[0];
|
|
34738
34903
|
return allSettingsTabs.find((tab) => tab.id === id);
|
|
@@ -34740,11 +34905,11 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34740
34905
|
const shellUser = user ? { fullName: user.fullName ?? user.email, email: user.email, avatarUrl: user.avatarUrl } : void 0;
|
|
34741
34906
|
const moduleVariant = moduleNav ?? (layout === "sidebar" ? "tabs" : "rail");
|
|
34742
34907
|
const setRailAvailable = useContextualNavStore((s) => s.setRailAvailable);
|
|
34743
|
-
|
|
34908
|
+
React132.useEffect(() => {
|
|
34744
34909
|
setRailAvailable(layout === "sidebar" && moduleVariant !== "rail");
|
|
34745
34910
|
}, [layout, moduleVariant, setRailAvailable]);
|
|
34746
34911
|
const moduleViewLabel = useModuleViewLabel();
|
|
34747
|
-
const activePageTitle =
|
|
34912
|
+
const activePageTitle = React132.useMemo(() => {
|
|
34748
34913
|
if (settingsTabDef) return settingsTabDef.label;
|
|
34749
34914
|
if (path === "/settings" || path.startsWith("/settings/")) return tr("common.settings", "Settings");
|
|
34750
34915
|
if (moduleViewLabel) return moduleViewLabel;
|
|
@@ -34759,7 +34924,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34759
34924
|
if (hiddenHit?.label) return hiddenHit.label;
|
|
34760
34925
|
return candidates.find((n) => n.route === "/")?.label ?? "";
|
|
34761
34926
|
}, [navigation, pages, path, tr, match, settingsTabDef, moduleViewLabel]);
|
|
34762
|
-
const parentBack =
|
|
34927
|
+
const parentBack = React132.useMemo(() => {
|
|
34763
34928
|
if (settingsTabDef) {
|
|
34764
34929
|
const first = allSettingsTabs[0]?.id;
|
|
34765
34930
|
return {
|
|
@@ -34802,9 +34967,9 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34802
34967
|
]
|
|
34803
34968
|
}
|
|
34804
34969
|
);
|
|
34805
|
-
const [railQuery, setRailQuery] =
|
|
34970
|
+
const [railQuery, setRailQuery] = React132.useState("");
|
|
34806
34971
|
const railBase = moduleRail?.base ?? null;
|
|
34807
|
-
|
|
34972
|
+
React132.useEffect(() => {
|
|
34808
34973
|
setRailQuery("");
|
|
34809
34974
|
}, [railBase]);
|
|
34810
34975
|
const railSearch = (placeholder) => /* @__PURE__ */ jsxs("div", { className: "relative px-0.5 pt-1", children: [
|
|
@@ -34835,10 +35000,16 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34835
35000
|
moduleRail.searchPlaceholder ? railSearch(moduleRail.searchPlaceholder) : null
|
|
34836
35001
|
] })
|
|
34837
35002
|
} : null;
|
|
34838
|
-
const
|
|
34839
|
-
|
|
35003
|
+
const liveRail = contextualRail?.navigation ?? navWithSettings;
|
|
35004
|
+
if (!navError && liveRail.length > 0) lastGoodRail.current = liveRail;
|
|
35005
|
+
const keptRail = navOffline ? lastGoodRail.current : null;
|
|
35006
|
+
const railRows = keptRail ?? liveRail;
|
|
35007
|
+
const railWaiting = !keptRail && (navWaiting || railRows.length === 0);
|
|
35008
|
+
const shownNavError = keptRail ? null : navOffline ? t("connection.menuOffline") : navError;
|
|
34840
35009
|
return /* @__PURE__ */ jsxs(ModuleLayoutProvider, { variant: moduleVariant, children: [
|
|
34841
35010
|
/* @__PURE__ */ jsx(ImpersonationBanner, {}),
|
|
35011
|
+
/* @__PURE__ */ jsx(ConnectionBanner, {}),
|
|
35012
|
+
/* @__PURE__ */ jsx(ShellMountedMarker, {}),
|
|
34842
35013
|
/* @__PURE__ */ jsxs(
|
|
34843
35014
|
AppShell,
|
|
34844
35015
|
{
|
|
@@ -34847,8 +35018,8 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34847
35018
|
navigation: railRows,
|
|
34848
35019
|
appNavigation: navWithSettings,
|
|
34849
35020
|
navLoading: railWaiting,
|
|
34850
|
-
navError,
|
|
34851
|
-
navErrorLabel: t("shell.navError") || "N\xE3o foi poss\xEDvel carregar o menu",
|
|
35021
|
+
navError: shownNavError,
|
|
35022
|
+
navErrorLabel: navOffline ? t("connection.offline") : t("shell.navError") || "N\xE3o foi poss\xEDvel carregar o menu",
|
|
34852
35023
|
navRetryLabel: t("common.retry") || "Tentar de novo",
|
|
34853
35024
|
onNavRetry,
|
|
34854
35025
|
sidebarSectionLabels: contextualRail?.sectionLabels,
|
|
@@ -35009,7 +35180,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
35009
35180
|
]
|
|
35010
35181
|
}
|
|
35011
35182
|
),
|
|
35012
|
-
/* @__PURE__ */ jsx(
|
|
35183
|
+
/* @__PURE__ */ jsx(React132.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
35013
35184
|
CommandPalette,
|
|
35014
35185
|
{
|
|
35015
35186
|
commands: commandItems,
|
|
@@ -35277,7 +35448,7 @@ function buildI18nConfig(config) {
|
|
|
35277
35448
|
function BillingInitializer({ config }) {
|
|
35278
35449
|
const setPlans = useBillingStore((s) => s.setPlans);
|
|
35279
35450
|
const setCheckout = useBillingStore((s) => s.setCheckout);
|
|
35280
|
-
|
|
35451
|
+
React132.useEffect(() => {
|
|
35281
35452
|
if (config.billing?.plans) setPlans(config.billing.plans.map(normalizeBillingPlan));
|
|
35282
35453
|
setCheckout(config.billing?.onCheckout ?? null);
|
|
35283
35454
|
}, [config.billing, setPlans, setCheckout]);
|
|
@@ -35396,13 +35567,13 @@ function ThemeInitializer({ config }) {
|
|
|
35396
35567
|
const rawBranding = useOrganizationStore((s) => s.currentOrg?.settings?.branding);
|
|
35397
35568
|
const access = useAccessOptional();
|
|
35398
35569
|
const wearsOwnSkin = access.entitled("branding.theme");
|
|
35399
|
-
const brandTokens =
|
|
35570
|
+
const brandTokens = React132.useMemo(
|
|
35400
35571
|
() => wearsOwnSkin ? normalizeBrand(rawBranding).tokens : EMPTY_BRAND.tokens,
|
|
35401
35572
|
[rawBranding, wearsOwnSkin]
|
|
35402
35573
|
);
|
|
35403
35574
|
const brandKey = JSON.stringify(brandTokens);
|
|
35404
35575
|
const appTheme = useAppTheme();
|
|
35405
|
-
|
|
35576
|
+
React132.useEffect(() => {
|
|
35406
35577
|
const tokens = JSON.parse(brandKey);
|
|
35407
35578
|
const brand = tokens.color?.primary ? hexToHslTriplet(tokens.color.primary) : null;
|
|
35408
35579
|
const base = appTheme ?? config.theme;
|
|
@@ -35420,20 +35591,20 @@ function ThemeInitializer({ config }) {
|
|
|
35420
35591
|
return null;
|
|
35421
35592
|
}
|
|
35422
35593
|
function PersistentCacheInitializer() {
|
|
35423
|
-
|
|
35594
|
+
React132.useEffect(() => {
|
|
35424
35595
|
attachPersistentCache();
|
|
35425
35596
|
void getPersistentCache()?.hydrate();
|
|
35426
35597
|
}, []);
|
|
35427
35598
|
return null;
|
|
35428
35599
|
}
|
|
35429
35600
|
function FayzEventBridgeInitializer({ config }) {
|
|
35430
|
-
|
|
35601
|
+
React132.useEffect(() => startFayzEventBridge(config.chat?.agent), [config.chat?.agent]);
|
|
35431
35602
|
return null;
|
|
35432
35603
|
}
|
|
35433
35604
|
function TeamInitializer({ config }) {
|
|
35434
35605
|
const setTeamPersonKinds = useOrganizationStore((s) => s.setTeamPersonKinds);
|
|
35435
35606
|
const kinds = config.team?.personKinds;
|
|
35436
|
-
|
|
35607
|
+
React132.useEffect(() => {
|
|
35437
35608
|
setTeamPersonKinds(kinds ?? []);
|
|
35438
35609
|
}, [setTeamPersonKinds, kinds]);
|
|
35439
35610
|
return null;
|
|
@@ -35450,7 +35621,7 @@ function ChatRailPanel({ config }) {
|
|
|
35450
35621
|
const agent = config.chat?.agent;
|
|
35451
35622
|
const voice = config.chat?.voice;
|
|
35452
35623
|
const whatsapp = config.chat?.whatsapp;
|
|
35453
|
-
const Component2 =
|
|
35624
|
+
const Component2 = React132.useMemo(() => {
|
|
35454
35625
|
const Panel = () => /* @__PURE__ */ jsx(
|
|
35455
35626
|
ChatConversation,
|
|
35456
35627
|
{
|
|
@@ -35467,8 +35638,8 @@ function ChatRailPanel({ config }) {
|
|
|
35467
35638
|
const conversations = useChatStore((s) => s.conversations);
|
|
35468
35639
|
const setConversations = useChatStore((s) => s.setConversations);
|
|
35469
35640
|
const user = useAuthStore((s) => s.user);
|
|
35470
|
-
const connection =
|
|
35471
|
-
|
|
35641
|
+
const connection = React132.useMemo(() => resolveFayzAgentConnection(agent), [agent]);
|
|
35642
|
+
React132.useEffect(() => {
|
|
35472
35643
|
if (!connection) return;
|
|
35473
35644
|
getFayzAgentClient(connection).listConversations(user?.id).then(setConversations).catch(() => {
|
|
35474
35645
|
});
|
|
@@ -35477,7 +35648,7 @@ function ChatRailPanel({ config }) {
|
|
|
35477
35648
|
useAssistantInviteStore((s) => s.invite?.id === ASK_AI_HANDOFF_ID);
|
|
35478
35649
|
const activeAgent = useAgent();
|
|
35479
35650
|
const persona = activeAgent?.name ?? invitePersona;
|
|
35480
|
-
const icon =
|
|
35651
|
+
const icon = React132.useMemo(
|
|
35481
35652
|
() => activeAgent ? function AgentTabIcon() {
|
|
35482
35653
|
return /* @__PURE__ */ jsx(
|
|
35483
35654
|
AgentAvatar,
|
|
@@ -35492,7 +35663,7 @@ function ChatRailPanel({ config }) {
|
|
|
35492
35663
|
[activeAgent]
|
|
35493
35664
|
);
|
|
35494
35665
|
useRightRailPanel(
|
|
35495
|
-
|
|
35666
|
+
React132.useMemo(
|
|
35496
35667
|
() => ({
|
|
35497
35668
|
id: "chat",
|
|
35498
35669
|
// "Chat" nomeia o CANO, não o que está do outro lado — e era a única
|
|
@@ -35508,22 +35679,22 @@ function ChatRailPanel({ config }) {
|
|
|
35508
35679
|
[Component2, conversations.length, persona, icon, activeAgent, t]
|
|
35509
35680
|
)
|
|
35510
35681
|
);
|
|
35511
|
-
|
|
35682
|
+
React132.useEffect(() => {
|
|
35512
35683
|
if (chatOpen) openPanel("chat");
|
|
35513
35684
|
}, [chatOpen, openPanel]);
|
|
35514
|
-
|
|
35685
|
+
React132.useEffect(() => {
|
|
35515
35686
|
if (!(railOpen && railActive === "chat")) setChatOpen(false);
|
|
35516
35687
|
}, [railOpen, railActive, setChatOpen]);
|
|
35517
35688
|
return null;
|
|
35518
35689
|
}
|
|
35519
35690
|
function AdminProviders({ config, children }) {
|
|
35520
35691
|
const currentOrg = useOrganizationStore((s) => s.currentOrg);
|
|
35521
|
-
const hasFayzAgent =
|
|
35692
|
+
const hasFayzAgent = React132.useMemo(
|
|
35522
35693
|
() => !!resolveFayzAgentConnection(config.chat?.agent),
|
|
35523
35694
|
[config.chat?.agent]
|
|
35524
35695
|
);
|
|
35525
35696
|
const assistantEnabled = config.chat?.enabled !== false && (!!config.chat || hasFayzAgent);
|
|
35526
|
-
|
|
35697
|
+
React132.useEffect(() => {
|
|
35527
35698
|
if (!config.chat || config.chat.enabled === false || config.chat.apiEndpoint || hasFayzAgent) return;
|
|
35528
35699
|
const gap = describeFayzAgentGap(config.chat.agent);
|
|
35529
35700
|
if (!gap) return;
|
|
@@ -35531,11 +35702,11 @@ function AdminProviders({ config, children }) {
|
|
|
35531
35702
|
`[fayz] chat configurado, agente inacess\xEDvel: falta ${gap.missing.join(", ")} no build. A chave sai do canal WEB do agente no Fayz (scripts/agent-provision.mjs).`
|
|
35532
35703
|
);
|
|
35533
35704
|
}, [config.chat, hasFayzAgent]);
|
|
35534
|
-
useRegisterStaff(config.chat?.staff);
|
|
35705
|
+
useRegisterStaff(config.chat?.staff, config.chat?.staffByApp);
|
|
35535
35706
|
const surface = config.chat?.surface ?? "dock";
|
|
35536
35707
|
const onConsentScreen = typeof window !== "undefined" && window.location.pathname.replace(/\/+$/, "").endsWith("/connect");
|
|
35537
35708
|
const showFab = assistantEnabled && surface === "dock" && !onConsentScreen;
|
|
35538
|
-
const resolved =
|
|
35709
|
+
const resolved = React132.useMemo(() => {
|
|
35539
35710
|
if (config.supabaseUrl && config.supabaseAnonKey) {
|
|
35540
35711
|
createFayzSupabaseClient(config.supabaseUrl, config.supabaseAnonKey);
|
|
35541
35712
|
}
|
|
@@ -35553,7 +35724,7 @@ function AdminProviders({ config, children }) {
|
|
|
35553
35724
|
const { bindings, ready: configReady } = useAppConfig();
|
|
35554
35725
|
const offeredPlugins = useOfferedPlugins();
|
|
35555
35726
|
const path = useAdminPath();
|
|
35556
|
-
const runtime =
|
|
35727
|
+
const runtime = React132.useMemo(
|
|
35557
35728
|
() => resolvePluginRuntime({
|
|
35558
35729
|
plugins: resolved.plugins,
|
|
35559
35730
|
// Só as ligações DESTA conta. Na janela da troca o config em mãos ainda
|
|
@@ -35593,7 +35764,7 @@ function AdminProviders({ config, children }) {
|
|
|
35593
35764
|
}),
|
|
35594
35765
|
[resolved.plugins, bindings, offeredPlugins, configReady, path, config.layout, currentOrg]
|
|
35595
35766
|
);
|
|
35596
|
-
|
|
35767
|
+
React132.useEffect(() => {
|
|
35597
35768
|
if (!import.meta.env?.DEV || !currentOrg) return;
|
|
35598
35769
|
const registered = new Set(resolved.plugins.map((p) => p.id));
|
|
35599
35770
|
const bound = new Set(bindings.map((b) => b.pluginId));
|
|
@@ -35649,7 +35820,7 @@ AdminProviders.displayName = "AdminProviders";
|
|
|
35649
35820
|
function createFayzApp(config) {
|
|
35650
35821
|
const authShellProps = getAuthShellProps(config.auth);
|
|
35651
35822
|
function FayzApp({ children }) {
|
|
35652
|
-
return /* @__PURE__ */ jsx(AdminProviders, { config, children: children ?? /* @__PURE__ */ jsx(FayzAppShell, { config, authShellProps }) });
|
|
35823
|
+
return /* @__PURE__ */ jsx(AppErrorBoundary, { children: /* @__PURE__ */ jsx(OfflineBootGuard, { children: /* @__PURE__ */ jsx(AdminProviders, { config, children: children ?? /* @__PURE__ */ jsx(FayzAppShell, { config, authShellProps }) }) }) });
|
|
35653
35824
|
}
|
|
35654
35825
|
FayzApp.displayName = `FayzApp(${config.name})`;
|
|
35655
35826
|
return FayzApp;
|
|
@@ -35947,8 +36118,8 @@ function manifestToFayzConfig(manifest, surfaceName) {
|
|
|
35947
36118
|
};
|
|
35948
36119
|
}
|
|
35949
36120
|
function AdminScaffold({ manifest, surface }) {
|
|
35950
|
-
const config =
|
|
35951
|
-
const authShellProps =
|
|
36121
|
+
const config = React132.useMemo(() => manifestToFayzConfig(manifest, surface), [manifest, surface]);
|
|
36122
|
+
const authShellProps = React132.useMemo(() => getAuthShellProps(config.auth), [config.auth]);
|
|
35952
36123
|
return /* @__PURE__ */ jsx(AdminProviders, { config, children: /* @__PURE__ */ jsx(ScaffoldShell, { config, authShellProps }) });
|
|
35953
36124
|
}
|
|
35954
36125
|
function ScaffoldShell({
|
|
@@ -36250,6 +36421,7 @@ function OrderDetailView(props) {
|
|
|
36250
36421
|
banner,
|
|
36251
36422
|
embedded
|
|
36252
36423
|
} = props;
|
|
36424
|
+
const actionSlots = Math.max(0, ...items.map((it) => it.actions?.length ?? 0));
|
|
36253
36425
|
const hasBadges = badges.length > 0 || !!props.badgesNode;
|
|
36254
36426
|
const titleNode = hasBadges ? /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
36255
36427
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: title }),
|
|
@@ -36290,36 +36462,45 @@ function OrderDetailView(props) {
|
|
|
36290
36462
|
/* @__PURE__ */ jsx(OrderDetailBlock, { title: itemsLabel, hint: `${items.length} item(ns)`, children: /* @__PURE__ */ jsx("div", { className: "divide-y", children: items.map((item, i) => /* @__PURE__ */ jsxs("div", { className: "group flex items-center gap-3 py-1.5", children: [
|
|
36291
36463
|
/* @__PURE__ */ jsx(Thumbnail, { src: item.imageUrl, size: "sm", icon: item.icon }),
|
|
36292
36464
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
36293
|
-
/* @__PURE__ */ jsx("p", { className: "truncate text-sm font-medium", children: item.name }),
|
|
36465
|
+
/* @__PURE__ */ jsx("p", { className: cn$1("truncate text-sm font-medium", item.struck && "text-muted-foreground line-through"), children: item.name }),
|
|
36294
36466
|
item.description ? /* @__PURE__ */ jsx("p", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null
|
|
36295
36467
|
] }),
|
|
36296
36468
|
item.account && /* @__PURE__ */ jsx(Badge, { variant: "secondary", title: item.account, className: "fz-tight-hide max-w-[12rem] shrink-0 truncate", children: item.account }),
|
|
36297
|
-
/* @__PURE__ */ jsxs("span", { className: "shrink-0 text-xs text-muted-foreground tabular-nums", children: [
|
|
36469
|
+
/* @__PURE__ */ jsxs("span", { className: cn$1("shrink-0 text-xs text-muted-foreground tabular-nums", item.struck && "line-through"), children: [
|
|
36298
36470
|
item.quantity,
|
|
36299
36471
|
" \xD7 ",
|
|
36300
36472
|
item.unitPrice
|
|
36301
36473
|
] }),
|
|
36302
|
-
/* @__PURE__ */ jsx("span", { className: "w-24 shrink-0 text-right text-sm font-medium tabular-nums", children: item.total }),
|
|
36303
|
-
|
|
36474
|
+
/* @__PURE__ */ jsx("span", { className: cn$1("w-24 shrink-0 text-right text-sm font-medium tabular-nums", item.struck && "text-muted-foreground line-through"), children: item.total }),
|
|
36475
|
+
actionSlots > 0 && // `opacity` e não montagem condicional: aparecendo só no
|
|
36304
36476
|
// hover, a linha mudaria de LARGURA ao passar o mouse e a
|
|
36305
36477
|
// coluna de valores dançaria. Reservado o espaço, o que
|
|
36306
36478
|
// muda é a tinta. Em toque não há hover, então os alvos
|
|
36307
36479
|
// ficam visíveis o tempo todo (`pointer: coarse`).
|
|
36308
|
-
|
|
36309
|
-
|
|
36310
|
-
|
|
36311
|
-
|
|
36312
|
-
|
|
36313
|
-
|
|
36314
|
-
|
|
36315
|
-
|
|
36316
|
-
|
|
36317
|
-
|
|
36318
|
-
|
|
36319
|
-
|
|
36320
|
-
|
|
36321
|
-
|
|
36322
|
-
|
|
36480
|
+
// Every row reserves the widest row's slot, so a line with fewer
|
|
36481
|
+
// actions (a cancelled one has none) keeps its numbers in the column.
|
|
36482
|
+
/* @__PURE__ */ jsx(
|
|
36483
|
+
"span",
|
|
36484
|
+
{
|
|
36485
|
+
style: { width: actionSlots * 28 + (actionSlots - 1) * 2 },
|
|
36486
|
+
className: "flex shrink-0 items-center justify-end gap-0.5 opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100 [@media(pointer:coarse)]:opacity-100",
|
|
36487
|
+
children: (item.actions ?? []).map((a) => {
|
|
36488
|
+
const Icon = a.icon;
|
|
36489
|
+
return /* @__PURE__ */ jsx(Hint, { label: a.label, children: /* @__PURE__ */ jsx(
|
|
36490
|
+
Button,
|
|
36491
|
+
{
|
|
36492
|
+
type: "button",
|
|
36493
|
+
variant: "ghost",
|
|
36494
|
+
size: "icon",
|
|
36495
|
+
className: "h-7 w-7",
|
|
36496
|
+
"aria-label": a.label,
|
|
36497
|
+
onClick: () => a.onSelect(item),
|
|
36498
|
+
children: Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-3.5 w-3.5" })
|
|
36499
|
+
}
|
|
36500
|
+
) }, a.id);
|
|
36501
|
+
})
|
|
36502
|
+
}
|
|
36503
|
+
)
|
|
36323
36504
|
] }, item.id ?? i)) }) }),
|
|
36324
36505
|
receivable !== void 0 && /* @__PURE__ */ jsxs(OrderDetailBlock, { title: receivableLabel, hint: "O mesmo registro que o Financeiro l\xEA", children: [
|
|
36325
36506
|
!receivable || receivable.rows.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: receivable?.emptyLabel ?? "Sem conta a receber." }) : /* @__PURE__ */ jsxs("div", { className: "text-sm", children: [
|
|
@@ -36386,9 +36567,9 @@ function LookupCreateInline({
|
|
|
36386
36567
|
className
|
|
36387
36568
|
}) {
|
|
36388
36569
|
const t = useTranslation();
|
|
36389
|
-
const [saving, setSaving] =
|
|
36390
|
-
const [error, setError] =
|
|
36391
|
-
const submitForm =
|
|
36570
|
+
const [saving, setSaving] = React132.useState(false);
|
|
36571
|
+
const [error, setError] = React132.useState(null);
|
|
36572
|
+
const submitForm = React132.useRef(null);
|
|
36392
36573
|
async function submit(data) {
|
|
36393
36574
|
setSaving(true);
|
|
36394
36575
|
setError(null);
|
|
@@ -36465,20 +36646,20 @@ function LookupCreateInline({
|
|
|
36465
36646
|
);
|
|
36466
36647
|
}
|
|
36467
36648
|
function useLookupCreate(lookup, onCreated, options = {}) {
|
|
36468
|
-
const [draftName, setDraftName] =
|
|
36649
|
+
const [draftName, setDraftName] = React132.useState(null);
|
|
36469
36650
|
const can = usePermissionOptional();
|
|
36470
36651
|
const entityDef = lookup?.entityDef;
|
|
36471
36652
|
const feature = entityDef?.permission?.feature;
|
|
36472
36653
|
const allowed = !feature || can(feature, "create");
|
|
36473
36654
|
const canCreate = !!lookup?.create && allowed;
|
|
36474
36655
|
const canEdit = !!entityDef && !!lookup?.load && !!lookup?.update && (!feature || can(feature, "edit"));
|
|
36475
|
-
const [editingId, setEditingId] =
|
|
36476
|
-
const onEdit =
|
|
36477
|
-
const createByName =
|
|
36656
|
+
const [editingId, setEditingId] = React132.useState(null);
|
|
36657
|
+
const onEdit = React132.useMemo(() => canEdit ? (id) => setEditingId(id) : void 0, [canEdit]);
|
|
36658
|
+
const createByName = React132.useCallback(async (name) => {
|
|
36478
36659
|
if (!lookup?.create) return;
|
|
36479
36660
|
onCreated(await lookup.create({ name }));
|
|
36480
36661
|
}, [lookup, onCreated]);
|
|
36481
|
-
const onCreate =
|
|
36662
|
+
const onCreate = React132.useMemo(() => {
|
|
36482
36663
|
if (!canCreate) return void 0;
|
|
36483
36664
|
if (!entityDef) return (name) => {
|
|
36484
36665
|
void createByName(name);
|
|
@@ -36587,8 +36768,8 @@ function OrderFormItemRow({
|
|
|
36587
36768
|
const rawKindLabel = itemTypes.find((tp) => tp.value === itemKind)?.label ?? itemKind;
|
|
36588
36769
|
const kindLabel = !itemKind || itemKind === "other" ? null : rawKindLabel;
|
|
36589
36770
|
const hasAdjustments = (discount ?? 0) > 0 || (surcharge ?? 0) > 0;
|
|
36590
|
-
const [showAdjustments, setShowAdjustments] =
|
|
36591
|
-
const [openExtras, setOpenExtras] =
|
|
36771
|
+
const [showAdjustments, setShowAdjustments] = React132.useState(hasAdjustments);
|
|
36772
|
+
const [openExtras, setOpenExtras] = React132.useState(
|
|
36592
36773
|
() => (extraFieldGroups ?? []).filter((g) => g.filled).map((g) => g.id)
|
|
36593
36774
|
);
|
|
36594
36775
|
const lookup = entityLookups[itemKind];
|
|
@@ -36858,9 +37039,9 @@ function OrderFormItemRow({
|
|
|
36858
37039
|
}
|
|
36859
37040
|
OrderFormItemRow.displayName = "OrderFormItemRow";
|
|
36860
37041
|
function CodeLookupField({ byCode, resolvedLabel, clearLabel, onResolved, onClear }) {
|
|
36861
|
-
const [code, setCode] =
|
|
36862
|
-
const [busy, setBusy] =
|
|
36863
|
-
const [error, setError] =
|
|
37042
|
+
const [code, setCode] = React132.useState("");
|
|
37043
|
+
const [busy, setBusy] = React132.useState(false);
|
|
37044
|
+
const [error, setError] = React132.useState(null);
|
|
36864
37045
|
async function submit() {
|
|
36865
37046
|
if (!code.trim() || busy) return;
|
|
36866
37047
|
setBusy(true);
|
|
@@ -36869,7 +37050,7 @@ function CodeLookupField({ byCode, resolvedLabel, clearLabel, onResolved, onClea
|
|
|
36869
37050
|
onResolved(await byCode.resolve(code));
|
|
36870
37051
|
setCode("");
|
|
36871
37052
|
} catch (e) {
|
|
36872
|
-
setError(
|
|
37053
|
+
setError(describeError(e));
|
|
36873
37054
|
} finally {
|
|
36874
37055
|
setBusy(false);
|
|
36875
37056
|
}
|
|
@@ -37081,13 +37262,13 @@ function OrderFormSkeleton({ parentLabel, onBack } = {}) {
|
|
|
37081
37262
|
] });
|
|
37082
37263
|
}
|
|
37083
37264
|
function useCatalogedItemTypes(itemTypes, lookups) {
|
|
37084
|
-
const countable =
|
|
37265
|
+
const countable = React132.useMemo(
|
|
37085
37266
|
() => itemTypes.filter((tp) => typeof lookups[tp.value]?.count === "function").map((tp) => tp.value),
|
|
37086
37267
|
[itemTypes, lookups]
|
|
37087
37268
|
);
|
|
37088
|
-
const [empty, setEmpty] =
|
|
37269
|
+
const [empty, setEmpty] = React132.useState([]);
|
|
37089
37270
|
const key = countable.join(",");
|
|
37090
|
-
|
|
37271
|
+
React132.useEffect(() => {
|
|
37091
37272
|
if (!countable.length) {
|
|
37092
37273
|
setEmpty([]);
|
|
37093
37274
|
return;
|
|
@@ -37106,7 +37287,7 @@ function useCatalogedItemTypes(itemTypes, lookups) {
|
|
|
37106
37287
|
cancelled = true;
|
|
37107
37288
|
};
|
|
37108
37289
|
}, [key, lookups]);
|
|
37109
|
-
return
|
|
37290
|
+
return React132.useMemo(
|
|
37110
37291
|
() => empty.length ? itemTypes.filter((tp) => !empty.includes(tp.value)) : itemTypes,
|
|
37111
37292
|
[itemTypes, empty]
|
|
37112
37293
|
);
|
|
@@ -37347,13 +37528,17 @@ function RecordPickerModal({
|
|
|
37347
37528
|
);
|
|
37348
37529
|
}) })
|
|
37349
37530
|
] }) }),
|
|
37350
|
-
/* @__PURE__ */ jsxs(
|
|
37351
|
-
|
|
37352
|
-
|
|
37353
|
-
|
|
37354
|
-
|
|
37355
|
-
|
|
37356
|
-
|
|
37531
|
+
/* @__PURE__ */ jsxs(
|
|
37532
|
+
ModalFooter,
|
|
37533
|
+
{
|
|
37534
|
+
variant: "bar",
|
|
37535
|
+
start: /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", "data-testid": "record-picker-count", children: multiple ? `${picked.length} selecionado(s)` : "" }),
|
|
37536
|
+
children: [
|
|
37537
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", onClick: onClose, children: "Cancelar" }),
|
|
37538
|
+
multiple && /* @__PURE__ */ jsx(Button, { size: "sm", onClick: confirm, disabled: picked.length === 0, "data-testid": "record-picker-confirm", children: confirmLabel })
|
|
37539
|
+
]
|
|
37540
|
+
}
|
|
37541
|
+
)
|
|
37357
37542
|
] }) }) }) });
|
|
37358
37543
|
}
|
|
37359
37544
|
function OrderCreateScreen({
|
|
@@ -37378,7 +37563,7 @@ function OrderCreateScreen({
|
|
|
37378
37563
|
errorActions,
|
|
37379
37564
|
saveBar
|
|
37380
37565
|
}) {
|
|
37381
|
-
const subtotal =
|
|
37566
|
+
const subtotal = React132.useMemo(
|
|
37382
37567
|
() => lines.reduce((sum, line) => sum + line.unitPrice * line.quantity, 0),
|
|
37383
37568
|
[lines]
|
|
37384
37569
|
);
|
|
@@ -37529,7 +37714,7 @@ function mergeLines(current2, incoming) {
|
|
|
37529
37714
|
return merged;
|
|
37530
37715
|
}
|
|
37531
37716
|
function ItemPicker({ search, onPick }) {
|
|
37532
|
-
const [open, setOpen] =
|
|
37717
|
+
const [open, setOpen] = React132.useState(false);
|
|
37533
37718
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
37534
37719
|
/* @__PURE__ */ jsxs(
|
|
37535
37720
|
"button",
|
|
@@ -37607,9 +37792,9 @@ function KanbanBoard({
|
|
|
37607
37792
|
toolbarActions
|
|
37608
37793
|
}) {
|
|
37609
37794
|
const collapsible = !!onToggleColumn;
|
|
37610
|
-
const frameRef =
|
|
37611
|
-
const [hoveredCol, setHoveredCol] =
|
|
37612
|
-
const centerFocused =
|
|
37795
|
+
const frameRef = React132.useRef(null);
|
|
37796
|
+
const [hoveredCol, setHoveredCol] = React132.useState(null);
|
|
37797
|
+
const centerFocused = React132.useCallback((event) => {
|
|
37613
37798
|
const frame = frameRef.current;
|
|
37614
37799
|
const column = event.target?.closest("[data-kanban-column]");
|
|
37615
37800
|
if (!frame || !column || frame.scrollWidth <= frame.clientWidth) return;
|
|
@@ -37618,14 +37803,14 @@ function KanbanBoard({
|
|
|
37618
37803
|
const delta = columnBox.left + columnBox.width / 2 - (frameBox.left + frameBox.width / 2);
|
|
37619
37804
|
if (Math.abs(delta) > 1) frame.scrollBy({ left: delta, behavior: "smooth" });
|
|
37620
37805
|
}, []);
|
|
37621
|
-
const autoScroll =
|
|
37622
|
-
const scrollStep =
|
|
37623
|
-
const stopAutoScroll =
|
|
37806
|
+
const autoScroll = React132.useRef(null);
|
|
37807
|
+
const scrollStep = React132.useRef(0);
|
|
37808
|
+
const stopAutoScroll = React132.useCallback(() => {
|
|
37624
37809
|
if (autoScroll.current !== null) cancelAnimationFrame(autoScroll.current);
|
|
37625
37810
|
autoScroll.current = null;
|
|
37626
37811
|
scrollStep.current = 0;
|
|
37627
37812
|
}, []);
|
|
37628
|
-
const tickAutoScroll =
|
|
37813
|
+
const tickAutoScroll = React132.useCallback(() => {
|
|
37629
37814
|
const frame = frameRef.current;
|
|
37630
37815
|
if (!frame || scrollStep.current === 0) {
|
|
37631
37816
|
stopAutoScroll();
|
|
@@ -37639,7 +37824,7 @@ function KanbanBoard({
|
|
|
37639
37824
|
}
|
|
37640
37825
|
autoScroll.current = requestAnimationFrame(tickAutoScroll);
|
|
37641
37826
|
}, [stopAutoScroll]);
|
|
37642
|
-
const onFrameDragOver =
|
|
37827
|
+
const onFrameDragOver = React132.useCallback((event) => {
|
|
37643
37828
|
const frame = frameRef.current;
|
|
37644
37829
|
if (!frame || frame.scrollWidth <= frame.clientWidth) return;
|
|
37645
37830
|
const box = frame.getBoundingClientRect();
|
|
@@ -37657,12 +37842,12 @@ function KanbanBoard({
|
|
|
37657
37842
|
}
|
|
37658
37843
|
if (autoScroll.current === null) autoScroll.current = requestAnimationFrame(tickAutoScroll);
|
|
37659
37844
|
}, [stopAutoScroll, tickAutoScroll]);
|
|
37660
|
-
const onFrameDragLeave =
|
|
37845
|
+
const onFrameDragLeave = React132.useCallback((event) => {
|
|
37661
37846
|
const indo = event.relatedTarget;
|
|
37662
37847
|
if (indo && event.currentTarget.contains(indo)) return;
|
|
37663
37848
|
stopAutoScroll();
|
|
37664
37849
|
}, [stopAutoScroll]);
|
|
37665
|
-
|
|
37850
|
+
React132.useEffect(() => stopAutoScroll, [stopAutoScroll]);
|
|
37666
37851
|
const hasToolbar = !!onSearchChange || !!onRefresh || !!toolbarActions;
|
|
37667
37852
|
const board = /* @__PURE__ */ jsx(
|
|
37668
37853
|
"div",
|
|
@@ -37770,10 +37955,10 @@ function BoardFrame({
|
|
|
37770
37955
|
toolbarActions,
|
|
37771
37956
|
className = ""
|
|
37772
37957
|
}) {
|
|
37773
|
-
const [open, setOpen] =
|
|
37774
|
-
const inputRef =
|
|
37958
|
+
const [open, setOpen] = React132.useState(false);
|
|
37959
|
+
const inputRef = React132.useRef(null);
|
|
37775
37960
|
const expanded = open || !!search;
|
|
37776
|
-
|
|
37961
|
+
React132.useEffect(() => {
|
|
37777
37962
|
if (open) inputRef.current?.focus();
|
|
37778
37963
|
}, [open]);
|
|
37779
37964
|
function collapse() {
|
|
@@ -37852,14 +38037,14 @@ function OrderBoardView({
|
|
|
37852
38037
|
rowId,
|
|
37853
38038
|
selectedRowId
|
|
37854
38039
|
}) {
|
|
37855
|
-
const getId =
|
|
38040
|
+
const getId = React132.useCallback(
|
|
37856
38041
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
37857
38042
|
[rowId]
|
|
37858
38043
|
);
|
|
37859
|
-
const [lastClicked, setLastClicked] =
|
|
37860
|
-
const [advancing, setAdvancing] =
|
|
38044
|
+
const [lastClicked, setLastClicked] = React132.useState(null);
|
|
38045
|
+
const [advancing, setAdvancing] = React132.useState({});
|
|
37861
38046
|
const selected = selectedRowId !== void 0 ? selectedRowId : lastClicked;
|
|
37862
|
-
const grouped =
|
|
38047
|
+
const grouped = React132.useMemo(() => {
|
|
37863
38048
|
const map = /* @__PURE__ */ new Map();
|
|
37864
38049
|
for (const col of board.columns) map.set(col.id, []);
|
|
37865
38050
|
for (const row of rows) {
|
|
@@ -37983,24 +38168,24 @@ function OrderListView({
|
|
|
37983
38168
|
boards,
|
|
37984
38169
|
viewKey
|
|
37985
38170
|
}) {
|
|
37986
|
-
const [search, setSearch] =
|
|
37987
|
-
const [page, setPage] =
|
|
37988
|
-
const [rawSelection, setRawSelection] =
|
|
37989
|
-
const offered =
|
|
38171
|
+
const [search, setSearch] = React132.useState("");
|
|
38172
|
+
const [page, setPage] = React132.useState(1);
|
|
38173
|
+
const [rawSelection, setRawSelection] = React132.useState([]);
|
|
38174
|
+
const offered = React132.useMemo(
|
|
37990
38175
|
() => views && views.length > 0 ? views : ["list"],
|
|
37991
38176
|
[views]
|
|
37992
38177
|
);
|
|
37993
|
-
const customFor =
|
|
38178
|
+
const customFor = React132.useCallback(
|
|
37994
38179
|
(id) => boards?.[id]?.render ?? null,
|
|
37995
38180
|
[boards]
|
|
37996
38181
|
);
|
|
37997
|
-
const boardFor =
|
|
38182
|
+
const boardFor = React132.useCallback(
|
|
37998
38183
|
(id) => (id === "board" ? board : boards?.[id]?.config) ?? null,
|
|
37999
38184
|
[board, boards]
|
|
38000
38185
|
);
|
|
38001
38186
|
const canBoard = offered.length > 1 && offered.some((id) => id !== "list" && (!!boardFor(id) || !!customFor(id)));
|
|
38002
38187
|
const storageKey2 = viewKey ? `fayz.orderView.${viewKey}` : null;
|
|
38003
|
-
const [view, setView] =
|
|
38188
|
+
const [view, setView] = React132.useState(() => {
|
|
38004
38189
|
const fallback = offered.includes(defaultView) ? defaultView : offered[0];
|
|
38005
38190
|
if (!storageKey2) return fallback;
|
|
38006
38191
|
try {
|
|
@@ -38010,7 +38195,7 @@ function OrderListView({
|
|
|
38010
38195
|
return fallback;
|
|
38011
38196
|
}
|
|
38012
38197
|
});
|
|
38013
|
-
const viewTabs =
|
|
38198
|
+
const viewTabs = React132.useMemo(
|
|
38014
38199
|
() => offered.map((option) => ({
|
|
38015
38200
|
value: option,
|
|
38016
38201
|
label: option === "list" ? "Lista" : boards?.[option]?.label ?? "Quadro",
|
|
@@ -38018,7 +38203,7 @@ function OrderListView({
|
|
|
38018
38203
|
})),
|
|
38019
38204
|
[offered, boards]
|
|
38020
38205
|
);
|
|
38021
|
-
const chooseView =
|
|
38206
|
+
const chooseView = React132.useCallback((next) => {
|
|
38022
38207
|
setView(next);
|
|
38023
38208
|
if (!storageKey2) return;
|
|
38024
38209
|
try {
|
|
@@ -38036,7 +38221,7 @@ function OrderListView({
|
|
|
38036
38221
|
const activeBoard = view === "list" ? null : boardFor(view);
|
|
38037
38222
|
const activeCustom = view === "list" ? null : customFor(view);
|
|
38038
38223
|
const showingBoard = !!activeBoard || !!activeCustom;
|
|
38039
|
-
const cols =
|
|
38224
|
+
const cols = React132.useMemo(
|
|
38040
38225
|
() => columns.map((c) => ({
|
|
38041
38226
|
id: c.key,
|
|
38042
38227
|
header: () => /* @__PURE__ */ jsx("div", { className: c.align === "right" ? "text-right" : "", children: c.header }),
|
|
@@ -38044,25 +38229,25 @@ function OrderListView({
|
|
|
38044
38229
|
})),
|
|
38045
38230
|
[columns]
|
|
38046
38231
|
);
|
|
38047
|
-
const filtered =
|
|
38232
|
+
const filtered = React132.useMemo(() => {
|
|
38048
38233
|
const term = search.trim().toLowerCase();
|
|
38049
38234
|
if (!term || !searchText) return rows;
|
|
38050
38235
|
return rows.filter((row) => searchText(row).toLowerCase().includes(term));
|
|
38051
38236
|
}, [rows, search, searchText]);
|
|
38052
|
-
|
|
38237
|
+
React132.useEffect(() => {
|
|
38053
38238
|
setPage(1);
|
|
38054
38239
|
}, [search]);
|
|
38055
38240
|
const paged = pageSize > 0 ? filtered.slice((page - 1) * pageSize, page * pageSize) : filtered;
|
|
38056
|
-
const getId =
|
|
38241
|
+
const getId = React132.useCallback(
|
|
38057
38242
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
38058
38243
|
[rowId]
|
|
38059
38244
|
);
|
|
38060
|
-
const pageIds =
|
|
38061
|
-
const selectedIds =
|
|
38245
|
+
const pageIds = React132.useMemo(() => paged.map(getId), [paged, getId]);
|
|
38246
|
+
const selectedIds = React132.useMemo(
|
|
38062
38247
|
() => rawSelection.filter((id) => pageIds.includes(id)),
|
|
38063
38248
|
[rawSelection, pageIds]
|
|
38064
38249
|
);
|
|
38065
|
-
const selectedRows =
|
|
38250
|
+
const selectedRows = React132.useMemo(
|
|
38066
38251
|
() => paged.filter((row) => selectedIds.includes(getId(row))),
|
|
38067
38252
|
[paged, selectedIds, getId]
|
|
38068
38253
|
);
|
|
@@ -38212,13 +38397,13 @@ function PaymentStatusBadge({
|
|
|
38212
38397
|
receiveLabel = "Receber",
|
|
38213
38398
|
onOpenDetails
|
|
38214
38399
|
}) {
|
|
38215
|
-
const [open, setOpen] =
|
|
38216
|
-
const [lines, setLines] =
|
|
38217
|
-
const timer =
|
|
38218
|
-
|
|
38400
|
+
const [open, setOpen] = React132__default.useState(false);
|
|
38401
|
+
const [lines, setLines] = React132__default.useState(null);
|
|
38402
|
+
const timer = React132__default.useRef(null);
|
|
38403
|
+
React132__default.useEffect(() => {
|
|
38219
38404
|
setLines(null);
|
|
38220
38405
|
}, [status, paidAmount]);
|
|
38221
|
-
const load =
|
|
38406
|
+
const load = React132__default.useCallback(() => {
|
|
38222
38407
|
if (lines || !onLoadDetails) return;
|
|
38223
38408
|
void onLoadDetails().then(setLines).catch(() => setLines([]));
|
|
38224
38409
|
}, [lines, onLoadDetails]);
|
|
@@ -38353,13 +38538,13 @@ function invalidateOrdersPaymentStatus(orderId) {
|
|
|
38353
38538
|
else cache2.clear();
|
|
38354
38539
|
}
|
|
38355
38540
|
function useOrdersPaymentStatus(orderIds) {
|
|
38356
|
-
const key =
|
|
38541
|
+
const key = React132.useMemo(
|
|
38357
38542
|
() => Array.from(new Set(orderIds.filter(Boolean))).sort().join(","),
|
|
38358
38543
|
[orderIds]
|
|
38359
38544
|
);
|
|
38360
|
-
const [byOrder, setByOrder] =
|
|
38361
|
-
const [loading, setLoading] =
|
|
38362
|
-
const load =
|
|
38545
|
+
const [byOrder, setByOrder] = React132.useState(() => /* @__PURE__ */ new Map());
|
|
38546
|
+
const [loading, setLoading] = React132.useState(false);
|
|
38547
|
+
const load = React132.useCallback(async (force = false) => {
|
|
38363
38548
|
const ids = key ? key.split(",") : [];
|
|
38364
38549
|
if (ids.length === 0) {
|
|
38365
38550
|
setByOrder(/* @__PURE__ */ new Map());
|
|
@@ -38390,7 +38575,7 @@ function useOrdersPaymentStatus(orderIds) {
|
|
|
38390
38575
|
}
|
|
38391
38576
|
setByOrder(new Map(ids.map((id) => [id, cache2.get(id)]).filter(([, v]) => Boolean(v))));
|
|
38392
38577
|
}, [key]);
|
|
38393
|
-
|
|
38578
|
+
React132.useEffect(() => {
|
|
38394
38579
|
void load();
|
|
38395
38580
|
}, [load]);
|
|
38396
38581
|
return { byOrder, loading, reload: () => load(true) };
|
|
@@ -38457,12 +38642,12 @@ function money2(value, currency) {
|
|
|
38457
38642
|
return value.toLocaleString("pt-BR", { style: "currency", currency: currency || "BRL" });
|
|
38458
38643
|
}
|
|
38459
38644
|
function useOrderDetail(orderId) {
|
|
38460
|
-
const [order, setOrder] =
|
|
38461
|
-
const [loading, setLoading] =
|
|
38462
|
-
const [error, setError] =
|
|
38463
|
-
const [nonce, setNonce] =
|
|
38464
|
-
const
|
|
38465
|
-
|
|
38645
|
+
const [order, setOrder] = React132.useState(null);
|
|
38646
|
+
const [loading, setLoading] = React132.useState(false);
|
|
38647
|
+
const [error, setError] = React132.useState(null);
|
|
38648
|
+
const [nonce, setNonce] = React132.useState(0);
|
|
38649
|
+
const reload2 = React132.useCallback(() => setNonce((n) => n + 1), []);
|
|
38650
|
+
React132.useEffect(() => {
|
|
38466
38651
|
if (!orderId) {
|
|
38467
38652
|
setOrder(null);
|
|
38468
38653
|
setError(null);
|
|
@@ -38525,7 +38710,7 @@ function useOrderDetail(orderId) {
|
|
|
38525
38710
|
cancelled = true;
|
|
38526
38711
|
};
|
|
38527
38712
|
}, [orderId, nonce]);
|
|
38528
|
-
return { order, loading, error, reload };
|
|
38713
|
+
return { order, loading, error, reload: reload2 };
|
|
38529
38714
|
}
|
|
38530
38715
|
var statusWord = (v) => v ? ORDER_STATUS_LABELS[v] ?? v : void 0;
|
|
38531
38716
|
var kindWord = (v) => v ? ORDER_KIND_LABELS[v] ?? v : void 0;
|
|
@@ -38577,17 +38762,17 @@ function OrderDetailRail({
|
|
|
38577
38762
|
kindLabel,
|
|
38578
38763
|
channelLabel
|
|
38579
38764
|
}) {
|
|
38580
|
-
const { order, loading, error, reload } = useOrderDetail(orderId);
|
|
38765
|
+
const { order, loading, error, reload: reload2 } = useOrderDetail(orderId);
|
|
38581
38766
|
const { byOrder: paymentByOrder } = useOrdersPaymentStatus([orderId]);
|
|
38582
|
-
const [running, setRunning] =
|
|
38583
|
-
const [pending2, setPending] =
|
|
38767
|
+
const [running, setRunning] = React132.useState(null);
|
|
38768
|
+
const [pending2, setPending] = React132.useState(null);
|
|
38584
38769
|
const perform = async (action) => {
|
|
38585
38770
|
if (!order) return;
|
|
38586
38771
|
setRunning(action.id);
|
|
38587
38772
|
try {
|
|
38588
38773
|
await action.onSelect(order);
|
|
38589
38774
|
onActionDone?.();
|
|
38590
|
-
if (action.keepOpen)
|
|
38775
|
+
if (action.keepOpen) reload2();
|
|
38591
38776
|
else onClose();
|
|
38592
38777
|
} finally {
|
|
38593
38778
|
setRunning(null);
|
|
@@ -38643,7 +38828,7 @@ function OrderDetailRail({
|
|
|
38643
38828
|
/* @__PURE__ */ jsx("p", { className: "pb-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/60", children: "Observa\xE7\xF5es" }),
|
|
38644
38829
|
/* @__PURE__ */ jsx("p", { className: "text-sm", children: order.notes })
|
|
38645
38830
|
] }),
|
|
38646
|
-
children?.(order,
|
|
38831
|
+
children?.(order, reload2),
|
|
38647
38832
|
/* @__PURE__ */ jsx("div", { className: "mt-auto border-t border-border/40 px-4 py-2.5", children: /* @__PURE__ */ jsxs("dl", { className: "grid grid-cols-[1fr_auto] gap-x-4 gap-y-1 text-sm", children: [
|
|
38648
38833
|
/* @__PURE__ */ jsx(Row3, { label: "Subtotal", value: money2(order.subtotal, order.currency) }),
|
|
38649
38834
|
order.discount > 0 && /* @__PURE__ */ jsx(Row3, { label: "Desconto", value: `\u2212 ${money2(order.discount, order.currency)}` }),
|
|
@@ -38738,11 +38923,11 @@ function receivableTone(value) {
|
|
|
38738
38923
|
return "warning";
|
|
38739
38924
|
}
|
|
38740
38925
|
function useOrderReceivable(orderId) {
|
|
38741
|
-
const [receivable, setReceivable] =
|
|
38926
|
+
const [receivable, setReceivable] = React132.useState(
|
|
38742
38927
|
() => orderId ? cache3.get(orderId) ?? null : null
|
|
38743
38928
|
);
|
|
38744
|
-
const [loading, setLoading] =
|
|
38745
|
-
const
|
|
38929
|
+
const [loading, setLoading] = React132.useState(() => Boolean(orderId) && !cache3.has(orderId));
|
|
38930
|
+
const reload2 = React132.useCallback(async (force = false) => {
|
|
38746
38931
|
if (!orderId) return;
|
|
38747
38932
|
const db2 = getSupabaseClientOptional();
|
|
38748
38933
|
if (!db2) {
|
|
@@ -38765,10 +38950,10 @@ function useOrderReceivable(orderId) {
|
|
|
38765
38950
|
setReceivable(next);
|
|
38766
38951
|
setLoading(false);
|
|
38767
38952
|
}, [orderId]);
|
|
38768
|
-
|
|
38769
|
-
void
|
|
38770
|
-
}, [
|
|
38771
|
-
return { receivable, loading, reload };
|
|
38953
|
+
React132.useEffect(() => {
|
|
38954
|
+
void reload2();
|
|
38955
|
+
}, [reload2]);
|
|
38956
|
+
return { receivable, loading, reload: reload2 };
|
|
38772
38957
|
}
|
|
38773
38958
|
function toOrderDetailReceivable(receivable, money4, options = {}) {
|
|
38774
38959
|
if (!receivable) return null;
|
|
@@ -38918,15 +39103,15 @@ function linesOf(order) {
|
|
|
38918
39103
|
}
|
|
38919
39104
|
function useOrderEditor(orderId) {
|
|
38920
39105
|
const { order, loading, error } = useOrderDetail(orderId);
|
|
38921
|
-
const [lines, setLines] =
|
|
38922
|
-
const [saving, setSaving] =
|
|
38923
|
-
const originalRef =
|
|
38924
|
-
|
|
39106
|
+
const [lines, setLines] = React132.useState([]);
|
|
39107
|
+
const [saving, setSaving] = React132.useState(false);
|
|
39108
|
+
const originalRef = React132.useRef([]);
|
|
39109
|
+
React132.useEffect(() => {
|
|
38925
39110
|
const seeded = linesOf(order);
|
|
38926
39111
|
originalRef.current = seeded;
|
|
38927
39112
|
setLines(seeded);
|
|
38928
39113
|
}, [order]);
|
|
38929
|
-
const dirty =
|
|
39114
|
+
const dirty = React132.useMemo(() => {
|
|
38930
39115
|
const before = originalRef.current;
|
|
38931
39116
|
if (before.length !== lines.length) return true;
|
|
38932
39117
|
return lines.some((line, i) => {
|
|
@@ -38934,7 +39119,7 @@ function useOrderEditor(orderId) {
|
|
|
38934
39119
|
return !was || was.key !== line.key || was.quantity !== line.quantity || was.unitPrice !== line.unitPrice;
|
|
38935
39120
|
});
|
|
38936
39121
|
}, [lines]);
|
|
38937
|
-
const save =
|
|
39122
|
+
const save = React132.useCallback(async () => {
|
|
38938
39123
|
if (!orderId || !order) return { ok: false, error: "Pedido n\xE3o carregado" };
|
|
38939
39124
|
const db2 = getSupabaseClientOptional();
|
|
38940
39125
|
if (!db2) return { ok: false, error: "Sem conex\xE3o" };
|
|
@@ -39091,19 +39276,19 @@ function createClientOrdersProvider() {
|
|
|
39091
39276
|
}
|
|
39092
39277
|
function createPlaceholder(title, description) {
|
|
39093
39278
|
return function PlaceholderPage() {
|
|
39094
|
-
return
|
|
39279
|
+
return React132__default.createElement(
|
|
39095
39280
|
"div",
|
|
39096
39281
|
{ className: "mx-auto max-w-4xl" },
|
|
39097
|
-
|
|
39098
|
-
description ?
|
|
39099
|
-
|
|
39282
|
+
React132__default.createElement("h1", { className: "text-3xl font-bold text-foreground" }, title),
|
|
39283
|
+
description ? React132__default.createElement("p", { className: "mt-1 text-muted-foreground" }, description) : null,
|
|
39284
|
+
React132__default.createElement(
|
|
39100
39285
|
"div",
|
|
39101
39286
|
{ className: "mt-8 flex items-center justify-center rounded-card border border-dashed border-border bg-card p-16" },
|
|
39102
|
-
|
|
39287
|
+
React132__default.createElement(
|
|
39103
39288
|
"div",
|
|
39104
39289
|
{ className: "text-center" },
|
|
39105
|
-
|
|
39106
|
-
|
|
39290
|
+
React132__default.createElement("p", { className: "text-lg font-medium text-muted-foreground" }, "Coming Soon"),
|
|
39291
|
+
React132__default.createElement(
|
|
39107
39292
|
"p",
|
|
39108
39293
|
{ className: "mt-1 text-sm text-muted-foreground/70" },
|
|
39109
39294
|
"This module is being built as a plugin."
|
|
@@ -39184,7 +39369,7 @@ function ModuleActionBar({
|
|
|
39184
39369
|
trailing
|
|
39185
39370
|
}) {
|
|
39186
39371
|
const t = useTranslation();
|
|
39187
|
-
const actions =
|
|
39372
|
+
const actions = React132__default.useMemo(() => {
|
|
39188
39373
|
const out = (quickActions ?? []).map((qa, i) => ({
|
|
39189
39374
|
id: qa.id,
|
|
39190
39375
|
label: qa.label,
|
|
@@ -39216,9 +39401,9 @@ function ModuleActionBar({
|
|
|
39216
39401
|
] });
|
|
39217
39402
|
}
|
|
39218
39403
|
function createPluginContext(displayName) {
|
|
39219
|
-
const ConfigContext =
|
|
39220
|
-
const ProviderContext =
|
|
39221
|
-
const StoreContext =
|
|
39404
|
+
const ConfigContext = React132__default.createContext(null);
|
|
39405
|
+
const ProviderContext = React132__default.createContext(null);
|
|
39406
|
+
const StoreContext = React132__default.createContext(null);
|
|
39222
39407
|
const ContextProvider = ({
|
|
39223
39408
|
config,
|
|
39224
39409
|
provider: provider2,
|
|
@@ -39227,17 +39412,17 @@ function createPluginContext(displayName) {
|
|
|
39227
39412
|
}) => /* @__PURE__ */ jsx(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsx(ProviderContext.Provider, { value: provider2, children: /* @__PURE__ */ jsx(StoreContext.Provider, { value: store, children }) }) });
|
|
39228
39413
|
ContextProvider.displayName = `${displayName}ContextProvider`;
|
|
39229
39414
|
function useConfig() {
|
|
39230
|
-
const ctx =
|
|
39415
|
+
const ctx = React132__default.useContext(ConfigContext);
|
|
39231
39416
|
if (!ctx) throw new Error(`useConfig must be used within ${displayName}`);
|
|
39232
39417
|
return ctx;
|
|
39233
39418
|
}
|
|
39234
39419
|
function useProvider() {
|
|
39235
|
-
const ctx =
|
|
39420
|
+
const ctx = React132__default.useContext(ProviderContext);
|
|
39236
39421
|
if (!ctx) throw new Error(`useProvider must be used within ${displayName}`);
|
|
39237
39422
|
return ctx;
|
|
39238
39423
|
}
|
|
39239
39424
|
function useStore2(selector) {
|
|
39240
|
-
const store =
|
|
39425
|
+
const store = React132__default.useContext(StoreContext);
|
|
39241
39426
|
if (!store) throw new Error(`useStore must be used within ${displayName}`);
|
|
39242
39427
|
return useStore$1(store, selector);
|
|
39243
39428
|
}
|
|
@@ -39294,7 +39479,7 @@ function PluginRegistryManager({ registries, routeBase, className }) {
|
|
|
39294
39479
|
return registries[0]?.id ?? "";
|
|
39295
39480
|
};
|
|
39296
39481
|
const [activeTab, setActiveTab] = useState(getTabFromHash);
|
|
39297
|
-
|
|
39482
|
+
React132__default.useEffect(() => {
|
|
39298
39483
|
if (!routeBase) return;
|
|
39299
39484
|
const handler = () => setActiveTab(getTabFromHash());
|
|
39300
39485
|
window.addEventListener("hashchange", handler);
|
|
@@ -39505,7 +39690,7 @@ function PersonLink2({ personId, name, avatarUrl, lookup, kind, profileHref, tab
|
|
|
39505
39690
|
const email = data?.email;
|
|
39506
39691
|
const phone = data?.phone;
|
|
39507
39692
|
const resolvedKind = kind ?? data?.kind ?? person?.group;
|
|
39508
|
-
const actions =
|
|
39693
|
+
const actions = React132__default.useMemo(
|
|
39509
39694
|
() => personId ? getPersonActions(resolvedKind) : [],
|
|
39510
39695
|
[personId, resolvedKind]
|
|
39511
39696
|
);
|
|
@@ -39958,7 +40143,7 @@ function useRememberedList(options) {
|
|
|
39958
40143
|
const entry = lists.get(key);
|
|
39959
40144
|
const [rows, setRows] = useState(() => entry.rows);
|
|
39960
40145
|
const [error, setError] = useState("");
|
|
39961
|
-
const
|
|
40146
|
+
const reload2 = useCallback(async () => {
|
|
39962
40147
|
const e = lists.get(key);
|
|
39963
40148
|
e.stale = false;
|
|
39964
40149
|
e.dirty.clear();
|
|
@@ -39975,14 +40160,14 @@ function useRememberedList(options) {
|
|
|
39975
40160
|
}, [key]);
|
|
39976
40161
|
const settle = useCallback(async () => {
|
|
39977
40162
|
const e = lists.get(key);
|
|
39978
|
-
if (e.stale || !e.rows) return
|
|
40163
|
+
if (e.stale || !e.rows) return reload2();
|
|
39979
40164
|
if (e.dirty.size === 0) return;
|
|
39980
40165
|
const { loadOne, rowFor } = opts.current;
|
|
39981
40166
|
const current2 = e.rows;
|
|
39982
40167
|
const ids = [...e.dirty];
|
|
39983
40168
|
e.dirty.clear();
|
|
39984
40169
|
const targets = ids.map((id) => rowFor ? rowFor(current2, id) : current2.find((r) => r.id === id));
|
|
39985
|
-
if (!loadOne || targets.some((t) => !t)) return
|
|
40170
|
+
if (!loadOne || targets.some((t) => !t)) return reload2();
|
|
39986
40171
|
try {
|
|
39987
40172
|
const unique = [...new Set(targets.map((t) => t.id))];
|
|
39988
40173
|
const fresh = new Map(await Promise.all(unique.map(async (id) => [id, await loadOne(id)])));
|
|
@@ -39990,9 +40175,9 @@ function useRememberedList(options) {
|
|
|
39990
40175
|
e.rows = next;
|
|
39991
40176
|
setRows(next);
|
|
39992
40177
|
} catch {
|
|
39993
|
-
return
|
|
40178
|
+
return reload2();
|
|
39994
40179
|
}
|
|
39995
|
-
}, [key,
|
|
40180
|
+
}, [key, reload2]);
|
|
39996
40181
|
useEffect(() => {
|
|
39997
40182
|
const e = lists.get(key);
|
|
39998
40183
|
e.tables = opts.current.tables;
|
|
@@ -40005,7 +40190,7 @@ function useRememberedList(options) {
|
|
|
40005
40190
|
if (e.wake) e.wake = void 0;
|
|
40006
40191
|
};
|
|
40007
40192
|
}, [key, settle]);
|
|
40008
|
-
return { rows, error, reload };
|
|
40193
|
+
return { rows, error, reload: reload2 };
|
|
40009
40194
|
}
|
|
40010
40195
|
var STORAGE_PREFIX2 = "saas:prefs:";
|
|
40011
40196
|
function readStore(pluginId, defaults) {
|
|
@@ -40330,10 +40515,10 @@ function useTeachMe(def) {
|
|
|
40330
40515
|
return useFeatureHelp(def).teach;
|
|
40331
40516
|
}
|
|
40332
40517
|
function useFeatureHelp(def) {
|
|
40333
|
-
const ref =
|
|
40518
|
+
const ref = React132.useRef(def);
|
|
40334
40519
|
ref.current = def;
|
|
40335
40520
|
const id = `teach.${def.feature}`;
|
|
40336
|
-
const contribution =
|
|
40521
|
+
const contribution = React132.useMemo(
|
|
40337
40522
|
() => ({
|
|
40338
40523
|
id,
|
|
40339
40524
|
pluginId: "teach-me",
|
|
@@ -40367,7 +40552,7 @@ function useFeatureHelp(def) {
|
|
|
40367
40552
|
[id]
|
|
40368
40553
|
);
|
|
40369
40554
|
useAgentSurface(contribution);
|
|
40370
|
-
return
|
|
40555
|
+
return React132.useMemo(
|
|
40371
40556
|
() => ({
|
|
40372
40557
|
help: () => helpWith(ref.current),
|
|
40373
40558
|
teach: () => teachMe(ref.current),
|
|
@@ -40531,23 +40716,23 @@ function getRailPage(id) {
|
|
|
40531
40716
|
}
|
|
40532
40717
|
function ConnectorsHub({ hostPluginId }) {
|
|
40533
40718
|
const { t } = useTranslation$1();
|
|
40534
|
-
const { connectors, reload } = useConnectors({ includeGrants: false });
|
|
40719
|
+
const { connectors, reload: reload2 } = useConnectors({ includeGrants: false });
|
|
40535
40720
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
40536
|
-
const [selected, setSelected] =
|
|
40537
|
-
const [adding, setAdding] =
|
|
40538
|
-
const hosted =
|
|
40721
|
+
const [selected, setSelected] = React132__default.useState(null);
|
|
40722
|
+
const [adding, setAdding] = React132__default.useState(false);
|
|
40723
|
+
const hosted = React132__default.useMemo(
|
|
40539
40724
|
() => (connectors ?? []).filter((c) => c.hostPluginId === hostPluginId),
|
|
40540
40725
|
[connectors, hostPluginId]
|
|
40541
40726
|
);
|
|
40542
|
-
const categories =
|
|
40727
|
+
const categories = React132__default.useMemo(
|
|
40543
40728
|
() => [...new Set(hosted.map((c) => c.category).filter((c) => !!c))],
|
|
40544
40729
|
[hosted]
|
|
40545
40730
|
);
|
|
40546
|
-
const scoped =
|
|
40731
|
+
const scoped = React132__default.useMemo(() => {
|
|
40547
40732
|
const siblings = inCategories(connectors ?? [], categories).filter((c) => c.hostPluginId !== hostPluginId);
|
|
40548
40733
|
return [...hosted, ...siblings];
|
|
40549
40734
|
}, [connectors, hosted, categories, hostPluginId]);
|
|
40550
|
-
|
|
40735
|
+
React132__default.useEffect(() => {
|
|
40551
40736
|
if (!selected || !connectors) return;
|
|
40552
40737
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
40553
40738
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -40613,7 +40798,7 @@ function ConnectorsHub({ hostPluginId }) {
|
|
|
40613
40798
|
connector: selected,
|
|
40614
40799
|
open: !!selected,
|
|
40615
40800
|
onOpenChange: (open) => !open && setSelected(null),
|
|
40616
|
-
onChanged:
|
|
40801
|
+
onChanged: reload2
|
|
40617
40802
|
}
|
|
40618
40803
|
)
|
|
40619
40804
|
] });
|
|
@@ -40723,7 +40908,7 @@ function PluginSettingsPanel({ title, generalSettings, registries, customTabs, r
|
|
|
40723
40908
|
return tabs[0]?.id ?? "";
|
|
40724
40909
|
}
|
|
40725
40910
|
const [activeTab, setActiveTab] = useState(getActiveFromHash);
|
|
40726
|
-
|
|
40911
|
+
React132__default.useEffect(() => {
|
|
40727
40912
|
const handler = () => setActiveTab(getActiveFromHash());
|
|
40728
40913
|
window.addEventListener("hashchange", handler);
|
|
40729
40914
|
return () => window.removeEventListener("hashchange", handler);
|