@fayz-ai/admin 0.36.1 → 0.38.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/ScheduleEditor-VGDE57L2.js +7 -0
- package/dist/{ScheduleEditor-VJYYNGSV.js.map → ScheduleEditor-VGDE57L2.js.map} +1 -1
- package/dist/app/AdminShell.d.ts.map +1 -1
- package/dist/{chunk-HZGF5N3A.js → chunk-TRDVM4ZO.js} +3 -2
- package/dist/chunk-TRDVM4ZO.js.map +1 -0
- package/dist/components/settings/ConnectedBrandingSettings.d.ts.map +1 -1
- package/dist/crud/BankField.d.ts +1 -1
- package/dist/crud/BankField.d.ts.map +1 -1
- package/dist/crud/CrudListView.d.ts +4 -1
- package/dist/crud/CrudListView.d.ts.map +1 -1
- package/dist/crud/CrudPage.d.ts.map +1 -1
- package/dist/crud/archetype-lookup.d.ts +26 -0
- package/dist/crud/archetype-lookup.d.ts.map +1 -1
- package/dist/crud/archetypes/AccessTab.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderFormView.d.ts +1 -0
- package/dist/crud/archetypes/OrderFormView.d.ts.map +1 -1
- package/dist/crud/archetypes/PayeeAccountsSection.d.ts +1 -1
- package/dist/crud/archetypes/PayeeAccountsSection.d.ts.map +1 -1
- package/dist/crud/archetypes/RoleSummary.d.ts +6 -0
- package/dist/crud/archetypes/RoleSummary.d.ts.map +1 -0
- package/dist/crud/fieldToColumn.d.ts +3 -1
- package/dist/crud/fieldToColumn.d.ts.map +1 -1
- package/dist/hooks/useListMemory.d.ts +29 -0
- package/dist/hooks/useListMemory.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1050 -807
- package/dist/index.js.map +1 -1
- package/dist/units/data.d.ts.map +1 -1
- package/dist/units/useUnitFilter.d.ts.map +1 -1
- package/package.json +7 -7
- package/dist/ScheduleEditor-VJYYNGSV.js +0 -7
- package/dist/chunk-HZGF5N3A.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -10,8 +10,8 @@ export { openEntity, resolveEntityAnchor, resolveEntityHref, resolveEntityRoute
|
|
|
10
10
|
import { useAdminPath, navigateTo, normalizeAdminPath, routeScore, matchRoute } from './chunk-VX3WJLKK.js';
|
|
11
11
|
export { navigateTo as adminNavigateTo, useAdminPath } from './chunk-VX3WJLKK.js';
|
|
12
12
|
export { ImportWizard } from './chunk-46UABOOC.js';
|
|
13
|
-
import { createArchetypeLookup, getPersonLookup } from './chunk-
|
|
14
|
-
export { ScheduleDateExceptions, ScheduleEditor, ScheduleGridPanel, createArchetypeLookup, deleteSchedule, getPersonBookable, getPersonLookup, getScheduleBlockConfig, getSchedules, mergeBlockSettings, parseBlockSettings, registerPersonLookup, replaceWeeklySchedules, saveSchedule, setPersonBookable, setScheduleBlockConfig, subscribeScheduleBlockConfig } from './chunk-
|
|
13
|
+
import { createArchetypeLookup, getPersonLookup } from './chunk-TRDVM4ZO.js';
|
|
14
|
+
export { ScheduleDateExceptions, ScheduleEditor, ScheduleGridPanel, createArchetypeLookup, deleteSchedule, getPersonBookable, getPersonLookup, getScheduleBlockConfig, getSchedules, mergeBlockSettings, parseBlockSettings, registerPersonLookup, replaceWeeklySchedules, saveSchedule, setPersonBookable, setScheduleBlockConfig, subscribeScheduleBlockConfig } from './chunk-TRDVM4ZO.js';
|
|
15
15
|
import { getFayzSupabaseClientOptional, getSupabaseClientOptional as getSupabaseClientOptional$1, useAppConfigStore, activePluginIds, hasPlugin, useWorkspaceSwitchingStore, searchWorkspaces, OrgMark, WorkspaceChooserGate, WorkspaceSwitchingHost, createFayzSupabaseClient, resolveAppId, createSupabaseOrgAdapter, createMockOrgAdapter, getFayzSupabaseClient } from './chunk-4YF6R7T3.js';
|
|
16
16
|
export { OrgMark, activePluginIds, createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, getFayzSupabaseClient, getFayzSupabaseClientOptional, hasPlugin, orgInitials, useAppConfigStore } from './chunk-4YF6R7T3.js';
|
|
17
17
|
import { readOrgSnapshot, useTenantOptional, useOrgAdapter, useTenant, OrgProvider, useOrgAdapterOptional } from './chunk-IDOTNT43.js';
|
|
@@ -20,13 +20,13 @@ import { usePermissionOptional, usePermissionsStore, PermissionsProvider } from
|
|
|
20
20
|
export { PermissionsProvider, useHasPermission, usePermission, usePermissionOptional, usePermissions, usePermissionsStore } from './chunk-UQ2NTFQC.js';
|
|
21
21
|
import { cn, useOrganizationStore } from './chunk-QOS6UAQ4.js';
|
|
22
22
|
export { getPersistedOrgId, useOrganizationStore } from './chunk-QOS6UAQ4.js';
|
|
23
|
-
import * as
|
|
24
|
-
import
|
|
25
|
-
import { createDebug, resetActiveUnit, setUnitMode, setActiveUnitId, setScopedResources, tl, fetchAppConfig, getSupabaseClientOptional, payeeAccountFields, maskCpfCnpj, 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, listConnections, connectorPlanes, connectorPermissions, connectorEntities, preferredPlane, connectorDirection, countByTenant, isAddressIncomplete, isBankIncomplete, payeeMethodOf, getCurrentLocale, searchEverything, getComponent, getPluginFactory, connectorSettings, groupedPermissions, invocationPlane, missingRequiredSettings, isBankEmpty, isAddressEmpty, isSettingSet, getEntityByKey, connectorSubscribesTo, eventKeyMatches } from '@fayz-ai/core';
|
|
23
|
+
import * as React128 from 'react';
|
|
24
|
+
import React128__default, { createContext, useMemo, useState, useRef, useCallback, useEffect, useLayoutEffect, useContext, createElement } from 'react';
|
|
25
|
+
import { createDebug, resetActiveUnit, setUnitMode, setActiveUnitId, setScopedResources, tl, fetchAppConfig, getSupabaseClientOptional, payeeAccountFields, maskCpfCnpj, 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, onDataChanged, useConnectorsForPlugin, renderApp as renderApp$1, parseRangeFilter, isFilterObject, connectionKey, useManifest, registerEventSink, formatPostalCode, isValidPostalCode, lookupPostalCode, usePluginRuntime, installGlobalErrorHandlers, registerErrorReporter, applyNavComposition, mergeTranslations, coreTranslations, attachPersistentCache, getPersistentCache, createMockProvider, listConnections, connectorPlanes, connectorPermissions, connectorEntities, preferredPlane, connectorDirection, countByTenant, isAddressIncomplete, isBankIncomplete, payeeMethodOf, getCurrentLocale, searchEverything, getComponent, getPluginFactory, connectorSettings, groupedPermissions, invocationPlane, missingRequiredSettings, isBankEmpty, isAddressEmpty, 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 { Input, SearchSelect, toast, usePageTrailParent, navigateToCrumb, Button, PageHeader, ConfirmDialog, RowActions, useRowSelection, getLucideIcon, ListFilterBar, Dropdown, DropdownTrigger, Hint, cn as cn$1, DropdownContent, DropdownLabel, DropdownItem, DropdownSeparator, RefreshButton, PageHeaderActions, PageTabs, StatTiles, Card, BulkActionBar, DataTable, Modal, ModalContent, ModalHeader, ModalTitle, ModalDescription, ModalFooter, Badge, PageActionBar, ICON_MAP, Sheet, SheetContent, SheetBody, useIsWide, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Checkbox, useTourStore, setTourNavigator, TourSpotlight, PracticeOverlay, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Wizard, SidebarOnboarding, OnboardingWidget, Skeleton, useLayoutStore, ModalPortal, ModalOverlay, ModalBody, useSaveBar, useBackHandler, SubpageHeader, Separator, Tabs, TabsList, TabsTrigger, TabsContent, CardContent, ToastProvider, NavTransitionProvider, ListView, Thumbnail, CurrencyInput, SearchField, ChevronPager, Popover, PopoverTrigger, PopoverContent, useModuleLayout,
|
|
29
|
+
import { Input, SearchSelect, toast, usePageTrailParent, navigateToCrumb, Button, PageHeader, ConfirmDialog, RowActions, useRowSelection, getLucideIcon, ListFilterBar, Dropdown, DropdownTrigger, Hint, cn as cn$1, DropdownContent, DropdownLabel, DropdownItem, DropdownSeparator, RefreshButton, PageHeaderActions, PageTabs, StatTiles, Card, BulkActionBar, DataTable, Modal, ModalContent, ModalHeader, ModalTitle, ModalDescription, ModalFooter, Badge, PersonAvatar, PageActionBar, ICON_MAP, Sheet, SheetContent, SheetBody, useIsWide, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Checkbox, useTourStore, setTourNavigator, TourSpotlight, PracticeOverlay, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Wizard, SidebarOnboarding, OnboardingWidget, Skeleton, useLayoutStore, ModalPortal, ModalOverlay, ModalBody, useSaveBar, useBackHandler, SubpageHeader, Separator, Tabs, TabsList, TabsTrigger, TabsContent, CardContent, ToastProvider, NavTransitionProvider, ListView, Thumbnail, CurrencyInput, SearchField, ChevronPager, Popover, PopoverTrigger, PopoverContent, useModuleLayout, PhoneLink, normalizePhone, SearchCombobox, HeaderTabs, usePageTrail, PageHeaderOutlet, AppShellSkeleton, usePracticeStore, ViewTabs, Switch, ModalTask, setPrintBrand, useModuleViewLabel, ModuleLayoutProvider, AppShell, PageTransition, PickerDialog, MarkdownEditor, PhoneField, isCreateRoute, PageSubNav, createFayzTheme, Avatar, AvatarImage, AvatarFallback, Markdown, PageTrail, CardTitle, CardDescription, DropdownSub, DropdownSubTrigger, DropdownSubContent, DropdownRadioGroup, DropdownRadioItem, BottomSheet, CardHeader, CardFooter, SegmentedControl, SheetCard, SheetRow, useSheetClose } from '@fayz-ai/ui';
|
|
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';
|
|
@@ -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 = React128.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] = React128__default.useState(false);
|
|
190
|
+
const [dispensada, setDispensada] = React128__default.useState(false);
|
|
191
|
+
const [aplicando, setAplicando] = React128__default.useState(false);
|
|
192
|
+
React128__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
|
+
React128.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
|
+
React128.useSyncExternalStore(subscribe, getVersion, getServerVersion);
|
|
1960
1960
|
return launchers;
|
|
1961
1961
|
}
|
|
1962
1962
|
function useLaunchersForRole(role) {
|
|
1963
1963
|
const all = useAssistantLaunchers();
|
|
1964
|
-
return
|
|
1964
|
+
return React128.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 = React128.useRef(activity);
|
|
1970
1970
|
ref.current = activity;
|
|
1971
|
-
|
|
1971
|
+
React128.useEffect(() => {
|
|
1972
1972
|
if (ref.current) publishAssistantActivity(ref.current);
|
|
1973
1973
|
}, [key]);
|
|
1974
|
-
|
|
1974
|
+
React128.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 = React128.useRef(launcher);
|
|
1983
1983
|
ref.current = launcher;
|
|
1984
|
-
|
|
1984
|
+
React128.useEffect(() => {
|
|
1985
1985
|
if (ref.current) registerAssistantLauncher(ref.current);
|
|
1986
1986
|
}, [key]);
|
|
1987
|
-
|
|
1987
|
+
React128.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 = React128.useRef({ label: label3, icon });
|
|
2086
|
+
React128.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
|
+
React128.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
|
+
React128.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 = React128.createContext(null);
|
|
2101
2101
|
var RightRailActionsSlotProvider = RightRailActionsSlotContext.Provider;
|
|
2102
2102
|
function RightRailActions({ children }) {
|
|
2103
|
-
const slot =
|
|
2103
|
+
const slot = React128.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 = React128.createContext(null);
|
|
2108
2108
|
var RightRailLeadingSlotProvider = RightRailLeadingSlotContext.Provider;
|
|
2109
2109
|
function RightRailLeading({ children }) {
|
|
2110
|
-
const slot =
|
|
2110
|
+
const slot = React128.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 = React128.useRef(handler);
|
|
2118
2118
|
ref.current = handler;
|
|
2119
|
-
const seen =
|
|
2120
|
-
|
|
2119
|
+
const seen = React128.useRef(reselects);
|
|
2120
|
+
React128.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 = React128.useRef(drill?.back);
|
|
2138
2138
|
backRef.current = drill?.back;
|
|
2139
|
-
|
|
2139
|
+
React128.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
|
+
React128__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
|
+
React128.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 = React128.useRef(null);
|
|
2315
|
+
const [box, setBox] = React128.useState(null);
|
|
2316
2316
|
const docked = stage === "dock" && !railOpen && hasAssistant;
|
|
2317
2317
|
const showing = hasAssistant && (stage === "hero" || docked);
|
|
2318
|
-
|
|
2318
|
+
React128.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
|
+
React128.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 React128.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] = React128.useState("");
|
|
2372
2372
|
const name = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
2373
|
-
|
|
2373
|
+
React128.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] = React128.useState(() => skip || prefersReducedMotion());
|
|
2436
|
+
React128.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] = React128.useState(
|
|
2456
2456
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
2457
2457
|
);
|
|
2458
|
-
|
|
2458
|
+
React128.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] = React128.useState("");
|
|
2490
|
+
const resumed = React128.useRef(
|
|
2491
2491
|
!!lastDockExit && lastDockExit.id === def.id && Date.now() - lastDockExit.at < RESUME_WINDOW_MS
|
|
2492
2492
|
).current;
|
|
2493
|
-
|
|
2493
|
+
React128.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 = React128.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] = React128.useState(resumed);
|
|
2501
2501
|
const geoLeft = settled ? left : mountGeo.left;
|
|
2502
2502
|
const geoWidth = settled ? width : mountGeo.width;
|
|
2503
|
-
|
|
2503
|
+
React128.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
|
+
React128.useEffect(() => {
|
|
2650
2650
|
if (prefersReducedMotion()) {
|
|
2651
2651
|
endLeave();
|
|
2652
2652
|
return;
|
|
@@ -4078,7 +4078,9 @@ async function fetchUnitBootstrap(tenantId2, deviceId) {
|
|
|
4078
4078
|
{ unitColumn: v?.unit_column ?? "unit_id", shareable: v?.shareable !== false }
|
|
4079
4079
|
])
|
|
4080
4080
|
),
|
|
4081
|
-
|
|
4081
|
+
// user_unit_ids_in walks the tree with UNION over (id, depth): a branch
|
|
4082
|
+
// reached directly AND through its HQ comes back twice.
|
|
4083
|
+
reachable: Array.isArray(raw.reachable) ? [...new Set(raw.reachable)] : void 0,
|
|
4082
4084
|
devicePin: { set: Boolean(raw.device_pin_set), unitId: raw.device_pin ?? null },
|
|
4083
4085
|
accountPin: { set: Boolean(raw.account_pin_set), unitId: raw.account_pin ?? null }
|
|
4084
4086
|
};
|
|
@@ -4560,12 +4562,12 @@ function detectActivePluginId(runtime) {
|
|
|
4560
4562
|
function useAITools() {
|
|
4561
4563
|
const runtime = usePluginRuntimeOptional();
|
|
4562
4564
|
const access = useAccessOptional();
|
|
4563
|
-
const surfaceVersion =
|
|
4565
|
+
const surfaceVersion = React128.useSyncExternalStore(subscribeSurfaces, getSurfaceVersion, getSurfaceVersion);
|
|
4564
4566
|
const features = usePermissionsStore((s) => s.features);
|
|
4565
4567
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
4566
4568
|
const hasSystem = useSystemPermission();
|
|
4567
4569
|
const canManagePermissions = hasSystem("manage_permissions");
|
|
4568
|
-
return
|
|
4570
|
+
return React128.useMemo(() => {
|
|
4569
4571
|
const hasPermission = runtime?.context.hasPermission;
|
|
4570
4572
|
const can = access.can;
|
|
4571
4573
|
const verticalId = runtime?.context.tenant?.verticalId;
|
|
@@ -5581,8 +5583,8 @@ function loadCatalog() {
|
|
|
5581
5583
|
return catalogPromise;
|
|
5582
5584
|
}
|
|
5583
5585
|
function useConnectorCatalog() {
|
|
5584
|
-
const [catalog, setCatalog] =
|
|
5585
|
-
|
|
5586
|
+
const [catalog, setCatalog] = React128__default.useState(null);
|
|
5587
|
+
React128__default.useEffect(() => {
|
|
5586
5588
|
let cancelled = false;
|
|
5587
5589
|
void loadCatalog().then((list) => {
|
|
5588
5590
|
if (!cancelled) setCatalog(list);
|
|
@@ -5606,7 +5608,7 @@ function refreshConnectors() {
|
|
|
5606
5608
|
_revisionListeners.forEach((listener) => listener());
|
|
5607
5609
|
}
|
|
5608
5610
|
function useConnectorsRevision() {
|
|
5609
|
-
return
|
|
5611
|
+
return React128__default.useSyncExternalStore(
|
|
5610
5612
|
(listener) => {
|
|
5611
5613
|
_revisionListeners.add(listener);
|
|
5612
5614
|
return () => _revisionListeners.delete(listener);
|
|
@@ -5625,11 +5627,11 @@ function loadGrants(key, fetcher) {
|
|
|
5625
5627
|
}
|
|
5626
5628
|
function useInstalledModuleIds() {
|
|
5627
5629
|
const runtime = usePluginRuntimeOptional();
|
|
5628
|
-
return
|
|
5630
|
+
return React128__default.useMemo(() => (runtime?.plugins ?? []).map((p) => p.id), [runtime]);
|
|
5629
5631
|
}
|
|
5630
5632
|
function useInstalledDefinitions(hostPluginId) {
|
|
5631
5633
|
const runtime = usePluginRuntimeOptional();
|
|
5632
|
-
return
|
|
5634
|
+
return React128__default.useMemo(() => {
|
|
5633
5635
|
const byHost = runtime?.connectorsByHost;
|
|
5634
5636
|
if (!byHost) return [];
|
|
5635
5637
|
if (hostPluginId) return byHost.get(hostPluginId) ?? [];
|
|
@@ -5642,12 +5644,12 @@ function useConnectors(options = {}) {
|
|
|
5642
5644
|
const catalog = useConnectorCatalog();
|
|
5643
5645
|
const tenant = useTenantOptional();
|
|
5644
5646
|
const tenantId2 = tenant?.org?.id;
|
|
5645
|
-
const connection =
|
|
5646
|
-
const [installed, setInstalled] =
|
|
5647
|
-
const [grants, setGrants] =
|
|
5648
|
-
const [error, setError] =
|
|
5647
|
+
const connection = React128__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
5648
|
+
const [installed, setInstalled] = React128__default.useState(null);
|
|
5649
|
+
const [grants, setGrants] = React128__default.useState(null);
|
|
5650
|
+
const [error, setError] = React128__default.useState(null);
|
|
5649
5651
|
const nonce = useConnectorsRevision();
|
|
5650
|
-
const call2 =
|
|
5652
|
+
const call2 = React128__default.useCallback(
|
|
5651
5653
|
async (path, init) => {
|
|
5652
5654
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
5653
5655
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -5667,7 +5669,7 @@ function useConnectors(options = {}) {
|
|
|
5667
5669
|
},
|
|
5668
5670
|
[connection]
|
|
5669
5671
|
);
|
|
5670
|
-
|
|
5672
|
+
React128__default.useEffect(() => {
|
|
5671
5673
|
let cancelled = false;
|
|
5672
5674
|
void loadConnectorStatuses(definitions, tenantId2).then((list) => {
|
|
5673
5675
|
if (!cancelled) setInstalled(list);
|
|
@@ -5676,7 +5678,7 @@ function useConnectors(options = {}) {
|
|
|
5676
5678
|
cancelled = true;
|
|
5677
5679
|
};
|
|
5678
5680
|
}, [definitions, tenantId2, nonce]);
|
|
5679
|
-
|
|
5681
|
+
React128__default.useEffect(() => {
|
|
5680
5682
|
if (!includeGrants || !connection || !tenantId2) {
|
|
5681
5683
|
setGrants(includeGrants ? null : []);
|
|
5682
5684
|
return;
|
|
@@ -5700,7 +5702,7 @@ function useConnectors(options = {}) {
|
|
|
5700
5702
|
cancelled = true;
|
|
5701
5703
|
};
|
|
5702
5704
|
}, [call2, tenantId2, includeGrants, connection, nonce]);
|
|
5703
|
-
const revokeGrant =
|
|
5705
|
+
const revokeGrant = React128__default.useCallback(
|
|
5704
5706
|
async (connector) => {
|
|
5705
5707
|
const response = await call2(`/${connector.id}`, { method: "DELETE" });
|
|
5706
5708
|
if (!response.ok) {
|
|
@@ -5713,7 +5715,7 @@ function useConnectors(options = {}) {
|
|
|
5713
5715
|
[call2]
|
|
5714
5716
|
);
|
|
5715
5717
|
const waitingGrants = includeGrants && !!connection && !!tenantId2 && grants === null;
|
|
5716
|
-
const connectors =
|
|
5718
|
+
const connectors = React128__default.useMemo(() => {
|
|
5717
5719
|
if (installed === null || waitingGrants) return null;
|
|
5718
5720
|
return buildConnectorList({
|
|
5719
5721
|
installed,
|
|
@@ -5954,9 +5956,9 @@ function ConnectorMark({
|
|
|
5954
5956
|
connector,
|
|
5955
5957
|
size = "md"
|
|
5956
5958
|
}) {
|
|
5957
|
-
const candidates =
|
|
5958
|
-
const [attempt, setAttempt] =
|
|
5959
|
-
|
|
5959
|
+
const candidates = React128__default.useMemo(() => markCandidates(connector), [connector.logoUrl, connector.name]);
|
|
5960
|
+
const [attempt, setAttempt] = React128__default.useState(0);
|
|
5961
|
+
React128__default.useEffect(() => setAttempt(0), [connector.id]);
|
|
5960
5962
|
const box = size === "sm" ? "h-9 w-9" : "h-10 w-10";
|
|
5961
5963
|
const glyph = size === "sm" ? "h-4 w-4" : "h-5 w-5";
|
|
5962
5964
|
if (connector.builtIn) {
|
|
@@ -6998,10 +7000,10 @@ function startRecordedDictation(endpoint, locale, cb) {
|
|
|
6998
7000
|
let stream = null;
|
|
6999
7001
|
let cancelled = false;
|
|
7000
7002
|
const chunks = [];
|
|
7001
|
-
const release = () => stream?.getTracks().forEach((
|
|
7003
|
+
const release = () => stream?.getTracks().forEach((track2) => track2.stop());
|
|
7002
7004
|
void navigator.mediaDevices.getUserMedia({ audio: true }).then((granted) => {
|
|
7003
7005
|
if (cancelled) {
|
|
7004
|
-
granted.getTracks().forEach((
|
|
7006
|
+
granted.getTracks().forEach((track2) => track2.stop());
|
|
7005
7007
|
return;
|
|
7006
7008
|
}
|
|
7007
7009
|
stream = granted;
|
|
@@ -7592,9 +7594,9 @@ function prefersReducedMotion2() {
|
|
|
7592
7594
|
return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
7593
7595
|
}
|
|
7594
7596
|
function TypewriterText({ text: text2, speed = 26, onDone }) {
|
|
7595
|
-
const [displayed, setDisplayed] =
|
|
7596
|
-
const indexRef =
|
|
7597
|
-
|
|
7597
|
+
const [displayed, setDisplayed] = React128.useState("");
|
|
7598
|
+
const indexRef = React128.useRef(0);
|
|
7599
|
+
React128.useEffect(() => {
|
|
7598
7600
|
if (prefersReducedMotion2()) {
|
|
7599
7601
|
setDisplayed(text2);
|
|
7600
7602
|
onDone?.();
|
|
@@ -7671,15 +7673,15 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7671
7673
|
const { contextualSuggestions } = useAITools();
|
|
7672
7674
|
const { sendMessage } = useChat({ apiEndpoint, systemPrompt, agent });
|
|
7673
7675
|
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
|
-
|
|
7676
|
+
const [phase, setPhase] = React128.useState("idle");
|
|
7677
|
+
const [activeSuggestion, setActiveSuggestion] = React128.useState(null);
|
|
7678
|
+
const timersRef = React128.useRef([]);
|
|
7679
|
+
const prevSuggestionRef = React128.useRef(null);
|
|
7680
|
+
const [greeting, setGreeting] = React128.useState(false);
|
|
7681
|
+
const greetTimerRef = React128.useRef(0);
|
|
7682
|
+
React128.useEffect(() => () => window.clearTimeout(greetTimerRef.current), []);
|
|
7681
7683
|
const hasFace = !!host?.AvatarComponent;
|
|
7682
|
-
|
|
7684
|
+
React128.useEffect(ensureStyles, []);
|
|
7683
7685
|
const clearTimers = () => {
|
|
7684
7686
|
timersRef.current.forEach(clearTimeout);
|
|
7685
7687
|
timersRef.current = [];
|
|
@@ -7692,10 +7694,10 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7692
7694
|
const invited = useAssistantInviteStore((s) => !!s.invite && s.stage === "dock");
|
|
7693
7695
|
const dockOnScreen = useAssistantInviteStore((s) => !!s.dockBox);
|
|
7694
7696
|
const morphingBack = useAssistantInviteStore((s) => !!s.leaving);
|
|
7695
|
-
const [wide, setWide] =
|
|
7697
|
+
const [wide, setWide] = React128.useState(
|
|
7696
7698
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
7697
7699
|
);
|
|
7698
|
-
|
|
7700
|
+
React128.useEffect(() => {
|
|
7699
7701
|
const query = window.matchMedia?.("(min-width: 768px)");
|
|
7700
7702
|
if (!query) return;
|
|
7701
7703
|
const sync = () => setWide(query.matches);
|
|
@@ -7704,7 +7706,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7704
7706
|
return () => query.removeEventListener("change", sync);
|
|
7705
7707
|
}, []);
|
|
7706
7708
|
const teaserAllowed = !hasMessages && !activity && !invited && !teaserDismissed() && teaserShownCount() < TEASER_MAX_PER_SESSION;
|
|
7707
|
-
|
|
7709
|
+
React128.useEffect(() => {
|
|
7708
7710
|
if (expanded || !topSuggestion || !topLabel || !teaserAllowed || teaserSeen().includes(topLabel)) {
|
|
7709
7711
|
if (phase !== "idle") {
|
|
7710
7712
|
clearTimers();
|
|
@@ -7735,14 +7737,14 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7735
7737
|
}, 9e3);
|
|
7736
7738
|
return clearTimers;
|
|
7737
7739
|
}, [topLabel, expanded, teaserAllowed]);
|
|
7738
|
-
|
|
7740
|
+
React128.useEffect(() => {
|
|
7739
7741
|
if (expanded && phase !== "idle") {
|
|
7740
7742
|
clearTimers();
|
|
7741
7743
|
setPhase("idle");
|
|
7742
7744
|
}
|
|
7743
7745
|
}, [expanded]);
|
|
7744
|
-
const [entrance, setEntrance] =
|
|
7745
|
-
|
|
7746
|
+
const [entrance, setEntrance] = React128.useState("pending");
|
|
7747
|
+
React128.useEffect(() => {
|
|
7746
7748
|
if (!currentOrg || entrance !== "pending") return;
|
|
7747
7749
|
if (prefersReducedMotion2()) {
|
|
7748
7750
|
setEntrance("done");
|
|
@@ -7752,9 +7754,9 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7752
7754
|
const timer = setTimeout(() => setEntrance("done"), 1600);
|
|
7753
7755
|
return () => clearTimeout(timer);
|
|
7754
7756
|
}, [currentOrg, entrance]);
|
|
7755
|
-
const [poppingBack, setPoppingBack] =
|
|
7756
|
-
const wasMorphing =
|
|
7757
|
-
|
|
7757
|
+
const [poppingBack, setPoppingBack] = React128.useState(false);
|
|
7758
|
+
const wasMorphing = React128.useRef(false);
|
|
7759
|
+
React128.useEffect(() => {
|
|
7758
7760
|
const was = wasMorphing.current;
|
|
7759
7761
|
wasMorphing.current = morphingBack;
|
|
7760
7762
|
if (!was || morphingBack || prefersReducedMotion2()) return;
|
|
@@ -8052,7 +8054,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
8052
8054
|
var MAX_SUGGESTIONS = 5;
|
|
8053
8055
|
function ChatSuggestions({ suggestions, onSelect, onDismiss, compact }) {
|
|
8054
8056
|
const { t } = useTranslation$1();
|
|
8055
|
-
const [open, setOpen] =
|
|
8057
|
+
const [open, setOpen] = React128.useState(true);
|
|
8056
8058
|
const visible = suggestions.slice(0, compact ? 3 : MAX_SUGGESTIONS);
|
|
8057
8059
|
if (!visible.length) return null;
|
|
8058
8060
|
return /* @__PURE__ */ jsxs(
|
|
@@ -8131,8 +8133,8 @@ function SuggestionRow({
|
|
|
8131
8133
|
detail,
|
|
8132
8134
|
onSelect
|
|
8133
8135
|
}) {
|
|
8134
|
-
const labelRef =
|
|
8135
|
-
const [showDetail, setShowDetail] =
|
|
8136
|
+
const labelRef = React128.useRef(null);
|
|
8137
|
+
const [showDetail, setShowDetail] = React128.useState(false);
|
|
8136
8138
|
const evaluate = () => {
|
|
8137
8139
|
const el = labelRef.current;
|
|
8138
8140
|
const clipped = !!el && el.scrollWidth > el.clientWidth + 1;
|
|
@@ -8226,8 +8228,8 @@ function ChatToolsPanel({ toolGroups, onClose }) {
|
|
|
8226
8228
|
}
|
|
8227
8229
|
function AutoApprovalsSection() {
|
|
8228
8230
|
const { t } = useTranslation$1();
|
|
8229
|
-
const [rules, setRules] =
|
|
8230
|
-
|
|
8231
|
+
const [rules, setRules] = React128.useState(() => listAutoApprovals());
|
|
8232
|
+
React128.useEffect(() => subscribeAutoApprovals(() => setRules(listAutoApprovals())), []);
|
|
8231
8233
|
if (!rules.length) return null;
|
|
8232
8234
|
return /* @__PURE__ */ jsxs("div", { className: "border-b border-border/40 px-3 py-2.5", children: [
|
|
8233
8235
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 px-1 pb-1.5", children: [
|
|
@@ -8280,14 +8282,14 @@ function bucketOf(iso) {
|
|
|
8280
8282
|
var ORDER = ["today", "yesterday", "week", "older"];
|
|
8281
8283
|
function ChatHistory({ conversations, activeId, onSelect }) {
|
|
8282
8284
|
const { t } = useTranslation$1();
|
|
8283
|
-
const [query, setQuery] =
|
|
8285
|
+
const [query, setQuery] = React128.useState("");
|
|
8284
8286
|
const mine = conversations;
|
|
8285
|
-
const filtered =
|
|
8287
|
+
const filtered = React128.useMemo(() => {
|
|
8286
8288
|
const needle = query.trim().toLowerCase();
|
|
8287
8289
|
if (!needle) return mine;
|
|
8288
8290
|
return mine.filter((c) => (c.title ?? "").toLowerCase().includes(needle));
|
|
8289
8291
|
}, [mine, query]);
|
|
8290
|
-
const groups =
|
|
8292
|
+
const groups = React128.useMemo(() => {
|
|
8291
8293
|
const map = /* @__PURE__ */ new Map();
|
|
8292
8294
|
for (const conversation of filtered) {
|
|
8293
8295
|
const bucket = bucketOf(conversation.updatedAt);
|
|
@@ -8414,7 +8416,7 @@ function TourCoachCard() {
|
|
|
8414
8416
|
const lastOutcome = useTourStore((s) => s.lastOutcome);
|
|
8415
8417
|
const stop = useTourStore((s) => s.stop);
|
|
8416
8418
|
const restart = useTourStore((s) => s.restart);
|
|
8417
|
-
const [dismissedId, setDismissedId] =
|
|
8419
|
+
const [dismissedId, setDismissedId] = React128.useState(null);
|
|
8418
8420
|
const pTitle = usePracticeStore((s) => s.title);
|
|
8419
8421
|
const pSteps = usePracticeStore((s) => s.steps);
|
|
8420
8422
|
const pDone = usePracticeStore((s) => s.done);
|
|
@@ -8485,8 +8487,8 @@ function AssistantRecordingView({ activity }) {
|
|
|
8485
8487
|
const live = activity.state === "running" || activity.state === "paused";
|
|
8486
8488
|
const running = activity.state === "running";
|
|
8487
8489
|
const actions = activity.actions ?? [];
|
|
8488
|
-
const [acknowledged, setAcknowledged] =
|
|
8489
|
-
|
|
8490
|
+
const [acknowledged, setAcknowledged] = React128.useState(false);
|
|
8491
|
+
React128.useEffect(() => setAcknowledged(false), [activity.id, activity.state]);
|
|
8490
8492
|
const withheld = pending2 && !!activity.confirm && !acknowledged;
|
|
8491
8493
|
const primary = actions.filter((a) => a.intent !== "discard");
|
|
8492
8494
|
const discard = actions.find((a) => a.intent === "discard");
|
|
@@ -8702,10 +8704,10 @@ function RightRailPage({
|
|
|
8702
8704
|
const closePage = useRightRailStore((s) => s.closePage);
|
|
8703
8705
|
const active2 = hosted && open;
|
|
8704
8706
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
8705
|
-
const onCloseRef =
|
|
8707
|
+
const onCloseRef = React128.useRef(onClose);
|
|
8706
8708
|
onCloseRef.current = onClose;
|
|
8707
|
-
const claimed =
|
|
8708
|
-
|
|
8709
|
+
const claimed = React128.useRef(false);
|
|
8710
|
+
React128.useEffect(() => {
|
|
8709
8711
|
if (!active2) return;
|
|
8710
8712
|
showPage();
|
|
8711
8713
|
claimed.current = true;
|
|
@@ -8714,7 +8716,7 @@ function RightRailPage({
|
|
|
8714
8716
|
closePage();
|
|
8715
8717
|
};
|
|
8716
8718
|
}, [active2, showPage, closePage]);
|
|
8717
|
-
|
|
8719
|
+
React128.useEffect(() => {
|
|
8718
8720
|
if (!claimed.current) return;
|
|
8719
8721
|
if (!useRightRailStore.getState().pageOpen) onCloseRef.current();
|
|
8720
8722
|
}, [pageOpen]);
|
|
@@ -8917,15 +8919,15 @@ function ConnectorSyncActions({
|
|
|
8917
8919
|
actions,
|
|
8918
8920
|
onRan
|
|
8919
8921
|
}) {
|
|
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
|
-
|
|
8922
|
+
const [running, setRunning] = React128__default.useState(null);
|
|
8923
|
+
const [open, setOpen] = React128__default.useState(null);
|
|
8924
|
+
const [pending2, setPending] = React128__default.useState(null);
|
|
8925
|
+
const [hidden, setHidden] = React128__default.useState(() => /* @__PURE__ */ new Set());
|
|
8926
|
+
const [queued, setQueued] = React128__default.useState({});
|
|
8927
|
+
const [nonce, setNonce] = React128__default.useState(0);
|
|
8928
|
+
const [expanded, setExpanded] = React128__default.useState(false);
|
|
8929
|
+
const [resolved, setResolved] = React128__default.useState(false);
|
|
8930
|
+
React128__default.useEffect(() => {
|
|
8929
8931
|
let cancelled = false;
|
|
8930
8932
|
setResolved(false);
|
|
8931
8933
|
void Promise.all(
|
|
@@ -9110,10 +9112,10 @@ function formatRelative(iso, t) {
|
|
|
9110
9112
|
}
|
|
9111
9113
|
function useConnectorRuns(connector) {
|
|
9112
9114
|
const listRuns = connector.definition?.listRuns;
|
|
9113
|
-
const [runs, setRuns] =
|
|
9114
|
-
const [loading, setLoading] =
|
|
9115
|
-
const [nonce, setNonce] =
|
|
9116
|
-
|
|
9115
|
+
const [runs, setRuns] = React128__default.useState([]);
|
|
9116
|
+
const [loading, setLoading] = React128__default.useState(!!listRuns);
|
|
9117
|
+
const [nonce, setNonce] = React128__default.useState(0);
|
|
9118
|
+
React128__default.useEffect(() => {
|
|
9117
9119
|
if (!listRuns) {
|
|
9118
9120
|
setRuns([]);
|
|
9119
9121
|
setLoading(false);
|
|
@@ -9135,7 +9137,7 @@ function useConnectorRuns(connector) {
|
|
|
9135
9137
|
return {
|
|
9136
9138
|
runs,
|
|
9137
9139
|
loading,
|
|
9138
|
-
reload:
|
|
9140
|
+
reload: React128__default.useCallback(() => setNonce((n) => n + 1), []),
|
|
9139
9141
|
failing: isFailing(runs)
|
|
9140
9142
|
};
|
|
9141
9143
|
}
|
|
@@ -9235,7 +9237,7 @@ function RunFailure({ run }) {
|
|
|
9235
9237
|
),
|
|
9236
9238
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t("connectors.runs.seeDetails") })
|
|
9237
9239
|
] }),
|
|
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(
|
|
9240
|
+
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(React128__default.Fragment, { children: [
|
|
9239
9241
|
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: label3 }),
|
|
9240
9242
|
/* @__PURE__ */ jsx("dd", { className: "min-w-0 break-words font-mono text-foreground/80", children: value })
|
|
9241
9243
|
] }, label3)) }),
|
|
@@ -9404,13 +9406,13 @@ function ConnectorSettingsPanel({
|
|
|
9404
9406
|
const { t } = useTranslation$1();
|
|
9405
9407
|
const def = connector.definition;
|
|
9406
9408
|
const settings = def ? connectorSettings(def) : [];
|
|
9407
|
-
const [values, setValues] =
|
|
9409
|
+
const [values, setValues] = React128__default.useState(
|
|
9408
9410
|
() => initialValues(settings, {})
|
|
9409
9411
|
);
|
|
9410
|
-
const [loaded2, setLoaded] =
|
|
9411
|
-
const [saving, setSaving] =
|
|
9412
|
-
const [dirty, setDirty] =
|
|
9413
|
-
|
|
9412
|
+
const [loaded2, setLoaded] = React128__default.useState(false);
|
|
9413
|
+
const [saving, setSaving] = React128__default.useState(false);
|
|
9414
|
+
const [dirty, setDirty] = React128__default.useState(false);
|
|
9415
|
+
React128__default.useEffect(() => {
|
|
9414
9416
|
if (settings.length === 0 || !def?.getSettings) return;
|
|
9415
9417
|
let cancelled = false;
|
|
9416
9418
|
setLoaded(false);
|
|
@@ -9661,13 +9663,13 @@ function ConnectorInstall({
|
|
|
9661
9663
|
}) {
|
|
9662
9664
|
const { t } = useTranslation$1();
|
|
9663
9665
|
const def = connector.definition;
|
|
9664
|
-
const [plane, setPlane] =
|
|
9666
|
+
const [plane, setPlane] = React128__default.useState(
|
|
9665
9667
|
connector.planes.includes("agentic") ? "agentic" : connector.planes[0]
|
|
9666
9668
|
);
|
|
9667
|
-
const [values, setValues] =
|
|
9668
|
-
const secrets =
|
|
9669
|
-
const [busy, setBusy] =
|
|
9670
|
-
|
|
9669
|
+
const [values, setValues] = React128__default.useState({});
|
|
9670
|
+
const secrets = React128__default.useRef({});
|
|
9671
|
+
const [busy, setBusy] = React128__default.useState(null);
|
|
9672
|
+
React128__default.useEffect(() => {
|
|
9671
9673
|
setValues({});
|
|
9672
9674
|
secrets.current = {};
|
|
9673
9675
|
setBusy(null);
|
|
@@ -9708,15 +9710,15 @@ function ConnectorHome({
|
|
|
9708
9710
|
const needsSetup = connector.state === "needs_setup";
|
|
9709
9711
|
const settingsAvailable = hasOperatingSettings(connector);
|
|
9710
9712
|
const runsAvailable = hasRunHistory(connector);
|
|
9711
|
-
const [tab, setTab] =
|
|
9713
|
+
const [tab, setTab] = React128__default.useState(
|
|
9712
9714
|
needsSetup && settingsAvailable ? "settings" : "overview"
|
|
9713
9715
|
);
|
|
9714
|
-
const [busy, setBusy] =
|
|
9716
|
+
const [busy, setBusy] = React128__default.useState(null);
|
|
9715
9717
|
const run = useRunner(setBusy, onChanged);
|
|
9716
|
-
const [values, setValues] =
|
|
9717
|
-
const secrets =
|
|
9718
|
+
const [values, setValues] = React128__default.useState({});
|
|
9719
|
+
const secrets = React128__default.useRef({});
|
|
9718
9720
|
const runs = useConnectorRuns(connector);
|
|
9719
|
-
|
|
9721
|
+
React128__default.useEffect(() => {
|
|
9720
9722
|
setTab(needsSetup && settingsAvailable ? "settings" : "overview");
|
|
9721
9723
|
setBusy(null);
|
|
9722
9724
|
setValues({});
|
|
@@ -9806,7 +9808,7 @@ function ConnectorHome({
|
|
|
9806
9808
|
}
|
|
9807
9809
|
function useRunner(setBusy, onChanged) {
|
|
9808
9810
|
const { t } = useTranslation$1();
|
|
9809
|
-
return
|
|
9811
|
+
return React128__default.useCallback(
|
|
9810
9812
|
async (kind, fn, okMessage) => {
|
|
9811
9813
|
setBusy(kind);
|
|
9812
9814
|
try {
|
|
@@ -9922,7 +9924,7 @@ function ConnectPanel({
|
|
|
9922
9924
|
const sinkMissing = needsSink && !getConnectorCredentialSink();
|
|
9923
9925
|
const secretFieldCount = (def.fields ?? []).filter(isSecretField).length;
|
|
9924
9926
|
const hasStoredCredential = connector.state === "connected" || connector.state === "needs_setup";
|
|
9925
|
-
const [formKey, setFormKey] =
|
|
9927
|
+
const [formKey, setFormKey] = React128__default.useState(0);
|
|
9926
9928
|
if (def.authKind === "oauth") {
|
|
9927
9929
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
9928
9930
|
/* @__PURE__ */ jsx(Note, { children: t("connectors.authorize.oauthOnly") }),
|
|
@@ -10055,7 +10057,7 @@ function GrantRevoke({
|
|
|
10055
10057
|
onRevoke
|
|
10056
10058
|
}) {
|
|
10057
10059
|
const { t } = useTranslation$1();
|
|
10058
|
-
const [revoking, setRevoking] =
|
|
10060
|
+
const [revoking, setRevoking] = React128__default.useState(false);
|
|
10059
10061
|
if (connector.revocable === false) {
|
|
10060
10062
|
return /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("connectors.partOfApp") });
|
|
10061
10063
|
}
|
|
@@ -10094,14 +10096,14 @@ function ConnectorsPanel({ onClose }) {
|
|
|
10094
10096
|
const { connectors, reload, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
10095
10097
|
const selectedId = useConnectorsSurface((s) => s.selected);
|
|
10096
10098
|
const select = useConnectorsSurface((s) => s.select);
|
|
10097
|
-
const [query, setQuery] =
|
|
10098
|
-
const [failure, setFailure] =
|
|
10099
|
-
const [revoking, setRevoking] =
|
|
10100
|
-
const selected =
|
|
10099
|
+
const [query, setQuery] = React128__default.useState("");
|
|
10100
|
+
const [failure, setFailure] = React128__default.useState(null);
|
|
10101
|
+
const [revoking, setRevoking] = React128__default.useState(null);
|
|
10102
|
+
const selected = React128__default.useMemo(
|
|
10101
10103
|
() => (connectors ?? []).find((c) => c.id === selectedId) ?? null,
|
|
10102
10104
|
[connectors, selectedId]
|
|
10103
10105
|
);
|
|
10104
|
-
const filtered =
|
|
10106
|
+
const filtered = React128__default.useMemo(
|
|
10105
10107
|
() => filterConnectors(connectors ?? [], "outbound", query),
|
|
10106
10108
|
[connectors, query]
|
|
10107
10109
|
);
|
|
@@ -10112,9 +10114,9 @@ function ConnectorsPanel({ onClose }) {
|
|
|
10112
10114
|
back: onClose
|
|
10113
10115
|
} : null
|
|
10114
10116
|
);
|
|
10115
|
-
const closeRef =
|
|
10117
|
+
const closeRef = React128__default.useRef(onClose);
|
|
10116
10118
|
closeRef.current = onClose;
|
|
10117
|
-
|
|
10119
|
+
React128__default.useEffect(() => {
|
|
10118
10120
|
if (hosted && !selectedId) closeRef.current();
|
|
10119
10121
|
}, [hosted, selectedId]);
|
|
10120
10122
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [
|
|
@@ -10242,20 +10244,20 @@ function useDictation({
|
|
|
10242
10244
|
onInterim
|
|
10243
10245
|
}) {
|
|
10244
10246
|
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 =
|
|
10247
|
+
const [state, setState] = React128.useState("idle");
|
|
10248
|
+
const [error, setError] = React128.useState(null);
|
|
10249
|
+
const sessionRef = React128.useRef(null);
|
|
10250
|
+
const callbacks = React128.useRef({ onTranscript, onInterim });
|
|
10249
10251
|
callbacks.current = { onTranscript, onInterim };
|
|
10250
|
-
const supported =
|
|
10252
|
+
const supported = React128.useMemo(
|
|
10251
10253
|
() => isDictationSupported(!!transcribeEndpoint),
|
|
10252
10254
|
[transcribeEndpoint]
|
|
10253
10255
|
);
|
|
10254
|
-
const finish =
|
|
10256
|
+
const finish = React128.useCallback(() => {
|
|
10255
10257
|
sessionRef.current = null;
|
|
10256
10258
|
setState("idle");
|
|
10257
10259
|
}, []);
|
|
10258
|
-
const start =
|
|
10260
|
+
const start = React128.useCallback(() => {
|
|
10259
10261
|
if (sessionRef.current || !supported) return;
|
|
10260
10262
|
stopSpeaking();
|
|
10261
10263
|
setError(null);
|
|
@@ -10276,28 +10278,28 @@ function useDictation({
|
|
|
10276
10278
|
}
|
|
10277
10279
|
);
|
|
10278
10280
|
}, [finish, resolvedLocale, supported, transcribeEndpoint]);
|
|
10279
|
-
const stop =
|
|
10281
|
+
const stop = React128.useCallback(() => {
|
|
10280
10282
|
if (!sessionRef.current) return;
|
|
10281
10283
|
if (transcribeEndpoint) setState("transcribing");
|
|
10282
10284
|
sessionRef.current.stop();
|
|
10283
10285
|
}, [transcribeEndpoint]);
|
|
10284
|
-
const cancel =
|
|
10286
|
+
const cancel = React128.useCallback(() => {
|
|
10285
10287
|
sessionRef.current?.cancel();
|
|
10286
10288
|
sessionRef.current = null;
|
|
10287
10289
|
setState("idle");
|
|
10288
10290
|
setError(null);
|
|
10289
10291
|
}, []);
|
|
10290
|
-
const toggle =
|
|
10292
|
+
const toggle = React128.useCallback(() => {
|
|
10291
10293
|
if (state === "listening" || state === "transcribing") stop();
|
|
10292
10294
|
else start();
|
|
10293
10295
|
}, [state, start, stop]);
|
|
10294
|
-
|
|
10296
|
+
React128.useEffect(() => () => sessionRef.current?.cancel(), []);
|
|
10295
10297
|
return { supported, state, error, start, stop, cancel, toggle, clearError: () => setError(null) };
|
|
10296
10298
|
}
|
|
10297
10299
|
function useMicLevels(active2, bandCount = 28, externalStream) {
|
|
10298
|
-
const levelsRef =
|
|
10299
|
-
const [available, setAvailable] =
|
|
10300
|
-
|
|
10300
|
+
const levelsRef = React128.useRef(new Float32Array(bandCount));
|
|
10301
|
+
const [available, setAvailable] = React128.useState(false);
|
|
10302
|
+
React128.useEffect(() => {
|
|
10301
10303
|
if (!active2) {
|
|
10302
10304
|
levelsRef.current.fill(0);
|
|
10303
10305
|
setAvailable(false);
|
|
@@ -10316,7 +10318,7 @@ function useMicLevels(active2, bandCount = 28, externalStream) {
|
|
|
10316
10318
|
});
|
|
10317
10319
|
void source.then((granted) => {
|
|
10318
10320
|
if (cancelled) {
|
|
10319
|
-
ownedStream?.getTracks().forEach((
|
|
10321
|
+
ownedStream?.getTracks().forEach((track2) => track2.stop());
|
|
10320
10322
|
return;
|
|
10321
10323
|
}
|
|
10322
10324
|
context = new AudioCtor();
|
|
@@ -10348,7 +10350,7 @@ function useMicLevels(active2, bandCount = 28, externalStream) {
|
|
|
10348
10350
|
return () => {
|
|
10349
10351
|
cancelled = true;
|
|
10350
10352
|
if (frame) cancelAnimationFrame(frame);
|
|
10351
|
-
ownedStream?.getTracks().forEach((
|
|
10353
|
+
ownedStream?.getTracks().forEach((track2) => track2.stop());
|
|
10352
10354
|
void context?.close().catch(() => {
|
|
10353
10355
|
});
|
|
10354
10356
|
levelsRef.current.fill(0);
|
|
@@ -10366,8 +10368,8 @@ var KIND_ICON = {
|
|
|
10366
10368
|
binary: File$1
|
|
10367
10369
|
};
|
|
10368
10370
|
function useFileDrop(enabled, onFiles) {
|
|
10369
|
-
const [dragging, setDragging] =
|
|
10370
|
-
const depth =
|
|
10371
|
+
const [dragging, setDragging] = React128.useState(false);
|
|
10372
|
+
const depth = React128.useRef(0);
|
|
10371
10373
|
const carriesFiles = (event) => Array.from(event.dataTransfer?.types ?? []).includes("Files");
|
|
10372
10374
|
const reset = () => {
|
|
10373
10375
|
depth.current = 0;
|
|
@@ -10427,7 +10429,7 @@ function AttachmentChips({
|
|
|
10427
10429
|
onRemove
|
|
10428
10430
|
}) {
|
|
10429
10431
|
const { t } = useTranslation$1();
|
|
10430
|
-
const [openId, setOpenId] =
|
|
10432
|
+
const [openId, setOpenId] = React128.useState(null);
|
|
10431
10433
|
if (!attachments.length) return null;
|
|
10432
10434
|
const opened = attachments.find((a) => a.id === openId);
|
|
10433
10435
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -10568,8 +10570,8 @@ function ChatComposer({
|
|
|
10568
10570
|
autoFocus
|
|
10569
10571
|
}) {
|
|
10570
10572
|
const { t } = useTranslation$1();
|
|
10571
|
-
const [input, setInput] =
|
|
10572
|
-
const textareaRef =
|
|
10573
|
+
const [input, setInput] = React128.useState("");
|
|
10574
|
+
const textareaRef = React128.useRef(null);
|
|
10573
10575
|
const voiceStartRequested = useChatStore((s) => s.voiceStartRequested);
|
|
10574
10576
|
const consumeVoiceStart = useChatStore((s) => s.consumeVoiceStart);
|
|
10575
10577
|
const draft = useChatStore((s) => s.draft);
|
|
@@ -10582,13 +10584,13 @@ function ChatComposer({
|
|
|
10582
10584
|
const removeAttachment = useChatStore((s) => s.removeAttachment);
|
|
10583
10585
|
const composerMedia = useChatStore((s) => s.composerMedia);
|
|
10584
10586
|
const clearComposerMedia = useChatStore((s) => s.clearComposerMedia);
|
|
10585
|
-
const fileInputRef =
|
|
10587
|
+
const fileInputRef = React128.useRef(null);
|
|
10586
10588
|
const autoSend = voice?.autoSend === true;
|
|
10587
10589
|
const micEnabled = voice?.input !== false;
|
|
10588
10590
|
const canAttach = isConfigured && !blocked && !isStreaming;
|
|
10589
10591
|
const parsing = attachments.some((a) => a.status === "parsing");
|
|
10590
10592
|
const readyAttachments = attachments.filter((a) => a.status === "ready").length;
|
|
10591
|
-
const submit =
|
|
10593
|
+
const submit = React128.useCallback(
|
|
10592
10594
|
(text2) => {
|
|
10593
10595
|
const trimmed = text2.trim();
|
|
10594
10596
|
const media = useChatStore.getState().composerMedia;
|
|
@@ -10618,23 +10620,23 @@ function ChatComposer({
|
|
|
10618
10620
|
}
|
|
10619
10621
|
}
|
|
10620
10622
|
});
|
|
10621
|
-
|
|
10623
|
+
React128.useEffect(() => {
|
|
10622
10624
|
if (!autoFocus) return;
|
|
10623
10625
|
const id = requestAnimationFrame(() => textareaRef.current?.focus());
|
|
10624
10626
|
return () => cancelAnimationFrame(id);
|
|
10625
10627
|
}, [autoFocus]);
|
|
10626
|
-
const
|
|
10628
|
+
const listening2 = dictation.state === "listening";
|
|
10627
10629
|
const transcribing = dictation.state === "transcribing";
|
|
10628
|
-
const micBusy =
|
|
10630
|
+
const micBusy = listening2 || transcribing;
|
|
10629
10631
|
const showMic = micEnabled && dictation.supported;
|
|
10630
10632
|
const WAVEFORM_BANDS = 56;
|
|
10631
10633
|
const activity = useAssistantActivity();
|
|
10632
10634
|
const sessionRecording = activity?.kind === "recording" && activity.state === "running";
|
|
10633
|
-
const sessionStream =
|
|
10635
|
+
const sessionStream = React128.useMemo(
|
|
10634
10636
|
() => sessionRecording ? activity?.stream?.() ?? null : null,
|
|
10635
10637
|
[sessionRecording, activity]
|
|
10636
10638
|
);
|
|
10637
|
-
const meterActive =
|
|
10639
|
+
const meterActive = listening2 || sessionRecording && !!sessionStream;
|
|
10638
10640
|
const { levelsRef, available: levelsAvailable } = useMicLevels(
|
|
10639
10641
|
meterActive,
|
|
10640
10642
|
WAVEFORM_BANDS,
|
|
@@ -10642,12 +10644,12 @@ function ChatComposer({
|
|
|
10642
10644
|
);
|
|
10643
10645
|
const sessionPause = activity?.actions?.find((a) => a.intent === "pause" || a.intent === "resume");
|
|
10644
10646
|
const sessionOwnsMic = activity?.kind === "recording" && (activity.state === "running" || activity.state === "paused");
|
|
10645
|
-
|
|
10647
|
+
React128.useEffect(() => {
|
|
10646
10648
|
if (!voiceStartRequested) return;
|
|
10647
10649
|
consumeVoiceStart();
|
|
10648
10650
|
if (showMic) dictation.start();
|
|
10649
10651
|
}, [voiceStartRequested, showMic]);
|
|
10650
|
-
|
|
10652
|
+
React128.useEffect(() => {
|
|
10651
10653
|
if (!focusRequested) return;
|
|
10652
10654
|
let frames = 0;
|
|
10653
10655
|
let raf = 0;
|
|
@@ -10664,7 +10666,7 @@ function ChatComposer({
|
|
|
10664
10666
|
raf = requestAnimationFrame(tick);
|
|
10665
10667
|
return () => cancelAnimationFrame(raf);
|
|
10666
10668
|
}, [focusRequested, consumeComposerFocus]);
|
|
10667
|
-
|
|
10669
|
+
React128.useEffect(() => {
|
|
10668
10670
|
if (!draft) return;
|
|
10669
10671
|
setInput(draft);
|
|
10670
10672
|
setDraft("");
|
|
@@ -10674,7 +10676,7 @@ function ChatComposer({
|
|
|
10674
10676
|
el.setSelectionRange(draft.length, draft.length);
|
|
10675
10677
|
}
|
|
10676
10678
|
}, [draft, setDraft]);
|
|
10677
|
-
|
|
10679
|
+
React128.useLayoutEffect(() => {
|
|
10678
10680
|
const el = textareaRef.current;
|
|
10679
10681
|
if (!el) return;
|
|
10680
10682
|
const style = getComputedStyle(el);
|
|
@@ -10700,22 +10702,22 @@ function ChatComposer({
|
|
|
10700
10702
|
setInput("");
|
|
10701
10703
|
}
|
|
10702
10704
|
};
|
|
10703
|
-
const placeholder = blocked ? t("chat.confirmAction.blocked") :
|
|
10705
|
+
const placeholder = blocked ? t("chat.confirmAction.blocked") : listening2 ? t("chat.voice.listening") : transcribing ? t("chat.voice.transcribing") : composerHint ?? t("chat.messagePlaceholder");
|
|
10704
10706
|
const hasContent = !!input.trim() || readyAttachments > 0 || !!composerMedia;
|
|
10705
10707
|
const canSubmit = hasContent && !parsing && !isStreaming && isConfigured && !blocked;
|
|
10706
10708
|
const showSend = hasContent || !showMic;
|
|
10707
|
-
const
|
|
10709
|
+
const errorMessage10 = dictation.error === "denied" ? t("chat.voice.denied") : dictation.error === "network" ? t("chat.voice.network") : dictation.error === "failed" ? t("chat.voice.failed") : null;
|
|
10708
10710
|
return (
|
|
10709
10711
|
// Rule only, no surface: the panel takes the page's own tone now, and a
|
|
10710
10712
|
// translucent card strip across the foot of it read as a second sheet.
|
|
10711
10713
|
/* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 p-2", children: [
|
|
10712
|
-
|
|
10714
|
+
errorMessage10 && /* @__PURE__ */ jsxs(
|
|
10713
10715
|
"div",
|
|
10714
10716
|
{
|
|
10715
10717
|
role: "status",
|
|
10716
10718
|
className: "mb-1.5 flex items-center gap-1.5 rounded-lg bg-destructive/10 px-2.5 py-1.5 text-[11px] text-destructive",
|
|
10717
10719
|
children: [
|
|
10718
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children:
|
|
10720
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1", children: errorMessage10 }),
|
|
10719
10721
|
/* @__PURE__ */ jsx(
|
|
10720
10722
|
"button",
|
|
10721
10723
|
{
|
|
@@ -10728,7 +10730,7 @@ function ChatComposer({
|
|
|
10728
10730
|
]
|
|
10729
10731
|
}
|
|
10730
10732
|
),
|
|
10731
|
-
|
|
10733
|
+
listening2 && /* @__PURE__ */ jsx(
|
|
10732
10734
|
"p",
|
|
10733
10735
|
{
|
|
10734
10736
|
role: "status",
|
|
@@ -10752,10 +10754,10 @@ function ChatComposer({
|
|
|
10752
10754
|
// so the text — the thing being composed — got whatever width the
|
|
10753
10755
|
// buttons left over.
|
|
10754
10756
|
"rounded-3xl border bg-card px-2 py-1.5 transition-all duration-200",
|
|
10755
|
-
|
|
10757
|
+
listening2 ? "border-primary ring-2 ring-primary/20" : "border-border/45 focus-within:border-foreground/15"
|
|
10756
10758
|
),
|
|
10757
10759
|
children: [
|
|
10758
|
-
|
|
10760
|
+
listening2 ? /* @__PURE__ */ jsx("div", { className: "min-w-0 px-1 py-1.5", children: /* @__PURE__ */ jsx(LiveWaveform, { levelsRef, bands: WAVEFORM_BANDS, live: levelsAvailable }) }) : /* @__PURE__ */ jsx(
|
|
10759
10761
|
"textarea",
|
|
10760
10762
|
{
|
|
10761
10763
|
ref: textareaRef,
|
|
@@ -10836,15 +10838,15 @@ function ChatComposer({
|
|
|
10836
10838
|
type: "button",
|
|
10837
10839
|
onClick: dictation.toggle,
|
|
10838
10840
|
disabled: !isConfigured || blocked || isStreaming || transcribing,
|
|
10839
|
-
"aria-pressed":
|
|
10840
|
-
"aria-label":
|
|
10841
|
-
title:
|
|
10841
|
+
"aria-pressed": listening2,
|
|
10842
|
+
"aria-label": listening2 ? t("chat.voice.stop") : t("chat.voice.start"),
|
|
10843
|
+
title: listening2 ? t("chat.voice.stop") : t("chat.voice.start"),
|
|
10842
10844
|
className: cn(
|
|
10843
10845
|
ROW_BUTTON,
|
|
10844
10846
|
"disabled:opacity-30",
|
|
10845
|
-
|
|
10847
|
+
listening2 ? "bg-primary text-primary-foreground shadow-[0_0_0_4px_hsl(var(--primary)/0.18)]" : "text-muted-foreground hover:bg-muted hover:text-foreground"
|
|
10846
10848
|
),
|
|
10847
|
-
children: transcribing ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) :
|
|
10849
|
+
children: transcribing ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : listening2 ? /* @__PURE__ */ jsx(Square, { className: "h-3 w-3 fill-current" }) : /* @__PURE__ */ jsx(Mic, { className: "h-4 w-4" })
|
|
10848
10850
|
}
|
|
10849
10851
|
) : null,
|
|
10850
10852
|
showSend && /* @__PURE__ */ jsx(
|
|
@@ -10877,8 +10879,8 @@ function UploadRequestCard() {
|
|
|
10877
10879
|
const removeUploadFile = useChatStore((s) => s.removeUploadFile);
|
|
10878
10880
|
const submitUpload = useChatStore((s) => s.submitUpload);
|
|
10879
10881
|
const clearUploadRequest = useChatStore((s) => s.clearUploadRequest);
|
|
10880
|
-
const cameraRef =
|
|
10881
|
-
const browseRef =
|
|
10882
|
+
const cameraRef = React128.useRef(null);
|
|
10883
|
+
const browseRef = React128.useRef(null);
|
|
10882
10884
|
if (!request) return null;
|
|
10883
10885
|
const working = request.status === "working";
|
|
10884
10886
|
const accept = request.accept ?? "image/*";
|
|
@@ -11020,8 +11022,8 @@ function LiveWaveform({
|
|
|
11020
11022
|
compact,
|
|
11021
11023
|
tone = "primary"
|
|
11022
11024
|
}) {
|
|
11023
|
-
const barsRef =
|
|
11024
|
-
|
|
11025
|
+
const barsRef = React128.useRef([]);
|
|
11026
|
+
React128.useEffect(() => {
|
|
11025
11027
|
if (!live) return;
|
|
11026
11028
|
let frame = 0;
|
|
11027
11029
|
const draw = () => {
|
|
@@ -11170,7 +11172,7 @@ function ChatMarkdown({ content }) {
|
|
|
11170
11172
|
}
|
|
11171
11173
|
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
11174
|
const prev = items.pop();
|
|
11173
|
-
if (prev &&
|
|
11175
|
+
if (prev && React128.isValidElement(prev)) {
|
|
11174
11176
|
items.push(
|
|
11175
11177
|
/* @__PURE__ */ jsxs("li", { children: [
|
|
11176
11178
|
prev.props.children,
|
|
@@ -11267,7 +11269,7 @@ var CARD_CTA = {
|
|
|
11267
11269
|
function useConnectorJourney(card) {
|
|
11268
11270
|
const panelAvailable = useConnectorsPanelAvailable();
|
|
11269
11271
|
useChatStore((s) => s.setOpen);
|
|
11270
|
-
return
|
|
11272
|
+
return React128.useCallback(() => {
|
|
11271
11273
|
if (panelAvailable && card.id) {
|
|
11272
11274
|
openConnectorsPanel({ id: card.id });
|
|
11273
11275
|
return;
|
|
@@ -11357,7 +11359,7 @@ function ConnectorSuggestionRow({ card }) {
|
|
|
11357
11359
|
] });
|
|
11358
11360
|
}
|
|
11359
11361
|
function ConnectorSuggestionGroup({ cards }) {
|
|
11360
|
-
const shelves =
|
|
11362
|
+
const shelves = React128.useMemo(() => shelveByCategory(cards), [cards]);
|
|
11361
11363
|
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
11364
|
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
11365
|
/* @__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 +11369,8 @@ function ChoiceCard({ card }) {
|
|
|
11367
11369
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
11368
11370
|
const isStreaming = useChatStore((s) => s.isStreaming);
|
|
11369
11371
|
const messages = useChatStore((s) => s.messages);
|
|
11370
|
-
const [optimistic, setOptimistic] =
|
|
11371
|
-
const answeredInThread =
|
|
11372
|
+
const [optimistic, setOptimistic] = React128.useState(null);
|
|
11373
|
+
const answeredInThread = React128.useMemo(
|
|
11372
11374
|
() => answeredOptionId(messages, card.options),
|
|
11373
11375
|
[messages, card.options]
|
|
11374
11376
|
);
|
|
@@ -11423,7 +11425,7 @@ function humanizeToolName(name) {
|
|
|
11423
11425
|
}
|
|
11424
11426
|
function ToolCallRow({ call: call2 }) {
|
|
11425
11427
|
const { t } = useTranslation$1();
|
|
11426
|
-
const [open, setOpen] =
|
|
11428
|
+
const [open, setOpen] = React128.useState(false);
|
|
11427
11429
|
const failed = call2.declined || /"error"\s*:/.test(call2.result ?? "");
|
|
11428
11430
|
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-xl border border-border/50 bg-muted/30", children: [
|
|
11429
11431
|
/* @__PURE__ */ jsxs(
|
|
@@ -11500,15 +11502,15 @@ function HandoffNotice({ notice }) {
|
|
|
11500
11502
|
}
|
|
11501
11503
|
function MessageBubble({ message, isPending }) {
|
|
11502
11504
|
const isUser = message.role === "user";
|
|
11503
|
-
const connectorCards =
|
|
11505
|
+
const connectorCards = React128.useMemo(
|
|
11504
11506
|
() => (message.cards ?? []).filter((card) => card.kind === "connector"),
|
|
11505
11507
|
[message.cards]
|
|
11506
11508
|
);
|
|
11507
|
-
const choiceCards =
|
|
11509
|
+
const choiceCards = React128.useMemo(
|
|
11508
11510
|
() => (message.cards ?? []).filter((card) => card.kind === "choice"),
|
|
11509
11511
|
[message.cards]
|
|
11510
11512
|
);
|
|
11511
|
-
const routedLinks =
|
|
11513
|
+
const routedLinks = React128.useMemo(
|
|
11512
11514
|
() => (message.links ?? []).filter(
|
|
11513
11515
|
(l) => !!l.path || !!resolveEntityRoute(l.archetype, l.kind, l.entityKey)
|
|
11514
11516
|
),
|
|
@@ -11599,9 +11601,9 @@ function ConfirmActionCard({
|
|
|
11599
11601
|
onResolveAll
|
|
11600
11602
|
}) {
|
|
11601
11603
|
const { t } = useTranslation$1();
|
|
11602
|
-
const schema =
|
|
11604
|
+
const schema = React128.useMemo(() => action.fields ?? [], [action.fields]);
|
|
11603
11605
|
const partial = action.partial === true;
|
|
11604
|
-
const seedValues =
|
|
11606
|
+
const seedValues = React128.useCallback(
|
|
11605
11607
|
(params) => {
|
|
11606
11608
|
if (partial) return { ...params };
|
|
11607
11609
|
const seeded = {};
|
|
@@ -11610,18 +11612,18 @@ function ConfirmActionCard({
|
|
|
11610
11612
|
},
|
|
11611
11613
|
[schema, partial]
|
|
11612
11614
|
);
|
|
11613
|
-
const [values, setValues] =
|
|
11614
|
-
const [showAll, setShowAll] =
|
|
11615
|
+
const [values, setValues] = React128.useState(() => seedValues(action.params));
|
|
11616
|
+
const [showAll, setShowAll] = React128.useState(false);
|
|
11615
11617
|
const batch = Math.max(0, sameToolQueued);
|
|
11616
|
-
|
|
11618
|
+
React128.useEffect(() => setValues(seedValues(action.params)), [action.params, seedValues]);
|
|
11617
11619
|
const isSet = (v) => v !== void 0 && v !== null && v !== "";
|
|
11618
|
-
const primaryKeys =
|
|
11620
|
+
const primaryKeys = React128.useMemo(() => {
|
|
11619
11621
|
const keys = Object.keys(action.params).filter((k) => isSet(action.params[k]));
|
|
11620
11622
|
if (partial) return keys;
|
|
11621
11623
|
for (const f of schema) if (f.required && !keys.includes(f.key)) keys.push(f.key);
|
|
11622
11624
|
return keys;
|
|
11623
11625
|
}, [action.params, schema, partial]);
|
|
11624
|
-
const extraKeys =
|
|
11626
|
+
const extraKeys = React128.useMemo(
|
|
11625
11627
|
() => schema.map((f) => f.key).filter((k) => !primaryKeys.includes(k) && k !== "id"),
|
|
11626
11628
|
[schema, primaryKeys]
|
|
11627
11629
|
);
|
|
@@ -11648,20 +11650,20 @@ function ConfirmActionCard({
|
|
|
11648
11650
|
if (sharedLabel !== shared) return sharedLabel;
|
|
11649
11651
|
return humanizeKey(key);
|
|
11650
11652
|
};
|
|
11651
|
-
const missingRequiredKeys =
|
|
11653
|
+
const missingRequiredKeys = React128.useMemo(
|
|
11652
11654
|
() => partial ? [] : schema.filter((f) => f.required && !isSet(values[f.key])).map((f) => f.key),
|
|
11653
11655
|
[schema, values, partial]
|
|
11654
11656
|
);
|
|
11655
11657
|
const canConfirm = missingRequiredKeys.length === 0;
|
|
11656
|
-
const submitted =
|
|
11658
|
+
const submitted = React128.useCallback(
|
|
11657
11659
|
() => partial ? Object.fromEntries(Object.entries(values).filter(([, v]) => isSet(v))) : values,
|
|
11658
11660
|
[partial, values]
|
|
11659
11661
|
);
|
|
11660
|
-
const approve =
|
|
11662
|
+
const approve = React128.useCallback(() => {
|
|
11661
11663
|
if (canConfirm) onResolve(true, submitted());
|
|
11662
11664
|
}, [canConfirm, onResolve, submitted]);
|
|
11663
|
-
const decline =
|
|
11664
|
-
const approveAlways =
|
|
11665
|
+
const decline = React128.useCallback(() => onResolve(false), [onResolve]);
|
|
11666
|
+
const approveAlways = React128.useCallback(() => {
|
|
11665
11667
|
if (!canConfirm) return;
|
|
11666
11668
|
grantAutoApproval({
|
|
11667
11669
|
toolName: action.toolName,
|
|
@@ -11671,7 +11673,7 @@ function ConfirmActionCard({
|
|
|
11671
11673
|
});
|
|
11672
11674
|
onResolve(true, submitted());
|
|
11673
11675
|
}, [canConfirm, action.toolName, action.scope, ruleLabel, destructive, onResolve, submitted]);
|
|
11674
|
-
|
|
11676
|
+
React128.useEffect(() => {
|
|
11675
11677
|
const handler = (event) => {
|
|
11676
11678
|
const target = event.target;
|
|
11677
11679
|
const typing = target?.tagName === "INPUT" || target?.tagName === "TEXTAREA" || target?.tagName === "SELECT";
|
|
@@ -12008,8 +12010,8 @@ var TYPE_MS = 620;
|
|
|
12008
12010
|
var MIN_CHAR_MS = 12;
|
|
12009
12011
|
var MAX_CHAR_MS = 34;
|
|
12010
12012
|
function usePrefersReducedMotion() {
|
|
12011
|
-
const [reduced, setReduced] =
|
|
12012
|
-
|
|
12013
|
+
const [reduced, setReduced] = React128.useState(false);
|
|
12014
|
+
React128.useEffect(() => {
|
|
12013
12015
|
if (typeof matchMedia !== "function") return;
|
|
12014
12016
|
const query = matchMedia("(prefers-reduced-motion: reduce)");
|
|
12015
12017
|
const sync = () => setReduced(query.matches);
|
|
@@ -12028,10 +12030,10 @@ function TypedText({
|
|
|
12028
12030
|
onDone
|
|
12029
12031
|
}) {
|
|
12030
12032
|
const reduced = usePrefersReducedMotion();
|
|
12031
|
-
const [count, setCount] =
|
|
12032
|
-
const done =
|
|
12033
|
+
const [count, setCount] = React128.useState(reduced ? text2.length : 0);
|
|
12034
|
+
const done = React128.useRef(onDone);
|
|
12033
12035
|
done.current = onDone;
|
|
12034
|
-
|
|
12036
|
+
React128.useEffect(() => {
|
|
12035
12037
|
if (!start) {
|
|
12036
12038
|
setCount(0);
|
|
12037
12039
|
return;
|
|
@@ -12071,9 +12073,9 @@ function RevealSequence({
|
|
|
12071
12073
|
children
|
|
12072
12074
|
}) {
|
|
12073
12075
|
const reduced = usePrefersReducedMotion();
|
|
12074
|
-
const items =
|
|
12075
|
-
const [shown, setShown] =
|
|
12076
|
-
|
|
12076
|
+
const items = React128.Children.toArray(children);
|
|
12077
|
+
const [shown, setShown] = React128.useState(0);
|
|
12078
|
+
React128.useEffect(() => {
|
|
12077
12079
|
if (!start) {
|
|
12078
12080
|
setShown(0);
|
|
12079
12081
|
return;
|
|
@@ -12135,7 +12137,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
12135
12137
|
const currentPlan = plans.find((p) => p.id === currentPlanId);
|
|
12136
12138
|
const currentPrice = currentPlan?.price ?? 0;
|
|
12137
12139
|
const currentPlanName = currentPlan?.name ?? tr("billing.free", "Free");
|
|
12138
|
-
const featureName =
|
|
12140
|
+
const featureName = React128.useMemo(() => {
|
|
12139
12141
|
if (!feature) return null;
|
|
12140
12142
|
const label3 = features.find((f) => f.id === feature)?.label;
|
|
12141
12143
|
if (label3) return featureDisplayName(label3);
|
|
@@ -12143,7 +12145,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
12143
12145
|
const named = t(key);
|
|
12144
12146
|
return named && named !== key ? named : featureDisplayName(feature);
|
|
12145
12147
|
}, [features, feature, t]);
|
|
12146
|
-
const unlockingPlans =
|
|
12148
|
+
const unlockingPlans = React128.useMemo(
|
|
12147
12149
|
() => plans.filter((p) => p.id !== currentPlanId && p.price > currentPrice && planUnlocks(p, feature)).sort((a, b) => a.price - b.price),
|
|
12148
12150
|
[plans, currentPlanId, currentPrice, feature]
|
|
12149
12151
|
);
|
|
@@ -12325,26 +12327,26 @@ function ChatConversation({
|
|
|
12325
12327
|
usable && !pendingAction && !isStreaming,
|
|
12326
12328
|
receiveFiles
|
|
12327
12329
|
);
|
|
12328
|
-
|
|
12329
|
-
const [view, setView] =
|
|
12330
|
+
React128.useEffect(ensureIntroStyles, []);
|
|
12331
|
+
const [view, setView] = React128.useState(
|
|
12330
12332
|
() => useChatStore.getState().messages.length > 0 ? "thread" : "list"
|
|
12331
12333
|
);
|
|
12332
|
-
const [drawer, setDrawer] =
|
|
12333
|
-
const [introStep, setIntroStep] =
|
|
12334
|
-
const [atBottom, setAtBottom] =
|
|
12335
|
-
const scrollRef =
|
|
12334
|
+
const [drawer, setDrawer] = React128.useState("none");
|
|
12335
|
+
const [introStep, setIntroStep] = React128.useState(0);
|
|
12336
|
+
const [atBottom, setAtBottom] = React128.useState(true);
|
|
12337
|
+
const scrollRef = React128.useRef(null);
|
|
12336
12338
|
const hasMessages = messages.length > 0;
|
|
12337
12339
|
const showThread = view === "thread" && hasMessages;
|
|
12338
12340
|
const totalTools = toolGroups.reduce((sum, g) => sum + g.tools.length, 0);
|
|
12339
|
-
const scrollToBottom =
|
|
12341
|
+
const scrollToBottom = React128.useCallback((behavior = "smooth") => {
|
|
12340
12342
|
const el = scrollRef.current;
|
|
12341
12343
|
if (!el) return;
|
|
12342
12344
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
12343
12345
|
}, []);
|
|
12344
|
-
|
|
12346
|
+
React128.useEffect(() => {
|
|
12345
12347
|
if (atBottom) scrollToBottom();
|
|
12346
12348
|
}, [messages, activeTools, pendingAction, atBottom, scrollToBottom]);
|
|
12347
|
-
|
|
12349
|
+
React128.useEffect(() => {
|
|
12348
12350
|
loadConversations();
|
|
12349
12351
|
setSuggestionsOpen(useChatStore.getState().messages.length === 0);
|
|
12350
12352
|
return () => stopSpeaking();
|
|
@@ -12361,7 +12363,7 @@ function ChatConversation({
|
|
|
12361
12363
|
};
|
|
12362
12364
|
const queuedPrompt = useChatStore((s) => s.queuedPrompt);
|
|
12363
12365
|
const consumeQueuedPrompt = useChatStore((s) => s.consumeQueuedPrompt);
|
|
12364
|
-
|
|
12366
|
+
React128.useEffect(() => {
|
|
12365
12367
|
if (!queuedPrompt) return;
|
|
12366
12368
|
const prompt = consumeQueuedPrompt();
|
|
12367
12369
|
if (prompt && usable) send(prompt);
|
|
@@ -12397,7 +12399,7 @@ function ChatConversation({
|
|
|
12397
12399
|
);
|
|
12398
12400
|
const connectorsPending = useConnectorsSurface((s) => s.pending);
|
|
12399
12401
|
const consumeConnectorsRequest = useConnectorsSurface((s) => s.consume);
|
|
12400
|
-
|
|
12402
|
+
React128.useEffect(() => {
|
|
12401
12403
|
if (!connectorsPending) return;
|
|
12402
12404
|
setDrawer("connectors");
|
|
12403
12405
|
consumeConnectorsRequest();
|
|
@@ -12405,7 +12407,7 @@ function ChatConversation({
|
|
|
12405
12407
|
const greetingName = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
12406
12408
|
const invite = useAssistantInviteStore((s) => s.invite);
|
|
12407
12409
|
const introKey = `${onDuty?.role ?? "solo"}:${invite?.id ?? ""}`;
|
|
12408
|
-
|
|
12410
|
+
React128.useEffect(() => setIntroStep(0), [introKey]);
|
|
12409
12411
|
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
12412
|
const greetingHint = invite?.description ?? onDuty?.goal ?? t("chat.greetingHint");
|
|
12411
12413
|
const openers2 = invite?.suggestions?.length ? invite.suggestions : onDuty?.suggestions?.length ? onDuty.suggestions : suggestions.length ? suggestions : [
|
|
@@ -12727,7 +12729,7 @@ function AgentAvatar({
|
|
|
12727
12729
|
size = "md",
|
|
12728
12730
|
className
|
|
12729
12731
|
}) {
|
|
12730
|
-
const [failed, setFailed] =
|
|
12732
|
+
const [failed, setFailed] = React128.useState(false);
|
|
12731
12733
|
const { box, text: text2, px } = SIZES[size];
|
|
12732
12734
|
if (Face) {
|
|
12733
12735
|
return /* @__PURE__ */ jsx(
|
|
@@ -13515,7 +13517,7 @@ function TaskStatusGroup({ status, tasks }) {
|
|
|
13515
13517
|
function useDelegateToAssistant() {
|
|
13516
13518
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
13517
13519
|
const openPanel = useRightRailStore((s) => s.openPanel);
|
|
13518
|
-
return
|
|
13520
|
+
return React128.useCallback(
|
|
13519
13521
|
(prompt) => {
|
|
13520
13522
|
queuePrompt(prompt);
|
|
13521
13523
|
openPanel("chat");
|
|
@@ -13752,12 +13754,12 @@ function TasksPanel() {
|
|
|
13752
13754
|
const fetchTasks = useTasksStore((s) => s.fetchTasks);
|
|
13753
13755
|
const fetchLabels = useTasksStore((s) => s.fetchLabels);
|
|
13754
13756
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13755
|
-
|
|
13757
|
+
React128__default.useEffect(() => {
|
|
13756
13758
|
void fetchTasks();
|
|
13757
13759
|
void fetchLabels();
|
|
13758
13760
|
void fetchSummary();
|
|
13759
13761
|
}, [fetchTasks, fetchLabels, fetchSummary]);
|
|
13760
|
-
const { onboarding, grouped } =
|
|
13762
|
+
const { onboarding, grouped } = React128__default.useMemo(() => {
|
|
13761
13763
|
const split = splitOnboardingTasks(tasks);
|
|
13762
13764
|
const map = /* @__PURE__ */ new Map();
|
|
13763
13765
|
for (const s of STATUS_ORDER) map.set(s, []);
|
|
@@ -13792,7 +13794,7 @@ function TasksPanel() {
|
|
|
13792
13794
|
function useTasksSummaryLine() {
|
|
13793
13795
|
const t = useTranslation();
|
|
13794
13796
|
const summary = useTasksStore((s) => s.summary);
|
|
13795
|
-
return
|
|
13797
|
+
return React128__default.useMemo(() => {
|
|
13796
13798
|
if (!summary) return "";
|
|
13797
13799
|
const parts = [];
|
|
13798
13800
|
if (summary.overdue > 0) parts.push(`${summary.overdue} ${t("tasks.summary.overdue")}`);
|
|
@@ -13817,16 +13819,16 @@ function TasksRailPanel() {
|
|
|
13817
13819
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13818
13820
|
const setCurrentUserId = useTasksStore((s) => s.setCurrentUserId);
|
|
13819
13821
|
const userId = useAuthStore6((s) => s.user?.id);
|
|
13820
|
-
|
|
13822
|
+
React128__default.useEffect(() => {
|
|
13821
13823
|
void fetchSummary();
|
|
13822
13824
|
}, [fetchSummary]);
|
|
13823
|
-
|
|
13825
|
+
React128__default.useEffect(() => {
|
|
13824
13826
|
setCurrentUserId(userId ?? null);
|
|
13825
13827
|
}, [userId, setCurrentUserId]);
|
|
13826
13828
|
const openCount = summary ? summary.todo + summary.inProgress : 0;
|
|
13827
13829
|
const defer = tasksSurfaceOwner() === "plugin";
|
|
13828
13830
|
useRightRailPanel(
|
|
13829
|
-
|
|
13831
|
+
React128__default.useMemo(
|
|
13830
13832
|
() => defer ? null : {
|
|
13831
13833
|
id: "tasks",
|
|
13832
13834
|
label: t("tasks.drawer.title") || "Tasks",
|
|
@@ -13850,15 +13852,15 @@ var useSettingsTabsStore = create((set, get) => ({
|
|
|
13850
13852
|
}));
|
|
13851
13853
|
function usePublishSettingsTabs(ids) {
|
|
13852
13854
|
const key = ids.join(",");
|
|
13853
|
-
|
|
13855
|
+
React128.useEffect(() => {
|
|
13854
13856
|
useSettingsTabsStore.getState().setIds(key ? key.split(",") : []);
|
|
13855
13857
|
}, [key]);
|
|
13856
13858
|
}
|
|
13857
13859
|
function useAgentSurface(contribution) {
|
|
13858
|
-
const ref =
|
|
13860
|
+
const ref = React128.useRef(contribution);
|
|
13859
13861
|
ref.current = contribution;
|
|
13860
13862
|
const id = contribution.id;
|
|
13861
|
-
|
|
13863
|
+
React128.useEffect(() => {
|
|
13862
13864
|
registerSurface({ id, get: () => ref.current });
|
|
13863
13865
|
const names = (ref.current.tools ?? []).map((t) => t.tool.name);
|
|
13864
13866
|
for (const name of names) {
|
|
@@ -14638,9 +14640,9 @@ function featureMap() {
|
|
|
14638
14640
|
}));
|
|
14639
14641
|
}
|
|
14640
14642
|
function ActivationAgentSurface({ programs }) {
|
|
14641
|
-
const programsRef =
|
|
14643
|
+
const programsRef = React128.useRef(programs);
|
|
14642
14644
|
programsRef.current = programs;
|
|
14643
|
-
const contribution =
|
|
14645
|
+
const contribution = React128.useMemo(
|
|
14644
14646
|
() => ({
|
|
14645
14647
|
id: "onboarding.activation",
|
|
14646
14648
|
pluginId: "onboarding",
|
|
@@ -14961,7 +14963,7 @@ Quando a pessoa perguntar COMO fazer algo que tem guia em \`setupGuides\` ("como
|
|
|
14961
14963
|
- Termine dizendo o que isso destrava e oferecendo a pr\xF3xima, uma vez s\xF3.`
|
|
14962
14964
|
);
|
|
14963
14965
|
function SetupAgentSurface() {
|
|
14964
|
-
const contribution =
|
|
14966
|
+
const contribution = React128.useMemo(
|
|
14965
14967
|
() => ({
|
|
14966
14968
|
id: "setup.guides",
|
|
14967
14969
|
pluginId: "setup",
|
|
@@ -15077,7 +15079,7 @@ function SetupAgentSurface() {
|
|
|
15077
15079
|
}
|
|
15078
15080
|
var DEBOUNCE_MS = 1200;
|
|
15079
15081
|
function useActivationWatch() {
|
|
15080
|
-
|
|
15082
|
+
React128.useEffect(() => {
|
|
15081
15083
|
let timer = null;
|
|
15082
15084
|
let running = false;
|
|
15083
15085
|
const sweep = async () => {
|
|
@@ -15116,7 +15118,7 @@ function useActivationWatch() {
|
|
|
15116
15118
|
off();
|
|
15117
15119
|
};
|
|
15118
15120
|
}, []);
|
|
15119
|
-
|
|
15121
|
+
React128.useEffect(() => {
|
|
15120
15122
|
useActivationStore.setState({
|
|
15121
15123
|
onStepCompleted: (step, by) => {
|
|
15122
15124
|
const state = useActivationStore.getState();
|
|
@@ -15773,7 +15775,7 @@ function ActivationProvider() {
|
|
|
15773
15775
|
const programs = runtime?.onboardingPrograms ?? [];
|
|
15774
15776
|
const settingsIds = useSettingsTabsStore((s) => s.ids);
|
|
15775
15777
|
const routeKey = (runtime?.routes.length ?? 0) + ":" + settingsIds.join(",");
|
|
15776
|
-
const hasRoute =
|
|
15778
|
+
const hasRoute = React128.useMemo(() => {
|
|
15777
15779
|
const known = /* @__PURE__ */ new Set(["/", "/settings"]);
|
|
15778
15780
|
for (const route of runtime?.routes ?? []) known.add(route.path);
|
|
15779
15781
|
for (const id of settingsIds) known.add(`/settings/${id}`);
|
|
@@ -15781,14 +15783,14 @@ function ActivationProvider() {
|
|
|
15781
15783
|
}, [routeKey]);
|
|
15782
15784
|
const answers = useBusinessProfileStore((s) => s.profile?.answers);
|
|
15783
15785
|
const programKey = programs.map((p) => p.id).join(",");
|
|
15784
|
-
const catalog =
|
|
15786
|
+
const catalog = React128.useMemo(
|
|
15785
15787
|
() => buildActivationCatalog({ verticalId, programs, hasRoute, answers }),
|
|
15786
15788
|
[verticalId, programKey, hasRoute, answers]
|
|
15787
15789
|
);
|
|
15788
|
-
|
|
15790
|
+
React128.useEffect(() => {
|
|
15789
15791
|
setCatalog(catalog);
|
|
15790
15792
|
}, [catalog, setCatalog]);
|
|
15791
|
-
|
|
15793
|
+
React128.useEffect(() => {
|
|
15792
15794
|
if (!tenantId2) return;
|
|
15793
15795
|
let cancelled = false;
|
|
15794
15796
|
void (async () => {
|
|
@@ -15820,14 +15822,14 @@ function ActivationProvider() {
|
|
|
15820
15822
|
cancelled = true;
|
|
15821
15823
|
};
|
|
15822
15824
|
}, [tenantId2, catalog, answers, hasRoute, settingsIds, user?.id, load]);
|
|
15823
|
-
|
|
15825
|
+
React128.useEffect(() => {
|
|
15824
15826
|
if (!tenantId2) {
|
|
15825
15827
|
useBusinessProfileStore.getState().clear();
|
|
15826
15828
|
return;
|
|
15827
15829
|
}
|
|
15828
15830
|
void useBusinessProfileStore.getState().load(tenantId2, orgName);
|
|
15829
15831
|
}, [tenantId2, orgName]);
|
|
15830
|
-
|
|
15832
|
+
React128.useEffect(() => {
|
|
15831
15833
|
if (!tenantId2) return;
|
|
15832
15834
|
const key = `${GREETING_FLAG}:${tenantId2}`;
|
|
15833
15835
|
let pending2 = false;
|
|
@@ -15849,10 +15851,10 @@ function ActivationProvider() {
|
|
|
15849
15851
|
return () => window.clearTimeout(timer);
|
|
15850
15852
|
}, [tenantId2]);
|
|
15851
15853
|
const guides = runtime?.setupGuides;
|
|
15852
|
-
|
|
15854
|
+
React128.useEffect(() => {
|
|
15853
15855
|
setRuntimeSetupGuides(guides ?? []);
|
|
15854
15856
|
}, [guides]);
|
|
15855
|
-
|
|
15857
|
+
React128.useEffect(() => {
|
|
15856
15858
|
setTourNavigator(navigateTo);
|
|
15857
15859
|
return () => setTourNavigator(void 0);
|
|
15858
15860
|
}, []);
|
|
@@ -16025,7 +16027,7 @@ Escrita:
|
|
|
16025
16027
|
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
16028
|
);
|
|
16027
16029
|
function HandbookAgentSurface() {
|
|
16028
|
-
const contribution =
|
|
16030
|
+
const contribution = React128.useMemo(
|
|
16029
16031
|
() => ({
|
|
16030
16032
|
id: "handbook",
|
|
16031
16033
|
pluginId: "handbook",
|
|
@@ -16136,18 +16138,18 @@ function NotebookPanel() {
|
|
|
16136
16138
|
const userId = useHandbookStore((s) => s.userId);
|
|
16137
16139
|
const write3 = useHandbookStore((s) => s.write);
|
|
16138
16140
|
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 =
|
|
16141
|
+
const [filter, setFilter] = React128.useState("all");
|
|
16142
|
+
const [search, setSearch] = React128.useState("");
|
|
16143
|
+
const [draft, setDraft] = React128.useState(null);
|
|
16144
|
+
const [preview, setPreview] = React128.useState(false);
|
|
16145
|
+
const [confirming, setConfirming] = React128.useState(null);
|
|
16146
|
+
const entries2 = React128.useMemo(
|
|
16145
16147
|
() => (pages ?? []).map((p) => ({ page: p, entry: toEntry2(p) })),
|
|
16146
16148
|
[pages]
|
|
16147
16149
|
);
|
|
16148
|
-
const timer =
|
|
16149
|
-
const inFlight =
|
|
16150
|
-
const persist =
|
|
16150
|
+
const timer = React128.useRef(null);
|
|
16151
|
+
const inFlight = React128.useRef(false);
|
|
16152
|
+
const persist = React128.useCallback(async (d) => {
|
|
16151
16153
|
const title = titleFromBody(d.body);
|
|
16152
16154
|
if (!title && !d.body.trim()) return d.id;
|
|
16153
16155
|
const filed = d.folder !== null;
|
|
@@ -16169,7 +16171,7 @@ function NotebookPanel() {
|
|
|
16169
16171
|
});
|
|
16170
16172
|
return saved?.id ?? d.id;
|
|
16171
16173
|
}, [write3, userId]);
|
|
16172
|
-
const schedule =
|
|
16174
|
+
const schedule = React128.useCallback((next) => {
|
|
16173
16175
|
setDraft(next);
|
|
16174
16176
|
if (timer.current) clearTimeout(timer.current);
|
|
16175
16177
|
timer.current = setTimeout(() => {
|
|
@@ -16201,7 +16203,7 @@ function NotebookPanel() {
|
|
|
16201
16203
|
legacyId: null
|
|
16202
16204
|
});
|
|
16203
16205
|
};
|
|
16204
|
-
const folders =
|
|
16206
|
+
const folders = React128.useMemo(() => {
|
|
16205
16207
|
const set = /* @__PURE__ */ new Set();
|
|
16206
16208
|
for (const { page } of entries2) {
|
|
16207
16209
|
if (page.kind !== "doc" || !page.path) continue;
|
|
@@ -16593,10 +16595,10 @@ ${body}`
|
|
|
16593
16595
|
}
|
|
16594
16596
|
function NoteTodosSection({ noteId, noteTitle }) {
|
|
16595
16597
|
const adapter = useNotesTasksBridge((s) => s.adapter);
|
|
16596
|
-
const [todos, setTodos] =
|
|
16597
|
-
const [draft, setDraft] =
|
|
16598
|
-
const [busy, setBusy] =
|
|
16599
|
-
|
|
16598
|
+
const [todos, setTodos] = React128.useState([]);
|
|
16599
|
+
const [draft, setDraft] = React128.useState("");
|
|
16600
|
+
const [busy, setBusy] = React128.useState(false);
|
|
16601
|
+
React128.useEffect(() => {
|
|
16600
16602
|
if (!adapter) return;
|
|
16601
16603
|
let alive = true;
|
|
16602
16604
|
adapter.listTodos(noteId).then((rows) => {
|
|
@@ -16726,7 +16728,7 @@ function NotebookRailPanel() {
|
|
|
16726
16728
|
const pages = useHandbookStore((s) => s.pages);
|
|
16727
16729
|
const count = pages?.length ?? 0;
|
|
16728
16730
|
useRightRailPanel(
|
|
16729
|
-
|
|
16731
|
+
React128.useMemo(
|
|
16730
16732
|
() => ({
|
|
16731
16733
|
id: "notes",
|
|
16732
16734
|
label: tl("Notes", "Notas"),
|
|
@@ -16745,10 +16747,10 @@ function HandbookProvider() {
|
|
|
16745
16747
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16746
16748
|
const load = useHandbookStore((s) => s.load);
|
|
16747
16749
|
const setUser = useHandbookStore((s) => s.setUser);
|
|
16748
|
-
|
|
16750
|
+
React128.useEffect(() => {
|
|
16749
16751
|
setUser(userId);
|
|
16750
16752
|
}, [userId, setUser]);
|
|
16751
|
-
|
|
16753
|
+
React128.useEffect(() => {
|
|
16752
16754
|
if (tenantId2) void load(tenantId2);
|
|
16753
16755
|
}, [tenantId2, load]);
|
|
16754
16756
|
useLocalNotesImport(tenantId2, userId);
|
|
@@ -16758,7 +16760,7 @@ function HandbookProvider() {
|
|
|
16758
16760
|
] });
|
|
16759
16761
|
}
|
|
16760
16762
|
function useLocalNotesImport(tenantId2, userId) {
|
|
16761
|
-
|
|
16763
|
+
React128.useEffect(() => {
|
|
16762
16764
|
if (!tenantId2 || !userId) return;
|
|
16763
16765
|
const source = `fayz.notes.${tenantId2}.${userId}`;
|
|
16764
16766
|
const flag = `fayz.notes.imported.${tenantId2}.${userId}`;
|
|
@@ -16806,7 +16808,7 @@ function useUnitBootstrap() {
|
|
|
16806
16808
|
const tenant = useTenantOptional();
|
|
16807
16809
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16808
16810
|
const orgId = tenant?.org?.id;
|
|
16809
|
-
|
|
16811
|
+
React128.useEffect(() => {
|
|
16810
16812
|
if (!orgId) return;
|
|
16811
16813
|
const { loadedFor, load, reset } = useUnitStore.getState();
|
|
16812
16814
|
if (loadedFor && loadedFor !== orgId) reset();
|
|
@@ -16845,19 +16847,19 @@ function UnitMembersTab({ item }) {
|
|
|
16845
16847
|
const orgMembers = useOrganizationStore((s) => s.members);
|
|
16846
16848
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
16847
16849
|
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 =
|
|
16850
|
+
const [rows, setRows] = React128.useState(null);
|
|
16851
|
+
const [activity, setActivity] = React128.useState({});
|
|
16852
|
+
const [adding, setAdding] = React128.useState(false);
|
|
16853
|
+
const [busy, setBusy] = React128.useState(null);
|
|
16854
|
+
const reload = React128.useCallback(async () => {
|
|
16853
16855
|
if (!unitId) return;
|
|
16854
16856
|
setRows(await fetchUnitMembers(unitId));
|
|
16855
16857
|
}, [unitId]);
|
|
16856
16858
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
16857
|
-
|
|
16859
|
+
React128.useEffect(() => {
|
|
16858
16860
|
void reload();
|
|
16859
16861
|
}, [reload, version5]);
|
|
16860
|
-
|
|
16862
|
+
React128.useEffect(() => {
|
|
16861
16863
|
if (!orgId) return;
|
|
16862
16864
|
let alive = true;
|
|
16863
16865
|
void fetchMemberActivity(orgId).then((a) => {
|
|
@@ -16867,7 +16869,7 @@ function UnitMembersTab({ item }) {
|
|
|
16867
16869
|
alive = false;
|
|
16868
16870
|
};
|
|
16869
16871
|
}, [orgId]);
|
|
16870
|
-
const byUser =
|
|
16872
|
+
const byUser = React128.useMemo(() => {
|
|
16871
16873
|
const map = /* @__PURE__ */ new Map();
|
|
16872
16874
|
for (const m of orgMembers) {
|
|
16873
16875
|
map.set(m.userId, {
|
|
@@ -16879,7 +16881,7 @@ function UnitMembersTab({ item }) {
|
|
|
16879
16881
|
}
|
|
16880
16882
|
return map;
|
|
16881
16883
|
}, [orgMembers]);
|
|
16882
|
-
const available =
|
|
16884
|
+
const available = React128.useMemo(
|
|
16883
16885
|
() => orgMembers.filter((m) => !(rows ?? []).some((r) => r.userId === m.userId)),
|
|
16884
16886
|
[orgMembers, rows]
|
|
16885
16887
|
);
|
|
@@ -17085,15 +17087,15 @@ function MemberAccessBody({
|
|
|
17085
17087
|
const units = useUnitStore((s) => s.units);
|
|
17086
17088
|
const byId = useUnitStore((s) => s.byId);
|
|
17087
17089
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
17088
|
-
const [bindings, setBindings] =
|
|
17089
|
-
const [loading, setLoading] =
|
|
17090
|
-
const [adding, setAdding] =
|
|
17091
|
-
const branches =
|
|
17092
|
-
const unbound =
|
|
17090
|
+
const [bindings, setBindings] = React128.useState([]);
|
|
17091
|
+
const [loading, setLoading] = React128.useState(false);
|
|
17092
|
+
const [adding, setAdding] = React128.useState(false);
|
|
17093
|
+
const branches = React128.useMemo(() => units.filter((u) => u.isActive !== false), [units]);
|
|
17094
|
+
const unbound = React128.useMemo(
|
|
17093
17095
|
() => branches.filter((u) => !bindings.some((b) => b.locationId === u.id)),
|
|
17094
17096
|
[branches, bindings]
|
|
17095
17097
|
);
|
|
17096
|
-
const reload =
|
|
17098
|
+
const reload = React128.useCallback(async () => {
|
|
17097
17099
|
if (!userId) return;
|
|
17098
17100
|
setLoading(true);
|
|
17099
17101
|
try {
|
|
@@ -17103,7 +17105,7 @@ function MemberAccessBody({
|
|
|
17103
17105
|
}
|
|
17104
17106
|
}, [userId]);
|
|
17105
17107
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
17106
|
-
|
|
17108
|
+
React128.useEffect(() => {
|
|
17107
17109
|
void reload();
|
|
17108
17110
|
}, [reload, version5]);
|
|
17109
17111
|
async function add(unitId) {
|
|
@@ -17790,7 +17792,7 @@ function useWrongApp() {
|
|
|
17790
17792
|
const tenantId2 = useAppConfigStore((s) => s.tenantId);
|
|
17791
17793
|
const activeTenantId = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
17792
17794
|
const appId = resolveAppId();
|
|
17793
|
-
return
|
|
17795
|
+
return React128.useMemo(() => {
|
|
17794
17796
|
if (!appId || !activeTenantId || tenantId2 !== activeTenantId) return { app: null };
|
|
17795
17797
|
const list = (apps ?? []).filter((a) => !a.house);
|
|
17796
17798
|
if (!list.length) return { app: null };
|
|
@@ -17913,13 +17915,13 @@ function surveyTokenFromPath(pathname) {
|
|
|
17913
17915
|
return m ? decodeURIComponent(m[1]) : null;
|
|
17914
17916
|
}
|
|
17915
17917
|
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
|
-
|
|
17918
|
+
const [loaded2, setLoaded] = React128__default.useState(null);
|
|
17919
|
+
const [draft, setDraft] = React128__default.useState({});
|
|
17920
|
+
const [name, setName] = React128__default.useState("");
|
|
17921
|
+
const [sending, setSending] = React128__default.useState(false);
|
|
17922
|
+
const [sent, setSent] = React128__default.useState(null);
|
|
17923
|
+
const [failed, setFailed] = React128__default.useState(null);
|
|
17924
|
+
React128__default.useEffect(() => {
|
|
17923
17925
|
let alive = true;
|
|
17924
17926
|
const client3 = getFayzSupabaseClientOptional();
|
|
17925
17927
|
if (!client3) {
|
|
@@ -18217,7 +18219,7 @@ function isServed2(route) {
|
|
|
18217
18219
|
function getPersonActions(kind) {
|
|
18218
18220
|
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
18221
|
}
|
|
18220
|
-
var RouteErrorBoundary = class extends
|
|
18222
|
+
var RouteErrorBoundary = class extends React128.Component {
|
|
18221
18223
|
constructor() {
|
|
18222
18224
|
super(...arguments);
|
|
18223
18225
|
this.state = { crashed: false, report: null };
|
|
@@ -18259,7 +18261,7 @@ var RouteErrorBoundary = class extends React127.Component {
|
|
|
18259
18261
|
}
|
|
18260
18262
|
};
|
|
18261
18263
|
function RouteErrorScreen({ report, tr, onBack, onRetry, backLabel }) {
|
|
18262
|
-
const [copied, setCopied] =
|
|
18264
|
+
const [copied, setCopied] = React128.useState(false);
|
|
18263
18265
|
const copyDetails = () => {
|
|
18264
18266
|
if (!report || typeof navigator === "undefined" || !navigator.clipboard) return;
|
|
18265
18267
|
const details = [
|
|
@@ -18364,9 +18366,9 @@ function UnitSwitching({ unitName, isAll, onDone }) {
|
|
|
18364
18366
|
const v = t(key);
|
|
18365
18367
|
return !v || v === key ? fallback : v;
|
|
18366
18368
|
};
|
|
18367
|
-
const doneRef =
|
|
18369
|
+
const doneRef = React128.useRef(onDone);
|
|
18368
18370
|
doneRef.current = onDone;
|
|
18369
|
-
|
|
18371
|
+
React128.useEffect(() => {
|
|
18370
18372
|
const id = window.setTimeout(() => doneRef.current(), HOLD_MS);
|
|
18371
18373
|
return () => window.clearTimeout(id);
|
|
18372
18374
|
}, []);
|
|
@@ -18423,11 +18425,11 @@ function UnitPickerDialog() {
|
|
|
18423
18425
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
18424
18426
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
18425
18427
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
18426
|
-
const reachable =
|
|
18428
|
+
const reachable = React128.useMemo(
|
|
18427
18429
|
() => myUnitIds.length > 0 ? myUnitIds : units.filter((u) => u.kind !== "region").map((u) => u.id),
|
|
18428
18430
|
[myUnitIds, units]
|
|
18429
18431
|
);
|
|
18430
|
-
const groups =
|
|
18432
|
+
const groups = React128.useMemo(() => {
|
|
18431
18433
|
const out = [];
|
|
18432
18434
|
if (reachable.length > 1) {
|
|
18433
18435
|
out.push({ id: "_all", options: [{ id: ALL_UNITS, label: "Todas as unidades" }] });
|
|
@@ -18626,16 +18628,16 @@ function WorkspaceSetupFlow({
|
|
|
18626
18628
|
const user = useAuthStore((s) => s.user);
|
|
18627
18629
|
const { switchOrg } = useTenant();
|
|
18628
18630
|
const closeSetup = useWorkspaceSetupStore((s) => s.close);
|
|
18629
|
-
const uploadLogo =
|
|
18631
|
+
const uploadLogo = React128.useMemo(
|
|
18630
18632
|
() => user ? createLogoUploader(user.id) : void 0,
|
|
18631
18633
|
[user?.id]
|
|
18632
18634
|
);
|
|
18633
|
-
const country =
|
|
18635
|
+
const country = React128.useMemo(
|
|
18634
18636
|
() => currency === "BRL" || (locale ?? "").toLowerCase().startsWith("pt") ? "BR" : void 0,
|
|
18635
18637
|
[currency, locale]
|
|
18636
18638
|
);
|
|
18637
|
-
const stepsRef =
|
|
18638
|
-
const analyzeSite =
|
|
18639
|
+
const stepsRef = React128.useRef([]);
|
|
18640
|
+
const analyzeSite = React128.useMemo(
|
|
18639
18641
|
() => createSiteAnalyzer({
|
|
18640
18642
|
apiBaseUrl: resolveFayzApiBaseUrl(),
|
|
18641
18643
|
steps: () => stepsRef.current,
|
|
@@ -18643,7 +18645,7 @@ function WorkspaceSetupFlow({
|
|
|
18643
18645
|
}),
|
|
18644
18646
|
[locale]
|
|
18645
18647
|
);
|
|
18646
|
-
const steps =
|
|
18648
|
+
const steps = React128.useMemo(
|
|
18647
18649
|
() => buildWorkspaceSetupSteps({
|
|
18648
18650
|
verticalId,
|
|
18649
18651
|
uploadLogo,
|
|
@@ -18655,13 +18657,13 @@ function WorkspaceSetupFlow({
|
|
|
18655
18657
|
[verticalId, uploadLogo, media, country, analyzeSite]
|
|
18656
18658
|
);
|
|
18657
18659
|
stepsRef.current = steps;
|
|
18658
|
-
const initialValues2 =
|
|
18660
|
+
const initialValues2 = React128.useMemo(
|
|
18659
18661
|
// Seeding the contact email with the account's own is one field fewer to
|
|
18660
18662
|
// type, and it is right far more often than it is wrong.
|
|
18661
18663
|
() => user?.email ? { "workspace.email": user.email } : {},
|
|
18662
18664
|
[user?.email]
|
|
18663
18665
|
);
|
|
18664
|
-
const onSubmit =
|
|
18666
|
+
const onSubmit = React128.useCallback(
|
|
18665
18667
|
async (values) => {
|
|
18666
18668
|
if (!user) throw new Error(tl("You are signed out.", "Sua sess\xE3o terminou."));
|
|
18667
18669
|
const org = await submitWorkspaceSetup({
|
|
@@ -18778,16 +18780,16 @@ function GettingStartedWidget() {
|
|
|
18778
18780
|
const t = useTranslation();
|
|
18779
18781
|
const rows = useActivationStore((s) => s.rows);
|
|
18780
18782
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18781
|
-
const steps =
|
|
18783
|
+
const steps = React128.useMemo(
|
|
18782
18784
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18783
18785
|
[rows, catalog]
|
|
18784
18786
|
);
|
|
18785
|
-
const onNavigate =
|
|
18787
|
+
const onNavigate = React128.useCallback((path) => {
|
|
18786
18788
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18787
18789
|
navigateTo(path);
|
|
18788
18790
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18789
18791
|
}, []);
|
|
18790
|
-
const onAskAgent =
|
|
18792
|
+
const onAskAgent = React128.useCallback((step) => {
|
|
18791
18793
|
void startGuidedRun(step.id);
|
|
18792
18794
|
}, []);
|
|
18793
18795
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18812,16 +18814,16 @@ function ActivationChecklistCard({
|
|
|
18812
18814
|
}) {
|
|
18813
18815
|
const rows = useActivationStore((s) => s.rows);
|
|
18814
18816
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18815
|
-
const steps =
|
|
18817
|
+
const steps = React128.useMemo(
|
|
18816
18818
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18817
18819
|
[rows, catalog]
|
|
18818
18820
|
);
|
|
18819
|
-
const onNavigate =
|
|
18821
|
+
const onNavigate = React128.useCallback((path) => {
|
|
18820
18822
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18821
18823
|
navigateTo(path);
|
|
18822
18824
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18823
18825
|
}, []);
|
|
18824
|
-
const onAskAgent =
|
|
18826
|
+
const onAskAgent = React128.useCallback((step) => {
|
|
18825
18827
|
void startGuidedRun(step.id);
|
|
18826
18828
|
}, []);
|
|
18827
18829
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18855,12 +18857,12 @@ function rememberCompleted(storageKey2) {
|
|
|
18855
18857
|
}
|
|
18856
18858
|
}
|
|
18857
18859
|
function usePluginOnboardingGate(storageKey2, checkExistingData) {
|
|
18858
|
-
const checkRef =
|
|
18860
|
+
const checkRef = React128.useRef(checkExistingData);
|
|
18859
18861
|
checkRef.current = checkExistingData;
|
|
18860
|
-
const [status, setStatus] =
|
|
18862
|
+
const [status, setStatus] = React128.useState(
|
|
18861
18863
|
() => wasCompleted(storageKey2) ? "complete" : "checking"
|
|
18862
18864
|
);
|
|
18863
|
-
|
|
18865
|
+
React128.useEffect(() => {
|
|
18864
18866
|
if (status !== "checking") return;
|
|
18865
18867
|
let cancelled = false;
|
|
18866
18868
|
void checkRef.current().then((hasData) => {
|
|
@@ -18874,7 +18876,7 @@ function usePluginOnboardingGate(storageKey2, checkExistingData) {
|
|
|
18874
18876
|
cancelled = true;
|
|
18875
18877
|
};
|
|
18876
18878
|
}, [status, storageKey2]);
|
|
18877
|
-
const complete =
|
|
18879
|
+
const complete = React128.useCallback(() => {
|
|
18878
18880
|
rememberCompleted(storageKey2);
|
|
18879
18881
|
setStatus("complete");
|
|
18880
18882
|
}, [storageKey2]);
|
|
@@ -18894,9 +18896,9 @@ function PluginOnboardingGateSkeleton() {
|
|
|
18894
18896
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-72 rounded-card" })
|
|
18895
18897
|
] });
|
|
18896
18898
|
}
|
|
18897
|
-
var WidgetSurfaceContext =
|
|
18899
|
+
var WidgetSurfaceContext = React128.createContext("rail");
|
|
18898
18900
|
function useWidgetSurface() {
|
|
18899
|
-
return
|
|
18901
|
+
return React128.useContext(WidgetSurfaceContext);
|
|
18900
18902
|
}
|
|
18901
18903
|
function WidgetSlot({
|
|
18902
18904
|
zone,
|
|
@@ -18940,7 +18942,7 @@ function useNavContribution(id, entries2) {
|
|
|
18940
18942
|
const setContribution = useNavContributionsStore((s) => s.setContribution);
|
|
18941
18943
|
const clearContribution = useNavContributionsStore((s) => s.clearContribution);
|
|
18942
18944
|
const key = JSON.stringify(entries2);
|
|
18943
|
-
|
|
18945
|
+
React128.useEffect(() => {
|
|
18944
18946
|
setContribution(id, entries2);
|
|
18945
18947
|
return () => clearContribution(id);
|
|
18946
18948
|
}, [id, key]);
|
|
@@ -19010,7 +19012,7 @@ function useAppDirectory() {
|
|
|
19010
19012
|
const tenantId2 = useActiveTenantId();
|
|
19011
19013
|
const apps = useAppDirectoryStore((s) => s.apps);
|
|
19012
19014
|
const load = useAppDirectoryStore((s) => s.load);
|
|
19013
|
-
|
|
19015
|
+
React128.useEffect(() => {
|
|
19014
19016
|
if (tenantId2) void load(tenantId2, resolveAppId());
|
|
19015
19017
|
}, [tenantId2, load]);
|
|
19016
19018
|
return { apps };
|
|
@@ -19102,7 +19104,7 @@ var CSS2 = `
|
|
|
19102
19104
|
}
|
|
19103
19105
|
`;
|
|
19104
19106
|
function useWordmarkStyle() {
|
|
19105
|
-
|
|
19107
|
+
React128.useEffect(() => {
|
|
19106
19108
|
if (typeof document === "undefined") return;
|
|
19107
19109
|
const existing = document.getElementById(STYLE_ID2);
|
|
19108
19110
|
if (existing) {
|
|
@@ -19336,7 +19338,7 @@ var SWAP_CSS = `
|
|
|
19336
19338
|
}
|
|
19337
19339
|
`;
|
|
19338
19340
|
function useSwapStyle() {
|
|
19339
|
-
|
|
19341
|
+
React128.useEffect(() => {
|
|
19340
19342
|
if (typeof document === "undefined" || document.getElementById(SWAP_STYLE_ID)) return;
|
|
19341
19343
|
const el = document.createElement("style");
|
|
19342
19344
|
el.id = SWAP_STYLE_ID;
|
|
@@ -19345,9 +19347,9 @@ function useSwapStyle() {
|
|
|
19345
19347
|
}, []);
|
|
19346
19348
|
}
|
|
19347
19349
|
function AppSwitcherView({ apps, mark, logo, collapsed = false, label: label3, onSelect, brandedByTenant = false }) {
|
|
19348
|
-
const [hovered, setHovered] =
|
|
19349
|
-
const [open, setOpen] =
|
|
19350
|
-
const [pending2, setPending] =
|
|
19350
|
+
const [hovered, setHovered] = React128.useState(false);
|
|
19351
|
+
const [open, setOpen] = React128.useState(false);
|
|
19352
|
+
const [pending2, setPending] = React128.useState(null);
|
|
19351
19353
|
const active2 = hovered || open;
|
|
19352
19354
|
useSwapStyle();
|
|
19353
19355
|
const brand = /* @__PURE__ */ jsx(BrandFace, { mark, logo, collapsed });
|
|
@@ -19494,7 +19496,7 @@ function useContextualNav(nav) {
|
|
|
19494
19496
|
const setNav = useContextualNavStore((s) => s.setNav);
|
|
19495
19497
|
const clearNav = useContextualNavStore((s) => s.clearNav);
|
|
19496
19498
|
const key = nav ? JSON.stringify(nav) : null;
|
|
19497
|
-
|
|
19499
|
+
React128.useEffect(() => {
|
|
19498
19500
|
if (!nav) return;
|
|
19499
19501
|
setNav(nav);
|
|
19500
19502
|
return () => clearNav(nav.base);
|
|
@@ -19566,7 +19568,7 @@ async function findNearestUnit(units, reachable) {
|
|
|
19566
19568
|
}
|
|
19567
19569
|
var UNIT_SEARCH_THRESHOLD = 8;
|
|
19568
19570
|
function WorkspaceUnitSheet({ onClose, canCreate = true }) {
|
|
19569
|
-
const [level, setLevel] =
|
|
19571
|
+
const [level, setLevel] = React128.useState("root");
|
|
19570
19572
|
return /* @__PURE__ */ jsxs(
|
|
19571
19573
|
BottomSheet,
|
|
19572
19574
|
{
|
|
@@ -19629,9 +19631,9 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19629
19631
|
const closeSheet = useSheetClose();
|
|
19630
19632
|
const beginSwitch = useWorkspaceSwitchingStore((s) => s.begin);
|
|
19631
19633
|
const openSetup = useWorkspaceSetupStore((s) => s.open);
|
|
19632
|
-
const [query, setQuery] =
|
|
19634
|
+
const [query, setQuery] = React128.useState("");
|
|
19633
19635
|
const org = tenant?.org ?? null;
|
|
19634
|
-
const options =
|
|
19636
|
+
const options = React128.useMemo(() => {
|
|
19635
19637
|
const list = tenant?.userOrgs ?? [];
|
|
19636
19638
|
if (list.length) return list;
|
|
19637
19639
|
return org ? [{ orgId: org.id, orgName: org.name, orgSlug: org.slug, orgLogoUrl: org.logoUrl }] : [];
|
|
@@ -19640,7 +19642,7 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19640
19642
|
const v = t.t(key);
|
|
19641
19643
|
return !v || v === key ? fallback : v;
|
|
19642
19644
|
};
|
|
19643
|
-
const search =
|
|
19645
|
+
const search = React128.useMemo(
|
|
19644
19646
|
() => searchWorkspaces(options, query, org?.id),
|
|
19645
19647
|
[options, query, org?.id]
|
|
19646
19648
|
);
|
|
@@ -19692,8 +19694,8 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19692
19694
|
function UnitLevel() {
|
|
19693
19695
|
useUnitBootstrap();
|
|
19694
19696
|
const closeSheet = useSheetClose();
|
|
19695
|
-
const [locating, setLocating] =
|
|
19696
|
-
const [query, setQuery] =
|
|
19697
|
+
const [locating, setLocating] = React128.useState(false);
|
|
19698
|
+
const [query, setQuery] = React128.useState("");
|
|
19697
19699
|
const units = useUnitStore((s) => s.units);
|
|
19698
19700
|
const tree = useUnitStore((s) => s.tree);
|
|
19699
19701
|
const byId = useUnitStore((s) => s.byId);
|
|
@@ -19730,7 +19732,7 @@ function UnitLevel() {
|
|
|
19730
19732
|
const leaves = node.children.filter((c) => c.kind !== "region" && reachable.includes(c.id));
|
|
19731
19733
|
const regions = node.children.filter((c) => c.kind === "region");
|
|
19732
19734
|
if (leaves.length === 0 && regions.length === 0) return null;
|
|
19733
|
-
return /* @__PURE__ */ jsxs(
|
|
19735
|
+
return /* @__PURE__ */ jsxs(React128.Fragment, { children: [
|
|
19734
19736
|
/* @__PURE__ */ jsx("p", { className: "px-4 pb-1 pt-3 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
19735
19737
|
leaves.length > 0 && /* @__PURE__ */ jsx(SheetCard, { children: leaves.map(leaf) }),
|
|
19736
19738
|
regions.map(group)
|
|
@@ -19800,7 +19802,7 @@ function UnitLevel() {
|
|
|
19800
19802
|
}
|
|
19801
19803
|
function WorkspaceUnitRow({ canCreate = true }) {
|
|
19802
19804
|
useUnitBootstrap();
|
|
19803
|
-
const [open, setOpen] =
|
|
19805
|
+
const [open, setOpen] = React128.useState(false);
|
|
19804
19806
|
const tenant = useTenantOptional();
|
|
19805
19807
|
const org = tenant?.org ?? null;
|
|
19806
19808
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
@@ -19987,10 +19989,10 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
19987
19989
|
const load = useFayzProjectsStore((s) => s.load);
|
|
19988
19990
|
const loadedFor = useFayzProjectsStore((s) => s.loadedFor);
|
|
19989
19991
|
const collapsed = useLayoutStore((s) => s.sidebarCollapsed);
|
|
19990
|
-
const [selectedId, setSelectedId] =
|
|
19991
|
-
const [hovered, setHovered] =
|
|
19992
|
-
const [primed, setPrimed] =
|
|
19993
|
-
const closeTimer =
|
|
19992
|
+
const [selectedId, setSelectedId] = React128.useState(null);
|
|
19993
|
+
const [hovered, setHovered] = React128.useState(false);
|
|
19994
|
+
const [primed, setPrimed] = React128.useState(false);
|
|
19995
|
+
const closeTimer = React128.useRef(null);
|
|
19994
19996
|
const cancelClose = () => {
|
|
19995
19997
|
if (closeTimer.current) {
|
|
19996
19998
|
clearTimeout(closeTimer.current);
|
|
@@ -20006,8 +20008,8 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
20006
20008
|
cancelClose();
|
|
20007
20009
|
closeTimer.current = setTimeout(() => setHovered(false), 140);
|
|
20008
20010
|
};
|
|
20009
|
-
|
|
20010
|
-
|
|
20011
|
+
React128.useEffect(() => () => cancelClose(), []);
|
|
20012
|
+
React128.useEffect(() => {
|
|
20011
20013
|
if (loadedFor !== (currentOrgId ?? null)) void load(currentOrgId);
|
|
20012
20014
|
}, [currentOrgId, loadedFor, load]);
|
|
20013
20015
|
const active2 = projects.find((p) => p.id === selectedId) ?? defaultProjectOf(projects) ?? synthFromFallback(fallback);
|
|
@@ -20118,10 +20120,10 @@ function SitePreview({
|
|
|
20118
20120
|
onEdit,
|
|
20119
20121
|
tr
|
|
20120
20122
|
}) {
|
|
20121
|
-
const [nonce, setNonce] =
|
|
20122
|
-
const [loading, setLoading] =
|
|
20123
|
+
const [nonce, setNonce] = React128.useState(0);
|
|
20124
|
+
const [loading, setLoading] = React128.useState(true);
|
|
20123
20125
|
const url = previewSourceOf(project);
|
|
20124
|
-
|
|
20126
|
+
React128.useEffect(() => {
|
|
20125
20127
|
setLoading(true);
|
|
20126
20128
|
}, [nonce, url]);
|
|
20127
20129
|
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 +20233,10 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
20231
20233
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
20232
20234
|
const setPageSlot = useRightRailStore((s) => s.setPageSlot);
|
|
20233
20235
|
const setWidth = useRightRailStore((s) => s.setWidth);
|
|
20234
|
-
const rootRef =
|
|
20235
|
-
const [actionsSlot, setActionsSlot] =
|
|
20236
|
-
const [leadingSlot, setLeadingSlot] =
|
|
20237
|
-
|
|
20236
|
+
const rootRef = React128.useRef(null);
|
|
20237
|
+
const [actionsSlot, setActionsSlot] = React128.useState(null);
|
|
20238
|
+
const [leadingSlot, setLeadingSlot] = React128.useState(null);
|
|
20239
|
+
React128.useEffect(() => {
|
|
20238
20240
|
if (!open) return;
|
|
20239
20241
|
const el = rootRef.current;
|
|
20240
20242
|
if (!el) return;
|
|
@@ -20256,8 +20258,8 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
20256
20258
|
el.removeEventListener("transitionend", publish);
|
|
20257
20259
|
};
|
|
20258
20260
|
}, [open, setWidth]);
|
|
20259
|
-
const [narrow, setNarrow] =
|
|
20260
|
-
|
|
20261
|
+
const [narrow, setNarrow] = React128.useState(false);
|
|
20262
|
+
React128.useEffect(() => {
|
|
20261
20263
|
if (!open) return;
|
|
20262
20264
|
const el = rootRef.current;
|
|
20263
20265
|
if (!el) return;
|
|
@@ -20620,9 +20622,9 @@ var TYPE_COLORS = {
|
|
|
20620
20622
|
fix: "text-success"
|
|
20621
20623
|
};
|
|
20622
20624
|
function ChangelogFeed({ changelogUrl, className }) {
|
|
20623
|
-
const [entries2, setEntries] =
|
|
20624
|
-
const [loading, setLoading] =
|
|
20625
|
-
|
|
20625
|
+
const [entries2, setEntries] = React128.useState([]);
|
|
20626
|
+
const [loading, setLoading] = React128.useState(false);
|
|
20627
|
+
React128.useEffect(() => {
|
|
20626
20628
|
if (!changelogUrl) return;
|
|
20627
20629
|
setLoading(true);
|
|
20628
20630
|
fetch(changelogUrl).then((r) => r.json()).then((data) => setEntries(data)).catch(() => setEntries([])).finally(() => setLoading(false));
|
|
@@ -20682,7 +20684,7 @@ function NotificationInbox({
|
|
|
20682
20684
|
changelogUrl,
|
|
20683
20685
|
className
|
|
20684
20686
|
}) {
|
|
20685
|
-
const [activeTab, setActiveTab] =
|
|
20687
|
+
const [activeTab, setActiveTab] = React128.useState("inbox");
|
|
20686
20688
|
const unreadCount = notifications.filter((n) => !n.read).length;
|
|
20687
20689
|
const inboxNotifications = notifications.filter((n) => n.category !== "changelog");
|
|
20688
20690
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex w-80 flex-col", className), children: [
|
|
@@ -20779,11 +20781,11 @@ function NotificationInbox({
|
|
|
20779
20781
|
}
|
|
20780
20782
|
function BrandAgentSurface() {
|
|
20781
20783
|
const org = useOrganizationStore((s) => s.currentOrg);
|
|
20782
|
-
const brand =
|
|
20784
|
+
const brand = React128__default.useMemo(
|
|
20783
20785
|
() => normalizeBrand(org?.settings?.branding, { name: org?.name, logoUrl: org?.logoUrl }),
|
|
20784
20786
|
[org?.settings, org?.name, org?.logoUrl]
|
|
20785
20787
|
);
|
|
20786
|
-
const surface =
|
|
20788
|
+
const surface = React128__default.useMemo(() => ({
|
|
20787
20789
|
id: "core.brand",
|
|
20788
20790
|
describe: () => ({
|
|
20789
20791
|
title: "Marca da casa",
|
|
@@ -20796,15 +20798,15 @@ function BrandAgentSurface() {
|
|
|
20796
20798
|
return null;
|
|
20797
20799
|
}
|
|
20798
20800
|
function ConnectConsentPage({ appName, logo }) {
|
|
20799
|
-
const [state, setState] =
|
|
20800
|
-
const [tenantId2, setTenantId] =
|
|
20801
|
-
const request =
|
|
20801
|
+
const [state, setState] = React128__default.useState({ status: "loading" });
|
|
20802
|
+
const [tenantId2, setTenantId] = React128__default.useState("");
|
|
20803
|
+
const request = React128__default.useMemo(
|
|
20802
20804
|
() => new URLSearchParams(window.location.search).get("request") ?? "",
|
|
20803
20805
|
[]
|
|
20804
20806
|
);
|
|
20805
|
-
const connection =
|
|
20807
|
+
const connection = React128__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
20806
20808
|
const product = appName ?? document.title ?? "este app";
|
|
20807
|
-
const authorizedFetch =
|
|
20809
|
+
const authorizedFetch = React128__default.useCallback(
|
|
20808
20810
|
async (path, init) => {
|
|
20809
20811
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
20810
20812
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -20828,7 +20830,7 @@ function ConnectConsentPage({ appName, logo }) {
|
|
|
20828
20830
|
},
|
|
20829
20831
|
[connection]
|
|
20830
20832
|
);
|
|
20831
|
-
|
|
20833
|
+
React128__default.useEffect(() => {
|
|
20832
20834
|
let cancelled = false;
|
|
20833
20835
|
(async () => {
|
|
20834
20836
|
if (!request) {
|
|
@@ -21072,7 +21074,7 @@ function Row2({ label: label3, value }) {
|
|
|
21072
21074
|
function PageActions({ actions, className }) {
|
|
21073
21075
|
const access = useAccessOptional();
|
|
21074
21076
|
const openUpgrade = useUpgradeModalStore((s) => s.open);
|
|
21075
|
-
const resolved =
|
|
21077
|
+
const resolved = React128__default.useMemo(
|
|
21076
21078
|
() => actions.map((a) => {
|
|
21077
21079
|
const { permission, limitKey, onSelect, ...rest } = a;
|
|
21078
21080
|
let hidden = false;
|
|
@@ -21102,25 +21104,25 @@ function AddConnectorPanel({
|
|
|
21102
21104
|
onSelect
|
|
21103
21105
|
}) {
|
|
21104
21106
|
const { t } = useTranslation$1();
|
|
21105
|
-
const [query, setQuery] =
|
|
21107
|
+
const [query, setQuery] = React128__default.useState("");
|
|
21106
21108
|
const modules = useInstalledModuleIds();
|
|
21107
21109
|
const catalog = useConnectorCatalog();
|
|
21108
21110
|
const scoped = !!categories?.length;
|
|
21109
|
-
const addable =
|
|
21111
|
+
const addable = React128__default.useMemo(
|
|
21110
21112
|
() => inCategories(addableConnectors(connectors ?? []), categories),
|
|
21111
21113
|
[connectors, categories]
|
|
21112
21114
|
);
|
|
21113
|
-
const shelf =
|
|
21115
|
+
const shelf = React128__default.useMemo(() => {
|
|
21114
21116
|
if (connectors === null) return [];
|
|
21115
21117
|
return inCategories(
|
|
21116
21118
|
shelfIntegrations({ present: connectors, installedModules: modules, catalog: catalog ?? [] }),
|
|
21117
21119
|
categories
|
|
21118
21120
|
);
|
|
21119
21121
|
}, [connectors, modules, catalog, categories]);
|
|
21120
|
-
const filtered =
|
|
21121
|
-
const filteredShelf =
|
|
21122
|
-
const soon =
|
|
21123
|
-
const elsewhere =
|
|
21122
|
+
const filtered = React128__default.useMemo(() => filterConnectors(addable, "all", query), [addable, query]);
|
|
21123
|
+
const filteredShelf = React128__default.useMemo(() => filterAvailable(shelf, query), [shelf, query]);
|
|
21124
|
+
const soon = React128__default.useMemo(() => comingSoonHere(filteredShelf), [filteredShelf]);
|
|
21125
|
+
const elsewhere = React128__default.useMemo(() => withAnotherModule(filteredShelf), [filteredShelf]);
|
|
21124
21126
|
const searchable = addable.length + shelf.length > 6;
|
|
21125
21127
|
return /* @__PURE__ */ jsx(Modal, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ModalContent, { size: "2xl", children: [
|
|
21126
21128
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
@@ -21279,22 +21281,22 @@ function AddConnectorButton({ onClick }) {
|
|
|
21279
21281
|
function ConnectorsTab() {
|
|
21280
21282
|
const { t } = useTranslation$1();
|
|
21281
21283
|
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] =
|
|
21284
|
+
const [adding, setAdding] = React128__default.useState(false);
|
|
21285
|
+
const [selected, setSelected] = React128__default.useState(null);
|
|
21286
|
+
const [filter, setFilter] = React128__default.useState("all");
|
|
21287
|
+
const [failure, setFailure] = React128__default.useState(null);
|
|
21288
|
+
const [revoking, setRevoking] = React128__default.useState(null);
|
|
21287
21289
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
21288
|
-
const openJourney =
|
|
21290
|
+
const openJourney = React128__default.useCallback(
|
|
21289
21291
|
(connector) => {
|
|
21290
21292
|
if (assistantAvailable) openConnectorsPanel(connector);
|
|
21291
21293
|
else setSelected(connector);
|
|
21292
21294
|
},
|
|
21293
21295
|
[assistantAvailable]
|
|
21294
21296
|
);
|
|
21295
|
-
const visible =
|
|
21296
|
-
const groups =
|
|
21297
|
-
|
|
21297
|
+
const visible = React128__default.useMemo(() => filterConnectors(connectors ?? [], filter), [connectors, filter]);
|
|
21298
|
+
const groups = React128__default.useMemo(() => groupConnectors(visible), [visible]);
|
|
21299
|
+
React128__default.useEffect(() => {
|
|
21298
21300
|
if (!selected || !connectors) return;
|
|
21299
21301
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
21300
21302
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -21329,7 +21331,7 @@ function ConnectorsTab() {
|
|
|
21329
21331
|
(connectors?.length ?? 0) > 4 && /* @__PURE__ */ jsx(Filters, { value: filter, onChange: setFilter }),
|
|
21330
21332
|
connectors === null && /* @__PURE__ */ jsx(ConnectionsSkeleton, {}),
|
|
21331
21333
|
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(
|
|
21334
|
+
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(React128__default.Fragment, { children: [
|
|
21333
21335
|
groups.length > 1 && /* @__PURE__ */ jsx(
|
|
21334
21336
|
"li",
|
|
21335
21337
|
{
|
|
@@ -21467,7 +21469,7 @@ function oauthFailureMessage(t, result) {
|
|
|
21467
21469
|
function useConnectorOAuthReturn() {
|
|
21468
21470
|
const { t } = useTranslation$1();
|
|
21469
21471
|
const runtime = usePluginRuntimeOptional();
|
|
21470
|
-
|
|
21472
|
+
React128__default.useEffect(() => {
|
|
21471
21473
|
if (typeof window === "undefined") return;
|
|
21472
21474
|
const result = readConnectorOAuthReturn(window.location.search);
|
|
21473
21475
|
if (!result) return;
|
|
@@ -21502,8 +21504,8 @@ function ConnectorDeliveries({
|
|
|
21502
21504
|
limit = 10
|
|
21503
21505
|
}) {
|
|
21504
21506
|
const { t } = useTranslation$1();
|
|
21505
|
-
const [rows, setRows] =
|
|
21506
|
-
|
|
21507
|
+
const [rows, setRows] = React128__default.useState(null);
|
|
21508
|
+
React128__default.useEffect(() => {
|
|
21507
21509
|
let cancelled = false;
|
|
21508
21510
|
void load({ limit }).then((r) => {
|
|
21509
21511
|
if (!cancelled) setRows(r);
|
|
@@ -21577,11 +21579,11 @@ var CURRENCIES = [
|
|
|
21577
21579
|
function CompanySettings({ tenant, onSave }) {
|
|
21578
21580
|
const { t } = useTranslation$1();
|
|
21579
21581
|
const { locale: uiLocale, setLocale: setUiLocale } = useLocaleStore();
|
|
21580
|
-
const [name, setName] =
|
|
21581
|
-
const [timezone, setTimezone] =
|
|
21582
|
-
const [currency, setCurrency] =
|
|
21583
|
-
const [saving, setSaving] =
|
|
21584
|
-
|
|
21582
|
+
const [name, setName] = React128.useState(tenant?.name ?? "");
|
|
21583
|
+
const [timezone, setTimezone] = React128.useState(tenant?.settings?.timezone ?? "UTC");
|
|
21584
|
+
const [currency, setCurrency] = React128.useState(tenant?.settings?.currency ?? "USD");
|
|
21585
|
+
const [saving, setSaving] = React128.useState(false);
|
|
21586
|
+
React128.useEffect(() => {
|
|
21585
21587
|
if (tenant) {
|
|
21586
21588
|
setName(tenant.name);
|
|
21587
21589
|
setTimezone(tenant.settings?.timezone ?? "UTC");
|
|
@@ -21673,15 +21675,15 @@ function UnitModeCard() {
|
|
|
21673
21675
|
const units = useUnitStore((s) => s.units);
|
|
21674
21676
|
const setMode = useUnitStore((s) => s.setMode);
|
|
21675
21677
|
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 =
|
|
21678
|
+
const [unbound, setUnbound] = React128.useState(null);
|
|
21679
|
+
const [bindEveryone, setBindEveryone] = React128.useState(true);
|
|
21680
|
+
const [pending2, setPending] = React128.useState(null);
|
|
21681
|
+
const [saving, setSaving] = React128.useState(false);
|
|
21682
|
+
const headquarters = React128.useMemo(
|
|
21681
21683
|
() => units.find((u) => u.isHeadquarters && u.kind !== "region") ?? units.find((u) => u.kind !== "region"),
|
|
21682
21684
|
[units]
|
|
21683
21685
|
);
|
|
21684
|
-
|
|
21686
|
+
React128.useEffect(() => {
|
|
21685
21687
|
if (!org?.id || unitMode) return;
|
|
21686
21688
|
let alive = true;
|
|
21687
21689
|
void countUnboundMembers(org.id).then((n) => {
|
|
@@ -21845,10 +21847,10 @@ function getInitials(name) {
|
|
|
21845
21847
|
}
|
|
21846
21848
|
function UserProfile({ user, onSave, onAvatarChange }) {
|
|
21847
21849
|
const { t } = useTranslation$1();
|
|
21848
|
-
const [fullName, setFullName] =
|
|
21849
|
-
const [saving, setSaving] =
|
|
21850
|
-
const fileInputRef =
|
|
21851
|
-
|
|
21850
|
+
const [fullName, setFullName] = React128.useState(user?.fullName ?? "");
|
|
21851
|
+
const [saving, setSaving] = React128.useState(false);
|
|
21852
|
+
const fileInputRef = React128.useRef(null);
|
|
21853
|
+
React128.useEffect(() => {
|
|
21852
21854
|
if (user) {
|
|
21853
21855
|
setFullName(user.fullName);
|
|
21854
21856
|
}
|
|
@@ -21988,8 +21990,8 @@ async function fetchMyPersonId(tenantId2, userId) {
|
|
|
21988
21990
|
function useMyPersonId(enabled = true) {
|
|
21989
21991
|
const orgId = useOrganizationStore((s) => s.currentOrg?.id);
|
|
21990
21992
|
const userId = useAuthStore((s) => s.user?.id);
|
|
21991
|
-
const [personId, setPersonId] =
|
|
21992
|
-
|
|
21993
|
+
const [personId, setPersonId] = React128.useState(void 0);
|
|
21994
|
+
React128.useEffect(() => {
|
|
21993
21995
|
if (!enabled || !orgId || !userId) return;
|
|
21994
21996
|
let alive = true;
|
|
21995
21997
|
void dedup(`self:person:${orgId}:${userId}`, () => fetchMyPersonId(orgId, userId)).then((id) => {
|
|
@@ -22049,18 +22051,18 @@ function MyWorkspaceCard() {
|
|
|
22049
22051
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
22050
22052
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
22051
22053
|
const entryReason = useUnitStore((s) => s.entryReason);
|
|
22052
|
-
const [person, setPerson] =
|
|
22053
|
-
const [candidate, setCandidate] =
|
|
22054
|
-
const [linking, setLinking] =
|
|
22054
|
+
const [person, setPerson] = React128.useState(void 0);
|
|
22055
|
+
const [candidate, setCandidate] = React128.useState(null);
|
|
22056
|
+
const [linking, setLinking] = React128.useState(false);
|
|
22055
22057
|
const orgId = currentOrg?.id;
|
|
22056
22058
|
const userId = user?.id;
|
|
22057
|
-
const load =
|
|
22059
|
+
const load = React128.useCallback(async () => {
|
|
22058
22060
|
if (!orgId || !userId) return;
|
|
22059
22061
|
const linked = await fetchMyPersonRecord(orgId, userId);
|
|
22060
22062
|
setPerson(linked);
|
|
22061
22063
|
setCandidate(linked ? null : await findMyPersonCandidate(orgId, user?.email, staffKinds));
|
|
22062
22064
|
}, [orgId, userId, user?.email, staffKinds]);
|
|
22063
|
-
|
|
22065
|
+
React128.useEffect(() => {
|
|
22064
22066
|
void load();
|
|
22065
22067
|
}, [load]);
|
|
22066
22068
|
if (!currentOrg) return null;
|
|
@@ -22154,10 +22156,10 @@ var useStore = create((set) => ({
|
|
|
22154
22156
|
function useHeaderAction(zone, action) {
|
|
22155
22157
|
const register = useStore((s) => s.register);
|
|
22156
22158
|
const unregister = useStore((s) => s.unregister);
|
|
22157
|
-
const latest =
|
|
22159
|
+
const latest = React128.useRef(action);
|
|
22158
22160
|
latest.current = action;
|
|
22159
22161
|
const id = action?.id;
|
|
22160
|
-
|
|
22162
|
+
React128.useEffect(() => {
|
|
22161
22163
|
if (!zone || !id) return;
|
|
22162
22164
|
const current2 = latest.current;
|
|
22163
22165
|
if (current2) register(zone, { ...current2, onSelect: () => latest.current?.onSelect() });
|
|
@@ -22166,7 +22168,7 @@ function useHeaderAction(zone, action) {
|
|
|
22166
22168
|
}
|
|
22167
22169
|
function useHeaderActions(zone) {
|
|
22168
22170
|
const byZone = useStore((s) => s.byZone);
|
|
22169
|
-
return
|
|
22171
|
+
return React128.useMemo(() => Object.values(byZone[zone] ?? {}), [byZone, zone]);
|
|
22170
22172
|
}
|
|
22171
22173
|
function useUserLabel(userId) {
|
|
22172
22174
|
const members = useOrganizationStore((s) => s.members);
|
|
@@ -22799,6 +22801,10 @@ function PayeeAccountsSection({
|
|
|
22799
22801
|
const [form, setForm] = useState(EMPTY_FORM2);
|
|
22800
22802
|
const [saving, setSaving] = useState(false);
|
|
22801
22803
|
const [deleting, setDeleting] = useState(null);
|
|
22804
|
+
const can = usePermissionOptional();
|
|
22805
|
+
const canRead = can("financial", "read");
|
|
22806
|
+
const canEdit = can("financial", "edit");
|
|
22807
|
+
const canDelete = can("financial", "delete");
|
|
22802
22808
|
const db2 = () => getSupabaseClientOptional();
|
|
22803
22809
|
const load = useCallback(async () => {
|
|
22804
22810
|
const client3 = db2();
|
|
@@ -22872,6 +22878,7 @@ function PayeeAccountsSection({
|
|
|
22872
22878
|
await load();
|
|
22873
22879
|
toast.success(t("crud.archetype.payeeAccounts.deleted"));
|
|
22874
22880
|
};
|
|
22881
|
+
if (!canRead) return null;
|
|
22875
22882
|
if (loading) {
|
|
22876
22883
|
return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(CardContent, { className: "space-y-2 py-6", children: [
|
|
22877
22884
|
/* @__PURE__ */ jsx("div", { className: "h-4 w-56 animate-pulse rounded bg-muted/40" }),
|
|
@@ -22887,7 +22894,7 @@ function PayeeAccountsSection({
|
|
|
22887
22894
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
22888
22895
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
22889
22896
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold", children: t("crud.archetype.payeeAccounts.title") }),
|
|
22890
|
-
/* @__PURE__ */ jsxs(
|
|
22897
|
+
canEdit && /* @__PURE__ */ jsxs(
|
|
22891
22898
|
Button,
|
|
22892
22899
|
{
|
|
22893
22900
|
type: "button",
|
|
@@ -22928,7 +22935,7 @@ function PayeeAccountsSection({
|
|
|
22928
22935
|
(a.holder_name || a.holder_document) && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: [a.holder_name, a.holder_document].filter(Boolean).join(" \xB7 ") })
|
|
22929
22936
|
] }),
|
|
22930
22937
|
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 gap-1", children: [
|
|
22931
|
-
/* @__PURE__ */ jsx(
|
|
22938
|
+
canEdit && /* @__PURE__ */ jsx(
|
|
22932
22939
|
Button,
|
|
22933
22940
|
{
|
|
22934
22941
|
type: "button",
|
|
@@ -22943,7 +22950,7 @@ function PayeeAccountsSection({
|
|
|
22943
22950
|
children: /* @__PURE__ */ jsx(Pencil, { className: "h-3.5 w-3.5" })
|
|
22944
22951
|
}
|
|
22945
22952
|
),
|
|
22946
|
-
/* @__PURE__ */ jsx(
|
|
22953
|
+
canDelete && /* @__PURE__ */ jsx(
|
|
22947
22954
|
Button,
|
|
22948
22955
|
{
|
|
22949
22956
|
type: "button",
|
|
@@ -23168,12 +23175,12 @@ function CrudRecordModal({
|
|
|
23168
23175
|
essentialFirst,
|
|
23169
23176
|
notice
|
|
23170
23177
|
}) {
|
|
23171
|
-
const [record, setRecord] =
|
|
23172
|
-
const [loading, setLoading] =
|
|
23173
|
-
const [saving, setSaving] =
|
|
23174
|
-
const [error, setError] =
|
|
23175
|
-
const formId =
|
|
23176
|
-
|
|
23178
|
+
const [record, setRecord] = React128.useState(null);
|
|
23179
|
+
const [loading, setLoading] = React128.useState(false);
|
|
23180
|
+
const [saving, setSaving] = React128.useState(false);
|
|
23181
|
+
const [error, setError] = React128.useState(null);
|
|
23182
|
+
const formId = React128.useId();
|
|
23183
|
+
React128.useEffect(() => {
|
|
23177
23184
|
if (!open) return;
|
|
23178
23185
|
setError(null);
|
|
23179
23186
|
if (mode === "create" || !load) {
|
|
@@ -23351,10 +23358,10 @@ function resolveRelation(relation, row) {
|
|
|
23351
23358
|
}
|
|
23352
23359
|
return { ...relation, filter: { ...relation.filter ?? {}, ...extra } };
|
|
23353
23360
|
}
|
|
23354
|
-
var PendingChildrenContext =
|
|
23361
|
+
var PendingChildrenContext = React128.createContext(null);
|
|
23355
23362
|
function usePendingChildren() {
|
|
23356
|
-
const pending2 =
|
|
23357
|
-
const provider2 =
|
|
23363
|
+
const pending2 = React128.useRef(/* @__PURE__ */ new Set());
|
|
23364
|
+
const provider2 = React128.useMemo(() => ({
|
|
23358
23365
|
register: (f) => {
|
|
23359
23366
|
pending2.current.add(f);
|
|
23360
23367
|
return () => {
|
|
@@ -23362,7 +23369,7 @@ function usePendingChildren() {
|
|
|
23362
23369
|
};
|
|
23363
23370
|
}
|
|
23364
23371
|
}), []);
|
|
23365
|
-
const flush =
|
|
23372
|
+
const flush = React128.useCallback(async (parentId) => {
|
|
23366
23373
|
for (const f of [...pending2.current]) await f(parentId);
|
|
23367
23374
|
}, []);
|
|
23368
23375
|
return { provider: provider2, flush };
|
|
@@ -23378,7 +23385,7 @@ function money(value) {
|
|
|
23378
23385
|
}
|
|
23379
23386
|
}
|
|
23380
23387
|
function GridRelationCell({ field, value, row, onChange }) {
|
|
23381
|
-
const relation =
|
|
23388
|
+
const relation = React128.useMemo(() => resolveRelation(field.relation, row), [field.relation, row]);
|
|
23382
23389
|
const { labelFor: labelFor2 } = useRelationOptions(relation);
|
|
23383
23390
|
const label3 = value ? labelFor2(value) : "";
|
|
23384
23391
|
return /* @__PURE__ */ jsx(
|
|
@@ -23409,11 +23416,11 @@ function columnOf(entity, key) {
|
|
|
23409
23416
|
}
|
|
23410
23417
|
function RelatedSection({ parentId, related, compact }) {
|
|
23411
23418
|
const orfa = !parentId;
|
|
23412
|
-
const pendentes =
|
|
23419
|
+
const pendentes = React128.useContext(PendingChildrenContext);
|
|
23413
23420
|
const fkColumn = columnOf(related.entity, related.foreignKey);
|
|
23414
23421
|
const label3 = related.label ?? related.entity.namePlural ?? related.entity.name;
|
|
23415
23422
|
const Icon = related.icon ? ICON_MAP[related.icon] ?? null : null;
|
|
23416
|
-
const child =
|
|
23423
|
+
const child = React128.useMemo(() => ({
|
|
23417
23424
|
...related.entity,
|
|
23418
23425
|
fields: related.entity.fields.filter((f) => f.key !== related.foreignKey),
|
|
23419
23426
|
data: related.entity.data ? {
|
|
@@ -23422,13 +23429,13 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23422
23429
|
defaults: { ...related.entity.data.defaults ?? {}, [fkColumn]: parentId }
|
|
23423
23430
|
} : void 0
|
|
23424
23431
|
}), [related, parentId, fkColumn]);
|
|
23425
|
-
const provider2 =
|
|
23426
|
-
const [rows, setRows] =
|
|
23427
|
-
const [loading, setLoading] =
|
|
23428
|
-
const [error, setError] =
|
|
23429
|
-
const [adding, setAdding] =
|
|
23430
|
-
const [draft, setDraft] =
|
|
23431
|
-
const load =
|
|
23432
|
+
const provider2 = React128.useMemo(() => resolveDataProvider(child, [], { cache: false }), [child]);
|
|
23433
|
+
const [rows, setRows] = React128.useState([]);
|
|
23434
|
+
const [loading, setLoading] = React128.useState(true);
|
|
23435
|
+
const [error, setError] = React128.useState(null);
|
|
23436
|
+
const [adding, setAdding] = React128.useState(false);
|
|
23437
|
+
const [draft, setDraft] = React128.useState(null);
|
|
23438
|
+
const load = React128.useCallback(async () => {
|
|
23432
23439
|
if (orfa) {
|
|
23433
23440
|
setLoading(false);
|
|
23434
23441
|
return;
|
|
@@ -23444,12 +23451,12 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23444
23451
|
setLoading(false);
|
|
23445
23452
|
}
|
|
23446
23453
|
}, [provider2, orfa]);
|
|
23447
|
-
|
|
23454
|
+
React128.useEffect(() => {
|
|
23448
23455
|
void load();
|
|
23449
23456
|
}, [load]);
|
|
23450
|
-
const guardadas =
|
|
23457
|
+
const guardadas = React128.useRef([]);
|
|
23451
23458
|
guardadas.current = rows;
|
|
23452
|
-
|
|
23459
|
+
React128.useEffect(() => {
|
|
23453
23460
|
if (!orfa || !pendentes) return;
|
|
23454
23461
|
return pendentes.register(async (novoPai) => {
|
|
23455
23462
|
if (!guardadas.current.length) return;
|
|
@@ -23473,7 +23480,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23473
23480
|
}
|
|
23474
23481
|
const shown = child.fields.filter((f) => f.showInTable !== false);
|
|
23475
23482
|
const groupKey = related.duplicable ? child.fields.find((f) => f.type === "relation")?.key : void 0;
|
|
23476
|
-
const [lastEdit, setLastEdit] =
|
|
23483
|
+
const [lastEdit, setLastEdit] = React128.useState(null);
|
|
23477
23484
|
function siblingsToSync(row, key) {
|
|
23478
23485
|
if (!groupKey || key === groupKey || row[groupKey] == null) return [];
|
|
23479
23486
|
return rows.filter((r) => r.id !== row.id && r[groupKey] === row[groupKey] && r[key] !== row[key]);
|
|
@@ -23504,7 +23511,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23504
23511
|
if (orfa) return;
|
|
23505
23512
|
queueWrite(id, mudanca, antes);
|
|
23506
23513
|
}
|
|
23507
|
-
const escritas =
|
|
23514
|
+
const escritas = React128.useRef(/* @__PURE__ */ new Map());
|
|
23508
23515
|
function queueWrite(id, mudanca, antes) {
|
|
23509
23516
|
const atual = escritas.current.get(id);
|
|
23510
23517
|
const entry = atual ?? { mudanca: {}, antes, fila: Promise.resolve() };
|
|
@@ -23533,7 +23540,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23533
23540
|
if (e && e.fila === fila && !e.timer) escritas.current.delete(id);
|
|
23534
23541
|
});
|
|
23535
23542
|
}
|
|
23536
|
-
|
|
23543
|
+
React128.useEffect(() => () => {
|
|
23537
23544
|
for (const [id, e] of escritas.current) {
|
|
23538
23545
|
if (e.timer) {
|
|
23539
23546
|
clearTimeout(e.timer);
|
|
@@ -23542,7 +23549,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23542
23549
|
}
|
|
23543
23550
|
}, []);
|
|
23544
23551
|
const required = child.fields.filter((f) => f.required);
|
|
23545
|
-
const criando =
|
|
23552
|
+
const criando = React128.useRef(false);
|
|
23546
23553
|
async function commitDraft(key, next, price) {
|
|
23547
23554
|
const completo = { ...next, ...heranca(key, price, next) };
|
|
23548
23555
|
setDraft(completo);
|
|
@@ -24375,7 +24382,7 @@ function SubjectFormLayout({ fields, allFields, fieldGroups, values, onChange, r
|
|
|
24375
24382
|
const IconComponent = getLucideIcon(entityIcon ?? "Heart") ?? Heart;
|
|
24376
24383
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
24377
24384
|
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: "pt-5", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-5", children: [
|
|
24378
|
-
/* @__PURE__ */ jsx("div", { className: "flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary", children:
|
|
24385
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: React128__default.createElement(IconComponent, { className: "h-8 w-8" }) }),
|
|
24379
24386
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-4", children: [
|
|
24380
24387
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-4", children: [
|
|
24381
24388
|
nameField && /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-1.5", children: [
|
|
@@ -24519,6 +24526,8 @@ function BankField({
|
|
|
24519
24526
|
const t = useTranslation();
|
|
24520
24527
|
const v = value ?? {};
|
|
24521
24528
|
const withMethod = { ...v, method: v.method ?? payeeMethodOf(v) };
|
|
24529
|
+
const canEdit = usePermissionOptional()("financial", "edit");
|
|
24530
|
+
if (!canEdit) return null;
|
|
24522
24531
|
return /* @__PURE__ */ jsxs(
|
|
24523
24532
|
AttachedFieldSection,
|
|
24524
24533
|
{
|
|
@@ -24775,6 +24784,15 @@ function fieldToColumns(fields, options) {
|
|
|
24775
24784
|
return { key: field.key, label: field.label, sortable, render };
|
|
24776
24785
|
});
|
|
24777
24786
|
}
|
|
24787
|
+
function renderDisplayCell(entityDef, value, rendered, row) {
|
|
24788
|
+
const name = /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: rendered });
|
|
24789
|
+
if (entityDef.layout !== "person" || !(entityDef.imageField || entityDef.image)) return name;
|
|
24790
|
+
const src = entityDef.image?.get(row) ?? (entityDef.imageField ? row[entityDef.imageField] : null);
|
|
24791
|
+
return /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2.5", children: [
|
|
24792
|
+
/* @__PURE__ */ jsx(PersonAvatar, { name: typeof value === "string" ? value : "", src, size: "md" }),
|
|
24793
|
+
name
|
|
24794
|
+
] });
|
|
24795
|
+
}
|
|
24778
24796
|
function toLocalDateTimeInput(value) {
|
|
24779
24797
|
if (!value) return "";
|
|
24780
24798
|
const raw = String(value);
|
|
@@ -24846,7 +24864,7 @@ function getDefaultValues(fields) {
|
|
|
24846
24864
|
}
|
|
24847
24865
|
return values;
|
|
24848
24866
|
}
|
|
24849
|
-
var SetFieldValueContext =
|
|
24867
|
+
var SetFieldValueContext = React128__default.createContext(void 0);
|
|
24850
24868
|
function renderField(field, value, onChange, allValues = {}, selectPlaceholder, setValue) {
|
|
24851
24869
|
const baseClass = "flex h-9 w-full rounded-input border border-input bg-background px-3 py-1.5 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50";
|
|
24852
24870
|
switch (field.type) {
|
|
@@ -25093,14 +25111,14 @@ function ImageSlot({
|
|
|
25093
25111
|
onDraftFile
|
|
25094
25112
|
}) {
|
|
25095
25113
|
const t = useTranslation();
|
|
25096
|
-
const inputRef =
|
|
25097
|
-
const [url, setUrl] =
|
|
25098
|
-
const [busy, setBusy] =
|
|
25099
|
-
const [error, setError] =
|
|
25100
|
-
const draftUrlRef =
|
|
25114
|
+
const inputRef = React128__default.useRef(null);
|
|
25115
|
+
const [url, setUrl] = React128__default.useState(() => image.get(row));
|
|
25116
|
+
const [busy, setBusy] = React128__default.useState(false);
|
|
25117
|
+
const [error, setError] = React128__default.useState(null);
|
|
25118
|
+
const draftUrlRef = React128__default.useRef(null);
|
|
25101
25119
|
const currentUrl = image.get(row);
|
|
25102
25120
|
const draftFile = image.draftField ? row[image.draftField] : void 0;
|
|
25103
|
-
|
|
25121
|
+
React128__default.useEffect(() => {
|
|
25104
25122
|
if (draftFile) return;
|
|
25105
25123
|
if (draftUrlRef.current) {
|
|
25106
25124
|
URL.revokeObjectURL(draftUrlRef.current);
|
|
@@ -25108,7 +25126,7 @@ function ImageSlot({
|
|
|
25108
25126
|
}
|
|
25109
25127
|
setUrl(currentUrl);
|
|
25110
25128
|
}, [currentUrl, draftFile]);
|
|
25111
|
-
|
|
25129
|
+
React128__default.useEffect(() => () => {
|
|
25112
25130
|
if (draftUrlRef.current) URL.revokeObjectURL(draftUrlRef.current);
|
|
25113
25131
|
}, []);
|
|
25114
25132
|
const acceptsDraft = !canEdit && Boolean(image.draftField && onDraftFile);
|
|
@@ -25258,7 +25276,7 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25258
25276
|
const [values, setValues] = useState(computeInit);
|
|
25259
25277
|
const [saving, setSaving] = useState(false);
|
|
25260
25278
|
const [invalidKeys, setInvalidKeys] = useState(EMPTY_KEYS);
|
|
25261
|
-
const initialRef =
|
|
25279
|
+
const initialRef = React128__default.useRef(JSON.stringify(values));
|
|
25262
25280
|
useEffect(() => {
|
|
25263
25281
|
const init = computeInit();
|
|
25264
25282
|
setValues(init);
|
|
@@ -25318,7 +25336,7 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25318
25336
|
if (submitRef) submitRef.current = () => {
|
|
25319
25337
|
void submit();
|
|
25320
25338
|
};
|
|
25321
|
-
|
|
25339
|
+
React128__default.useEffect(() => () => {
|
|
25322
25340
|
if (submitRef) submitRef.current = null;
|
|
25323
25341
|
}, [submitRef]);
|
|
25324
25342
|
const dirty = JSON.stringify(values) !== initialRef.current;
|
|
@@ -25885,16 +25903,18 @@ function useUnitFilter(options = {}) {
|
|
|
25885
25903
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
25886
25904
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
25887
25905
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
25888
|
-
const
|
|
25889
|
-
const
|
|
25890
|
-
|
|
25906
|
+
const can = usePermissionOptional();
|
|
25907
|
+
const canManageUnits = can("units", "manage");
|
|
25908
|
+
const reachable = React128.useMemo(() => unitFilterOptions(units, myUnitIds), [units, myUnitIds]);
|
|
25909
|
+
const [local2, setLocal] = React128.useState(activeUnitId);
|
|
25910
|
+
React128.useEffect(() => {
|
|
25891
25911
|
setLocal(activeUnitId);
|
|
25892
25912
|
}, [activeUnitId]);
|
|
25893
25913
|
const raw = scope === "global" ? activeUnitId : local2;
|
|
25894
25914
|
const value = standableUnit(raw, reachable);
|
|
25895
25915
|
const filterLabel = label(t, "units.filterLabel", "Unidade");
|
|
25896
25916
|
const allLabel = label(t, "units.filterAll", "Todas as minhas unidades");
|
|
25897
|
-
const setValue =
|
|
25917
|
+
const setValue = React128.useCallback((next) => {
|
|
25898
25918
|
if (scope === "global") {
|
|
25899
25919
|
if (next === activeUnitId) return;
|
|
25900
25920
|
beginSwitch({ unitId: next, unitName: next ? byId[next]?.name ?? "" : allLabel });
|
|
@@ -25903,7 +25923,7 @@ function useUnitFilter(options = {}) {
|
|
|
25903
25923
|
setLocal(next);
|
|
25904
25924
|
}, [scope, activeUnitId, beginSwitch, byId, allLabel]);
|
|
25905
25925
|
const visible = unitFilterVisible(unitMode, reachable);
|
|
25906
|
-
const def =
|
|
25926
|
+
const def = React128.useMemo(() => visible ? {
|
|
25907
25927
|
id: "unit",
|
|
25908
25928
|
label: filterLabel,
|
|
25909
25929
|
icon: Building2,
|
|
@@ -25911,8 +25931,13 @@ function useUnitFilter(options = {}) {
|
|
|
25911
25931
|
options: reachable.map((u) => ({ value: u.id, label: u.name })),
|
|
25912
25932
|
value,
|
|
25913
25933
|
onChange: setValue,
|
|
25914
|
-
|
|
25915
|
-
|
|
25934
|
+
// Unit names are typed, not scrolled for — search even for a short list.
|
|
25935
|
+
searchable: true,
|
|
25936
|
+
searchPlaceholder: label(t, "units.search", "Buscar unidade"),
|
|
25937
|
+
manage: canManageUnits ? { label: label(t, "units.manage", "Gerenciar unidades"), onSelect: () => {
|
|
25938
|
+
window.location.hash = "#/settings/locations";
|
|
25939
|
+
} } : void 0
|
|
25940
|
+
} : null, [visible, filterLabel, allLabel, reachable, value, setValue, canManageUnits, t]);
|
|
25916
25941
|
return { visible, value: visible ? value : unitMode ? activeUnitId : void 0, setValue, options: reachable, label: filterLabel, allLabel, def };
|
|
25917
25942
|
}
|
|
25918
25943
|
var ALL_TAB = "__all__";
|
|
@@ -25962,7 +25987,8 @@ function CrudListView({
|
|
|
25962
25987
|
onSortDir,
|
|
25963
25988
|
sortBy,
|
|
25964
25989
|
sortDir,
|
|
25965
|
-
error
|
|
25990
|
+
error,
|
|
25991
|
+
groupBy
|
|
25966
25992
|
}) {
|
|
25967
25993
|
const t = useTranslation();
|
|
25968
25994
|
const pluralKey = entityDef.namePluralKey ?? entityDef.nameKey;
|
|
@@ -25981,10 +26007,10 @@ function CrudListView({
|
|
|
25981
26007
|
cell: ({ row }) => {
|
|
25982
26008
|
const value = row.original[col.key];
|
|
25983
26009
|
const rendered = col.render(value, row.original);
|
|
25984
|
-
return col.key === displayField ?
|
|
26010
|
+
return col.key === displayField ? renderDisplayCell(entityDef, value, rendered, row.original) : rendered;
|
|
25985
26011
|
}
|
|
25986
26012
|
}));
|
|
25987
|
-
}, [entityDef
|
|
26013
|
+
}, [entityDef, displayField]);
|
|
25988
26014
|
const tanColumns = columns ?? derivedColumns;
|
|
25989
26015
|
const isInitialLoad = items === null;
|
|
25990
26016
|
const isEmpty = items !== null && items.length === 0;
|
|
@@ -26039,7 +26065,7 @@ function CrudListView({
|
|
|
26039
26065
|
if (onImport) {
|
|
26040
26066
|
createRoutes.push({ id: "import", label: t("crud.import.action"), description: t("crud.import.hint"), icon: "Upload", action: onImport });
|
|
26041
26067
|
}
|
|
26042
|
-
const createActions =
|
|
26068
|
+
const createActions = React128__default.useMemo(() => {
|
|
26043
26069
|
const out = createRoutes.map((qa, i) => ({
|
|
26044
26070
|
id: qa.id,
|
|
26045
26071
|
label: qa.label,
|
|
@@ -26290,7 +26316,8 @@ function CrudListView({
|
|
|
26290
26316
|
/* Search, table tools and the table are ONE surface. They act on the
|
|
26291
26317
|
same rows, so a search box floating on the page background above a
|
|
26292
26318
|
separate table card read as two unrelated controls. */
|
|
26293
|
-
|
|
26319
|
+
// `clip`, not `hidden`: a scroll container here would hold the table's sticky header.
|
|
26320
|
+
/* @__PURE__ */ jsxs(Card, { style: { overflow: "clip" }, children: [
|
|
26294
26321
|
(searchBox || facetChips || tableTools || hasSelection) && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2 border-b border-border px-3 py-2", children: hasSelection ? /* @__PURE__ */ jsx(
|
|
26295
26322
|
BulkActionBar,
|
|
26296
26323
|
{
|
|
@@ -26319,7 +26346,8 @@ function CrudListView({
|
|
|
26319
26346
|
loading: isInitialLoad,
|
|
26320
26347
|
skeletonRows: isInitialLoad ? 3 : void 0,
|
|
26321
26348
|
emptyMessage: emptyState,
|
|
26322
|
-
onRowClick: (row) => onRowClick?.(row)
|
|
26349
|
+
onRowClick: (row) => onRowClick?.(row),
|
|
26350
|
+
groupBy
|
|
26323
26351
|
}
|
|
26324
26352
|
),
|
|
26325
26353
|
tableFooter
|
|
@@ -26450,9 +26478,9 @@ function buildCrudSurfaceContribution(read3) {
|
|
|
26450
26478
|
};
|
|
26451
26479
|
}
|
|
26452
26480
|
function CrudAgentSurface(props) {
|
|
26453
|
-
const ref =
|
|
26481
|
+
const ref = React128.useRef(props);
|
|
26454
26482
|
ref.current = props;
|
|
26455
|
-
const contribution =
|
|
26483
|
+
const contribution = React128.useMemo(
|
|
26456
26484
|
() => buildCrudSurfaceContribution(() => ref.current),
|
|
26457
26485
|
[]
|
|
26458
26486
|
);
|
|
@@ -26505,7 +26533,7 @@ function useFieldRules(entityKey) {
|
|
|
26505
26533
|
};
|
|
26506
26534
|
}, [entityKey, fieldRules]);
|
|
26507
26535
|
}
|
|
26508
|
-
var ImportWizard2 =
|
|
26536
|
+
var ImportWizard2 = React128__default.lazy(
|
|
26509
26537
|
() => import('./ImportWizard-7UFB2PPF.js').then((m) => ({ default: m.ImportWizard }))
|
|
26510
26538
|
);
|
|
26511
26539
|
var PAGE_SIZE = 50;
|
|
@@ -26570,7 +26598,7 @@ function useCrudColumns(entityDef, options) {
|
|
|
26570
26598
|
cell: ({ row }) => {
|
|
26571
26599
|
const value = row.original[col.key];
|
|
26572
26600
|
const rendered = col.render(value, row.original);
|
|
26573
|
-
return col.key === displayField ?
|
|
26601
|
+
return col.key === displayField ? renderDisplayCell(entityDef, value, rendered, row.original) : rendered;
|
|
26574
26602
|
}
|
|
26575
26603
|
}));
|
|
26576
26604
|
if (!options?.readOnly && options?.basePath) {
|
|
@@ -26616,7 +26644,7 @@ function useCrudColumns(entityDef, options) {
|
|
|
26616
26644
|
});
|
|
26617
26645
|
}
|
|
26618
26646
|
return tanCols;
|
|
26619
|
-
}, [cols, displayField, options?.basePath, options?.onDelete, options?.onDuplicate, options?.feature, options?.readOnly, t, can]);
|
|
26647
|
+
}, [cols, entityDef, displayField, options?.basePath, options?.onDelete, options?.onDuplicate, options?.feature, options?.readOnly, t, can]);
|
|
26620
26648
|
}
|
|
26621
26649
|
function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, display, feature, readOnly, navTabs, activeNavTab, stats, embedded, emptyHint, aiCreate }) {
|
|
26622
26650
|
const store = useStore2();
|
|
@@ -27077,7 +27105,7 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
27077
27105
|
mode: softDelete ? "deactivate" : "delete"
|
|
27078
27106
|
}
|
|
27079
27107
|
),
|
|
27080
|
-
/* @__PURE__ */ jsx(
|
|
27108
|
+
/* @__PURE__ */ jsx(React128__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
27081
27109
|
ImportWizard2,
|
|
27082
27110
|
{
|
|
27083
27111
|
open: importOpen,
|
|
@@ -27418,7 +27446,7 @@ function columnOf2(entity, key) {
|
|
|
27418
27446
|
function RelatedListTab({ item, related, parentTabId }) {
|
|
27419
27447
|
const parentId = item?.id;
|
|
27420
27448
|
const pathname = useHashPath();
|
|
27421
|
-
const Page =
|
|
27449
|
+
const Page = React128.useMemo(() => {
|
|
27422
27450
|
if (!parentId) return null;
|
|
27423
27451
|
const child = related.entity;
|
|
27424
27452
|
const fkColumn = columnOf2(child, related.foreignKey);
|
|
@@ -27458,8 +27486,8 @@ function nestedBasePath(pathname, parentTabId, childId) {
|
|
|
27458
27486
|
}
|
|
27459
27487
|
function useHashPath() {
|
|
27460
27488
|
const read3 = () => typeof window === "undefined" ? "/" : window.location.hash.slice(1) || "/";
|
|
27461
|
-
const [path, setPath] =
|
|
27462
|
-
|
|
27489
|
+
const [path, setPath] = React128.useState(read3);
|
|
27490
|
+
React128.useEffect(() => {
|
|
27463
27491
|
const handler = () => setPath(read3());
|
|
27464
27492
|
window.addEventListener("hashchange", handler);
|
|
27465
27493
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -27527,6 +27555,54 @@ var useInviteStore = create((set) => ({
|
|
|
27527
27555
|
setLoading: (loading) => set({ loading }),
|
|
27528
27556
|
reset: () => set({ invites: [], loading: false })
|
|
27529
27557
|
}));
|
|
27558
|
+
var ACTIONS2 = ["read", "create", "edit", "delete"];
|
|
27559
|
+
var SYSTEM_PERMISSIONS = [
|
|
27560
|
+
{ id: "manage_team", key: "organization.permissions.manageTeam" },
|
|
27561
|
+
{ id: "manage_billing", key: "organization.permissions.manageBilling" },
|
|
27562
|
+
{ id: "manage_settings", key: "organization.permissions.manageSettings" },
|
|
27563
|
+
{ id: "manage_permissions", key: "organization.permissions.managePermissions" }
|
|
27564
|
+
];
|
|
27565
|
+
function RoleSummary({ roleId }) {
|
|
27566
|
+
const t = useTranslation();
|
|
27567
|
+
const profile = usePermissionsStore((s) => s.profiles.find((p) => p.id === roleId));
|
|
27568
|
+
const features = usePermissionsStore((s) => s.features);
|
|
27569
|
+
const canEditRoles = useSystemPermission()("manage_permissions");
|
|
27570
|
+
const groups = React128.useMemo(() => {
|
|
27571
|
+
const map = /* @__PURE__ */ new Map();
|
|
27572
|
+
for (const feature of features) {
|
|
27573
|
+
const group = feature.group ?? t("crud.archetype.access.generalGroup");
|
|
27574
|
+
if (!map.has(group)) map.set(group, { granted: [], denied: [] });
|
|
27575
|
+
const held = profile?.grants[feature.id] ?? [];
|
|
27576
|
+
const actions = ACTIONS2.filter((a) => held.includes(a) || held.includes("manage"));
|
|
27577
|
+
if (actions.length) map.get(group).granted.push({ feature, actions });
|
|
27578
|
+
else map.get(group).denied.push(feature);
|
|
27579
|
+
}
|
|
27580
|
+
return [...map.entries()];
|
|
27581
|
+
}, [features, profile, t]);
|
|
27582
|
+
if (!profile) return null;
|
|
27583
|
+
const system = SYSTEM_PERMISSIONS.filter((sp) => profile.systemPermissions?.includes(sp.id));
|
|
27584
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4 border-t border-border pt-4", children: [
|
|
27585
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
27586
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
27587
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: t("crud.archetype.access.summaryTitle", { role: profile.name }) }),
|
|
27588
|
+
profile.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: profile.description })
|
|
27589
|
+
] }),
|
|
27590
|
+
canEditRoles && /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => navigateTo("/settings/permissions"), children: [
|
|
27591
|
+
/* @__PURE__ */ jsx(Settings2, { className: "mr-1.5 h-4 w-4" }),
|
|
27592
|
+
t("crud.archetype.access.editRole")
|
|
27593
|
+
] })
|
|
27594
|
+
] }),
|
|
27595
|
+
system.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: system.map((sp) => /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: t(sp.key) }, sp.id)) }),
|
|
27596
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y divide-border rounded-lg border border-border", children: groups.map(([group, { granted, denied }]) => /* @__PURE__ */ jsxs("div", { className: "space-y-2 p-3", children: [
|
|
27597
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: group }),
|
|
27598
|
+
granted.map(({ feature, actions }) => /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
27599
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: feature.label }),
|
|
27600
|
+
/* @__PURE__ */ jsx("span", { className: "flex flex-wrap gap-1", children: actions.map((a) => /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-[11px]", children: t(`crud.archetype.access.action.${a}`) }, a)) })
|
|
27601
|
+
] }, feature.id)),
|
|
27602
|
+
denied.length > 0 && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("crud.archetype.access.noAccessTo", { list: denied.map((f) => f.label).join(", ") }) })
|
|
27603
|
+
] }, group)) })
|
|
27604
|
+
] });
|
|
27605
|
+
}
|
|
27530
27606
|
var useOrgAdapterOptional2 = () => useOrgAdapterOptional();
|
|
27531
27607
|
function isEmail(value) {
|
|
27532
27608
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value.trim());
|
|
@@ -27544,30 +27620,33 @@ function AccessTab({ item }) {
|
|
|
27544
27620
|
const hasSystemPermission = useSystemPermission();
|
|
27545
27621
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
27546
27622
|
const guardSeats = useLimitGuard("users");
|
|
27547
|
-
const [access, setAccess] =
|
|
27548
|
-
const [email, setEmail] =
|
|
27549
|
-
const [roleId, setRoleId] =
|
|
27550
|
-
const [busy, setBusy] =
|
|
27551
|
-
const [confirmRemove, setConfirmRemove] =
|
|
27552
|
-
|
|
27553
|
-
|
|
27554
|
-
|
|
27555
|
-
|
|
27623
|
+
const [access, setAccess] = React128.useState(void 0);
|
|
27624
|
+
const [email, setEmail] = React128.useState(person?.email ?? "");
|
|
27625
|
+
const [roleId, setRoleId] = React128.useState("");
|
|
27626
|
+
const [busy, setBusy] = React128.useState(false);
|
|
27627
|
+
const [confirmRemove, setConfirmRemove] = React128.useState(false);
|
|
27628
|
+
const suggestedRoleId = person?.metadata?.access?.suggested_role_id;
|
|
27629
|
+
React128.useEffect(() => {
|
|
27630
|
+
if (roleId || !profiles.length) return;
|
|
27631
|
+
const sugerido = suggestedRoleId ? profiles.find((p) => p.id === suggestedRoleId) : void 0;
|
|
27632
|
+
setRoleId(sugerido ? sugerido.id : profiles[1]?.id ?? profiles[0].id);
|
|
27633
|
+
}, [profiles, roleId, suggestedRoleId]);
|
|
27634
|
+
React128.useEffect(() => {
|
|
27556
27635
|
setEmail(person?.email ?? "");
|
|
27557
27636
|
}, [person?.email]);
|
|
27558
|
-
const reload =
|
|
27637
|
+
const reload = React128.useCallback(async () => {
|
|
27559
27638
|
if (!personId) return;
|
|
27560
27639
|
setAccess(await fetchPersonAccess(personId));
|
|
27561
27640
|
}, [personId]);
|
|
27562
|
-
|
|
27641
|
+
React128.useEffect(() => {
|
|
27563
27642
|
void reload();
|
|
27564
27643
|
}, [reload]);
|
|
27565
|
-
|
|
27644
|
+
React128.useEffect(() => {
|
|
27566
27645
|
if (!adapter || !currentOrg || invites.length > 0) return;
|
|
27567
27646
|
adapter.listInvites(currentOrg.id).then(setInvites).catch(() => {
|
|
27568
27647
|
});
|
|
27569
27648
|
}, [adapter, currentOrg?.id]);
|
|
27570
|
-
const pendingInvite =
|
|
27649
|
+
const pendingInvite = React128.useMemo(() => {
|
|
27571
27650
|
const target = (person?.email ?? "").trim().toLowerCase();
|
|
27572
27651
|
if (!target) return void 0;
|
|
27573
27652
|
return invites.find((i) => i.status === "pending" && i.email.toLowerCase() === target);
|
|
@@ -27655,6 +27734,7 @@ function AccessTab({ item }) {
|
|
|
27655
27734
|
] }) : /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs", children: roleName }) }),
|
|
27656
27735
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("crud.archetype.access.roleHint") })
|
|
27657
27736
|
] }),
|
|
27737
|
+
/* @__PURE__ */ jsx(RoleSummary, { roleId: access.role }),
|
|
27658
27738
|
canManageTeam && !isSelf && /* @__PURE__ */ jsx("div", { className: "border-t border-border pt-4", children: /* @__PURE__ */ jsxs(
|
|
27659
27739
|
Button,
|
|
27660
27740
|
{
|
|
@@ -27781,11 +27861,11 @@ function PersonUnitsTab({ item }) {
|
|
|
27781
27861
|
const units = useUnitStore((s) => s.units);
|
|
27782
27862
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
27783
27863
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
27784
|
-
const [userId, setUserId] =
|
|
27785
|
-
const [bindings, setBindings] =
|
|
27786
|
-
const [busy, setBusy] =
|
|
27864
|
+
const [userId, setUserId] = React128.useState(void 0);
|
|
27865
|
+
const [bindings, setBindings] = React128.useState({});
|
|
27866
|
+
const [busy, setBusy] = React128.useState(null);
|
|
27787
27867
|
const bindingsVersion = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
27788
|
-
|
|
27868
|
+
React128.useEffect(() => {
|
|
27789
27869
|
if (!personId) return;
|
|
27790
27870
|
let alive = true;
|
|
27791
27871
|
void fetchUserIdForPerson(personId).then((uid2) => {
|
|
@@ -27795,11 +27875,11 @@ function PersonUnitsTab({ item }) {
|
|
|
27795
27875
|
alive = false;
|
|
27796
27876
|
};
|
|
27797
27877
|
}, [personId]);
|
|
27798
|
-
const reload =
|
|
27878
|
+
const reload = React128.useCallback(async (uid2) => {
|
|
27799
27879
|
const rows = await fetchMemberUnits(uid2);
|
|
27800
27880
|
setBindings(Object.fromEntries(rows.map((r) => [r.locationId, r.role])));
|
|
27801
27881
|
}, []);
|
|
27802
|
-
|
|
27882
|
+
React128.useEffect(() => {
|
|
27803
27883
|
if (userId) void reload(userId);
|
|
27804
27884
|
}, [userId, reload, bindingsVersion]);
|
|
27805
27885
|
async function toggle(unitId, on) {
|
|
@@ -27897,13 +27977,13 @@ function PersonUnitsTab({ item }) {
|
|
|
27897
27977
|
function PersonAvailabilityTab({ item }) {
|
|
27898
27978
|
const person = item;
|
|
27899
27979
|
const personId = person?.id;
|
|
27900
|
-
const [units, setUnits] =
|
|
27901
|
-
const [selected, setSelected] =
|
|
27902
|
-
const [loading, setLoading] =
|
|
27903
|
-
const [busy, setBusy] =
|
|
27904
|
-
const [availabilityReady, setAvailabilityReady] =
|
|
27980
|
+
const [units, setUnits] = React128.useState([]);
|
|
27981
|
+
const [selected, setSelected] = React128.useState(/* @__PURE__ */ new Set());
|
|
27982
|
+
const [loading, setLoading] = React128.useState(true);
|
|
27983
|
+
const [busy, setBusy] = React128.useState(false);
|
|
27984
|
+
const [availabilityReady, setAvailabilityReady] = React128.useState(true);
|
|
27905
27985
|
const db2 = () => getSupabaseClientOptional();
|
|
27906
|
-
const load =
|
|
27986
|
+
const load = React128.useCallback(async () => {
|
|
27907
27987
|
const client3 = db2();
|
|
27908
27988
|
if (!client3 || !personId) {
|
|
27909
27989
|
setLoading(false);
|
|
@@ -27932,7 +28012,7 @@ function PersonAvailabilityTab({ item }) {
|
|
|
27932
28012
|
setLoading(false);
|
|
27933
28013
|
}
|
|
27934
28014
|
}, [personId]);
|
|
27935
|
-
|
|
28015
|
+
React128.useEffect(() => {
|
|
27936
28016
|
void load();
|
|
27937
28017
|
}, [load]);
|
|
27938
28018
|
async function makeOrganizationWide() {
|
|
@@ -28010,10 +28090,10 @@ function PersonAvailabilityTab({ item }) {
|
|
|
28010
28090
|
/* @__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." })
|
|
28011
28091
|
] }) });
|
|
28012
28092
|
}
|
|
28013
|
-
var ScheduleEditor2 =
|
|
28014
|
-
() => import('./ScheduleEditor-
|
|
28093
|
+
var ScheduleEditor2 = React128__default.lazy(
|
|
28094
|
+
() => import('./ScheduleEditor-VGDE57L2.js').then((m) => ({ default: m.ScheduleEditor }))
|
|
28015
28095
|
);
|
|
28016
|
-
var PersonTimeline2 =
|
|
28096
|
+
var PersonTimeline2 = React128__default.lazy(
|
|
28017
28097
|
() => import('./timeline-LECYQ4IA.js').then((m) => ({ default: m.PersonTimeline }))
|
|
28018
28098
|
);
|
|
28019
28099
|
function ComingSoon({ icon: Icon, title, description }) {
|
|
@@ -28037,7 +28117,7 @@ function ActivityTab({ item, recordPath }) {
|
|
|
28037
28117
|
}
|
|
28038
28118
|
);
|
|
28039
28119
|
}
|
|
28040
|
-
return /* @__PURE__ */ jsx(
|
|
28120
|
+
return /* @__PURE__ */ jsx(React128__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(PersonTimeline2, { personId: item.id, recordPath }) });
|
|
28041
28121
|
}
|
|
28042
28122
|
function DocumentsTab({ item }) {
|
|
28043
28123
|
const t = useTranslation();
|
|
@@ -28149,7 +28229,7 @@ function ScheduleTab({ item }) {
|
|
|
28149
28229
|
return (
|
|
28150
28230
|
// O interruptor "Aparece na agenda" agora vem DENTRO do editor: era a
|
|
28151
28231
|
// única coisa que esta porta mostrava e a da agenda não.
|
|
28152
|
-
/* @__PURE__ */ jsx(
|
|
28232
|
+
/* @__PURE__ */ jsx(React128__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(ScheduleEditor2, { assigneeId: item.id }) })
|
|
28153
28233
|
);
|
|
28154
28234
|
}
|
|
28155
28235
|
var PERSON_DETAIL_TABS = [
|
|
@@ -28636,7 +28716,7 @@ function InlineEditor({
|
|
|
28636
28716
|
}) {
|
|
28637
28717
|
const [draft, setDraft] = useState(value ?? "");
|
|
28638
28718
|
const [saving, setSaving] = useState(false);
|
|
28639
|
-
const inputRef =
|
|
28719
|
+
const inputRef = React128__default.useRef(null);
|
|
28640
28720
|
useEffect(() => {
|
|
28641
28721
|
inputRef.current?.focus();
|
|
28642
28722
|
if (inputRef.current instanceof HTMLInputElement) inputRef.current.select();
|
|
@@ -29007,9 +29087,9 @@ function CrudDetailPage({
|
|
|
29007
29087
|
const t = useTranslation();
|
|
29008
29088
|
const [pending2, setPending] = useState({});
|
|
29009
29089
|
const [savingDraft, setSavingDraft] = useState(false);
|
|
29010
|
-
const pendingKeys =
|
|
29090
|
+
const pendingKeys = React128__default.useMemo(() => new Set(Object.keys(pending2)), [pending2]);
|
|
29011
29091
|
const dirty = pendingKeys.size > 0;
|
|
29012
|
-
const view =
|
|
29092
|
+
const view = React128__default.useMemo(
|
|
29013
29093
|
() => dirty ? { ...item, ...pending2 } : item,
|
|
29014
29094
|
[item, pending2, dirty]
|
|
29015
29095
|
);
|
|
@@ -29059,7 +29139,7 @@ function CrudDetailPage({
|
|
|
29059
29139
|
const isMyRecord = Boolean(myPersonId) && myPersonId === item.id;
|
|
29060
29140
|
const nameEditable = Boolean(onFieldSave || onFieldsSave) && Boolean(displayFieldDef) && isInlineEditable(displayFieldDef);
|
|
29061
29141
|
const [editingName, setEditingName] = useState(false);
|
|
29062
|
-
const imageInputRef =
|
|
29142
|
+
const imageInputRef = React128__default.useRef(null);
|
|
29063
29143
|
const runtime = usePluginRuntimeOptional();
|
|
29064
29144
|
const archetypeTabs = getArchetypeTabs(entityDef.layout, entityDef.data?.archetypeKind);
|
|
29065
29145
|
const relatedTabs = (entityDef.relatedLists ?? []).map((related) => ({
|
|
@@ -29069,7 +29149,7 @@ function CrudDetailPage({
|
|
|
29069
29149
|
component: (props) => /* @__PURE__ */ jsx(RelatedListTab, { ...props, related })
|
|
29070
29150
|
}));
|
|
29071
29151
|
const unitMode = useUnitMode();
|
|
29072
|
-
const fieldGroupTabs =
|
|
29152
|
+
const fieldGroupTabs = React128__default.useMemo(() => {
|
|
29073
29153
|
const groups = entityDef.fieldGroups ?? [];
|
|
29074
29154
|
if (!groups.some((g) => g.tab) || !item) return [];
|
|
29075
29155
|
const applicable = new Set(visibleDetailFields(entityDef, item).map((f) => f.group));
|
|
@@ -29152,7 +29232,7 @@ function CrudDetailPage({
|
|
|
29152
29232
|
window.history.replaceState(null, "", `#${segments.length ? `${base}/${segments.join("/")}` : base}`);
|
|
29153
29233
|
}, [basePath, item.id, selectedTab, embedded]);
|
|
29154
29234
|
const parentLabel = usePresetLabel(basePath, namePlural);
|
|
29155
|
-
const headerNode =
|
|
29235
|
+
const headerNode = React128__default.useMemo(
|
|
29156
29236
|
() => embedded ? null : /* @__PURE__ */ jsx(SubpageHeader, { title: displayValue, parentLabel, onBack }),
|
|
29157
29237
|
[embedded, displayValue, parentLabel, onBack]
|
|
29158
29238
|
);
|
|
@@ -29284,7 +29364,7 @@ function CrudDetailPage({
|
|
|
29284
29364
|
})
|
|
29285
29365
|
] }),
|
|
29286
29366
|
/* @__PURE__ */ jsxs(TabsContent, { value: "overview", className: embedded ? "mt-2" : "mt-4", children: [
|
|
29287
|
-
entityDef.overviewComponent ?
|
|
29367
|
+
entityDef.overviewComponent ? React128__default.createElement(entityDef.overviewComponent, { item, entityDef }) : /* @__PURE__ */ jsx(
|
|
29288
29368
|
OverviewTab,
|
|
29289
29369
|
{
|
|
29290
29370
|
entityDef,
|
|
@@ -29303,7 +29383,7 @@ function CrudDetailPage({
|
|
|
29303
29383
|
// `tabPath` only to the tab the URL is actually addressing —
|
|
29304
29384
|
// handing it to every tab would have the documents tab trying to
|
|
29305
29385
|
// open a recording id when the user switches across.
|
|
29306
|
-
|
|
29386
|
+
React128__default.createElement(tab.component, {
|
|
29307
29387
|
item,
|
|
29308
29388
|
entityDef,
|
|
29309
29389
|
// A rota DESTE registro. Uma aba que lista eventos precisa
|
|
@@ -29344,8 +29424,8 @@ function MyRecordPanel() {
|
|
|
29344
29424
|
const userId = useAuthStore((s) => s.user?.id);
|
|
29345
29425
|
const members = useOrganizationStore((s) => s.members);
|
|
29346
29426
|
const myRole = members.find((m) => m.userId === userId)?.profileName;
|
|
29347
|
-
const [state, setState] =
|
|
29348
|
-
const load =
|
|
29427
|
+
const [state, setState] = React128.useState({ status: "loading" });
|
|
29428
|
+
const load = React128.useCallback(async () => {
|
|
29349
29429
|
if (!orgId || !userId) return;
|
|
29350
29430
|
const person = await dedup(`self:record:${orgId}:${userId}`, () => fetchMyPersonRecord(orgId, userId));
|
|
29351
29431
|
if (!person) return setState({ status: "none" });
|
|
@@ -29362,10 +29442,10 @@ function MyRecordPanel() {
|
|
|
29362
29442
|
setState({ status: "none" });
|
|
29363
29443
|
}
|
|
29364
29444
|
}, [orgId, userId]);
|
|
29365
|
-
|
|
29445
|
+
React128.useEffect(() => {
|
|
29366
29446
|
void load();
|
|
29367
29447
|
}, [load]);
|
|
29368
|
-
const changePhoto =
|
|
29448
|
+
const changePhoto = React128.useCallback(async (file) => {
|
|
29369
29449
|
if (state.status !== "ready") return;
|
|
29370
29450
|
const supabase = getFayzSupabaseClientOptional();
|
|
29371
29451
|
if (!supabase) return;
|
|
@@ -29421,8 +29501,8 @@ function ConnectedUserProfile() {
|
|
|
29421
29501
|
const myPersonId = useMyPersonId();
|
|
29422
29502
|
const hasRecord = Boolean(myPersonId);
|
|
29423
29503
|
const setUser = useAuthStore((s) => s.setUser);
|
|
29424
|
-
const [profile, setProfile] =
|
|
29425
|
-
|
|
29504
|
+
const [profile, setProfile] = React128.useState(null);
|
|
29505
|
+
React128.useEffect(() => {
|
|
29426
29506
|
const supabase = getFayzSupabaseClientOptional();
|
|
29427
29507
|
if (!user || !supabase) return;
|
|
29428
29508
|
let cancelled = false;
|
|
@@ -29533,9 +29613,9 @@ function SecuritySettings({
|
|
|
29533
29613
|
onTenantSecurityChange
|
|
29534
29614
|
}) {
|
|
29535
29615
|
const { t } = useTranslation$1();
|
|
29536
|
-
const [resetting, setResetting] =
|
|
29537
|
-
const [resetSent, setResetSent] =
|
|
29538
|
-
const [savingTenant, setSavingTenant] =
|
|
29616
|
+
const [resetting, setResetting] = React128.useState(false);
|
|
29617
|
+
const [resetSent, setResetSent] = React128.useState(false);
|
|
29618
|
+
const [savingTenant, setSavingTenant] = React128.useState(false);
|
|
29539
29619
|
const handleResetPassword = async () => {
|
|
29540
29620
|
if (!onResetPassword) return;
|
|
29541
29621
|
setResetting(true);
|
|
@@ -29709,8 +29789,8 @@ function FileUploadField({
|
|
|
29709
29789
|
hint
|
|
29710
29790
|
}) {
|
|
29711
29791
|
const { t } = useTranslation$1();
|
|
29712
|
-
const inputRef =
|
|
29713
|
-
const [preview, setPreview] =
|
|
29792
|
+
const inputRef = React128.useRef(null);
|
|
29793
|
+
const [preview, setPreview] = React128.useState(null);
|
|
29714
29794
|
const handleChange = (e) => {
|
|
29715
29795
|
const file = e.target.files?.[0];
|
|
29716
29796
|
if (file) {
|
|
@@ -29932,13 +30012,13 @@ function SkinGate({ children }) {
|
|
|
29932
30012
|
}
|
|
29933
30013
|
function BrandingSettings({ brand, onSave }) {
|
|
29934
30014
|
const { t } = useTranslation$1();
|
|
29935
|
-
const [section, setSection] =
|
|
29936
|
-
const [saved, setSaved] =
|
|
29937
|
-
const [draft, setDraft] =
|
|
29938
|
-
const [logoFile, setLogoFile] =
|
|
29939
|
-
const [faviconFile, setFaviconFile] =
|
|
29940
|
-
const [saving, setSaving] =
|
|
29941
|
-
|
|
30015
|
+
const [section, setSection] = React128.useState("identity");
|
|
30016
|
+
const [saved, setSaved] = React128.useState(brand ?? EMPTY_BRAND);
|
|
30017
|
+
const [draft, setDraft] = React128.useState(brand ?? EMPTY_BRAND);
|
|
30018
|
+
const [logoFile, setLogoFile] = React128.useState(null);
|
|
30019
|
+
const [faviconFile, setFaviconFile] = React128.useState(null);
|
|
30020
|
+
const [saving, setSaving] = React128.useState(false);
|
|
30021
|
+
React128.useEffect(() => {
|
|
29942
30022
|
if (brand) {
|
|
29943
30023
|
setSaved(brand);
|
|
29944
30024
|
setDraft(brand);
|
|
@@ -30281,14 +30361,14 @@ function ConnectedBrandingSettings() {
|
|
|
30281
30361
|
};
|
|
30282
30362
|
if (assets?.logoFile) {
|
|
30283
30363
|
const ext = assets.logoFile.name.split(".").pop() ?? "png";
|
|
30284
|
-
const path =
|
|
30364
|
+
const path = `${currentOrg.id}/branding/logo.${ext}`;
|
|
30285
30365
|
const { error } = await supabase.storage.from("avatars").upload(path, assets.logoFile, { upsert: true });
|
|
30286
30366
|
if (error) throw error;
|
|
30287
30367
|
next.identity.logoUrl = supabase.storage.from("avatars").getPublicUrl(path).data.publicUrl;
|
|
30288
30368
|
}
|
|
30289
30369
|
if (assets?.faviconFile) {
|
|
30290
30370
|
const ext = assets.faviconFile.name.split(".").pop() ?? "png";
|
|
30291
|
-
const path =
|
|
30371
|
+
const path = `${currentOrg.id}/branding/favicon.${ext}`;
|
|
30292
30372
|
const { error } = await supabase.storage.from("avatars").upload(path, assets.faviconFile, { upsert: true });
|
|
30293
30373
|
if (error) throw error;
|
|
30294
30374
|
next.identity.faviconUrl = supabase.storage.from("avatars").getPublicUrl(path).data.publicUrl;
|
|
@@ -30312,11 +30392,11 @@ function ConnectedBrandingSettings() {
|
|
|
30312
30392
|
toast.error("N\xE3o foi poss\xEDvel salvar a marca", { description: err?.message });
|
|
30313
30393
|
}
|
|
30314
30394
|
};
|
|
30315
|
-
const [brand, setBrand] =
|
|
30395
|
+
const [brand, setBrand] = React128.useState(() => normalizeBrand(
|
|
30316
30396
|
(currentOrg?.settings ?? {}).branding,
|
|
30317
30397
|
{ name: currentOrg?.name, logoUrl: currentOrg?.logoUrl }
|
|
30318
30398
|
));
|
|
30319
|
-
|
|
30399
|
+
React128.useEffect(() => {
|
|
30320
30400
|
let alive = true;
|
|
30321
30401
|
void (async () => {
|
|
30322
30402
|
try {
|
|
@@ -30437,12 +30517,12 @@ function ProjectsSettings() {
|
|
|
30437
30517
|
const projects = useFayzProjectsStore((s) => s.projects);
|
|
30438
30518
|
const load = useFayzProjectsStore((s) => s.load);
|
|
30439
30519
|
const refresh = useFayzProjectsStore((s) => s.refresh);
|
|
30440
|
-
const [linking, setLinking] =
|
|
30520
|
+
const [linking, setLinking] = React128.useState(false);
|
|
30441
30521
|
const connected = isPlatformConnected();
|
|
30442
|
-
|
|
30522
|
+
React128.useEffect(() => {
|
|
30443
30523
|
void load(currentOrgId);
|
|
30444
30524
|
}, [currentOrgId, load]);
|
|
30445
|
-
|
|
30525
|
+
React128.useEffect(() => {
|
|
30446
30526
|
if (!connected || projects.length === 0) return;
|
|
30447
30527
|
let cancelled = false;
|
|
30448
30528
|
void (async () => {
|
|
@@ -30514,7 +30594,7 @@ function SiteRow({
|
|
|
30514
30594
|
showDefaultAction,
|
|
30515
30595
|
onChanged
|
|
30516
30596
|
}) {
|
|
30517
|
-
const [busy, setBusy] =
|
|
30597
|
+
const [busy, setBusy] = React128.useState(false);
|
|
30518
30598
|
const editorUrl = editorUrlOf(project);
|
|
30519
30599
|
const run = async (action) => {
|
|
30520
30600
|
setBusy(true);
|
|
@@ -30585,7 +30665,7 @@ function SiteRow({
|
|
|
30585
30665
|
] });
|
|
30586
30666
|
}
|
|
30587
30667
|
function LinkSiteModal({ onClose, onLinked }) {
|
|
30588
|
-
const [mode, setMode] =
|
|
30668
|
+
const [mode, setMode] = React128.useState("import");
|
|
30589
30669
|
return /* @__PURE__ */ jsx(Modal, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs(ModalContent, { size: "lg", children: [
|
|
30590
30670
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
30591
30671
|
/* @__PURE__ */ jsx(ModalTitle, { children: "Vincular um site" }),
|
|
@@ -30621,11 +30701,11 @@ function ModeTab({
|
|
|
30621
30701
|
}
|
|
30622
30702
|
function ImportPane({ onLinked }) {
|
|
30623
30703
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
30624
|
-
const [search, setSearch] =
|
|
30625
|
-
const [remote, setRemote] =
|
|
30626
|
-
const [error, setError] =
|
|
30627
|
-
const [linkingId, setLinkingId] =
|
|
30628
|
-
|
|
30704
|
+
const [search, setSearch] = React128.useState("");
|
|
30705
|
+
const [remote, setRemote] = React128.useState(null);
|
|
30706
|
+
const [error, setError] = React128.useState(null);
|
|
30707
|
+
const [linkingId, setLinkingId] = React128.useState(null);
|
|
30708
|
+
React128.useEffect(() => {
|
|
30629
30709
|
let cancelled = false;
|
|
30630
30710
|
setError(null);
|
|
30631
30711
|
const timer = setTimeout(() => {
|
|
@@ -30707,9 +30787,9 @@ function ImportPane({ onLinked }) {
|
|
|
30707
30787
|
}
|
|
30708
30788
|
function CreatePane({ onLinked, onCancel }) {
|
|
30709
30789
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
30710
|
-
const [prompt, setPrompt] =
|
|
30711
|
-
const [busy, setBusy] =
|
|
30712
|
-
const [error, setError] =
|
|
30790
|
+
const [prompt, setPrompt] = React128.useState("");
|
|
30791
|
+
const [busy, setBusy] = React128.useState(false);
|
|
30792
|
+
const [error, setError] = React128.useState(null);
|
|
30713
30793
|
const tooShort = prompt.trim().length < PROMPT_MIN_CHARS;
|
|
30714
30794
|
const submit = async () => {
|
|
30715
30795
|
setBusy(true);
|
|
@@ -30898,10 +30978,10 @@ function ModuleCatalogSections({
|
|
|
30898
30978
|
onToggle,
|
|
30899
30979
|
busy
|
|
30900
30980
|
}) {
|
|
30901
|
-
const [query, setQuery] =
|
|
30981
|
+
const [query, setQuery] = React128.useState("");
|
|
30902
30982
|
const total = categories.reduce((n, c) => n + c.rows.length, 0);
|
|
30903
30983
|
const searchable = total > 6;
|
|
30904
|
-
const filtered =
|
|
30984
|
+
const filtered = React128.useMemo(() => filterCategories(categories, query), [categories, query]);
|
|
30905
30985
|
if (categories.length === 0) {
|
|
30906
30986
|
return /* @__PURE__ */ jsxs("div", { className: "py-8 text-center", children: [
|
|
30907
30987
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Nada a adicionar" }),
|
|
@@ -30943,7 +31023,7 @@ function CategorySection({
|
|
|
30943
31023
|
onToggle,
|
|
30944
31024
|
busy
|
|
30945
31025
|
}) {
|
|
30946
|
-
const [open, setOpen] =
|
|
31026
|
+
const [open, setOpen] = React128.useState(category.mine);
|
|
30947
31027
|
const expanded = open || forceOpen;
|
|
30948
31028
|
const Chevron = expanded ? ChevronDown : ChevronRight;
|
|
30949
31029
|
return /* @__PURE__ */ jsxs("section", { children: [
|
|
@@ -31074,8 +31154,8 @@ function buildCategories(catalog, rows) {
|
|
|
31074
31154
|
}
|
|
31075
31155
|
function useModuleCatalog() {
|
|
31076
31156
|
const tenantId2 = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
31077
|
-
const [catalog, setCatalog] =
|
|
31078
|
-
|
|
31157
|
+
const [catalog, setCatalog] = React128.useState([]);
|
|
31158
|
+
React128.useEffect(() => {
|
|
31079
31159
|
const supabase = getSupabaseClientOptional$1();
|
|
31080
31160
|
if (!supabase) return;
|
|
31081
31161
|
let alive = true;
|
|
@@ -31092,7 +31172,7 @@ function useModuleCatalog() {
|
|
|
31092
31172
|
function ModulesPreview() {
|
|
31093
31173
|
const runtime = usePluginRuntime();
|
|
31094
31174
|
const preset = useAppPreset();
|
|
31095
|
-
const rows =
|
|
31175
|
+
const rows = React128.useMemo(() => {
|
|
31096
31176
|
const flat = runtime.navigation.filter((entry) => entry.section !== "settings").map((entry) => toRailRow(entry, preset.labels));
|
|
31097
31177
|
return applyRailPreset(flat, preset.rail, preset.hide, preset.whole);
|
|
31098
31178
|
}, [runtime.navigation, preset.rail, preset.hide, preset.whole, preset.labels]);
|
|
@@ -31136,15 +31216,15 @@ function PreviewRow({ row, depth = 0 }) {
|
|
|
31136
31216
|
function ModulesSettings({ hidden = [], onToggle, permits, busy, catalog = [] }) {
|
|
31137
31217
|
const runtime = usePluginRuntime();
|
|
31138
31218
|
const offered = useOfferedPlugins();
|
|
31139
|
-
const [adding, setAdding] =
|
|
31140
|
-
const rows =
|
|
31219
|
+
const [adding, setAdding] = React128.useState(false);
|
|
31220
|
+
const rows = React128.useMemo(() => {
|
|
31141
31221
|
const known = catalog.length ? new Set(catalog.flatMap((app) => app.modules)) : new Set(offered);
|
|
31142
31222
|
const inCatalogue = known.size ? runtime.plugins.filter((p) => known.has(p.id) || p.isActive) : runtime.plugins;
|
|
31143
31223
|
return buildRows(inCatalogue, new Set(hidden), permits);
|
|
31144
31224
|
}, [runtime.plugins, hidden, permits, offered, catalog]);
|
|
31145
31225
|
const on = rows.filter((r) => r.plugin.isActive);
|
|
31146
|
-
const off =
|
|
31147
|
-
const categories =
|
|
31226
|
+
const off = React128.useMemo(() => rows.filter((r) => !r.plugin.isActive), [rows]);
|
|
31227
|
+
const categories = React128.useMemo(() => buildCategories(catalog, off), [catalog, off]);
|
|
31148
31228
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
|
|
31149
31229
|
/* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsxs(Button, { size: "sm", className: "shrink-0 gap-1.5", onClick: () => setAdding(true), children: [
|
|
31150
31230
|
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
|
|
@@ -31364,8 +31444,8 @@ function ConnectedModulesSettings({ hidden = SHELL_PLUGINS }) {
|
|
|
31364
31444
|
const access = useAccessOptional();
|
|
31365
31445
|
const catalog = useModuleCatalog();
|
|
31366
31446
|
const tenantId2 = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
31367
|
-
const [busy, setBusy] =
|
|
31368
|
-
const onToggle =
|
|
31447
|
+
const [busy, setBusy] = React128.useState(false);
|
|
31448
|
+
const onToggle = React128.useCallback(
|
|
31369
31449
|
async (plugin, status, facet) => {
|
|
31370
31450
|
const supabase = getSupabaseClientOptional$1();
|
|
31371
31451
|
if (!supabase) return;
|
|
@@ -31391,7 +31471,7 @@ function ConnectedModulesSettings({ hidden = SHELL_PLUGINS }) {
|
|
|
31391
31471
|
},
|
|
31392
31472
|
[refresh, tenantId2]
|
|
31393
31473
|
);
|
|
31394
|
-
const permits =
|
|
31474
|
+
const permits = React128.useCallback(
|
|
31395
31475
|
(plugin) => access ? access.can(plugin, "read").allowed || access.entitled(plugin) : true,
|
|
31396
31476
|
[access]
|
|
31397
31477
|
);
|
|
@@ -31402,7 +31482,7 @@ function useCoreSettingsTabs({
|
|
|
31402
31482
|
showBranding = true
|
|
31403
31483
|
} = {}) {
|
|
31404
31484
|
const { t } = useTranslation$1();
|
|
31405
|
-
return
|
|
31485
|
+
return React128.useMemo(() => [
|
|
31406
31486
|
...showCompany ? [{ id: "general", label: t("settings.general"), icon: /* @__PURE__ */ jsx(Building2, { className: "h-4 w-4" }), iconName: "Building2", component: /* @__PURE__ */ jsx(ConnectedCompanySettings, {}) }] : [],
|
|
31407
31487
|
{ id: "profile", label: t("settings.profile"), icon: /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }), iconName: "User", component: /* @__PURE__ */ jsx(ConnectedUserProfile, {}) },
|
|
31408
31488
|
{ id: "security", label: t("settings.security"), icon: /* @__PURE__ */ jsx(Shield, { className: "h-4 w-4" }), iconName: "Shield", component: /* @__PURE__ */ jsx(ConnectedSecuritySettings, {}) },
|
|
@@ -31447,10 +31527,10 @@ function SettingsPage({
|
|
|
31447
31527
|
}
|
|
31448
31528
|
return null;
|
|
31449
31529
|
}
|
|
31450
|
-
const [activeTab, setActiveTab] =
|
|
31530
|
+
const [activeTab, setActiveTab] = React128.useState(() => {
|
|
31451
31531
|
return getTabFromHash() ?? defaultTab ?? null;
|
|
31452
31532
|
});
|
|
31453
|
-
|
|
31533
|
+
React128.useEffect(() => {
|
|
31454
31534
|
const handler = () => {
|
|
31455
31535
|
const tab = getTabFromHash();
|
|
31456
31536
|
if (tab) setActiveTab(tab);
|
|
@@ -31477,8 +31557,8 @@ function SettingsPage({
|
|
|
31477
31557
|
setActiveTab(null);
|
|
31478
31558
|
window.location.hash = "/settings";
|
|
31479
31559
|
};
|
|
31480
|
-
const [query, setQuery] =
|
|
31481
|
-
const sections =
|
|
31560
|
+
const [query, setQuery] = React128.useState("");
|
|
31561
|
+
const sections = React128.useMemo(() => {
|
|
31482
31562
|
const q = query.trim().toLowerCase();
|
|
31483
31563
|
const out = [];
|
|
31484
31564
|
for (const tab of resolvedTabs) {
|
|
@@ -31563,14 +31643,14 @@ function InviteMemberDialog({ open, onOpenChange, defaultEmail }) {
|
|
|
31563
31643
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
31564
31644
|
const setInvites = useInviteStore((s) => s.setInvites);
|
|
31565
31645
|
const { user } = useAuthStore();
|
|
31566
|
-
const [emails, setEmails] =
|
|
31567
|
-
const [profileId, setProfileId] =
|
|
31568
|
-
const [sending, setSending] =
|
|
31569
|
-
const [sent, setSent] =
|
|
31570
|
-
|
|
31646
|
+
const [emails, setEmails] = React128.useState([defaultEmail ?? ""]);
|
|
31647
|
+
const [profileId, setProfileId] = React128.useState(profiles[1]?.id ?? profiles[0]?.id ?? "");
|
|
31648
|
+
const [sending, setSending] = React128.useState(false);
|
|
31649
|
+
const [sent, setSent] = React128.useState(false);
|
|
31650
|
+
React128.useEffect(() => {
|
|
31571
31651
|
if (open) setEmails([defaultEmail ?? ""]);
|
|
31572
31652
|
}, [open, defaultEmail]);
|
|
31573
|
-
|
|
31653
|
+
React128.useEffect(() => {
|
|
31574
31654
|
if (!profileId && profiles.length) setProfileId(profiles[1]?.id ?? profiles[0].id);
|
|
31575
31655
|
}, [profiles, profileId]);
|
|
31576
31656
|
const addEmail = () => setEmails((prev) => [...prev, ""]);
|
|
@@ -31674,7 +31754,7 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
31674
31754
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
31675
31755
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
31676
31756
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
31677
|
-
const [query, setQuery] =
|
|
31757
|
+
const [query, setQuery] = React128.useState("");
|
|
31678
31758
|
const singular = label2(t, "unit.singular", "unidade");
|
|
31679
31759
|
const plural = label2(t, "unit.plural", "unidades");
|
|
31680
31760
|
if (!unitMode) return null;
|
|
@@ -31699,13 +31779,13 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
31699
31779
|
}
|
|
31700
31780
|
const renderNode = (node, depth) => {
|
|
31701
31781
|
if (node.kind === "region") {
|
|
31702
|
-
return /* @__PURE__ */ jsxs(
|
|
31782
|
+
return /* @__PURE__ */ jsxs(React128.Fragment, { children: [
|
|
31703
31783
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
31704
31784
|
node.children.map((child) => renderNode(child, depth + 1))
|
|
31705
31785
|
] }, node.id);
|
|
31706
31786
|
}
|
|
31707
31787
|
if (!reachable.includes(node.id)) return null;
|
|
31708
|
-
return /* @__PURE__ */ jsxs(
|
|
31788
|
+
return /* @__PURE__ */ jsxs(React128.Fragment, { children: [
|
|
31709
31789
|
/* @__PURE__ */ jsxs(
|
|
31710
31790
|
DropdownItem,
|
|
31711
31791
|
{
|
|
@@ -31788,7 +31868,7 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
31788
31868
|
var MENU_LIST_CAP = 5;
|
|
31789
31869
|
function UnitMenuSection() {
|
|
31790
31870
|
useUnitBootstrap();
|
|
31791
|
-
const [locating, setLocating] =
|
|
31871
|
+
const [locating, setLocating] = React128.useState(false);
|
|
31792
31872
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
31793
31873
|
const units = useUnitStore((s) => s.units);
|
|
31794
31874
|
const tree = useUnitStore((s) => s.tree);
|
|
@@ -31839,13 +31919,13 @@ function UnitMenuSection() {
|
|
|
31839
31919
|
if (node.kind === "region") {
|
|
31840
31920
|
const visibleChildren = node.children.filter((c) => c.kind === "region" || reachable.includes(c.id));
|
|
31841
31921
|
if (visibleChildren.length === 0) return null;
|
|
31842
|
-
return /* @__PURE__ */ jsxs(
|
|
31922
|
+
return /* @__PURE__ */ jsxs(React128.Fragment, { children: [
|
|
31843
31923
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
31844
31924
|
visibleChildren.map((child) => renderNode(child, depth + 1))
|
|
31845
31925
|
] }, node.id);
|
|
31846
31926
|
}
|
|
31847
31927
|
if (!reachable.includes(node.id)) return null;
|
|
31848
|
-
return /* @__PURE__ */ jsxs(
|
|
31928
|
+
return /* @__PURE__ */ jsxs(React128.Fragment, { children: [
|
|
31849
31929
|
/* @__PURE__ */ jsxs(
|
|
31850
31930
|
DropdownItem,
|
|
31851
31931
|
{
|
|
@@ -31964,7 +32044,7 @@ var UNIT_DETAIL_TABS = [
|
|
|
31964
32044
|
{ id: "activity", label: "Activity", hidden: true }
|
|
31965
32045
|
];
|
|
31966
32046
|
function SuggestInput({ column, value, onChange, placeholder }) {
|
|
31967
|
-
const search =
|
|
32047
|
+
const search = React128__default.useCallback(async (query) => {
|
|
31968
32048
|
const supabase = getSupabaseClientOptional();
|
|
31969
32049
|
if (!supabase) return [];
|
|
31970
32050
|
const { data } = await supabase.from("v_units").select(column).not(column, "is", null).limit(500);
|
|
@@ -32241,9 +32321,9 @@ function MemberUnitsCell({
|
|
|
32241
32321
|
const byId = useUnitStore((s) => s.byId);
|
|
32242
32322
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
32243
32323
|
const openUnit = useUnitPanel((s) => s.openUnit);
|
|
32244
|
-
const [unitIds, setUnitIds] =
|
|
32324
|
+
const [unitIds, setUnitIds] = React128.useState(null);
|
|
32245
32325
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
32246
|
-
|
|
32326
|
+
React128.useEffect(() => {
|
|
32247
32327
|
if (!userId) {
|
|
32248
32328
|
setUnitIds([]);
|
|
32249
32329
|
return;
|
|
@@ -32301,10 +32381,10 @@ function TeamTab() {
|
|
|
32301
32381
|
const { user } = useAuthStore();
|
|
32302
32382
|
const hasSystemPermission = useSystemPermission();
|
|
32303
32383
|
const personMode = teamPersonKinds.length > 0 && typeof adapter?.listTeam === "function";
|
|
32304
|
-
const [team, setTeam] =
|
|
32305
|
-
const [inviteOpen, setInviteOpen] =
|
|
32384
|
+
const [team, setTeam] = React128.useState(null);
|
|
32385
|
+
const [inviteOpen, setInviteOpen] = React128.useState(false);
|
|
32306
32386
|
const guardSeats = useLimitGuard("users");
|
|
32307
|
-
const [inviteEmail, setInviteEmail] =
|
|
32387
|
+
const [inviteEmail, setInviteEmail] = React128.useState(void 0);
|
|
32308
32388
|
const handleOpenInvite = async (row) => {
|
|
32309
32389
|
if (row && !row.email && row.personId && entityRouteHasDetail("person", row.kind)) {
|
|
32310
32390
|
openEntity(row.personId, "person", row.kind, "access");
|
|
@@ -32314,7 +32394,7 @@ function TeamTab() {
|
|
|
32314
32394
|
setInviteEmail(row?.email || void 0);
|
|
32315
32395
|
setInviteOpen(true);
|
|
32316
32396
|
};
|
|
32317
|
-
const reloadTeam =
|
|
32397
|
+
const reloadTeam = React128.useCallback(async () => {
|
|
32318
32398
|
if (!adapter || !currentOrg) return;
|
|
32319
32399
|
if (personMode && adapter.listTeam) {
|
|
32320
32400
|
setTeam(await adapter.listTeam(currentOrg.id, teamPersonKinds));
|
|
@@ -32322,12 +32402,12 @@ function TeamTab() {
|
|
|
32322
32402
|
setMembers(await adapter.listMembers(currentOrg.id));
|
|
32323
32403
|
}
|
|
32324
32404
|
}, [adapter, currentOrg?.id, personMode, teamPersonKinds, setMembers]);
|
|
32325
|
-
|
|
32405
|
+
React128.useEffect(() => {
|
|
32326
32406
|
if (personMode && adapter?.listTeam && currentOrg) {
|
|
32327
32407
|
dedup("team:people:" + currentOrg.id, () => adapter.listTeam(currentOrg.id, teamPersonKinds)).then(setTeam).catch(() => setTeam([]));
|
|
32328
32408
|
}
|
|
32329
32409
|
}, [personMode, adapter, currentOrg?.id, teamPersonKinds.join(",")]);
|
|
32330
|
-
|
|
32410
|
+
React128.useEffect(() => {
|
|
32331
32411
|
if (adapter && currentOrg) {
|
|
32332
32412
|
dedup("team:invites:" + currentOrg.id, () => adapter.listInvites(currentOrg.id)).then(setInvites).catch(() => {
|
|
32333
32413
|
});
|
|
@@ -32408,7 +32488,7 @@ function TeamTab() {
|
|
|
32408
32488
|
};
|
|
32409
32489
|
const { t } = useTranslation$1();
|
|
32410
32490
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
32411
|
-
const inviteActions =
|
|
32491
|
+
const inviteActions = React128.useMemo(() => [{
|
|
32412
32492
|
id: "invite",
|
|
32413
32493
|
label: t("organization.team.invite"),
|
|
32414
32494
|
icon: UserPlus,
|
|
@@ -32580,14 +32660,14 @@ function TeamTab() {
|
|
|
32580
32660
|
)
|
|
32581
32661
|
] });
|
|
32582
32662
|
}
|
|
32583
|
-
var
|
|
32663
|
+
var ACTIONS3 = ["read", "create", "edit", "delete"];
|
|
32584
32664
|
var ACTION_COLORS = {
|
|
32585
32665
|
read: "primary",
|
|
32586
32666
|
create: "success",
|
|
32587
32667
|
edit: "warning",
|
|
32588
32668
|
delete: "destructive"
|
|
32589
32669
|
};
|
|
32590
|
-
var
|
|
32670
|
+
var SYSTEM_PERMISSIONS2 = [
|
|
32591
32671
|
{ id: "manage_team", key: "organization.permissions.manageTeam" },
|
|
32592
32672
|
{ id: "manage_billing", key: "organization.permissions.manageBilling" },
|
|
32593
32673
|
{ id: "manage_settings", key: "organization.permissions.manageSettings" },
|
|
@@ -32595,13 +32675,13 @@ var SYSTEM_PERMISSIONS = [
|
|
|
32595
32675
|
];
|
|
32596
32676
|
function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, isNew, parentLabel }) {
|
|
32597
32677
|
const { t } = useTranslation$1();
|
|
32598
|
-
const [name, setName] =
|
|
32599
|
-
const [description, setDescription] =
|
|
32600
|
-
const [systemPerms, setSystemPerms] =
|
|
32601
|
-
const [grants, setGrants] =
|
|
32602
|
-
const [collapsed, setCollapsed] =
|
|
32603
|
-
const [search, setSearch] =
|
|
32604
|
-
const initial =
|
|
32678
|
+
const [name, setName] = React128.useState(profile?.name ?? "");
|
|
32679
|
+
const [description, setDescription] = React128.useState(profile?.description ?? "");
|
|
32680
|
+
const [systemPerms, setSystemPerms] = React128.useState(profile?.systemPermissions ?? []);
|
|
32681
|
+
const [grants, setGrants] = React128.useState(profile?.grants ?? {});
|
|
32682
|
+
const [collapsed, setCollapsed] = React128.useState(/* @__PURE__ */ new Set());
|
|
32683
|
+
const [search, setSearch] = React128.useState("");
|
|
32684
|
+
const initial = React128.useRef({
|
|
32605
32685
|
name: profile?.name ?? "",
|
|
32606
32686
|
description: profile?.description ?? "",
|
|
32607
32687
|
systemPerms: JSON.stringify(profile?.systemPermissions ?? []),
|
|
@@ -32638,7 +32718,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
32638
32718
|
onDiscard: onCancel,
|
|
32639
32719
|
saveLabel: isNew ? t("organization.permissions.createProfile") : t("organization.permissions.updateProfile")
|
|
32640
32720
|
});
|
|
32641
|
-
const groups =
|
|
32721
|
+
const groups = React128.useMemo(() => {
|
|
32642
32722
|
const filtered = search ? features.filter((f) => f.label.toLowerCase().includes(search.toLowerCase())) : features;
|
|
32643
32723
|
const map = /* @__PURE__ */ new Map();
|
|
32644
32724
|
for (const f of filtered) {
|
|
@@ -32683,7 +32763,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
32683
32763
|
/* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full", children: [
|
|
32684
32764
|
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-b bg-muted/50", children: [
|
|
32685
32765
|
/* @__PURE__ */ jsx("th", { className: "text-left p-3 text-sm font-medium text-muted-foreground", children: t("common.feature") }),
|
|
32686
|
-
|
|
32766
|
+
ACTIONS3.map((action) => /* @__PURE__ */ jsx("th", { className: "p-3 text-center text-sm font-medium text-muted-foreground capitalize w-20", children: t(`organization.permissions.action.${action}`) === `organization.permissions.action.${action}` ? action : t(`organization.permissions.action.${action}`) }, action))
|
|
32687
32767
|
] }) }),
|
|
32688
32768
|
/* @__PURE__ */ jsxs("tbody", { className: "divide-y", children: [
|
|
32689
32769
|
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: 5, className: "p-2 px-3", children: /* @__PURE__ */ jsxs(
|
|
@@ -32697,7 +32777,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
32697
32777
|
]
|
|
32698
32778
|
}
|
|
32699
32779
|
) }) }),
|
|
32700
|
-
!collapsed.has("__system") &&
|
|
32780
|
+
!collapsed.has("__system") && SYSTEM_PERMISSIONS2.map((sp) => /* @__PURE__ */ jsxs("tr", { className: "hover:bg-muted/30", children: [
|
|
32701
32781
|
/* @__PURE__ */ jsx("td", { className: "p-3 text-sm font-medium", children: t(sp.key) }),
|
|
32702
32782
|
/* @__PURE__ */ jsx("td", { colSpan: 4, className: "p-3", children: /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
32703
32783
|
Checkbox,
|
|
@@ -32707,7 +32787,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
32707
32787
|
}
|
|
32708
32788
|
) }) })
|
|
32709
32789
|
] }, sp.id)),
|
|
32710
|
-
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(
|
|
32790
|
+
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(React128.Fragment, { children: [
|
|
32711
32791
|
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: 5, className: "p-2 px-3", children: /* @__PURE__ */ jsxs(
|
|
32712
32792
|
"button",
|
|
32713
32793
|
{
|
|
@@ -32722,7 +32802,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
32722
32802
|
) }) }),
|
|
32723
32803
|
!collapsed.has(groupName) && groupFeatures.map((feature) => /* @__PURE__ */ jsxs("tr", { className: "hover:bg-muted/30", children: [
|
|
32724
32804
|
/* @__PURE__ */ jsx("td", { className: "p-3 text-sm font-medium", children: feature.label }),
|
|
32725
|
-
|
|
32805
|
+
ACTIONS3.map((action) => /* @__PURE__ */ jsx("td", { className: "p-3 text-center", children: /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(
|
|
32726
32806
|
Checkbox,
|
|
32727
32807
|
{
|
|
32728
32808
|
checked: grants[feature.id]?.includes(action) ?? false,
|
|
@@ -32779,12 +32859,12 @@ function PermissionProfilesTab() {
|
|
|
32779
32859
|
const startImpersonation = usePermissionsStore((s) => s.startImpersonation);
|
|
32780
32860
|
const canPreview = (realProfile?.systemPermissions ?? []).includes("manage_permissions") ?? false;
|
|
32781
32861
|
const { t } = useTranslation$1();
|
|
32782
|
-
const [editingProfile, setEditingProfile] =
|
|
32783
|
-
const [creating, setCreating] =
|
|
32784
|
-
const [duplicateSource, setDuplicateSource] =
|
|
32785
|
-
const [saving, setSaving] =
|
|
32786
|
-
const [error, setError] =
|
|
32787
|
-
const [deleting, setDeleting] =
|
|
32862
|
+
const [editingProfile, setEditingProfile] = React128.useState(null);
|
|
32863
|
+
const [creating, setCreating] = React128.useState(false);
|
|
32864
|
+
const [duplicateSource, setDuplicateSource] = React128.useState(null);
|
|
32865
|
+
const [saving, setSaving] = React128.useState(false);
|
|
32866
|
+
const [error, setError] = React128.useState(null);
|
|
32867
|
+
const [deleting, setDeleting] = React128.useState(null);
|
|
32788
32868
|
const handleDuplicate = (profile) => {
|
|
32789
32869
|
setEditingProfile(null);
|
|
32790
32870
|
setCreating(false);
|
|
@@ -32794,9 +32874,9 @@ function PermissionProfilesTab() {
|
|
|
32794
32874
|
isSystem: false
|
|
32795
32875
|
});
|
|
32796
32876
|
};
|
|
32797
|
-
const surfaceRef =
|
|
32877
|
+
const surfaceRef = React128.useRef({ features, profiles, adapter, currentOrg, setProfiles });
|
|
32798
32878
|
surfaceRef.current = { features, profiles, adapter, currentOrg, setProfiles };
|
|
32799
|
-
const agentSurface =
|
|
32879
|
+
const agentSurface = React128.useMemo(() => ({
|
|
32800
32880
|
id: "org.permissions",
|
|
32801
32881
|
instructions: PERMISSIONS_INSTRUCTIONS,
|
|
32802
32882
|
describe: () => {
|
|
@@ -32850,7 +32930,7 @@ function PermissionProfilesTab() {
|
|
|
32850
32930
|
}]
|
|
32851
32931
|
}), []);
|
|
32852
32932
|
useAgentSurface(agentSurface);
|
|
32853
|
-
const createActions =
|
|
32933
|
+
const createActions = React128.useMemo(() => [
|
|
32854
32934
|
{
|
|
32855
32935
|
id: "new",
|
|
32856
32936
|
label: t("organization.permissions.createProfile"),
|
|
@@ -32879,7 +32959,7 @@ function PermissionProfilesTab() {
|
|
|
32879
32959
|
})
|
|
32880
32960
|
}
|
|
32881
32961
|
], [t]);
|
|
32882
|
-
const memberCountByProfile =
|
|
32962
|
+
const memberCountByProfile = React128.useMemo(() => {
|
|
32883
32963
|
const counts = {};
|
|
32884
32964
|
for (const m of members) {
|
|
32885
32965
|
counts[m.profileId] = (counts[m.profileId] ?? 0) + 1;
|
|
@@ -33184,7 +33264,7 @@ function FieldRulesSettings({ entities, rules: initialRules, onSave }) {
|
|
|
33184
33264
|
const [saving, setSaving] = useState(false);
|
|
33185
33265
|
const [search, setSearch] = useState("");
|
|
33186
33266
|
const [showMore, setShowMore] = useState(false);
|
|
33187
|
-
|
|
33267
|
+
React128.useEffect(() => {
|
|
33188
33268
|
setDraft(initialRules);
|
|
33189
33269
|
}, [initialRules]);
|
|
33190
33270
|
const isDirty = useMemo(
|
|
@@ -33584,19 +33664,19 @@ function SoftLimitWidget() {
|
|
|
33584
33664
|
function LimitProbe({ limitKey }) {
|
|
33585
33665
|
const info = useLimit(limitKey);
|
|
33586
33666
|
const report = useSoftLimitStore((s) => s.report);
|
|
33587
|
-
|
|
33667
|
+
React128.useEffect(() => {
|
|
33588
33668
|
report(limitKey, info);
|
|
33589
33669
|
}, [limitKey, info, report]);
|
|
33590
33670
|
return null;
|
|
33591
33671
|
}
|
|
33592
33672
|
function SoftLimitProbes({ keys }) {
|
|
33593
|
-
const monitored =
|
|
33673
|
+
const monitored = React128.useMemo(() => Array.from(new Set(keys)), [keys]);
|
|
33594
33674
|
return /* @__PURE__ */ jsx(Fragment, { children: monitored.map((k) => /* @__PURE__ */ jsx(LimitProbe, { limitKey: k }, k)) });
|
|
33595
33675
|
}
|
|
33596
|
-
var CommandPalette =
|
|
33676
|
+
var CommandPalette = React128.lazy(
|
|
33597
33677
|
() => import('./CommandPalette-B5PMQFDG.js').then((m) => ({ default: m.CommandPalette }))
|
|
33598
33678
|
);
|
|
33599
|
-
var SubscriptionPage =
|
|
33679
|
+
var SubscriptionPage = React128.lazy(
|
|
33600
33680
|
() => import('./SubscriptionPage-2WK57426.js').then((m) => ({ default: m.SubscriptionPage }))
|
|
33601
33681
|
);
|
|
33602
33682
|
function WorkspaceSwitcher({
|
|
@@ -33646,8 +33726,8 @@ function WorkspaceSwitcher({
|
|
|
33646
33726
|
const v = t(key);
|
|
33647
33727
|
return !v || v === key ? fallback : v;
|
|
33648
33728
|
};
|
|
33649
|
-
const [query, setQuery] =
|
|
33650
|
-
const search =
|
|
33729
|
+
const [query, setQuery] = React128.useState("");
|
|
33730
|
+
const search = React128.useMemo(
|
|
33651
33731
|
() => searchWorkspaces(
|
|
33652
33732
|
options,
|
|
33653
33733
|
query,
|
|
@@ -33961,9 +34041,9 @@ function PluginHeaderControls() {
|
|
|
33961
34041
|
}
|
|
33962
34042
|
function AdminNotifications() {
|
|
33963
34043
|
const { notifications, unreadCount, fetchNotifications, markAsRead, markAllAsRead } = useNotifications();
|
|
33964
|
-
const [open, setOpen] =
|
|
33965
|
-
const fetchedRef =
|
|
33966
|
-
|
|
34044
|
+
const [open, setOpen] = React128.useState(false);
|
|
34045
|
+
const fetchedRef = React128.useRef(false);
|
|
34046
|
+
React128.useEffect(() => {
|
|
33967
34047
|
if (fetchedRef.current) return;
|
|
33968
34048
|
fetchedRef.current = true;
|
|
33969
34049
|
void fetchNotifications();
|
|
@@ -34109,7 +34189,7 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
34109
34189
|
// sidebar ICON_MAP, which made the settings rail fall back to Home.
|
|
34110
34190
|
icon: /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
|
|
34111
34191
|
iconName: "CreditCard",
|
|
34112
|
-
component: /* @__PURE__ */ jsx(
|
|
34192
|
+
component: /* @__PURE__ */ jsx(React128.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(SubscriptionPage, {}) })
|
|
34113
34193
|
});
|
|
34114
34194
|
}
|
|
34115
34195
|
if (showOrgSettings) {
|
|
@@ -34137,9 +34217,9 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
34137
34217
|
settingsTabs.push({
|
|
34138
34218
|
id: tab.id,
|
|
34139
34219
|
label: translated === labelKey ? tab.label : translated,
|
|
34140
|
-
icon:
|
|
34220
|
+
icon: React128.createElement(IconComp, { className: "h-4 w-4" }),
|
|
34141
34221
|
iconName,
|
|
34142
|
-
component:
|
|
34222
|
+
component: React128.createElement(tab.component),
|
|
34143
34223
|
// Flag plugin-contributed tabs so SettingsPage draws the core/plugins divider.
|
|
34144
34224
|
isPlugin: true,
|
|
34145
34225
|
group: tab.group,
|
|
@@ -34165,6 +34245,7 @@ function dedupeByRoute(items) {
|
|
|
34165
34245
|
return [...porRota.values()];
|
|
34166
34246
|
}
|
|
34167
34247
|
function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar", logo, markLogo, pages = [], showSettings = true, showOrgSettings = false, showBranding = true, hiddenSettingsTabs, settingsGroups, showOrgSwitcher = true, setup = "wizard", contentFrame = true, moduleNav, bottomNav, onBottomNavAction, mobileHeader, shellMounts = [], sidebarFooter, navChildConnector, site, locales, trialDays }) {
|
|
34248
|
+
setPrintBrand(appName);
|
|
34168
34249
|
const runtime = usePluginRuntime();
|
|
34169
34250
|
const t = useTranslation();
|
|
34170
34251
|
const can = usePermissionOptional();
|
|
@@ -34190,12 +34271,12 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34190
34271
|
profileKnown: !activeTenantId || profileKnownFor === activeTenantId
|
|
34191
34272
|
});
|
|
34192
34273
|
const navError = configError ?? tenantCtx?.loadError ?? null;
|
|
34193
|
-
const onNavRetry =
|
|
34274
|
+
const onNavRetry = React128.useCallback(() => {
|
|
34194
34275
|
if (tenantCtx?.loadError) tenantCtx.retryOrgs();
|
|
34195
34276
|
else window.location.reload();
|
|
34196
34277
|
}, [tenantCtx]);
|
|
34197
34278
|
const currentProfile = usePermissionsStore((s) => s.currentProfile);
|
|
34198
|
-
const hasSystem =
|
|
34279
|
+
const hasSystem = React128.useCallback(
|
|
34199
34280
|
(perm) => {
|
|
34200
34281
|
if (!currentProfile) return false;
|
|
34201
34282
|
if (currentProfile.id === "owner" || currentProfile.name?.toLowerCase() === "owner") return true;
|
|
@@ -34209,8 +34290,8 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34209
34290
|
};
|
|
34210
34291
|
const path = useAdminPath();
|
|
34211
34292
|
const { user, signOut } = useAuth();
|
|
34212
|
-
|
|
34213
|
-
|
|
34293
|
+
React128.useEffect(() => installGlobalErrorHandlers(), []);
|
|
34294
|
+
React128.useEffect(() => registerErrorReporter((report) => {
|
|
34214
34295
|
if (report.source !== "data") return;
|
|
34215
34296
|
const alvo = report.extra?.operation;
|
|
34216
34297
|
toast.error(
|
|
@@ -34228,15 +34309,15 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34228
34309
|
const hasChatPanel = useRightRailStore((s) => s.panels.some((pn) => pn.id === "chat"));
|
|
34229
34310
|
const rightRail = railHasPanels ? /* @__PURE__ */ jsx(RightRail, { frame: contentFrame, attached: layout !== "topbar" }) : null;
|
|
34230
34311
|
const setRailMounted = useRightRailStore((s) => s.setMounted);
|
|
34231
|
-
|
|
34312
|
+
React128.useEffect(() => {
|
|
34232
34313
|
setRailMounted(true);
|
|
34233
34314
|
return () => setRailMounted(false);
|
|
34234
34315
|
}, [setRailMounted]);
|
|
34235
34316
|
useConnectorOAuthReturn();
|
|
34236
34317
|
const railWidthLive = useRightRailStore((s) => s.width);
|
|
34237
34318
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
34238
|
-
const railAutoCollapsedRef =
|
|
34239
|
-
|
|
34319
|
+
const railAutoCollapsedRef = React128.useRef(false);
|
|
34320
|
+
React128.useEffect(() => {
|
|
34240
34321
|
if (layout !== "sidebar") return;
|
|
34241
34322
|
const SIDEBAR_EXPANDED = 224;
|
|
34242
34323
|
const MIN_CONTENT = 620;
|
|
@@ -34258,22 +34339,22 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34258
34339
|
window.addEventListener("resize", apply);
|
|
34259
34340
|
return () => window.removeEventListener("resize", apply);
|
|
34260
34341
|
}, [railOpen, railWidthLive, layout, setSidebarCollapsed]);
|
|
34261
|
-
const [railWidth] =
|
|
34342
|
+
const [railWidth] = React128.useState(() => readRightRailWidth());
|
|
34262
34343
|
const billingPlans = useBillingStore((s) => s.plans);
|
|
34263
34344
|
const hasBilling = billingPlans.length > 0;
|
|
34264
34345
|
const orgPlan = useTenantOptional()?.org?.plan;
|
|
34265
|
-
const planBadge =
|
|
34346
|
+
const planBadge = React128.useMemo(
|
|
34266
34347
|
() => hasBilling ? resolvePlanBadge(orgPlan, billingPlans) : null,
|
|
34267
34348
|
[hasBilling, orgPlan, billingPlans]
|
|
34268
34349
|
);
|
|
34269
|
-
const softLimitKeys =
|
|
34350
|
+
const softLimitKeys = React128.useMemo(() => {
|
|
34270
34351
|
const plan = billingPlans.find((p) => p.id === (orgPlan || "free"));
|
|
34271
34352
|
return Object.keys(getPlanEntitlements(plan)?.limits ?? {});
|
|
34272
34353
|
}, [billingPlans, orgPlan]);
|
|
34273
34354
|
const overshoots = useOvershoots();
|
|
34274
34355
|
const navContributions = useNavContributionsStore((s) => s.contributions);
|
|
34275
34356
|
const appConfigNav = useAppConfigStore((state) => state.config.nav);
|
|
34276
|
-
const navigation =
|
|
34357
|
+
const navigation = React128.useMemo(() => {
|
|
34277
34358
|
const contributed = Object.values(navContributions).flat();
|
|
34278
34359
|
const flat = dedupeByRoute(
|
|
34279
34360
|
[...runtime.navigation, ...contributed].map((entry) => ({
|
|
@@ -34344,7 +34425,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34344
34425
|
}).filter((item) => item !== null).sort(compareNavigation);
|
|
34345
34426
|
return applyRailPreset(gated, presetRail, presetHide, presetWhole);
|
|
34346
34427
|
}, [runtime.navigation, runtime.routes, navContributions, pages, access, navWaiting, presetRail, presetHide, presetWhole, presetLabels]);
|
|
34347
|
-
const composedNavigation =
|
|
34428
|
+
const composedNavigation = React128.useMemo(() => {
|
|
34348
34429
|
if (!appConfigNav.length) return navigation;
|
|
34349
34430
|
const keyed = navigation.map((item) => ({ ...item, key: item.route }));
|
|
34350
34431
|
return applyNavComposition(keyed, appConfigNav).map((item) => {
|
|
@@ -34360,13 +34441,13 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34360
34441
|
};
|
|
34361
34442
|
});
|
|
34362
34443
|
}, [navigation, appConfigNav]);
|
|
34363
|
-
const resolvedBottomNav =
|
|
34444
|
+
const resolvedBottomNav = React128.useMemo(
|
|
34364
34445
|
() => deriveBottomNav(navigation, bottomNav, { assistant: hasChatPanel }),
|
|
34365
34446
|
[navigation, bottomNav, hasChatPanel]
|
|
34366
34447
|
);
|
|
34367
34448
|
const commandPaletteOpen = useLayoutStore((s) => s.commandPaletteOpen);
|
|
34368
34449
|
const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
|
|
34369
|
-
const commandItems =
|
|
34450
|
+
const commandItems = React128.useMemo(() => {
|
|
34370
34451
|
const navGroup = tr("layout.commandPalette.navigation", "Navigation");
|
|
34371
34452
|
const items = [];
|
|
34372
34453
|
for (const nav of navigation) {
|
|
@@ -34378,7 +34459,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34378
34459
|
return items;
|
|
34379
34460
|
}, [navigation]);
|
|
34380
34461
|
const globalSearch = useGlobalSearch();
|
|
34381
|
-
const routes =
|
|
34462
|
+
const routes = React128.useMemo(() => {
|
|
34382
34463
|
const list = [];
|
|
34383
34464
|
const entityRouteMap = /* @__PURE__ */ new Map();
|
|
34384
34465
|
for (const r of runtime.routes) {
|
|
@@ -34401,14 +34482,14 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34401
34482
|
setEntityRouteMap(entityRouteMap);
|
|
34402
34483
|
return list.sort((a, b) => routeScore(b.path) - routeScore(a.path));
|
|
34403
34484
|
}, [runtime.routes, pages, showSettings]);
|
|
34404
|
-
const match =
|
|
34485
|
+
const match = React128.useMemo(() => {
|
|
34405
34486
|
for (const r of routes) {
|
|
34406
34487
|
const params = matchRoute(r.path, path);
|
|
34407
34488
|
if (params) return { route: r, params };
|
|
34408
34489
|
}
|
|
34409
34490
|
return null;
|
|
34410
34491
|
}, [routes, path]);
|
|
34411
|
-
|
|
34492
|
+
React128.useEffect(() => {
|
|
34412
34493
|
if (!match && (path === "/" || path === "") && navigation.length > 0) {
|
|
34413
34494
|
navigateTo(navigation[0].route);
|
|
34414
34495
|
}
|
|
@@ -34416,11 +34497,11 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34416
34497
|
const ActiveComponent = match?.route.Component;
|
|
34417
34498
|
const activeParams = match?.params ?? {};
|
|
34418
34499
|
const routeKey = (match?.route.path ?? path).replace(/\/\*$/, "");
|
|
34419
|
-
const settingsTabs =
|
|
34500
|
+
const settingsTabs = React128.useMemo(
|
|
34420
34501
|
() => buildSettingsTabs(runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling),
|
|
34421
34502
|
[runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling]
|
|
34422
34503
|
);
|
|
34423
|
-
const profileRoute =
|
|
34504
|
+
const profileRoute = React128.useMemo(() => {
|
|
34424
34505
|
const explicit = routes.find((r) => r.path === "/perfil" || r.path === "/profile");
|
|
34425
34506
|
if (explicit) return explicit.path;
|
|
34426
34507
|
return showSettings ? "/settings/profile" : null;
|
|
@@ -34429,8 +34510,8 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34429
34510
|
const onBilling = hasBilling && showSettings ? () => navigateTo("/settings/subscription") : void 0;
|
|
34430
34511
|
const coreSettingsTabs = useCoreSettingsTabs({ showCompany: showBranding, showBranding });
|
|
34431
34512
|
const catalog = useModuleCatalog();
|
|
34432
|
-
const verticalByPlugin =
|
|
34433
|
-
const allSettingsTabs =
|
|
34513
|
+
const verticalByPlugin = React128.useMemo(() => pluginVerticalIndex(catalog), [catalog]);
|
|
34514
|
+
const allSettingsTabs = React128.useMemo(
|
|
34434
34515
|
() => {
|
|
34435
34516
|
const hidden = new Set(hiddenSettingsTabs ?? []);
|
|
34436
34517
|
const visible = [...coreSettingsTabs, ...settingsTabs].filter((tab) => !hidden.has(tab.id));
|
|
@@ -34453,7 +34534,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34453
34534
|
[coreSettingsTabs, settingsTabs, hiddenSettingsTabs, settingsGroups, verticalByPlugin]
|
|
34454
34535
|
);
|
|
34455
34536
|
usePublishSettingsTabs(allSettingsTabs.map((tab) => tab.id));
|
|
34456
|
-
const navWithSettings =
|
|
34537
|
+
const navWithSettings = React128.useMemo(() => {
|
|
34457
34538
|
if (!showSettings || allSettingsTabs.length === 0) return composedNavigation;
|
|
34458
34539
|
if (composedNavigation.some((item) => item.route === "/settings")) return composedNavigation;
|
|
34459
34540
|
return [...composedNavigation, {
|
|
@@ -34471,7 +34552,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34471
34552
|
const moduleRail = !inSettings && layout === "sidebar" && contextualNav && (path === contextualNav.base || path.startsWith(contextualNav.base + "/")) ? contextualNav : null;
|
|
34472
34553
|
const settingsPathActive = showSettings && (path === "/settings" || path.startsWith("/settings/"));
|
|
34473
34554
|
const activeSettingsTab = settingsPathActive ? path === "/settings" ? null : path.slice("/settings/".length).split("/")[0] : void 0;
|
|
34474
|
-
const settingsTabDef =
|
|
34555
|
+
const settingsTabDef = React128.useMemo(() => {
|
|
34475
34556
|
if (!showSettings || !path.startsWith("/settings/")) return void 0;
|
|
34476
34557
|
const id = path.slice("/settings/".length).split("/")[0];
|
|
34477
34558
|
return allSettingsTabs.find((tab) => tab.id === id);
|
|
@@ -34479,11 +34560,11 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34479
34560
|
const shellUser = user ? { fullName: user.fullName ?? user.email, email: user.email, avatarUrl: user.avatarUrl } : void 0;
|
|
34480
34561
|
const moduleVariant = moduleNav ?? (layout === "sidebar" ? "tabs" : "rail");
|
|
34481
34562
|
const setRailAvailable = useContextualNavStore((s) => s.setRailAvailable);
|
|
34482
|
-
|
|
34563
|
+
React128.useEffect(() => {
|
|
34483
34564
|
setRailAvailable(layout === "sidebar" && moduleVariant !== "rail");
|
|
34484
34565
|
}, [layout, moduleVariant, setRailAvailable]);
|
|
34485
34566
|
const moduleViewLabel = useModuleViewLabel();
|
|
34486
|
-
const activePageTitle =
|
|
34567
|
+
const activePageTitle = React128.useMemo(() => {
|
|
34487
34568
|
if (settingsTabDef) return settingsTabDef.label;
|
|
34488
34569
|
if (path === "/settings" || path.startsWith("/settings/")) return tr("common.settings", "Settings");
|
|
34489
34570
|
if (moduleViewLabel) return moduleViewLabel;
|
|
@@ -34498,7 +34579,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34498
34579
|
if (hiddenHit?.label) return hiddenHit.label;
|
|
34499
34580
|
return candidates.find((n) => n.route === "/")?.label ?? "";
|
|
34500
34581
|
}, [navigation, pages, path, tr, match, settingsTabDef, moduleViewLabel]);
|
|
34501
|
-
const parentBack =
|
|
34582
|
+
const parentBack = React128.useMemo(() => {
|
|
34502
34583
|
if (settingsTabDef) {
|
|
34503
34584
|
const first = allSettingsTabs[0]?.id;
|
|
34504
34585
|
return {
|
|
@@ -34541,9 +34622,9 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34541
34622
|
]
|
|
34542
34623
|
}
|
|
34543
34624
|
);
|
|
34544
|
-
const [railQuery, setRailQuery] =
|
|
34625
|
+
const [railQuery, setRailQuery] = React128.useState("");
|
|
34545
34626
|
const railBase = moduleRail?.base ?? null;
|
|
34546
|
-
|
|
34627
|
+
React128.useEffect(() => {
|
|
34547
34628
|
setRailQuery("");
|
|
34548
34629
|
}, [railBase]);
|
|
34549
34630
|
const railSearch = (placeholder) => /* @__PURE__ */ jsxs("div", { className: "relative px-0.5 pt-1", children: [
|
|
@@ -34747,7 +34828,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34747
34828
|
]
|
|
34748
34829
|
}
|
|
34749
34830
|
),
|
|
34750
|
-
/* @__PURE__ */ jsx(
|
|
34831
|
+
/* @__PURE__ */ jsx(React128.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
34751
34832
|
CommandPalette,
|
|
34752
34833
|
{
|
|
34753
34834
|
commands: commandItems,
|
|
@@ -35014,7 +35095,7 @@ function buildI18nConfig(config) {
|
|
|
35014
35095
|
function BillingInitializer({ config }) {
|
|
35015
35096
|
const setPlans = useBillingStore((s) => s.setPlans);
|
|
35016
35097
|
const setCheckout = useBillingStore((s) => s.setCheckout);
|
|
35017
|
-
|
|
35098
|
+
React128.useEffect(() => {
|
|
35018
35099
|
if (config.billing?.plans) setPlans(config.billing.plans.map(normalizeBillingPlan));
|
|
35019
35100
|
setCheckout(config.billing?.onCheckout ?? null);
|
|
35020
35101
|
}, [config.billing, setPlans, setCheckout]);
|
|
@@ -35133,13 +35214,13 @@ function ThemeInitializer({ config }) {
|
|
|
35133
35214
|
const rawBranding = useOrganizationStore((s) => s.currentOrg?.settings?.branding);
|
|
35134
35215
|
const access = useAccessOptional();
|
|
35135
35216
|
const wearsOwnSkin = access.entitled("branding.theme");
|
|
35136
|
-
const brandTokens =
|
|
35217
|
+
const brandTokens = React128.useMemo(
|
|
35137
35218
|
() => wearsOwnSkin ? normalizeBrand(rawBranding).tokens : EMPTY_BRAND.tokens,
|
|
35138
35219
|
[rawBranding, wearsOwnSkin]
|
|
35139
35220
|
);
|
|
35140
35221
|
const brandKey = JSON.stringify(brandTokens);
|
|
35141
35222
|
const appTheme = useAppTheme();
|
|
35142
|
-
|
|
35223
|
+
React128.useEffect(() => {
|
|
35143
35224
|
const tokens = JSON.parse(brandKey);
|
|
35144
35225
|
const brand = tokens.color?.primary ? hexToHslTriplet(tokens.color.primary) : null;
|
|
35145
35226
|
const base = appTheme ?? config.theme;
|
|
@@ -35157,20 +35238,20 @@ function ThemeInitializer({ config }) {
|
|
|
35157
35238
|
return null;
|
|
35158
35239
|
}
|
|
35159
35240
|
function PersistentCacheInitializer() {
|
|
35160
|
-
|
|
35241
|
+
React128.useEffect(() => {
|
|
35161
35242
|
attachPersistentCache();
|
|
35162
35243
|
void getPersistentCache()?.hydrate();
|
|
35163
35244
|
}, []);
|
|
35164
35245
|
return null;
|
|
35165
35246
|
}
|
|
35166
35247
|
function FayzEventBridgeInitializer({ config }) {
|
|
35167
|
-
|
|
35248
|
+
React128.useEffect(() => startFayzEventBridge(config.chat?.agent), [config.chat?.agent]);
|
|
35168
35249
|
return null;
|
|
35169
35250
|
}
|
|
35170
35251
|
function TeamInitializer({ config }) {
|
|
35171
35252
|
const setTeamPersonKinds = useOrganizationStore((s) => s.setTeamPersonKinds);
|
|
35172
35253
|
const kinds = config.team?.personKinds;
|
|
35173
|
-
|
|
35254
|
+
React128.useEffect(() => {
|
|
35174
35255
|
setTeamPersonKinds(kinds ?? []);
|
|
35175
35256
|
}, [setTeamPersonKinds, kinds]);
|
|
35176
35257
|
return null;
|
|
@@ -35187,7 +35268,7 @@ function ChatRailPanel({ config }) {
|
|
|
35187
35268
|
const agent = config.chat?.agent;
|
|
35188
35269
|
const voice = config.chat?.voice;
|
|
35189
35270
|
const whatsapp = config.chat?.whatsapp;
|
|
35190
|
-
const Component2 =
|
|
35271
|
+
const Component2 = React128.useMemo(() => {
|
|
35191
35272
|
const Panel = () => /* @__PURE__ */ jsx(
|
|
35192
35273
|
ChatConversation,
|
|
35193
35274
|
{
|
|
@@ -35204,8 +35285,8 @@ function ChatRailPanel({ config }) {
|
|
|
35204
35285
|
const conversations = useChatStore((s) => s.conversations);
|
|
35205
35286
|
const setConversations = useChatStore((s) => s.setConversations);
|
|
35206
35287
|
const user = useAuthStore((s) => s.user);
|
|
35207
|
-
const connection =
|
|
35208
|
-
|
|
35288
|
+
const connection = React128.useMemo(() => resolveFayzAgentConnection(agent), [agent]);
|
|
35289
|
+
React128.useEffect(() => {
|
|
35209
35290
|
if (!connection) return;
|
|
35210
35291
|
getFayzAgentClient(connection).listConversations(user?.id).then(setConversations).catch(() => {
|
|
35211
35292
|
});
|
|
@@ -35214,7 +35295,7 @@ function ChatRailPanel({ config }) {
|
|
|
35214
35295
|
useAssistantInviteStore((s) => s.invite?.id === ASK_AI_HANDOFF_ID);
|
|
35215
35296
|
const activeAgent = useAgent();
|
|
35216
35297
|
const persona = activeAgent?.name ?? invitePersona;
|
|
35217
|
-
const icon =
|
|
35298
|
+
const icon = React128.useMemo(
|
|
35218
35299
|
() => activeAgent ? function AgentTabIcon() {
|
|
35219
35300
|
return /* @__PURE__ */ jsx(
|
|
35220
35301
|
AgentAvatar,
|
|
@@ -35229,7 +35310,7 @@ function ChatRailPanel({ config }) {
|
|
|
35229
35310
|
[activeAgent]
|
|
35230
35311
|
);
|
|
35231
35312
|
useRightRailPanel(
|
|
35232
|
-
|
|
35313
|
+
React128.useMemo(
|
|
35233
35314
|
() => ({
|
|
35234
35315
|
id: "chat",
|
|
35235
35316
|
// "Chat" nomeia o CANO, não o que está do outro lado — e era a única
|
|
@@ -35245,22 +35326,22 @@ function ChatRailPanel({ config }) {
|
|
|
35245
35326
|
[Component2, conversations.length, persona, icon, activeAgent, t]
|
|
35246
35327
|
)
|
|
35247
35328
|
);
|
|
35248
|
-
|
|
35329
|
+
React128.useEffect(() => {
|
|
35249
35330
|
if (chatOpen) openPanel("chat");
|
|
35250
35331
|
}, [chatOpen, openPanel]);
|
|
35251
|
-
|
|
35332
|
+
React128.useEffect(() => {
|
|
35252
35333
|
if (!(railOpen && railActive === "chat")) setChatOpen(false);
|
|
35253
35334
|
}, [railOpen, railActive, setChatOpen]);
|
|
35254
35335
|
return null;
|
|
35255
35336
|
}
|
|
35256
35337
|
function AdminProviders({ config, children }) {
|
|
35257
35338
|
const currentOrg = useOrganizationStore((s) => s.currentOrg);
|
|
35258
|
-
const hasFayzAgent =
|
|
35339
|
+
const hasFayzAgent = React128.useMemo(
|
|
35259
35340
|
() => !!resolveFayzAgentConnection(config.chat?.agent),
|
|
35260
35341
|
[config.chat?.agent]
|
|
35261
35342
|
);
|
|
35262
35343
|
const assistantEnabled = config.chat?.enabled !== false && (!!config.chat || hasFayzAgent);
|
|
35263
|
-
|
|
35344
|
+
React128.useEffect(() => {
|
|
35264
35345
|
if (!config.chat || config.chat.enabled === false || config.chat.apiEndpoint || hasFayzAgent) return;
|
|
35265
35346
|
const gap = describeFayzAgentGap(config.chat.agent);
|
|
35266
35347
|
if (!gap) return;
|
|
@@ -35272,7 +35353,7 @@ function AdminProviders({ config, children }) {
|
|
|
35272
35353
|
const surface = config.chat?.surface ?? "dock";
|
|
35273
35354
|
const onConsentScreen = typeof window !== "undefined" && window.location.pathname.replace(/\/+$/, "").endsWith("/connect");
|
|
35274
35355
|
const showFab = assistantEnabled && surface === "dock" && !onConsentScreen;
|
|
35275
|
-
const resolved =
|
|
35356
|
+
const resolved = React128.useMemo(() => {
|
|
35276
35357
|
if (config.supabaseUrl && config.supabaseAnonKey) {
|
|
35277
35358
|
createFayzSupabaseClient(config.supabaseUrl, config.supabaseAnonKey);
|
|
35278
35359
|
}
|
|
@@ -35290,7 +35371,7 @@ function AdminProviders({ config, children }) {
|
|
|
35290
35371
|
const { bindings, ready: configReady } = useAppConfig();
|
|
35291
35372
|
const offeredPlugins = useOfferedPlugins();
|
|
35292
35373
|
const path = useAdminPath();
|
|
35293
|
-
const runtime =
|
|
35374
|
+
const runtime = React128.useMemo(
|
|
35294
35375
|
() => resolvePluginRuntime({
|
|
35295
35376
|
plugins: resolved.plugins,
|
|
35296
35377
|
// Só as ligações DESTA conta. Na janela da troca o config em mãos ainda
|
|
@@ -35330,7 +35411,7 @@ function AdminProviders({ config, children }) {
|
|
|
35330
35411
|
}),
|
|
35331
35412
|
[resolved.plugins, bindings, offeredPlugins, configReady, path, config.layout, currentOrg]
|
|
35332
35413
|
);
|
|
35333
|
-
|
|
35414
|
+
React128.useEffect(() => {
|
|
35334
35415
|
if (!import.meta.env?.DEV || !currentOrg) return;
|
|
35335
35416
|
const registered = new Set(resolved.plugins.map((p) => p.id));
|
|
35336
35417
|
const bound = new Set(bindings.map((b) => b.pluginId));
|
|
@@ -35684,8 +35765,8 @@ function manifestToFayzConfig(manifest, surfaceName) {
|
|
|
35684
35765
|
};
|
|
35685
35766
|
}
|
|
35686
35767
|
function AdminScaffold({ manifest, surface }) {
|
|
35687
|
-
const config =
|
|
35688
|
-
const authShellProps =
|
|
35768
|
+
const config = React128.useMemo(() => manifestToFayzConfig(manifest, surface), [manifest, surface]);
|
|
35769
|
+
const authShellProps = React128.useMemo(() => getAuthShellProps(config.auth), [config.auth]);
|
|
35689
35770
|
return /* @__PURE__ */ jsx(AdminProviders, { config, children: /* @__PURE__ */ jsx(ScaffoldShell, { config, authShellProps }) });
|
|
35690
35771
|
}
|
|
35691
35772
|
function ScaffoldShell({
|
|
@@ -35917,7 +35998,7 @@ var TONE_CLASS = {
|
|
|
35917
35998
|
info: "bg-sky-100 text-sky-800 dark:bg-sky-900/40 dark:text-sky-300",
|
|
35918
35999
|
muted: "bg-muted text-muted-foreground"
|
|
35919
36000
|
};
|
|
35920
|
-
function
|
|
36001
|
+
function Badge26({ badge, className = "" }) {
|
|
35921
36002
|
return (
|
|
35922
36003
|
// shrink-0: in the crumb it sits beside a truncating title, and without it
|
|
35923
36004
|
// a long record name eats the status instead of ellipsing itself.
|
|
@@ -35990,7 +36071,7 @@ function OrderDetailView(props) {
|
|
|
35990
36071
|
const hasBadges = badges.length > 0 || !!props.badgesNode;
|
|
35991
36072
|
const titleNode = hasBadges ? /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
35992
36073
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: title }),
|
|
35993
|
-
props.badgesNode ?? badges.map((b, i) => /* @__PURE__ */ jsx(
|
|
36074
|
+
props.badgesNode ?? badges.map((b, i) => /* @__PURE__ */ jsx(Badge26, { badge: b, className: i > 0 ? "hidden sm:inline-flex" : "" }, i))
|
|
35994
36075
|
] }) : title;
|
|
35995
36076
|
return (
|
|
35996
36077
|
// A coluna decide o layout, não a janela: com o assistente aberto ao lado,
|
|
@@ -36062,7 +36143,7 @@ function OrderDetailView(props) {
|
|
|
36062
36143
|
!receivable || receivable.rows.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: receivable?.emptyLabel ?? "Sem conta a receber." }) : /* @__PURE__ */ jsxs("div", { className: "text-sm", children: [
|
|
36063
36144
|
(receivable.referenceNumber || receivable.statusBadge) && /* @__PURE__ */ jsxs("div", { className: "mb-2 flex flex-wrap items-center gap-2", children: [
|
|
36064
36145
|
receivable.referenceNumber && /* @__PURE__ */ jsx("span", { className: "font-mono font-semibold", children: receivable.referenceNumber }),
|
|
36065
|
-
receivable.statusBadge && /* @__PURE__ */ jsx(
|
|
36146
|
+
receivable.statusBadge && /* @__PURE__ */ jsx(Badge26, { badge: receivable.statusBadge })
|
|
36066
36147
|
] }),
|
|
36067
36148
|
receivable.rows.map((r, i) => /* @__PURE__ */ jsx(OrderDetailRow, { label: r.label, value: r.value, strong: r.strong, muted: r.muted }, i)),
|
|
36068
36149
|
/* @__PURE__ */ jsx("div", { className: "mt-3 space-y-1.5 border-t pt-2", children: receivable.installments.map((inst) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -36123,9 +36204,9 @@ function LookupCreateInline({
|
|
|
36123
36204
|
className
|
|
36124
36205
|
}) {
|
|
36125
36206
|
const t = useTranslation();
|
|
36126
|
-
const [saving, setSaving] =
|
|
36127
|
-
const [error, setError] =
|
|
36128
|
-
const submitForm =
|
|
36207
|
+
const [saving, setSaving] = React128.useState(false);
|
|
36208
|
+
const [error, setError] = React128.useState(null);
|
|
36209
|
+
const submitForm = React128.useRef(null);
|
|
36129
36210
|
async function submit(data) {
|
|
36130
36211
|
setSaving(true);
|
|
36131
36212
|
setError(null);
|
|
@@ -36202,20 +36283,20 @@ function LookupCreateInline({
|
|
|
36202
36283
|
);
|
|
36203
36284
|
}
|
|
36204
36285
|
function useLookupCreate(lookup, onCreated, options = {}) {
|
|
36205
|
-
const [draftName, setDraftName] =
|
|
36286
|
+
const [draftName, setDraftName] = React128.useState(null);
|
|
36206
36287
|
const can = usePermissionOptional();
|
|
36207
36288
|
const entityDef = lookup?.entityDef;
|
|
36208
36289
|
const feature = entityDef?.permission?.feature;
|
|
36209
36290
|
const allowed = !feature || can(feature, "create");
|
|
36210
36291
|
const canCreate = !!lookup?.create && allowed;
|
|
36211
36292
|
const canEdit = !!entityDef && !!lookup?.load && !!lookup?.update && (!feature || can(feature, "edit"));
|
|
36212
|
-
const [editingId, setEditingId] =
|
|
36213
|
-
const onEdit =
|
|
36214
|
-
const createByName =
|
|
36293
|
+
const [editingId, setEditingId] = React128.useState(null);
|
|
36294
|
+
const onEdit = React128.useMemo(() => canEdit ? (id) => setEditingId(id) : void 0, [canEdit]);
|
|
36295
|
+
const createByName = React128.useCallback(async (name) => {
|
|
36215
36296
|
if (!lookup?.create) return;
|
|
36216
36297
|
onCreated(await lookup.create({ name }));
|
|
36217
36298
|
}, [lookup, onCreated]);
|
|
36218
|
-
const onCreate =
|
|
36299
|
+
const onCreate = React128.useMemo(() => {
|
|
36219
36300
|
if (!canCreate) return void 0;
|
|
36220
36301
|
if (!entityDef) return (name) => {
|
|
36221
36302
|
void createByName(name);
|
|
@@ -36291,7 +36372,8 @@ var ITEM_LABELS = {
|
|
|
36291
36372
|
done: "Conclu\xEDdo",
|
|
36292
36373
|
create: "Cadastrar",
|
|
36293
36374
|
clear: "Limpar",
|
|
36294
|
-
edit: "Editar"
|
|
36375
|
+
edit: "Editar",
|
|
36376
|
+
manage: "Gerenciar cadastro"
|
|
36295
36377
|
};
|
|
36296
36378
|
function OrderFormItemRow({
|
|
36297
36379
|
index,
|
|
@@ -36323,11 +36405,16 @@ function OrderFormItemRow({
|
|
|
36323
36405
|
const rawKindLabel = itemTypes.find((tp) => tp.value === itemKind)?.label ?? itemKind;
|
|
36324
36406
|
const kindLabel = !itemKind || itemKind === "other" ? null : rawKindLabel;
|
|
36325
36407
|
const hasAdjustments = (discount ?? 0) > 0 || (surcharge ?? 0) > 0;
|
|
36326
|
-
const [showAdjustments, setShowAdjustments] =
|
|
36327
|
-
const [openExtras, setOpenExtras] =
|
|
36408
|
+
const [showAdjustments, setShowAdjustments] = React128.useState(hasAdjustments);
|
|
36409
|
+
const [openExtras, setOpenExtras] = React128.useState(
|
|
36328
36410
|
() => (extraFieldGroups ?? []).filter((g) => g.filled).map((g) => g.id)
|
|
36329
36411
|
);
|
|
36330
36412
|
const lookup = entityLookups[itemKind];
|
|
36413
|
+
const awaitingCode = !!lookup?.byCode && !referenceId;
|
|
36414
|
+
const pickOnlyRow = pickOnly || awaitingCode;
|
|
36415
|
+
const can = usePermissionOptional();
|
|
36416
|
+
const manage = lookup?.manage;
|
|
36417
|
+
const canManage = !!manage && (!manage.permission || can(manage.permission.feature, manage.permission.action ?? "edit"));
|
|
36331
36418
|
const itemCreate = useLookupCreate(lookup, (created) => {
|
|
36332
36419
|
onChange({
|
|
36333
36420
|
referenceId: created.id,
|
|
@@ -36366,12 +36453,12 @@ function OrderFormItemRow({
|
|
|
36366
36453
|
},
|
|
36367
36454
|
g.id
|
|
36368
36455
|
)),
|
|
36369
|
-
!
|
|
36456
|
+
!pickOnlyRow && /* @__PURE__ */ jsxs("span", { className: "fz-tight-hide shrink-0 text-xs text-muted-foreground tabular-nums", children: [
|
|
36370
36457
|
quantity,
|
|
36371
36458
|
" \xD7 ",
|
|
36372
36459
|
formatMoney(unitPrice)
|
|
36373
36460
|
] }),
|
|
36374
|
-
!
|
|
36461
|
+
!pickOnlyRow && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-right text-sm font-semibold tabular-nums", children: formatMoney(total) }),
|
|
36375
36462
|
!readOnly && /* @__PURE__ */ jsx(
|
|
36376
36463
|
"button",
|
|
36377
36464
|
{
|
|
@@ -36400,7 +36487,20 @@ function OrderFormItemRow({
|
|
|
36400
36487
|
tp.value
|
|
36401
36488
|
)) }),
|
|
36402
36489
|
/* @__PURE__ */ jsxs("div", { className: "fz-fields fz-fields-2", children: [
|
|
36403
|
-
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: lookup ? /* @__PURE__ */ jsx(
|
|
36490
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: lookup?.byCode ? /* @__PURE__ */ jsx(
|
|
36491
|
+
CodeLookupField,
|
|
36492
|
+
{
|
|
36493
|
+
byCode: lookup.byCode,
|
|
36494
|
+
resolvedLabel: referenceId ? lookup.byCode.display?.({ description }) ?? description : null,
|
|
36495
|
+
clearLabel: l.clear,
|
|
36496
|
+
onResolved: (r) => onChange({
|
|
36497
|
+
referenceId: r.id,
|
|
36498
|
+
description: r.label,
|
|
36499
|
+
...r.price != null ? { unitPrice: r.price } : {}
|
|
36500
|
+
}),
|
|
36501
|
+
onClear: () => onChange({ referenceId: void 0, description: "", unitPrice: 0 })
|
|
36502
|
+
}
|
|
36503
|
+
) : lookup ? /* @__PURE__ */ jsx(
|
|
36404
36504
|
SearchSelect,
|
|
36405
36505
|
{
|
|
36406
36506
|
label: l.item,
|
|
@@ -36424,6 +36524,8 @@ function OrderFormItemRow({
|
|
|
36424
36524
|
onCreate: itemCreate.onCreate,
|
|
36425
36525
|
onEdit: itemCreate.onEdit,
|
|
36426
36526
|
editLabel: l.edit,
|
|
36527
|
+
onManage: canManage ? () => navigateTo(manage.route) : void 0,
|
|
36528
|
+
manageLabel: manage?.label ?? l.manage,
|
|
36427
36529
|
placeholder: `${l.item}\u2026`,
|
|
36428
36530
|
renderOption: (opt) => /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
36429
36531
|
/* @__PURE__ */ jsx("p", { className: "truncate text-sm", children: opt.label }),
|
|
@@ -36445,7 +36547,7 @@ function OrderFormItemRow({
|
|
|
36445
36547
|
}
|
|
36446
36548
|
)
|
|
36447
36549
|
] }) }),
|
|
36448
|
-
!
|
|
36550
|
+
!pickOnlyRow && /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 gap-3", children: [
|
|
36449
36551
|
/* @__PURE__ */ jsxs("div", { className: "w-16 shrink-0", children: [
|
|
36450
36552
|
/* @__PURE__ */ jsx("label", { className: "text-[10px] font-medium text-muted-foreground", children: l.qty }),
|
|
36451
36553
|
/* @__PURE__ */ jsx(
|
|
@@ -36473,7 +36575,7 @@ function OrderFormItemRow({
|
|
|
36473
36575
|
) })
|
|
36474
36576
|
] })
|
|
36475
36577
|
] }),
|
|
36476
|
-
showAdjustments && !
|
|
36578
|
+
showAdjustments && !pickOnlyRow && /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-3", children: [
|
|
36477
36579
|
/* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx(
|
|
36478
36580
|
CurrencyInput,
|
|
36479
36581
|
{
|
|
@@ -36511,7 +36613,7 @@ function OrderFormItemRow({
|
|
|
36511
36613
|
)
|
|
36512
36614
|
] }),
|
|
36513
36615
|
extraFields,
|
|
36514
|
-
!
|
|
36616
|
+
!pickOnlyRow && (!showAdjustments || (extraFieldGroups ?? []).some((g) => !openExtras.includes(g.id))) && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1.5", children: [
|
|
36515
36617
|
!showAdjustments && /* @__PURE__ */ jsxs(
|
|
36516
36618
|
"button",
|
|
36517
36619
|
{
|
|
@@ -36540,7 +36642,7 @@ function OrderFormItemRow({
|
|
|
36540
36642
|
g.id
|
|
36541
36643
|
))
|
|
36542
36644
|
] }),
|
|
36543
|
-
!
|
|
36645
|
+
!pickOnlyRow && (extraFieldGroups ?? []).filter((g) => openExtras.includes(g.id)).map((g) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
36544
36646
|
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: g.field }),
|
|
36545
36647
|
g.onClear && /* @__PURE__ */ jsx(
|
|
36546
36648
|
"button",
|
|
@@ -36556,7 +36658,7 @@ function OrderFormItemRow({
|
|
|
36556
36658
|
}
|
|
36557
36659
|
)
|
|
36558
36660
|
] }, g.id)),
|
|
36559
|
-
!
|
|
36661
|
+
!pickOnlyRow && /* @__PURE__ */ jsx("div", { className: "flex justify-end pt-1", children: /* @__PURE__ */ jsxs(
|
|
36560
36662
|
"button",
|
|
36561
36663
|
{
|
|
36562
36664
|
type: "button",
|
|
@@ -36573,6 +36675,73 @@ function OrderFormItemRow({
|
|
|
36573
36675
|
] });
|
|
36574
36676
|
}
|
|
36575
36677
|
OrderFormItemRow.displayName = "OrderFormItemRow";
|
|
36678
|
+
function CodeLookupField({ byCode, resolvedLabel, clearLabel, onResolved, onClear }) {
|
|
36679
|
+
const [code, setCode] = React128.useState("");
|
|
36680
|
+
const [busy, setBusy] = React128.useState(false);
|
|
36681
|
+
const [error, setError] = React128.useState(null);
|
|
36682
|
+
async function submit() {
|
|
36683
|
+
if (!code.trim() || busy) return;
|
|
36684
|
+
setBusy(true);
|
|
36685
|
+
setError(null);
|
|
36686
|
+
try {
|
|
36687
|
+
onResolved(await byCode.resolve(code));
|
|
36688
|
+
setCode("");
|
|
36689
|
+
} catch (e) {
|
|
36690
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
36691
|
+
} finally {
|
|
36692
|
+
setBusy(false);
|
|
36693
|
+
}
|
|
36694
|
+
}
|
|
36695
|
+
if (resolvedLabel) {
|
|
36696
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
36697
|
+
/* @__PURE__ */ jsx("label", { className: "text-[10px] font-medium text-muted-foreground", children: byCode.label }),
|
|
36698
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-0.5 flex items-center gap-2 rounded-input border border-input bg-muted/40 px-2.5 py-1.5", children: [
|
|
36699
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-sm", children: resolvedLabel }),
|
|
36700
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: onClear, "aria-label": clearLabel, className: "p-0.5 text-muted-foreground transition-colors hover:text-destructive", children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" }) })
|
|
36701
|
+
] })
|
|
36702
|
+
] });
|
|
36703
|
+
}
|
|
36704
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
36705
|
+
/* @__PURE__ */ jsx("label", { className: "text-[10px] font-medium text-muted-foreground", children: byCode.label }),
|
|
36706
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-0.5 flex gap-2", children: [
|
|
36707
|
+
/* @__PURE__ */ jsx(
|
|
36708
|
+
"input",
|
|
36709
|
+
{
|
|
36710
|
+
type: "text",
|
|
36711
|
+
value: code,
|
|
36712
|
+
autoFocus: true,
|
|
36713
|
+
autoComplete: "off",
|
|
36714
|
+
inputMode: "numeric",
|
|
36715
|
+
onChange: (e) => {
|
|
36716
|
+
setCode(e.target.value);
|
|
36717
|
+
setError(null);
|
|
36718
|
+
},
|
|
36719
|
+
onKeyDown: (e) => {
|
|
36720
|
+
if (e.key === "Enter") {
|
|
36721
|
+
e.preventDefault();
|
|
36722
|
+
void submit();
|
|
36723
|
+
}
|
|
36724
|
+
},
|
|
36725
|
+
placeholder: byCode.placeholder,
|
|
36726
|
+
"aria-invalid": !!error,
|
|
36727
|
+
className: "min-w-0 flex-1 rounded-input border border-input bg-card px-2.5 py-1.5 font-mono text-sm shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] focus:outline-none focus:ring-2 focus:ring-ring aria-[invalid=true]:border-destructive"
|
|
36728
|
+
}
|
|
36729
|
+
),
|
|
36730
|
+
/* @__PURE__ */ jsx(
|
|
36731
|
+
"button",
|
|
36732
|
+
{
|
|
36733
|
+
type: "button",
|
|
36734
|
+
onClick: () => void submit(),
|
|
36735
|
+
disabled: busy || !code.trim(),
|
|
36736
|
+
"aria-label": byCode.label,
|
|
36737
|
+
className: "fz-tap inline-flex shrink-0 items-center rounded-button border border-input bg-card px-2.5 text-muted-foreground transition-colors hover:text-foreground disabled:opacity-50",
|
|
36738
|
+
children: busy ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Search, { className: "h-4 w-4" })
|
|
36739
|
+
}
|
|
36740
|
+
)
|
|
36741
|
+
] }),
|
|
36742
|
+
error ? /* @__PURE__ */ jsx("p", { role: "alert", className: "mt-1 text-[11px] text-destructive", children: error }) : byCode.hint && /* @__PURE__ */ jsx("p", { className: "mt-1 text-[11px] text-muted-foreground", children: byCode.hint })
|
|
36743
|
+
] });
|
|
36744
|
+
}
|
|
36576
36745
|
function OrderFormAddItemStep({ itemTypes, onSelect, onCancel, label: label3 = "Que tipo de item?", cancelLabel = "Cancelar" }) {
|
|
36577
36746
|
return /* @__PURE__ */ jsxs("div", { className: "animate-in fade-in-0 slide-in-from-top-1 border-b bg-primary/5 px-4 py-3", children: [
|
|
36578
36747
|
/* @__PURE__ */ jsx("p", { className: "mb-2 text-xs font-medium text-muted-foreground", children: label3 }),
|
|
@@ -36730,13 +36899,13 @@ function OrderFormSkeleton({ parentLabel, onBack } = {}) {
|
|
|
36730
36899
|
] });
|
|
36731
36900
|
}
|
|
36732
36901
|
function useCatalogedItemTypes(itemTypes, lookups) {
|
|
36733
|
-
const countable =
|
|
36902
|
+
const countable = React128.useMemo(
|
|
36734
36903
|
() => itemTypes.filter((tp) => typeof lookups[tp.value]?.count === "function").map((tp) => tp.value),
|
|
36735
36904
|
[itemTypes, lookups]
|
|
36736
36905
|
);
|
|
36737
|
-
const [empty, setEmpty] =
|
|
36906
|
+
const [empty, setEmpty] = React128.useState([]);
|
|
36738
36907
|
const key = countable.join(",");
|
|
36739
|
-
|
|
36908
|
+
React128.useEffect(() => {
|
|
36740
36909
|
if (!countable.length) {
|
|
36741
36910
|
setEmpty([]);
|
|
36742
36911
|
return;
|
|
@@ -36755,7 +36924,7 @@ function useCatalogedItemTypes(itemTypes, lookups) {
|
|
|
36755
36924
|
cancelled = true;
|
|
36756
36925
|
};
|
|
36757
36926
|
}, [key, lookups]);
|
|
36758
|
-
return
|
|
36927
|
+
return React128.useMemo(
|
|
36759
36928
|
() => empty.length ? itemTypes.filter((tp) => !empty.includes(tp.value)) : itemTypes,
|
|
36760
36929
|
[itemTypes, empty]
|
|
36761
36930
|
);
|
|
@@ -37027,7 +37196,7 @@ function OrderCreateScreen({
|
|
|
37027
37196
|
errorActions,
|
|
37028
37197
|
saveBar
|
|
37029
37198
|
}) {
|
|
37030
|
-
const subtotal =
|
|
37199
|
+
const subtotal = React128.useMemo(
|
|
37031
37200
|
() => lines.reduce((sum, line) => sum + line.unitPrice * line.quantity, 0),
|
|
37032
37201
|
[lines]
|
|
37033
37202
|
);
|
|
@@ -37178,7 +37347,7 @@ function mergeLines(current2, incoming) {
|
|
|
37178
37347
|
return merged;
|
|
37179
37348
|
}
|
|
37180
37349
|
function ItemPicker({ search, onPick }) {
|
|
37181
|
-
const [open, setOpen] =
|
|
37350
|
+
const [open, setOpen] = React128.useState(false);
|
|
37182
37351
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
37183
37352
|
/* @__PURE__ */ jsxs(
|
|
37184
37353
|
"button",
|
|
@@ -37256,9 +37425,9 @@ function KanbanBoard({
|
|
|
37256
37425
|
toolbarActions
|
|
37257
37426
|
}) {
|
|
37258
37427
|
const collapsible = !!onToggleColumn;
|
|
37259
|
-
const frameRef =
|
|
37260
|
-
const [hoveredCol, setHoveredCol] =
|
|
37261
|
-
const centerFocused =
|
|
37428
|
+
const frameRef = React128.useRef(null);
|
|
37429
|
+
const [hoveredCol, setHoveredCol] = React128.useState(null);
|
|
37430
|
+
const centerFocused = React128.useCallback((event) => {
|
|
37262
37431
|
const frame = frameRef.current;
|
|
37263
37432
|
const column = event.target?.closest("[data-kanban-column]");
|
|
37264
37433
|
if (!frame || !column || frame.scrollWidth <= frame.clientWidth) return;
|
|
@@ -37267,14 +37436,14 @@ function KanbanBoard({
|
|
|
37267
37436
|
const delta = columnBox.left + columnBox.width / 2 - (frameBox.left + frameBox.width / 2);
|
|
37268
37437
|
if (Math.abs(delta) > 1) frame.scrollBy({ left: delta, behavior: "smooth" });
|
|
37269
37438
|
}, []);
|
|
37270
|
-
const autoScroll =
|
|
37271
|
-
const scrollStep =
|
|
37272
|
-
const stopAutoScroll =
|
|
37439
|
+
const autoScroll = React128.useRef(null);
|
|
37440
|
+
const scrollStep = React128.useRef(0);
|
|
37441
|
+
const stopAutoScroll = React128.useCallback(() => {
|
|
37273
37442
|
if (autoScroll.current !== null) cancelAnimationFrame(autoScroll.current);
|
|
37274
37443
|
autoScroll.current = null;
|
|
37275
37444
|
scrollStep.current = 0;
|
|
37276
37445
|
}, []);
|
|
37277
|
-
const tickAutoScroll =
|
|
37446
|
+
const tickAutoScroll = React128.useCallback(() => {
|
|
37278
37447
|
const frame = frameRef.current;
|
|
37279
37448
|
if (!frame || scrollStep.current === 0) {
|
|
37280
37449
|
stopAutoScroll();
|
|
@@ -37288,7 +37457,7 @@ function KanbanBoard({
|
|
|
37288
37457
|
}
|
|
37289
37458
|
autoScroll.current = requestAnimationFrame(tickAutoScroll);
|
|
37290
37459
|
}, [stopAutoScroll]);
|
|
37291
|
-
const onFrameDragOver =
|
|
37460
|
+
const onFrameDragOver = React128.useCallback((event) => {
|
|
37292
37461
|
const frame = frameRef.current;
|
|
37293
37462
|
if (!frame || frame.scrollWidth <= frame.clientWidth) return;
|
|
37294
37463
|
const box = frame.getBoundingClientRect();
|
|
@@ -37306,12 +37475,12 @@ function KanbanBoard({
|
|
|
37306
37475
|
}
|
|
37307
37476
|
if (autoScroll.current === null) autoScroll.current = requestAnimationFrame(tickAutoScroll);
|
|
37308
37477
|
}, [stopAutoScroll, tickAutoScroll]);
|
|
37309
|
-
const onFrameDragLeave =
|
|
37478
|
+
const onFrameDragLeave = React128.useCallback((event) => {
|
|
37310
37479
|
const indo = event.relatedTarget;
|
|
37311
37480
|
if (indo && event.currentTarget.contains(indo)) return;
|
|
37312
37481
|
stopAutoScroll();
|
|
37313
37482
|
}, [stopAutoScroll]);
|
|
37314
|
-
|
|
37483
|
+
React128.useEffect(() => stopAutoScroll, [stopAutoScroll]);
|
|
37315
37484
|
const hasToolbar = !!onSearchChange || !!onRefresh || !!toolbarActions;
|
|
37316
37485
|
const board = /* @__PURE__ */ jsx(
|
|
37317
37486
|
"div",
|
|
@@ -37419,10 +37588,10 @@ function BoardFrame({
|
|
|
37419
37588
|
toolbarActions,
|
|
37420
37589
|
className = ""
|
|
37421
37590
|
}) {
|
|
37422
|
-
const [open, setOpen] =
|
|
37423
|
-
const inputRef =
|
|
37591
|
+
const [open, setOpen] = React128.useState(false);
|
|
37592
|
+
const inputRef = React128.useRef(null);
|
|
37424
37593
|
const expanded = open || !!search;
|
|
37425
|
-
|
|
37594
|
+
React128.useEffect(() => {
|
|
37426
37595
|
if (open) inputRef.current?.focus();
|
|
37427
37596
|
}, [open]);
|
|
37428
37597
|
function collapse() {
|
|
@@ -37501,14 +37670,14 @@ function OrderBoardView({
|
|
|
37501
37670
|
rowId,
|
|
37502
37671
|
selectedRowId
|
|
37503
37672
|
}) {
|
|
37504
|
-
const getId =
|
|
37673
|
+
const getId = React128.useCallback(
|
|
37505
37674
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
37506
37675
|
[rowId]
|
|
37507
37676
|
);
|
|
37508
|
-
const [lastClicked, setLastClicked] =
|
|
37509
|
-
const [advancing, setAdvancing] =
|
|
37677
|
+
const [lastClicked, setLastClicked] = React128.useState(null);
|
|
37678
|
+
const [advancing, setAdvancing] = React128.useState({});
|
|
37510
37679
|
const selected = selectedRowId !== void 0 ? selectedRowId : lastClicked;
|
|
37511
|
-
const grouped =
|
|
37680
|
+
const grouped = React128.useMemo(() => {
|
|
37512
37681
|
const map = /* @__PURE__ */ new Map();
|
|
37513
37682
|
for (const col of board.columns) map.set(col.id, []);
|
|
37514
37683
|
for (const row of rows) {
|
|
@@ -37632,24 +37801,24 @@ function OrderListView({
|
|
|
37632
37801
|
boards,
|
|
37633
37802
|
viewKey
|
|
37634
37803
|
}) {
|
|
37635
|
-
const [search, setSearch] =
|
|
37636
|
-
const [page, setPage] =
|
|
37637
|
-
const [rawSelection, setRawSelection] =
|
|
37638
|
-
const offered =
|
|
37804
|
+
const [search, setSearch] = React128.useState("");
|
|
37805
|
+
const [page, setPage] = React128.useState(1);
|
|
37806
|
+
const [rawSelection, setRawSelection] = React128.useState([]);
|
|
37807
|
+
const offered = React128.useMemo(
|
|
37639
37808
|
() => views && views.length > 0 ? views : ["list"],
|
|
37640
37809
|
[views]
|
|
37641
37810
|
);
|
|
37642
|
-
const customFor =
|
|
37811
|
+
const customFor = React128.useCallback(
|
|
37643
37812
|
(id) => boards?.[id]?.render ?? null,
|
|
37644
37813
|
[boards]
|
|
37645
37814
|
);
|
|
37646
|
-
const boardFor =
|
|
37815
|
+
const boardFor = React128.useCallback(
|
|
37647
37816
|
(id) => (id === "board" ? board : boards?.[id]?.config) ?? null,
|
|
37648
37817
|
[board, boards]
|
|
37649
37818
|
);
|
|
37650
37819
|
const canBoard = offered.length > 1 && offered.some((id) => id !== "list" && (!!boardFor(id) || !!customFor(id)));
|
|
37651
37820
|
const storageKey2 = viewKey ? `fayz.orderView.${viewKey}` : null;
|
|
37652
|
-
const [view, setView] =
|
|
37821
|
+
const [view, setView] = React128.useState(() => {
|
|
37653
37822
|
const fallback = offered.includes(defaultView) ? defaultView : offered[0];
|
|
37654
37823
|
if (!storageKey2) return fallback;
|
|
37655
37824
|
try {
|
|
@@ -37659,7 +37828,7 @@ function OrderListView({
|
|
|
37659
37828
|
return fallback;
|
|
37660
37829
|
}
|
|
37661
37830
|
});
|
|
37662
|
-
const viewTabs =
|
|
37831
|
+
const viewTabs = React128.useMemo(
|
|
37663
37832
|
() => offered.map((option) => ({
|
|
37664
37833
|
value: option,
|
|
37665
37834
|
label: option === "list" ? "Lista" : boards?.[option]?.label ?? "Quadro",
|
|
@@ -37667,7 +37836,7 @@ function OrderListView({
|
|
|
37667
37836
|
})),
|
|
37668
37837
|
[offered, boards]
|
|
37669
37838
|
);
|
|
37670
|
-
const chooseView =
|
|
37839
|
+
const chooseView = React128.useCallback((next) => {
|
|
37671
37840
|
setView(next);
|
|
37672
37841
|
if (!storageKey2) return;
|
|
37673
37842
|
try {
|
|
@@ -37685,7 +37854,7 @@ function OrderListView({
|
|
|
37685
37854
|
const activeBoard = view === "list" ? null : boardFor(view);
|
|
37686
37855
|
const activeCustom = view === "list" ? null : customFor(view);
|
|
37687
37856
|
const showingBoard = !!activeBoard || !!activeCustom;
|
|
37688
|
-
const cols =
|
|
37857
|
+
const cols = React128.useMemo(
|
|
37689
37858
|
() => columns.map((c) => ({
|
|
37690
37859
|
id: c.key,
|
|
37691
37860
|
header: () => /* @__PURE__ */ jsx("div", { className: c.align === "right" ? "text-right" : "", children: c.header }),
|
|
@@ -37693,25 +37862,25 @@ function OrderListView({
|
|
|
37693
37862
|
})),
|
|
37694
37863
|
[columns]
|
|
37695
37864
|
);
|
|
37696
|
-
const filtered =
|
|
37865
|
+
const filtered = React128.useMemo(() => {
|
|
37697
37866
|
const term = search.trim().toLowerCase();
|
|
37698
37867
|
if (!term || !searchText) return rows;
|
|
37699
37868
|
return rows.filter((row) => searchText(row).toLowerCase().includes(term));
|
|
37700
37869
|
}, [rows, search, searchText]);
|
|
37701
|
-
|
|
37870
|
+
React128.useEffect(() => {
|
|
37702
37871
|
setPage(1);
|
|
37703
37872
|
}, [search]);
|
|
37704
37873
|
const paged = pageSize > 0 ? filtered.slice((page - 1) * pageSize, page * pageSize) : filtered;
|
|
37705
|
-
const getId =
|
|
37874
|
+
const getId = React128.useCallback(
|
|
37706
37875
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
37707
37876
|
[rowId]
|
|
37708
37877
|
);
|
|
37709
|
-
const pageIds =
|
|
37710
|
-
const selectedIds =
|
|
37878
|
+
const pageIds = React128.useMemo(() => paged.map(getId), [paged, getId]);
|
|
37879
|
+
const selectedIds = React128.useMemo(
|
|
37711
37880
|
() => rawSelection.filter((id) => pageIds.includes(id)),
|
|
37712
37881
|
[rawSelection, pageIds]
|
|
37713
37882
|
);
|
|
37714
|
-
const selectedRows =
|
|
37883
|
+
const selectedRows = React128.useMemo(
|
|
37715
37884
|
() => paged.filter((row) => selectedIds.includes(getId(row))),
|
|
37716
37885
|
[paged, selectedIds, getId]
|
|
37717
37886
|
);
|
|
@@ -37861,13 +38030,13 @@ function PaymentStatusBadge({
|
|
|
37861
38030
|
receiveLabel = "Receber",
|
|
37862
38031
|
onOpenDetails
|
|
37863
38032
|
}) {
|
|
37864
|
-
const [open, setOpen] =
|
|
37865
|
-
const [lines, setLines] =
|
|
37866
|
-
const timer =
|
|
37867
|
-
|
|
38033
|
+
const [open, setOpen] = React128__default.useState(false);
|
|
38034
|
+
const [lines, setLines] = React128__default.useState(null);
|
|
38035
|
+
const timer = React128__default.useRef(null);
|
|
38036
|
+
React128__default.useEffect(() => {
|
|
37868
38037
|
setLines(null);
|
|
37869
38038
|
}, [status, paidAmount]);
|
|
37870
|
-
const load =
|
|
38039
|
+
const load = React128__default.useCallback(() => {
|
|
37871
38040
|
if (lines || !onLoadDetails) return;
|
|
37872
38041
|
void onLoadDetails().then(setLines).catch(() => setLines([]));
|
|
37873
38042
|
}, [lines, onLoadDetails]);
|
|
@@ -38002,13 +38171,13 @@ function invalidateOrdersPaymentStatus(orderId) {
|
|
|
38002
38171
|
else cache2.clear();
|
|
38003
38172
|
}
|
|
38004
38173
|
function useOrdersPaymentStatus(orderIds) {
|
|
38005
|
-
const key =
|
|
38174
|
+
const key = React128.useMemo(
|
|
38006
38175
|
() => Array.from(new Set(orderIds.filter(Boolean))).sort().join(","),
|
|
38007
38176
|
[orderIds]
|
|
38008
38177
|
);
|
|
38009
|
-
const [byOrder, setByOrder] =
|
|
38010
|
-
const [loading, setLoading] =
|
|
38011
|
-
const load =
|
|
38178
|
+
const [byOrder, setByOrder] = React128.useState(() => /* @__PURE__ */ new Map());
|
|
38179
|
+
const [loading, setLoading] = React128.useState(false);
|
|
38180
|
+
const load = React128.useCallback(async (force = false) => {
|
|
38012
38181
|
const ids = key ? key.split(",") : [];
|
|
38013
38182
|
if (ids.length === 0) {
|
|
38014
38183
|
setByOrder(/* @__PURE__ */ new Map());
|
|
@@ -38039,7 +38208,7 @@ function useOrdersPaymentStatus(orderIds) {
|
|
|
38039
38208
|
}
|
|
38040
38209
|
setByOrder(new Map(ids.map((id) => [id, cache2.get(id)]).filter(([, v]) => Boolean(v))));
|
|
38041
38210
|
}, [key]);
|
|
38042
|
-
|
|
38211
|
+
React128.useEffect(() => {
|
|
38043
38212
|
void load();
|
|
38044
38213
|
}, [load]);
|
|
38045
38214
|
return { byOrder, loading, reload: () => load(true) };
|
|
@@ -38077,7 +38246,7 @@ var ORDER_CHANNEL_LABELS = {
|
|
|
38077
38246
|
dine_in: "Sal\xE3o",
|
|
38078
38247
|
delivery: "Delivery"
|
|
38079
38248
|
};
|
|
38080
|
-
function
|
|
38249
|
+
function Badge28({ children }) {
|
|
38081
38250
|
return /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium", children });
|
|
38082
38251
|
}
|
|
38083
38252
|
function orderKindColumn(kindOf, header = "Tipo") {
|
|
@@ -38087,7 +38256,7 @@ function orderKindColumn(kindOf, header = "Tipo") {
|
|
|
38087
38256
|
render: (row) => {
|
|
38088
38257
|
const kind = kindOf(row);
|
|
38089
38258
|
if (!kind) return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
38090
|
-
return /* @__PURE__ */ jsx(
|
|
38259
|
+
return /* @__PURE__ */ jsx(Badge28, { children: ORDER_KIND_LABELS[kind] ?? kind });
|
|
38091
38260
|
}
|
|
38092
38261
|
};
|
|
38093
38262
|
}
|
|
@@ -38098,7 +38267,7 @@ function orderChannelColumn(channelOf, header = "Canal") {
|
|
|
38098
38267
|
render: (row) => {
|
|
38099
38268
|
const channel = channelOf(row);
|
|
38100
38269
|
if (!channel) return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
38101
|
-
return /* @__PURE__ */ jsx(
|
|
38270
|
+
return /* @__PURE__ */ jsx(Badge28, { children: ORDER_CHANNEL_LABELS[channel] ?? channel });
|
|
38102
38271
|
}
|
|
38103
38272
|
};
|
|
38104
38273
|
}
|
|
@@ -38106,12 +38275,12 @@ function money2(value, currency) {
|
|
|
38106
38275
|
return value.toLocaleString("pt-BR", { style: "currency", currency: currency || "BRL" });
|
|
38107
38276
|
}
|
|
38108
38277
|
function useOrderDetail(orderId) {
|
|
38109
|
-
const [order, setOrder] =
|
|
38110
|
-
const [loading, setLoading] =
|
|
38111
|
-
const [error, setError] =
|
|
38112
|
-
const [nonce, setNonce] =
|
|
38113
|
-
const reload =
|
|
38114
|
-
|
|
38278
|
+
const [order, setOrder] = React128.useState(null);
|
|
38279
|
+
const [loading, setLoading] = React128.useState(false);
|
|
38280
|
+
const [error, setError] = React128.useState(null);
|
|
38281
|
+
const [nonce, setNonce] = React128.useState(0);
|
|
38282
|
+
const reload = React128.useCallback(() => setNonce((n) => n + 1), []);
|
|
38283
|
+
React128.useEffect(() => {
|
|
38115
38284
|
if (!orderId) {
|
|
38116
38285
|
setOrder(null);
|
|
38117
38286
|
setError(null);
|
|
@@ -38228,8 +38397,8 @@ function OrderDetailRail({
|
|
|
38228
38397
|
}) {
|
|
38229
38398
|
const { order, loading, error, reload } = useOrderDetail(orderId);
|
|
38230
38399
|
const { byOrder: paymentByOrder } = useOrdersPaymentStatus([orderId]);
|
|
38231
|
-
const [running, setRunning] =
|
|
38232
|
-
const [pending2, setPending] =
|
|
38400
|
+
const [running, setRunning] = React128.useState(null);
|
|
38401
|
+
const [pending2, setPending] = React128.useState(null);
|
|
38233
38402
|
const perform = async (action) => {
|
|
38234
38403
|
if (!order) return;
|
|
38235
38404
|
setRunning(action.id);
|
|
@@ -38387,11 +38556,11 @@ function receivableTone(value) {
|
|
|
38387
38556
|
return "warning";
|
|
38388
38557
|
}
|
|
38389
38558
|
function useOrderReceivable(orderId) {
|
|
38390
|
-
const [receivable, setReceivable] =
|
|
38559
|
+
const [receivable, setReceivable] = React128.useState(
|
|
38391
38560
|
() => orderId ? cache3.get(orderId) ?? null : null
|
|
38392
38561
|
);
|
|
38393
|
-
const [loading, setLoading] =
|
|
38394
|
-
const reload =
|
|
38562
|
+
const [loading, setLoading] = React128.useState(() => Boolean(orderId) && !cache3.has(orderId));
|
|
38563
|
+
const reload = React128.useCallback(async (force = false) => {
|
|
38395
38564
|
if (!orderId) return;
|
|
38396
38565
|
const db2 = getSupabaseClientOptional();
|
|
38397
38566
|
if (!db2) {
|
|
@@ -38414,7 +38583,7 @@ function useOrderReceivable(orderId) {
|
|
|
38414
38583
|
setReceivable(next);
|
|
38415
38584
|
setLoading(false);
|
|
38416
38585
|
}, [orderId]);
|
|
38417
|
-
|
|
38586
|
+
React128.useEffect(() => {
|
|
38418
38587
|
void reload();
|
|
38419
38588
|
}, [reload]);
|
|
38420
38589
|
return { receivable, loading, reload };
|
|
@@ -38567,15 +38736,15 @@ function linesOf(order) {
|
|
|
38567
38736
|
}
|
|
38568
38737
|
function useOrderEditor(orderId) {
|
|
38569
38738
|
const { order, loading, error } = useOrderDetail(orderId);
|
|
38570
|
-
const [lines, setLines] =
|
|
38571
|
-
const [saving, setSaving] =
|
|
38572
|
-
const originalRef =
|
|
38573
|
-
|
|
38739
|
+
const [lines, setLines] = React128.useState([]);
|
|
38740
|
+
const [saving, setSaving] = React128.useState(false);
|
|
38741
|
+
const originalRef = React128.useRef([]);
|
|
38742
|
+
React128.useEffect(() => {
|
|
38574
38743
|
const seeded = linesOf(order);
|
|
38575
38744
|
originalRef.current = seeded;
|
|
38576
38745
|
setLines(seeded);
|
|
38577
38746
|
}, [order]);
|
|
38578
|
-
const dirty =
|
|
38747
|
+
const dirty = React128.useMemo(() => {
|
|
38579
38748
|
const before = originalRef.current;
|
|
38580
38749
|
if (before.length !== lines.length) return true;
|
|
38581
38750
|
return lines.some((line, i) => {
|
|
@@ -38583,7 +38752,7 @@ function useOrderEditor(orderId) {
|
|
|
38583
38752
|
return !was || was.key !== line.key || was.quantity !== line.quantity || was.unitPrice !== line.unitPrice;
|
|
38584
38753
|
});
|
|
38585
38754
|
}, [lines]);
|
|
38586
|
-
const save =
|
|
38755
|
+
const save = React128.useCallback(async () => {
|
|
38587
38756
|
if (!orderId || !order) return { ok: false, error: "Pedido n\xE3o carregado" };
|
|
38588
38757
|
const db2 = getSupabaseClientOptional();
|
|
38589
38758
|
if (!db2) return { ok: false, error: "Sem conex\xE3o" };
|
|
@@ -38740,19 +38909,19 @@ function createClientOrdersProvider() {
|
|
|
38740
38909
|
}
|
|
38741
38910
|
function createPlaceholder(title, description) {
|
|
38742
38911
|
return function PlaceholderPage() {
|
|
38743
|
-
return
|
|
38912
|
+
return React128__default.createElement(
|
|
38744
38913
|
"div",
|
|
38745
38914
|
{ className: "mx-auto max-w-4xl" },
|
|
38746
|
-
|
|
38747
|
-
description ?
|
|
38748
|
-
|
|
38915
|
+
React128__default.createElement("h1", { className: "text-3xl font-bold text-foreground" }, title),
|
|
38916
|
+
description ? React128__default.createElement("p", { className: "mt-1 text-muted-foreground" }, description) : null,
|
|
38917
|
+
React128__default.createElement(
|
|
38749
38918
|
"div",
|
|
38750
38919
|
{ className: "mt-8 flex items-center justify-center rounded-card border border-dashed border-border bg-card p-16" },
|
|
38751
|
-
|
|
38920
|
+
React128__default.createElement(
|
|
38752
38921
|
"div",
|
|
38753
38922
|
{ className: "text-center" },
|
|
38754
|
-
|
|
38755
|
-
|
|
38923
|
+
React128__default.createElement("p", { className: "text-lg font-medium text-muted-foreground" }, "Coming Soon"),
|
|
38924
|
+
React128__default.createElement(
|
|
38756
38925
|
"p",
|
|
38757
38926
|
{ className: "mt-1 text-sm text-muted-foreground/70" },
|
|
38758
38927
|
"This module is being built as a plugin."
|
|
@@ -38833,7 +39002,7 @@ function ModuleActionBar({
|
|
|
38833
39002
|
trailing
|
|
38834
39003
|
}) {
|
|
38835
39004
|
const t = useTranslation();
|
|
38836
|
-
const actions =
|
|
39005
|
+
const actions = React128__default.useMemo(() => {
|
|
38837
39006
|
const out = (quickActions ?? []).map((qa, i) => ({
|
|
38838
39007
|
id: qa.id,
|
|
38839
39008
|
label: qa.label,
|
|
@@ -38865,9 +39034,9 @@ function ModuleActionBar({
|
|
|
38865
39034
|
] });
|
|
38866
39035
|
}
|
|
38867
39036
|
function createPluginContext(displayName) {
|
|
38868
|
-
const ConfigContext =
|
|
38869
|
-
const ProviderContext =
|
|
38870
|
-
const StoreContext =
|
|
39037
|
+
const ConfigContext = React128__default.createContext(null);
|
|
39038
|
+
const ProviderContext = React128__default.createContext(null);
|
|
39039
|
+
const StoreContext = React128__default.createContext(null);
|
|
38871
39040
|
const ContextProvider = ({
|
|
38872
39041
|
config,
|
|
38873
39042
|
provider: provider2,
|
|
@@ -38876,17 +39045,17 @@ function createPluginContext(displayName) {
|
|
|
38876
39045
|
}) => /* @__PURE__ */ jsx(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsx(ProviderContext.Provider, { value: provider2, children: /* @__PURE__ */ jsx(StoreContext.Provider, { value: store, children }) }) });
|
|
38877
39046
|
ContextProvider.displayName = `${displayName}ContextProvider`;
|
|
38878
39047
|
function useConfig() {
|
|
38879
|
-
const ctx =
|
|
39048
|
+
const ctx = React128__default.useContext(ConfigContext);
|
|
38880
39049
|
if (!ctx) throw new Error(`useConfig must be used within ${displayName}`);
|
|
38881
39050
|
return ctx;
|
|
38882
39051
|
}
|
|
38883
39052
|
function useProvider() {
|
|
38884
|
-
const ctx =
|
|
39053
|
+
const ctx = React128__default.useContext(ProviderContext);
|
|
38885
39054
|
if (!ctx) throw new Error(`useProvider must be used within ${displayName}`);
|
|
38886
39055
|
return ctx;
|
|
38887
39056
|
}
|
|
38888
39057
|
function useStore2(selector) {
|
|
38889
|
-
const store =
|
|
39058
|
+
const store = React128__default.useContext(StoreContext);
|
|
38890
39059
|
if (!store) throw new Error(`useStore must be used within ${displayName}`);
|
|
38891
39060
|
return useStore$1(store, selector);
|
|
38892
39061
|
}
|
|
@@ -38943,7 +39112,7 @@ function PluginRegistryManager({ registries, routeBase, className }) {
|
|
|
38943
39112
|
return registries[0]?.id ?? "";
|
|
38944
39113
|
};
|
|
38945
39114
|
const [activeTab, setActiveTab] = useState(getTabFromHash);
|
|
38946
|
-
|
|
39115
|
+
React128__default.useEffect(() => {
|
|
38947
39116
|
if (!routeBase) return;
|
|
38948
39117
|
const handler = () => setActiveTab(getTabFromHash());
|
|
38949
39118
|
window.addEventListener("hashchange", handler);
|
|
@@ -39154,7 +39323,7 @@ function PersonLink2({ personId, name, avatarUrl, lookup, kind, profileHref, tab
|
|
|
39154
39323
|
const email = data?.email;
|
|
39155
39324
|
const phone = data?.phone;
|
|
39156
39325
|
const resolvedKind = kind ?? data?.kind ?? person?.group;
|
|
39157
|
-
const actions =
|
|
39326
|
+
const actions = React128__default.useMemo(
|
|
39158
39327
|
() => personId ? getPersonActions(resolvedKind) : [],
|
|
39159
39328
|
[personId, resolvedKind]
|
|
39160
39329
|
);
|
|
@@ -39542,6 +39711,9 @@ function useScrollMemory(chave) {
|
|
|
39542
39711
|
const rolante = useCallback(() => {
|
|
39543
39712
|
const el = ancora.current;
|
|
39544
39713
|
if (!el) return null;
|
|
39714
|
+
for (let p = el.parentElement; p; p = p.parentElement) {
|
|
39715
|
+
if (/(auto|scroll)/.test(getComputedStyle(p).overflowY)) return p;
|
|
39716
|
+
}
|
|
39545
39717
|
return el.closest("main") ?? el.closest("[data-scroll-container]");
|
|
39546
39718
|
}, []);
|
|
39547
39719
|
useEffect(() => {
|
|
@@ -39582,6 +39754,77 @@ function useScrollMemory(chave) {
|
|
|
39582
39754
|
}, [completa, rolante]);
|
|
39583
39755
|
return ancora;
|
|
39584
39756
|
}
|
|
39757
|
+
var lists = /* @__PURE__ */ new Map();
|
|
39758
|
+
var listening = false;
|
|
39759
|
+
function track(payload) {
|
|
39760
|
+
for (const entry of lists.values()) {
|
|
39761
|
+
if (entry.tables && payload.table && !entry.tables.includes(payload.table)) continue;
|
|
39762
|
+
if (payload.id && payload.op !== "create") entry.dirty.add(payload.id);
|
|
39763
|
+
else entry.stale = true;
|
|
39764
|
+
entry.wake?.();
|
|
39765
|
+
}
|
|
39766
|
+
}
|
|
39767
|
+
function useRememberedList(options) {
|
|
39768
|
+
const key = `${getActiveTenantId() ?? "_"}:${options.key}`;
|
|
39769
|
+
const opts = useRef(options);
|
|
39770
|
+
opts.current = options;
|
|
39771
|
+
if (!listening) {
|
|
39772
|
+
listening = true;
|
|
39773
|
+
onDataChanged(track);
|
|
39774
|
+
}
|
|
39775
|
+
if (!lists.has(key)) lists.set(key, { rows: null, stale: true, dirty: /* @__PURE__ */ new Set(), tables: options.tables });
|
|
39776
|
+
const entry = lists.get(key);
|
|
39777
|
+
const [rows, setRows] = useState(() => entry.rows);
|
|
39778
|
+
const [error, setError] = useState("");
|
|
39779
|
+
const reload = useCallback(async () => {
|
|
39780
|
+
const e = lists.get(key);
|
|
39781
|
+
e.stale = false;
|
|
39782
|
+
e.dirty.clear();
|
|
39783
|
+
try {
|
|
39784
|
+
const next = await opts.current.load();
|
|
39785
|
+
e.rows = next;
|
|
39786
|
+
setRows(next);
|
|
39787
|
+
setError("");
|
|
39788
|
+
} catch (err) {
|
|
39789
|
+
e.stale = true;
|
|
39790
|
+
setError(errorMessage(err));
|
|
39791
|
+
if (!e.rows) setRows([]);
|
|
39792
|
+
}
|
|
39793
|
+
}, [key]);
|
|
39794
|
+
const settle = useCallback(async () => {
|
|
39795
|
+
const e = lists.get(key);
|
|
39796
|
+
if (e.stale || !e.rows) return reload();
|
|
39797
|
+
if (e.dirty.size === 0) return;
|
|
39798
|
+
const { loadOne, rowFor } = opts.current;
|
|
39799
|
+
const current2 = e.rows;
|
|
39800
|
+
const ids = [...e.dirty];
|
|
39801
|
+
e.dirty.clear();
|
|
39802
|
+
const targets = ids.map((id) => rowFor ? rowFor(current2, id) : current2.find((r) => r.id === id));
|
|
39803
|
+
if (!loadOne || targets.some((t) => !t)) return reload();
|
|
39804
|
+
try {
|
|
39805
|
+
const unique = [...new Set(targets.map((t) => t.id))];
|
|
39806
|
+
const fresh = new Map(await Promise.all(unique.map(async (id) => [id, await loadOne(id)])));
|
|
39807
|
+
const next = current2.flatMap((r) => fresh.has(r.id) ? fresh.get(r.id) ? [fresh.get(r.id)] : [] : [r]);
|
|
39808
|
+
e.rows = next;
|
|
39809
|
+
setRows(next);
|
|
39810
|
+
} catch {
|
|
39811
|
+
return reload();
|
|
39812
|
+
}
|
|
39813
|
+
}, [key, reload]);
|
|
39814
|
+
useEffect(() => {
|
|
39815
|
+
const e = lists.get(key);
|
|
39816
|
+
e.tables = opts.current.tables;
|
|
39817
|
+
setRows(e.rows);
|
|
39818
|
+
e.wake = () => {
|
|
39819
|
+
void settle();
|
|
39820
|
+
};
|
|
39821
|
+
void settle();
|
|
39822
|
+
return () => {
|
|
39823
|
+
if (e.wake) e.wake = void 0;
|
|
39824
|
+
};
|
|
39825
|
+
}, [key, settle]);
|
|
39826
|
+
return { rows, error, reload };
|
|
39827
|
+
}
|
|
39585
39828
|
var STORAGE_PREFIX2 = "saas:prefs:";
|
|
39586
39829
|
function readStore(pluginId, defaults) {
|
|
39587
39830
|
try {
|
|
@@ -39905,10 +40148,10 @@ function useTeachMe(def) {
|
|
|
39905
40148
|
return useFeatureHelp(def).teach;
|
|
39906
40149
|
}
|
|
39907
40150
|
function useFeatureHelp(def) {
|
|
39908
|
-
const ref =
|
|
40151
|
+
const ref = React128.useRef(def);
|
|
39909
40152
|
ref.current = def;
|
|
39910
40153
|
const id = `teach.${def.feature}`;
|
|
39911
|
-
const contribution =
|
|
40154
|
+
const contribution = React128.useMemo(
|
|
39912
40155
|
() => ({
|
|
39913
40156
|
id,
|
|
39914
40157
|
pluginId: "teach-me",
|
|
@@ -39942,7 +40185,7 @@ function useFeatureHelp(def) {
|
|
|
39942
40185
|
[id]
|
|
39943
40186
|
);
|
|
39944
40187
|
useAgentSurface(contribution);
|
|
39945
|
-
return
|
|
40188
|
+
return React128.useMemo(
|
|
39946
40189
|
() => ({
|
|
39947
40190
|
help: () => helpWith(ref.current),
|
|
39948
40191
|
teach: () => teachMe(ref.current),
|
|
@@ -40108,21 +40351,21 @@ function ConnectorsHub({ hostPluginId }) {
|
|
|
40108
40351
|
const { t } = useTranslation$1();
|
|
40109
40352
|
const { connectors, reload } = useConnectors({ includeGrants: false });
|
|
40110
40353
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
40111
|
-
const [selected, setSelected] =
|
|
40112
|
-
const [adding, setAdding] =
|
|
40113
|
-
const hosted =
|
|
40354
|
+
const [selected, setSelected] = React128__default.useState(null);
|
|
40355
|
+
const [adding, setAdding] = React128__default.useState(false);
|
|
40356
|
+
const hosted = React128__default.useMemo(
|
|
40114
40357
|
() => (connectors ?? []).filter((c) => c.hostPluginId === hostPluginId),
|
|
40115
40358
|
[connectors, hostPluginId]
|
|
40116
40359
|
);
|
|
40117
|
-
const categories =
|
|
40360
|
+
const categories = React128__default.useMemo(
|
|
40118
40361
|
() => [...new Set(hosted.map((c) => c.category).filter((c) => !!c))],
|
|
40119
40362
|
[hosted]
|
|
40120
40363
|
);
|
|
40121
|
-
const scoped =
|
|
40364
|
+
const scoped = React128__default.useMemo(() => {
|
|
40122
40365
|
const siblings = inCategories(connectors ?? [], categories).filter((c) => c.hostPluginId !== hostPluginId);
|
|
40123
40366
|
return [...hosted, ...siblings];
|
|
40124
40367
|
}, [connectors, hosted, categories, hostPluginId]);
|
|
40125
|
-
|
|
40368
|
+
React128__default.useEffect(() => {
|
|
40126
40369
|
if (!selected || !connectors) return;
|
|
40127
40370
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
40128
40371
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -40298,7 +40541,7 @@ function PluginSettingsPanel({ title, generalSettings, registries, customTabs, r
|
|
|
40298
40541
|
return tabs[0]?.id ?? "";
|
|
40299
40542
|
}
|
|
40300
40543
|
const [activeTab, setActiveTab] = useState(getActiveFromHash);
|
|
40301
|
-
|
|
40544
|
+
React128__default.useEffect(() => {
|
|
40302
40545
|
const handler = () => setActiveTab(getActiveFromHash());
|
|
40303
40546
|
window.addEventListener("hashchange", handler);
|
|
40304
40547
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -40336,6 +40579,6 @@ var renderApp = (...args) => {
|
|
|
40336
40579
|
return renderApp$1(...args);
|
|
40337
40580
|
};
|
|
40338
40581
|
|
|
40339
|
-
export { ALWAYS_ON_TOOLS, ActivationChecklistCard, ActivationProvider, AddConnectorButton, AddConnectorPanel, AdminProviders, AdminScaffold, AdminShell, AskAIButton, AskAIMenuItem, AssistantInvite, BoardFrame, ChatConversation, ClientOrdersTab, ConnectConsentPage, ConnectorDeliveries, ConnectorDetail, ConnectorMark, ConnectorRow, ConnectorSyncActions, ConnectorsHub, ConnectorsTab, ContactPicker, CredentialSinkMissingError, CrudCardGrid, CrudDetailPage, CrudDetailSkeleton, CrudFormPage, CrudFormSkeleton, CrudListView, CrudPage, CrudRecordModal, DeleteConfirmDialog, DetailTabHeader, EntitlementGate, EntityLink, GetStarted, GettingStartedWidget, NotebookPanel as HandbookPanel, HandbookProvider, NotebookRailPanel as HandbookRailPanel, KanbanBoard, LimitGate, LookupCreateInline, MemberAccessRailPage, ModuleActionBar, MultiSelectRow, NOTE_LABEL_PREFIX, NotebookPanel, NotebookRailPanel, ONBOARDING_TASK_SOURCE, ORDER_CHANNEL_LABELS, ORDER_KIND_LABELS, OTHER_CONNECTOR, OrderAmount, OrderBoardView, OrderCreateScreen, OrderDetailBlock, OrderDetailPage, OrderDetailRail, OrderDetailRow, OrderDetailSkeleton, OrderDetailView, OrderFormAddItemStep, OrderDetailBlock as OrderFormBlock, OrderFormItemRow, OrderFormItemsCard, OrderFormSkeleton, OrderFormView, OrderListView, OrderPaymentChip, PAYMENT_STATUS_CONFIG, PAYMENT_STATUS_LABEL, PageActions, PaymentStatusBadge, PermissionGate, PersonLink2 as PersonLink, PlatformError, PluginOnboardingGateSkeleton, PluginRegistryManager, PluginSettingsPanel, ProjectsSettings, QUESTION_PACKS, QuickActionsButton, RECEIVABLE_LABEL, RecordPickerModal, RegistryCrudView2 as RegistryCrudView, RelatedListTab, RightRailActions, RightRailLeading, RightRailPage, RouteErrorBoundary, RouteErrorScreen, SelectRow, SettingsGroup, SettingsTabs, SetupAgentSurface, SetupMeLink, SeuSiteWidget, StateChip, TASK_PRIORITIES, TASK_STATUSES, TaskCard, TaskDetail, TaskGroup, TaskLabelBadge, TaskLabelBadges, TaskPriorityBadge, TaskQuickAdd, TaskSourceBadge, TaskStatusGroup, TasksFilterBar, TasksPanel, TasksRailPanel, TeachMeLink, TextRow, ToggleRow, UNIT_DETAIL_ZONES, UnitSwitcher, UnitsSettingsPage, UpgradePrompt, WORKSPACE_SETUP_FLOW_ID, WORKSPACE_SETUP_FLOW_VERSION, WORKSPACE_SETUP_ROUTE, WidgetSlot, WorkspaceSetupFlow, WorkspaceSetupGate, WorkspaceSwitcher, appendHandbookPage, askAI, beautyPack, brandMark, buildBusinessProfile, buildHandbookTree, buildWorkspaceSetupSteps, businessProfileBlock, categoryLabel, checkSlugAvailable, claimTasksSurface, clearDocumentOpeners, clearPersonActions, connectorOptions, connectorRoute, connectorRows, createClientOrdersProvider, createCrudPage, createFayzApp, createFayzProject, createLogoUploader, createMockTasksProvider, createCrudPage as createNativeCrudPage, createOneShotAsk, createPlaceholder, createPlatformProject, createPluginContext, createSupabaseTasksProvider, createViewRouter, currentBusinessProfileBlock, dedup, defaultProjectOf, defineSaas, deleteFayzProject, deriveAgentContract, describeAiError, describeAiGap, describeFayzAgentGap, duplicateWrite, ensureChecklist, exportToCSV, filterConnectors, foodPack, formatActivityElapsed, formatCurrency4 as formatCurrency, formatSetupGuide, getActiveAgent, getAgent, getCrudNavTabs, getDefaultFayzProject, getFayzAgentClient, getGenerationStatus, getHost, getPersonActions, getPersonPath, getPreview, getQuestionPack, getRailPage, getSetupGuide, getSetupGuideForStep, getTabCountProviders, getTasksProvider, helpWith, humanizeWriteError, inferVerticalId, invalidateOrderReceivable, invalidateOrdersPaymentStatus, invalidateRelationOptions, invalidateTabCounts, isPlatformConnected, listFayzProjects, listHandbook, listPlatformProjects, listSetupGuides, loadArea, loadTools, loadedToolNames, mergeLines, needsCredentialSink, normalizePath, openAssistant, openAssistantAs, openConnectorsPanel, orderChannelColumn, orderIsEditable, orderKindColumn, orientationTour, parseViewId, publishAssistantActivity, readAttachmentBytes, readHandbookPage, readSetupAnswers, receivableTone, recordOnboardingResponse, registerAdminScaffold, registerAssistantLauncher, registerCrudNavTabs, registerDocumentOpener, registerEntityPath, registerNotesTasksAdapter, registerPersonActions, registerRailPage, registerSetupGuides, registerTabCountProvider, renderApp, renderHandbookOutline, requestChatUpload, requestProjectChange, resetLoadedTools, resolveDocumentOpener, resolveDocumentOpenerFor, resolveFayzAgentConnection, resolveSetupMode, resolveVerticalId, retailPack, revealPage, runWelcome, searchHandbook, searchSetupGuides, setServedRoutes, setTasksProvider, setUpWithMe, shrinkForVision, slugify, soleAgent, splitConnectorValues, splitOnboardingTasks, startGuidedRun, startPreview, stopPreview, submitConnection, submitWorkspaceSetup, summariseSetupGuides, taskEntityDef, tasksSurfaceOwner, teachMe, toInlineFile, toOrderDetailReceivable, unregisterAssistantLauncher, unregisterTabCountProvider, updateFayzProject, useActivationStore, useActiveAgent, useAgent, useAgentStore, useAgentSurface, useAppConfig, useAssistantActivity, useAssistantInviteStore, useAssistantLaunchers, useBusinessProfileStore, useCatalogedItemTypes, useChatStore, useConnectors, useConnectorsPanelAvailable, useContextualNav, useContextualNavStore, useDelegateToAssistant, useFayzProjectsStore, useFeatureHelp, useFieldRules, useHandbookStore, useHasRightRail, useHeaderAction, useHeaderActions, useLaunchersForRole, useLookupCreate, useMemberAccessPanel, useModuleNavigation, useNavContribution, useNavContributionsStore, useNotesTasksBridge, useOrderDetail, useOrderEditor, useOrderReceivable, useOrdersPaymentStatus, usePersistedState, usePersonTabCounts, usePluginOnboardingGate, usePluginPrefs, usePresetLabel, usePublishAssistantActivity, useRegisterAssistantLauncher, useRightRailDrill, useRightRailHosted, useRightRailPanel, useRightRailStore, useScrollMemory, useSettingsTabsStore, useShellRailAvailable, useTasksStore, useTasksSummaryLine, useTeachMe, useTenantPluginSettings, useUnitBootstrap, useUnitFilter, useUnitStore, useWidgetSurface, useWorkspaceSetupBusy, useWorkspaceSetupGate, useWorkspaceSetupStore, validateSetupGuides, withdrawAssistantActivity, writeHandbookPage };
|
|
40582
|
+
export { ALWAYS_ON_TOOLS, ActivationChecklistCard, ActivationProvider, AddConnectorButton, AddConnectorPanel, AdminProviders, AdminScaffold, AdminShell, AskAIButton, AskAIMenuItem, AssistantInvite, BoardFrame, ChatConversation, ClientOrdersTab, ConnectConsentPage, ConnectorDeliveries, ConnectorDetail, ConnectorMark, ConnectorRow, ConnectorSyncActions, ConnectorsHub, ConnectorsTab, ContactPicker, CredentialSinkMissingError, CrudCardGrid, CrudDetailPage, CrudDetailSkeleton, CrudFormPage, CrudFormSkeleton, CrudListView, CrudPage, CrudRecordModal, DeleteConfirmDialog, DetailTabHeader, EntitlementGate, EntityLink, GetStarted, GettingStartedWidget, NotebookPanel as HandbookPanel, HandbookProvider, NotebookRailPanel as HandbookRailPanel, KanbanBoard, LimitGate, LookupCreateInline, MemberAccessRailPage, ModuleActionBar, MultiSelectRow, NOTE_LABEL_PREFIX, NotebookPanel, NotebookRailPanel, ONBOARDING_TASK_SOURCE, ORDER_CHANNEL_LABELS, ORDER_KIND_LABELS, OTHER_CONNECTOR, OrderAmount, OrderBoardView, OrderCreateScreen, OrderDetailBlock, OrderDetailPage, OrderDetailRail, OrderDetailRow, OrderDetailSkeleton, OrderDetailView, OrderFormAddItemStep, OrderDetailBlock as OrderFormBlock, OrderFormItemRow, OrderFormItemsCard, OrderFormSkeleton, OrderFormView, OrderListView, OrderPaymentChip, PAYMENT_STATUS_CONFIG, PAYMENT_STATUS_LABEL, PageActions, PaymentStatusBadge, PermissionGate, PersonLink2 as PersonLink, PlatformError, PluginOnboardingGateSkeleton, PluginRegistryManager, PluginSettingsPanel, ProjectsSettings, QUESTION_PACKS, QuickActionsButton, RECEIVABLE_LABEL, RecordPickerModal, RegistryCrudView2 as RegistryCrudView, RelatedListTab, RightRailActions, RightRailLeading, RightRailPage, RouteErrorBoundary, RouteErrorScreen, SelectRow, SettingsGroup, SettingsTabs, SetupAgentSurface, SetupMeLink, SeuSiteWidget, StateChip, TASK_PRIORITIES, TASK_STATUSES, TaskCard, TaskDetail, TaskGroup, TaskLabelBadge, TaskLabelBadges, TaskPriorityBadge, TaskQuickAdd, TaskSourceBadge, TaskStatusGroup, TasksFilterBar, TasksPanel, TasksRailPanel, TeachMeLink, TextRow, ToggleRow, UNIT_DETAIL_ZONES, UnitSwitcher, UnitsSettingsPage, UpgradePrompt, WORKSPACE_SETUP_FLOW_ID, WORKSPACE_SETUP_FLOW_VERSION, WORKSPACE_SETUP_ROUTE, WidgetSlot, WorkspaceSetupFlow, WorkspaceSetupGate, WorkspaceSwitcher, appendHandbookPage, askAI, beautyPack, brandMark, buildBusinessProfile, buildHandbookTree, buildWorkspaceSetupSteps, businessProfileBlock, categoryLabel, checkSlugAvailable, claimTasksSurface, clearDocumentOpeners, clearPersonActions, connectorOptions, connectorRoute, connectorRows, createClientOrdersProvider, createCrudPage, createFayzApp, createFayzProject, createLogoUploader, createMockTasksProvider, createCrudPage as createNativeCrudPage, createOneShotAsk, createPlaceholder, createPlatformProject, createPluginContext, createSupabaseTasksProvider, createViewRouter, currentBusinessProfileBlock, dedup, defaultProjectOf, defineSaas, deleteFayzProject, deriveAgentContract, describeAiError, describeAiGap, describeFayzAgentGap, duplicateWrite, ensureChecklist, exportToCSV, filterConnectors, foodPack, formatActivityElapsed, formatCurrency4 as formatCurrency, formatSetupGuide, getActiveAgent, getAgent, getCrudNavTabs, getDefaultFayzProject, getFayzAgentClient, getGenerationStatus, getHost, getPersonActions, getPersonPath, getPreview, getQuestionPack, getRailPage, getSetupGuide, getSetupGuideForStep, getTabCountProviders, getTasksProvider, helpWith, humanizeWriteError, inferVerticalId, invalidateOrderReceivable, invalidateOrdersPaymentStatus, invalidateRelationOptions, invalidateTabCounts, isPlatformConnected, listFayzProjects, listHandbook, listPlatformProjects, listSetupGuides, loadArea, loadTools, loadedToolNames, mergeLines, needsCredentialSink, normalizePath, openAssistant, openAssistantAs, openConnectorsPanel, orderChannelColumn, orderIsEditable, orderKindColumn, orientationTour, parseViewId, publishAssistantActivity, readAttachmentBytes, readHandbookPage, readSetupAnswers, receivableTone, recordOnboardingResponse, registerAdminScaffold, registerAssistantLauncher, registerCrudNavTabs, registerDocumentOpener, registerEntityPath, registerNotesTasksAdapter, registerPersonActions, registerRailPage, registerSetupGuides, registerTabCountProvider, renderApp, renderHandbookOutline, requestChatUpload, requestProjectChange, resetLoadedTools, resolveDocumentOpener, resolveDocumentOpenerFor, resolveFayzAgentConnection, resolveSetupMode, resolveVerticalId, retailPack, revealPage, runWelcome, searchHandbook, searchSetupGuides, setServedRoutes, setTasksProvider, setUpWithMe, shrinkForVision, slugify, soleAgent, splitConnectorValues, splitOnboardingTasks, startGuidedRun, startPreview, stopPreview, submitConnection, submitWorkspaceSetup, summariseSetupGuides, taskEntityDef, tasksSurfaceOwner, teachMe, toInlineFile, toOrderDetailReceivable, unregisterAssistantLauncher, unregisterTabCountProvider, updateFayzProject, useActivationStore, useActiveAgent, useAgent, useAgentStore, useAgentSurface, useAppConfig, useAssistantActivity, useAssistantInviteStore, useAssistantLaunchers, useBusinessProfileStore, useCatalogedItemTypes, useChatStore, useConnectors, useConnectorsPanelAvailable, useContextualNav, useContextualNavStore, useDelegateToAssistant, useFayzProjectsStore, useFeatureHelp, useFieldRules, useHandbookStore, useHasRightRail, useHeaderAction, useHeaderActions, useLaunchersForRole, useLookupCreate, useMemberAccessPanel, useModuleNavigation, useNavContribution, useNavContributionsStore, useNotesTasksBridge, useOrderDetail, useOrderEditor, useOrderReceivable, useOrdersPaymentStatus, usePersistedState, usePersonTabCounts, usePluginOnboardingGate, usePluginPrefs, usePresetLabel, usePublishAssistantActivity, useRegisterAssistantLauncher, useRememberedList, useRightRailDrill, useRightRailHosted, useRightRailPanel, useRightRailStore, useScrollMemory, useSettingsTabsStore, useShellRailAvailable, useTasksStore, useTasksSummaryLine, useTeachMe, useTenantPluginSettings, useUnitBootstrap, useUnitFilter, useUnitStore, useWidgetSurface, useWorkspaceSetupBusy, useWorkspaceSetupGate, useWorkspaceSetupStore, validateSetupGuides, withdrawAssistantActivity, writeHandbookPage };
|
|
40340
40583
|
//# sourceMappingURL=index.js.map
|
|
40341
40584
|
//# sourceMappingURL=index.js.map
|