@fayz-ai/admin 0.33.1 → 0.35.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/components/settings/ModuleCard.d.ts +8 -1
- package/dist/components/settings/ModuleCard.d.ts.map +1 -1
- package/dist/components/settings/ModulesPreview.d.ts +30 -0
- package/dist/components/settings/ModulesPreview.d.ts.map +1 -0
- package/dist/components/settings/ModulesSettings.d.ts.map +1 -1
- package/dist/components/settings/module-catalog.d.ts +19 -0
- package/dist/components/settings/module-catalog.d.ts.map +1 -1
- package/dist/components/shared/PersonLink.d.ts +3 -1
- package/dist/components/shared/PersonLink.d.ts.map +1 -1
- package/dist/crud/CrudDetailPage.d.ts +9 -1
- package/dist/crud/CrudDetailPage.d.ts.map +1 -1
- package/dist/crud/CrudPage.d.ts.map +1 -1
- package/dist/crud/archetypes/AddressesTab.d.ts.map +1 -1
- package/dist/crud/archetypes/KanbanBoard.d.ts.map +1 -1
- package/dist/index.js +1095 -786
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -20,19 +20,19 @@ 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
|
|
23
|
+
import * as React126 from 'react';
|
|
24
|
+
import React126__default, { createContext, useMemo, useState, useRef, useCallback, useEffect, useLayoutEffect, createElement, useContext } from 'react';
|
|
25
25
|
import { createDebug, resetActiveUnit, setUnitMode, setActiveUnitId, setScopedResources, tl, fetchAppConfig, getSupabaseClientOptional, payeeAccountFields, recordRailFields, RECORD_GROUP, activeFacet, createSafeDataProvider, isKnownMissing, rememberIfMissing, deriveEntityKey, registerEntity, getActiveTenantId, resolveDataProvider, bulkRemove, emitDomainEvent, entityEventKey, errorMessage, useTranslation, useDataChanged, emitDataChanged, exportCSV, getScopedResource, formatDateTime as formatDateTime$1, formatDate as formatDate$1, formatCurrency as formatCurrency$1, bulkCreate, matchesRange, isConnectorCategory, usePluginRuntimeOptional, useDataVersion, reportAppError, getWidgetsForZone, resolvePluginComponent, useUnitMode, invalidateAppConfig, toTenantPluginBindings, setCurrentLocale, resolveLocale, resolvePluginRuntime, PluginRuntimeProvider, I18nProvider, getAllEntities, resolveIntegrationSurface, defineApp, registerScaffold, useActiveTenantId, useConnectorsForPlugin, renderApp as renderApp$1, parseRangeFilter, isFilterObject, connectionKey, useManifest, registerEventSink, formatPostalCode, isValidPostalCode, lookupPostalCode, usePluginRuntime, installGlobalErrorHandlers, registerErrorReporter, applyNavComposition, mergeTranslations, coreTranslations, attachPersistentCache, getPersistentCache, createMockProvider, isAddressIncomplete, isBankIncomplete, listConnections, connectorPlanes, connectorPermissions, connectorEntities, preferredPlane, connectorDirection, countByTenant, payeeMethodOf, getCurrentLocale, searchEverything, getComponent, getPluginFactory, isBankEmpty, isAddressEmpty, connectorSettings, groupedPermissions, invocationPlane, missingRequiredSettings, isSettingSet, getEntityByKey, connectorSubscribesTo, eventKeyMatches } from '@fayz-ai/core';
|
|
26
26
|
export { ConnectorRuntimeTokenUnavailableError, createSafeDataProvider, formatDate, formatDateTime, getActiveLocale, getActiveTenantId, getConnectorRuntimeTokenSource, getCurrentLocale, getSupabaseClientOptional, preloadLocale, resolveBackendEnv, setConnectorRuntimeTokenSource, setCurrentLocale, tl, useActiveTenantId } from '@fayz-ai/core';
|
|
27
27
|
import { usePasswordSetupGate, SetPasswordPage, AuthGate, AuthProvider, createAuthRuntime } from '@fayz-ai/plugin-auth';
|
|
28
28
|
export { LoginPage } from '@fayz-ai/plugin-auth';
|
|
29
|
-
import { 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, PageActionBar, ICON_MAP, Sheet, SheetContent, SheetBody, useIsWide, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Checkbox, useTourStore, setTourNavigator, TourSpotlight, PracticeOverlay, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Wizard, SidebarOnboarding, OnboardingWidget, Skeleton, useLayoutStore, ModalPortal, ModalOverlay, ModalBody, useSaveBar, useBackHandler, SubpageHeader, Separator, Tabs, TabsList, TabsTrigger, TabsContent, CardContent, ToastProvider, NavTransitionProvider, ListView, Thumbnail, SearchSelect, CurrencyInput, SearchField, ChevronPager, Popover, PopoverTrigger, PopoverContent, useModuleLayout, PhoneLink, normalizePhone, SearchCombobox, HeaderTabs, usePageTrail, PageHeaderOutlet, AppShellSkeleton, usePracticeStore, Switch, ModalTask, 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';
|
|
29
|
+
import { 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, PageActionBar, ICON_MAP, Sheet, SheetContent, SheetBody, useIsWide, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Checkbox, useTourStore, setTourNavigator, TourSpotlight, PracticeOverlay, Input, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Wizard, SidebarOnboarding, OnboardingWidget, Skeleton, useLayoutStore, ModalPortal, ModalOverlay, ModalBody, useSaveBar, useBackHandler, SubpageHeader, Separator, Tabs, TabsList, TabsTrigger, TabsContent, CardContent, ToastProvider, NavTransitionProvider, ListView, Thumbnail, SearchSelect, CurrencyInput, SearchField, ChevronPager, Popover, PopoverTrigger, PopoverContent, useModuleLayout, PersonAvatar, PhoneLink, normalizePhone, SearchCombobox, HeaderTabs, usePageTrail, PageHeaderOutlet, AppShellSkeleton, usePracticeStore, Switch, ModalTask, 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';
|
|
30
30
|
export { createFayzTheme, fayzThemePresets } from '@fayz-ai/ui';
|
|
31
31
|
import { useAuthStore, useAuth, buildAppHandoffUrl } from '@fayz-ai/auth';
|
|
32
32
|
export { useAuth } from '@fayz-ai/auth';
|
|
33
33
|
import { create, useStore as useStore$1 } from 'zustand';
|
|
34
34
|
import * as LucideIcons from 'lucide-react';
|
|
35
|
-
import { Pencil, 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, Copy, 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, ImagePlus, Database, Radio, Zap, Save, UserPlus, Contact, UserMinus, Send, Sun, Moon, Monitor, Languages, Info, Link2, KeyRound, Bug, Heart, Briefcase, BarChart3, Tag, Truck, Globe2 } from 'lucide-react';
|
|
35
|
+
import { Pencil, 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, Copy, 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, ImagePlus, Database, Radio, Zap, Save, UserPlus, Contact, UserMinus, Send, Sun, Moon, Monitor, Languages, Info, Link2, KeyRound, Bug, Home, Heart, Briefcase, BarChart3, Tag, Truck, Globe2 } from 'lucide-react';
|
|
36
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';
|
|
@@ -77,7 +77,7 @@ function useWorkspaceSetupGate(enabled) {
|
|
|
77
77
|
const close = useWorkspaceSetupStore((s) => s.close);
|
|
78
78
|
const path = useAdminPath();
|
|
79
79
|
const onRoute = path === WORKSPACE_SETUP_ROUTE;
|
|
80
|
-
const exitDeliberate =
|
|
80
|
+
const exitDeliberate = React126.useCallback(() => {
|
|
81
81
|
close();
|
|
82
82
|
if (onRoute) navigateTo("/");
|
|
83
83
|
}, [close, onRoute]);
|
|
@@ -186,10 +186,10 @@ function brandInstructions(brand) {
|
|
|
186
186
|
var UPDATE_EVENT = "fayz:update-ready";
|
|
187
187
|
function UpdateReady() {
|
|
188
188
|
const { t } = useTranslation$1();
|
|
189
|
-
const [pronta, setPronta] =
|
|
190
|
-
const [dispensada, setDispensada] =
|
|
191
|
-
const [aplicando, setAplicando] =
|
|
192
|
-
|
|
189
|
+
const [pronta, setPronta] = React126__default.useState(false);
|
|
190
|
+
const [dispensada, setDispensada] = React126__default.useState(false);
|
|
191
|
+
const [aplicando, setAplicando] = React126__default.useState(false);
|
|
192
|
+
React126__default.useEffect(() => {
|
|
193
193
|
const aviso = () => setPronta(true);
|
|
194
194
|
window.addEventListener(UPDATE_EVENT, aviso);
|
|
195
195
|
return () => window.removeEventListener(UPDATE_EVENT, aviso);
|
|
@@ -1940,7 +1940,7 @@ function getServerVersion() {
|
|
|
1940
1940
|
return 0;
|
|
1941
1941
|
}
|
|
1942
1942
|
function useAssistantActivity() {
|
|
1943
|
-
|
|
1943
|
+
React126.useSyncExternalStore(subscribe, getVersion, getServerVersion);
|
|
1944
1944
|
return pickActivity(activities);
|
|
1945
1945
|
}
|
|
1946
1946
|
var STATE_RANK = {
|
|
@@ -1956,22 +1956,22 @@ function pickActivity(list) {
|
|
|
1956
1956
|
return pool.find((a) => a.kind === "recording") ?? pool[0];
|
|
1957
1957
|
}
|
|
1958
1958
|
function useAssistantLaunchers() {
|
|
1959
|
-
|
|
1959
|
+
React126.useSyncExternalStore(subscribe, getVersion, getServerVersion);
|
|
1960
1960
|
return launchers;
|
|
1961
1961
|
}
|
|
1962
1962
|
function useLaunchersForRole(role) {
|
|
1963
1963
|
const all = useAssistantLaunchers();
|
|
1964
|
-
return
|
|
1964
|
+
return React126.useMemo(() => all.filter((l) => !l.role || l.role === role), [all, role]);
|
|
1965
1965
|
}
|
|
1966
1966
|
function usePublishAssistantActivity(activity) {
|
|
1967
1967
|
const id = activity?.id;
|
|
1968
1968
|
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 =
|
|
1969
|
+
const ref = React126.useRef(activity);
|
|
1970
1970
|
ref.current = activity;
|
|
1971
|
-
|
|
1971
|
+
React126.useEffect(() => {
|
|
1972
1972
|
if (ref.current) publishAssistantActivity(ref.current);
|
|
1973
1973
|
}, [key]);
|
|
1974
|
-
|
|
1974
|
+
React126.useEffect(() => {
|
|
1975
1975
|
if (!id) return;
|
|
1976
1976
|
return () => withdrawAssistantActivity(id);
|
|
1977
1977
|
}, [id]);
|
|
@@ -1979,12 +1979,12 @@ function usePublishAssistantActivity(activity) {
|
|
|
1979
1979
|
function useRegisterAssistantLauncher(launcher) {
|
|
1980
1980
|
const id = launcher?.id;
|
|
1981
1981
|
const key = launcher ? `${launcher.id}|${launcher.label}|${launcher.disabled ? "1" : "0"}|${launcher.role ?? ""}` : null;
|
|
1982
|
-
const ref =
|
|
1982
|
+
const ref = React126.useRef(launcher);
|
|
1983
1983
|
ref.current = launcher;
|
|
1984
|
-
|
|
1984
|
+
React126.useEffect(() => {
|
|
1985
1985
|
if (ref.current) registerAssistantLauncher(ref.current);
|
|
1986
1986
|
}, [key]);
|
|
1987
|
-
|
|
1987
|
+
React126.useEffect(() => {
|
|
1988
1988
|
if (!id) return;
|
|
1989
1989
|
return () => unregisterAssistantLauncher(id);
|
|
1990
1990
|
}, [id]);
|
|
@@ -2082,42 +2082,42 @@ function useRightRailPanel(panel) {
|
|
|
2082
2082
|
const sublabel = panel?.sublabel;
|
|
2083
2083
|
const badgeCount = panel?.badge?.count;
|
|
2084
2084
|
const badgeTone = panel?.badge?.tone;
|
|
2085
|
-
const initial =
|
|
2086
|
-
|
|
2085
|
+
const initial = React126.useRef({ label: label3, icon });
|
|
2086
|
+
React126.useEffect(() => {
|
|
2087
2087
|
if (!id || !Component2) return;
|
|
2088
2088
|
register({ id, label: initial.current.label ?? id, order, Component: Component2, icon: initial.current.icon });
|
|
2089
2089
|
return () => unregister(id);
|
|
2090
2090
|
}, [id, order, Component2, register, unregister]);
|
|
2091
|
-
|
|
2091
|
+
React126.useEffect(() => {
|
|
2092
2092
|
if (!id) return;
|
|
2093
2093
|
updateMeta(id, { label: label3, icon, iconBare, trailing, sublabel });
|
|
2094
2094
|
}, [id, label3, icon, iconBare, trailing, sublabel, updateMeta]);
|
|
2095
|
-
|
|
2095
|
+
React126.useEffect(() => {
|
|
2096
2096
|
if (!id) return;
|
|
2097
2097
|
updateBadge(id, badgeCount !== void 0 ? { count: badgeCount, tone: badgeTone } : void 0);
|
|
2098
2098
|
}, [id, badgeCount, badgeTone, updateBadge]);
|
|
2099
2099
|
}
|
|
2100
|
-
var RightRailActionsSlotContext =
|
|
2100
|
+
var RightRailActionsSlotContext = React126.createContext(null);
|
|
2101
2101
|
var RightRailActionsSlotProvider = RightRailActionsSlotContext.Provider;
|
|
2102
2102
|
function RightRailActions({ children }) {
|
|
2103
|
-
const slot =
|
|
2103
|
+
const slot = React126.useContext(RightRailActionsSlotContext);
|
|
2104
2104
|
if (slot) return createPortal(children, slot);
|
|
2105
2105
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-end gap-0.5 px-2 pt-1.5", children });
|
|
2106
2106
|
}
|
|
2107
|
-
var RightRailLeadingSlotContext =
|
|
2107
|
+
var RightRailLeadingSlotContext = React126.createContext(null);
|
|
2108
2108
|
var RightRailLeadingSlotProvider = RightRailLeadingSlotContext.Provider;
|
|
2109
2109
|
function RightRailLeading({ children }) {
|
|
2110
|
-
const slot =
|
|
2110
|
+
const slot = React126.useContext(RightRailLeadingSlotContext);
|
|
2111
2111
|
if (slot) return createPortal(children, slot);
|
|
2112
2112
|
return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5 px-2 pt-1.5", children });
|
|
2113
2113
|
}
|
|
2114
2114
|
function useRightRailReselect(id, handler) {
|
|
2115
2115
|
const reselects = useRightRailStore((s) => s.reselects);
|
|
2116
2116
|
const reselectId = useRightRailStore((s) => s.reselectId);
|
|
2117
|
-
const ref =
|
|
2117
|
+
const ref = React126.useRef(handler);
|
|
2118
2118
|
ref.current = handler;
|
|
2119
|
-
const seen =
|
|
2120
|
-
|
|
2119
|
+
const seen = React126.useRef(reselects);
|
|
2120
|
+
React126.useEffect(() => {
|
|
2121
2121
|
if (reselects === seen.current) return;
|
|
2122
2122
|
seen.current = reselects;
|
|
2123
2123
|
if (reselectId === id) ref.current();
|
|
@@ -2134,9 +2134,9 @@ function useRightRailDrill(drill) {
|
|
|
2134
2134
|
const avatarName = drill?.avatar?.name;
|
|
2135
2135
|
const avatarSrc = drill?.avatar?.src;
|
|
2136
2136
|
const avatarFace = drill?.avatar?.Face;
|
|
2137
|
-
const backRef =
|
|
2137
|
+
const backRef = React126.useRef(drill?.back);
|
|
2138
2138
|
backRef.current = drill?.back;
|
|
2139
|
-
|
|
2139
|
+
React126.useEffect(() => {
|
|
2140
2140
|
if (!title) return;
|
|
2141
2141
|
setDrill({
|
|
2142
2142
|
title,
|
|
@@ -2264,7 +2264,7 @@ Voc\xEA cuida do sistema inteiro. As telas desta conta est\xE3o em \`pages\`, e
|
|
|
2264
2264
|
}
|
|
2265
2265
|
function useRegisterStaff(staff) {
|
|
2266
2266
|
const setAgent = useAgentStore((s) => s.setAgent);
|
|
2267
|
-
|
|
2267
|
+
React126__default.useEffect(() => {
|
|
2268
2268
|
if (staff && staff.length > 1) {
|
|
2269
2269
|
console.warn(
|
|
2270
2270
|
`[fayz] chat.staff lists ${staff.length} agents; an app has one. Using "${soleAgent(staff)?.name}" and ignoring the rest \u2014 see chat.agent.`
|
|
@@ -2297,7 +2297,7 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2297
2297
|
const { id, persona, headline, pitch, description, placeholder, auto } = def;
|
|
2298
2298
|
const suggestions = def.suggestions;
|
|
2299
2299
|
const suggestionKey = JSON.stringify(suggestions ?? []);
|
|
2300
|
-
|
|
2300
|
+
React126.useEffect(() => {
|
|
2301
2301
|
if (!hasAssistant) return;
|
|
2302
2302
|
setInvite({
|
|
2303
2303
|
id,
|
|
@@ -2311,11 +2311,11 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2311
2311
|
});
|
|
2312
2312
|
return () => setInvite(null, id);
|
|
2313
2313
|
}, [hasAssistant, id, persona, headline, pitch, description, placeholder, auto, suggestionKey, setInvite]);
|
|
2314
|
-
const anchorRef =
|
|
2315
|
-
const [box, setBox] =
|
|
2314
|
+
const anchorRef = React126.useRef(null);
|
|
2315
|
+
const [box, setBox] = React126.useState(null);
|
|
2316
2316
|
const docked = stage === "dock" && !railOpen && hasAssistant;
|
|
2317
2317
|
const showing = hasAssistant && (stage === "hero" || docked);
|
|
2318
|
-
|
|
2318
|
+
React126.useEffect(() => {
|
|
2319
2319
|
if (!showing) return;
|
|
2320
2320
|
const el = anchorRef.current;
|
|
2321
2321
|
if (!el) return;
|
|
@@ -2336,7 +2336,7 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2336
2336
|
}, [showing]);
|
|
2337
2337
|
const setDockBox = useAssistantInviteStore((s) => s.setDockBox);
|
|
2338
2338
|
const wide = useWideViewport();
|
|
2339
|
-
|
|
2339
|
+
React126.useEffect(() => {
|
|
2340
2340
|
if (!docked || !wide || !box) {
|
|
2341
2341
|
setDockBox(null);
|
|
2342
2342
|
return;
|
|
@@ -2350,7 +2350,7 @@ function AssistantInvite({ className, ...def }) {
|
|
|
2350
2350
|
function useAsk() {
|
|
2351
2351
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
2352
2352
|
const dismiss = useAssistantInviteStore((s) => s.dismiss);
|
|
2353
|
-
return
|
|
2353
|
+
return React126.useCallback(
|
|
2354
2354
|
(text2) => {
|
|
2355
2355
|
const trimmed = text2.trim();
|
|
2356
2356
|
if (!trimmed) return;
|
|
@@ -2368,9 +2368,9 @@ function InviteHero({
|
|
|
2368
2368
|
const { t } = useTranslation$1();
|
|
2369
2369
|
const user = useAuthStore((s) => s.user);
|
|
2370
2370
|
const ask = useAsk();
|
|
2371
|
-
const [draft, setDraft] =
|
|
2371
|
+
const [draft, setDraft] = React126.useState("");
|
|
2372
2372
|
const name = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
2373
|
-
|
|
2373
|
+
React126.useEffect(() => {
|
|
2374
2374
|
const onKey = (event) => {
|
|
2375
2375
|
if (event.key === "Escape") onDismiss();
|
|
2376
2376
|
};
|
|
@@ -2432,8 +2432,8 @@ function InviteHero({
|
|
|
2432
2432
|
);
|
|
2433
2433
|
}
|
|
2434
2434
|
function useMorphIn(skip = false) {
|
|
2435
|
-
const [entered, setEntered] =
|
|
2436
|
-
|
|
2435
|
+
const [entered, setEntered] = React126.useState(() => skip || prefersReducedMotion());
|
|
2436
|
+
React126.useEffect(() => {
|
|
2437
2437
|
if (entered) return;
|
|
2438
2438
|
let second = 0;
|
|
2439
2439
|
const first = requestAnimationFrame(() => {
|
|
@@ -2452,10 +2452,10 @@ function prefersReducedMotion() {
|
|
|
2452
2452
|
var lastDockExit = null;
|
|
2453
2453
|
var RESUME_WINDOW_MS = 700;
|
|
2454
2454
|
function useWideViewport() {
|
|
2455
|
-
const [wide, setWide] =
|
|
2455
|
+
const [wide, setWide] = React126.useState(
|
|
2456
2456
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
2457
2457
|
);
|
|
2458
|
-
|
|
2458
|
+
React126.useEffect(() => {
|
|
2459
2459
|
const query = window.matchMedia?.("(min-width: 768px)");
|
|
2460
2460
|
if (!query) return;
|
|
2461
2461
|
const sync = () => setWide(query.matches);
|
|
@@ -2486,21 +2486,21 @@ function InviteDock({ def, left, maxWidth }) {
|
|
|
2486
2486
|
const setOpen = useChatStore((s) => s.setOpen);
|
|
2487
2487
|
const railOpen = useRightRailStore((s) => s.open);
|
|
2488
2488
|
const railWidth = useRightRailStore((s) => s.width);
|
|
2489
|
-
const [draft, setDraft] =
|
|
2490
|
-
const resumed =
|
|
2489
|
+
const [draft, setDraft] = React126.useState("");
|
|
2490
|
+
const resumed = React126.useRef(
|
|
2491
2491
|
!!lastDockExit && lastDockExit.id === def.id && Date.now() - lastDockExit.at < RESUME_WINDOW_MS
|
|
2492
2492
|
).current;
|
|
2493
|
-
|
|
2493
|
+
React126.useEffect(() => () => {
|
|
2494
2494
|
lastDockExit = { id: def.id, at: Date.now() };
|
|
2495
2495
|
}, [def.id]);
|
|
2496
2496
|
const entered = useMorphIn(resumed);
|
|
2497
2497
|
const width = Math.min(maxWidth, DOCK_MAX_WIDTH);
|
|
2498
|
-
const mountGeo =
|
|
2498
|
+
const mountGeo = React126.useRef({ left, width }).current;
|
|
2499
2499
|
const morph = morphStyles({ left: mountGeo.left, width: mountGeo.width }, railOpen, railWidth);
|
|
2500
|
-
const [settled, setSettled] =
|
|
2500
|
+
const [settled, setSettled] = React126.useState(resumed);
|
|
2501
2501
|
const geoLeft = settled ? left : mountGeo.left;
|
|
2502
2502
|
const geoWidth = settled ? width : mountGeo.width;
|
|
2503
|
-
|
|
2503
|
+
React126.useEffect(() => {
|
|
2504
2504
|
if (!entered || settled) return;
|
|
2505
2505
|
const id = setTimeout(() => setSettled(true), MORPH_MS + 60);
|
|
2506
2506
|
return () => clearTimeout(id);
|
|
@@ -2646,7 +2646,7 @@ function MorphBackPill() {
|
|
|
2646
2646
|
const railWidth = useRightRailStore((s) => s.width);
|
|
2647
2647
|
const { t } = useTranslation$1();
|
|
2648
2648
|
const collapsed = useMorphIn();
|
|
2649
|
-
|
|
2649
|
+
React126.useEffect(() => {
|
|
2650
2650
|
if (prefersReducedMotion()) {
|
|
2651
2651
|
endLeave();
|
|
2652
2652
|
return;
|
|
@@ -4560,12 +4560,12 @@ function detectActivePluginId(runtime) {
|
|
|
4560
4560
|
function useAITools() {
|
|
4561
4561
|
const runtime = usePluginRuntimeOptional();
|
|
4562
4562
|
const access = useAccessOptional();
|
|
4563
|
-
const surfaceVersion =
|
|
4563
|
+
const surfaceVersion = React126.useSyncExternalStore(subscribeSurfaces, getSurfaceVersion, getSurfaceVersion);
|
|
4564
4564
|
const features = usePermissionsStore((s) => s.features);
|
|
4565
4565
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
4566
4566
|
const hasSystem = useSystemPermission();
|
|
4567
4567
|
const canManagePermissions = hasSystem("manage_permissions");
|
|
4568
|
-
return
|
|
4568
|
+
return React126.useMemo(() => {
|
|
4569
4569
|
const hasPermission = runtime?.context.hasPermission;
|
|
4570
4570
|
const can = access.can;
|
|
4571
4571
|
const verticalId = runtime?.context.tenant?.verticalId;
|
|
@@ -5581,8 +5581,8 @@ function loadCatalog() {
|
|
|
5581
5581
|
return catalogPromise;
|
|
5582
5582
|
}
|
|
5583
5583
|
function useConnectorCatalog() {
|
|
5584
|
-
const [catalog, setCatalog] =
|
|
5585
|
-
|
|
5584
|
+
const [catalog, setCatalog] = React126__default.useState(null);
|
|
5585
|
+
React126__default.useEffect(() => {
|
|
5586
5586
|
let cancelled = false;
|
|
5587
5587
|
void loadCatalog().then((list) => {
|
|
5588
5588
|
if (!cancelled) setCatalog(list);
|
|
@@ -5606,7 +5606,7 @@ function refreshConnectors() {
|
|
|
5606
5606
|
_revisionListeners.forEach((listener) => listener());
|
|
5607
5607
|
}
|
|
5608
5608
|
function useConnectorsRevision() {
|
|
5609
|
-
return
|
|
5609
|
+
return React126__default.useSyncExternalStore(
|
|
5610
5610
|
(listener) => {
|
|
5611
5611
|
_revisionListeners.add(listener);
|
|
5612
5612
|
return () => _revisionListeners.delete(listener);
|
|
@@ -5625,11 +5625,11 @@ function loadGrants(key, fetcher) {
|
|
|
5625
5625
|
}
|
|
5626
5626
|
function useInstalledModuleIds() {
|
|
5627
5627
|
const runtime = usePluginRuntimeOptional();
|
|
5628
|
-
return
|
|
5628
|
+
return React126__default.useMemo(() => (runtime?.plugins ?? []).map((p) => p.id), [runtime]);
|
|
5629
5629
|
}
|
|
5630
5630
|
function useInstalledDefinitions(hostPluginId) {
|
|
5631
5631
|
const runtime = usePluginRuntimeOptional();
|
|
5632
|
-
return
|
|
5632
|
+
return React126__default.useMemo(() => {
|
|
5633
5633
|
const byHost = runtime?.connectorsByHost;
|
|
5634
5634
|
if (!byHost) return [];
|
|
5635
5635
|
if (hostPluginId) return byHost.get(hostPluginId) ?? [];
|
|
@@ -5642,12 +5642,12 @@ function useConnectors(options = {}) {
|
|
|
5642
5642
|
const catalog = useConnectorCatalog();
|
|
5643
5643
|
const tenant = useTenantOptional();
|
|
5644
5644
|
const tenantId2 = tenant?.org?.id;
|
|
5645
|
-
const connection =
|
|
5646
|
-
const [installed, setInstalled] =
|
|
5647
|
-
const [grants, setGrants] =
|
|
5648
|
-
const [error, setError] =
|
|
5645
|
+
const connection = React126__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
5646
|
+
const [installed, setInstalled] = React126__default.useState(null);
|
|
5647
|
+
const [grants, setGrants] = React126__default.useState(null);
|
|
5648
|
+
const [error, setError] = React126__default.useState(null);
|
|
5649
5649
|
const nonce = useConnectorsRevision();
|
|
5650
|
-
const call2 =
|
|
5650
|
+
const call2 = React126__default.useCallback(
|
|
5651
5651
|
async (path, init) => {
|
|
5652
5652
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
5653
5653
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -5667,7 +5667,7 @@ function useConnectors(options = {}) {
|
|
|
5667
5667
|
},
|
|
5668
5668
|
[connection]
|
|
5669
5669
|
);
|
|
5670
|
-
|
|
5670
|
+
React126__default.useEffect(() => {
|
|
5671
5671
|
let cancelled = false;
|
|
5672
5672
|
void loadConnectorStatuses(definitions, tenantId2).then((list) => {
|
|
5673
5673
|
if (!cancelled) setInstalled(list);
|
|
@@ -5676,7 +5676,7 @@ function useConnectors(options = {}) {
|
|
|
5676
5676
|
cancelled = true;
|
|
5677
5677
|
};
|
|
5678
5678
|
}, [definitions, tenantId2, nonce]);
|
|
5679
|
-
|
|
5679
|
+
React126__default.useEffect(() => {
|
|
5680
5680
|
if (!includeGrants || !connection || !tenantId2) {
|
|
5681
5681
|
setGrants(includeGrants ? null : []);
|
|
5682
5682
|
return;
|
|
@@ -5700,7 +5700,7 @@ function useConnectors(options = {}) {
|
|
|
5700
5700
|
cancelled = true;
|
|
5701
5701
|
};
|
|
5702
5702
|
}, [call2, tenantId2, includeGrants, connection, nonce]);
|
|
5703
|
-
const revokeGrant =
|
|
5703
|
+
const revokeGrant = React126__default.useCallback(
|
|
5704
5704
|
async (connector) => {
|
|
5705
5705
|
const response = await call2(`/${connector.id}`, { method: "DELETE" });
|
|
5706
5706
|
if (!response.ok) {
|
|
@@ -5713,7 +5713,7 @@ function useConnectors(options = {}) {
|
|
|
5713
5713
|
[call2]
|
|
5714
5714
|
);
|
|
5715
5715
|
const waitingGrants = includeGrants && !!connection && !!tenantId2 && grants === null;
|
|
5716
|
-
const connectors =
|
|
5716
|
+
const connectors = React126__default.useMemo(() => {
|
|
5717
5717
|
if (installed === null || waitingGrants) return null;
|
|
5718
5718
|
return buildConnectorList({
|
|
5719
5719
|
installed,
|
|
@@ -5954,9 +5954,9 @@ function ConnectorMark({
|
|
|
5954
5954
|
connector,
|
|
5955
5955
|
size = "md"
|
|
5956
5956
|
}) {
|
|
5957
|
-
const candidates =
|
|
5958
|
-
const [attempt, setAttempt] =
|
|
5959
|
-
|
|
5957
|
+
const candidates = React126__default.useMemo(() => markCandidates(connector), [connector.logoUrl, connector.name]);
|
|
5958
|
+
const [attempt, setAttempt] = React126__default.useState(0);
|
|
5959
|
+
React126__default.useEffect(() => setAttempt(0), [connector.id]);
|
|
5960
5960
|
const box = size === "sm" ? "h-9 w-9" : "h-10 w-10";
|
|
5961
5961
|
const glyph = size === "sm" ? "h-4 w-4" : "h-5 w-5";
|
|
5962
5962
|
if (connector.builtIn) {
|
|
@@ -7592,9 +7592,9 @@ function prefersReducedMotion2() {
|
|
|
7592
7592
|
return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
7593
7593
|
}
|
|
7594
7594
|
function TypewriterText({ text: text2, speed = 26, onDone }) {
|
|
7595
|
-
const [displayed, setDisplayed] =
|
|
7596
|
-
const indexRef =
|
|
7597
|
-
|
|
7595
|
+
const [displayed, setDisplayed] = React126.useState("");
|
|
7596
|
+
const indexRef = React126.useRef(0);
|
|
7597
|
+
React126.useEffect(() => {
|
|
7598
7598
|
if (prefersReducedMotion2()) {
|
|
7599
7599
|
setDisplayed(text2);
|
|
7600
7600
|
onDone?.();
|
|
@@ -7671,15 +7671,15 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7671
7671
|
const { contextualSuggestions } = useAITools();
|
|
7672
7672
|
const { sendMessage } = useChat({ apiEndpoint, systemPrompt, agent });
|
|
7673
7673
|
const { t } = useTranslation$1();
|
|
7674
|
-
const [phase, setPhase] =
|
|
7675
|
-
const [activeSuggestion, setActiveSuggestion] =
|
|
7676
|
-
const timersRef =
|
|
7677
|
-
const prevSuggestionRef =
|
|
7678
|
-
const [greeting, setGreeting] =
|
|
7679
|
-
const greetTimerRef =
|
|
7680
|
-
|
|
7674
|
+
const [phase, setPhase] = React126.useState("idle");
|
|
7675
|
+
const [activeSuggestion, setActiveSuggestion] = React126.useState(null);
|
|
7676
|
+
const timersRef = React126.useRef([]);
|
|
7677
|
+
const prevSuggestionRef = React126.useRef(null);
|
|
7678
|
+
const [greeting, setGreeting] = React126.useState(false);
|
|
7679
|
+
const greetTimerRef = React126.useRef(0);
|
|
7680
|
+
React126.useEffect(() => () => window.clearTimeout(greetTimerRef.current), []);
|
|
7681
7681
|
const hasFace = !!host?.AvatarComponent;
|
|
7682
|
-
|
|
7682
|
+
React126.useEffect(ensureStyles, []);
|
|
7683
7683
|
const clearTimers = () => {
|
|
7684
7684
|
timersRef.current.forEach(clearTimeout);
|
|
7685
7685
|
timersRef.current = [];
|
|
@@ -7692,10 +7692,10 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7692
7692
|
const invited = useAssistantInviteStore((s) => !!s.invite && s.stage === "dock");
|
|
7693
7693
|
const dockOnScreen = useAssistantInviteStore((s) => !!s.dockBox);
|
|
7694
7694
|
const morphingBack = useAssistantInviteStore((s) => !!s.leaving);
|
|
7695
|
-
const [wide, setWide] =
|
|
7695
|
+
const [wide, setWide] = React126.useState(
|
|
7696
7696
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
7697
7697
|
);
|
|
7698
|
-
|
|
7698
|
+
React126.useEffect(() => {
|
|
7699
7699
|
const query = window.matchMedia?.("(min-width: 768px)");
|
|
7700
7700
|
if (!query) return;
|
|
7701
7701
|
const sync = () => setWide(query.matches);
|
|
@@ -7704,7 +7704,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7704
7704
|
return () => query.removeEventListener("change", sync);
|
|
7705
7705
|
}, []);
|
|
7706
7706
|
const teaserAllowed = !hasMessages && !activity && !invited && !teaserDismissed() && teaserShownCount() < TEASER_MAX_PER_SESSION;
|
|
7707
|
-
|
|
7707
|
+
React126.useEffect(() => {
|
|
7708
7708
|
if (expanded || !topSuggestion || !topLabel || !teaserAllowed || teaserSeen().includes(topLabel)) {
|
|
7709
7709
|
if (phase !== "idle") {
|
|
7710
7710
|
clearTimers();
|
|
@@ -7735,14 +7735,14 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7735
7735
|
}, 9e3);
|
|
7736
7736
|
return clearTimers;
|
|
7737
7737
|
}, [topLabel, expanded, teaserAllowed]);
|
|
7738
|
-
|
|
7738
|
+
React126.useEffect(() => {
|
|
7739
7739
|
if (expanded && phase !== "idle") {
|
|
7740
7740
|
clearTimers();
|
|
7741
7741
|
setPhase("idle");
|
|
7742
7742
|
}
|
|
7743
7743
|
}, [expanded]);
|
|
7744
|
-
const [entrance, setEntrance] =
|
|
7745
|
-
|
|
7744
|
+
const [entrance, setEntrance] = React126.useState("pending");
|
|
7745
|
+
React126.useEffect(() => {
|
|
7746
7746
|
if (!currentOrg || entrance !== "pending") return;
|
|
7747
7747
|
if (prefersReducedMotion2()) {
|
|
7748
7748
|
setEntrance("done");
|
|
@@ -7752,9 +7752,9 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7752
7752
|
const timer = setTimeout(() => setEntrance("done"), 1600);
|
|
7753
7753
|
return () => clearTimeout(timer);
|
|
7754
7754
|
}, [currentOrg, entrance]);
|
|
7755
|
-
const [poppingBack, setPoppingBack] =
|
|
7756
|
-
const wasMorphing =
|
|
7757
|
-
|
|
7755
|
+
const [poppingBack, setPoppingBack] = React126.useState(false);
|
|
7756
|
+
const wasMorphing = React126.useRef(false);
|
|
7757
|
+
React126.useEffect(() => {
|
|
7758
7758
|
const was = wasMorphing.current;
|
|
7759
7759
|
wasMorphing.current = morphingBack;
|
|
7760
7760
|
if (!was || morphingBack || prefersReducedMotion2()) return;
|
|
@@ -8052,7 +8052,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
8052
8052
|
var MAX_SUGGESTIONS = 5;
|
|
8053
8053
|
function ChatSuggestions({ suggestions, onSelect, onDismiss, compact }) {
|
|
8054
8054
|
const { t } = useTranslation$1();
|
|
8055
|
-
const [open, setOpen] =
|
|
8055
|
+
const [open, setOpen] = React126.useState(true);
|
|
8056
8056
|
const visible = suggestions.slice(0, compact ? 3 : MAX_SUGGESTIONS);
|
|
8057
8057
|
if (!visible.length) return null;
|
|
8058
8058
|
return /* @__PURE__ */ jsxs(
|
|
@@ -8131,8 +8131,8 @@ function SuggestionRow({
|
|
|
8131
8131
|
detail,
|
|
8132
8132
|
onSelect
|
|
8133
8133
|
}) {
|
|
8134
|
-
const labelRef =
|
|
8135
|
-
const [showDetail, setShowDetail] =
|
|
8134
|
+
const labelRef = React126.useRef(null);
|
|
8135
|
+
const [showDetail, setShowDetail] = React126.useState(false);
|
|
8136
8136
|
const evaluate = () => {
|
|
8137
8137
|
const el = labelRef.current;
|
|
8138
8138
|
const clipped = !!el && el.scrollWidth > el.clientWidth + 1;
|
|
@@ -8226,8 +8226,8 @@ function ChatToolsPanel({ toolGroups, onClose }) {
|
|
|
8226
8226
|
}
|
|
8227
8227
|
function AutoApprovalsSection() {
|
|
8228
8228
|
const { t } = useTranslation$1();
|
|
8229
|
-
const [rules, setRules] =
|
|
8230
|
-
|
|
8229
|
+
const [rules, setRules] = React126.useState(() => listAutoApprovals());
|
|
8230
|
+
React126.useEffect(() => subscribeAutoApprovals(() => setRules(listAutoApprovals())), []);
|
|
8231
8231
|
if (!rules.length) return null;
|
|
8232
8232
|
return /* @__PURE__ */ jsxs("div", { className: "border-b border-border/40 px-3 py-2.5", children: [
|
|
8233
8233
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 px-1 pb-1.5", children: [
|
|
@@ -8280,14 +8280,14 @@ function bucketOf(iso) {
|
|
|
8280
8280
|
var ORDER = ["today", "yesterday", "week", "older"];
|
|
8281
8281
|
function ChatHistory({ conversations, activeId, onSelect }) {
|
|
8282
8282
|
const { t } = useTranslation$1();
|
|
8283
|
-
const [query, setQuery] =
|
|
8283
|
+
const [query, setQuery] = React126.useState("");
|
|
8284
8284
|
const mine = conversations;
|
|
8285
|
-
const filtered =
|
|
8285
|
+
const filtered = React126.useMemo(() => {
|
|
8286
8286
|
const needle = query.trim().toLowerCase();
|
|
8287
8287
|
if (!needle) return mine;
|
|
8288
8288
|
return mine.filter((c) => (c.title ?? "").toLowerCase().includes(needle));
|
|
8289
8289
|
}, [mine, query]);
|
|
8290
|
-
const groups =
|
|
8290
|
+
const groups = React126.useMemo(() => {
|
|
8291
8291
|
const map = /* @__PURE__ */ new Map();
|
|
8292
8292
|
for (const conversation of filtered) {
|
|
8293
8293
|
const bucket = bucketOf(conversation.updatedAt);
|
|
@@ -8414,7 +8414,7 @@ function TourCoachCard() {
|
|
|
8414
8414
|
const lastOutcome = useTourStore((s) => s.lastOutcome);
|
|
8415
8415
|
const stop = useTourStore((s) => s.stop);
|
|
8416
8416
|
const restart = useTourStore((s) => s.restart);
|
|
8417
|
-
const [dismissedId, setDismissedId] =
|
|
8417
|
+
const [dismissedId, setDismissedId] = React126.useState(null);
|
|
8418
8418
|
const pTitle = usePracticeStore((s) => s.title);
|
|
8419
8419
|
const pSteps = usePracticeStore((s) => s.steps);
|
|
8420
8420
|
const pDone = usePracticeStore((s) => s.done);
|
|
@@ -8485,8 +8485,8 @@ function AssistantRecordingView({ activity }) {
|
|
|
8485
8485
|
const live = activity.state === "running" || activity.state === "paused";
|
|
8486
8486
|
const running = activity.state === "running";
|
|
8487
8487
|
const actions = activity.actions ?? [];
|
|
8488
|
-
const [acknowledged, setAcknowledged] =
|
|
8489
|
-
|
|
8488
|
+
const [acknowledged, setAcknowledged] = React126.useState(false);
|
|
8489
|
+
React126.useEffect(() => setAcknowledged(false), [activity.id, activity.state]);
|
|
8490
8490
|
const withheld = pending2 && !!activity.confirm && !acknowledged;
|
|
8491
8491
|
const primary = actions.filter((a) => a.intent !== "discard");
|
|
8492
8492
|
const discard = actions.find((a) => a.intent === "discard");
|
|
@@ -8702,10 +8702,10 @@ function RightRailPage({
|
|
|
8702
8702
|
const closePage = useRightRailStore((s) => s.closePage);
|
|
8703
8703
|
const active2 = hosted && open;
|
|
8704
8704
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
8705
|
-
const onCloseRef =
|
|
8705
|
+
const onCloseRef = React126.useRef(onClose);
|
|
8706
8706
|
onCloseRef.current = onClose;
|
|
8707
|
-
const claimed =
|
|
8708
|
-
|
|
8707
|
+
const claimed = React126.useRef(false);
|
|
8708
|
+
React126.useEffect(() => {
|
|
8709
8709
|
if (!active2) return;
|
|
8710
8710
|
showPage();
|
|
8711
8711
|
claimed.current = true;
|
|
@@ -8714,7 +8714,7 @@ function RightRailPage({
|
|
|
8714
8714
|
closePage();
|
|
8715
8715
|
};
|
|
8716
8716
|
}, [active2, showPage, closePage]);
|
|
8717
|
-
|
|
8717
|
+
React126.useEffect(() => {
|
|
8718
8718
|
if (!claimed.current) return;
|
|
8719
8719
|
if (!useRightRailStore.getState().pageOpen) onCloseRef.current();
|
|
8720
8720
|
}, [pageOpen]);
|
|
@@ -8917,15 +8917,15 @@ function ConnectorSyncActions({
|
|
|
8917
8917
|
actions,
|
|
8918
8918
|
onRan
|
|
8919
8919
|
}) {
|
|
8920
|
-
const [running, setRunning] =
|
|
8921
|
-
const [open, setOpen] =
|
|
8922
|
-
const [pending2, setPending] =
|
|
8923
|
-
const [hidden, setHidden] =
|
|
8924
|
-
const [queued, setQueued] =
|
|
8925
|
-
const [nonce, setNonce] =
|
|
8926
|
-
const [expanded, setExpanded] =
|
|
8927
|
-
const [resolved, setResolved] =
|
|
8928
|
-
|
|
8920
|
+
const [running, setRunning] = React126__default.useState(null);
|
|
8921
|
+
const [open, setOpen] = React126__default.useState(null);
|
|
8922
|
+
const [pending2, setPending] = React126__default.useState(null);
|
|
8923
|
+
const [hidden, setHidden] = React126__default.useState(() => /* @__PURE__ */ new Set());
|
|
8924
|
+
const [queued, setQueued] = React126__default.useState({});
|
|
8925
|
+
const [nonce, setNonce] = React126__default.useState(0);
|
|
8926
|
+
const [expanded, setExpanded] = React126__default.useState(false);
|
|
8927
|
+
const [resolved, setResolved] = React126__default.useState(false);
|
|
8928
|
+
React126__default.useEffect(() => {
|
|
8929
8929
|
let cancelled = false;
|
|
8930
8930
|
setResolved(false);
|
|
8931
8931
|
void Promise.all(
|
|
@@ -9110,10 +9110,10 @@ function formatRelative(iso, t) {
|
|
|
9110
9110
|
}
|
|
9111
9111
|
function useConnectorRuns(connector) {
|
|
9112
9112
|
const listRuns = connector.definition?.listRuns;
|
|
9113
|
-
const [runs, setRuns] =
|
|
9114
|
-
const [loading, setLoading] =
|
|
9115
|
-
const [nonce, setNonce] =
|
|
9116
|
-
|
|
9113
|
+
const [runs, setRuns] = React126__default.useState([]);
|
|
9114
|
+
const [loading, setLoading] = React126__default.useState(!!listRuns);
|
|
9115
|
+
const [nonce, setNonce] = React126__default.useState(0);
|
|
9116
|
+
React126__default.useEffect(() => {
|
|
9117
9117
|
if (!listRuns) {
|
|
9118
9118
|
setRuns([]);
|
|
9119
9119
|
setLoading(false);
|
|
@@ -9135,7 +9135,7 @@ function useConnectorRuns(connector) {
|
|
|
9135
9135
|
return {
|
|
9136
9136
|
runs,
|
|
9137
9137
|
loading,
|
|
9138
|
-
reload:
|
|
9138
|
+
reload: React126__default.useCallback(() => setNonce((n) => n + 1), []),
|
|
9139
9139
|
failing: isFailing(runs)
|
|
9140
9140
|
};
|
|
9141
9141
|
}
|
|
@@ -9235,7 +9235,7 @@ function RunFailure({ run }) {
|
|
|
9235
9235
|
),
|
|
9236
9236
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t("connectors.runs.seeDetails") })
|
|
9237
9237
|
] }),
|
|
9238
|
-
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(
|
|
9238
|
+
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(React126__default.Fragment, { children: [
|
|
9239
9239
|
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: label3 }),
|
|
9240
9240
|
/* @__PURE__ */ jsx("dd", { className: "min-w-0 break-words font-mono text-foreground/80", children: value })
|
|
9241
9241
|
] }, label3)) }),
|
|
@@ -9404,13 +9404,13 @@ function ConnectorSettingsPanel({
|
|
|
9404
9404
|
const { t } = useTranslation$1();
|
|
9405
9405
|
const def = connector.definition;
|
|
9406
9406
|
const settings = def ? connectorSettings(def) : [];
|
|
9407
|
-
const [values, setValues] =
|
|
9407
|
+
const [values, setValues] = React126__default.useState(
|
|
9408
9408
|
() => initialValues(settings, {})
|
|
9409
9409
|
);
|
|
9410
|
-
const [loaded2, setLoaded] =
|
|
9411
|
-
const [saving, setSaving] =
|
|
9412
|
-
const [dirty, setDirty] =
|
|
9413
|
-
|
|
9410
|
+
const [loaded2, setLoaded] = React126__default.useState(false);
|
|
9411
|
+
const [saving, setSaving] = React126__default.useState(false);
|
|
9412
|
+
const [dirty, setDirty] = React126__default.useState(false);
|
|
9413
|
+
React126__default.useEffect(() => {
|
|
9414
9414
|
if (settings.length === 0 || !def?.getSettings) return;
|
|
9415
9415
|
let cancelled = false;
|
|
9416
9416
|
setLoaded(false);
|
|
@@ -9661,13 +9661,13 @@ function ConnectorInstall({
|
|
|
9661
9661
|
}) {
|
|
9662
9662
|
const { t } = useTranslation$1();
|
|
9663
9663
|
const def = connector.definition;
|
|
9664
|
-
const [plane, setPlane] =
|
|
9664
|
+
const [plane, setPlane] = React126__default.useState(
|
|
9665
9665
|
connector.planes.includes("agentic") ? "agentic" : connector.planes[0]
|
|
9666
9666
|
);
|
|
9667
|
-
const [values, setValues] =
|
|
9668
|
-
const secrets =
|
|
9669
|
-
const [busy, setBusy] =
|
|
9670
|
-
|
|
9667
|
+
const [values, setValues] = React126__default.useState({});
|
|
9668
|
+
const secrets = React126__default.useRef({});
|
|
9669
|
+
const [busy, setBusy] = React126__default.useState(null);
|
|
9670
|
+
React126__default.useEffect(() => {
|
|
9671
9671
|
setValues({});
|
|
9672
9672
|
secrets.current = {};
|
|
9673
9673
|
setBusy(null);
|
|
@@ -9708,15 +9708,15 @@ function ConnectorHome({
|
|
|
9708
9708
|
const needsSetup = connector.state === "needs_setup";
|
|
9709
9709
|
const settingsAvailable = hasOperatingSettings(connector);
|
|
9710
9710
|
const runsAvailable = hasRunHistory(connector);
|
|
9711
|
-
const [tab, setTab] =
|
|
9711
|
+
const [tab, setTab] = React126__default.useState(
|
|
9712
9712
|
needsSetup && settingsAvailable ? "settings" : "overview"
|
|
9713
9713
|
);
|
|
9714
|
-
const [busy, setBusy] =
|
|
9714
|
+
const [busy, setBusy] = React126__default.useState(null);
|
|
9715
9715
|
const run = useRunner(setBusy, onChanged);
|
|
9716
|
-
const [values, setValues] =
|
|
9717
|
-
const secrets =
|
|
9716
|
+
const [values, setValues] = React126__default.useState({});
|
|
9717
|
+
const secrets = React126__default.useRef({});
|
|
9718
9718
|
const runs = useConnectorRuns(connector);
|
|
9719
|
-
|
|
9719
|
+
React126__default.useEffect(() => {
|
|
9720
9720
|
setTab(needsSetup && settingsAvailable ? "settings" : "overview");
|
|
9721
9721
|
setBusy(null);
|
|
9722
9722
|
setValues({});
|
|
@@ -9806,7 +9806,7 @@ function ConnectorHome({
|
|
|
9806
9806
|
}
|
|
9807
9807
|
function useRunner(setBusy, onChanged) {
|
|
9808
9808
|
const { t } = useTranslation$1();
|
|
9809
|
-
return
|
|
9809
|
+
return React126__default.useCallback(
|
|
9810
9810
|
async (kind, fn, okMessage) => {
|
|
9811
9811
|
setBusy(kind);
|
|
9812
9812
|
try {
|
|
@@ -9922,7 +9922,7 @@ function ConnectPanel({
|
|
|
9922
9922
|
const sinkMissing = needsSink && !getConnectorCredentialSink();
|
|
9923
9923
|
const secretFieldCount = (def.fields ?? []).filter(isSecretField).length;
|
|
9924
9924
|
const hasStoredCredential = connector.state === "connected" || connector.state === "needs_setup";
|
|
9925
|
-
const [formKey, setFormKey] =
|
|
9925
|
+
const [formKey, setFormKey] = React126__default.useState(0);
|
|
9926
9926
|
if (def.authKind === "oauth") {
|
|
9927
9927
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
9928
9928
|
/* @__PURE__ */ jsx(Note, { children: t("connectors.authorize.oauthOnly") }),
|
|
@@ -10055,7 +10055,7 @@ function GrantRevoke({
|
|
|
10055
10055
|
onRevoke
|
|
10056
10056
|
}) {
|
|
10057
10057
|
const { t } = useTranslation$1();
|
|
10058
|
-
const [revoking, setRevoking] =
|
|
10058
|
+
const [revoking, setRevoking] = React126__default.useState(false);
|
|
10059
10059
|
if (connector.revocable === false) {
|
|
10060
10060
|
return /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("connectors.partOfApp") });
|
|
10061
10061
|
}
|
|
@@ -10094,14 +10094,14 @@ function ConnectorsPanel({ onClose }) {
|
|
|
10094
10094
|
const { connectors, reload, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
10095
10095
|
const selectedId = useConnectorsSurface((s) => s.selected);
|
|
10096
10096
|
const select = useConnectorsSurface((s) => s.select);
|
|
10097
|
-
const [query, setQuery] =
|
|
10098
|
-
const [failure, setFailure] =
|
|
10099
|
-
const [revoking, setRevoking] =
|
|
10100
|
-
const selected =
|
|
10097
|
+
const [query, setQuery] = React126__default.useState("");
|
|
10098
|
+
const [failure, setFailure] = React126__default.useState(null);
|
|
10099
|
+
const [revoking, setRevoking] = React126__default.useState(null);
|
|
10100
|
+
const selected = React126__default.useMemo(
|
|
10101
10101
|
() => (connectors ?? []).find((c) => c.id === selectedId) ?? null,
|
|
10102
10102
|
[connectors, selectedId]
|
|
10103
10103
|
);
|
|
10104
|
-
const filtered =
|
|
10104
|
+
const filtered = React126__default.useMemo(
|
|
10105
10105
|
() => filterConnectors(connectors ?? [], "outbound", query),
|
|
10106
10106
|
[connectors, query]
|
|
10107
10107
|
);
|
|
@@ -10112,9 +10112,9 @@ function ConnectorsPanel({ onClose }) {
|
|
|
10112
10112
|
back: onClose
|
|
10113
10113
|
} : null
|
|
10114
10114
|
);
|
|
10115
|
-
const closeRef =
|
|
10115
|
+
const closeRef = React126__default.useRef(onClose);
|
|
10116
10116
|
closeRef.current = onClose;
|
|
10117
|
-
|
|
10117
|
+
React126__default.useEffect(() => {
|
|
10118
10118
|
if (hosted && !selectedId) closeRef.current();
|
|
10119
10119
|
}, [hosted, selectedId]);
|
|
10120
10120
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [
|
|
@@ -10242,20 +10242,20 @@ function useDictation({
|
|
|
10242
10242
|
onInterim
|
|
10243
10243
|
}) {
|
|
10244
10244
|
const resolvedLocale = locale ?? (typeof navigator !== "undefined" ? navigator.language || "pt-BR" : "pt-BR");
|
|
10245
|
-
const [state, setState] =
|
|
10246
|
-
const [error, setError] =
|
|
10247
|
-
const sessionRef =
|
|
10248
|
-
const callbacks =
|
|
10245
|
+
const [state, setState] = React126.useState("idle");
|
|
10246
|
+
const [error, setError] = React126.useState(null);
|
|
10247
|
+
const sessionRef = React126.useRef(null);
|
|
10248
|
+
const callbacks = React126.useRef({ onTranscript, onInterim });
|
|
10249
10249
|
callbacks.current = { onTranscript, onInterim };
|
|
10250
|
-
const supported =
|
|
10250
|
+
const supported = React126.useMemo(
|
|
10251
10251
|
() => isDictationSupported(!!transcribeEndpoint),
|
|
10252
10252
|
[transcribeEndpoint]
|
|
10253
10253
|
);
|
|
10254
|
-
const finish =
|
|
10254
|
+
const finish = React126.useCallback(() => {
|
|
10255
10255
|
sessionRef.current = null;
|
|
10256
10256
|
setState("idle");
|
|
10257
10257
|
}, []);
|
|
10258
|
-
const start =
|
|
10258
|
+
const start = React126.useCallback(() => {
|
|
10259
10259
|
if (sessionRef.current || !supported) return;
|
|
10260
10260
|
stopSpeaking();
|
|
10261
10261
|
setError(null);
|
|
@@ -10276,28 +10276,28 @@ function useDictation({
|
|
|
10276
10276
|
}
|
|
10277
10277
|
);
|
|
10278
10278
|
}, [finish, resolvedLocale, supported, transcribeEndpoint]);
|
|
10279
|
-
const stop =
|
|
10279
|
+
const stop = React126.useCallback(() => {
|
|
10280
10280
|
if (!sessionRef.current) return;
|
|
10281
10281
|
if (transcribeEndpoint) setState("transcribing");
|
|
10282
10282
|
sessionRef.current.stop();
|
|
10283
10283
|
}, [transcribeEndpoint]);
|
|
10284
|
-
const cancel =
|
|
10284
|
+
const cancel = React126.useCallback(() => {
|
|
10285
10285
|
sessionRef.current?.cancel();
|
|
10286
10286
|
sessionRef.current = null;
|
|
10287
10287
|
setState("idle");
|
|
10288
10288
|
setError(null);
|
|
10289
10289
|
}, []);
|
|
10290
|
-
const toggle =
|
|
10290
|
+
const toggle = React126.useCallback(() => {
|
|
10291
10291
|
if (state === "listening" || state === "transcribing") stop();
|
|
10292
10292
|
else start();
|
|
10293
10293
|
}, [state, start, stop]);
|
|
10294
|
-
|
|
10294
|
+
React126.useEffect(() => () => sessionRef.current?.cancel(), []);
|
|
10295
10295
|
return { supported, state, error, start, stop, cancel, toggle, clearError: () => setError(null) };
|
|
10296
10296
|
}
|
|
10297
10297
|
function useMicLevels(active2, bandCount = 28, externalStream) {
|
|
10298
|
-
const levelsRef =
|
|
10299
|
-
const [available, setAvailable] =
|
|
10300
|
-
|
|
10298
|
+
const levelsRef = React126.useRef(new Float32Array(bandCount));
|
|
10299
|
+
const [available, setAvailable] = React126.useState(false);
|
|
10300
|
+
React126.useEffect(() => {
|
|
10301
10301
|
if (!active2) {
|
|
10302
10302
|
levelsRef.current.fill(0);
|
|
10303
10303
|
setAvailable(false);
|
|
@@ -10366,8 +10366,8 @@ var KIND_ICON = {
|
|
|
10366
10366
|
binary: File$1
|
|
10367
10367
|
};
|
|
10368
10368
|
function useFileDrop(enabled, onFiles) {
|
|
10369
|
-
const [dragging, setDragging] =
|
|
10370
|
-
const depth =
|
|
10369
|
+
const [dragging, setDragging] = React126.useState(false);
|
|
10370
|
+
const depth = React126.useRef(0);
|
|
10371
10371
|
const carriesFiles = (event) => Array.from(event.dataTransfer?.types ?? []).includes("Files");
|
|
10372
10372
|
const reset = () => {
|
|
10373
10373
|
depth.current = 0;
|
|
@@ -10427,7 +10427,7 @@ function AttachmentChips({
|
|
|
10427
10427
|
onRemove
|
|
10428
10428
|
}) {
|
|
10429
10429
|
const { t } = useTranslation$1();
|
|
10430
|
-
const [openId, setOpenId] =
|
|
10430
|
+
const [openId, setOpenId] = React126.useState(null);
|
|
10431
10431
|
if (!attachments.length) return null;
|
|
10432
10432
|
const opened = attachments.find((a) => a.id === openId);
|
|
10433
10433
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -10568,8 +10568,8 @@ function ChatComposer({
|
|
|
10568
10568
|
autoFocus
|
|
10569
10569
|
}) {
|
|
10570
10570
|
const { t } = useTranslation$1();
|
|
10571
|
-
const [input, setInput] =
|
|
10572
|
-
const textareaRef =
|
|
10571
|
+
const [input, setInput] = React126.useState("");
|
|
10572
|
+
const textareaRef = React126.useRef(null);
|
|
10573
10573
|
const voiceStartRequested = useChatStore((s) => s.voiceStartRequested);
|
|
10574
10574
|
const consumeVoiceStart = useChatStore((s) => s.consumeVoiceStart);
|
|
10575
10575
|
const draft = useChatStore((s) => s.draft);
|
|
@@ -10582,13 +10582,13 @@ function ChatComposer({
|
|
|
10582
10582
|
const removeAttachment = useChatStore((s) => s.removeAttachment);
|
|
10583
10583
|
const composerMedia = useChatStore((s) => s.composerMedia);
|
|
10584
10584
|
const clearComposerMedia = useChatStore((s) => s.clearComposerMedia);
|
|
10585
|
-
const fileInputRef =
|
|
10585
|
+
const fileInputRef = React126.useRef(null);
|
|
10586
10586
|
const autoSend = voice?.autoSend === true;
|
|
10587
10587
|
const micEnabled = voice?.input !== false;
|
|
10588
10588
|
const canAttach = isConfigured && !blocked && !isStreaming;
|
|
10589
10589
|
const parsing = attachments.some((a) => a.status === "parsing");
|
|
10590
10590
|
const readyAttachments = attachments.filter((a) => a.status === "ready").length;
|
|
10591
|
-
const submit =
|
|
10591
|
+
const submit = React126.useCallback(
|
|
10592
10592
|
(text2) => {
|
|
10593
10593
|
const trimmed = text2.trim();
|
|
10594
10594
|
const media = useChatStore.getState().composerMedia;
|
|
@@ -10618,7 +10618,7 @@ function ChatComposer({
|
|
|
10618
10618
|
}
|
|
10619
10619
|
}
|
|
10620
10620
|
});
|
|
10621
|
-
|
|
10621
|
+
React126.useEffect(() => {
|
|
10622
10622
|
if (!autoFocus) return;
|
|
10623
10623
|
const id = requestAnimationFrame(() => textareaRef.current?.focus());
|
|
10624
10624
|
return () => cancelAnimationFrame(id);
|
|
@@ -10630,7 +10630,7 @@ function ChatComposer({
|
|
|
10630
10630
|
const WAVEFORM_BANDS = 56;
|
|
10631
10631
|
const activity = useAssistantActivity();
|
|
10632
10632
|
const sessionRecording = activity?.kind === "recording" && activity.state === "running";
|
|
10633
|
-
const sessionStream =
|
|
10633
|
+
const sessionStream = React126.useMemo(
|
|
10634
10634
|
() => sessionRecording ? activity?.stream?.() ?? null : null,
|
|
10635
10635
|
[sessionRecording, activity]
|
|
10636
10636
|
);
|
|
@@ -10642,12 +10642,12 @@ function ChatComposer({
|
|
|
10642
10642
|
);
|
|
10643
10643
|
const sessionPause = activity?.actions?.find((a) => a.intent === "pause" || a.intent === "resume");
|
|
10644
10644
|
const sessionOwnsMic = activity?.kind === "recording" && (activity.state === "running" || activity.state === "paused");
|
|
10645
|
-
|
|
10645
|
+
React126.useEffect(() => {
|
|
10646
10646
|
if (!voiceStartRequested) return;
|
|
10647
10647
|
consumeVoiceStart();
|
|
10648
10648
|
if (showMic) dictation.start();
|
|
10649
10649
|
}, [voiceStartRequested, showMic]);
|
|
10650
|
-
|
|
10650
|
+
React126.useEffect(() => {
|
|
10651
10651
|
if (!focusRequested) return;
|
|
10652
10652
|
let frames = 0;
|
|
10653
10653
|
let raf = 0;
|
|
@@ -10664,7 +10664,7 @@ function ChatComposer({
|
|
|
10664
10664
|
raf = requestAnimationFrame(tick);
|
|
10665
10665
|
return () => cancelAnimationFrame(raf);
|
|
10666
10666
|
}, [focusRequested, consumeComposerFocus]);
|
|
10667
|
-
|
|
10667
|
+
React126.useEffect(() => {
|
|
10668
10668
|
if (!draft) return;
|
|
10669
10669
|
setInput(draft);
|
|
10670
10670
|
setDraft("");
|
|
@@ -10674,7 +10674,7 @@ function ChatComposer({
|
|
|
10674
10674
|
el.setSelectionRange(draft.length, draft.length);
|
|
10675
10675
|
}
|
|
10676
10676
|
}, [draft, setDraft]);
|
|
10677
|
-
|
|
10677
|
+
React126.useLayoutEffect(() => {
|
|
10678
10678
|
const el = textareaRef.current;
|
|
10679
10679
|
if (!el) return;
|
|
10680
10680
|
const style = getComputedStyle(el);
|
|
@@ -10877,8 +10877,8 @@ function UploadRequestCard() {
|
|
|
10877
10877
|
const removeUploadFile = useChatStore((s) => s.removeUploadFile);
|
|
10878
10878
|
const submitUpload = useChatStore((s) => s.submitUpload);
|
|
10879
10879
|
const clearUploadRequest = useChatStore((s) => s.clearUploadRequest);
|
|
10880
|
-
const cameraRef =
|
|
10881
|
-
const browseRef =
|
|
10880
|
+
const cameraRef = React126.useRef(null);
|
|
10881
|
+
const browseRef = React126.useRef(null);
|
|
10882
10882
|
if (!request) return null;
|
|
10883
10883
|
const working = request.status === "working";
|
|
10884
10884
|
const accept = request.accept ?? "image/*";
|
|
@@ -11020,8 +11020,8 @@ function LiveWaveform({
|
|
|
11020
11020
|
compact,
|
|
11021
11021
|
tone = "primary"
|
|
11022
11022
|
}) {
|
|
11023
|
-
const barsRef =
|
|
11024
|
-
|
|
11023
|
+
const barsRef = React126.useRef([]);
|
|
11024
|
+
React126.useEffect(() => {
|
|
11025
11025
|
if (!live) return;
|
|
11026
11026
|
let frame = 0;
|
|
11027
11027
|
const draw = () => {
|
|
@@ -11170,7 +11170,7 @@ function ChatMarkdown({ content }) {
|
|
|
11170
11170
|
}
|
|
11171
11171
|
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}`);
|
|
11172
11172
|
const prev = items.pop();
|
|
11173
|
-
if (prev &&
|
|
11173
|
+
if (prev && React126.isValidElement(prev)) {
|
|
11174
11174
|
items.push(
|
|
11175
11175
|
/* @__PURE__ */ jsxs("li", { children: [
|
|
11176
11176
|
prev.props.children,
|
|
@@ -11267,7 +11267,7 @@ var CARD_CTA = {
|
|
|
11267
11267
|
function useConnectorJourney(card) {
|
|
11268
11268
|
const panelAvailable = useConnectorsPanelAvailable();
|
|
11269
11269
|
useChatStore((s) => s.setOpen);
|
|
11270
|
-
return
|
|
11270
|
+
return React126.useCallback(() => {
|
|
11271
11271
|
if (panelAvailable && card.id) {
|
|
11272
11272
|
openConnectorsPanel({ id: card.id });
|
|
11273
11273
|
return;
|
|
@@ -11357,7 +11357,7 @@ function ConnectorSuggestionRow({ card }) {
|
|
|
11357
11357
|
] });
|
|
11358
11358
|
}
|
|
11359
11359
|
function ConnectorSuggestionGroup({ cards }) {
|
|
11360
|
-
const shelves =
|
|
11360
|
+
const shelves = React126.useMemo(() => shelveByCategory(cards), [cards]);
|
|
11361
11361
|
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: [
|
|
11362
11362
|
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 }),
|
|
11363
11363
|
/* @__PURE__ */ jsx("div", { className: "divide-y divide-border/40", children: shelf.items.map((card) => /* @__PURE__ */ jsx(ConnectorSuggestionRow, { card }, card.slug ?? card.id ?? card.name)) })
|
|
@@ -11367,8 +11367,8 @@ function ChoiceCard({ card }) {
|
|
|
11367
11367
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
11368
11368
|
const isStreaming = useChatStore((s) => s.isStreaming);
|
|
11369
11369
|
const messages = useChatStore((s) => s.messages);
|
|
11370
|
-
const [optimistic, setOptimistic] =
|
|
11371
|
-
const answeredInThread =
|
|
11370
|
+
const [optimistic, setOptimistic] = React126.useState(null);
|
|
11371
|
+
const answeredInThread = React126.useMemo(
|
|
11372
11372
|
() => answeredOptionId(messages, card.options),
|
|
11373
11373
|
[messages, card.options]
|
|
11374
11374
|
);
|
|
@@ -11423,7 +11423,7 @@ function humanizeToolName(name) {
|
|
|
11423
11423
|
}
|
|
11424
11424
|
function ToolCallRow({ call: call2 }) {
|
|
11425
11425
|
const { t } = useTranslation$1();
|
|
11426
|
-
const [open, setOpen] =
|
|
11426
|
+
const [open, setOpen] = React126.useState(false);
|
|
11427
11427
|
const failed = call2.declined || /"error"\s*:/.test(call2.result ?? "");
|
|
11428
11428
|
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-xl border border-border/50 bg-muted/30", children: [
|
|
11429
11429
|
/* @__PURE__ */ jsxs(
|
|
@@ -11500,15 +11500,15 @@ function HandoffNotice({ notice }) {
|
|
|
11500
11500
|
}
|
|
11501
11501
|
function MessageBubble({ message, isPending }) {
|
|
11502
11502
|
const isUser = message.role === "user";
|
|
11503
|
-
const connectorCards =
|
|
11503
|
+
const connectorCards = React126.useMemo(
|
|
11504
11504
|
() => (message.cards ?? []).filter((card) => card.kind === "connector"),
|
|
11505
11505
|
[message.cards]
|
|
11506
11506
|
);
|
|
11507
|
-
const choiceCards =
|
|
11507
|
+
const choiceCards = React126.useMemo(
|
|
11508
11508
|
() => (message.cards ?? []).filter((card) => card.kind === "choice"),
|
|
11509
11509
|
[message.cards]
|
|
11510
11510
|
);
|
|
11511
|
-
const routedLinks =
|
|
11511
|
+
const routedLinks = React126.useMemo(
|
|
11512
11512
|
() => (message.links ?? []).filter(
|
|
11513
11513
|
(l) => !!l.path || !!resolveEntityRoute(l.archetype, l.kind, l.entityKey)
|
|
11514
11514
|
),
|
|
@@ -11599,9 +11599,9 @@ function ConfirmActionCard({
|
|
|
11599
11599
|
onResolveAll
|
|
11600
11600
|
}) {
|
|
11601
11601
|
const { t } = useTranslation$1();
|
|
11602
|
-
const schema =
|
|
11602
|
+
const schema = React126.useMemo(() => action.fields ?? [], [action.fields]);
|
|
11603
11603
|
const partial = action.partial === true;
|
|
11604
|
-
const seedValues =
|
|
11604
|
+
const seedValues = React126.useCallback(
|
|
11605
11605
|
(params) => {
|
|
11606
11606
|
if (partial) return { ...params };
|
|
11607
11607
|
const seeded = {};
|
|
@@ -11610,18 +11610,18 @@ function ConfirmActionCard({
|
|
|
11610
11610
|
},
|
|
11611
11611
|
[schema, partial]
|
|
11612
11612
|
);
|
|
11613
|
-
const [values, setValues] =
|
|
11614
|
-
const [showAll, setShowAll] =
|
|
11613
|
+
const [values, setValues] = React126.useState(() => seedValues(action.params));
|
|
11614
|
+
const [showAll, setShowAll] = React126.useState(false);
|
|
11615
11615
|
const batch = Math.max(0, sameToolQueued);
|
|
11616
|
-
|
|
11616
|
+
React126.useEffect(() => setValues(seedValues(action.params)), [action.params, seedValues]);
|
|
11617
11617
|
const isSet = (v) => v !== void 0 && v !== null && v !== "";
|
|
11618
|
-
const primaryKeys =
|
|
11618
|
+
const primaryKeys = React126.useMemo(() => {
|
|
11619
11619
|
const keys = Object.keys(action.params).filter((k) => isSet(action.params[k]));
|
|
11620
11620
|
if (partial) return keys;
|
|
11621
11621
|
for (const f of schema) if (f.required && !keys.includes(f.key)) keys.push(f.key);
|
|
11622
11622
|
return keys;
|
|
11623
11623
|
}, [action.params, schema, partial]);
|
|
11624
|
-
const extraKeys =
|
|
11624
|
+
const extraKeys = React126.useMemo(
|
|
11625
11625
|
() => schema.map((f) => f.key).filter((k) => !primaryKeys.includes(k) && k !== "id"),
|
|
11626
11626
|
[schema, primaryKeys]
|
|
11627
11627
|
);
|
|
@@ -11648,20 +11648,20 @@ function ConfirmActionCard({
|
|
|
11648
11648
|
if (sharedLabel !== shared) return sharedLabel;
|
|
11649
11649
|
return humanizeKey(key);
|
|
11650
11650
|
};
|
|
11651
|
-
const missingRequiredKeys =
|
|
11651
|
+
const missingRequiredKeys = React126.useMemo(
|
|
11652
11652
|
() => partial ? [] : schema.filter((f) => f.required && !isSet(values[f.key])).map((f) => f.key),
|
|
11653
11653
|
[schema, values, partial]
|
|
11654
11654
|
);
|
|
11655
11655
|
const canConfirm = missingRequiredKeys.length === 0;
|
|
11656
|
-
const submitted =
|
|
11656
|
+
const submitted = React126.useCallback(
|
|
11657
11657
|
() => partial ? Object.fromEntries(Object.entries(values).filter(([, v]) => isSet(v))) : values,
|
|
11658
11658
|
[partial, values]
|
|
11659
11659
|
);
|
|
11660
|
-
const approve =
|
|
11660
|
+
const approve = React126.useCallback(() => {
|
|
11661
11661
|
if (canConfirm) onResolve(true, submitted());
|
|
11662
11662
|
}, [canConfirm, onResolve, submitted]);
|
|
11663
|
-
const decline =
|
|
11664
|
-
const approveAlways =
|
|
11663
|
+
const decline = React126.useCallback(() => onResolve(false), [onResolve]);
|
|
11664
|
+
const approveAlways = React126.useCallback(() => {
|
|
11665
11665
|
if (!canConfirm) return;
|
|
11666
11666
|
grantAutoApproval({
|
|
11667
11667
|
toolName: action.toolName,
|
|
@@ -11671,7 +11671,7 @@ function ConfirmActionCard({
|
|
|
11671
11671
|
});
|
|
11672
11672
|
onResolve(true, submitted());
|
|
11673
11673
|
}, [canConfirm, action.toolName, action.scope, ruleLabel, destructive, onResolve, submitted]);
|
|
11674
|
-
|
|
11674
|
+
React126.useEffect(() => {
|
|
11675
11675
|
const handler = (event) => {
|
|
11676
11676
|
const target = event.target;
|
|
11677
11677
|
const typing = target?.tagName === "INPUT" || target?.tagName === "TEXTAREA" || target?.tagName === "SELECT";
|
|
@@ -12008,8 +12008,8 @@ var TYPE_MS = 620;
|
|
|
12008
12008
|
var MIN_CHAR_MS = 12;
|
|
12009
12009
|
var MAX_CHAR_MS = 34;
|
|
12010
12010
|
function usePrefersReducedMotion() {
|
|
12011
|
-
const [reduced, setReduced] =
|
|
12012
|
-
|
|
12011
|
+
const [reduced, setReduced] = React126.useState(false);
|
|
12012
|
+
React126.useEffect(() => {
|
|
12013
12013
|
if (typeof matchMedia !== "function") return;
|
|
12014
12014
|
const query = matchMedia("(prefers-reduced-motion: reduce)");
|
|
12015
12015
|
const sync = () => setReduced(query.matches);
|
|
@@ -12028,10 +12028,10 @@ function TypedText({
|
|
|
12028
12028
|
onDone
|
|
12029
12029
|
}) {
|
|
12030
12030
|
const reduced = usePrefersReducedMotion();
|
|
12031
|
-
const [count, setCount] =
|
|
12032
|
-
const done =
|
|
12031
|
+
const [count, setCount] = React126.useState(reduced ? text2.length : 0);
|
|
12032
|
+
const done = React126.useRef(onDone);
|
|
12033
12033
|
done.current = onDone;
|
|
12034
|
-
|
|
12034
|
+
React126.useEffect(() => {
|
|
12035
12035
|
if (!start) {
|
|
12036
12036
|
setCount(0);
|
|
12037
12037
|
return;
|
|
@@ -12071,9 +12071,9 @@ function RevealSequence({
|
|
|
12071
12071
|
children
|
|
12072
12072
|
}) {
|
|
12073
12073
|
const reduced = usePrefersReducedMotion();
|
|
12074
|
-
const items =
|
|
12075
|
-
const [shown, setShown] =
|
|
12076
|
-
|
|
12074
|
+
const items = React126.Children.toArray(children);
|
|
12075
|
+
const [shown, setShown] = React126.useState(0);
|
|
12076
|
+
React126.useEffect(() => {
|
|
12077
12077
|
if (!start) {
|
|
12078
12078
|
setShown(0);
|
|
12079
12079
|
return;
|
|
@@ -12135,7 +12135,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
12135
12135
|
const currentPlan = plans.find((p) => p.id === currentPlanId);
|
|
12136
12136
|
const currentPrice = currentPlan?.price ?? 0;
|
|
12137
12137
|
const currentPlanName = currentPlan?.name ?? tr("billing.free", "Free");
|
|
12138
|
-
const featureName =
|
|
12138
|
+
const featureName = React126.useMemo(() => {
|
|
12139
12139
|
if (!feature) return null;
|
|
12140
12140
|
const label3 = features.find((f) => f.id === feature)?.label;
|
|
12141
12141
|
if (label3) return featureDisplayName(label3);
|
|
@@ -12143,7 +12143,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
12143
12143
|
const named = t(key);
|
|
12144
12144
|
return named && named !== key ? named : featureDisplayName(feature);
|
|
12145
12145
|
}, [features, feature, t]);
|
|
12146
|
-
const unlockingPlans =
|
|
12146
|
+
const unlockingPlans = React126.useMemo(
|
|
12147
12147
|
() => plans.filter((p) => p.id !== currentPlanId && p.price > currentPrice && planUnlocks(p, feature)).sort((a, b) => a.price - b.price),
|
|
12148
12148
|
[plans, currentPlanId, currentPrice, feature]
|
|
12149
12149
|
);
|
|
@@ -12325,26 +12325,26 @@ function ChatConversation({
|
|
|
12325
12325
|
usable && !pendingAction && !isStreaming,
|
|
12326
12326
|
receiveFiles
|
|
12327
12327
|
);
|
|
12328
|
-
|
|
12329
|
-
const [view, setView] =
|
|
12328
|
+
React126.useEffect(ensureIntroStyles, []);
|
|
12329
|
+
const [view, setView] = React126.useState(
|
|
12330
12330
|
() => useChatStore.getState().messages.length > 0 ? "thread" : "list"
|
|
12331
12331
|
);
|
|
12332
|
-
const [drawer, setDrawer] =
|
|
12333
|
-
const [introStep, setIntroStep] =
|
|
12334
|
-
const [atBottom, setAtBottom] =
|
|
12335
|
-
const scrollRef =
|
|
12332
|
+
const [drawer, setDrawer] = React126.useState("none");
|
|
12333
|
+
const [introStep, setIntroStep] = React126.useState(0);
|
|
12334
|
+
const [atBottom, setAtBottom] = React126.useState(true);
|
|
12335
|
+
const scrollRef = React126.useRef(null);
|
|
12336
12336
|
const hasMessages = messages.length > 0;
|
|
12337
12337
|
const showThread = view === "thread" && hasMessages;
|
|
12338
12338
|
const totalTools = toolGroups.reduce((sum, g) => sum + g.tools.length, 0);
|
|
12339
|
-
const scrollToBottom =
|
|
12339
|
+
const scrollToBottom = React126.useCallback((behavior = "smooth") => {
|
|
12340
12340
|
const el = scrollRef.current;
|
|
12341
12341
|
if (!el) return;
|
|
12342
12342
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
12343
12343
|
}, []);
|
|
12344
|
-
|
|
12344
|
+
React126.useEffect(() => {
|
|
12345
12345
|
if (atBottom) scrollToBottom();
|
|
12346
12346
|
}, [messages, activeTools, pendingAction, atBottom, scrollToBottom]);
|
|
12347
|
-
|
|
12347
|
+
React126.useEffect(() => {
|
|
12348
12348
|
loadConversations();
|
|
12349
12349
|
setSuggestionsOpen(useChatStore.getState().messages.length === 0);
|
|
12350
12350
|
return () => stopSpeaking();
|
|
@@ -12361,7 +12361,7 @@ function ChatConversation({
|
|
|
12361
12361
|
};
|
|
12362
12362
|
const queuedPrompt = useChatStore((s) => s.queuedPrompt);
|
|
12363
12363
|
const consumeQueuedPrompt = useChatStore((s) => s.consumeQueuedPrompt);
|
|
12364
|
-
|
|
12364
|
+
React126.useEffect(() => {
|
|
12365
12365
|
if (!queuedPrompt) return;
|
|
12366
12366
|
const prompt = consumeQueuedPrompt();
|
|
12367
12367
|
if (prompt && usable) send(prompt);
|
|
@@ -12397,7 +12397,7 @@ function ChatConversation({
|
|
|
12397
12397
|
);
|
|
12398
12398
|
const connectorsPending = useConnectorsSurface((s) => s.pending);
|
|
12399
12399
|
const consumeConnectorsRequest = useConnectorsSurface((s) => s.consume);
|
|
12400
|
-
|
|
12400
|
+
React126.useEffect(() => {
|
|
12401
12401
|
if (!connectorsPending) return;
|
|
12402
12402
|
setDrawer("connectors");
|
|
12403
12403
|
consumeConnectorsRequest();
|
|
@@ -12405,7 +12405,7 @@ function ChatConversation({
|
|
|
12405
12405
|
const greetingName = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
12406
12406
|
const invite = useAssistantInviteStore((s) => s.invite);
|
|
12407
12407
|
const introKey = `${onDuty?.role ?? "solo"}:${invite?.id ?? ""}`;
|
|
12408
|
-
|
|
12408
|
+
React126.useEffect(() => setIntroStep(0), [introKey]);
|
|
12409
12409
|
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");
|
|
12410
12410
|
const greetingHint = invite?.description ?? onDuty?.goal ?? t("chat.greetingHint");
|
|
12411
12411
|
const openers = invite?.suggestions?.length ? invite.suggestions : onDuty?.suggestions?.length ? onDuty.suggestions : suggestions.length ? suggestions : [
|
|
@@ -12727,7 +12727,7 @@ function AgentAvatar({
|
|
|
12727
12727
|
size = "md",
|
|
12728
12728
|
className
|
|
12729
12729
|
}) {
|
|
12730
|
-
const [failed, setFailed] =
|
|
12730
|
+
const [failed, setFailed] = React126.useState(false);
|
|
12731
12731
|
const { box, text: text2, px } = SIZES[size];
|
|
12732
12732
|
if (Face) {
|
|
12733
12733
|
return /* @__PURE__ */ jsx(
|
|
@@ -13515,7 +13515,7 @@ function TaskStatusGroup({ status, tasks }) {
|
|
|
13515
13515
|
function useDelegateToAssistant() {
|
|
13516
13516
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
13517
13517
|
const openPanel = useRightRailStore((s) => s.openPanel);
|
|
13518
|
-
return
|
|
13518
|
+
return React126.useCallback(
|
|
13519
13519
|
(prompt) => {
|
|
13520
13520
|
queuePrompt(prompt);
|
|
13521
13521
|
openPanel("chat");
|
|
@@ -13752,12 +13752,12 @@ function TasksPanel() {
|
|
|
13752
13752
|
const fetchTasks = useTasksStore((s) => s.fetchTasks);
|
|
13753
13753
|
const fetchLabels = useTasksStore((s) => s.fetchLabels);
|
|
13754
13754
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13755
|
-
|
|
13755
|
+
React126__default.useEffect(() => {
|
|
13756
13756
|
void fetchTasks();
|
|
13757
13757
|
void fetchLabels();
|
|
13758
13758
|
void fetchSummary();
|
|
13759
13759
|
}, [fetchTasks, fetchLabels, fetchSummary]);
|
|
13760
|
-
const { onboarding, grouped } =
|
|
13760
|
+
const { onboarding, grouped } = React126__default.useMemo(() => {
|
|
13761
13761
|
const split = splitOnboardingTasks(tasks);
|
|
13762
13762
|
const map = /* @__PURE__ */ new Map();
|
|
13763
13763
|
for (const s of STATUS_ORDER) map.set(s, []);
|
|
@@ -13792,7 +13792,7 @@ function TasksPanel() {
|
|
|
13792
13792
|
function useTasksSummaryLine() {
|
|
13793
13793
|
const t = useTranslation();
|
|
13794
13794
|
const summary = useTasksStore((s) => s.summary);
|
|
13795
|
-
return
|
|
13795
|
+
return React126__default.useMemo(() => {
|
|
13796
13796
|
if (!summary) return "";
|
|
13797
13797
|
const parts = [];
|
|
13798
13798
|
if (summary.overdue > 0) parts.push(`${summary.overdue} ${t("tasks.summary.overdue")}`);
|
|
@@ -13817,16 +13817,16 @@ function TasksRailPanel() {
|
|
|
13817
13817
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13818
13818
|
const setCurrentUserId = useTasksStore((s) => s.setCurrentUserId);
|
|
13819
13819
|
const userId = useAuthStore6((s) => s.user?.id);
|
|
13820
|
-
|
|
13820
|
+
React126__default.useEffect(() => {
|
|
13821
13821
|
void fetchSummary();
|
|
13822
13822
|
}, [fetchSummary]);
|
|
13823
|
-
|
|
13823
|
+
React126__default.useEffect(() => {
|
|
13824
13824
|
setCurrentUserId(userId ?? null);
|
|
13825
13825
|
}, [userId, setCurrentUserId]);
|
|
13826
13826
|
const openCount = summary ? summary.todo + summary.inProgress : 0;
|
|
13827
13827
|
const defer = tasksSurfaceOwner() === "plugin";
|
|
13828
13828
|
useRightRailPanel(
|
|
13829
|
-
|
|
13829
|
+
React126__default.useMemo(
|
|
13830
13830
|
() => defer ? null : {
|
|
13831
13831
|
id: "tasks",
|
|
13832
13832
|
label: t("tasks.drawer.title") || "Tasks",
|
|
@@ -13850,15 +13850,15 @@ var useSettingsTabsStore = create((set, get) => ({
|
|
|
13850
13850
|
}));
|
|
13851
13851
|
function usePublishSettingsTabs(ids) {
|
|
13852
13852
|
const key = ids.join(",");
|
|
13853
|
-
|
|
13853
|
+
React126.useEffect(() => {
|
|
13854
13854
|
useSettingsTabsStore.getState().setIds(key ? key.split(",") : []);
|
|
13855
13855
|
}, [key]);
|
|
13856
13856
|
}
|
|
13857
13857
|
function useAgentSurface(contribution) {
|
|
13858
|
-
const ref =
|
|
13858
|
+
const ref = React126.useRef(contribution);
|
|
13859
13859
|
ref.current = contribution;
|
|
13860
13860
|
const id = contribution.id;
|
|
13861
|
-
|
|
13861
|
+
React126.useEffect(() => {
|
|
13862
13862
|
registerSurface({ id, get: () => ref.current });
|
|
13863
13863
|
const names = (ref.current.tools ?? []).map((t) => t.tool.name);
|
|
13864
13864
|
for (const name of names) {
|
|
@@ -14638,9 +14638,9 @@ function featureMap() {
|
|
|
14638
14638
|
}));
|
|
14639
14639
|
}
|
|
14640
14640
|
function ActivationAgentSurface({ programs }) {
|
|
14641
|
-
const programsRef =
|
|
14641
|
+
const programsRef = React126.useRef(programs);
|
|
14642
14642
|
programsRef.current = programs;
|
|
14643
|
-
const contribution =
|
|
14643
|
+
const contribution = React126.useMemo(
|
|
14644
14644
|
() => ({
|
|
14645
14645
|
id: "onboarding.activation",
|
|
14646
14646
|
pluginId: "onboarding",
|
|
@@ -14961,7 +14961,7 @@ Quando a pessoa perguntar COMO fazer algo que tem guia em \`setupGuides\` ("como
|
|
|
14961
14961
|
- Termine dizendo o que isso destrava e oferecendo a pr\xF3xima, uma vez s\xF3.`
|
|
14962
14962
|
);
|
|
14963
14963
|
function SetupAgentSurface() {
|
|
14964
|
-
const contribution =
|
|
14964
|
+
const contribution = React126.useMemo(
|
|
14965
14965
|
() => ({
|
|
14966
14966
|
id: "setup.guides",
|
|
14967
14967
|
pluginId: "setup",
|
|
@@ -15077,7 +15077,7 @@ function SetupAgentSurface() {
|
|
|
15077
15077
|
}
|
|
15078
15078
|
var DEBOUNCE_MS = 1200;
|
|
15079
15079
|
function useActivationWatch() {
|
|
15080
|
-
|
|
15080
|
+
React126.useEffect(() => {
|
|
15081
15081
|
let timer = null;
|
|
15082
15082
|
let running = false;
|
|
15083
15083
|
const sweep = async () => {
|
|
@@ -15116,7 +15116,7 @@ function useActivationWatch() {
|
|
|
15116
15116
|
off();
|
|
15117
15117
|
};
|
|
15118
15118
|
}, []);
|
|
15119
|
-
|
|
15119
|
+
React126.useEffect(() => {
|
|
15120
15120
|
useActivationStore.setState({
|
|
15121
15121
|
onStepCompleted: (step, by) => {
|
|
15122
15122
|
const state = useActivationStore.getState();
|
|
@@ -15773,7 +15773,7 @@ function ActivationProvider() {
|
|
|
15773
15773
|
const programs = runtime?.onboardingPrograms ?? [];
|
|
15774
15774
|
const settingsIds = useSettingsTabsStore((s) => s.ids);
|
|
15775
15775
|
const routeKey = (runtime?.routes.length ?? 0) + ":" + settingsIds.join(",");
|
|
15776
|
-
const hasRoute =
|
|
15776
|
+
const hasRoute = React126.useMemo(() => {
|
|
15777
15777
|
const known = /* @__PURE__ */ new Set(["/", "/settings"]);
|
|
15778
15778
|
for (const route of runtime?.routes ?? []) known.add(route.path);
|
|
15779
15779
|
for (const id of settingsIds) known.add(`/settings/${id}`);
|
|
@@ -15781,14 +15781,14 @@ function ActivationProvider() {
|
|
|
15781
15781
|
}, [routeKey]);
|
|
15782
15782
|
const answers = useBusinessProfileStore((s) => s.profile?.answers);
|
|
15783
15783
|
const programKey = programs.map((p) => p.id).join(",");
|
|
15784
|
-
const catalog =
|
|
15784
|
+
const catalog = React126.useMemo(
|
|
15785
15785
|
() => buildActivationCatalog({ verticalId, programs, hasRoute, answers }),
|
|
15786
15786
|
[verticalId, programKey, hasRoute, answers]
|
|
15787
15787
|
);
|
|
15788
|
-
|
|
15788
|
+
React126.useEffect(() => {
|
|
15789
15789
|
setCatalog(catalog);
|
|
15790
15790
|
}, [catalog, setCatalog]);
|
|
15791
|
-
|
|
15791
|
+
React126.useEffect(() => {
|
|
15792
15792
|
if (!tenantId2) return;
|
|
15793
15793
|
let cancelled = false;
|
|
15794
15794
|
void (async () => {
|
|
@@ -15820,14 +15820,14 @@ function ActivationProvider() {
|
|
|
15820
15820
|
cancelled = true;
|
|
15821
15821
|
};
|
|
15822
15822
|
}, [tenantId2, catalog, answers, hasRoute, settingsIds, user?.id, load]);
|
|
15823
|
-
|
|
15823
|
+
React126.useEffect(() => {
|
|
15824
15824
|
if (!tenantId2) {
|
|
15825
15825
|
useBusinessProfileStore.getState().clear();
|
|
15826
15826
|
return;
|
|
15827
15827
|
}
|
|
15828
15828
|
void useBusinessProfileStore.getState().load(tenantId2, orgName);
|
|
15829
15829
|
}, [tenantId2, orgName]);
|
|
15830
|
-
|
|
15830
|
+
React126.useEffect(() => {
|
|
15831
15831
|
if (!tenantId2) return;
|
|
15832
15832
|
const key = `${GREETING_FLAG}:${tenantId2}`;
|
|
15833
15833
|
let pending2 = false;
|
|
@@ -15849,10 +15849,10 @@ function ActivationProvider() {
|
|
|
15849
15849
|
return () => window.clearTimeout(timer);
|
|
15850
15850
|
}, [tenantId2]);
|
|
15851
15851
|
const guides = runtime?.setupGuides;
|
|
15852
|
-
|
|
15852
|
+
React126.useEffect(() => {
|
|
15853
15853
|
setRuntimeSetupGuides(guides ?? []);
|
|
15854
15854
|
}, [guides]);
|
|
15855
|
-
|
|
15855
|
+
React126.useEffect(() => {
|
|
15856
15856
|
setTourNavigator(navigateTo);
|
|
15857
15857
|
return () => setTourNavigator(void 0);
|
|
15858
15858
|
}, []);
|
|
@@ -16025,7 +16025,7 @@ Escrita:
|
|
|
16025
16025
|
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.`
|
|
16026
16026
|
);
|
|
16027
16027
|
function HandbookAgentSurface() {
|
|
16028
|
-
const contribution =
|
|
16028
|
+
const contribution = React126.useMemo(
|
|
16029
16029
|
() => ({
|
|
16030
16030
|
id: "handbook",
|
|
16031
16031
|
pluginId: "handbook",
|
|
@@ -16136,18 +16136,18 @@ function NotebookPanel() {
|
|
|
16136
16136
|
const userId = useHandbookStore((s) => s.userId);
|
|
16137
16137
|
const write3 = useHandbookStore((s) => s.write);
|
|
16138
16138
|
const remove = useHandbookStore((s) => s.remove);
|
|
16139
|
-
const [filter, setFilter] =
|
|
16140
|
-
const [search, setSearch] =
|
|
16141
|
-
const [draft, setDraft] =
|
|
16142
|
-
const [preview, setPreview] =
|
|
16143
|
-
const [confirming, setConfirming] =
|
|
16144
|
-
const entries2 =
|
|
16139
|
+
const [filter, setFilter] = React126.useState("all");
|
|
16140
|
+
const [search, setSearch] = React126.useState("");
|
|
16141
|
+
const [draft, setDraft] = React126.useState(null);
|
|
16142
|
+
const [preview, setPreview] = React126.useState(false);
|
|
16143
|
+
const [confirming, setConfirming] = React126.useState(null);
|
|
16144
|
+
const entries2 = React126.useMemo(
|
|
16145
16145
|
() => (pages ?? []).map((p) => ({ page: p, entry: toEntry2(p) })),
|
|
16146
16146
|
[pages]
|
|
16147
16147
|
);
|
|
16148
|
-
const timer =
|
|
16149
|
-
const inFlight =
|
|
16150
|
-
const persist =
|
|
16148
|
+
const timer = React126.useRef(null);
|
|
16149
|
+
const inFlight = React126.useRef(false);
|
|
16150
|
+
const persist = React126.useCallback(async (d) => {
|
|
16151
16151
|
const title = titleFromBody(d.body);
|
|
16152
16152
|
if (!title && !d.body.trim()) return d.id;
|
|
16153
16153
|
const filed = d.folder !== null;
|
|
@@ -16169,7 +16169,7 @@ function NotebookPanel() {
|
|
|
16169
16169
|
});
|
|
16170
16170
|
return saved?.id ?? d.id;
|
|
16171
16171
|
}, [write3, userId]);
|
|
16172
|
-
const schedule =
|
|
16172
|
+
const schedule = React126.useCallback((next) => {
|
|
16173
16173
|
setDraft(next);
|
|
16174
16174
|
if (timer.current) clearTimeout(timer.current);
|
|
16175
16175
|
timer.current = setTimeout(() => {
|
|
@@ -16201,7 +16201,7 @@ function NotebookPanel() {
|
|
|
16201
16201
|
legacyId: null
|
|
16202
16202
|
});
|
|
16203
16203
|
};
|
|
16204
|
-
const folders =
|
|
16204
|
+
const folders = React126.useMemo(() => {
|
|
16205
16205
|
const set = /* @__PURE__ */ new Set();
|
|
16206
16206
|
for (const { page } of entries2) {
|
|
16207
16207
|
if (page.kind !== "doc" || !page.path) continue;
|
|
@@ -16593,10 +16593,10 @@ ${body}`
|
|
|
16593
16593
|
}
|
|
16594
16594
|
function NoteTodosSection({ noteId, noteTitle }) {
|
|
16595
16595
|
const adapter = useNotesTasksBridge((s) => s.adapter);
|
|
16596
|
-
const [todos, setTodos] =
|
|
16597
|
-
const [draft, setDraft] =
|
|
16598
|
-
const [busy, setBusy] =
|
|
16599
|
-
|
|
16596
|
+
const [todos, setTodos] = React126.useState([]);
|
|
16597
|
+
const [draft, setDraft] = React126.useState("");
|
|
16598
|
+
const [busy, setBusy] = React126.useState(false);
|
|
16599
|
+
React126.useEffect(() => {
|
|
16600
16600
|
if (!adapter) return;
|
|
16601
16601
|
let alive = true;
|
|
16602
16602
|
adapter.listTodos(noteId).then((rows) => {
|
|
@@ -16726,7 +16726,7 @@ function NotebookRailPanel() {
|
|
|
16726
16726
|
const pages = useHandbookStore((s) => s.pages);
|
|
16727
16727
|
const count = pages?.length ?? 0;
|
|
16728
16728
|
useRightRailPanel(
|
|
16729
|
-
|
|
16729
|
+
React126.useMemo(
|
|
16730
16730
|
() => ({
|
|
16731
16731
|
id: "notes",
|
|
16732
16732
|
label: tl("Notes", "Notas"),
|
|
@@ -16745,10 +16745,10 @@ function HandbookProvider() {
|
|
|
16745
16745
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16746
16746
|
const load = useHandbookStore((s) => s.load);
|
|
16747
16747
|
const setUser = useHandbookStore((s) => s.setUser);
|
|
16748
|
-
|
|
16748
|
+
React126.useEffect(() => {
|
|
16749
16749
|
setUser(userId);
|
|
16750
16750
|
}, [userId, setUser]);
|
|
16751
|
-
|
|
16751
|
+
React126.useEffect(() => {
|
|
16752
16752
|
if (tenantId2) void load(tenantId2);
|
|
16753
16753
|
}, [tenantId2, load]);
|
|
16754
16754
|
useLocalNotesImport(tenantId2, userId);
|
|
@@ -16758,7 +16758,7 @@ function HandbookProvider() {
|
|
|
16758
16758
|
] });
|
|
16759
16759
|
}
|
|
16760
16760
|
function useLocalNotesImport(tenantId2, userId) {
|
|
16761
|
-
|
|
16761
|
+
React126.useEffect(() => {
|
|
16762
16762
|
if (!tenantId2 || !userId) return;
|
|
16763
16763
|
const source = `fayz.notes.${tenantId2}.${userId}`;
|
|
16764
16764
|
const flag = `fayz.notes.imported.${tenantId2}.${userId}`;
|
|
@@ -16806,7 +16806,7 @@ function useUnitBootstrap() {
|
|
|
16806
16806
|
const tenant = useTenantOptional();
|
|
16807
16807
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16808
16808
|
const orgId = tenant?.org?.id;
|
|
16809
|
-
|
|
16809
|
+
React126.useEffect(() => {
|
|
16810
16810
|
if (!orgId) return;
|
|
16811
16811
|
const { loadedFor, load, reset } = useUnitStore.getState();
|
|
16812
16812
|
if (loadedFor && loadedFor !== orgId) reset();
|
|
@@ -16845,19 +16845,19 @@ function UnitMembersTab({ item }) {
|
|
|
16845
16845
|
const orgMembers = useOrganizationStore((s) => s.members);
|
|
16846
16846
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
16847
16847
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
16848
|
-
const [rows, setRows] =
|
|
16849
|
-
const [activity, setActivity] =
|
|
16850
|
-
const [adding, setAdding] =
|
|
16851
|
-
const [busy, setBusy] =
|
|
16852
|
-
const reload =
|
|
16848
|
+
const [rows, setRows] = React126.useState(null);
|
|
16849
|
+
const [activity, setActivity] = React126.useState({});
|
|
16850
|
+
const [adding, setAdding] = React126.useState(false);
|
|
16851
|
+
const [busy, setBusy] = React126.useState(null);
|
|
16852
|
+
const reload = React126.useCallback(async () => {
|
|
16853
16853
|
if (!unitId) return;
|
|
16854
16854
|
setRows(await fetchUnitMembers(unitId));
|
|
16855
16855
|
}, [unitId]);
|
|
16856
16856
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
16857
|
-
|
|
16857
|
+
React126.useEffect(() => {
|
|
16858
16858
|
void reload();
|
|
16859
16859
|
}, [reload, version5]);
|
|
16860
|
-
|
|
16860
|
+
React126.useEffect(() => {
|
|
16861
16861
|
if (!orgId) return;
|
|
16862
16862
|
let alive = true;
|
|
16863
16863
|
void fetchMemberActivity(orgId).then((a) => {
|
|
@@ -16867,7 +16867,7 @@ function UnitMembersTab({ item }) {
|
|
|
16867
16867
|
alive = false;
|
|
16868
16868
|
};
|
|
16869
16869
|
}, [orgId]);
|
|
16870
|
-
const byUser =
|
|
16870
|
+
const byUser = React126.useMemo(() => {
|
|
16871
16871
|
const map = /* @__PURE__ */ new Map();
|
|
16872
16872
|
for (const m of orgMembers) {
|
|
16873
16873
|
map.set(m.userId, {
|
|
@@ -16879,7 +16879,7 @@ function UnitMembersTab({ item }) {
|
|
|
16879
16879
|
}
|
|
16880
16880
|
return map;
|
|
16881
16881
|
}, [orgMembers]);
|
|
16882
|
-
const available =
|
|
16882
|
+
const available = React126.useMemo(
|
|
16883
16883
|
() => orgMembers.filter((m) => !(rows ?? []).some((r) => r.userId === m.userId)),
|
|
16884
16884
|
[orgMembers, rows]
|
|
16885
16885
|
);
|
|
@@ -17085,15 +17085,15 @@ function MemberAccessBody({
|
|
|
17085
17085
|
const units = useUnitStore((s) => s.units);
|
|
17086
17086
|
const byId = useUnitStore((s) => s.byId);
|
|
17087
17087
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
17088
|
-
const [bindings, setBindings] =
|
|
17089
|
-
const [loading, setLoading] =
|
|
17090
|
-
const [adding, setAdding] =
|
|
17091
|
-
const branches =
|
|
17092
|
-
const unbound =
|
|
17088
|
+
const [bindings, setBindings] = React126.useState([]);
|
|
17089
|
+
const [loading, setLoading] = React126.useState(false);
|
|
17090
|
+
const [adding, setAdding] = React126.useState(false);
|
|
17091
|
+
const branches = React126.useMemo(() => units.filter((u) => u.isActive !== false), [units]);
|
|
17092
|
+
const unbound = React126.useMemo(
|
|
17093
17093
|
() => branches.filter((u) => !bindings.some((b) => b.locationId === u.id)),
|
|
17094
17094
|
[branches, bindings]
|
|
17095
17095
|
);
|
|
17096
|
-
const reload =
|
|
17096
|
+
const reload = React126.useCallback(async () => {
|
|
17097
17097
|
if (!userId) return;
|
|
17098
17098
|
setLoading(true);
|
|
17099
17099
|
try {
|
|
@@ -17103,7 +17103,7 @@ function MemberAccessBody({
|
|
|
17103
17103
|
}
|
|
17104
17104
|
}, [userId]);
|
|
17105
17105
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
17106
|
-
|
|
17106
|
+
React126.useEffect(() => {
|
|
17107
17107
|
void reload();
|
|
17108
17108
|
}, [reload, version5]);
|
|
17109
17109
|
async function add(unitId) {
|
|
@@ -17790,7 +17790,7 @@ function useWrongApp() {
|
|
|
17790
17790
|
const tenantId2 = useAppConfigStore((s) => s.tenantId);
|
|
17791
17791
|
const activeTenantId = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
17792
17792
|
const appId = resolveAppId();
|
|
17793
|
-
return
|
|
17793
|
+
return React126.useMemo(() => {
|
|
17794
17794
|
if (!appId || !activeTenantId || tenantId2 !== activeTenantId) return { app: null };
|
|
17795
17795
|
const list = (apps ?? []).filter((a) => !a.house);
|
|
17796
17796
|
if (!list.length) return { app: null };
|
|
@@ -17913,13 +17913,13 @@ function surveyTokenFromPath(pathname) {
|
|
|
17913
17913
|
return m ? decodeURIComponent(m[1]) : null;
|
|
17914
17914
|
}
|
|
17915
17915
|
function PublicSurveyPage({ token, appName }) {
|
|
17916
|
-
const [loaded2, setLoaded] =
|
|
17917
|
-
const [draft, setDraft] =
|
|
17918
|
-
const [name, setName] =
|
|
17919
|
-
const [sending, setSending] =
|
|
17920
|
-
const [sent, setSent] =
|
|
17921
|
-
const [failed, setFailed] =
|
|
17922
|
-
|
|
17916
|
+
const [loaded2, setLoaded] = React126__default.useState(null);
|
|
17917
|
+
const [draft, setDraft] = React126__default.useState({});
|
|
17918
|
+
const [name, setName] = React126__default.useState("");
|
|
17919
|
+
const [sending, setSending] = React126__default.useState(false);
|
|
17920
|
+
const [sent, setSent] = React126__default.useState(null);
|
|
17921
|
+
const [failed, setFailed] = React126__default.useState(null);
|
|
17922
|
+
React126__default.useEffect(() => {
|
|
17923
17923
|
let alive = true;
|
|
17924
17924
|
const client3 = getFayzSupabaseClientOptional();
|
|
17925
17925
|
if (!client3) {
|
|
@@ -18217,7 +18217,7 @@ function isServed2(route) {
|
|
|
18217
18217
|
function getPersonActions(kind) {
|
|
18218
18218
|
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));
|
|
18219
18219
|
}
|
|
18220
|
-
var RouteErrorBoundary = class extends
|
|
18220
|
+
var RouteErrorBoundary = class extends React126.Component {
|
|
18221
18221
|
constructor() {
|
|
18222
18222
|
super(...arguments);
|
|
18223
18223
|
this.state = { crashed: false, report: null };
|
|
@@ -18259,7 +18259,7 @@ var RouteErrorBoundary = class extends React125.Component {
|
|
|
18259
18259
|
}
|
|
18260
18260
|
};
|
|
18261
18261
|
function RouteErrorScreen({ report, tr, onBack, onRetry, backLabel }) {
|
|
18262
|
-
const [copied, setCopied] =
|
|
18262
|
+
const [copied, setCopied] = React126.useState(false);
|
|
18263
18263
|
const copyDetails = () => {
|
|
18264
18264
|
if (!report || typeof navigator === "undefined" || !navigator.clipboard) return;
|
|
18265
18265
|
const details = [
|
|
@@ -18364,9 +18364,9 @@ function UnitSwitching({ unitName, isAll, onDone }) {
|
|
|
18364
18364
|
const v = t(key);
|
|
18365
18365
|
return !v || v === key ? fallback : v;
|
|
18366
18366
|
};
|
|
18367
|
-
const doneRef =
|
|
18367
|
+
const doneRef = React126.useRef(onDone);
|
|
18368
18368
|
doneRef.current = onDone;
|
|
18369
|
-
|
|
18369
|
+
React126.useEffect(() => {
|
|
18370
18370
|
const id = window.setTimeout(() => doneRef.current(), HOLD_MS);
|
|
18371
18371
|
return () => window.clearTimeout(id);
|
|
18372
18372
|
}, []);
|
|
@@ -18423,11 +18423,11 @@ function UnitPickerDialog() {
|
|
|
18423
18423
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
18424
18424
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
18425
18425
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
18426
|
-
const reachable =
|
|
18426
|
+
const reachable = React126.useMemo(
|
|
18427
18427
|
() => myUnitIds.length > 0 ? myUnitIds : units.filter((u) => u.kind !== "region").map((u) => u.id),
|
|
18428
18428
|
[myUnitIds, units]
|
|
18429
18429
|
);
|
|
18430
|
-
const groups =
|
|
18430
|
+
const groups = React126.useMemo(() => {
|
|
18431
18431
|
const out = [];
|
|
18432
18432
|
if (reachable.length > 1) {
|
|
18433
18433
|
out.push({ id: "_all", options: [{ id: ALL_UNITS, label: "Todas as unidades" }] });
|
|
@@ -18626,16 +18626,16 @@ function WorkspaceSetupFlow({
|
|
|
18626
18626
|
const user = useAuthStore((s) => s.user);
|
|
18627
18627
|
const { switchOrg } = useTenant();
|
|
18628
18628
|
const closeSetup = useWorkspaceSetupStore((s) => s.close);
|
|
18629
|
-
const uploadLogo =
|
|
18629
|
+
const uploadLogo = React126.useMemo(
|
|
18630
18630
|
() => user ? createLogoUploader(user.id) : void 0,
|
|
18631
18631
|
[user?.id]
|
|
18632
18632
|
);
|
|
18633
|
-
const country =
|
|
18633
|
+
const country = React126.useMemo(
|
|
18634
18634
|
() => currency === "BRL" || (locale ?? "").toLowerCase().startsWith("pt") ? "BR" : void 0,
|
|
18635
18635
|
[currency, locale]
|
|
18636
18636
|
);
|
|
18637
|
-
const stepsRef =
|
|
18638
|
-
const analyzeSite =
|
|
18637
|
+
const stepsRef = React126.useRef([]);
|
|
18638
|
+
const analyzeSite = React126.useMemo(
|
|
18639
18639
|
() => createSiteAnalyzer({
|
|
18640
18640
|
apiBaseUrl: resolveFayzApiBaseUrl(),
|
|
18641
18641
|
steps: () => stepsRef.current,
|
|
@@ -18643,7 +18643,7 @@ function WorkspaceSetupFlow({
|
|
|
18643
18643
|
}),
|
|
18644
18644
|
[locale]
|
|
18645
18645
|
);
|
|
18646
|
-
const steps =
|
|
18646
|
+
const steps = React126.useMemo(
|
|
18647
18647
|
() => buildWorkspaceSetupSteps({
|
|
18648
18648
|
verticalId,
|
|
18649
18649
|
uploadLogo,
|
|
@@ -18655,13 +18655,13 @@ function WorkspaceSetupFlow({
|
|
|
18655
18655
|
[verticalId, uploadLogo, media, country, analyzeSite]
|
|
18656
18656
|
);
|
|
18657
18657
|
stepsRef.current = steps;
|
|
18658
|
-
const initialValues2 =
|
|
18658
|
+
const initialValues2 = React126.useMemo(
|
|
18659
18659
|
// Seeding the contact email with the account's own is one field fewer to
|
|
18660
18660
|
// type, and it is right far more often than it is wrong.
|
|
18661
18661
|
() => user?.email ? { "workspace.email": user.email } : {},
|
|
18662
18662
|
[user?.email]
|
|
18663
18663
|
);
|
|
18664
|
-
const onSubmit =
|
|
18664
|
+
const onSubmit = React126.useCallback(
|
|
18665
18665
|
async (values) => {
|
|
18666
18666
|
if (!user) throw new Error(tl("You are signed out.", "Sua sess\xE3o terminou."));
|
|
18667
18667
|
const org = await submitWorkspaceSetup({
|
|
@@ -18778,16 +18778,16 @@ function GettingStartedWidget() {
|
|
|
18778
18778
|
const t = useTranslation();
|
|
18779
18779
|
const rows = useActivationStore((s) => s.rows);
|
|
18780
18780
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18781
|
-
const steps =
|
|
18781
|
+
const steps = React126.useMemo(
|
|
18782
18782
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18783
18783
|
[rows, catalog]
|
|
18784
18784
|
);
|
|
18785
|
-
const onNavigate =
|
|
18785
|
+
const onNavigate = React126.useCallback((path) => {
|
|
18786
18786
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18787
18787
|
navigateTo(path);
|
|
18788
18788
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18789
18789
|
}, []);
|
|
18790
|
-
const onAskAgent =
|
|
18790
|
+
const onAskAgent = React126.useCallback((step) => {
|
|
18791
18791
|
void startGuidedRun(step.id);
|
|
18792
18792
|
}, []);
|
|
18793
18793
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18812,16 +18812,16 @@ function ActivationChecklistCard({
|
|
|
18812
18812
|
}) {
|
|
18813
18813
|
const rows = useActivationStore((s) => s.rows);
|
|
18814
18814
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18815
|
-
const steps =
|
|
18815
|
+
const steps = React126.useMemo(
|
|
18816
18816
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18817
18817
|
[rows, catalog]
|
|
18818
18818
|
);
|
|
18819
|
-
const onNavigate =
|
|
18819
|
+
const onNavigate = React126.useCallback((path) => {
|
|
18820
18820
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18821
18821
|
navigateTo(path);
|
|
18822
18822
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18823
18823
|
}, []);
|
|
18824
|
-
const onAskAgent =
|
|
18824
|
+
const onAskAgent = React126.useCallback((step) => {
|
|
18825
18825
|
void startGuidedRun(step.id);
|
|
18826
18826
|
}, []);
|
|
18827
18827
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18855,12 +18855,12 @@ function rememberCompleted(storageKey2) {
|
|
|
18855
18855
|
}
|
|
18856
18856
|
}
|
|
18857
18857
|
function usePluginOnboardingGate(storageKey2, checkExistingData) {
|
|
18858
|
-
const checkRef =
|
|
18858
|
+
const checkRef = React126.useRef(checkExistingData);
|
|
18859
18859
|
checkRef.current = checkExistingData;
|
|
18860
|
-
const [status, setStatus] =
|
|
18860
|
+
const [status, setStatus] = React126.useState(
|
|
18861
18861
|
() => wasCompleted(storageKey2) ? "complete" : "checking"
|
|
18862
18862
|
);
|
|
18863
|
-
|
|
18863
|
+
React126.useEffect(() => {
|
|
18864
18864
|
if (status !== "checking") return;
|
|
18865
18865
|
let cancelled = false;
|
|
18866
18866
|
void checkRef.current().then((hasData) => {
|
|
@@ -18874,7 +18874,7 @@ function usePluginOnboardingGate(storageKey2, checkExistingData) {
|
|
|
18874
18874
|
cancelled = true;
|
|
18875
18875
|
};
|
|
18876
18876
|
}, [status, storageKey2]);
|
|
18877
|
-
const complete =
|
|
18877
|
+
const complete = React126.useCallback(() => {
|
|
18878
18878
|
rememberCompleted(storageKey2);
|
|
18879
18879
|
setStatus("complete");
|
|
18880
18880
|
}, [storageKey2]);
|
|
@@ -18894,9 +18894,9 @@ function PluginOnboardingGateSkeleton() {
|
|
|
18894
18894
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-72 rounded-card" })
|
|
18895
18895
|
] });
|
|
18896
18896
|
}
|
|
18897
|
-
var WidgetSurfaceContext =
|
|
18897
|
+
var WidgetSurfaceContext = React126.createContext("rail");
|
|
18898
18898
|
function useWidgetSurface() {
|
|
18899
|
-
return
|
|
18899
|
+
return React126.useContext(WidgetSurfaceContext);
|
|
18900
18900
|
}
|
|
18901
18901
|
function WidgetSlot({
|
|
18902
18902
|
zone,
|
|
@@ -18940,7 +18940,7 @@ function useNavContribution(id, entries2) {
|
|
|
18940
18940
|
const setContribution = useNavContributionsStore((s) => s.setContribution);
|
|
18941
18941
|
const clearContribution = useNavContributionsStore((s) => s.clearContribution);
|
|
18942
18942
|
const key = JSON.stringify(entries2);
|
|
18943
|
-
|
|
18943
|
+
React126.useEffect(() => {
|
|
18944
18944
|
setContribution(id, entries2);
|
|
18945
18945
|
return () => clearContribution(id);
|
|
18946
18946
|
}, [id, key]);
|
|
@@ -19010,7 +19010,7 @@ function useAppDirectory() {
|
|
|
19010
19010
|
const tenantId2 = useActiveTenantId();
|
|
19011
19011
|
const apps = useAppDirectoryStore((s) => s.apps);
|
|
19012
19012
|
const load = useAppDirectoryStore((s) => s.load);
|
|
19013
|
-
|
|
19013
|
+
React126.useEffect(() => {
|
|
19014
19014
|
if (tenantId2) void load(tenantId2, resolveAppId());
|
|
19015
19015
|
}, [tenantId2, load]);
|
|
19016
19016
|
return { apps };
|
|
@@ -19102,7 +19102,7 @@ var CSS2 = `
|
|
|
19102
19102
|
}
|
|
19103
19103
|
`;
|
|
19104
19104
|
function useWordmarkStyle() {
|
|
19105
|
-
|
|
19105
|
+
React126.useEffect(() => {
|
|
19106
19106
|
if (typeof document === "undefined") return;
|
|
19107
19107
|
const existing = document.getElementById(STYLE_ID2);
|
|
19108
19108
|
if (existing) {
|
|
@@ -19336,7 +19336,7 @@ var SWAP_CSS = `
|
|
|
19336
19336
|
}
|
|
19337
19337
|
`;
|
|
19338
19338
|
function useSwapStyle() {
|
|
19339
|
-
|
|
19339
|
+
React126.useEffect(() => {
|
|
19340
19340
|
if (typeof document === "undefined" || document.getElementById(SWAP_STYLE_ID)) return;
|
|
19341
19341
|
const el = document.createElement("style");
|
|
19342
19342
|
el.id = SWAP_STYLE_ID;
|
|
@@ -19345,9 +19345,9 @@ function useSwapStyle() {
|
|
|
19345
19345
|
}, []);
|
|
19346
19346
|
}
|
|
19347
19347
|
function AppSwitcherView({ apps, mark, logo, collapsed = false, label: label3, onSelect, brandedByTenant = false }) {
|
|
19348
|
-
const [hovered, setHovered] =
|
|
19349
|
-
const [open, setOpen] =
|
|
19350
|
-
const [pending2, setPending] =
|
|
19348
|
+
const [hovered, setHovered] = React126.useState(false);
|
|
19349
|
+
const [open, setOpen] = React126.useState(false);
|
|
19350
|
+
const [pending2, setPending] = React126.useState(null);
|
|
19351
19351
|
const active2 = hovered || open;
|
|
19352
19352
|
useSwapStyle();
|
|
19353
19353
|
const brand = /* @__PURE__ */ jsx(BrandFace, { mark, logo, collapsed });
|
|
@@ -19494,7 +19494,7 @@ function useContextualNav(nav) {
|
|
|
19494
19494
|
const setNav = useContextualNavStore((s) => s.setNav);
|
|
19495
19495
|
const clearNav = useContextualNavStore((s) => s.clearNav);
|
|
19496
19496
|
const key = nav ? JSON.stringify(nav) : null;
|
|
19497
|
-
|
|
19497
|
+
React126.useEffect(() => {
|
|
19498
19498
|
if (!nav) return;
|
|
19499
19499
|
setNav(nav);
|
|
19500
19500
|
return () => clearNav(nav.base);
|
|
@@ -19566,7 +19566,7 @@ async function findNearestUnit(units, reachable) {
|
|
|
19566
19566
|
}
|
|
19567
19567
|
var UNIT_SEARCH_THRESHOLD = 8;
|
|
19568
19568
|
function WorkspaceUnitSheet({ onClose, canCreate = true }) {
|
|
19569
|
-
const [level, setLevel] =
|
|
19569
|
+
const [level, setLevel] = React126.useState("root");
|
|
19570
19570
|
return /* @__PURE__ */ jsxs(
|
|
19571
19571
|
BottomSheet,
|
|
19572
19572
|
{
|
|
@@ -19629,9 +19629,9 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19629
19629
|
const closeSheet = useSheetClose();
|
|
19630
19630
|
const beginSwitch = useWorkspaceSwitchingStore((s) => s.begin);
|
|
19631
19631
|
const openSetup = useWorkspaceSetupStore((s) => s.open);
|
|
19632
|
-
const [query, setQuery] =
|
|
19632
|
+
const [query, setQuery] = React126.useState("");
|
|
19633
19633
|
const org = tenant?.org ?? null;
|
|
19634
|
-
const options =
|
|
19634
|
+
const options = React126.useMemo(() => {
|
|
19635
19635
|
const list = tenant?.userOrgs ?? [];
|
|
19636
19636
|
if (list.length) return list;
|
|
19637
19637
|
return org ? [{ orgId: org.id, orgName: org.name, orgSlug: org.slug, orgLogoUrl: org.logoUrl }] : [];
|
|
@@ -19640,7 +19640,7 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19640
19640
|
const v = t.t(key);
|
|
19641
19641
|
return !v || v === key ? fallback : v;
|
|
19642
19642
|
};
|
|
19643
|
-
const search =
|
|
19643
|
+
const search = React126.useMemo(
|
|
19644
19644
|
() => searchWorkspaces(options, query, org?.id),
|
|
19645
19645
|
[options, query, org?.id]
|
|
19646
19646
|
);
|
|
@@ -19692,8 +19692,8 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19692
19692
|
function UnitLevel() {
|
|
19693
19693
|
useUnitBootstrap();
|
|
19694
19694
|
const closeSheet = useSheetClose();
|
|
19695
|
-
const [locating, setLocating] =
|
|
19696
|
-
const [query, setQuery] =
|
|
19695
|
+
const [locating, setLocating] = React126.useState(false);
|
|
19696
|
+
const [query, setQuery] = React126.useState("");
|
|
19697
19697
|
const units = useUnitStore((s) => s.units);
|
|
19698
19698
|
const tree = useUnitStore((s) => s.tree);
|
|
19699
19699
|
const byId = useUnitStore((s) => s.byId);
|
|
@@ -19730,7 +19730,7 @@ function UnitLevel() {
|
|
|
19730
19730
|
const leaves = node.children.filter((c) => c.kind !== "region" && reachable.includes(c.id));
|
|
19731
19731
|
const regions = node.children.filter((c) => c.kind === "region");
|
|
19732
19732
|
if (leaves.length === 0 && regions.length === 0) return null;
|
|
19733
|
-
return /* @__PURE__ */ jsxs(
|
|
19733
|
+
return /* @__PURE__ */ jsxs(React126.Fragment, { children: [
|
|
19734
19734
|
/* @__PURE__ */ jsx("p", { className: "px-4 pb-1 pt-3 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
19735
19735
|
leaves.length > 0 && /* @__PURE__ */ jsx(SheetCard, { children: leaves.map(leaf) }),
|
|
19736
19736
|
regions.map(group)
|
|
@@ -19800,7 +19800,7 @@ function UnitLevel() {
|
|
|
19800
19800
|
}
|
|
19801
19801
|
function WorkspaceUnitRow({ canCreate = true }) {
|
|
19802
19802
|
useUnitBootstrap();
|
|
19803
|
-
const [open, setOpen] =
|
|
19803
|
+
const [open, setOpen] = React126.useState(false);
|
|
19804
19804
|
const tenant = useTenantOptional();
|
|
19805
19805
|
const org = tenant?.org ?? null;
|
|
19806
19806
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
@@ -19987,10 +19987,10 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
19987
19987
|
const load = useFayzProjectsStore((s) => s.load);
|
|
19988
19988
|
const loadedFor = useFayzProjectsStore((s) => s.loadedFor);
|
|
19989
19989
|
const collapsed = useLayoutStore((s) => s.sidebarCollapsed);
|
|
19990
|
-
const [selectedId, setSelectedId] =
|
|
19991
|
-
const [hovered, setHovered] =
|
|
19992
|
-
const [primed, setPrimed] =
|
|
19993
|
-
const closeTimer =
|
|
19990
|
+
const [selectedId, setSelectedId] = React126.useState(null);
|
|
19991
|
+
const [hovered, setHovered] = React126.useState(false);
|
|
19992
|
+
const [primed, setPrimed] = React126.useState(false);
|
|
19993
|
+
const closeTimer = React126.useRef(null);
|
|
19994
19994
|
const cancelClose = () => {
|
|
19995
19995
|
if (closeTimer.current) {
|
|
19996
19996
|
clearTimeout(closeTimer.current);
|
|
@@ -20006,8 +20006,8 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
20006
20006
|
cancelClose();
|
|
20007
20007
|
closeTimer.current = setTimeout(() => setHovered(false), 140);
|
|
20008
20008
|
};
|
|
20009
|
-
|
|
20010
|
-
|
|
20009
|
+
React126.useEffect(() => () => cancelClose(), []);
|
|
20010
|
+
React126.useEffect(() => {
|
|
20011
20011
|
if (loadedFor !== (currentOrgId ?? null)) void load(currentOrgId);
|
|
20012
20012
|
}, [currentOrgId, loadedFor, load]);
|
|
20013
20013
|
const active2 = projects.find((p) => p.id === selectedId) ?? defaultProjectOf(projects) ?? synthFromFallback(fallback);
|
|
@@ -20118,10 +20118,10 @@ function SitePreview({
|
|
|
20118
20118
|
onEdit,
|
|
20119
20119
|
tr
|
|
20120
20120
|
}) {
|
|
20121
|
-
const [nonce, setNonce] =
|
|
20122
|
-
const [loading, setLoading] =
|
|
20121
|
+
const [nonce, setNonce] = React126.useState(0);
|
|
20122
|
+
const [loading, setLoading] = React126.useState(true);
|
|
20123
20123
|
const url = previewSourceOf(project);
|
|
20124
|
-
|
|
20124
|
+
React126.useEffect(() => {
|
|
20125
20125
|
setLoading(true);
|
|
20126
20126
|
}, [nonce, url]);
|
|
20127
20127
|
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";
|
|
@@ -20231,10 +20231,10 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
20231
20231
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
20232
20232
|
const setPageSlot = useRightRailStore((s) => s.setPageSlot);
|
|
20233
20233
|
const setWidth = useRightRailStore((s) => s.setWidth);
|
|
20234
|
-
const rootRef =
|
|
20235
|
-
const [actionsSlot, setActionsSlot] =
|
|
20236
|
-
const [leadingSlot, setLeadingSlot] =
|
|
20237
|
-
|
|
20234
|
+
const rootRef = React126.useRef(null);
|
|
20235
|
+
const [actionsSlot, setActionsSlot] = React126.useState(null);
|
|
20236
|
+
const [leadingSlot, setLeadingSlot] = React126.useState(null);
|
|
20237
|
+
React126.useEffect(() => {
|
|
20238
20238
|
if (!open) return;
|
|
20239
20239
|
const el = rootRef.current;
|
|
20240
20240
|
if (!el) return;
|
|
@@ -20256,8 +20256,8 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
20256
20256
|
el.removeEventListener("transitionend", publish);
|
|
20257
20257
|
};
|
|
20258
20258
|
}, [open, setWidth]);
|
|
20259
|
-
const [narrow, setNarrow] =
|
|
20260
|
-
|
|
20259
|
+
const [narrow, setNarrow] = React126.useState(false);
|
|
20260
|
+
React126.useEffect(() => {
|
|
20261
20261
|
if (!open) return;
|
|
20262
20262
|
const el = rootRef.current;
|
|
20263
20263
|
if (!el) return;
|
|
@@ -20620,9 +20620,9 @@ var TYPE_COLORS = {
|
|
|
20620
20620
|
fix: "text-success"
|
|
20621
20621
|
};
|
|
20622
20622
|
function ChangelogFeed({ changelogUrl, className }) {
|
|
20623
|
-
const [entries2, setEntries] =
|
|
20624
|
-
const [loading, setLoading] =
|
|
20625
|
-
|
|
20623
|
+
const [entries2, setEntries] = React126.useState([]);
|
|
20624
|
+
const [loading, setLoading] = React126.useState(false);
|
|
20625
|
+
React126.useEffect(() => {
|
|
20626
20626
|
if (!changelogUrl) return;
|
|
20627
20627
|
setLoading(true);
|
|
20628
20628
|
fetch(changelogUrl).then((r) => r.json()).then((data) => setEntries(data)).catch(() => setEntries([])).finally(() => setLoading(false));
|
|
@@ -20682,7 +20682,7 @@ function NotificationInbox({
|
|
|
20682
20682
|
changelogUrl,
|
|
20683
20683
|
className
|
|
20684
20684
|
}) {
|
|
20685
|
-
const [activeTab, setActiveTab] =
|
|
20685
|
+
const [activeTab, setActiveTab] = React126.useState("inbox");
|
|
20686
20686
|
const unreadCount = notifications.filter((n) => !n.read).length;
|
|
20687
20687
|
const inboxNotifications = notifications.filter((n) => n.category !== "changelog");
|
|
20688
20688
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex w-80 flex-col", className), children: [
|
|
@@ -20779,11 +20779,11 @@ function NotificationInbox({
|
|
|
20779
20779
|
}
|
|
20780
20780
|
function BrandAgentSurface() {
|
|
20781
20781
|
const org = useOrganizationStore((s) => s.currentOrg);
|
|
20782
|
-
const brand =
|
|
20782
|
+
const brand = React126__default.useMemo(
|
|
20783
20783
|
() => normalizeBrand(org?.settings?.branding, { name: org?.name, logoUrl: org?.logoUrl }),
|
|
20784
20784
|
[org?.settings, org?.name, org?.logoUrl]
|
|
20785
20785
|
);
|
|
20786
|
-
const surface =
|
|
20786
|
+
const surface = React126__default.useMemo(() => ({
|
|
20787
20787
|
id: "core.brand",
|
|
20788
20788
|
describe: () => ({
|
|
20789
20789
|
title: "Marca da casa",
|
|
@@ -20796,15 +20796,15 @@ function BrandAgentSurface() {
|
|
|
20796
20796
|
return null;
|
|
20797
20797
|
}
|
|
20798
20798
|
function ConnectConsentPage({ appName, logo }) {
|
|
20799
|
-
const [state, setState] =
|
|
20800
|
-
const [tenantId2, setTenantId] =
|
|
20801
|
-
const request =
|
|
20799
|
+
const [state, setState] = React126__default.useState({ status: "loading" });
|
|
20800
|
+
const [tenantId2, setTenantId] = React126__default.useState("");
|
|
20801
|
+
const request = React126__default.useMemo(
|
|
20802
20802
|
() => new URLSearchParams(window.location.search).get("request") ?? "",
|
|
20803
20803
|
[]
|
|
20804
20804
|
);
|
|
20805
|
-
const connection =
|
|
20805
|
+
const connection = React126__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
20806
20806
|
const product = appName ?? document.title ?? "este app";
|
|
20807
|
-
const authorizedFetch =
|
|
20807
|
+
const authorizedFetch = React126__default.useCallback(
|
|
20808
20808
|
async (path, init) => {
|
|
20809
20809
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
20810
20810
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -20828,7 +20828,7 @@ function ConnectConsentPage({ appName, logo }) {
|
|
|
20828
20828
|
},
|
|
20829
20829
|
[connection]
|
|
20830
20830
|
);
|
|
20831
|
-
|
|
20831
|
+
React126__default.useEffect(() => {
|
|
20832
20832
|
let cancelled = false;
|
|
20833
20833
|
(async () => {
|
|
20834
20834
|
if (!request) {
|
|
@@ -21072,7 +21072,7 @@ function Row2({ label: label3, value }) {
|
|
|
21072
21072
|
function PageActions({ actions, className }) {
|
|
21073
21073
|
const access = useAccessOptional();
|
|
21074
21074
|
const openUpgrade = useUpgradeModalStore((s) => s.open);
|
|
21075
|
-
const resolved =
|
|
21075
|
+
const resolved = React126__default.useMemo(
|
|
21076
21076
|
() => actions.map((a) => {
|
|
21077
21077
|
const { permission, limitKey, onSelect, ...rest } = a;
|
|
21078
21078
|
let hidden = false;
|
|
@@ -21102,25 +21102,25 @@ function AddConnectorPanel({
|
|
|
21102
21102
|
onSelect
|
|
21103
21103
|
}) {
|
|
21104
21104
|
const { t } = useTranslation$1();
|
|
21105
|
-
const [query, setQuery] =
|
|
21105
|
+
const [query, setQuery] = React126__default.useState("");
|
|
21106
21106
|
const modules = useInstalledModuleIds();
|
|
21107
21107
|
const catalog = useConnectorCatalog();
|
|
21108
21108
|
const scoped = !!categories?.length;
|
|
21109
|
-
const addable =
|
|
21109
|
+
const addable = React126__default.useMemo(
|
|
21110
21110
|
() => inCategories(addableConnectors(connectors ?? []), categories),
|
|
21111
21111
|
[connectors, categories]
|
|
21112
21112
|
);
|
|
21113
|
-
const shelf =
|
|
21113
|
+
const shelf = React126__default.useMemo(() => {
|
|
21114
21114
|
if (connectors === null) return [];
|
|
21115
21115
|
return inCategories(
|
|
21116
21116
|
shelfIntegrations({ present: connectors, installedModules: modules, catalog: catalog ?? [] }),
|
|
21117
21117
|
categories
|
|
21118
21118
|
);
|
|
21119
21119
|
}, [connectors, modules, catalog, categories]);
|
|
21120
|
-
const filtered =
|
|
21121
|
-
const filteredShelf =
|
|
21122
|
-
const soon =
|
|
21123
|
-
const elsewhere =
|
|
21120
|
+
const filtered = React126__default.useMemo(() => filterConnectors(addable, "all", query), [addable, query]);
|
|
21121
|
+
const filteredShelf = React126__default.useMemo(() => filterAvailable(shelf, query), [shelf, query]);
|
|
21122
|
+
const soon = React126__default.useMemo(() => comingSoonHere(filteredShelf), [filteredShelf]);
|
|
21123
|
+
const elsewhere = React126__default.useMemo(() => withAnotherModule(filteredShelf), [filteredShelf]);
|
|
21124
21124
|
const searchable = addable.length + shelf.length > 6;
|
|
21125
21125
|
return /* @__PURE__ */ jsx(Modal, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ModalContent, { size: "2xl", children: [
|
|
21126
21126
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
@@ -21279,22 +21279,22 @@ function AddConnectorButton({ onClick }) {
|
|
|
21279
21279
|
function ConnectorsTab() {
|
|
21280
21280
|
const { t } = useTranslation$1();
|
|
21281
21281
|
const { connectors, error, reload, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
21282
|
-
const [adding, setAdding] =
|
|
21283
|
-
const [selected, setSelected] =
|
|
21284
|
-
const [filter, setFilter] =
|
|
21285
|
-
const [failure, setFailure] =
|
|
21286
|
-
const [revoking, setRevoking] =
|
|
21282
|
+
const [adding, setAdding] = React126__default.useState(false);
|
|
21283
|
+
const [selected, setSelected] = React126__default.useState(null);
|
|
21284
|
+
const [filter, setFilter] = React126__default.useState("all");
|
|
21285
|
+
const [failure, setFailure] = React126__default.useState(null);
|
|
21286
|
+
const [revoking, setRevoking] = React126__default.useState(null);
|
|
21287
21287
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
21288
|
-
const openJourney =
|
|
21288
|
+
const openJourney = React126__default.useCallback(
|
|
21289
21289
|
(connector) => {
|
|
21290
21290
|
if (assistantAvailable) openConnectorsPanel(connector);
|
|
21291
21291
|
else setSelected(connector);
|
|
21292
21292
|
},
|
|
21293
21293
|
[assistantAvailable]
|
|
21294
21294
|
);
|
|
21295
|
-
const visible =
|
|
21296
|
-
const groups =
|
|
21297
|
-
|
|
21295
|
+
const visible = React126__default.useMemo(() => filterConnectors(connectors ?? [], filter), [connectors, filter]);
|
|
21296
|
+
const groups = React126__default.useMemo(() => groupConnectors(visible), [visible]);
|
|
21297
|
+
React126__default.useEffect(() => {
|
|
21298
21298
|
if (!selected || !connectors) return;
|
|
21299
21299
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
21300
21300
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -21329,7 +21329,7 @@ function ConnectorsTab() {
|
|
|
21329
21329
|
(connectors?.length ?? 0) > 4 && /* @__PURE__ */ jsx(Filters, { value: filter, onChange: setFilter }),
|
|
21330
21330
|
connectors === null && /* @__PURE__ */ jsx(ConnectionsSkeleton, {}),
|
|
21331
21331
|
connectors !== null && visible.length === 0 && /* @__PURE__ */ jsx(Empty2, { title: t("connectors.emptyTitle"), body: t("connectors.emptyBody") }),
|
|
21332
|
-
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(
|
|
21332
|
+
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(React126__default.Fragment, { children: [
|
|
21333
21333
|
groups.length > 1 && /* @__PURE__ */ jsx(
|
|
21334
21334
|
"li",
|
|
21335
21335
|
{
|
|
@@ -21467,7 +21467,7 @@ function oauthFailureMessage(t, result) {
|
|
|
21467
21467
|
function useConnectorOAuthReturn() {
|
|
21468
21468
|
const { t } = useTranslation$1();
|
|
21469
21469
|
const runtime = usePluginRuntimeOptional();
|
|
21470
|
-
|
|
21470
|
+
React126__default.useEffect(() => {
|
|
21471
21471
|
if (typeof window === "undefined") return;
|
|
21472
21472
|
const result = readConnectorOAuthReturn(window.location.search);
|
|
21473
21473
|
if (!result) return;
|
|
@@ -21502,8 +21502,8 @@ function ConnectorDeliveries({
|
|
|
21502
21502
|
limit = 10
|
|
21503
21503
|
}) {
|
|
21504
21504
|
const { t } = useTranslation$1();
|
|
21505
|
-
const [rows, setRows] =
|
|
21506
|
-
|
|
21505
|
+
const [rows, setRows] = React126__default.useState(null);
|
|
21506
|
+
React126__default.useEffect(() => {
|
|
21507
21507
|
let cancelled = false;
|
|
21508
21508
|
void load({ limit }).then((r) => {
|
|
21509
21509
|
if (!cancelled) setRows(r);
|
|
@@ -21577,11 +21577,11 @@ var CURRENCIES = [
|
|
|
21577
21577
|
function CompanySettings({ tenant, onSave }) {
|
|
21578
21578
|
const { t } = useTranslation$1();
|
|
21579
21579
|
const { locale: uiLocale, setLocale: setUiLocale } = useLocaleStore();
|
|
21580
|
-
const [name, setName] =
|
|
21581
|
-
const [timezone, setTimezone] =
|
|
21582
|
-
const [currency, setCurrency] =
|
|
21583
|
-
const [saving, setSaving] =
|
|
21584
|
-
|
|
21580
|
+
const [name, setName] = React126.useState(tenant?.name ?? "");
|
|
21581
|
+
const [timezone, setTimezone] = React126.useState(tenant?.settings?.timezone ?? "UTC");
|
|
21582
|
+
const [currency, setCurrency] = React126.useState(tenant?.settings?.currency ?? "USD");
|
|
21583
|
+
const [saving, setSaving] = React126.useState(false);
|
|
21584
|
+
React126.useEffect(() => {
|
|
21585
21585
|
if (tenant) {
|
|
21586
21586
|
setName(tenant.name);
|
|
21587
21587
|
setTimezone(tenant.settings?.timezone ?? "UTC");
|
|
@@ -21673,15 +21673,15 @@ function UnitModeCard() {
|
|
|
21673
21673
|
const units = useUnitStore((s) => s.units);
|
|
21674
21674
|
const setMode = useUnitStore((s) => s.setMode);
|
|
21675
21675
|
const load = useUnitStore((s) => s.load);
|
|
21676
|
-
const [unbound, setUnbound] =
|
|
21677
|
-
const [bindEveryone, setBindEveryone] =
|
|
21678
|
-
const [pending2, setPending] =
|
|
21679
|
-
const [saving, setSaving] =
|
|
21680
|
-
const headquarters =
|
|
21676
|
+
const [unbound, setUnbound] = React126.useState(null);
|
|
21677
|
+
const [bindEveryone, setBindEveryone] = React126.useState(true);
|
|
21678
|
+
const [pending2, setPending] = React126.useState(null);
|
|
21679
|
+
const [saving, setSaving] = React126.useState(false);
|
|
21680
|
+
const headquarters = React126.useMemo(
|
|
21681
21681
|
() => units.find((u) => u.isHeadquarters && u.kind !== "region") ?? units.find((u) => u.kind !== "region"),
|
|
21682
21682
|
[units]
|
|
21683
21683
|
);
|
|
21684
|
-
|
|
21684
|
+
React126.useEffect(() => {
|
|
21685
21685
|
if (!org?.id || unitMode) return;
|
|
21686
21686
|
let alive = true;
|
|
21687
21687
|
void countUnboundMembers(org.id).then((n) => {
|
|
@@ -21845,10 +21845,10 @@ function getInitials(name) {
|
|
|
21845
21845
|
}
|
|
21846
21846
|
function UserProfile({ user, onSave, onAvatarChange }) {
|
|
21847
21847
|
const { t } = useTranslation$1();
|
|
21848
|
-
const [fullName, setFullName] =
|
|
21849
|
-
const [saving, setSaving] =
|
|
21850
|
-
const fileInputRef =
|
|
21851
|
-
|
|
21848
|
+
const [fullName, setFullName] = React126.useState(user?.fullName ?? "");
|
|
21849
|
+
const [saving, setSaving] = React126.useState(false);
|
|
21850
|
+
const fileInputRef = React126.useRef(null);
|
|
21851
|
+
React126.useEffect(() => {
|
|
21852
21852
|
if (user) {
|
|
21853
21853
|
setFullName(user.fullName);
|
|
21854
21854
|
}
|
|
@@ -21988,8 +21988,8 @@ async function fetchMyPersonId(tenantId2, userId) {
|
|
|
21988
21988
|
function useMyPersonId(enabled = true) {
|
|
21989
21989
|
const orgId = useOrganizationStore((s) => s.currentOrg?.id);
|
|
21990
21990
|
const userId = useAuthStore((s) => s.user?.id);
|
|
21991
|
-
const [personId, setPersonId] =
|
|
21992
|
-
|
|
21991
|
+
const [personId, setPersonId] = React126.useState(void 0);
|
|
21992
|
+
React126.useEffect(() => {
|
|
21993
21993
|
if (!enabled || !orgId || !userId) return;
|
|
21994
21994
|
let alive = true;
|
|
21995
21995
|
void dedup(`self:person:${orgId}:${userId}`, () => fetchMyPersonId(orgId, userId)).then((id) => {
|
|
@@ -22049,18 +22049,18 @@ function MyWorkspaceCard() {
|
|
|
22049
22049
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
22050
22050
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
22051
22051
|
const entryReason = useUnitStore((s) => s.entryReason);
|
|
22052
|
-
const [person, setPerson] =
|
|
22053
|
-
const [candidate, setCandidate] =
|
|
22054
|
-
const [linking, setLinking] =
|
|
22052
|
+
const [person, setPerson] = React126.useState(void 0);
|
|
22053
|
+
const [candidate, setCandidate] = React126.useState(null);
|
|
22054
|
+
const [linking, setLinking] = React126.useState(false);
|
|
22055
22055
|
const orgId = currentOrg?.id;
|
|
22056
22056
|
const userId = user?.id;
|
|
22057
|
-
const load =
|
|
22057
|
+
const load = React126.useCallback(async () => {
|
|
22058
22058
|
if (!orgId || !userId) return;
|
|
22059
22059
|
const linked = await fetchMyPersonRecord(orgId, userId);
|
|
22060
22060
|
setPerson(linked);
|
|
22061
22061
|
setCandidate(linked ? null : await findMyPersonCandidate(orgId, user?.email, staffKinds));
|
|
22062
22062
|
}, [orgId, userId, user?.email, staffKinds]);
|
|
22063
|
-
|
|
22063
|
+
React126.useEffect(() => {
|
|
22064
22064
|
void load();
|
|
22065
22065
|
}, [load]);
|
|
22066
22066
|
if (!currentOrg) return null;
|
|
@@ -22154,10 +22154,10 @@ var useStore = create((set) => ({
|
|
|
22154
22154
|
function useHeaderAction(zone, action) {
|
|
22155
22155
|
const register = useStore((s) => s.register);
|
|
22156
22156
|
const unregister = useStore((s) => s.unregister);
|
|
22157
|
-
const latest =
|
|
22157
|
+
const latest = React126.useRef(action);
|
|
22158
22158
|
latest.current = action;
|
|
22159
22159
|
const id = action?.id;
|
|
22160
|
-
|
|
22160
|
+
React126.useEffect(() => {
|
|
22161
22161
|
if (!zone || !id) return;
|
|
22162
22162
|
const current2 = latest.current;
|
|
22163
22163
|
if (current2) register(zone, { ...current2, onSelect: () => latest.current?.onSelect() });
|
|
@@ -22166,7 +22166,7 @@ function useHeaderAction(zone, action) {
|
|
|
22166
22166
|
}
|
|
22167
22167
|
function useHeaderActions(zone) {
|
|
22168
22168
|
const byZone = useStore((s) => s.byZone);
|
|
22169
|
-
return
|
|
22169
|
+
return React126.useMemo(() => Object.values(byZone[zone] ?? {}), [byZone, zone]);
|
|
22170
22170
|
}
|
|
22171
22171
|
function useUserLabel(userId) {
|
|
22172
22172
|
const members = useOrganizationStore((s) => s.members);
|
|
@@ -22358,6 +22358,8 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
22358
22358
|
const [formOpen, setFormOpen] = useState(false);
|
|
22359
22359
|
const [form, setForm] = useState(EMPTY_FORM);
|
|
22360
22360
|
const [saving, setSaving] = useState(false);
|
|
22361
|
+
const [geocoding, setGeocoding] = useState(false);
|
|
22362
|
+
const [geocodeState, setGeocodeState] = useState("idle");
|
|
22361
22363
|
const [deleting, setDeleting] = useState(null);
|
|
22362
22364
|
const ownerId = record?.id;
|
|
22363
22365
|
const db2 = () => getSupabaseClientOptional();
|
|
@@ -22383,6 +22385,7 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
22383
22385
|
setEditing(null);
|
|
22384
22386
|
setForm(single ? { ...EMPTY_FORM, kind: "main", is_default: true } : EMPTY_FORM);
|
|
22385
22387
|
setCepState("idle");
|
|
22388
|
+
setGeocodeState("idle");
|
|
22386
22389
|
lastLookup.current = "";
|
|
22387
22390
|
setFormOpen(true);
|
|
22388
22391
|
};
|
|
@@ -22390,10 +22393,19 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
22390
22393
|
setEditing(a);
|
|
22391
22394
|
setForm(toForm(a));
|
|
22392
22395
|
setCepState("idle");
|
|
22396
|
+
setGeocodeState(a.latitude != null && a.longitude != null ? "resolved" : "idle");
|
|
22393
22397
|
lastLookup.current = formatPostalCode(a.postal_code);
|
|
22394
22398
|
setFormOpen(true);
|
|
22395
22399
|
};
|
|
22396
|
-
const set = (key, value) =>
|
|
22400
|
+
const set = (key, value) => {
|
|
22401
|
+
const locatesAddress = ["postal_code", "street", "number", "district", "city", "state"].includes(key);
|
|
22402
|
+
if (locatesAddress) setGeocodeState("idle");
|
|
22403
|
+
setForm((prev) => ({
|
|
22404
|
+
...prev,
|
|
22405
|
+
[key]: value,
|
|
22406
|
+
...locatesAddress ? { latitude: "", longitude: "" } : {}
|
|
22407
|
+
}));
|
|
22408
|
+
};
|
|
22397
22409
|
const [cepState, setCepState] = useState("idle");
|
|
22398
22410
|
const lastLookup = useRef("");
|
|
22399
22411
|
const numberRef = useRef(null);
|
|
@@ -22414,8 +22426,11 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
22414
22426
|
street: found.street || prev.street,
|
|
22415
22427
|
district: found.district || prev.district,
|
|
22416
22428
|
city: found.city || prev.city,
|
|
22417
|
-
state: found.state || prev.state
|
|
22429
|
+
state: found.state || prev.state,
|
|
22430
|
+
latitude: "",
|
|
22431
|
+
longitude: ""
|
|
22418
22432
|
}));
|
|
22433
|
+
setGeocodeState("idle");
|
|
22419
22434
|
requestAnimationFrame(() => numberRef.current?.focus());
|
|
22420
22435
|
} catch {
|
|
22421
22436
|
setCepState("failed");
|
|
@@ -22429,6 +22444,31 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
22429
22444
|
else lastLookup.current = "";
|
|
22430
22445
|
};
|
|
22431
22446
|
const canSave = form.postal_code.trim() !== "" && form.street.trim() !== "" && form.city.trim() !== "";
|
|
22447
|
+
const handleGeocode = async () => {
|
|
22448
|
+
if (!canSave || geocoding) return;
|
|
22449
|
+
setGeocoding(true);
|
|
22450
|
+
setGeocodeState("idle");
|
|
22451
|
+
try {
|
|
22452
|
+
if (!navigator.geolocation) throw new Error("geolocation_unavailable");
|
|
22453
|
+
const position = await new Promise((resolve, reject) => {
|
|
22454
|
+
navigator.geolocation.getCurrentPosition(resolve, reject, {
|
|
22455
|
+
enableHighAccuracy: true,
|
|
22456
|
+
timeout: 12e3,
|
|
22457
|
+
maximumAge: 0
|
|
22458
|
+
});
|
|
22459
|
+
});
|
|
22460
|
+
setForm((prev) => ({
|
|
22461
|
+
...prev,
|
|
22462
|
+
latitude: position.coords.latitude.toFixed(7),
|
|
22463
|
+
longitude: position.coords.longitude.toFixed(7)
|
|
22464
|
+
}));
|
|
22465
|
+
setGeocodeState("resolved");
|
|
22466
|
+
} catch {
|
|
22467
|
+
setGeocodeState("failed");
|
|
22468
|
+
} finally {
|
|
22469
|
+
setGeocoding(false);
|
|
22470
|
+
}
|
|
22471
|
+
};
|
|
22432
22472
|
const handleSave = async () => {
|
|
22433
22473
|
const client3 = db2();
|
|
22434
22474
|
if (!client3 || !ownerId || !canSave) return;
|
|
@@ -22629,26 +22669,37 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
22629
22669
|
) }),
|
|
22630
22670
|
/* @__PURE__ */ jsx(Field2, { id: "recipient", span: 1, label: t("crud.archetype.addresses.field.recipient"), children: /* @__PURE__ */ jsx(Input, { id: "address-recipient", value: form.recipient, onChange: (e) => set("recipient", e.target.value) }) }),
|
|
22631
22671
|
/* @__PURE__ */ jsx(Field2, { id: "phone", span: 1, label: t("crud.archetype.addresses.field.phone"), children: /* @__PURE__ */ jsx(Input, { id: "address-phone", value: form.phone, onChange: (e) => set("phone", e.target.value) }) }),
|
|
22632
|
-
/* @__PURE__ */ jsx(
|
|
22633
|
-
|
|
22634
|
-
|
|
22635
|
-
|
|
22636
|
-
|
|
22637
|
-
|
|
22638
|
-
|
|
22639
|
-
|
|
22640
|
-
|
|
22641
|
-
|
|
22642
|
-
|
|
22643
|
-
|
|
22644
|
-
|
|
22645
|
-
|
|
22646
|
-
|
|
22647
|
-
|
|
22648
|
-
|
|
22649
|
-
|
|
22650
|
-
|
|
22651
|
-
|
|
22672
|
+
ownerType === "unit" ? /* @__PURE__ */ jsx("div", { className: "col-span-2 rounded-lg border border-border/70 bg-muted/20 p-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
22673
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
22674
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Coordenadas da unidade" }),
|
|
22675
|
+
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: geocodeState === "resolved" ? "Coordenadas capturadas deste dispositivo." : geocodeState === "notFound" ? "N\xE3o encontramos este endere\xE7o. Confira os dados e tente novamente." : geocodeState === "failed" ? "N\xE3o foi poss\xEDvel acessar sua localiza\xE7\xE3o. Confira a permiss\xE3o do navegador." : "Na unidade, preencha o endere\xE7o e capture a localiza\xE7\xE3o deste dispositivo." }),
|
|
22676
|
+
form.latitude && form.longitude ? /* @__PURE__ */ jsxs("dl", { className: "mt-2 flex flex-wrap gap-x-5 gap-y-1 text-xs", children: [
|
|
22677
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
|
|
22678
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: "Latitude" }),
|
|
22679
|
+
/* @__PURE__ */ jsx("dd", { className: "font-medium tabular-nums", children: form.latitude })
|
|
22680
|
+
] }),
|
|
22681
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-1.5", children: [
|
|
22682
|
+
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: "Longitude" }),
|
|
22683
|
+
/* @__PURE__ */ jsx("dd", { className: "font-medium tabular-nums", children: form.longitude })
|
|
22684
|
+
] })
|
|
22685
|
+
] }) : null
|
|
22686
|
+
] }),
|
|
22687
|
+
/* @__PURE__ */ jsxs(
|
|
22688
|
+
Button,
|
|
22689
|
+
{
|
|
22690
|
+
type: "button",
|
|
22691
|
+
variant: "outline",
|
|
22692
|
+
size: "sm",
|
|
22693
|
+
className: "shrink-0",
|
|
22694
|
+
disabled: !canSave || geocoding,
|
|
22695
|
+
onClick: () => void handleGeocode(),
|
|
22696
|
+
children: [
|
|
22697
|
+
geocoding ? /* @__PURE__ */ jsx(Loader2, { className: "mr-1.5 h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx(MapPin, { className: "mr-1.5 h-3.5 w-3.5" }),
|
|
22698
|
+
geocoding ? "Localizando\u2026" : "Atualizar coordenadas"
|
|
22699
|
+
]
|
|
22700
|
+
}
|
|
22701
|
+
)
|
|
22702
|
+
] }) }) : null,
|
|
22652
22703
|
!single && /* @__PURE__ */ jsxs("label", { className: "col-span-2 flex items-center gap-2 text-sm", children: [
|
|
22653
22704
|
/* @__PURE__ */ jsx(
|
|
22654
22705
|
"input",
|
|
@@ -23117,12 +23168,12 @@ function CrudRecordModal({
|
|
|
23117
23168
|
essentialFirst,
|
|
23118
23169
|
notice
|
|
23119
23170
|
}) {
|
|
23120
|
-
const [record, setRecord] =
|
|
23121
|
-
const [loading, setLoading] =
|
|
23122
|
-
const [saving, setSaving] =
|
|
23123
|
-
const [error, setError] =
|
|
23124
|
-
const formId =
|
|
23125
|
-
|
|
23171
|
+
const [record, setRecord] = React126.useState(null);
|
|
23172
|
+
const [loading, setLoading] = React126.useState(false);
|
|
23173
|
+
const [saving, setSaving] = React126.useState(false);
|
|
23174
|
+
const [error, setError] = React126.useState(null);
|
|
23175
|
+
const formId = React126.useId();
|
|
23176
|
+
React126.useEffect(() => {
|
|
23126
23177
|
if (!open) return;
|
|
23127
23178
|
setError(null);
|
|
23128
23179
|
if (mode === "create" || !load) {
|
|
@@ -23291,7 +23342,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23291
23342
|
const fkColumn = columnOf(related.entity, related.foreignKey);
|
|
23292
23343
|
const label3 = related.label ?? related.entity.namePlural ?? related.entity.name;
|
|
23293
23344
|
const Icon = related.icon ? ICON_MAP[related.icon] ?? null : null;
|
|
23294
|
-
const child =
|
|
23345
|
+
const child = React126.useMemo(() => ({
|
|
23295
23346
|
...related.entity,
|
|
23296
23347
|
fields: related.entity.fields.filter((f) => f.key !== related.foreignKey),
|
|
23297
23348
|
data: related.entity.data ? {
|
|
@@ -23300,12 +23351,12 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23300
23351
|
defaults: { ...related.entity.data.defaults ?? {}, [fkColumn]: parentId }
|
|
23301
23352
|
} : void 0
|
|
23302
23353
|
}), [related, parentId, fkColumn]);
|
|
23303
|
-
const provider2 =
|
|
23304
|
-
const [rows, setRows] =
|
|
23305
|
-
const [loading, setLoading] =
|
|
23306
|
-
const [error, setError] =
|
|
23307
|
-
const [adding, setAdding] =
|
|
23308
|
-
const load =
|
|
23354
|
+
const provider2 = React126.useMemo(() => resolveDataProvider(child, [], { cache: false }), [child]);
|
|
23355
|
+
const [rows, setRows] = React126.useState([]);
|
|
23356
|
+
const [loading, setLoading] = React126.useState(true);
|
|
23357
|
+
const [error, setError] = React126.useState(null);
|
|
23358
|
+
const [adding, setAdding] = React126.useState(false);
|
|
23359
|
+
const load = React126.useCallback(async () => {
|
|
23309
23360
|
setLoading(true);
|
|
23310
23361
|
try {
|
|
23311
23362
|
const result = await provider2.list({ page: 1, pageSize: 100 });
|
|
@@ -23317,7 +23368,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23317
23368
|
setLoading(false);
|
|
23318
23369
|
}
|
|
23319
23370
|
}, [provider2]);
|
|
23320
|
-
|
|
23371
|
+
React126.useEffect(() => {
|
|
23321
23372
|
void load();
|
|
23322
23373
|
}, [load]);
|
|
23323
23374
|
async function remove(id) {
|
|
@@ -23920,7 +23971,7 @@ function SubjectFormLayout({ fields, allFields, fieldGroups, values, onChange, r
|
|
|
23920
23971
|
const IconComponent = getLucideIcon(entityIcon ?? "Heart") ?? Heart;
|
|
23921
23972
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
23922
23973
|
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: "pt-5", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-5", children: [
|
|
23923
|
-
/* @__PURE__ */ jsx("div", { className: "flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary", children:
|
|
23974
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: React126__default.createElement(IconComponent, { className: "h-8 w-8" }) }),
|
|
23924
23975
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-4", children: [
|
|
23925
23976
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-4", children: [
|
|
23926
23977
|
nameField && /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-1.5", children: [
|
|
@@ -24636,14 +24687,14 @@ function ImageSlot({
|
|
|
24636
24687
|
onDraftFile
|
|
24637
24688
|
}) {
|
|
24638
24689
|
const t = useTranslation();
|
|
24639
|
-
const inputRef =
|
|
24640
|
-
const [url, setUrl] =
|
|
24641
|
-
const [busy, setBusy] =
|
|
24642
|
-
const [error, setError] =
|
|
24643
|
-
const draftUrlRef =
|
|
24690
|
+
const inputRef = React126__default.useRef(null);
|
|
24691
|
+
const [url, setUrl] = React126__default.useState(() => image.get(row));
|
|
24692
|
+
const [busy, setBusy] = React126__default.useState(false);
|
|
24693
|
+
const [error, setError] = React126__default.useState(null);
|
|
24694
|
+
const draftUrlRef = React126__default.useRef(null);
|
|
24644
24695
|
const currentUrl = image.get(row);
|
|
24645
24696
|
const draftFile = image.draftField ? row[image.draftField] : void 0;
|
|
24646
|
-
|
|
24697
|
+
React126__default.useEffect(() => {
|
|
24647
24698
|
if (draftFile) return;
|
|
24648
24699
|
if (draftUrlRef.current) {
|
|
24649
24700
|
URL.revokeObjectURL(draftUrlRef.current);
|
|
@@ -24651,7 +24702,7 @@ function ImageSlot({
|
|
|
24651
24702
|
}
|
|
24652
24703
|
setUrl(currentUrl);
|
|
24653
24704
|
}, [currentUrl, draftFile]);
|
|
24654
|
-
|
|
24705
|
+
React126__default.useEffect(() => () => {
|
|
24655
24706
|
if (draftUrlRef.current) URL.revokeObjectURL(draftUrlRef.current);
|
|
24656
24707
|
}, []);
|
|
24657
24708
|
const acceptsDraft = !canEdit && Boolean(image.draftField && onDraftFile);
|
|
@@ -24797,7 +24848,7 @@ function CrudFormPage({ entityDef, mode, initialData, onSubmit, onCancel, namePl
|
|
|
24797
24848
|
const [values, setValues] = useState(computeInit);
|
|
24798
24849
|
const [saving, setSaving] = useState(false);
|
|
24799
24850
|
const [invalidKeys, setInvalidKeys] = useState(EMPTY_KEYS);
|
|
24800
|
-
const initialRef =
|
|
24851
|
+
const initialRef = React126__default.useRef(JSON.stringify(values));
|
|
24801
24852
|
useEffect(() => {
|
|
24802
24853
|
const init = computeInit();
|
|
24803
24854
|
setValues(init);
|
|
@@ -24845,7 +24896,7 @@ function CrudFormPage({ entityDef, mode, initialData, onSubmit, onCancel, namePl
|
|
|
24845
24896
|
if (submitRef) submitRef.current = () => {
|
|
24846
24897
|
void submit();
|
|
24847
24898
|
};
|
|
24848
|
-
|
|
24899
|
+
React126__default.useEffect(() => () => {
|
|
24849
24900
|
if (submitRef) submitRef.current = null;
|
|
24850
24901
|
}, [submitRef]);
|
|
24851
24902
|
const dirty = JSON.stringify(values) !== initialRef.current;
|
|
@@ -25362,16 +25413,16 @@ function useUnitFilter(options = {}) {
|
|
|
25362
25413
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
25363
25414
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
25364
25415
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
25365
|
-
const reachable =
|
|
25366
|
-
const [local2, setLocal] =
|
|
25367
|
-
|
|
25416
|
+
const reachable = React126.useMemo(() => unitFilterOptions(units, myUnitIds), [units, myUnitIds]);
|
|
25417
|
+
const [local2, setLocal] = React126.useState(activeUnitId);
|
|
25418
|
+
React126.useEffect(() => {
|
|
25368
25419
|
setLocal(activeUnitId);
|
|
25369
25420
|
}, [activeUnitId]);
|
|
25370
25421
|
const raw = scope === "global" ? activeUnitId : local2;
|
|
25371
25422
|
const value = standableUnit(raw, reachable);
|
|
25372
25423
|
const filterLabel = label(t, "units.filterLabel", "Unidade");
|
|
25373
25424
|
const allLabel = label(t, "units.filterAll", "Todas as minhas unidades");
|
|
25374
|
-
const setValue =
|
|
25425
|
+
const setValue = React126.useCallback((next) => {
|
|
25375
25426
|
if (scope === "global") {
|
|
25376
25427
|
if (next === activeUnitId) return;
|
|
25377
25428
|
beginSwitch({ unitId: next, unitName: next ? byId[next]?.name ?? "" : allLabel });
|
|
@@ -25380,7 +25431,7 @@ function useUnitFilter(options = {}) {
|
|
|
25380
25431
|
setLocal(next);
|
|
25381
25432
|
}, [scope, activeUnitId, beginSwitch, byId, allLabel]);
|
|
25382
25433
|
const visible = unitFilterVisible(unitMode, reachable);
|
|
25383
|
-
const def =
|
|
25434
|
+
const def = React126.useMemo(() => visible ? {
|
|
25384
25435
|
id: "unit",
|
|
25385
25436
|
label: filterLabel,
|
|
25386
25437
|
icon: Building2,
|
|
@@ -25516,7 +25567,7 @@ function CrudListView({
|
|
|
25516
25567
|
if (onImport) {
|
|
25517
25568
|
createRoutes.push({ id: "import", label: t("crud.import.action"), description: t("crud.import.hint"), icon: "Upload", action: onImport });
|
|
25518
25569
|
}
|
|
25519
|
-
const createActions =
|
|
25570
|
+
const createActions = React126__default.useMemo(() => {
|
|
25520
25571
|
const out = createRoutes.map((qa, i) => ({
|
|
25521
25572
|
id: qa.id,
|
|
25522
25573
|
label: qa.label,
|
|
@@ -25926,9 +25977,9 @@ function buildCrudSurfaceContribution(read3) {
|
|
|
25926
25977
|
};
|
|
25927
25978
|
}
|
|
25928
25979
|
function CrudAgentSurface(props) {
|
|
25929
|
-
const ref =
|
|
25980
|
+
const ref = React126.useRef(props);
|
|
25930
25981
|
ref.current = props;
|
|
25931
|
-
const contribution =
|
|
25982
|
+
const contribution = React126.useMemo(
|
|
25932
25983
|
() => buildCrudSurfaceContribution(() => ref.current),
|
|
25933
25984
|
[]
|
|
25934
25985
|
);
|
|
@@ -25981,7 +26032,7 @@ function useFieldRules(entityKey) {
|
|
|
25981
26032
|
};
|
|
25982
26033
|
}, [entityKey, fieldRules]);
|
|
25983
26034
|
}
|
|
25984
|
-
var ImportWizard2 =
|
|
26035
|
+
var ImportWizard2 = React126__default.lazy(
|
|
25985
26036
|
() => import('./ImportWizard-7UFB2PPF.js').then((m) => ({ default: m.ImportWizard }))
|
|
25986
26037
|
);
|
|
25987
26038
|
var PAGE_SIZE = 50;
|
|
@@ -26342,6 +26393,9 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
26342
26393
|
},
|
|
26343
26394
|
onDelete: readOnly ? void 0 : () => setDeleteItem(item),
|
|
26344
26395
|
onFieldSave: readOnly ? void 0 : (key, value) => handleInlineUpdate(item.id, key, value),
|
|
26396
|
+
onFieldsSave: readOnly ? void 0 : async (values) => {
|
|
26397
|
+
await store.update(item.id, values);
|
|
26398
|
+
},
|
|
26345
26399
|
feature
|
|
26346
26400
|
}
|
|
26347
26401
|
);
|
|
@@ -26509,7 +26563,7 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
26509
26563
|
mode: softDelete ? "deactivate" : "delete"
|
|
26510
26564
|
}
|
|
26511
26565
|
),
|
|
26512
|
-
/* @__PURE__ */ jsx(
|
|
26566
|
+
/* @__PURE__ */ jsx(React126__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
26513
26567
|
ImportWizard2,
|
|
26514
26568
|
{
|
|
26515
26569
|
open: importOpen,
|
|
@@ -26850,7 +26904,7 @@ function columnOf2(entity, key) {
|
|
|
26850
26904
|
function RelatedListTab({ item, related }) {
|
|
26851
26905
|
const parentId = item?.id;
|
|
26852
26906
|
const pathname = useHashPath();
|
|
26853
|
-
const Page =
|
|
26907
|
+
const Page = React126.useMemo(() => {
|
|
26854
26908
|
if (!parentId) return null;
|
|
26855
26909
|
const child = related.entity;
|
|
26856
26910
|
const fkColumn = columnOf2(child, related.foreignKey);
|
|
@@ -26881,8 +26935,8 @@ function tabBasePath(pathname, tabId) {
|
|
|
26881
26935
|
}
|
|
26882
26936
|
function useHashPath() {
|
|
26883
26937
|
const read3 = () => typeof window === "undefined" ? "/" : window.location.hash.slice(1) || "/";
|
|
26884
|
-
const [path, setPath] =
|
|
26885
|
-
|
|
26938
|
+
const [path, setPath] = React126.useState(read3);
|
|
26939
|
+
React126.useEffect(() => {
|
|
26886
26940
|
const handler = () => setPath(read3());
|
|
26887
26941
|
window.addEventListener("hashchange", handler);
|
|
26888
26942
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -26966,30 +27020,30 @@ function AccessTab({ item }) {
|
|
|
26966
27020
|
const hasSystemPermission = useSystemPermission();
|
|
26967
27021
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
26968
27022
|
const guardSeats = useLimitGuard("users");
|
|
26969
|
-
const [access, setAccess] =
|
|
26970
|
-
const [email, setEmail] =
|
|
26971
|
-
const [roleId, setRoleId] =
|
|
26972
|
-
const [busy, setBusy] =
|
|
26973
|
-
const [confirmRemove, setConfirmRemove] =
|
|
26974
|
-
|
|
27023
|
+
const [access, setAccess] = React126.useState(void 0);
|
|
27024
|
+
const [email, setEmail] = React126.useState(person?.email ?? "");
|
|
27025
|
+
const [roleId, setRoleId] = React126.useState("");
|
|
27026
|
+
const [busy, setBusy] = React126.useState(false);
|
|
27027
|
+
const [confirmRemove, setConfirmRemove] = React126.useState(false);
|
|
27028
|
+
React126.useEffect(() => {
|
|
26975
27029
|
if (!roleId && profiles.length) setRoleId(profiles[1]?.id ?? profiles[0].id);
|
|
26976
27030
|
}, [profiles, roleId]);
|
|
26977
|
-
|
|
27031
|
+
React126.useEffect(() => {
|
|
26978
27032
|
setEmail(person?.email ?? "");
|
|
26979
27033
|
}, [person?.email]);
|
|
26980
|
-
const reload =
|
|
27034
|
+
const reload = React126.useCallback(async () => {
|
|
26981
27035
|
if (!personId) return;
|
|
26982
27036
|
setAccess(await fetchPersonAccess(personId));
|
|
26983
27037
|
}, [personId]);
|
|
26984
|
-
|
|
27038
|
+
React126.useEffect(() => {
|
|
26985
27039
|
void reload();
|
|
26986
27040
|
}, [reload]);
|
|
26987
|
-
|
|
27041
|
+
React126.useEffect(() => {
|
|
26988
27042
|
if (!adapter || !currentOrg || invites.length > 0) return;
|
|
26989
27043
|
adapter.listInvites(currentOrg.id).then(setInvites).catch(() => {
|
|
26990
27044
|
});
|
|
26991
27045
|
}, [adapter, currentOrg?.id]);
|
|
26992
|
-
const pendingInvite =
|
|
27046
|
+
const pendingInvite = React126.useMemo(() => {
|
|
26993
27047
|
const target = (person?.email ?? "").trim().toLowerCase();
|
|
26994
27048
|
if (!target) return void 0;
|
|
26995
27049
|
return invites.find((i) => i.status === "pending" && i.email.toLowerCase() === target);
|
|
@@ -27203,11 +27257,11 @@ function PersonUnitsTab({ item }) {
|
|
|
27203
27257
|
const units = useUnitStore((s) => s.units);
|
|
27204
27258
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
27205
27259
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
27206
|
-
const [userId, setUserId] =
|
|
27207
|
-
const [bindings, setBindings] =
|
|
27208
|
-
const [busy, setBusy] =
|
|
27260
|
+
const [userId, setUserId] = React126.useState(void 0);
|
|
27261
|
+
const [bindings, setBindings] = React126.useState({});
|
|
27262
|
+
const [busy, setBusy] = React126.useState(null);
|
|
27209
27263
|
const bindingsVersion = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
27210
|
-
|
|
27264
|
+
React126.useEffect(() => {
|
|
27211
27265
|
if (!personId) return;
|
|
27212
27266
|
let alive = true;
|
|
27213
27267
|
void fetchUserIdForPerson(personId).then((uid2) => {
|
|
@@ -27217,11 +27271,11 @@ function PersonUnitsTab({ item }) {
|
|
|
27217
27271
|
alive = false;
|
|
27218
27272
|
};
|
|
27219
27273
|
}, [personId]);
|
|
27220
|
-
const reload =
|
|
27274
|
+
const reload = React126.useCallback(async (uid2) => {
|
|
27221
27275
|
const rows = await fetchMemberUnits(uid2);
|
|
27222
27276
|
setBindings(Object.fromEntries(rows.map((r) => [r.locationId, r.role])));
|
|
27223
27277
|
}, []);
|
|
27224
|
-
|
|
27278
|
+
React126.useEffect(() => {
|
|
27225
27279
|
if (userId) void reload(userId);
|
|
27226
27280
|
}, [userId, reload, bindingsVersion]);
|
|
27227
27281
|
async function toggle(unitId, on) {
|
|
@@ -27319,13 +27373,13 @@ function PersonUnitsTab({ item }) {
|
|
|
27319
27373
|
function PersonAvailabilityTab({ item }) {
|
|
27320
27374
|
const person = item;
|
|
27321
27375
|
const personId = person?.id;
|
|
27322
|
-
const [units, setUnits] =
|
|
27323
|
-
const [selected, setSelected] =
|
|
27324
|
-
const [loading, setLoading] =
|
|
27325
|
-
const [busy, setBusy] =
|
|
27326
|
-
const [availabilityReady, setAvailabilityReady] =
|
|
27376
|
+
const [units, setUnits] = React126.useState([]);
|
|
27377
|
+
const [selected, setSelected] = React126.useState(/* @__PURE__ */ new Set());
|
|
27378
|
+
const [loading, setLoading] = React126.useState(true);
|
|
27379
|
+
const [busy, setBusy] = React126.useState(false);
|
|
27380
|
+
const [availabilityReady, setAvailabilityReady] = React126.useState(true);
|
|
27327
27381
|
const db2 = () => getSupabaseClientOptional();
|
|
27328
|
-
const load =
|
|
27382
|
+
const load = React126.useCallback(async () => {
|
|
27329
27383
|
const client3 = db2();
|
|
27330
27384
|
if (!client3 || !personId) {
|
|
27331
27385
|
setLoading(false);
|
|
@@ -27354,7 +27408,7 @@ function PersonAvailabilityTab({ item }) {
|
|
|
27354
27408
|
setLoading(false);
|
|
27355
27409
|
}
|
|
27356
27410
|
}, [personId]);
|
|
27357
|
-
|
|
27411
|
+
React126.useEffect(() => {
|
|
27358
27412
|
void load();
|
|
27359
27413
|
}, [load]);
|
|
27360
27414
|
async function makeOrganizationWide() {
|
|
@@ -27432,10 +27486,10 @@ function PersonAvailabilityTab({ item }) {
|
|
|
27432
27486
|
/* @__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." })
|
|
27433
27487
|
] }) });
|
|
27434
27488
|
}
|
|
27435
|
-
var ScheduleEditor2 =
|
|
27489
|
+
var ScheduleEditor2 = React126__default.lazy(
|
|
27436
27490
|
() => import('./ScheduleEditor-AWG3QNDS.js').then((m) => ({ default: m.ScheduleEditor }))
|
|
27437
27491
|
);
|
|
27438
|
-
var PersonTimeline2 =
|
|
27492
|
+
var PersonTimeline2 = React126__default.lazy(
|
|
27439
27493
|
() => import('./timeline-LECYQ4IA.js').then((m) => ({ default: m.PersonTimeline }))
|
|
27440
27494
|
);
|
|
27441
27495
|
function ComingSoon({ icon: Icon, title, description }) {
|
|
@@ -27459,7 +27513,7 @@ function ActivityTab({ item, recordPath }) {
|
|
|
27459
27513
|
}
|
|
27460
27514
|
);
|
|
27461
27515
|
}
|
|
27462
|
-
return /* @__PURE__ */ jsx(
|
|
27516
|
+
return /* @__PURE__ */ jsx(React126__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(PersonTimeline2, { personId: item.id, recordPath }) });
|
|
27463
27517
|
}
|
|
27464
27518
|
function DocumentsTab({ item }) {
|
|
27465
27519
|
const t = useTranslation();
|
|
@@ -27571,7 +27625,7 @@ function ScheduleTab({ item }) {
|
|
|
27571
27625
|
return (
|
|
27572
27626
|
// O interruptor "Aparece na agenda" agora vem DENTRO do editor: era a
|
|
27573
27627
|
// única coisa que esta porta mostrava e a da agenda não.
|
|
27574
|
-
/* @__PURE__ */ jsx(
|
|
27628
|
+
/* @__PURE__ */ jsx(React126__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(ScheduleEditor2, { assigneeId: item.id }) })
|
|
27575
27629
|
);
|
|
27576
27630
|
}
|
|
27577
27631
|
var PERSON_DETAIL_TABS = [
|
|
@@ -28053,11 +28107,12 @@ function InlineEditor({
|
|
|
28053
28107
|
field,
|
|
28054
28108
|
value,
|
|
28055
28109
|
onCancel,
|
|
28056
|
-
onSave
|
|
28110
|
+
onSave,
|
|
28111
|
+
cancelLabel = "Cancel"
|
|
28057
28112
|
}) {
|
|
28058
28113
|
const [draft, setDraft] = useState(value ?? "");
|
|
28059
28114
|
const [saving, setSaving] = useState(false);
|
|
28060
|
-
const inputRef =
|
|
28115
|
+
const inputRef = React126__default.useRef(null);
|
|
28061
28116
|
useEffect(() => {
|
|
28062
28117
|
inputRef.current?.focus();
|
|
28063
28118
|
if (inputRef.current instanceof HTMLInputElement) inputRef.current.select();
|
|
@@ -28098,8 +28153,12 @@ function InlineEditor({
|
|
|
28098
28153
|
"select",
|
|
28099
28154
|
{
|
|
28100
28155
|
value: String(draft ?? ""),
|
|
28101
|
-
onChange: (e) =>
|
|
28156
|
+
onChange: (e) => {
|
|
28157
|
+
setDraft(e.target.value);
|
|
28158
|
+
void onSave(e.target.value).then(onCancel);
|
|
28159
|
+
},
|
|
28102
28160
|
onKeyDown,
|
|
28161
|
+
onBlur: onCancel,
|
|
28103
28162
|
autoFocus: true,
|
|
28104
28163
|
className: "h-8 min-w-0 flex-1 rounded-input border border-input bg-background px-2 text-sm",
|
|
28105
28164
|
children: [
|
|
@@ -28114,6 +28173,7 @@ function InlineEditor({
|
|
|
28114
28173
|
value: String(draft ?? ""),
|
|
28115
28174
|
onChange: (e) => setDraft(e.target.value),
|
|
28116
28175
|
onKeyDown,
|
|
28176
|
+
onBlur: () => void commit(),
|
|
28117
28177
|
rows: 3,
|
|
28118
28178
|
className: "min-w-0 flex-1 rounded-input border border-input bg-background px-2 py-1.5 text-sm"
|
|
28119
28179
|
}
|
|
@@ -28125,13 +28185,24 @@ function InlineEditor({
|
|
|
28125
28185
|
value: String(draft ?? ""),
|
|
28126
28186
|
onChange: (e) => setDraft(e.target.value),
|
|
28127
28187
|
onKeyDown,
|
|
28188
|
+
onBlur: () => void commit(),
|
|
28128
28189
|
className: "h-8 min-w-0 flex-1 text-sm"
|
|
28129
28190
|
}
|
|
28130
28191
|
),
|
|
28131
|
-
field.type !== "boolean" && /* @__PURE__ */
|
|
28132
|
-
|
|
28133
|
-
|
|
28134
|
-
|
|
28192
|
+
field.type !== "boolean" && field.type !== "select" && /* @__PURE__ */ jsx(
|
|
28193
|
+
Button,
|
|
28194
|
+
{
|
|
28195
|
+
variant: "ghost",
|
|
28196
|
+
size: "sm",
|
|
28197
|
+
className: "h-7 w-7 shrink-0 p-0",
|
|
28198
|
+
"aria-label": cancelLabel,
|
|
28199
|
+
title: cancelLabel,
|
|
28200
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
28201
|
+
onClick: onCancel,
|
|
28202
|
+
disabled: saving,
|
|
28203
|
+
children: saving ? /* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
28204
|
+
}
|
|
28205
|
+
)
|
|
28135
28206
|
] });
|
|
28136
28207
|
}
|
|
28137
28208
|
function FieldRow({
|
|
@@ -28140,15 +28211,25 @@ function FieldRow({
|
|
|
28140
28211
|
row,
|
|
28141
28212
|
t,
|
|
28142
28213
|
compact,
|
|
28143
|
-
onSave
|
|
28214
|
+
onSave,
|
|
28215
|
+
pending: pending2
|
|
28144
28216
|
}) {
|
|
28145
28217
|
const [editing, setEditing] = useState(false);
|
|
28146
28218
|
const editable = !!onSave && isInlineEditable(field);
|
|
28147
28219
|
const label3 = field.labelWhen && field.labelWhen(row ?? {}) || field.label;
|
|
28148
28220
|
return /* @__PURE__ */ jsxs("div", { className: `group grid grid-cols-3 gap-4 ${compact ? "py-1.5" : "py-3"}`, children: [
|
|
28149
28221
|
/* @__PURE__ */ jsx("dt", { className: `font-medium text-muted-foreground ${compact ? "text-xs" : "text-sm"}`, children: label3 }),
|
|
28150
|
-
/* @__PURE__ */ jsx("dd", { className: `col-span-2 flex items-center gap-2 text-foreground ${compact ? "text-xs" : "text-sm"}`, children: editing && onSave ? /* @__PURE__ */ jsx(
|
|
28151
|
-
|
|
28222
|
+
/* @__PURE__ */ jsx("dd", { className: `col-span-2 flex items-center gap-2 text-foreground ${compact ? "text-xs" : "text-sm"}`, children: editing && onSave ? /* @__PURE__ */ jsx(
|
|
28223
|
+
InlineEditor,
|
|
28224
|
+
{
|
|
28225
|
+
field,
|
|
28226
|
+
value,
|
|
28227
|
+
onCancel: () => setEditing(false),
|
|
28228
|
+
onSave,
|
|
28229
|
+
cancelLabel: t?.("common.cancel") ?? "Cancel"
|
|
28230
|
+
}
|
|
28231
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
28232
|
+
/* @__PURE__ */ jsx("span", { className: `min-w-0 ${pending2 ? "rounded-sm bg-warning/10 px-1 font-medium text-warning" : ""}`, children: formatValue3(field, value, t) }),
|
|
28152
28233
|
editable && /* @__PURE__ */ jsx(
|
|
28153
28234
|
"button",
|
|
28154
28235
|
{
|
|
@@ -28168,7 +28249,8 @@ function FieldGroupSection({
|
|
|
28168
28249
|
fields,
|
|
28169
28250
|
item,
|
|
28170
28251
|
compact,
|
|
28171
|
-
onFieldSave
|
|
28252
|
+
onFieldSave,
|
|
28253
|
+
pendingKeys
|
|
28172
28254
|
}) {
|
|
28173
28255
|
const tFn = useTranslation();
|
|
28174
28256
|
const cols = group.columns ?? 2;
|
|
@@ -28185,7 +28267,8 @@ function FieldGroupSection({
|
|
|
28185
28267
|
row: item,
|
|
28186
28268
|
t: tFn,
|
|
28187
28269
|
compact,
|
|
28188
|
-
onSave: onFieldSave ? (next) => Promise.resolve(onFieldSave(field.key, next)) : void 0
|
|
28270
|
+
onSave: onFieldSave ? (next) => Promise.resolve(onFieldSave(field.key, next)) : void 0,
|
|
28271
|
+
pending: pendingKeys?.has(field.key)
|
|
28189
28272
|
}
|
|
28190
28273
|
) }, field.key)) }) }) })
|
|
28191
28274
|
] });
|
|
@@ -28199,7 +28282,8 @@ function OverviewTab({
|
|
|
28199
28282
|
entityDef,
|
|
28200
28283
|
item,
|
|
28201
28284
|
compact,
|
|
28202
|
-
onFieldSave
|
|
28285
|
+
onFieldSave,
|
|
28286
|
+
pendingKeys
|
|
28203
28287
|
}) {
|
|
28204
28288
|
const tFn = useTranslation();
|
|
28205
28289
|
const detailFields = visibleDetailFields(entityDef, item);
|
|
@@ -28224,7 +28308,8 @@ function OverviewTab({
|
|
|
28224
28308
|
row: item,
|
|
28225
28309
|
t: tFn,
|
|
28226
28310
|
compact,
|
|
28227
|
-
onSave: onFieldSave ? (next) => Promise.resolve(onFieldSave(field.key, next)) : void 0
|
|
28311
|
+
onSave: onFieldSave ? (next) => Promise.resolve(onFieldSave(field.key, next)) : void 0,
|
|
28312
|
+
pending: pendingKeys?.has(field.key)
|
|
28228
28313
|
}
|
|
28229
28314
|
) }, field.key)) }) }) }),
|
|
28230
28315
|
bodyGroups.map((group) => {
|
|
@@ -28237,7 +28322,8 @@ function OverviewTab({
|
|
|
28237
28322
|
fields,
|
|
28238
28323
|
item,
|
|
28239
28324
|
compact,
|
|
28240
|
-
onFieldSave
|
|
28325
|
+
onFieldSave,
|
|
28326
|
+
pendingKeys
|
|
28241
28327
|
},
|
|
28242
28328
|
group.id
|
|
28243
28329
|
);
|
|
@@ -28251,7 +28337,8 @@ function OverviewTab({
|
|
|
28251
28337
|
fields,
|
|
28252
28338
|
item,
|
|
28253
28339
|
compact,
|
|
28254
|
-
onFieldSave
|
|
28340
|
+
onFieldSave,
|
|
28341
|
+
pendingKeys
|
|
28255
28342
|
},
|
|
28256
28343
|
groupId
|
|
28257
28344
|
);
|
|
@@ -28269,7 +28356,8 @@ function OverviewTab({
|
|
|
28269
28356
|
fields: groupFieldMap.get(group.id),
|
|
28270
28357
|
item,
|
|
28271
28358
|
compact,
|
|
28272
|
-
onFieldSave
|
|
28359
|
+
onFieldSave,
|
|
28360
|
+
pendingKeys
|
|
28273
28361
|
},
|
|
28274
28362
|
group.id
|
|
28275
28363
|
)) })
|
|
@@ -28351,23 +28439,64 @@ function CrudDetailPage({
|
|
|
28351
28439
|
feature,
|
|
28352
28440
|
embedded,
|
|
28353
28441
|
onFieldSave,
|
|
28442
|
+
onFieldsSave,
|
|
28354
28443
|
badges,
|
|
28355
28444
|
onImageChange,
|
|
28356
28445
|
extraActions
|
|
28357
28446
|
}) {
|
|
28358
28447
|
const t = useTranslation();
|
|
28448
|
+
const [pending2, setPending] = useState({});
|
|
28449
|
+
const [savingDraft, setSavingDraft] = useState(false);
|
|
28450
|
+
const pendingKeys = React126__default.useMemo(() => new Set(Object.keys(pending2)), [pending2]);
|
|
28451
|
+
const dirty = pendingKeys.size > 0;
|
|
28452
|
+
const view = React126__default.useMemo(
|
|
28453
|
+
() => dirty ? { ...item, ...pending2 } : item,
|
|
28454
|
+
[item, pending2, dirty]
|
|
28455
|
+
);
|
|
28456
|
+
const stageField = useCallback((key, value) => {
|
|
28457
|
+
setPending((prev) => {
|
|
28458
|
+
const next = { ...prev, [key]: value };
|
|
28459
|
+
const original = item[key];
|
|
28460
|
+
if ((value ?? "") === (original ?? "")) delete next[key];
|
|
28461
|
+
return next;
|
|
28462
|
+
});
|
|
28463
|
+
}, [item]);
|
|
28464
|
+
const commitDraft = useCallback(async () => {
|
|
28465
|
+
const changes = pending2;
|
|
28466
|
+
if (Object.keys(changes).length === 0 || savingDraft) return;
|
|
28467
|
+
setSavingDraft(true);
|
|
28468
|
+
try {
|
|
28469
|
+
if (onFieldsSave) await onFieldsSave(changes);
|
|
28470
|
+
else if (onFieldSave) {
|
|
28471
|
+
for (const [key, value] of Object.entries(changes)) await onFieldSave(key, value);
|
|
28472
|
+
}
|
|
28473
|
+
setPending({});
|
|
28474
|
+
} catch (err) {
|
|
28475
|
+
toast.error(errorMessage(err));
|
|
28476
|
+
} finally {
|
|
28477
|
+
setSavingDraft(false);
|
|
28478
|
+
}
|
|
28479
|
+
}, [pending2, savingDraft, onFieldsSave, onFieldSave]);
|
|
28480
|
+
useSaveBar({
|
|
28481
|
+
dirty,
|
|
28482
|
+
saving: savingDraft,
|
|
28483
|
+
onSave: () => {
|
|
28484
|
+
void commitDraft();
|
|
28485
|
+
},
|
|
28486
|
+
onDiscard: () => setPending({})
|
|
28487
|
+
});
|
|
28359
28488
|
const displayField = entityDef.displayField ?? entityDef.fields[0]?.key ?? "id";
|
|
28360
|
-
const displayValue =
|
|
28361
|
-
const subtitleValue = entityDef.subtitleField ?
|
|
28489
|
+
const displayValue = view[displayField] ?? "Untitled";
|
|
28490
|
+
const subtitleValue = entityDef.subtitleField ? view[entityDef.subtitleField] : null;
|
|
28362
28491
|
const imageValue = entityDef.image?.get(item) ?? (entityDef.imageField ? item[entityDef.imageField] : null);
|
|
28363
|
-
const activeValue =
|
|
28492
|
+
const activeValue = view.isActive ?? view.is_active;
|
|
28364
28493
|
const initial = typeof displayValue === "string" ? displayValue.charAt(0).toUpperCase() : "?";
|
|
28365
28494
|
const myPersonId = useMyPersonId(entityDef.layout === "person");
|
|
28366
28495
|
const isMyRecord = Boolean(myPersonId) && myPersonId === item.id;
|
|
28367
28496
|
const displayFieldDef = entityDef.fields.find((f) => f.key === displayField);
|
|
28368
|
-
const nameEditable = Boolean(onFieldSave) && Boolean(displayFieldDef) && isInlineEditable(displayFieldDef);
|
|
28497
|
+
const nameEditable = Boolean(onFieldSave || onFieldsSave) && Boolean(displayFieldDef) && isInlineEditable(displayFieldDef);
|
|
28369
28498
|
const [editingName, setEditingName] = useState(false);
|
|
28370
|
-
const imageInputRef =
|
|
28499
|
+
const imageInputRef = React126__default.useRef(null);
|
|
28371
28500
|
const runtime = usePluginRuntimeOptional();
|
|
28372
28501
|
const archetypeTabs = getArchetypeTabs(entityDef.layout, entityDef.data?.archetypeKind);
|
|
28373
28502
|
const relatedTabs = (entityDef.relatedLists ?? []).map((related) => ({
|
|
@@ -28433,7 +28562,7 @@ function CrudDetailPage({
|
|
|
28433
28562
|
window.history.replaceState(null, "", `#${segments.length ? `${base}/${segments.join("/")}` : base}`);
|
|
28434
28563
|
}, [basePath, item.id, selectedTab, embedded]);
|
|
28435
28564
|
const parentLabel = usePresetLabel(basePath, namePlural);
|
|
28436
|
-
const headerNode =
|
|
28565
|
+
const headerNode = React126__default.useMemo(
|
|
28437
28566
|
() => embedded ? null : /* @__PURE__ */ jsx(SubpageHeader, { title: displayValue, parentLabel, onBack }),
|
|
28438
28567
|
[embedded, displayValue, parentLabel, onBack]
|
|
28439
28568
|
);
|
|
@@ -28480,15 +28609,16 @@ function CrudDetailPage({
|
|
|
28480
28609
|
] })
|
|
28481
28610
|
] }),
|
|
28482
28611
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
28483
|
-
/* @__PURE__ */ jsx("div", { className: "group flex items-center gap-2", children: editingName &&
|
|
28612
|
+
/* @__PURE__ */ jsx("div", { className: "group flex items-center gap-2", children: editingName && nameEditable && displayFieldDef ? /* @__PURE__ */ jsx(
|
|
28484
28613
|
InlineEditor,
|
|
28485
28614
|
{
|
|
28486
28615
|
field: displayFieldDef,
|
|
28487
28616
|
value: displayValue,
|
|
28488
28617
|
onCancel: () => setEditingName(false),
|
|
28489
28618
|
onSave: async (next) => {
|
|
28490
|
-
|
|
28491
|
-
}
|
|
28619
|
+
stageField(displayField, next);
|
|
28620
|
+
},
|
|
28621
|
+
cancelLabel: t("common.cancel")
|
|
28492
28622
|
}
|
|
28493
28623
|
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
28494
28624
|
/* @__PURE__ */ jsx("h1", { className: `font-bold text-foreground truncate ${embedded ? "text-base" : "text-2xl"}`, children: displayValue }),
|
|
@@ -28564,7 +28694,16 @@ function CrudDetailPage({
|
|
|
28564
28694
|
})
|
|
28565
28695
|
] }),
|
|
28566
28696
|
/* @__PURE__ */ jsxs(TabsContent, { value: "overview", className: embedded ? "mt-2" : "mt-4", children: [
|
|
28567
|
-
entityDef.overviewComponent ?
|
|
28697
|
+
entityDef.overviewComponent ? React126__default.createElement(entityDef.overviewComponent, { item, entityDef }) : /* @__PURE__ */ jsx(
|
|
28698
|
+
OverviewTab,
|
|
28699
|
+
{
|
|
28700
|
+
entityDef,
|
|
28701
|
+
item: view,
|
|
28702
|
+
compact: embedded,
|
|
28703
|
+
onFieldSave: onFieldSave || onFieldsSave ? (key, value) => stageField(key, value) : void 0,
|
|
28704
|
+
pendingKeys
|
|
28705
|
+
}
|
|
28706
|
+
),
|
|
28568
28707
|
entityDef.layout === "person" && item?.id && /* @__PURE__ */ jsx("div", { className: embedded ? "mt-3" : "mt-5", children: /* @__PURE__ */ jsx(AddressesTab, { item }) }),
|
|
28569
28708
|
entityDef.layout === "person" && item?.id && /* @__PURE__ */ jsx("div", { className: embedded ? "mt-3" : "mt-5", children: /* @__PURE__ */ jsx(PayeeAccountsSection, { item }) }),
|
|
28570
28709
|
entityDef.layout === "location" && item?.id && /* @__PURE__ */ jsx("div", { className: embedded ? "mt-3" : "mt-5", children: /* @__PURE__ */ jsx(AddressesTab, { item, ownerType: "unit", single: true }) }),
|
|
@@ -28574,7 +28713,7 @@ function CrudDetailPage({
|
|
|
28574
28713
|
// `tabPath` only to the tab the URL is actually addressing —
|
|
28575
28714
|
// handing it to every tab would have the documents tab trying to
|
|
28576
28715
|
// open a recording id when the user switches across.
|
|
28577
|
-
|
|
28716
|
+
React126__default.createElement(tab.component, {
|
|
28578
28717
|
item,
|
|
28579
28718
|
entityDef,
|
|
28580
28719
|
// A rota DESTE registro. Uma aba que lista eventos precisa
|
|
@@ -28611,8 +28750,8 @@ function MyRecordPanel() {
|
|
|
28611
28750
|
const userId = useAuthStore((s) => s.user?.id);
|
|
28612
28751
|
const members = useOrganizationStore((s) => s.members);
|
|
28613
28752
|
const myRole = members.find((m) => m.userId === userId)?.profileName;
|
|
28614
|
-
const [state, setState] =
|
|
28615
|
-
const load =
|
|
28753
|
+
const [state, setState] = React126.useState({ status: "loading" });
|
|
28754
|
+
const load = React126.useCallback(async () => {
|
|
28616
28755
|
if (!orgId || !userId) return;
|
|
28617
28756
|
const person = await dedup(`self:record:${orgId}:${userId}`, () => fetchMyPersonRecord(orgId, userId));
|
|
28618
28757
|
if (!person) return setState({ status: "none" });
|
|
@@ -28629,10 +28768,10 @@ function MyRecordPanel() {
|
|
|
28629
28768
|
setState({ status: "none" });
|
|
28630
28769
|
}
|
|
28631
28770
|
}, [orgId, userId]);
|
|
28632
|
-
|
|
28771
|
+
React126.useEffect(() => {
|
|
28633
28772
|
void load();
|
|
28634
28773
|
}, [load]);
|
|
28635
|
-
const changePhoto =
|
|
28774
|
+
const changePhoto = React126.useCallback(async (file) => {
|
|
28636
28775
|
if (state.status !== "ready") return;
|
|
28637
28776
|
const supabase = getFayzSupabaseClientOptional();
|
|
28638
28777
|
if (!supabase) return;
|
|
@@ -28688,8 +28827,8 @@ function ConnectedUserProfile() {
|
|
|
28688
28827
|
const myPersonId = useMyPersonId();
|
|
28689
28828
|
const hasRecord = Boolean(myPersonId);
|
|
28690
28829
|
const setUser = useAuthStore((s) => s.setUser);
|
|
28691
|
-
const [profile, setProfile] =
|
|
28692
|
-
|
|
28830
|
+
const [profile, setProfile] = React126.useState(null);
|
|
28831
|
+
React126.useEffect(() => {
|
|
28693
28832
|
const supabase = getFayzSupabaseClientOptional();
|
|
28694
28833
|
if (!user || !supabase) return;
|
|
28695
28834
|
let cancelled = false;
|
|
@@ -28800,9 +28939,9 @@ function SecuritySettings({
|
|
|
28800
28939
|
onTenantSecurityChange
|
|
28801
28940
|
}) {
|
|
28802
28941
|
const { t } = useTranslation$1();
|
|
28803
|
-
const [resetting, setResetting] =
|
|
28804
|
-
const [resetSent, setResetSent] =
|
|
28805
|
-
const [savingTenant, setSavingTenant] =
|
|
28942
|
+
const [resetting, setResetting] = React126.useState(false);
|
|
28943
|
+
const [resetSent, setResetSent] = React126.useState(false);
|
|
28944
|
+
const [savingTenant, setSavingTenant] = React126.useState(false);
|
|
28806
28945
|
const handleResetPassword = async () => {
|
|
28807
28946
|
if (!onResetPassword) return;
|
|
28808
28947
|
setResetting(true);
|
|
@@ -28976,8 +29115,8 @@ function FileUploadField({
|
|
|
28976
29115
|
hint
|
|
28977
29116
|
}) {
|
|
28978
29117
|
const { t } = useTranslation$1();
|
|
28979
|
-
const inputRef =
|
|
28980
|
-
const [preview, setPreview] =
|
|
29118
|
+
const inputRef = React126.useRef(null);
|
|
29119
|
+
const [preview, setPreview] = React126.useState(null);
|
|
28981
29120
|
const handleChange = (e) => {
|
|
28982
29121
|
const file = e.target.files?.[0];
|
|
28983
29122
|
if (file) {
|
|
@@ -29199,13 +29338,13 @@ function SkinGate({ children }) {
|
|
|
29199
29338
|
}
|
|
29200
29339
|
function BrandingSettings({ brand, onSave }) {
|
|
29201
29340
|
const { t } = useTranslation$1();
|
|
29202
|
-
const [section, setSection] =
|
|
29203
|
-
const [saved, setSaved] =
|
|
29204
|
-
const [draft, setDraft] =
|
|
29205
|
-
const [logoFile, setLogoFile] =
|
|
29206
|
-
const [faviconFile, setFaviconFile] =
|
|
29207
|
-
const [saving, setSaving] =
|
|
29208
|
-
|
|
29341
|
+
const [section, setSection] = React126.useState("identity");
|
|
29342
|
+
const [saved, setSaved] = React126.useState(brand ?? EMPTY_BRAND);
|
|
29343
|
+
const [draft, setDraft] = React126.useState(brand ?? EMPTY_BRAND);
|
|
29344
|
+
const [logoFile, setLogoFile] = React126.useState(null);
|
|
29345
|
+
const [faviconFile, setFaviconFile] = React126.useState(null);
|
|
29346
|
+
const [saving, setSaving] = React126.useState(false);
|
|
29347
|
+
React126.useEffect(() => {
|
|
29209
29348
|
if (brand) {
|
|
29210
29349
|
setSaved(brand);
|
|
29211
29350
|
setDraft(brand);
|
|
@@ -29579,11 +29718,11 @@ function ConnectedBrandingSettings() {
|
|
|
29579
29718
|
toast.error("N\xE3o foi poss\xEDvel salvar a marca", { description: err?.message });
|
|
29580
29719
|
}
|
|
29581
29720
|
};
|
|
29582
|
-
const [brand, setBrand] =
|
|
29721
|
+
const [brand, setBrand] = React126.useState(() => normalizeBrand(
|
|
29583
29722
|
(currentOrg?.settings ?? {}).branding,
|
|
29584
29723
|
{ name: currentOrg?.name, logoUrl: currentOrg?.logoUrl }
|
|
29585
29724
|
));
|
|
29586
|
-
|
|
29725
|
+
React126.useEffect(() => {
|
|
29587
29726
|
let alive = true;
|
|
29588
29727
|
void (async () => {
|
|
29589
29728
|
try {
|
|
@@ -29704,12 +29843,12 @@ function ProjectsSettings() {
|
|
|
29704
29843
|
const projects = useFayzProjectsStore((s) => s.projects);
|
|
29705
29844
|
const load = useFayzProjectsStore((s) => s.load);
|
|
29706
29845
|
const refresh = useFayzProjectsStore((s) => s.refresh);
|
|
29707
|
-
const [linking, setLinking] =
|
|
29846
|
+
const [linking, setLinking] = React126.useState(false);
|
|
29708
29847
|
const connected = isPlatformConnected();
|
|
29709
|
-
|
|
29848
|
+
React126.useEffect(() => {
|
|
29710
29849
|
void load(currentOrgId);
|
|
29711
29850
|
}, [currentOrgId, load]);
|
|
29712
|
-
|
|
29851
|
+
React126.useEffect(() => {
|
|
29713
29852
|
if (!connected || projects.length === 0) return;
|
|
29714
29853
|
let cancelled = false;
|
|
29715
29854
|
void (async () => {
|
|
@@ -29781,7 +29920,7 @@ function SiteRow({
|
|
|
29781
29920
|
showDefaultAction,
|
|
29782
29921
|
onChanged
|
|
29783
29922
|
}) {
|
|
29784
|
-
const [busy, setBusy] =
|
|
29923
|
+
const [busy, setBusy] = React126.useState(false);
|
|
29785
29924
|
const editorUrl = editorUrlOf(project);
|
|
29786
29925
|
const run = async (action) => {
|
|
29787
29926
|
setBusy(true);
|
|
@@ -29852,7 +29991,7 @@ function SiteRow({
|
|
|
29852
29991
|
] });
|
|
29853
29992
|
}
|
|
29854
29993
|
function LinkSiteModal({ onClose, onLinked }) {
|
|
29855
|
-
const [mode, setMode] =
|
|
29994
|
+
const [mode, setMode] = React126.useState("import");
|
|
29856
29995
|
return /* @__PURE__ */ jsx(Modal, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs(ModalContent, { size: "lg", children: [
|
|
29857
29996
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
29858
29997
|
/* @__PURE__ */ jsx(ModalTitle, { children: "Vincular um site" }),
|
|
@@ -29888,11 +30027,11 @@ function ModeTab({
|
|
|
29888
30027
|
}
|
|
29889
30028
|
function ImportPane({ onLinked }) {
|
|
29890
30029
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
29891
|
-
const [search, setSearch] =
|
|
29892
|
-
const [remote, setRemote] =
|
|
29893
|
-
const [error, setError] =
|
|
29894
|
-
const [linkingId, setLinkingId] =
|
|
29895
|
-
|
|
30030
|
+
const [search, setSearch] = React126.useState("");
|
|
30031
|
+
const [remote, setRemote] = React126.useState(null);
|
|
30032
|
+
const [error, setError] = React126.useState(null);
|
|
30033
|
+
const [linkingId, setLinkingId] = React126.useState(null);
|
|
30034
|
+
React126.useEffect(() => {
|
|
29896
30035
|
let cancelled = false;
|
|
29897
30036
|
setError(null);
|
|
29898
30037
|
const timer = setTimeout(() => {
|
|
@@ -29974,9 +30113,9 @@ function ImportPane({ onLinked }) {
|
|
|
29974
30113
|
}
|
|
29975
30114
|
function CreatePane({ onLinked, onCancel }) {
|
|
29976
30115
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
29977
|
-
const [prompt, setPrompt] =
|
|
29978
|
-
const [busy, setBusy] =
|
|
29979
|
-
const [error, setError] =
|
|
30116
|
+
const [prompt, setPrompt] = React126.useState("");
|
|
30117
|
+
const [busy, setBusy] = React126.useState(false);
|
|
30118
|
+
const [error, setError] = React126.useState(null);
|
|
29980
30119
|
const tooShort = prompt.trim().length < PROMPT_MIN_CHARS;
|
|
29981
30120
|
const submit = async () => {
|
|
29982
30121
|
setBusy(true);
|
|
@@ -30024,19 +30163,33 @@ function CreatePane({ onLinked, onCancel }) {
|
|
|
30024
30163
|
] })
|
|
30025
30164
|
] });
|
|
30026
30165
|
}
|
|
30166
|
+
function pluginScreens(plugin) {
|
|
30167
|
+
return plugin.navigation?.length ? plugin.navigation.map((n) => n.label) : (plugin.routes ?? []).map((r) => r.path).filter((p) => !p.endsWith("/*"));
|
|
30168
|
+
}
|
|
30027
30169
|
function buildRows(plugins, hidden, permits) {
|
|
30028
30170
|
const visible = plugins.filter((p) => !hidden.has(p.id) && p.scope !== "core");
|
|
30029
|
-
|
|
30171
|
+
const hosted = new Set(visible.filter((p) => p.hostPluginId).map((p) => p.id));
|
|
30172
|
+
return visible.filter((plugin) => !hosted.has(plugin.id)).map((plugin) => ({
|
|
30030
30173
|
plugin,
|
|
30031
30174
|
// O que o plugin oferece de menu. Um módulo sem entrada própria (o app
|
|
30032
30175
|
// desenhou o rail) cai nas rotas, que é o que some de verdade.
|
|
30033
|
-
screens:
|
|
30176
|
+
screens: pluginScreens(plugin),
|
|
30034
30177
|
neededBy: visible.filter((other) => other.isActive && other.id !== plugin.id && (other.dependencies ?? []).includes(plugin.id)).map((other) => other.name),
|
|
30035
|
-
permitted: permits ? permits(plugin.id) : true
|
|
30178
|
+
permitted: permits ? permits(plugin.id) : true,
|
|
30179
|
+
addons: visible.filter((candidate) => candidate.hostPluginId === plugin.id).map((addon) => ({
|
|
30180
|
+
plugin: addon,
|
|
30181
|
+
screens: pluginScreens(addon),
|
|
30182
|
+
permitted: permits ? permits(addon.id) : true
|
|
30183
|
+
})).sort((a, b) => a.plugin.name.localeCompare(b.plugin.name))
|
|
30036
30184
|
})).sort((a, b) => a.plugin.name.localeCompare(b.plugin.name));
|
|
30037
30185
|
}
|
|
30038
|
-
function ModuleCard({
|
|
30039
|
-
|
|
30186
|
+
function ModuleCard({
|
|
30187
|
+
row,
|
|
30188
|
+
onToggle,
|
|
30189
|
+
busy,
|
|
30190
|
+
appLabel
|
|
30191
|
+
}) {
|
|
30192
|
+
const { plugin, screens, neededBy, permitted, addons } = row;
|
|
30040
30193
|
const Icon = getLucideIcon(plugin.icon) ?? Puzzle;
|
|
30041
30194
|
const blocked = !permitted && !plugin.isActive;
|
|
30042
30195
|
const locked = plugin.isActive && neededBy.length > 0;
|
|
@@ -30047,7 +30200,10 @@ function ModuleCard({ row, onToggle, busy }) {
|
|
|
30047
30200
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
30048
30201
|
/* @__PURE__ */ jsx(Icon, { className: "mt-0.5 h-5 w-5 shrink-0 text-muted-foreground" }),
|
|
30049
30202
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
30050
|
-
/* @__PURE__ */
|
|
30203
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
30204
|
+
/* @__PURE__ */ jsx(CardTitle, { className: "text-base", children: plugin.name }),
|
|
30205
|
+
appLabel ? /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0 font-normal", children: appLabel }) : null
|
|
30206
|
+
] }),
|
|
30051
30207
|
plugin.description ? /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: plugin.description }) : null
|
|
30052
30208
|
] })
|
|
30053
30209
|
] }),
|
|
@@ -30097,6 +30253,33 @@ function ModuleCard({ row, onToggle, busy }) {
|
|
|
30097
30253
|
}
|
|
30098
30254
|
)
|
|
30099
30255
|
] }, facet.id)) })
|
|
30256
|
+
] }) : null,
|
|
30257
|
+
plugin.isActive && addons.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
30258
|
+
/* @__PURE__ */ jsx(Separator, {}),
|
|
30259
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-3", children: addons.map((addon) => {
|
|
30260
|
+
const addonBlocked = !addon.permitted && !addon.plugin.isActive;
|
|
30261
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between gap-4", addonBlocked && "opacity-60"), children: [
|
|
30262
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
30263
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: addon.plugin.name }),
|
|
30264
|
+
addon.plugin.description ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: addon.plugin.description }) : addon.screens.length > 0 ? /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
30265
|
+
"Adiciona ao menu: ",
|
|
30266
|
+
addon.screens.join(" \xB7 ")
|
|
30267
|
+
] }) : null
|
|
30268
|
+
] }),
|
|
30269
|
+
addonBlocked ? /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "shrink-0 gap-1", children: [
|
|
30270
|
+
/* @__PURE__ */ jsx(Crown, { className: "h-3 w-3" }),
|
|
30271
|
+
" No plano maior"
|
|
30272
|
+
] }) : /* @__PURE__ */ jsx(
|
|
30273
|
+
Switch,
|
|
30274
|
+
{
|
|
30275
|
+
checked: addon.plugin.isActive,
|
|
30276
|
+
disabled: busy,
|
|
30277
|
+
"aria-label": `${addon.plugin.isActive ? "Desligar" : "Ligar"} ${addon.plugin.name}`,
|
|
30278
|
+
onCheckedChange: (next) => void onToggle(addon.plugin.id, next ? "active" : "disabled")
|
|
30279
|
+
}
|
|
30280
|
+
)
|
|
30281
|
+
] }, addon.plugin.id);
|
|
30282
|
+
}) })
|
|
30100
30283
|
] }) : null
|
|
30101
30284
|
] })
|
|
30102
30285
|
] });
|
|
@@ -30121,10 +30304,10 @@ function ModuleCatalogSections({
|
|
|
30121
30304
|
onToggle,
|
|
30122
30305
|
busy
|
|
30123
30306
|
}) {
|
|
30124
|
-
const [query, setQuery] =
|
|
30307
|
+
const [query, setQuery] = React126.useState("");
|
|
30125
30308
|
const total = categories.reduce((n, c) => n + c.rows.length, 0);
|
|
30126
30309
|
const searchable = total > 6;
|
|
30127
|
-
const filtered =
|
|
30310
|
+
const filtered = React126.useMemo(() => filterCategories(categories, query), [categories, query]);
|
|
30128
30311
|
if (categories.length === 0) {
|
|
30129
30312
|
return /* @__PURE__ */ jsxs("div", { className: "py-8 text-center", children: [
|
|
30130
30313
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Nada a adicionar" }),
|
|
@@ -30166,7 +30349,7 @@ function CategorySection({
|
|
|
30166
30349
|
onToggle,
|
|
30167
30350
|
busy
|
|
30168
30351
|
}) {
|
|
30169
|
-
const [open, setOpen] =
|
|
30352
|
+
const [open, setOpen] = React126.useState(category.mine);
|
|
30170
30353
|
const expanded = open || forceOpen;
|
|
30171
30354
|
const Chevron = expanded ? ChevronDown : ChevronRight;
|
|
30172
30355
|
return /* @__PURE__ */ jsxs("section", { children: [
|
|
@@ -30238,6 +30421,27 @@ function pluginVerticalIndex(catalog) {
|
|
|
30238
30421
|
}
|
|
30239
30422
|
return index;
|
|
30240
30423
|
}
|
|
30424
|
+
function pluginAppNames(catalog, pluginId) {
|
|
30425
|
+
return [...new Set(catalog.filter((app) => app.modules.includes(pluginId)).map((app) => app.name))].sort();
|
|
30426
|
+
}
|
|
30427
|
+
function isCrossCutting(catalog, pluginId) {
|
|
30428
|
+
const byVertical = /* @__PURE__ */ new Map();
|
|
30429
|
+
for (const app of catalog) {
|
|
30430
|
+
if (!app.vertical_id) continue;
|
|
30431
|
+
const offer = byVertical.get(app.vertical_id) ?? /* @__PURE__ */ new Set();
|
|
30432
|
+
for (const id of app.modules) offer.add(id);
|
|
30433
|
+
byVertical.set(app.vertical_id, offer);
|
|
30434
|
+
}
|
|
30435
|
+
const total = byVertical.size;
|
|
30436
|
+
const offering = [...byVertical.values()].filter((offer) => offer.has(pluginId)).length;
|
|
30437
|
+
return offering >= 2 && offering * 2 > total;
|
|
30438
|
+
}
|
|
30439
|
+
function appLabelFor(catalog, pluginId) {
|
|
30440
|
+
if (catalog.length === 0) return void 0;
|
|
30441
|
+
if (isCrossCutting(catalog, pluginId)) return "Todos os neg\xF3cios";
|
|
30442
|
+
const names = pluginAppNames(catalog, pluginId);
|
|
30443
|
+
return names.length ? `Estende: ${names.join(", ")}` : void 0;
|
|
30444
|
+
}
|
|
30241
30445
|
function buildCategories(catalog, rows) {
|
|
30242
30446
|
if (catalog.length === 0) {
|
|
30243
30447
|
return rows.length ? [{ id: CROSS_CUTTING, label: "Dispon\xEDveis", mine: true, rows }] : [];
|
|
@@ -30276,8 +30480,8 @@ function buildCategories(catalog, rows) {
|
|
|
30276
30480
|
}
|
|
30277
30481
|
function useModuleCatalog() {
|
|
30278
30482
|
const tenantId2 = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
30279
|
-
const [catalog, setCatalog] =
|
|
30280
|
-
|
|
30483
|
+
const [catalog, setCatalog] = React126.useState([]);
|
|
30484
|
+
React126.useEffect(() => {
|
|
30281
30485
|
const supabase = getSupabaseClientOptional$1();
|
|
30282
30486
|
if (!supabase) return;
|
|
30283
30487
|
let alive = true;
|
|
@@ -30291,36 +30495,92 @@ function useModuleCatalog() {
|
|
|
30291
30495
|
}, [tenantId2]);
|
|
30292
30496
|
return catalog;
|
|
30293
30497
|
}
|
|
30498
|
+
function ModulesPreview() {
|
|
30499
|
+
const runtime = usePluginRuntime();
|
|
30500
|
+
const preset = useAppPreset();
|
|
30501
|
+
const rows = React126.useMemo(() => {
|
|
30502
|
+
const flat = runtime.navigation.filter((entry) => entry.section !== "settings").map((entry) => toRailRow(entry, preset.labels));
|
|
30503
|
+
return applyRailPreset(flat, preset.rail, preset.hide, preset.whole);
|
|
30504
|
+
}, [runtime.navigation, preset.rail, preset.hide, preset.whole, preset.labels]);
|
|
30505
|
+
return /* @__PURE__ */ jsxs("div", { className: "sticky top-4 overflow-hidden rounded-2xl border border-sidebar-border bg-sidebar p-3", children: [
|
|
30506
|
+
/* @__PURE__ */ jsx("p", { className: "mb-2 px-2 text-xs font-medium text-sidebar-muted", children: "Pr\xE9via do menu" }),
|
|
30507
|
+
rows.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-2 py-6 text-center text-xs text-sidebar-muted", children: "Nenhum m\xF3dulo ligado ainda." }) : /* @__PURE__ */ jsx("nav", { className: "space-y-0.5", children: rows.map((row) => /* @__PURE__ */ jsx(PreviewRow, { row }, row.id)) })
|
|
30508
|
+
] });
|
|
30509
|
+
}
|
|
30510
|
+
function toRailRow(entry, labels) {
|
|
30511
|
+
return {
|
|
30512
|
+
id: entry.id ?? entry.route,
|
|
30513
|
+
label: labelFor(labels, entry.route, entry.label),
|
|
30514
|
+
route: entry.route,
|
|
30515
|
+
icon: entry.icon ?? "Circle",
|
|
30516
|
+
section: entry.section,
|
|
30517
|
+
pluginId: entry.pluginId
|
|
30518
|
+
};
|
|
30519
|
+
}
|
|
30520
|
+
function PreviewRow({ row, depth = 0 }) {
|
|
30521
|
+
const Icon = depth === 0 ? getLucideIcon(row.icon) ?? Home : null;
|
|
30522
|
+
const hasChildren = !!row.children?.length;
|
|
30523
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
30524
|
+
/* @__PURE__ */ jsxs(
|
|
30525
|
+
"div",
|
|
30526
|
+
{
|
|
30527
|
+
className: cn(
|
|
30528
|
+
"flex items-center gap-2 rounded-lg px-2 py-1.5 text-sm text-sidebar-foreground/80",
|
|
30529
|
+
depth === 0 && "hover:bg-sidebar-accent/60 hover:text-sidebar-accent-foreground"
|
|
30530
|
+
),
|
|
30531
|
+
style: depth > 0 ? { paddingLeft: 12 + depth * 16 } : void 0,
|
|
30532
|
+
children: [
|
|
30533
|
+
Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0" }) : null,
|
|
30534
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: row.label }),
|
|
30535
|
+
hasChildren ? /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5 shrink-0 text-sidebar-muted" }) : null
|
|
30536
|
+
]
|
|
30537
|
+
}
|
|
30538
|
+
),
|
|
30539
|
+
row.children?.map((child) => /* @__PURE__ */ jsx(PreviewRow, { row: child, depth: depth + 1 }, child.id))
|
|
30540
|
+
] });
|
|
30541
|
+
}
|
|
30294
30542
|
function ModulesSettings({ hidden = [], onToggle, permits, busy, catalog = [] }) {
|
|
30295
30543
|
const runtime = usePluginRuntime();
|
|
30296
30544
|
const offered = useOfferedPlugins();
|
|
30297
|
-
const [adding, setAdding] =
|
|
30298
|
-
const rows =
|
|
30545
|
+
const [adding, setAdding] = React126.useState(false);
|
|
30546
|
+
const rows = React126.useMemo(() => {
|
|
30299
30547
|
const known = catalog.length ? new Set(catalog.flatMap((app) => app.modules)) : new Set(offered);
|
|
30300
30548
|
const inCatalogue = known.size ? runtime.plugins.filter((p) => known.has(p.id) || p.isActive) : runtime.plugins;
|
|
30301
30549
|
return buildRows(inCatalogue, new Set(hidden), permits);
|
|
30302
30550
|
}, [runtime.plugins, hidden, permits, offered, catalog]);
|
|
30303
30551
|
const on = rows.filter((r) => r.plugin.isActive);
|
|
30304
|
-
const off =
|
|
30305
|
-
const categories =
|
|
30552
|
+
const off = React126.useMemo(() => rows.filter((r) => !r.plugin.isActive), [rows]);
|
|
30553
|
+
const categories = React126.useMemo(() => buildCategories(catalog, off), [catalog, off]);
|
|
30306
30554
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
|
|
30307
30555
|
/* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsxs(Button, { size: "sm", className: "shrink-0 gap-1.5", onClick: () => setAdding(true), children: [
|
|
30308
30556
|
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
|
|
30309
30557
|
" Adicionar"
|
|
30310
30558
|
] }) }),
|
|
30311
|
-
/* @__PURE__ */ jsxs("
|
|
30312
|
-
/* @__PURE__ */ jsxs("
|
|
30313
|
-
/* @__PURE__ */ jsxs("
|
|
30314
|
-
|
|
30315
|
-
|
|
30316
|
-
|
|
30559
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-8 lg:grid-cols-[minmax(0,1fr)_260px]", children: [
|
|
30560
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
30561
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
30562
|
+
/* @__PURE__ */ jsxs("h3", { className: "text-sm font-medium", children: [
|
|
30563
|
+
"Ligados (",
|
|
30564
|
+
on.length,
|
|
30565
|
+
")"
|
|
30566
|
+
] }),
|
|
30567
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "O que esta conta usa hoje. Desligar tira as telas do menu; os dados continuam onde est\xE3o." })
|
|
30317
30568
|
] }),
|
|
30318
|
-
/* @__PURE__ */
|
|
30569
|
+
on.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-dashed border-border p-8 text-center", children: [
|
|
30570
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-foreground", children: "Nenhum m\xF3dulo ligado" }),
|
|
30571
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: 'Abra o cat\xE1logo em "Adicionar" para escolher o que esta conta vai usar.' })
|
|
30572
|
+
] }) : on.map((row) => /* @__PURE__ */ jsx(
|
|
30573
|
+
ModuleCard,
|
|
30574
|
+
{
|
|
30575
|
+
row,
|
|
30576
|
+
onToggle,
|
|
30577
|
+
busy,
|
|
30578
|
+
appLabel: appLabelFor(catalog, row.plugin.id)
|
|
30579
|
+
},
|
|
30580
|
+
row.plugin.id
|
|
30581
|
+
))
|
|
30319
30582
|
] }),
|
|
30320
|
-
|
|
30321
|
-
/* @__PURE__ */ jsx("p", { className: "font-medium text-foreground", children: "Nenhum m\xF3dulo ligado" }),
|
|
30322
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: 'Abra o cat\xE1logo em "Adicionar" para escolher o que esta conta vai usar.' })
|
|
30323
|
-
] }) : on.map((row) => /* @__PURE__ */ jsx(ModuleCard, { row, onToggle, busy }, row.plugin.id))
|
|
30583
|
+
/* @__PURE__ */ jsx(ModulesPreview, {})
|
|
30324
30584
|
] }),
|
|
30325
30585
|
/* @__PURE__ */ jsx(
|
|
30326
30586
|
AddModulesPanel,
|
|
@@ -30510,8 +30770,8 @@ function ConnectedModulesSettings({ hidden = SHELL_PLUGINS }) {
|
|
|
30510
30770
|
const access = useAccessOptional();
|
|
30511
30771
|
const catalog = useModuleCatalog();
|
|
30512
30772
|
const tenantId2 = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
30513
|
-
const [busy, setBusy] =
|
|
30514
|
-
const onToggle =
|
|
30773
|
+
const [busy, setBusy] = React126.useState(false);
|
|
30774
|
+
const onToggle = React126.useCallback(
|
|
30515
30775
|
async (plugin, status, facet) => {
|
|
30516
30776
|
const supabase = getSupabaseClientOptional$1();
|
|
30517
30777
|
if (!supabase) return;
|
|
@@ -30537,7 +30797,7 @@ function ConnectedModulesSettings({ hidden = SHELL_PLUGINS }) {
|
|
|
30537
30797
|
},
|
|
30538
30798
|
[refresh, tenantId2]
|
|
30539
30799
|
);
|
|
30540
|
-
const permits =
|
|
30800
|
+
const permits = React126.useCallback(
|
|
30541
30801
|
(plugin) => access ? access.can(plugin, "read").allowed || access.entitled(plugin) : true,
|
|
30542
30802
|
[access]
|
|
30543
30803
|
);
|
|
@@ -30548,7 +30808,7 @@ function useCoreSettingsTabs({
|
|
|
30548
30808
|
showBranding = true
|
|
30549
30809
|
} = {}) {
|
|
30550
30810
|
const { t } = useTranslation$1();
|
|
30551
|
-
return
|
|
30811
|
+
return React126.useMemo(() => [
|
|
30552
30812
|
...showCompany ? [{ id: "general", label: t("settings.general"), icon: /* @__PURE__ */ jsx(Building2, { className: "h-4 w-4" }), iconName: "Building2", component: /* @__PURE__ */ jsx(ConnectedCompanySettings, {}) }] : [],
|
|
30553
30813
|
{ id: "profile", label: t("settings.profile"), icon: /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }), iconName: "User", component: /* @__PURE__ */ jsx(ConnectedUserProfile, {}) },
|
|
30554
30814
|
{ id: "security", label: t("settings.security"), icon: /* @__PURE__ */ jsx(Shield, { className: "h-4 w-4" }), iconName: "Shield", component: /* @__PURE__ */ jsx(ConnectedSecuritySettings, {}) },
|
|
@@ -30593,10 +30853,10 @@ function SettingsPage({
|
|
|
30593
30853
|
}
|
|
30594
30854
|
return null;
|
|
30595
30855
|
}
|
|
30596
|
-
const [activeTab, setActiveTab] =
|
|
30856
|
+
const [activeTab, setActiveTab] = React126.useState(() => {
|
|
30597
30857
|
return getTabFromHash() ?? defaultTab ?? null;
|
|
30598
30858
|
});
|
|
30599
|
-
|
|
30859
|
+
React126.useEffect(() => {
|
|
30600
30860
|
const handler = () => {
|
|
30601
30861
|
const tab = getTabFromHash();
|
|
30602
30862
|
if (tab) setActiveTab(tab);
|
|
@@ -30623,8 +30883,8 @@ function SettingsPage({
|
|
|
30623
30883
|
setActiveTab(null);
|
|
30624
30884
|
window.location.hash = "/settings";
|
|
30625
30885
|
};
|
|
30626
|
-
const [query, setQuery] =
|
|
30627
|
-
const sections =
|
|
30886
|
+
const [query, setQuery] = React126.useState("");
|
|
30887
|
+
const sections = React126.useMemo(() => {
|
|
30628
30888
|
const q = query.trim().toLowerCase();
|
|
30629
30889
|
const out = [];
|
|
30630
30890
|
for (const tab of resolvedTabs) {
|
|
@@ -30709,14 +30969,14 @@ function InviteMemberDialog({ open, onOpenChange, defaultEmail }) {
|
|
|
30709
30969
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
30710
30970
|
const setInvites = useInviteStore((s) => s.setInvites);
|
|
30711
30971
|
const { user } = useAuthStore();
|
|
30712
|
-
const [emails, setEmails] =
|
|
30713
|
-
const [profileId, setProfileId] =
|
|
30714
|
-
const [sending, setSending] =
|
|
30715
|
-
const [sent, setSent] =
|
|
30716
|
-
|
|
30972
|
+
const [emails, setEmails] = React126.useState([defaultEmail ?? ""]);
|
|
30973
|
+
const [profileId, setProfileId] = React126.useState(profiles[1]?.id ?? profiles[0]?.id ?? "");
|
|
30974
|
+
const [sending, setSending] = React126.useState(false);
|
|
30975
|
+
const [sent, setSent] = React126.useState(false);
|
|
30976
|
+
React126.useEffect(() => {
|
|
30717
30977
|
if (open) setEmails([defaultEmail ?? ""]);
|
|
30718
30978
|
}, [open, defaultEmail]);
|
|
30719
|
-
|
|
30979
|
+
React126.useEffect(() => {
|
|
30720
30980
|
if (!profileId && profiles.length) setProfileId(profiles[1]?.id ?? profiles[0].id);
|
|
30721
30981
|
}, [profiles, profileId]);
|
|
30722
30982
|
const addEmail = () => setEmails((prev) => [...prev, ""]);
|
|
@@ -30820,7 +31080,7 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
30820
31080
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
30821
31081
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
30822
31082
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
30823
|
-
const [query, setQuery] =
|
|
31083
|
+
const [query, setQuery] = React126.useState("");
|
|
30824
31084
|
const singular = label2(t, "unit.singular", "unidade");
|
|
30825
31085
|
const plural = label2(t, "unit.plural", "unidades");
|
|
30826
31086
|
if (!unitMode) return null;
|
|
@@ -30845,13 +31105,13 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
30845
31105
|
}
|
|
30846
31106
|
const renderNode = (node, depth) => {
|
|
30847
31107
|
if (node.kind === "region") {
|
|
30848
|
-
return /* @__PURE__ */ jsxs(
|
|
31108
|
+
return /* @__PURE__ */ jsxs(React126.Fragment, { children: [
|
|
30849
31109
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
30850
31110
|
node.children.map((child) => renderNode(child, depth + 1))
|
|
30851
31111
|
] }, node.id);
|
|
30852
31112
|
}
|
|
30853
31113
|
if (!reachable.includes(node.id)) return null;
|
|
30854
|
-
return /* @__PURE__ */ jsxs(
|
|
31114
|
+
return /* @__PURE__ */ jsxs(React126.Fragment, { children: [
|
|
30855
31115
|
/* @__PURE__ */ jsxs(
|
|
30856
31116
|
DropdownItem,
|
|
30857
31117
|
{
|
|
@@ -30934,7 +31194,7 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
30934
31194
|
var MENU_LIST_CAP = 5;
|
|
30935
31195
|
function UnitMenuSection() {
|
|
30936
31196
|
useUnitBootstrap();
|
|
30937
|
-
const [locating, setLocating] =
|
|
31197
|
+
const [locating, setLocating] = React126.useState(false);
|
|
30938
31198
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
30939
31199
|
const units = useUnitStore((s) => s.units);
|
|
30940
31200
|
const tree = useUnitStore((s) => s.tree);
|
|
@@ -30985,13 +31245,13 @@ function UnitMenuSection() {
|
|
|
30985
31245
|
if (node.kind === "region") {
|
|
30986
31246
|
const visibleChildren = node.children.filter((c) => c.kind === "region" || reachable.includes(c.id));
|
|
30987
31247
|
if (visibleChildren.length === 0) return null;
|
|
30988
|
-
return /* @__PURE__ */ jsxs(
|
|
31248
|
+
return /* @__PURE__ */ jsxs(React126.Fragment, { children: [
|
|
30989
31249
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
30990
31250
|
visibleChildren.map((child) => renderNode(child, depth + 1))
|
|
30991
31251
|
] }, node.id);
|
|
30992
31252
|
}
|
|
30993
31253
|
if (!reachable.includes(node.id)) return null;
|
|
30994
|
-
return /* @__PURE__ */ jsxs(
|
|
31254
|
+
return /* @__PURE__ */ jsxs(React126.Fragment, { children: [
|
|
30995
31255
|
/* @__PURE__ */ jsxs(
|
|
30996
31256
|
DropdownItem,
|
|
30997
31257
|
{
|
|
@@ -31139,9 +31399,9 @@ function MemberUnitsCell({
|
|
|
31139
31399
|
const byId = useUnitStore((s) => s.byId);
|
|
31140
31400
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
31141
31401
|
const openUnit = useUnitPanel((s) => s.openUnit);
|
|
31142
|
-
const [unitIds, setUnitIds] =
|
|
31402
|
+
const [unitIds, setUnitIds] = React126.useState(null);
|
|
31143
31403
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
31144
|
-
|
|
31404
|
+
React126.useEffect(() => {
|
|
31145
31405
|
if (!userId) {
|
|
31146
31406
|
setUnitIds([]);
|
|
31147
31407
|
return;
|
|
@@ -31199,10 +31459,10 @@ function TeamTab() {
|
|
|
31199
31459
|
const { user } = useAuthStore();
|
|
31200
31460
|
const hasSystemPermission = useSystemPermission();
|
|
31201
31461
|
const personMode = teamPersonKinds.length > 0 && typeof adapter?.listTeam === "function";
|
|
31202
|
-
const [team, setTeam] =
|
|
31203
|
-
const [inviteOpen, setInviteOpen] =
|
|
31462
|
+
const [team, setTeam] = React126.useState(null);
|
|
31463
|
+
const [inviteOpen, setInviteOpen] = React126.useState(false);
|
|
31204
31464
|
const guardSeats = useLimitGuard("users");
|
|
31205
|
-
const [inviteEmail, setInviteEmail] =
|
|
31465
|
+
const [inviteEmail, setInviteEmail] = React126.useState(void 0);
|
|
31206
31466
|
const handleOpenInvite = async (row) => {
|
|
31207
31467
|
if (row && !row.email && row.personId && entityRouteHasDetail("person", row.kind)) {
|
|
31208
31468
|
openEntity(row.personId, "person", row.kind, "access");
|
|
@@ -31212,7 +31472,7 @@ function TeamTab() {
|
|
|
31212
31472
|
setInviteEmail(row?.email || void 0);
|
|
31213
31473
|
setInviteOpen(true);
|
|
31214
31474
|
};
|
|
31215
|
-
const reloadTeam =
|
|
31475
|
+
const reloadTeam = React126.useCallback(async () => {
|
|
31216
31476
|
if (!adapter || !currentOrg) return;
|
|
31217
31477
|
if (personMode && adapter.listTeam) {
|
|
31218
31478
|
setTeam(await adapter.listTeam(currentOrg.id, teamPersonKinds));
|
|
@@ -31220,12 +31480,12 @@ function TeamTab() {
|
|
|
31220
31480
|
setMembers(await adapter.listMembers(currentOrg.id));
|
|
31221
31481
|
}
|
|
31222
31482
|
}, [adapter, currentOrg?.id, personMode, teamPersonKinds, setMembers]);
|
|
31223
|
-
|
|
31483
|
+
React126.useEffect(() => {
|
|
31224
31484
|
if (personMode && adapter?.listTeam && currentOrg) {
|
|
31225
31485
|
dedup("team:people:" + currentOrg.id, () => adapter.listTeam(currentOrg.id, teamPersonKinds)).then(setTeam).catch(() => setTeam([]));
|
|
31226
31486
|
}
|
|
31227
31487
|
}, [personMode, adapter, currentOrg?.id, teamPersonKinds.join(",")]);
|
|
31228
|
-
|
|
31488
|
+
React126.useEffect(() => {
|
|
31229
31489
|
if (adapter && currentOrg) {
|
|
31230
31490
|
dedup("team:invites:" + currentOrg.id, () => adapter.listInvites(currentOrg.id)).then(setInvites).catch(() => {
|
|
31231
31491
|
});
|
|
@@ -31306,7 +31566,7 @@ function TeamTab() {
|
|
|
31306
31566
|
};
|
|
31307
31567
|
const { t } = useTranslation$1();
|
|
31308
31568
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
31309
|
-
const inviteActions =
|
|
31569
|
+
const inviteActions = React126.useMemo(() => [{
|
|
31310
31570
|
id: "invite",
|
|
31311
31571
|
label: t("organization.team.invite"),
|
|
31312
31572
|
icon: UserPlus,
|
|
@@ -31493,13 +31753,13 @@ var SYSTEM_PERMISSIONS = [
|
|
|
31493
31753
|
];
|
|
31494
31754
|
function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, isNew, parentLabel }) {
|
|
31495
31755
|
const { t } = useTranslation$1();
|
|
31496
|
-
const [name, setName] =
|
|
31497
|
-
const [description, setDescription] =
|
|
31498
|
-
const [systemPerms, setSystemPerms] =
|
|
31499
|
-
const [grants, setGrants] =
|
|
31500
|
-
const [collapsed, setCollapsed] =
|
|
31501
|
-
const [search, setSearch] =
|
|
31502
|
-
const initial =
|
|
31756
|
+
const [name, setName] = React126.useState(profile?.name ?? "");
|
|
31757
|
+
const [description, setDescription] = React126.useState(profile?.description ?? "");
|
|
31758
|
+
const [systemPerms, setSystemPerms] = React126.useState(profile?.systemPermissions ?? []);
|
|
31759
|
+
const [grants, setGrants] = React126.useState(profile?.grants ?? {});
|
|
31760
|
+
const [collapsed, setCollapsed] = React126.useState(/* @__PURE__ */ new Set());
|
|
31761
|
+
const [search, setSearch] = React126.useState("");
|
|
31762
|
+
const initial = React126.useRef({
|
|
31503
31763
|
name: profile?.name ?? "",
|
|
31504
31764
|
description: profile?.description ?? "",
|
|
31505
31765
|
systemPerms: JSON.stringify(profile?.systemPermissions ?? []),
|
|
@@ -31536,7 +31796,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
31536
31796
|
onDiscard: onCancel,
|
|
31537
31797
|
saveLabel: isNew ? t("organization.permissions.createProfile") : t("organization.permissions.updateProfile")
|
|
31538
31798
|
});
|
|
31539
|
-
const groups =
|
|
31799
|
+
const groups = React126.useMemo(() => {
|
|
31540
31800
|
const filtered = search ? features.filter((f) => f.label.toLowerCase().includes(search.toLowerCase())) : features;
|
|
31541
31801
|
const map = /* @__PURE__ */ new Map();
|
|
31542
31802
|
for (const f of filtered) {
|
|
@@ -31605,7 +31865,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
31605
31865
|
}
|
|
31606
31866
|
) }) })
|
|
31607
31867
|
] }, sp.id)),
|
|
31608
|
-
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(
|
|
31868
|
+
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(React126.Fragment, { children: [
|
|
31609
31869
|
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: 5, className: "p-2 px-3", children: /* @__PURE__ */ jsxs(
|
|
31610
31870
|
"button",
|
|
31611
31871
|
{
|
|
@@ -31677,12 +31937,12 @@ function PermissionProfilesTab() {
|
|
|
31677
31937
|
const startImpersonation = usePermissionsStore((s) => s.startImpersonation);
|
|
31678
31938
|
const canPreview = (realProfile?.systemPermissions ?? []).includes("manage_permissions") ?? false;
|
|
31679
31939
|
const { t } = useTranslation$1();
|
|
31680
|
-
const [editingProfile, setEditingProfile] =
|
|
31681
|
-
const [creating, setCreating] =
|
|
31682
|
-
const [duplicateSource, setDuplicateSource] =
|
|
31683
|
-
const [saving, setSaving] =
|
|
31684
|
-
const [error, setError] =
|
|
31685
|
-
const [deleting, setDeleting] =
|
|
31940
|
+
const [editingProfile, setEditingProfile] = React126.useState(null);
|
|
31941
|
+
const [creating, setCreating] = React126.useState(false);
|
|
31942
|
+
const [duplicateSource, setDuplicateSource] = React126.useState(null);
|
|
31943
|
+
const [saving, setSaving] = React126.useState(false);
|
|
31944
|
+
const [error, setError] = React126.useState(null);
|
|
31945
|
+
const [deleting, setDeleting] = React126.useState(null);
|
|
31686
31946
|
const handleDuplicate = (profile) => {
|
|
31687
31947
|
setEditingProfile(null);
|
|
31688
31948
|
setCreating(false);
|
|
@@ -31692,9 +31952,9 @@ function PermissionProfilesTab() {
|
|
|
31692
31952
|
isSystem: false
|
|
31693
31953
|
});
|
|
31694
31954
|
};
|
|
31695
|
-
const surfaceRef =
|
|
31955
|
+
const surfaceRef = React126.useRef({ features, profiles, adapter, currentOrg, setProfiles });
|
|
31696
31956
|
surfaceRef.current = { features, profiles, adapter, currentOrg, setProfiles };
|
|
31697
|
-
const agentSurface =
|
|
31957
|
+
const agentSurface = React126.useMemo(() => ({
|
|
31698
31958
|
id: "org.permissions",
|
|
31699
31959
|
instructions: PERMISSIONS_INSTRUCTIONS,
|
|
31700
31960
|
describe: () => {
|
|
@@ -31748,7 +32008,7 @@ function PermissionProfilesTab() {
|
|
|
31748
32008
|
}]
|
|
31749
32009
|
}), []);
|
|
31750
32010
|
useAgentSurface(agentSurface);
|
|
31751
|
-
const createActions =
|
|
32011
|
+
const createActions = React126.useMemo(() => [
|
|
31752
32012
|
{
|
|
31753
32013
|
id: "new",
|
|
31754
32014
|
label: t("organization.permissions.createProfile"),
|
|
@@ -31777,7 +32037,7 @@ function PermissionProfilesTab() {
|
|
|
31777
32037
|
})
|
|
31778
32038
|
}
|
|
31779
32039
|
], [t]);
|
|
31780
|
-
const memberCountByProfile =
|
|
32040
|
+
const memberCountByProfile = React126.useMemo(() => {
|
|
31781
32041
|
const counts = {};
|
|
31782
32042
|
for (const m of members) {
|
|
31783
32043
|
counts[m.profileId] = (counts[m.profileId] ?? 0) + 1;
|
|
@@ -32082,7 +32342,7 @@ function FieldRulesSettings({ entities, rules: initialRules, onSave }) {
|
|
|
32082
32342
|
const [saving, setSaving] = useState(false);
|
|
32083
32343
|
const [search, setSearch] = useState("");
|
|
32084
32344
|
const [showMore, setShowMore] = useState(false);
|
|
32085
|
-
|
|
32345
|
+
React126.useEffect(() => {
|
|
32086
32346
|
setDraft(initialRules);
|
|
32087
32347
|
}, [initialRules]);
|
|
32088
32348
|
const isDirty = useMemo(
|
|
@@ -32482,19 +32742,19 @@ function SoftLimitWidget() {
|
|
|
32482
32742
|
function LimitProbe({ limitKey }) {
|
|
32483
32743
|
const info = useLimit(limitKey);
|
|
32484
32744
|
const report = useSoftLimitStore((s) => s.report);
|
|
32485
|
-
|
|
32745
|
+
React126.useEffect(() => {
|
|
32486
32746
|
report(limitKey, info);
|
|
32487
32747
|
}, [limitKey, info, report]);
|
|
32488
32748
|
return null;
|
|
32489
32749
|
}
|
|
32490
32750
|
function SoftLimitProbes({ keys }) {
|
|
32491
|
-
const monitored =
|
|
32751
|
+
const monitored = React126.useMemo(() => Array.from(new Set(keys)), [keys]);
|
|
32492
32752
|
return /* @__PURE__ */ jsx(Fragment, { children: monitored.map((k) => /* @__PURE__ */ jsx(LimitProbe, { limitKey: k }, k)) });
|
|
32493
32753
|
}
|
|
32494
|
-
var CommandPalette =
|
|
32754
|
+
var CommandPalette = React126.lazy(
|
|
32495
32755
|
() => import('./CommandPalette-B5PMQFDG.js').then((m) => ({ default: m.CommandPalette }))
|
|
32496
32756
|
);
|
|
32497
|
-
var SubscriptionPage =
|
|
32757
|
+
var SubscriptionPage = React126.lazy(
|
|
32498
32758
|
() => import('./SubscriptionPage-WQBBD35Q.js').then((m) => ({ default: m.SubscriptionPage }))
|
|
32499
32759
|
);
|
|
32500
32760
|
function WorkspaceSwitcher({
|
|
@@ -32544,8 +32804,8 @@ function WorkspaceSwitcher({
|
|
|
32544
32804
|
const v = t(key);
|
|
32545
32805
|
return !v || v === key ? fallback : v;
|
|
32546
32806
|
};
|
|
32547
|
-
const [query, setQuery] =
|
|
32548
|
-
const search =
|
|
32807
|
+
const [query, setQuery] = React126.useState("");
|
|
32808
|
+
const search = React126.useMemo(
|
|
32549
32809
|
() => searchWorkspaces(
|
|
32550
32810
|
options,
|
|
32551
32811
|
query,
|
|
@@ -32859,9 +33119,9 @@ function PluginHeaderControls() {
|
|
|
32859
33119
|
}
|
|
32860
33120
|
function AdminNotifications() {
|
|
32861
33121
|
const { notifications, unreadCount, fetchNotifications, markAsRead, markAllAsRead } = useNotifications();
|
|
32862
|
-
const [open, setOpen] =
|
|
32863
|
-
const fetchedRef =
|
|
32864
|
-
|
|
33122
|
+
const [open, setOpen] = React126.useState(false);
|
|
33123
|
+
const fetchedRef = React126.useRef(false);
|
|
33124
|
+
React126.useEffect(() => {
|
|
32865
33125
|
if (fetchedRef.current) return;
|
|
32866
33126
|
fetchedRef.current = true;
|
|
32867
33127
|
void fetchNotifications();
|
|
@@ -33007,7 +33267,7 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
33007
33267
|
// sidebar ICON_MAP, which made the settings rail fall back to Home.
|
|
33008
33268
|
icon: /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
|
|
33009
33269
|
iconName: "CreditCard",
|
|
33010
|
-
component: /* @__PURE__ */ jsx(
|
|
33270
|
+
component: /* @__PURE__ */ jsx(React126.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(SubscriptionPage, {}) })
|
|
33011
33271
|
});
|
|
33012
33272
|
}
|
|
33013
33273
|
if (showOrgSettings) {
|
|
@@ -33035,9 +33295,9 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
33035
33295
|
settingsTabs.push({
|
|
33036
33296
|
id: tab.id,
|
|
33037
33297
|
label: translated === labelKey ? tab.label : translated,
|
|
33038
|
-
icon:
|
|
33298
|
+
icon: React126.createElement(IconComp, { className: "h-4 w-4" }),
|
|
33039
33299
|
iconName,
|
|
33040
|
-
component:
|
|
33300
|
+
component: React126.createElement(tab.component),
|
|
33041
33301
|
// Flag plugin-contributed tabs so SettingsPage draws the core/plugins divider.
|
|
33042
33302
|
isPlugin: true,
|
|
33043
33303
|
group: tab.group,
|
|
@@ -33088,12 +33348,12 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33088
33348
|
profileKnown: !activeTenantId || profileKnownFor === activeTenantId
|
|
33089
33349
|
});
|
|
33090
33350
|
const navError = configError ?? tenantCtx?.loadError ?? null;
|
|
33091
|
-
const onNavRetry =
|
|
33351
|
+
const onNavRetry = React126.useCallback(() => {
|
|
33092
33352
|
if (tenantCtx?.loadError) tenantCtx.retryOrgs();
|
|
33093
33353
|
else window.location.reload();
|
|
33094
33354
|
}, [tenantCtx]);
|
|
33095
33355
|
const currentProfile = usePermissionsStore((s) => s.currentProfile);
|
|
33096
|
-
const hasSystem =
|
|
33356
|
+
const hasSystem = React126.useCallback(
|
|
33097
33357
|
(perm) => {
|
|
33098
33358
|
if (!currentProfile) return false;
|
|
33099
33359
|
if (currentProfile.id === "owner" || currentProfile.name?.toLowerCase() === "owner") return true;
|
|
@@ -33107,8 +33367,8 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33107
33367
|
};
|
|
33108
33368
|
const path = useAdminPath();
|
|
33109
33369
|
const { user, signOut } = useAuth();
|
|
33110
|
-
|
|
33111
|
-
|
|
33370
|
+
React126.useEffect(() => installGlobalErrorHandlers(), []);
|
|
33371
|
+
React126.useEffect(() => registerErrorReporter((report) => {
|
|
33112
33372
|
if (report.source !== "data") return;
|
|
33113
33373
|
const alvo = report.extra?.operation;
|
|
33114
33374
|
toast.error(
|
|
@@ -33126,15 +33386,15 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33126
33386
|
const hasChatPanel = useRightRailStore((s) => s.panels.some((pn) => pn.id === "chat"));
|
|
33127
33387
|
const rightRail = railHasPanels ? /* @__PURE__ */ jsx(RightRail, { frame: contentFrame, attached: layout !== "topbar" }) : null;
|
|
33128
33388
|
const setRailMounted = useRightRailStore((s) => s.setMounted);
|
|
33129
|
-
|
|
33389
|
+
React126.useEffect(() => {
|
|
33130
33390
|
setRailMounted(true);
|
|
33131
33391
|
return () => setRailMounted(false);
|
|
33132
33392
|
}, [setRailMounted]);
|
|
33133
33393
|
useConnectorOAuthReturn();
|
|
33134
33394
|
const railWidthLive = useRightRailStore((s) => s.width);
|
|
33135
33395
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
33136
|
-
const railAutoCollapsedRef =
|
|
33137
|
-
|
|
33396
|
+
const railAutoCollapsedRef = React126.useRef(false);
|
|
33397
|
+
React126.useEffect(() => {
|
|
33138
33398
|
if (layout !== "sidebar") return;
|
|
33139
33399
|
const SIDEBAR_EXPANDED = 224;
|
|
33140
33400
|
const MIN_CONTENT = 620;
|
|
@@ -33156,22 +33416,22 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33156
33416
|
window.addEventListener("resize", apply);
|
|
33157
33417
|
return () => window.removeEventListener("resize", apply);
|
|
33158
33418
|
}, [railOpen, railWidthLive, layout, setSidebarCollapsed]);
|
|
33159
|
-
const [railWidth] =
|
|
33419
|
+
const [railWidth] = React126.useState(() => readRightRailWidth());
|
|
33160
33420
|
const billingPlans = useBillingStore((s) => s.plans);
|
|
33161
33421
|
const hasBilling = billingPlans.length > 0;
|
|
33162
33422
|
const orgPlan = useTenantOptional()?.org?.plan;
|
|
33163
|
-
const planBadge =
|
|
33423
|
+
const planBadge = React126.useMemo(
|
|
33164
33424
|
() => hasBilling ? resolvePlanBadge(orgPlan, billingPlans) : null,
|
|
33165
33425
|
[hasBilling, orgPlan, billingPlans]
|
|
33166
33426
|
);
|
|
33167
|
-
const softLimitKeys =
|
|
33427
|
+
const softLimitKeys = React126.useMemo(() => {
|
|
33168
33428
|
const plan = billingPlans.find((p) => p.id === (orgPlan || "free"));
|
|
33169
33429
|
return Object.keys(getPlanEntitlements(plan)?.limits ?? {});
|
|
33170
33430
|
}, [billingPlans, orgPlan]);
|
|
33171
33431
|
const overshoots = useOvershoots();
|
|
33172
33432
|
const navContributions = useNavContributionsStore((s) => s.contributions);
|
|
33173
33433
|
const appConfigNav = useAppConfigStore((state) => state.config.nav);
|
|
33174
|
-
const navigation =
|
|
33434
|
+
const navigation = React126.useMemo(() => {
|
|
33175
33435
|
const contributed = Object.values(navContributions).flat();
|
|
33176
33436
|
const flat = dedupeByRoute(
|
|
33177
33437
|
[...runtime.navigation, ...contributed].map((entry) => ({
|
|
@@ -33242,7 +33502,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33242
33502
|
}).filter((item) => item !== null).sort(compareNavigation);
|
|
33243
33503
|
return applyRailPreset(gated, presetRail, presetHide, presetWhole);
|
|
33244
33504
|
}, [runtime.navigation, runtime.routes, navContributions, pages, access, navWaiting, presetRail, presetHide, presetWhole, presetLabels]);
|
|
33245
|
-
const composedNavigation =
|
|
33505
|
+
const composedNavigation = React126.useMemo(() => {
|
|
33246
33506
|
if (!appConfigNav.length) return navigation;
|
|
33247
33507
|
const keyed = navigation.map((item) => ({ ...item, key: item.route }));
|
|
33248
33508
|
return applyNavComposition(keyed, appConfigNav).map((item) => {
|
|
@@ -33258,13 +33518,13 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33258
33518
|
};
|
|
33259
33519
|
});
|
|
33260
33520
|
}, [navigation, appConfigNav]);
|
|
33261
|
-
const resolvedBottomNav =
|
|
33521
|
+
const resolvedBottomNav = React126.useMemo(
|
|
33262
33522
|
() => deriveBottomNav(navigation, bottomNav, { assistant: hasChatPanel }),
|
|
33263
33523
|
[navigation, bottomNav, hasChatPanel]
|
|
33264
33524
|
);
|
|
33265
33525
|
const commandPaletteOpen = useLayoutStore((s) => s.commandPaletteOpen);
|
|
33266
33526
|
const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
|
|
33267
|
-
const commandItems =
|
|
33527
|
+
const commandItems = React126.useMemo(() => {
|
|
33268
33528
|
const navGroup = tr("layout.commandPalette.navigation", "Navigation");
|
|
33269
33529
|
const items = [];
|
|
33270
33530
|
for (const nav of navigation) {
|
|
@@ -33276,7 +33536,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33276
33536
|
return items;
|
|
33277
33537
|
}, [navigation]);
|
|
33278
33538
|
const globalSearch = useGlobalSearch();
|
|
33279
|
-
const routes =
|
|
33539
|
+
const routes = React126.useMemo(() => {
|
|
33280
33540
|
const list = [];
|
|
33281
33541
|
const entityRouteMap = /* @__PURE__ */ new Map();
|
|
33282
33542
|
for (const r of runtime.routes) {
|
|
@@ -33299,14 +33559,14 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33299
33559
|
setEntityRouteMap(entityRouteMap);
|
|
33300
33560
|
return list.sort((a, b) => routeScore(b.path) - routeScore(a.path));
|
|
33301
33561
|
}, [runtime.routes, pages, showSettings]);
|
|
33302
|
-
const match =
|
|
33562
|
+
const match = React126.useMemo(() => {
|
|
33303
33563
|
for (const r of routes) {
|
|
33304
33564
|
const params = matchRoute(r.path, path);
|
|
33305
33565
|
if (params) return { route: r, params };
|
|
33306
33566
|
}
|
|
33307
33567
|
return null;
|
|
33308
33568
|
}, [routes, path]);
|
|
33309
|
-
|
|
33569
|
+
React126.useEffect(() => {
|
|
33310
33570
|
if (!match && (path === "/" || path === "") && navigation.length > 0) {
|
|
33311
33571
|
navigateTo(navigation[0].route);
|
|
33312
33572
|
}
|
|
@@ -33314,11 +33574,11 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33314
33574
|
const ActiveComponent = match?.route.Component;
|
|
33315
33575
|
const activeParams = match?.params ?? {};
|
|
33316
33576
|
const routeKey = (match?.route.path ?? path).replace(/\/\*$/, "");
|
|
33317
|
-
const settingsTabs =
|
|
33577
|
+
const settingsTabs = React126.useMemo(
|
|
33318
33578
|
() => buildSettingsTabs(runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling),
|
|
33319
33579
|
[runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling]
|
|
33320
33580
|
);
|
|
33321
|
-
const profileRoute =
|
|
33581
|
+
const profileRoute = React126.useMemo(() => {
|
|
33322
33582
|
const explicit = routes.find((r) => r.path === "/perfil" || r.path === "/profile");
|
|
33323
33583
|
if (explicit) return explicit.path;
|
|
33324
33584
|
return showSettings ? "/settings/profile" : null;
|
|
@@ -33327,8 +33587,8 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33327
33587
|
const onBilling = hasBilling && showSettings ? () => navigateTo("/settings/subscription") : void 0;
|
|
33328
33588
|
const coreSettingsTabs = useCoreSettingsTabs({ showCompany: showBranding, showBranding });
|
|
33329
33589
|
const catalog = useModuleCatalog();
|
|
33330
|
-
const verticalByPlugin =
|
|
33331
|
-
const allSettingsTabs =
|
|
33590
|
+
const verticalByPlugin = React126.useMemo(() => pluginVerticalIndex(catalog), [catalog]);
|
|
33591
|
+
const allSettingsTabs = React126.useMemo(
|
|
33332
33592
|
() => {
|
|
33333
33593
|
const hidden = new Set(hiddenSettingsTabs ?? []);
|
|
33334
33594
|
const visible = [...coreSettingsTabs, ...settingsTabs].filter((tab) => !hidden.has(tab.id));
|
|
@@ -33351,7 +33611,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33351
33611
|
[coreSettingsTabs, settingsTabs, hiddenSettingsTabs, settingsGroups, verticalByPlugin]
|
|
33352
33612
|
);
|
|
33353
33613
|
usePublishSettingsTabs(allSettingsTabs.map((tab) => tab.id));
|
|
33354
|
-
const navWithSettings =
|
|
33614
|
+
const navWithSettings = React126.useMemo(() => {
|
|
33355
33615
|
if (!showSettings || allSettingsTabs.length === 0) return composedNavigation;
|
|
33356
33616
|
if (composedNavigation.some((item) => item.route === "/settings")) return composedNavigation;
|
|
33357
33617
|
return [...composedNavigation, {
|
|
@@ -33369,7 +33629,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33369
33629
|
const moduleRail = !inSettings && layout === "sidebar" && contextualNav && (path === contextualNav.base || path.startsWith(contextualNav.base + "/")) ? contextualNav : null;
|
|
33370
33630
|
const settingsPathActive = showSettings && (path === "/settings" || path.startsWith("/settings/"));
|
|
33371
33631
|
const activeSettingsTab = settingsPathActive ? path === "/settings" ? null : path.slice("/settings/".length).split("/")[0] : void 0;
|
|
33372
|
-
const settingsTabDef =
|
|
33632
|
+
const settingsTabDef = React126.useMemo(() => {
|
|
33373
33633
|
if (!showSettings || !path.startsWith("/settings/")) return void 0;
|
|
33374
33634
|
const id = path.slice("/settings/".length).split("/")[0];
|
|
33375
33635
|
return allSettingsTabs.find((tab) => tab.id === id);
|
|
@@ -33377,11 +33637,11 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33377
33637
|
const shellUser = user ? { fullName: user.fullName ?? user.email, email: user.email, avatarUrl: user.avatarUrl } : void 0;
|
|
33378
33638
|
const moduleVariant = moduleNav ?? (layout === "sidebar" ? "tabs" : "rail");
|
|
33379
33639
|
const setRailAvailable = useContextualNavStore((s) => s.setRailAvailable);
|
|
33380
|
-
|
|
33640
|
+
React126.useEffect(() => {
|
|
33381
33641
|
setRailAvailable(layout === "sidebar" && moduleVariant !== "rail");
|
|
33382
33642
|
}, [layout, moduleVariant, setRailAvailable]);
|
|
33383
33643
|
const moduleViewLabel = useModuleViewLabel();
|
|
33384
|
-
const activePageTitle =
|
|
33644
|
+
const activePageTitle = React126.useMemo(() => {
|
|
33385
33645
|
if (settingsTabDef) return settingsTabDef.label;
|
|
33386
33646
|
if (path === "/settings" || path.startsWith("/settings/")) return tr("common.settings", "Settings");
|
|
33387
33647
|
if (moduleViewLabel) return moduleViewLabel;
|
|
@@ -33396,7 +33656,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33396
33656
|
if (hiddenHit?.label) return hiddenHit.label;
|
|
33397
33657
|
return candidates.find((n) => n.route === "/")?.label ?? "";
|
|
33398
33658
|
}, [navigation, pages, path, tr, match, settingsTabDef, moduleViewLabel]);
|
|
33399
|
-
const parentBack =
|
|
33659
|
+
const parentBack = React126.useMemo(() => {
|
|
33400
33660
|
if (settingsTabDef) {
|
|
33401
33661
|
const first = allSettingsTabs[0]?.id;
|
|
33402
33662
|
return {
|
|
@@ -33439,9 +33699,9 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33439
33699
|
]
|
|
33440
33700
|
}
|
|
33441
33701
|
);
|
|
33442
|
-
const [railQuery, setRailQuery] =
|
|
33702
|
+
const [railQuery, setRailQuery] = React126.useState("");
|
|
33443
33703
|
const railBase = moduleRail?.base ?? null;
|
|
33444
|
-
|
|
33704
|
+
React126.useEffect(() => {
|
|
33445
33705
|
setRailQuery("");
|
|
33446
33706
|
}, [railBase]);
|
|
33447
33707
|
const railSearch = (placeholder) => /* @__PURE__ */ jsxs("div", { className: "relative px-0.5 pt-1", children: [
|
|
@@ -33645,7 +33905,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
33645
33905
|
]
|
|
33646
33906
|
}
|
|
33647
33907
|
),
|
|
33648
|
-
/* @__PURE__ */ jsx(
|
|
33908
|
+
/* @__PURE__ */ jsx(React126.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
33649
33909
|
CommandPalette,
|
|
33650
33910
|
{
|
|
33651
33911
|
commands: commandItems,
|
|
@@ -33912,7 +34172,7 @@ function buildI18nConfig(config) {
|
|
|
33912
34172
|
function BillingInitializer({ config }) {
|
|
33913
34173
|
const setPlans = useBillingStore((s) => s.setPlans);
|
|
33914
34174
|
const setCheckout = useBillingStore((s) => s.setCheckout);
|
|
33915
|
-
|
|
34175
|
+
React126.useEffect(() => {
|
|
33916
34176
|
if (config.billing?.plans) setPlans(config.billing.plans.map(normalizeBillingPlan));
|
|
33917
34177
|
setCheckout(config.billing?.onCheckout ?? null);
|
|
33918
34178
|
}, [config.billing, setPlans, setCheckout]);
|
|
@@ -34031,13 +34291,13 @@ function ThemeInitializer({ config }) {
|
|
|
34031
34291
|
const rawBranding = useOrganizationStore((s) => s.currentOrg?.settings?.branding);
|
|
34032
34292
|
const access = useAccessOptional();
|
|
34033
34293
|
const wearsOwnSkin = access.entitled("branding.theme");
|
|
34034
|
-
const brandTokens =
|
|
34294
|
+
const brandTokens = React126.useMemo(
|
|
34035
34295
|
() => wearsOwnSkin ? normalizeBrand(rawBranding).tokens : EMPTY_BRAND.tokens,
|
|
34036
34296
|
[rawBranding, wearsOwnSkin]
|
|
34037
34297
|
);
|
|
34038
34298
|
const brandKey = JSON.stringify(brandTokens);
|
|
34039
34299
|
const appTheme = useAppTheme();
|
|
34040
|
-
|
|
34300
|
+
React126.useEffect(() => {
|
|
34041
34301
|
const tokens = JSON.parse(brandKey);
|
|
34042
34302
|
const brand = tokens.color?.primary ? hexToHslTriplet(tokens.color.primary) : null;
|
|
34043
34303
|
const base = appTheme ?? config.theme;
|
|
@@ -34055,20 +34315,20 @@ function ThemeInitializer({ config }) {
|
|
|
34055
34315
|
return null;
|
|
34056
34316
|
}
|
|
34057
34317
|
function PersistentCacheInitializer() {
|
|
34058
|
-
|
|
34318
|
+
React126.useEffect(() => {
|
|
34059
34319
|
attachPersistentCache();
|
|
34060
34320
|
void getPersistentCache()?.hydrate();
|
|
34061
34321
|
}, []);
|
|
34062
34322
|
return null;
|
|
34063
34323
|
}
|
|
34064
34324
|
function FayzEventBridgeInitializer({ config }) {
|
|
34065
|
-
|
|
34325
|
+
React126.useEffect(() => startFayzEventBridge(config.chat?.agent), [config.chat?.agent]);
|
|
34066
34326
|
return null;
|
|
34067
34327
|
}
|
|
34068
34328
|
function TeamInitializer({ config }) {
|
|
34069
34329
|
const setTeamPersonKinds = useOrganizationStore((s) => s.setTeamPersonKinds);
|
|
34070
34330
|
const kinds = config.team?.personKinds;
|
|
34071
|
-
|
|
34331
|
+
React126.useEffect(() => {
|
|
34072
34332
|
setTeamPersonKinds(kinds ?? []);
|
|
34073
34333
|
}, [setTeamPersonKinds, kinds]);
|
|
34074
34334
|
return null;
|
|
@@ -34085,7 +34345,7 @@ function ChatRailPanel({ config }) {
|
|
|
34085
34345
|
const agent = config.chat?.agent;
|
|
34086
34346
|
const voice = config.chat?.voice;
|
|
34087
34347
|
const whatsapp = config.chat?.whatsapp;
|
|
34088
|
-
const Component2 =
|
|
34348
|
+
const Component2 = React126.useMemo(() => {
|
|
34089
34349
|
const Panel = () => /* @__PURE__ */ jsx(
|
|
34090
34350
|
ChatConversation,
|
|
34091
34351
|
{
|
|
@@ -34102,8 +34362,8 @@ function ChatRailPanel({ config }) {
|
|
|
34102
34362
|
const conversations = useChatStore((s) => s.conversations);
|
|
34103
34363
|
const setConversations = useChatStore((s) => s.setConversations);
|
|
34104
34364
|
const user = useAuthStore((s) => s.user);
|
|
34105
|
-
const connection =
|
|
34106
|
-
|
|
34365
|
+
const connection = React126.useMemo(() => resolveFayzAgentConnection(agent), [agent]);
|
|
34366
|
+
React126.useEffect(() => {
|
|
34107
34367
|
if (!connection) return;
|
|
34108
34368
|
getFayzAgentClient(connection).listConversations(user?.id).then(setConversations).catch(() => {
|
|
34109
34369
|
});
|
|
@@ -34112,7 +34372,7 @@ function ChatRailPanel({ config }) {
|
|
|
34112
34372
|
useAssistantInviteStore((s) => s.invite?.id === ASK_AI_HANDOFF_ID);
|
|
34113
34373
|
const activeAgent = useAgent();
|
|
34114
34374
|
const persona = activeAgent?.name ?? invitePersona;
|
|
34115
|
-
const icon =
|
|
34375
|
+
const icon = React126.useMemo(
|
|
34116
34376
|
() => activeAgent ? function AgentTabIcon() {
|
|
34117
34377
|
return /* @__PURE__ */ jsx(
|
|
34118
34378
|
AgentAvatar,
|
|
@@ -34127,7 +34387,7 @@ function ChatRailPanel({ config }) {
|
|
|
34127
34387
|
[activeAgent]
|
|
34128
34388
|
);
|
|
34129
34389
|
useRightRailPanel(
|
|
34130
|
-
|
|
34390
|
+
React126.useMemo(
|
|
34131
34391
|
() => ({
|
|
34132
34392
|
id: "chat",
|
|
34133
34393
|
// "Chat" nomeia o CANO, não o que está do outro lado — e era a única
|
|
@@ -34143,22 +34403,22 @@ function ChatRailPanel({ config }) {
|
|
|
34143
34403
|
[Component2, conversations.length, persona, icon, activeAgent, t]
|
|
34144
34404
|
)
|
|
34145
34405
|
);
|
|
34146
|
-
|
|
34406
|
+
React126.useEffect(() => {
|
|
34147
34407
|
if (chatOpen) openPanel("chat");
|
|
34148
34408
|
}, [chatOpen, openPanel]);
|
|
34149
|
-
|
|
34409
|
+
React126.useEffect(() => {
|
|
34150
34410
|
if (!(railOpen && railActive === "chat")) setChatOpen(false);
|
|
34151
34411
|
}, [railOpen, railActive, setChatOpen]);
|
|
34152
34412
|
return null;
|
|
34153
34413
|
}
|
|
34154
34414
|
function AdminProviders({ config, children }) {
|
|
34155
34415
|
const currentOrg = useOrganizationStore((s) => s.currentOrg);
|
|
34156
|
-
const hasFayzAgent =
|
|
34416
|
+
const hasFayzAgent = React126.useMemo(
|
|
34157
34417
|
() => !!resolveFayzAgentConnection(config.chat?.agent),
|
|
34158
34418
|
[config.chat?.agent]
|
|
34159
34419
|
);
|
|
34160
34420
|
const assistantEnabled = config.chat?.enabled !== false && (!!config.chat || hasFayzAgent);
|
|
34161
|
-
|
|
34421
|
+
React126.useEffect(() => {
|
|
34162
34422
|
if (!config.chat || config.chat.enabled === false || config.chat.apiEndpoint || hasFayzAgent) return;
|
|
34163
34423
|
const gap = describeFayzAgentGap(config.chat.agent);
|
|
34164
34424
|
if (!gap) return;
|
|
@@ -34170,7 +34430,7 @@ function AdminProviders({ config, children }) {
|
|
|
34170
34430
|
const surface = config.chat?.surface ?? "dock";
|
|
34171
34431
|
const onConsentScreen = typeof window !== "undefined" && window.location.pathname.replace(/\/+$/, "").endsWith("/connect");
|
|
34172
34432
|
const showFab = assistantEnabled && surface === "dock" && !onConsentScreen;
|
|
34173
|
-
const resolved =
|
|
34433
|
+
const resolved = React126.useMemo(() => {
|
|
34174
34434
|
if (config.supabaseUrl && config.supabaseAnonKey) {
|
|
34175
34435
|
createFayzSupabaseClient(config.supabaseUrl, config.supabaseAnonKey);
|
|
34176
34436
|
}
|
|
@@ -34188,7 +34448,7 @@ function AdminProviders({ config, children }) {
|
|
|
34188
34448
|
const { bindings, ready: configReady } = useAppConfig();
|
|
34189
34449
|
const offeredPlugins = useOfferedPlugins();
|
|
34190
34450
|
const path = useAdminPath();
|
|
34191
|
-
const runtime =
|
|
34451
|
+
const runtime = React126.useMemo(
|
|
34192
34452
|
() => resolvePluginRuntime({
|
|
34193
34453
|
plugins: resolved.plugins,
|
|
34194
34454
|
// Só as ligações DESTA conta. Na janela da troca o config em mãos ainda
|
|
@@ -34228,7 +34488,7 @@ function AdminProviders({ config, children }) {
|
|
|
34228
34488
|
}),
|
|
34229
34489
|
[resolved.plugins, bindings, offeredPlugins, configReady, path, config.layout, currentOrg]
|
|
34230
34490
|
);
|
|
34231
|
-
|
|
34491
|
+
React126.useEffect(() => {
|
|
34232
34492
|
if (!import.meta.env?.DEV || !currentOrg) return;
|
|
34233
34493
|
const registered = new Set(resolved.plugins.map((p) => p.id));
|
|
34234
34494
|
const bound = new Set(bindings.map((b) => b.pluginId));
|
|
@@ -34582,8 +34842,8 @@ function manifestToFayzConfig(manifest, surfaceName) {
|
|
|
34582
34842
|
};
|
|
34583
34843
|
}
|
|
34584
34844
|
function AdminScaffold({ manifest, surface }) {
|
|
34585
|
-
const config =
|
|
34586
|
-
const authShellProps =
|
|
34845
|
+
const config = React126.useMemo(() => manifestToFayzConfig(manifest, surface), [manifest, surface]);
|
|
34846
|
+
const authShellProps = React126.useMemo(() => getAuthShellProps(config.auth), [config.auth]);
|
|
34587
34847
|
return /* @__PURE__ */ jsx(AdminProviders, { config, children: /* @__PURE__ */ jsx(ScaffoldShell, { config, authShellProps }) });
|
|
34588
34848
|
}
|
|
34589
34849
|
function ScaffoldShell({
|
|
@@ -35021,9 +35281,9 @@ function LookupCreateInline({
|
|
|
35021
35281
|
className
|
|
35022
35282
|
}) {
|
|
35023
35283
|
const t = useTranslation();
|
|
35024
|
-
const [saving, setSaving] =
|
|
35025
|
-
const [error, setError] =
|
|
35026
|
-
const submitForm =
|
|
35284
|
+
const [saving, setSaving] = React126.useState(false);
|
|
35285
|
+
const [error, setError] = React126.useState(null);
|
|
35286
|
+
const submitForm = React126.useRef(null);
|
|
35027
35287
|
async function submit(data) {
|
|
35028
35288
|
setSaving(true);
|
|
35029
35289
|
setError(null);
|
|
@@ -35100,20 +35360,20 @@ function LookupCreateInline({
|
|
|
35100
35360
|
);
|
|
35101
35361
|
}
|
|
35102
35362
|
function useLookupCreate(lookup, onCreated, options = {}) {
|
|
35103
|
-
const [draftName, setDraftName] =
|
|
35363
|
+
const [draftName, setDraftName] = React126.useState(null);
|
|
35104
35364
|
const can = usePermissionOptional();
|
|
35105
35365
|
const entityDef = lookup?.entityDef;
|
|
35106
35366
|
const feature = entityDef?.permission?.feature;
|
|
35107
35367
|
const allowed = !feature || can(feature, "create");
|
|
35108
35368
|
const canCreate = !!lookup?.create && allowed;
|
|
35109
35369
|
const canEdit = !!entityDef && !!lookup?.load && !!lookup?.update && (!feature || can(feature, "edit"));
|
|
35110
|
-
const [editingId, setEditingId] =
|
|
35111
|
-
const onEdit =
|
|
35112
|
-
const createByName =
|
|
35370
|
+
const [editingId, setEditingId] = React126.useState(null);
|
|
35371
|
+
const onEdit = React126.useMemo(() => canEdit ? (id) => setEditingId(id) : void 0, [canEdit]);
|
|
35372
|
+
const createByName = React126.useCallback(async (name) => {
|
|
35113
35373
|
if (!lookup?.create) return;
|
|
35114
35374
|
onCreated(await lookup.create({ name }));
|
|
35115
35375
|
}, [lookup, onCreated]);
|
|
35116
|
-
const onCreate =
|
|
35376
|
+
const onCreate = React126.useMemo(() => {
|
|
35117
35377
|
if (!canCreate) return void 0;
|
|
35118
35378
|
if (!entityDef) return (name) => {
|
|
35119
35379
|
void createByName(name);
|
|
@@ -35220,8 +35480,8 @@ function OrderFormItemRow({
|
|
|
35220
35480
|
const rawKindLabel = itemTypes.find((tp) => tp.value === itemKind)?.label ?? itemKind;
|
|
35221
35481
|
const kindLabel = !itemKind || itemKind === "other" ? null : rawKindLabel;
|
|
35222
35482
|
const hasAdjustments = (discount ?? 0) > 0 || (surcharge ?? 0) > 0;
|
|
35223
|
-
const [showAdjustments, setShowAdjustments] =
|
|
35224
|
-
const [openExtras, setOpenExtras] =
|
|
35483
|
+
const [showAdjustments, setShowAdjustments] = React126.useState(hasAdjustments);
|
|
35484
|
+
const [openExtras, setOpenExtras] = React126.useState(
|
|
35225
35485
|
() => (extraFieldGroups ?? []).filter((g) => g.filled).map((g) => g.id)
|
|
35226
35486
|
);
|
|
35227
35487
|
const lookup = entityLookups[itemKind];
|
|
@@ -35615,13 +35875,13 @@ function OrderFormSkeleton({ parentLabel, onBack } = {}) {
|
|
|
35615
35875
|
] });
|
|
35616
35876
|
}
|
|
35617
35877
|
function useCatalogedItemTypes(itemTypes, lookups) {
|
|
35618
|
-
const countable =
|
|
35878
|
+
const countable = React126.useMemo(
|
|
35619
35879
|
() => itemTypes.filter((tp) => typeof lookups[tp.value]?.count === "function").map((tp) => tp.value),
|
|
35620
35880
|
[itemTypes, lookups]
|
|
35621
35881
|
);
|
|
35622
|
-
const [empty, setEmpty] =
|
|
35882
|
+
const [empty, setEmpty] = React126.useState([]);
|
|
35623
35883
|
const key = countable.join(",");
|
|
35624
|
-
|
|
35884
|
+
React126.useEffect(() => {
|
|
35625
35885
|
if (!countable.length) {
|
|
35626
35886
|
setEmpty([]);
|
|
35627
35887
|
return;
|
|
@@ -35640,7 +35900,7 @@ function useCatalogedItemTypes(itemTypes, lookups) {
|
|
|
35640
35900
|
cancelled = true;
|
|
35641
35901
|
};
|
|
35642
35902
|
}, [key, lookups]);
|
|
35643
|
-
return
|
|
35903
|
+
return React126.useMemo(
|
|
35644
35904
|
() => empty.length ? itemTypes.filter((tp) => !empty.includes(tp.value)) : itemTypes,
|
|
35645
35905
|
[itemTypes, empty]
|
|
35646
35906
|
);
|
|
@@ -35912,7 +36172,7 @@ function OrderCreateScreen({
|
|
|
35912
36172
|
errorActions,
|
|
35913
36173
|
saveBar
|
|
35914
36174
|
}) {
|
|
35915
|
-
const subtotal =
|
|
36175
|
+
const subtotal = React126.useMemo(
|
|
35916
36176
|
() => lines.reduce((sum, line) => sum + line.unitPrice * line.quantity, 0),
|
|
35917
36177
|
[lines]
|
|
35918
36178
|
);
|
|
@@ -36063,7 +36323,7 @@ function mergeLines(current2, incoming) {
|
|
|
36063
36323
|
return merged;
|
|
36064
36324
|
}
|
|
36065
36325
|
function ItemPicker({ search, onPick }) {
|
|
36066
|
-
const [open, setOpen] =
|
|
36326
|
+
const [open, setOpen] = React126.useState(false);
|
|
36067
36327
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
36068
36328
|
/* @__PURE__ */ jsxs(
|
|
36069
36329
|
"button",
|
|
@@ -36141,9 +36401,9 @@ function KanbanBoard({
|
|
|
36141
36401
|
toolbarActions
|
|
36142
36402
|
}) {
|
|
36143
36403
|
const collapsible = !!onToggleColumn;
|
|
36144
|
-
const frameRef =
|
|
36145
|
-
const [hoveredCol, setHoveredCol] =
|
|
36146
|
-
const centerFocused =
|
|
36404
|
+
const frameRef = React126.useRef(null);
|
|
36405
|
+
const [hoveredCol, setHoveredCol] = React126.useState(null);
|
|
36406
|
+
const centerFocused = React126.useCallback((event) => {
|
|
36147
36407
|
const frame = frameRef.current;
|
|
36148
36408
|
const column = event.target?.closest("[data-kanban-column]");
|
|
36149
36409
|
if (!frame || !column || frame.scrollWidth <= frame.clientWidth) return;
|
|
@@ -36152,12 +36412,61 @@ function KanbanBoard({
|
|
|
36152
36412
|
const delta = columnBox.left + columnBox.width / 2 - (frameBox.left + frameBox.width / 2);
|
|
36153
36413
|
if (Math.abs(delta) > 1) frame.scrollBy({ left: delta, behavior: "smooth" });
|
|
36154
36414
|
}, []);
|
|
36415
|
+
const autoScroll = React126.useRef(null);
|
|
36416
|
+
const scrollStep = React126.useRef(0);
|
|
36417
|
+
const stopAutoScroll = React126.useCallback(() => {
|
|
36418
|
+
if (autoScroll.current !== null) cancelAnimationFrame(autoScroll.current);
|
|
36419
|
+
autoScroll.current = null;
|
|
36420
|
+
scrollStep.current = 0;
|
|
36421
|
+
}, []);
|
|
36422
|
+
const tickAutoScroll = React126.useCallback(() => {
|
|
36423
|
+
const frame = frameRef.current;
|
|
36424
|
+
if (!frame || scrollStep.current === 0) {
|
|
36425
|
+
stopAutoScroll();
|
|
36426
|
+
return;
|
|
36427
|
+
}
|
|
36428
|
+
const antes = frame.scrollLeft;
|
|
36429
|
+
frame.scrollLeft = antes + scrollStep.current;
|
|
36430
|
+
if (frame.scrollLeft === antes) {
|
|
36431
|
+
stopAutoScroll();
|
|
36432
|
+
return;
|
|
36433
|
+
}
|
|
36434
|
+
autoScroll.current = requestAnimationFrame(tickAutoScroll);
|
|
36435
|
+
}, [stopAutoScroll]);
|
|
36436
|
+
const onFrameDragOver = React126.useCallback((event) => {
|
|
36437
|
+
const frame = frameRef.current;
|
|
36438
|
+
if (!frame || frame.scrollWidth <= frame.clientWidth) return;
|
|
36439
|
+
const box = frame.getBoundingClientRect();
|
|
36440
|
+
const faixa = 112;
|
|
36441
|
+
const maximo = 22;
|
|
36442
|
+
const daEsquerda = event.clientX - box.left;
|
|
36443
|
+
const daDireita = box.right - event.clientX;
|
|
36444
|
+
let passo = 0;
|
|
36445
|
+
if (daEsquerda < faixa) passo = -maximo * (1 - Math.max(daEsquerda, 0) / faixa);
|
|
36446
|
+
else if (daDireita < faixa) passo = maximo * (1 - Math.max(daDireita, 0) / faixa);
|
|
36447
|
+
scrollStep.current = passo;
|
|
36448
|
+
if (passo === 0) {
|
|
36449
|
+
stopAutoScroll();
|
|
36450
|
+
return;
|
|
36451
|
+
}
|
|
36452
|
+
if (autoScroll.current === null) autoScroll.current = requestAnimationFrame(tickAutoScroll);
|
|
36453
|
+
}, [stopAutoScroll, tickAutoScroll]);
|
|
36454
|
+
const onFrameDragLeave = React126.useCallback((event) => {
|
|
36455
|
+
const indo = event.relatedTarget;
|
|
36456
|
+
if (indo && event.currentTarget.contains(indo)) return;
|
|
36457
|
+
stopAutoScroll();
|
|
36458
|
+
}, [stopAutoScroll]);
|
|
36459
|
+
React126.useEffect(() => stopAutoScroll, [stopAutoScroll]);
|
|
36155
36460
|
const hasToolbar = !!onSearchChange || !!onRefresh || !!toolbarActions;
|
|
36156
36461
|
const board = /* @__PURE__ */ jsx(
|
|
36157
36462
|
"div",
|
|
36158
36463
|
{
|
|
36159
36464
|
ref: frameRef,
|
|
36160
36465
|
onFocus: centerFocused,
|
|
36466
|
+
onDragOver: dropProps ? onFrameDragOver : void 0,
|
|
36467
|
+
onDragLeave: dropProps ? onFrameDragLeave : void 0,
|
|
36468
|
+
onDrop: dropProps ? stopAutoScroll : void 0,
|
|
36469
|
+
onDragEnd: dropProps ? stopAutoScroll : void 0,
|
|
36161
36470
|
className: `flex gap-3 overflow-x-auto pb-2 ${fitViewport ? "min-h-0 items-stretch" : ""} ${hasToolbar ? "" : className}`,
|
|
36162
36471
|
style: fitViewport ? { height: "calc(100dvh - 11rem)", minHeight: "20rem" } : void 0,
|
|
36163
36472
|
children: columns.map((column) => {
|
|
@@ -36255,10 +36564,10 @@ function BoardFrame({
|
|
|
36255
36564
|
toolbarActions,
|
|
36256
36565
|
className = ""
|
|
36257
36566
|
}) {
|
|
36258
|
-
const [open, setOpen] =
|
|
36259
|
-
const inputRef =
|
|
36567
|
+
const [open, setOpen] = React126.useState(false);
|
|
36568
|
+
const inputRef = React126.useRef(null);
|
|
36260
36569
|
const expanded = open || !!search;
|
|
36261
|
-
|
|
36570
|
+
React126.useEffect(() => {
|
|
36262
36571
|
if (open) inputRef.current?.focus();
|
|
36263
36572
|
}, [open]);
|
|
36264
36573
|
function collapse() {
|
|
@@ -36337,14 +36646,14 @@ function OrderBoardView({
|
|
|
36337
36646
|
rowId,
|
|
36338
36647
|
selectedRowId
|
|
36339
36648
|
}) {
|
|
36340
|
-
const getId =
|
|
36649
|
+
const getId = React126.useCallback(
|
|
36341
36650
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
36342
36651
|
[rowId]
|
|
36343
36652
|
);
|
|
36344
|
-
const [lastClicked, setLastClicked] =
|
|
36345
|
-
const [advancing, setAdvancing] =
|
|
36653
|
+
const [lastClicked, setLastClicked] = React126.useState(null);
|
|
36654
|
+
const [advancing, setAdvancing] = React126.useState({});
|
|
36346
36655
|
const selected = selectedRowId !== void 0 ? selectedRowId : lastClicked;
|
|
36347
|
-
const grouped =
|
|
36656
|
+
const grouped = React126.useMemo(() => {
|
|
36348
36657
|
const map = /* @__PURE__ */ new Map();
|
|
36349
36658
|
for (const col of board.columns) map.set(col.id, []);
|
|
36350
36659
|
for (const row of rows) {
|
|
@@ -36468,24 +36777,24 @@ function OrderListView({
|
|
|
36468
36777
|
boards,
|
|
36469
36778
|
viewKey
|
|
36470
36779
|
}) {
|
|
36471
|
-
const [search, setSearch] =
|
|
36472
|
-
const [page, setPage] =
|
|
36473
|
-
const [rawSelection, setRawSelection] =
|
|
36474
|
-
const offered =
|
|
36780
|
+
const [search, setSearch] = React126.useState("");
|
|
36781
|
+
const [page, setPage] = React126.useState(1);
|
|
36782
|
+
const [rawSelection, setRawSelection] = React126.useState([]);
|
|
36783
|
+
const offered = React126.useMemo(
|
|
36475
36784
|
() => views && views.length > 0 ? views : ["list"],
|
|
36476
36785
|
[views]
|
|
36477
36786
|
);
|
|
36478
|
-
const customFor =
|
|
36787
|
+
const customFor = React126.useCallback(
|
|
36479
36788
|
(id) => boards?.[id]?.render ?? null,
|
|
36480
36789
|
[boards]
|
|
36481
36790
|
);
|
|
36482
|
-
const boardFor =
|
|
36791
|
+
const boardFor = React126.useCallback(
|
|
36483
36792
|
(id) => (id === "board" ? board : boards?.[id]?.config) ?? null,
|
|
36484
36793
|
[board, boards]
|
|
36485
36794
|
);
|
|
36486
36795
|
const canBoard = offered.length > 1 && offered.some((id) => id !== "list" && (!!boardFor(id) || !!customFor(id)));
|
|
36487
36796
|
const storageKey2 = viewKey ? `fayz.orderView.${viewKey}` : null;
|
|
36488
|
-
const [view, setView] =
|
|
36797
|
+
const [view, setView] = React126.useState(() => {
|
|
36489
36798
|
const fallback = offered.includes(defaultView) ? defaultView : offered[0];
|
|
36490
36799
|
if (!storageKey2) return fallback;
|
|
36491
36800
|
try {
|
|
@@ -36495,7 +36804,7 @@ function OrderListView({
|
|
|
36495
36804
|
return fallback;
|
|
36496
36805
|
}
|
|
36497
36806
|
});
|
|
36498
|
-
const viewTabs =
|
|
36807
|
+
const viewTabs = React126.useMemo(
|
|
36499
36808
|
() => offered.map((option) => ({
|
|
36500
36809
|
value: option,
|
|
36501
36810
|
label: option === "list" ? "Lista" : boards?.[option]?.label ?? "Quadro",
|
|
@@ -36503,7 +36812,7 @@ function OrderListView({
|
|
|
36503
36812
|
})),
|
|
36504
36813
|
[offered, boards]
|
|
36505
36814
|
);
|
|
36506
|
-
const chooseView =
|
|
36815
|
+
const chooseView = React126.useCallback((next) => {
|
|
36507
36816
|
setView(next);
|
|
36508
36817
|
if (!storageKey2) return;
|
|
36509
36818
|
try {
|
|
@@ -36521,7 +36830,7 @@ function OrderListView({
|
|
|
36521
36830
|
const activeBoard = view === "list" ? null : boardFor(view);
|
|
36522
36831
|
const activeCustom = view === "list" ? null : customFor(view);
|
|
36523
36832
|
const showingBoard = !!activeBoard || !!activeCustom;
|
|
36524
|
-
const cols =
|
|
36833
|
+
const cols = React126.useMemo(
|
|
36525
36834
|
() => columns.map((c) => ({
|
|
36526
36835
|
id: c.key,
|
|
36527
36836
|
header: () => /* @__PURE__ */ jsx("div", { className: c.align === "right" ? "text-right" : "", children: c.header }),
|
|
@@ -36529,25 +36838,25 @@ function OrderListView({
|
|
|
36529
36838
|
})),
|
|
36530
36839
|
[columns]
|
|
36531
36840
|
);
|
|
36532
|
-
const filtered =
|
|
36841
|
+
const filtered = React126.useMemo(() => {
|
|
36533
36842
|
const term = search.trim().toLowerCase();
|
|
36534
36843
|
if (!term || !searchText) return rows;
|
|
36535
36844
|
return rows.filter((row) => searchText(row).toLowerCase().includes(term));
|
|
36536
36845
|
}, [rows, search, searchText]);
|
|
36537
|
-
|
|
36846
|
+
React126.useEffect(() => {
|
|
36538
36847
|
setPage(1);
|
|
36539
36848
|
}, [search]);
|
|
36540
36849
|
const paged = pageSize > 0 ? filtered.slice((page - 1) * pageSize, page * pageSize) : filtered;
|
|
36541
|
-
const getId =
|
|
36850
|
+
const getId = React126.useCallback(
|
|
36542
36851
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
36543
36852
|
[rowId]
|
|
36544
36853
|
);
|
|
36545
|
-
const pageIds =
|
|
36546
|
-
const selectedIds =
|
|
36854
|
+
const pageIds = React126.useMemo(() => paged.map(getId), [paged, getId]);
|
|
36855
|
+
const selectedIds = React126.useMemo(
|
|
36547
36856
|
() => rawSelection.filter((id) => pageIds.includes(id)),
|
|
36548
36857
|
[rawSelection, pageIds]
|
|
36549
36858
|
);
|
|
36550
|
-
const selectedRows =
|
|
36859
|
+
const selectedRows = React126.useMemo(
|
|
36551
36860
|
() => paged.filter((row) => selectedIds.includes(getId(row))),
|
|
36552
36861
|
[paged, selectedIds, getId]
|
|
36553
36862
|
);
|
|
@@ -36697,13 +37006,13 @@ function PaymentStatusBadge({
|
|
|
36697
37006
|
receiveLabel = "Receber",
|
|
36698
37007
|
onOpenDetails
|
|
36699
37008
|
}) {
|
|
36700
|
-
const [open, setOpen] =
|
|
36701
|
-
const [lines, setLines] =
|
|
36702
|
-
const timer =
|
|
36703
|
-
|
|
37009
|
+
const [open, setOpen] = React126__default.useState(false);
|
|
37010
|
+
const [lines, setLines] = React126__default.useState(null);
|
|
37011
|
+
const timer = React126__default.useRef(null);
|
|
37012
|
+
React126__default.useEffect(() => {
|
|
36704
37013
|
setLines(null);
|
|
36705
37014
|
}, [status, paidAmount]);
|
|
36706
|
-
const load =
|
|
37015
|
+
const load = React126__default.useCallback(() => {
|
|
36707
37016
|
if (lines || !onLoadDetails) return;
|
|
36708
37017
|
void onLoadDetails().then(setLines).catch(() => setLines([]));
|
|
36709
37018
|
}, [lines, onLoadDetails]);
|
|
@@ -36838,13 +37147,13 @@ function invalidateOrdersPaymentStatus(orderId) {
|
|
|
36838
37147
|
else cache2.clear();
|
|
36839
37148
|
}
|
|
36840
37149
|
function useOrdersPaymentStatus(orderIds) {
|
|
36841
|
-
const key =
|
|
37150
|
+
const key = React126.useMemo(
|
|
36842
37151
|
() => Array.from(new Set(orderIds.filter(Boolean))).sort().join(","),
|
|
36843
37152
|
[orderIds]
|
|
36844
37153
|
);
|
|
36845
|
-
const [byOrder, setByOrder] =
|
|
36846
|
-
const [loading, setLoading] =
|
|
36847
|
-
const load =
|
|
37154
|
+
const [byOrder, setByOrder] = React126.useState(() => /* @__PURE__ */ new Map());
|
|
37155
|
+
const [loading, setLoading] = React126.useState(false);
|
|
37156
|
+
const load = React126.useCallback(async (force = false) => {
|
|
36848
37157
|
const ids = key ? key.split(",") : [];
|
|
36849
37158
|
if (ids.length === 0) {
|
|
36850
37159
|
setByOrder(/* @__PURE__ */ new Map());
|
|
@@ -36875,7 +37184,7 @@ function useOrdersPaymentStatus(orderIds) {
|
|
|
36875
37184
|
}
|
|
36876
37185
|
setByOrder(new Map(ids.map((id) => [id, cache2.get(id)]).filter(([, v]) => Boolean(v))));
|
|
36877
37186
|
}, [key]);
|
|
36878
|
-
|
|
37187
|
+
React126.useEffect(() => {
|
|
36879
37188
|
void load();
|
|
36880
37189
|
}, [load]);
|
|
36881
37190
|
return { byOrder, loading, reload: () => load(true) };
|
|
@@ -36942,12 +37251,12 @@ function money(value, currency) {
|
|
|
36942
37251
|
return value.toLocaleString("pt-BR", { style: "currency", currency: currency || "BRL" });
|
|
36943
37252
|
}
|
|
36944
37253
|
function useOrderDetail(orderId) {
|
|
36945
|
-
const [order, setOrder] =
|
|
36946
|
-
const [loading, setLoading] =
|
|
36947
|
-
const [error, setError] =
|
|
36948
|
-
const [nonce, setNonce] =
|
|
36949
|
-
const reload =
|
|
36950
|
-
|
|
37254
|
+
const [order, setOrder] = React126.useState(null);
|
|
37255
|
+
const [loading, setLoading] = React126.useState(false);
|
|
37256
|
+
const [error, setError] = React126.useState(null);
|
|
37257
|
+
const [nonce, setNonce] = React126.useState(0);
|
|
37258
|
+
const reload = React126.useCallback(() => setNonce((n) => n + 1), []);
|
|
37259
|
+
React126.useEffect(() => {
|
|
36951
37260
|
if (!orderId) {
|
|
36952
37261
|
setOrder(null);
|
|
36953
37262
|
setError(null);
|
|
@@ -37064,8 +37373,8 @@ function OrderDetailRail({
|
|
|
37064
37373
|
}) {
|
|
37065
37374
|
const { order, loading, error, reload } = useOrderDetail(orderId);
|
|
37066
37375
|
const { byOrder: paymentByOrder } = useOrdersPaymentStatus([orderId]);
|
|
37067
|
-
const [running, setRunning] =
|
|
37068
|
-
const [pending2, setPending] =
|
|
37376
|
+
const [running, setRunning] = React126.useState(null);
|
|
37377
|
+
const [pending2, setPending] = React126.useState(null);
|
|
37069
37378
|
const perform = async (action) => {
|
|
37070
37379
|
if (!order) return;
|
|
37071
37380
|
setRunning(action.id);
|
|
@@ -37223,11 +37532,11 @@ function receivableTone(value) {
|
|
|
37223
37532
|
return "warning";
|
|
37224
37533
|
}
|
|
37225
37534
|
function useOrderReceivable(orderId) {
|
|
37226
|
-
const [receivable, setReceivable] =
|
|
37535
|
+
const [receivable, setReceivable] = React126.useState(
|
|
37227
37536
|
() => orderId ? cache3.get(orderId) ?? null : null
|
|
37228
37537
|
);
|
|
37229
|
-
const [loading, setLoading] =
|
|
37230
|
-
const reload =
|
|
37538
|
+
const [loading, setLoading] = React126.useState(() => Boolean(orderId) && !cache3.has(orderId));
|
|
37539
|
+
const reload = React126.useCallback(async (force = false) => {
|
|
37231
37540
|
if (!orderId) return;
|
|
37232
37541
|
const db2 = getSupabaseClientOptional();
|
|
37233
37542
|
if (!db2) {
|
|
@@ -37250,7 +37559,7 @@ function useOrderReceivable(orderId) {
|
|
|
37250
37559
|
setReceivable(next);
|
|
37251
37560
|
setLoading(false);
|
|
37252
37561
|
}, [orderId]);
|
|
37253
|
-
|
|
37562
|
+
React126.useEffect(() => {
|
|
37254
37563
|
void reload();
|
|
37255
37564
|
}, [reload]);
|
|
37256
37565
|
return { receivable, loading, reload };
|
|
@@ -37403,15 +37712,15 @@ function linesOf(order) {
|
|
|
37403
37712
|
}
|
|
37404
37713
|
function useOrderEditor(orderId) {
|
|
37405
37714
|
const { order, loading, error } = useOrderDetail(orderId);
|
|
37406
|
-
const [lines, setLines] =
|
|
37407
|
-
const [saving, setSaving] =
|
|
37408
|
-
const originalRef =
|
|
37409
|
-
|
|
37715
|
+
const [lines, setLines] = React126.useState([]);
|
|
37716
|
+
const [saving, setSaving] = React126.useState(false);
|
|
37717
|
+
const originalRef = React126.useRef([]);
|
|
37718
|
+
React126.useEffect(() => {
|
|
37410
37719
|
const seeded = linesOf(order);
|
|
37411
37720
|
originalRef.current = seeded;
|
|
37412
37721
|
setLines(seeded);
|
|
37413
37722
|
}, [order]);
|
|
37414
|
-
const dirty =
|
|
37723
|
+
const dirty = React126.useMemo(() => {
|
|
37415
37724
|
const before = originalRef.current;
|
|
37416
37725
|
if (before.length !== lines.length) return true;
|
|
37417
37726
|
return lines.some((line, i) => {
|
|
@@ -37419,7 +37728,7 @@ function useOrderEditor(orderId) {
|
|
|
37419
37728
|
return !was || was.key !== line.key || was.quantity !== line.quantity || was.unitPrice !== line.unitPrice;
|
|
37420
37729
|
});
|
|
37421
37730
|
}, [lines]);
|
|
37422
|
-
const save =
|
|
37731
|
+
const save = React126.useCallback(async () => {
|
|
37423
37732
|
if (!orderId || !order) return { ok: false, error: "Pedido n\xE3o carregado" };
|
|
37424
37733
|
const db2 = getSupabaseClientOptional();
|
|
37425
37734
|
if (!db2) return { ok: false, error: "Sem conex\xE3o" };
|
|
@@ -37576,19 +37885,19 @@ function createClientOrdersProvider() {
|
|
|
37576
37885
|
}
|
|
37577
37886
|
function createPlaceholder(title, description) {
|
|
37578
37887
|
return function PlaceholderPage() {
|
|
37579
|
-
return
|
|
37888
|
+
return React126__default.createElement(
|
|
37580
37889
|
"div",
|
|
37581
37890
|
{ className: "mx-auto max-w-4xl" },
|
|
37582
|
-
|
|
37583
|
-
description ?
|
|
37584
|
-
|
|
37891
|
+
React126__default.createElement("h1", { className: "text-3xl font-bold text-foreground" }, title),
|
|
37892
|
+
description ? React126__default.createElement("p", { className: "mt-1 text-muted-foreground" }, description) : null,
|
|
37893
|
+
React126__default.createElement(
|
|
37585
37894
|
"div",
|
|
37586
37895
|
{ className: "mt-8 flex items-center justify-center rounded-card border border-dashed border-border bg-card p-16" },
|
|
37587
|
-
|
|
37896
|
+
React126__default.createElement(
|
|
37588
37897
|
"div",
|
|
37589
37898
|
{ className: "text-center" },
|
|
37590
|
-
|
|
37591
|
-
|
|
37899
|
+
React126__default.createElement("p", { className: "text-lg font-medium text-muted-foreground" }, "Coming Soon"),
|
|
37900
|
+
React126__default.createElement(
|
|
37592
37901
|
"p",
|
|
37593
37902
|
{ className: "mt-1 text-sm text-muted-foreground/70" },
|
|
37594
37903
|
"This module is being built as a plugin."
|
|
@@ -37669,7 +37978,7 @@ function ModuleActionBar({
|
|
|
37669
37978
|
trailing
|
|
37670
37979
|
}) {
|
|
37671
37980
|
const t = useTranslation();
|
|
37672
|
-
const actions =
|
|
37981
|
+
const actions = React126__default.useMemo(() => {
|
|
37673
37982
|
const out = (quickActions ?? []).map((qa, i) => ({
|
|
37674
37983
|
id: qa.id,
|
|
37675
37984
|
label: qa.label,
|
|
@@ -37701,9 +38010,9 @@ function ModuleActionBar({
|
|
|
37701
38010
|
] });
|
|
37702
38011
|
}
|
|
37703
38012
|
function createPluginContext(displayName) {
|
|
37704
|
-
const ConfigContext =
|
|
37705
|
-
const ProviderContext =
|
|
37706
|
-
const StoreContext =
|
|
38013
|
+
const ConfigContext = React126__default.createContext(null);
|
|
38014
|
+
const ProviderContext = React126__default.createContext(null);
|
|
38015
|
+
const StoreContext = React126__default.createContext(null);
|
|
37707
38016
|
const ContextProvider = ({
|
|
37708
38017
|
config,
|
|
37709
38018
|
provider: provider2,
|
|
@@ -37712,17 +38021,17 @@ function createPluginContext(displayName) {
|
|
|
37712
38021
|
}) => /* @__PURE__ */ jsx(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsx(ProviderContext.Provider, { value: provider2, children: /* @__PURE__ */ jsx(StoreContext.Provider, { value: store, children }) }) });
|
|
37713
38022
|
ContextProvider.displayName = `${displayName}ContextProvider`;
|
|
37714
38023
|
function useConfig() {
|
|
37715
|
-
const ctx =
|
|
38024
|
+
const ctx = React126__default.useContext(ConfigContext);
|
|
37716
38025
|
if (!ctx) throw new Error(`useConfig must be used within ${displayName}`);
|
|
37717
38026
|
return ctx;
|
|
37718
38027
|
}
|
|
37719
38028
|
function useProvider() {
|
|
37720
|
-
const ctx =
|
|
38029
|
+
const ctx = React126__default.useContext(ProviderContext);
|
|
37721
38030
|
if (!ctx) throw new Error(`useProvider must be used within ${displayName}`);
|
|
37722
38031
|
return ctx;
|
|
37723
38032
|
}
|
|
37724
38033
|
function useStore2(selector) {
|
|
37725
|
-
const store =
|
|
38034
|
+
const store = React126__default.useContext(StoreContext);
|
|
37726
38035
|
if (!store) throw new Error(`useStore must be used within ${displayName}`);
|
|
37727
38036
|
return useStore$1(store, selector);
|
|
37728
38037
|
}
|
|
@@ -37779,7 +38088,7 @@ function PluginRegistryManager({ registries, routeBase, className }) {
|
|
|
37779
38088
|
return registries[0]?.id ?? "";
|
|
37780
38089
|
};
|
|
37781
38090
|
const [activeTab, setActiveTab] = useState(getTabFromHash);
|
|
37782
|
-
|
|
38091
|
+
React126__default.useEffect(() => {
|
|
37783
38092
|
if (!routeBase) return;
|
|
37784
38093
|
const handler = () => setActiveTab(getTabFromHash());
|
|
37785
38094
|
window.addEventListener("hashchange", handler);
|
|
@@ -37947,7 +38256,7 @@ function formatAge(dob) {
|
|
|
37947
38256
|
return null;
|
|
37948
38257
|
}
|
|
37949
38258
|
}
|
|
37950
|
-
function PersonLink2({ personId, name, lookup, kind, profileHref, tab, size = "default", className }) {
|
|
38259
|
+
function PersonLink2({ personId, name, avatarUrl, lookup, kind, profileHref, tab, size = "default", className }) {
|
|
37951
38260
|
const t = useTranslation();
|
|
37952
38261
|
const [person, setPerson] = useState(null);
|
|
37953
38262
|
const [loading, setLoading] = useState(false);
|
|
@@ -37990,7 +38299,7 @@ function PersonLink2({ personId, name, lookup, kind, profileHref, tab, size = "d
|
|
|
37990
38299
|
const email = data?.email;
|
|
37991
38300
|
const phone = data?.phone;
|
|
37992
38301
|
const resolvedKind = kind ?? data?.kind ?? person?.group;
|
|
37993
|
-
const actions =
|
|
38302
|
+
const actions = React126__default.useMemo(
|
|
37994
38303
|
() => personId ? getPersonActions(resolvedKind) : [],
|
|
37995
38304
|
[personId, resolvedKind]
|
|
37996
38305
|
);
|
|
@@ -37999,7 +38308,7 @@ function PersonLink2({ personId, name, lookup, kind, profileHref, tab, size = "d
|
|
|
37999
38308
|
const dob = data?.date_of_birth;
|
|
38000
38309
|
const createdAt = data?.created_at;
|
|
38001
38310
|
const age = dob ? formatAge(dob) : null;
|
|
38002
|
-
const
|
|
38311
|
+
const photo = avatarUrl ?? data?.avatar_url ?? data?.avatarUrl ?? null;
|
|
38003
38312
|
const registeredPath = kind ? getPersonPath(kind) : null;
|
|
38004
38313
|
const temRotaDeVerdade = entityRouteHasDetail("person", resolvedKind ?? void 0);
|
|
38005
38314
|
const resolvedHref = profileHref ?? (temRotaDeVerdade ? resolveEntityAnchor(personId, "person", resolvedKind ?? void 0, tab) : void 0) ?? (registeredPath ? `#${registeredPath}/${personId}${tab ? `/${tab}` : ""}` : void 0);
|
|
@@ -38038,7 +38347,7 @@ function PersonLink2({ personId, name, lookup, kind, profileHref, tab, size = "d
|
|
|
38038
38347
|
] })
|
|
38039
38348
|
] }) : /* @__PURE__ */ jsxs("div", { children: [
|
|
38040
38349
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 p-4 pb-3", children: [
|
|
38041
|
-
/* @__PURE__ */ jsx(
|
|
38350
|
+
/* @__PURE__ */ jsx(PersonAvatar, { name, src: photo, size: "lg" }),
|
|
38042
38351
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
38043
38352
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold truncate", children: name }),
|
|
38044
38353
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mt-0.5", children: [
|
|
@@ -38685,10 +38994,10 @@ function useTeachMe(def) {
|
|
|
38685
38994
|
return useFeatureHelp(def).teach;
|
|
38686
38995
|
}
|
|
38687
38996
|
function useFeatureHelp(def) {
|
|
38688
|
-
const ref =
|
|
38997
|
+
const ref = React126.useRef(def);
|
|
38689
38998
|
ref.current = def;
|
|
38690
38999
|
const id = `teach.${def.feature}`;
|
|
38691
|
-
const contribution =
|
|
39000
|
+
const contribution = React126.useMemo(
|
|
38692
39001
|
() => ({
|
|
38693
39002
|
id,
|
|
38694
39003
|
pluginId: "teach-me",
|
|
@@ -38722,7 +39031,7 @@ function useFeatureHelp(def) {
|
|
|
38722
39031
|
[id]
|
|
38723
39032
|
);
|
|
38724
39033
|
useAgentSurface(contribution);
|
|
38725
|
-
return
|
|
39034
|
+
return React126.useMemo(
|
|
38726
39035
|
() => ({
|
|
38727
39036
|
help: () => helpWith(ref.current),
|
|
38728
39037
|
teach: () => teachMe(ref.current),
|
|
@@ -38888,21 +39197,21 @@ function ConnectorsHub({ hostPluginId }) {
|
|
|
38888
39197
|
const { t } = useTranslation$1();
|
|
38889
39198
|
const { connectors, reload } = useConnectors({ includeGrants: false });
|
|
38890
39199
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
38891
|
-
const [selected, setSelected] =
|
|
38892
|
-
const [adding, setAdding] =
|
|
38893
|
-
const hosted =
|
|
39200
|
+
const [selected, setSelected] = React126__default.useState(null);
|
|
39201
|
+
const [adding, setAdding] = React126__default.useState(false);
|
|
39202
|
+
const hosted = React126__default.useMemo(
|
|
38894
39203
|
() => (connectors ?? []).filter((c) => c.hostPluginId === hostPluginId),
|
|
38895
39204
|
[connectors, hostPluginId]
|
|
38896
39205
|
);
|
|
38897
|
-
const categories =
|
|
39206
|
+
const categories = React126__default.useMemo(
|
|
38898
39207
|
() => [...new Set(hosted.map((c) => c.category).filter((c) => !!c))],
|
|
38899
39208
|
[hosted]
|
|
38900
39209
|
);
|
|
38901
|
-
const scoped =
|
|
39210
|
+
const scoped = React126__default.useMemo(() => {
|
|
38902
39211
|
const siblings = inCategories(connectors ?? [], categories).filter((c) => c.hostPluginId !== hostPluginId);
|
|
38903
39212
|
return [...hosted, ...siblings];
|
|
38904
39213
|
}, [connectors, hosted, categories, hostPluginId]);
|
|
38905
|
-
|
|
39214
|
+
React126__default.useEffect(() => {
|
|
38906
39215
|
if (!selected || !connectors) return;
|
|
38907
39216
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
38908
39217
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -39078,7 +39387,7 @@ function PluginSettingsPanel({ title, generalSettings, registries, customTabs, r
|
|
|
39078
39387
|
return tabs[0]?.id ?? "";
|
|
39079
39388
|
}
|
|
39080
39389
|
const [activeTab, setActiveTab] = useState(getActiveFromHash);
|
|
39081
|
-
|
|
39390
|
+
React126__default.useEffect(() => {
|
|
39082
39391
|
const handler = () => setActiveTab(getActiveFromHash());
|
|
39083
39392
|
window.addEventListener("hashchange", handler);
|
|
39084
39393
|
return () => window.removeEventListener("hashchange", handler);
|