@fayz-ai/admin 0.38.0 → 0.39.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-ZEG6PG3Z.js +7 -0
- package/dist/{ScheduleEditor-VGDE57L2.js.map → ScheduleEditor-ZEG6PG3Z.js.map} +1 -1
- package/dist/SubscriptionPage-VXZ37WZZ.js +9 -0
- package/dist/{SubscriptionPage-2WK57426.js.map → SubscriptionPage-VXZ37WZZ.js.map} +1 -1
- package/dist/app/AdminShell.d.ts.map +1 -1
- package/dist/app/admin-app.d.ts.map +1 -1
- package/dist/{chunk-IDOTNT43.js → chunk-3C5Q4OGJ.js} +4 -4
- package/dist/chunk-3C5Q4OGJ.js.map +1 -0
- package/dist/{chunk-TRDVM4ZO.js → chunk-A5UZL52H.js} +15 -3
- package/dist/chunk-A5UZL52H.js.map +1 -0
- package/dist/{chunk-QLRZUU4V.js → chunk-HOMD2MAG.js} +3 -3
- package/dist/{chunk-QLRZUU4V.js.map → chunk-HOMD2MAG.js.map} +1 -1
- package/dist/{chunk-4YF6R7T3.js → chunk-KP3LNCNP.js} +63 -11
- package/dist/chunk-KP3LNCNP.js.map +1 -0
- package/dist/components/chat/ChatFab.d.ts.map +1 -1
- package/dist/components/organization/TeamTab.d.ts.map +1 -1
- package/dist/crud/archetype-lookup.d.ts.map +1 -1
- package/dist/crud/archetypes/ServiceFormLayout.d.ts.map +1 -1
- package/dist/impersonation/ImpersonateDialog.d.ts +11 -0
- package/dist/impersonation/ImpersonateDialog.d.ts.map +1 -0
- package/dist/impersonation/ImpersonationBanner.d.ts +4 -0
- package/dist/impersonation/ImpersonationBanner.d.ts.map +1 -0
- package/dist/impersonation/session.d.ts +15 -0
- package/dist/impersonation/session.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +949 -767
- package/dist/index.js.map +1 -1
- package/dist/org/adapters/supabase.d.ts +2 -0
- package/dist/org/adapters/supabase.d.ts.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/index.js +2 -2
- package/package.json +6 -6
- package/dist/ScheduleEditor-VGDE57L2.js +0 -7
- package/dist/SubscriptionPage-2WK57426.js +0 -9
- package/dist/chunk-4YF6R7T3.js.map +0 -1
- package/dist/chunk-IDOTNT43.js.map +0 -1
- package/dist/chunk-TRDVM4ZO.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { PersonTimeline, TimelineList, TimelineSkeleton, getTimelineSources, registerTimelineSource, unregisterTimelineSource, usePersonTimeline } from './chunk-WXNTUCX3.js';
|
|
2
|
-
import { useLimitGuard, invalidateLimit, useAccessOptional, useUpgradeModalStore, guardLimit, useLimit, checkAccess, featureDisplayName, PlanFeatureItem, AccessProvider, CORE_LIMIT_DECLARATIONS, entityDerivedLimitDeclarations, getPlanEntitlements, resolvePlanCurrency } from './chunk-
|
|
3
|
-
export { AccessProvider, UPGRADE_URL, agentDenial, checkAccess, getAccessSnapshot, guardLimit, invalidateLimit, isEntitledByPlan, resolveAccess, useAccess, useAccessOptional, useLimit, useLimitGuard, useModuleNavAccess, useUpgradeModalStore } from './chunk-
|
|
2
|
+
import { useLimitGuard, invalidateLimit, useAccessOptional, useUpgradeModalStore, guardLimit, useLimit, checkAccess, featureDisplayName, PlanFeatureItem, AccessProvider, CORE_LIMIT_DECLARATIONS, entityDerivedLimitDeclarations, getPlanEntitlements, resolvePlanCurrency } from './chunk-HOMD2MAG.js';
|
|
3
|
+
export { AccessProvider, UPGRADE_URL, agentDenial, checkAccess, getAccessSnapshot, guardLimit, invalidateLimit, isEntitledByPlan, resolveAccess, useAccess, useAccessOptional, useLimit, useLimitGuard, useModuleNavAccess, useUpgradeModalStore } from './chunk-HOMD2MAG.js';
|
|
4
4
|
export { clearRecentRecords, listRecentRecords, rememberVisit, subscribeRecentRecords, useOpenRecent, useRecentRecords, useRecordVisit } from './chunk-OD7P4L3D.js';
|
|
5
5
|
import { useTranslation as useTranslation$1 } from './chunk-YUHCC7JY.js';
|
|
6
6
|
import { useBillingStore, resolvePlanBadge, TrialWidget } from './chunk-IUCDHAAB.js';
|
|
@@ -10,19 +10,19 @@ 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-
|
|
15
|
-
import { getFayzSupabaseClientOptional, getSupabaseClientOptional as getSupabaseClientOptional$1, useAppConfigStore, activePluginIds, hasPlugin, useWorkspaceSwitchingStore, searchWorkspaces, OrgMark, WorkspaceChooserGate, WorkspaceSwitchingHost, createFayzSupabaseClient, resolveAppId, createSupabaseOrgAdapter, createMockOrgAdapter, getFayzSupabaseClient } from './chunk-
|
|
16
|
-
export { OrgMark, activePluginIds, createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, getFayzSupabaseClient, getFayzSupabaseClientOptional, hasPlugin, orgInitials, useAppConfigStore } from './chunk-
|
|
17
|
-
import { readOrgSnapshot, useTenantOptional, useOrgAdapter, useTenant, OrgProvider, useOrgAdapterOptional } from './chunk-
|
|
18
|
-
export { ORG_CACHE_TTL_MS, OrgProvider, clearOrgSnapshot, readOrgSnapshot, useOrgAdapter, useOrgAdapterOptional, useTenant, useTenantOptional } from './chunk-
|
|
13
|
+
import { createArchetypeLookup, getPersonLookup } from './chunk-A5UZL52H.js';
|
|
14
|
+
export { ScheduleDateExceptions, ScheduleEditor, ScheduleGridPanel, createArchetypeLookup, deleteSchedule, getPersonBookable, getPersonLookup, getScheduleBlockConfig, getSchedules, mergeBlockSettings, parseBlockSettings, registerPersonLookup, replaceWeeklySchedules, saveSchedule, setPersonBookable, setScheduleBlockConfig, subscribeScheduleBlockConfig } from './chunk-A5UZL52H.js';
|
|
15
|
+
import { getFayzSupabaseClientOptional, getSupabaseClientOptional as getSupabaseClientOptional$1, useAppConfigStore, activePluginIds, hasPlugin, useWorkspaceSwitchingStore, searchWorkspaces, OrgMark, WorkspaceChooserGate, WorkspaceSwitchingHost, createFayzSupabaseClient, resolveAppId, createSupabaseOrgAdapter, createMockOrgAdapter, getFayzSupabaseClient } from './chunk-KP3LNCNP.js';
|
|
16
|
+
export { OrgMark, activePluginIds, createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, getFayzSupabaseClient, getFayzSupabaseClientOptional, hasPlugin, orgInitials, useAppConfigStore } from './chunk-KP3LNCNP.js';
|
|
17
|
+
import { readOrgSnapshot, useTenantOptional, useOrgAdapter, useTenant, OrgProvider, useOrgAdapterOptional, markWorkspaceSwitch } from './chunk-3C5Q4OGJ.js';
|
|
18
|
+
export { ORG_CACHE_TTL_MS, OrgProvider, clearOrgSnapshot, readOrgSnapshot, useOrgAdapter, useOrgAdapterOptional, useTenant, useTenantOptional } from './chunk-3C5Q4OGJ.js';
|
|
19
19
|
import { usePermissionOptional, usePermissionsStore, PermissionsProvider } from './chunk-UQ2NTFQC.js';
|
|
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, 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';
|
|
23
|
+
import * as React130 from 'react';
|
|
24
|
+
import React130__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, readImpersonation, getComponent, getPluginFactory, connectorSettings, groupedPermissions, invocationPlane, missingRequiredSettings, isBankEmpty, isAddressEmpty, writeImpersonation, 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';
|
|
@@ -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 = React130.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] = React130__default.useState(false);
|
|
190
|
+
const [dispensada, setDispensada] = React130__default.useState(false);
|
|
191
|
+
const [aplicando, setAplicando] = React130__default.useState(false);
|
|
192
|
+
React130__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
|
+
React130.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
|
+
React130.useSyncExternalStore(subscribe, getVersion, getServerVersion);
|
|
1960
1960
|
return launchers;
|
|
1961
1961
|
}
|
|
1962
1962
|
function useLaunchersForRole(role) {
|
|
1963
1963
|
const all = useAssistantLaunchers();
|
|
1964
|
-
return
|
|
1964
|
+
return React130.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 = React130.useRef(activity);
|
|
1970
1970
|
ref.current = activity;
|
|
1971
|
-
|
|
1971
|
+
React130.useEffect(() => {
|
|
1972
1972
|
if (ref.current) publishAssistantActivity(ref.current);
|
|
1973
1973
|
}, [key]);
|
|
1974
|
-
|
|
1974
|
+
React130.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 = React130.useRef(launcher);
|
|
1983
1983
|
ref.current = launcher;
|
|
1984
|
-
|
|
1984
|
+
React130.useEffect(() => {
|
|
1985
1985
|
if (ref.current) registerAssistantLauncher(ref.current);
|
|
1986
1986
|
}, [key]);
|
|
1987
|
-
|
|
1987
|
+
React130.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 = React130.useRef({ label: label3, icon });
|
|
2086
|
+
React130.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
|
+
React130.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
|
+
React130.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 = React130.createContext(null);
|
|
2101
2101
|
var RightRailActionsSlotProvider = RightRailActionsSlotContext.Provider;
|
|
2102
2102
|
function RightRailActions({ children }) {
|
|
2103
|
-
const slot =
|
|
2103
|
+
const slot = React130.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 = React130.createContext(null);
|
|
2108
2108
|
var RightRailLeadingSlotProvider = RightRailLeadingSlotContext.Provider;
|
|
2109
2109
|
function RightRailLeading({ children }) {
|
|
2110
|
-
const slot =
|
|
2110
|
+
const slot = React130.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 = React130.useRef(handler);
|
|
2118
2118
|
ref.current = handler;
|
|
2119
|
-
const seen =
|
|
2120
|
-
|
|
2119
|
+
const seen = React130.useRef(reselects);
|
|
2120
|
+
React130.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 = React130.useRef(drill?.back);
|
|
2138
2138
|
backRef.current = drill?.back;
|
|
2139
|
-
|
|
2139
|
+
React130.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
|
+
React130__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
|
+
React130.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 = React130.useRef(null);
|
|
2315
|
+
const [box, setBox] = React130.useState(null);
|
|
2316
2316
|
const docked = stage === "dock" && !railOpen && hasAssistant;
|
|
2317
2317
|
const showing = hasAssistant && (stage === "hero" || docked);
|
|
2318
|
-
|
|
2318
|
+
React130.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
|
+
React130.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 React130.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] = React130.useState("");
|
|
2372
2372
|
const name = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
2373
|
-
|
|
2373
|
+
React130.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] = React130.useState(() => skip || prefersReducedMotion());
|
|
2436
|
+
React130.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] = React130.useState(
|
|
2456
2456
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
2457
2457
|
);
|
|
2458
|
-
|
|
2458
|
+
React130.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] = React130.useState("");
|
|
2490
|
+
const resumed = React130.useRef(
|
|
2491
2491
|
!!lastDockExit && lastDockExit.id === def.id && Date.now() - lastDockExit.at < RESUME_WINDOW_MS
|
|
2492
2492
|
).current;
|
|
2493
|
-
|
|
2493
|
+
React130.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 = React130.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] = React130.useState(resumed);
|
|
2501
2501
|
const geoLeft = settled ? left : mountGeo.left;
|
|
2502
2502
|
const geoWidth = settled ? width : mountGeo.width;
|
|
2503
|
-
|
|
2503
|
+
React130.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
|
+
React130.useEffect(() => {
|
|
2650
2650
|
if (prefersReducedMotion()) {
|
|
2651
2651
|
endLeave();
|
|
2652
2652
|
return;
|
|
@@ -4562,12 +4562,12 @@ function detectActivePluginId(runtime) {
|
|
|
4562
4562
|
function useAITools() {
|
|
4563
4563
|
const runtime = usePluginRuntimeOptional();
|
|
4564
4564
|
const access = useAccessOptional();
|
|
4565
|
-
const surfaceVersion =
|
|
4565
|
+
const surfaceVersion = React130.useSyncExternalStore(subscribeSurfaces, getSurfaceVersion, getSurfaceVersion);
|
|
4566
4566
|
const features = usePermissionsStore((s) => s.features);
|
|
4567
4567
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
4568
4568
|
const hasSystem = useSystemPermission();
|
|
4569
4569
|
const canManagePermissions = hasSystem("manage_permissions");
|
|
4570
|
-
return
|
|
4570
|
+
return React130.useMemo(() => {
|
|
4571
4571
|
const hasPermission = runtime?.context.hasPermission;
|
|
4572
4572
|
const can = access.can;
|
|
4573
4573
|
const verticalId = runtime?.context.tenant?.verticalId;
|
|
@@ -5583,8 +5583,8 @@ function loadCatalog() {
|
|
|
5583
5583
|
return catalogPromise;
|
|
5584
5584
|
}
|
|
5585
5585
|
function useConnectorCatalog() {
|
|
5586
|
-
const [catalog, setCatalog] =
|
|
5587
|
-
|
|
5586
|
+
const [catalog, setCatalog] = React130__default.useState(null);
|
|
5587
|
+
React130__default.useEffect(() => {
|
|
5588
5588
|
let cancelled = false;
|
|
5589
5589
|
void loadCatalog().then((list) => {
|
|
5590
5590
|
if (!cancelled) setCatalog(list);
|
|
@@ -5608,7 +5608,7 @@ function refreshConnectors() {
|
|
|
5608
5608
|
_revisionListeners.forEach((listener) => listener());
|
|
5609
5609
|
}
|
|
5610
5610
|
function useConnectorsRevision() {
|
|
5611
|
-
return
|
|
5611
|
+
return React130__default.useSyncExternalStore(
|
|
5612
5612
|
(listener) => {
|
|
5613
5613
|
_revisionListeners.add(listener);
|
|
5614
5614
|
return () => _revisionListeners.delete(listener);
|
|
@@ -5627,11 +5627,11 @@ function loadGrants(key, fetcher) {
|
|
|
5627
5627
|
}
|
|
5628
5628
|
function useInstalledModuleIds() {
|
|
5629
5629
|
const runtime = usePluginRuntimeOptional();
|
|
5630
|
-
return
|
|
5630
|
+
return React130__default.useMemo(() => (runtime?.plugins ?? []).map((p) => p.id), [runtime]);
|
|
5631
5631
|
}
|
|
5632
5632
|
function useInstalledDefinitions(hostPluginId) {
|
|
5633
5633
|
const runtime = usePluginRuntimeOptional();
|
|
5634
|
-
return
|
|
5634
|
+
return React130__default.useMemo(() => {
|
|
5635
5635
|
const byHost = runtime?.connectorsByHost;
|
|
5636
5636
|
if (!byHost) return [];
|
|
5637
5637
|
if (hostPluginId) return byHost.get(hostPluginId) ?? [];
|
|
@@ -5644,12 +5644,12 @@ function useConnectors(options = {}) {
|
|
|
5644
5644
|
const catalog = useConnectorCatalog();
|
|
5645
5645
|
const tenant = useTenantOptional();
|
|
5646
5646
|
const tenantId2 = tenant?.org?.id;
|
|
5647
|
-
const connection =
|
|
5648
|
-
const [installed, setInstalled] =
|
|
5649
|
-
const [grants, setGrants] =
|
|
5650
|
-
const [error, setError] =
|
|
5647
|
+
const connection = React130__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
5648
|
+
const [installed, setInstalled] = React130__default.useState(null);
|
|
5649
|
+
const [grants, setGrants] = React130__default.useState(null);
|
|
5650
|
+
const [error, setError] = React130__default.useState(null);
|
|
5651
5651
|
const nonce = useConnectorsRevision();
|
|
5652
|
-
const call2 =
|
|
5652
|
+
const call2 = React130__default.useCallback(
|
|
5653
5653
|
async (path, init) => {
|
|
5654
5654
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
5655
5655
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -5669,7 +5669,7 @@ function useConnectors(options = {}) {
|
|
|
5669
5669
|
},
|
|
5670
5670
|
[connection]
|
|
5671
5671
|
);
|
|
5672
|
-
|
|
5672
|
+
React130__default.useEffect(() => {
|
|
5673
5673
|
let cancelled = false;
|
|
5674
5674
|
void loadConnectorStatuses(definitions, tenantId2).then((list) => {
|
|
5675
5675
|
if (!cancelled) setInstalled(list);
|
|
@@ -5678,7 +5678,7 @@ function useConnectors(options = {}) {
|
|
|
5678
5678
|
cancelled = true;
|
|
5679
5679
|
};
|
|
5680
5680
|
}, [definitions, tenantId2, nonce]);
|
|
5681
|
-
|
|
5681
|
+
React130__default.useEffect(() => {
|
|
5682
5682
|
if (!includeGrants || !connection || !tenantId2) {
|
|
5683
5683
|
setGrants(includeGrants ? null : []);
|
|
5684
5684
|
return;
|
|
@@ -5702,7 +5702,7 @@ function useConnectors(options = {}) {
|
|
|
5702
5702
|
cancelled = true;
|
|
5703
5703
|
};
|
|
5704
5704
|
}, [call2, tenantId2, includeGrants, connection, nonce]);
|
|
5705
|
-
const revokeGrant =
|
|
5705
|
+
const revokeGrant = React130__default.useCallback(
|
|
5706
5706
|
async (connector) => {
|
|
5707
5707
|
const response = await call2(`/${connector.id}`, { method: "DELETE" });
|
|
5708
5708
|
if (!response.ok) {
|
|
@@ -5715,7 +5715,7 @@ function useConnectors(options = {}) {
|
|
|
5715
5715
|
[call2]
|
|
5716
5716
|
);
|
|
5717
5717
|
const waitingGrants = includeGrants && !!connection && !!tenantId2 && grants === null;
|
|
5718
|
-
const connectors =
|
|
5718
|
+
const connectors = React130__default.useMemo(() => {
|
|
5719
5719
|
if (installed === null || waitingGrants) return null;
|
|
5720
5720
|
return buildConnectorList({
|
|
5721
5721
|
installed,
|
|
@@ -5956,9 +5956,9 @@ function ConnectorMark({
|
|
|
5956
5956
|
connector,
|
|
5957
5957
|
size = "md"
|
|
5958
5958
|
}) {
|
|
5959
|
-
const candidates =
|
|
5960
|
-
const [attempt, setAttempt] =
|
|
5961
|
-
|
|
5959
|
+
const candidates = React130__default.useMemo(() => markCandidates(connector), [connector.logoUrl, connector.name]);
|
|
5960
|
+
const [attempt, setAttempt] = React130__default.useState(0);
|
|
5961
|
+
React130__default.useEffect(() => setAttempt(0), [connector.id]);
|
|
5962
5962
|
const box = size === "sm" ? "h-9 w-9" : "h-10 w-10";
|
|
5963
5963
|
const glyph = size === "sm" ? "h-4 w-4" : "h-5 w-5";
|
|
5964
5964
|
if (connector.builtIn) {
|
|
@@ -7594,9 +7594,9 @@ function prefersReducedMotion2() {
|
|
|
7594
7594
|
return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
7595
7595
|
}
|
|
7596
7596
|
function TypewriterText({ text: text2, speed = 26, onDone }) {
|
|
7597
|
-
const [displayed, setDisplayed] =
|
|
7598
|
-
const indexRef =
|
|
7599
|
-
|
|
7597
|
+
const [displayed, setDisplayed] = React130.useState("");
|
|
7598
|
+
const indexRef = React130.useRef(0);
|
|
7599
|
+
React130.useEffect(() => {
|
|
7600
7600
|
if (prefersReducedMotion2()) {
|
|
7601
7601
|
setDisplayed(text2);
|
|
7602
7602
|
onDone?.();
|
|
@@ -7673,15 +7673,19 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7673
7673
|
const { contextualSuggestions } = useAITools();
|
|
7674
7674
|
const { sendMessage } = useChat({ apiEndpoint, systemPrompt, agent });
|
|
7675
7675
|
const { t } = useTranslation$1();
|
|
7676
|
-
const [phase, setPhase] =
|
|
7677
|
-
const [activeSuggestion, setActiveSuggestion] =
|
|
7678
|
-
const timersRef =
|
|
7679
|
-
const prevSuggestionRef =
|
|
7680
|
-
const [greeting, setGreeting] =
|
|
7681
|
-
const greetTimerRef =
|
|
7682
|
-
|
|
7676
|
+
const [phase, setPhase] = React130.useState("idle");
|
|
7677
|
+
const [activeSuggestion, setActiveSuggestion] = React130.useState(null);
|
|
7678
|
+
const timersRef = React130.useRef([]);
|
|
7679
|
+
const prevSuggestionRef = React130.useRef(null);
|
|
7680
|
+
const [greeting, setGreeting] = React130.useState(false);
|
|
7681
|
+
const greetTimerRef = React130.useRef(0);
|
|
7682
|
+
React130.useEffect(() => () => window.clearTimeout(greetTimerRef.current), []);
|
|
7683
7683
|
const hasFace = !!host?.AvatarComponent;
|
|
7684
|
-
|
|
7684
|
+
React130.useEffect(ensureStyles, []);
|
|
7685
|
+
React130.useEffect(() => {
|
|
7686
|
+
document.documentElement.classList.add("fz-has-fab");
|
|
7687
|
+
return () => document.documentElement.classList.remove("fz-has-fab");
|
|
7688
|
+
}, []);
|
|
7685
7689
|
const clearTimers = () => {
|
|
7686
7690
|
timersRef.current.forEach(clearTimeout);
|
|
7687
7691
|
timersRef.current = [];
|
|
@@ -7694,10 +7698,10 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7694
7698
|
const invited = useAssistantInviteStore((s) => !!s.invite && s.stage === "dock");
|
|
7695
7699
|
const dockOnScreen = useAssistantInviteStore((s) => !!s.dockBox);
|
|
7696
7700
|
const morphingBack = useAssistantInviteStore((s) => !!s.leaving);
|
|
7697
|
-
const [wide, setWide] =
|
|
7701
|
+
const [wide, setWide] = React130.useState(
|
|
7698
7702
|
() => typeof window !== "undefined" && !!window.matchMedia?.("(min-width: 768px)").matches
|
|
7699
7703
|
);
|
|
7700
|
-
|
|
7704
|
+
React130.useEffect(() => {
|
|
7701
7705
|
const query = window.matchMedia?.("(min-width: 768px)");
|
|
7702
7706
|
if (!query) return;
|
|
7703
7707
|
const sync = () => setWide(query.matches);
|
|
@@ -7706,7 +7710,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7706
7710
|
return () => query.removeEventListener("change", sync);
|
|
7707
7711
|
}, []);
|
|
7708
7712
|
const teaserAllowed = !hasMessages && !activity && !invited && !teaserDismissed() && teaserShownCount() < TEASER_MAX_PER_SESSION;
|
|
7709
|
-
|
|
7713
|
+
React130.useEffect(() => {
|
|
7710
7714
|
if (expanded || !topSuggestion || !topLabel || !teaserAllowed || teaserSeen().includes(topLabel)) {
|
|
7711
7715
|
if (phase !== "idle") {
|
|
7712
7716
|
clearTimers();
|
|
@@ -7737,14 +7741,14 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7737
7741
|
}, 9e3);
|
|
7738
7742
|
return clearTimers;
|
|
7739
7743
|
}, [topLabel, expanded, teaserAllowed]);
|
|
7740
|
-
|
|
7744
|
+
React130.useEffect(() => {
|
|
7741
7745
|
if (expanded && phase !== "idle") {
|
|
7742
7746
|
clearTimers();
|
|
7743
7747
|
setPhase("idle");
|
|
7744
7748
|
}
|
|
7745
7749
|
}, [expanded]);
|
|
7746
|
-
const [entrance, setEntrance] =
|
|
7747
|
-
|
|
7750
|
+
const [entrance, setEntrance] = React130.useState("pending");
|
|
7751
|
+
React130.useEffect(() => {
|
|
7748
7752
|
if (!currentOrg || entrance !== "pending") return;
|
|
7749
7753
|
if (prefersReducedMotion2()) {
|
|
7750
7754
|
setEntrance("done");
|
|
@@ -7754,9 +7758,9 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
7754
7758
|
const timer = setTimeout(() => setEntrance("done"), 1600);
|
|
7755
7759
|
return () => clearTimeout(timer);
|
|
7756
7760
|
}, [currentOrg, entrance]);
|
|
7757
|
-
const [poppingBack, setPoppingBack] =
|
|
7758
|
-
const wasMorphing =
|
|
7759
|
-
|
|
7761
|
+
const [poppingBack, setPoppingBack] = React130.useState(false);
|
|
7762
|
+
const wasMorphing = React130.useRef(false);
|
|
7763
|
+
React130.useEffect(() => {
|
|
7760
7764
|
const was = wasMorphing.current;
|
|
7761
7765
|
wasMorphing.current = morphingBack;
|
|
7762
7766
|
if (!was || morphingBack || prefersReducedMotion2()) return;
|
|
@@ -8054,7 +8058,7 @@ function ChatFab({ className, apiEndpoint, systemPrompt, agent, voice }) {
|
|
|
8054
8058
|
var MAX_SUGGESTIONS = 5;
|
|
8055
8059
|
function ChatSuggestions({ suggestions, onSelect, onDismiss, compact }) {
|
|
8056
8060
|
const { t } = useTranslation$1();
|
|
8057
|
-
const [open, setOpen] =
|
|
8061
|
+
const [open, setOpen] = React130.useState(true);
|
|
8058
8062
|
const visible = suggestions.slice(0, compact ? 3 : MAX_SUGGESTIONS);
|
|
8059
8063
|
if (!visible.length) return null;
|
|
8060
8064
|
return /* @__PURE__ */ jsxs(
|
|
@@ -8133,8 +8137,8 @@ function SuggestionRow({
|
|
|
8133
8137
|
detail,
|
|
8134
8138
|
onSelect
|
|
8135
8139
|
}) {
|
|
8136
|
-
const labelRef =
|
|
8137
|
-
const [showDetail, setShowDetail] =
|
|
8140
|
+
const labelRef = React130.useRef(null);
|
|
8141
|
+
const [showDetail, setShowDetail] = React130.useState(false);
|
|
8138
8142
|
const evaluate = () => {
|
|
8139
8143
|
const el = labelRef.current;
|
|
8140
8144
|
const clipped = !!el && el.scrollWidth > el.clientWidth + 1;
|
|
@@ -8228,8 +8232,8 @@ function ChatToolsPanel({ toolGroups, onClose }) {
|
|
|
8228
8232
|
}
|
|
8229
8233
|
function AutoApprovalsSection() {
|
|
8230
8234
|
const { t } = useTranslation$1();
|
|
8231
|
-
const [rules, setRules] =
|
|
8232
|
-
|
|
8235
|
+
const [rules, setRules] = React130.useState(() => listAutoApprovals());
|
|
8236
|
+
React130.useEffect(() => subscribeAutoApprovals(() => setRules(listAutoApprovals())), []);
|
|
8233
8237
|
if (!rules.length) return null;
|
|
8234
8238
|
return /* @__PURE__ */ jsxs("div", { className: "border-b border-border/40 px-3 py-2.5", children: [
|
|
8235
8239
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 px-1 pb-1.5", children: [
|
|
@@ -8282,14 +8286,14 @@ function bucketOf(iso) {
|
|
|
8282
8286
|
var ORDER = ["today", "yesterday", "week", "older"];
|
|
8283
8287
|
function ChatHistory({ conversations, activeId, onSelect }) {
|
|
8284
8288
|
const { t } = useTranslation$1();
|
|
8285
|
-
const [query, setQuery] =
|
|
8289
|
+
const [query, setQuery] = React130.useState("");
|
|
8286
8290
|
const mine = conversations;
|
|
8287
|
-
const filtered =
|
|
8291
|
+
const filtered = React130.useMemo(() => {
|
|
8288
8292
|
const needle = query.trim().toLowerCase();
|
|
8289
8293
|
if (!needle) return mine;
|
|
8290
8294
|
return mine.filter((c) => (c.title ?? "").toLowerCase().includes(needle));
|
|
8291
8295
|
}, [mine, query]);
|
|
8292
|
-
const groups =
|
|
8296
|
+
const groups = React130.useMemo(() => {
|
|
8293
8297
|
const map = /* @__PURE__ */ new Map();
|
|
8294
8298
|
for (const conversation of filtered) {
|
|
8295
8299
|
const bucket = bucketOf(conversation.updatedAt);
|
|
@@ -8416,7 +8420,7 @@ function TourCoachCard() {
|
|
|
8416
8420
|
const lastOutcome = useTourStore((s) => s.lastOutcome);
|
|
8417
8421
|
const stop = useTourStore((s) => s.stop);
|
|
8418
8422
|
const restart = useTourStore((s) => s.restart);
|
|
8419
|
-
const [dismissedId, setDismissedId] =
|
|
8423
|
+
const [dismissedId, setDismissedId] = React130.useState(null);
|
|
8420
8424
|
const pTitle = usePracticeStore((s) => s.title);
|
|
8421
8425
|
const pSteps = usePracticeStore((s) => s.steps);
|
|
8422
8426
|
const pDone = usePracticeStore((s) => s.done);
|
|
@@ -8487,8 +8491,8 @@ function AssistantRecordingView({ activity }) {
|
|
|
8487
8491
|
const live = activity.state === "running" || activity.state === "paused";
|
|
8488
8492
|
const running = activity.state === "running";
|
|
8489
8493
|
const actions = activity.actions ?? [];
|
|
8490
|
-
const [acknowledged, setAcknowledged] =
|
|
8491
|
-
|
|
8494
|
+
const [acknowledged, setAcknowledged] = React130.useState(false);
|
|
8495
|
+
React130.useEffect(() => setAcknowledged(false), [activity.id, activity.state]);
|
|
8492
8496
|
const withheld = pending2 && !!activity.confirm && !acknowledged;
|
|
8493
8497
|
const primary = actions.filter((a) => a.intent !== "discard");
|
|
8494
8498
|
const discard = actions.find((a) => a.intent === "discard");
|
|
@@ -8704,10 +8708,10 @@ function RightRailPage({
|
|
|
8704
8708
|
const closePage = useRightRailStore((s) => s.closePage);
|
|
8705
8709
|
const active2 = hosted && open;
|
|
8706
8710
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
8707
|
-
const onCloseRef =
|
|
8711
|
+
const onCloseRef = React130.useRef(onClose);
|
|
8708
8712
|
onCloseRef.current = onClose;
|
|
8709
|
-
const claimed =
|
|
8710
|
-
|
|
8713
|
+
const claimed = React130.useRef(false);
|
|
8714
|
+
React130.useEffect(() => {
|
|
8711
8715
|
if (!active2) return;
|
|
8712
8716
|
showPage();
|
|
8713
8717
|
claimed.current = true;
|
|
@@ -8716,7 +8720,7 @@ function RightRailPage({
|
|
|
8716
8720
|
closePage();
|
|
8717
8721
|
};
|
|
8718
8722
|
}, [active2, showPage, closePage]);
|
|
8719
|
-
|
|
8723
|
+
React130.useEffect(() => {
|
|
8720
8724
|
if (!claimed.current) return;
|
|
8721
8725
|
if (!useRightRailStore.getState().pageOpen) onCloseRef.current();
|
|
8722
8726
|
}, [pageOpen]);
|
|
@@ -8919,15 +8923,15 @@ function ConnectorSyncActions({
|
|
|
8919
8923
|
actions,
|
|
8920
8924
|
onRan
|
|
8921
8925
|
}) {
|
|
8922
|
-
const [running, setRunning] =
|
|
8923
|
-
const [open, setOpen] =
|
|
8924
|
-
const [pending2, setPending] =
|
|
8925
|
-
const [hidden, setHidden] =
|
|
8926
|
-
const [queued, setQueued] =
|
|
8927
|
-
const [nonce, setNonce] =
|
|
8928
|
-
const [expanded, setExpanded] =
|
|
8929
|
-
const [resolved, setResolved] =
|
|
8930
|
-
|
|
8926
|
+
const [running, setRunning] = React130__default.useState(null);
|
|
8927
|
+
const [open, setOpen] = React130__default.useState(null);
|
|
8928
|
+
const [pending2, setPending] = React130__default.useState(null);
|
|
8929
|
+
const [hidden, setHidden] = React130__default.useState(() => /* @__PURE__ */ new Set());
|
|
8930
|
+
const [queued, setQueued] = React130__default.useState({});
|
|
8931
|
+
const [nonce, setNonce] = React130__default.useState(0);
|
|
8932
|
+
const [expanded, setExpanded] = React130__default.useState(false);
|
|
8933
|
+
const [resolved, setResolved] = React130__default.useState(false);
|
|
8934
|
+
React130__default.useEffect(() => {
|
|
8931
8935
|
let cancelled = false;
|
|
8932
8936
|
setResolved(false);
|
|
8933
8937
|
void Promise.all(
|
|
@@ -9112,10 +9116,10 @@ function formatRelative(iso, t) {
|
|
|
9112
9116
|
}
|
|
9113
9117
|
function useConnectorRuns(connector) {
|
|
9114
9118
|
const listRuns = connector.definition?.listRuns;
|
|
9115
|
-
const [runs, setRuns] =
|
|
9116
|
-
const [loading, setLoading] =
|
|
9117
|
-
const [nonce, setNonce] =
|
|
9118
|
-
|
|
9119
|
+
const [runs, setRuns] = React130__default.useState([]);
|
|
9120
|
+
const [loading, setLoading] = React130__default.useState(!!listRuns);
|
|
9121
|
+
const [nonce, setNonce] = React130__default.useState(0);
|
|
9122
|
+
React130__default.useEffect(() => {
|
|
9119
9123
|
if (!listRuns) {
|
|
9120
9124
|
setRuns([]);
|
|
9121
9125
|
setLoading(false);
|
|
@@ -9137,7 +9141,7 @@ function useConnectorRuns(connector) {
|
|
|
9137
9141
|
return {
|
|
9138
9142
|
runs,
|
|
9139
9143
|
loading,
|
|
9140
|
-
reload:
|
|
9144
|
+
reload: React130__default.useCallback(() => setNonce((n) => n + 1), []),
|
|
9141
9145
|
failing: isFailing(runs)
|
|
9142
9146
|
};
|
|
9143
9147
|
}
|
|
@@ -9237,7 +9241,7 @@ function RunFailure({ run }) {
|
|
|
9237
9241
|
),
|
|
9238
9242
|
/* @__PURE__ */ jsx("span", { className: "sr-only", children: t("connectors.runs.seeDetails") })
|
|
9239
9243
|
] }),
|
|
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(
|
|
9244
|
+
facts.length > 0 && /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 border-t border-border px-2 py-2 text-[11px] leading-relaxed", children: facts.map(([label3, value]) => /* @__PURE__ */ jsxs(React130__default.Fragment, { children: [
|
|
9241
9245
|
/* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: label3 }),
|
|
9242
9246
|
/* @__PURE__ */ jsx("dd", { className: "min-w-0 break-words font-mono text-foreground/80", children: value })
|
|
9243
9247
|
] }, label3)) }),
|
|
@@ -9406,13 +9410,13 @@ function ConnectorSettingsPanel({
|
|
|
9406
9410
|
const { t } = useTranslation$1();
|
|
9407
9411
|
const def = connector.definition;
|
|
9408
9412
|
const settings = def ? connectorSettings(def) : [];
|
|
9409
|
-
const [values, setValues] =
|
|
9413
|
+
const [values, setValues] = React130__default.useState(
|
|
9410
9414
|
() => initialValues(settings, {})
|
|
9411
9415
|
);
|
|
9412
|
-
const [loaded2, setLoaded] =
|
|
9413
|
-
const [saving, setSaving] =
|
|
9414
|
-
const [dirty, setDirty] =
|
|
9415
|
-
|
|
9416
|
+
const [loaded2, setLoaded] = React130__default.useState(false);
|
|
9417
|
+
const [saving, setSaving] = React130__default.useState(false);
|
|
9418
|
+
const [dirty, setDirty] = React130__default.useState(false);
|
|
9419
|
+
React130__default.useEffect(() => {
|
|
9416
9420
|
if (settings.length === 0 || !def?.getSettings) return;
|
|
9417
9421
|
let cancelled = false;
|
|
9418
9422
|
setLoaded(false);
|
|
@@ -9663,13 +9667,13 @@ function ConnectorInstall({
|
|
|
9663
9667
|
}) {
|
|
9664
9668
|
const { t } = useTranslation$1();
|
|
9665
9669
|
const def = connector.definition;
|
|
9666
|
-
const [plane, setPlane] =
|
|
9670
|
+
const [plane, setPlane] = React130__default.useState(
|
|
9667
9671
|
connector.planes.includes("agentic") ? "agentic" : connector.planes[0]
|
|
9668
9672
|
);
|
|
9669
|
-
const [values, setValues] =
|
|
9670
|
-
const secrets =
|
|
9671
|
-
const [busy, setBusy] =
|
|
9672
|
-
|
|
9673
|
+
const [values, setValues] = React130__default.useState({});
|
|
9674
|
+
const secrets = React130__default.useRef({});
|
|
9675
|
+
const [busy, setBusy] = React130__default.useState(null);
|
|
9676
|
+
React130__default.useEffect(() => {
|
|
9673
9677
|
setValues({});
|
|
9674
9678
|
secrets.current = {};
|
|
9675
9679
|
setBusy(null);
|
|
@@ -9710,15 +9714,15 @@ function ConnectorHome({
|
|
|
9710
9714
|
const needsSetup = connector.state === "needs_setup";
|
|
9711
9715
|
const settingsAvailable = hasOperatingSettings(connector);
|
|
9712
9716
|
const runsAvailable = hasRunHistory(connector);
|
|
9713
|
-
const [tab, setTab] =
|
|
9717
|
+
const [tab, setTab] = React130__default.useState(
|
|
9714
9718
|
needsSetup && settingsAvailable ? "settings" : "overview"
|
|
9715
9719
|
);
|
|
9716
|
-
const [busy, setBusy] =
|
|
9720
|
+
const [busy, setBusy] = React130__default.useState(null);
|
|
9717
9721
|
const run = useRunner(setBusy, onChanged);
|
|
9718
|
-
const [values, setValues] =
|
|
9719
|
-
const secrets =
|
|
9722
|
+
const [values, setValues] = React130__default.useState({});
|
|
9723
|
+
const secrets = React130__default.useRef({});
|
|
9720
9724
|
const runs = useConnectorRuns(connector);
|
|
9721
|
-
|
|
9725
|
+
React130__default.useEffect(() => {
|
|
9722
9726
|
setTab(needsSetup && settingsAvailable ? "settings" : "overview");
|
|
9723
9727
|
setBusy(null);
|
|
9724
9728
|
setValues({});
|
|
@@ -9808,7 +9812,7 @@ function ConnectorHome({
|
|
|
9808
9812
|
}
|
|
9809
9813
|
function useRunner(setBusy, onChanged) {
|
|
9810
9814
|
const { t } = useTranslation$1();
|
|
9811
|
-
return
|
|
9815
|
+
return React130__default.useCallback(
|
|
9812
9816
|
async (kind, fn, okMessage) => {
|
|
9813
9817
|
setBusy(kind);
|
|
9814
9818
|
try {
|
|
@@ -9924,7 +9928,7 @@ function ConnectPanel({
|
|
|
9924
9928
|
const sinkMissing = needsSink && !getConnectorCredentialSink();
|
|
9925
9929
|
const secretFieldCount = (def.fields ?? []).filter(isSecretField).length;
|
|
9926
9930
|
const hasStoredCredential = connector.state === "connected" || connector.state === "needs_setup";
|
|
9927
|
-
const [formKey, setFormKey] =
|
|
9931
|
+
const [formKey, setFormKey] = React130__default.useState(0);
|
|
9928
9932
|
if (def.authKind === "oauth") {
|
|
9929
9933
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
9930
9934
|
/* @__PURE__ */ jsx(Note, { children: t("connectors.authorize.oauthOnly") }),
|
|
@@ -10057,7 +10061,7 @@ function GrantRevoke({
|
|
|
10057
10061
|
onRevoke
|
|
10058
10062
|
}) {
|
|
10059
10063
|
const { t } = useTranslation$1();
|
|
10060
|
-
const [revoking, setRevoking] =
|
|
10064
|
+
const [revoking, setRevoking] = React130__default.useState(false);
|
|
10061
10065
|
if (connector.revocable === false) {
|
|
10062
10066
|
return /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("connectors.partOfApp") });
|
|
10063
10067
|
}
|
|
@@ -10096,14 +10100,14 @@ function ConnectorsPanel({ onClose }) {
|
|
|
10096
10100
|
const { connectors, reload, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
10097
10101
|
const selectedId = useConnectorsSurface((s) => s.selected);
|
|
10098
10102
|
const select = useConnectorsSurface((s) => s.select);
|
|
10099
|
-
const [query, setQuery] =
|
|
10100
|
-
const [failure, setFailure] =
|
|
10101
|
-
const [revoking, setRevoking] =
|
|
10102
|
-
const selected =
|
|
10103
|
+
const [query, setQuery] = React130__default.useState("");
|
|
10104
|
+
const [failure, setFailure] = React130__default.useState(null);
|
|
10105
|
+
const [revoking, setRevoking] = React130__default.useState(null);
|
|
10106
|
+
const selected = React130__default.useMemo(
|
|
10103
10107
|
() => (connectors ?? []).find((c) => c.id === selectedId) ?? null,
|
|
10104
10108
|
[connectors, selectedId]
|
|
10105
10109
|
);
|
|
10106
|
-
const filtered =
|
|
10110
|
+
const filtered = React130__default.useMemo(
|
|
10107
10111
|
() => filterConnectors(connectors ?? [], "outbound", query),
|
|
10108
10112
|
[connectors, query]
|
|
10109
10113
|
);
|
|
@@ -10114,9 +10118,9 @@ function ConnectorsPanel({ onClose }) {
|
|
|
10114
10118
|
back: onClose
|
|
10115
10119
|
} : null
|
|
10116
10120
|
);
|
|
10117
|
-
const closeRef =
|
|
10121
|
+
const closeRef = React130__default.useRef(onClose);
|
|
10118
10122
|
closeRef.current = onClose;
|
|
10119
|
-
|
|
10123
|
+
React130__default.useEffect(() => {
|
|
10120
10124
|
if (hosted && !selectedId) closeRef.current();
|
|
10121
10125
|
}, [hosted, selectedId]);
|
|
10122
10126
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [
|
|
@@ -10244,20 +10248,20 @@ function useDictation({
|
|
|
10244
10248
|
onInterim
|
|
10245
10249
|
}) {
|
|
10246
10250
|
const resolvedLocale = locale ?? (typeof navigator !== "undefined" ? navigator.language || "pt-BR" : "pt-BR");
|
|
10247
|
-
const [state, setState] =
|
|
10248
|
-
const [error, setError] =
|
|
10249
|
-
const sessionRef =
|
|
10250
|
-
const callbacks =
|
|
10251
|
+
const [state, setState] = React130.useState("idle");
|
|
10252
|
+
const [error, setError] = React130.useState(null);
|
|
10253
|
+
const sessionRef = React130.useRef(null);
|
|
10254
|
+
const callbacks = React130.useRef({ onTranscript, onInterim });
|
|
10251
10255
|
callbacks.current = { onTranscript, onInterim };
|
|
10252
|
-
const supported =
|
|
10256
|
+
const supported = React130.useMemo(
|
|
10253
10257
|
() => isDictationSupported(!!transcribeEndpoint),
|
|
10254
10258
|
[transcribeEndpoint]
|
|
10255
10259
|
);
|
|
10256
|
-
const finish =
|
|
10260
|
+
const finish = React130.useCallback(() => {
|
|
10257
10261
|
sessionRef.current = null;
|
|
10258
10262
|
setState("idle");
|
|
10259
10263
|
}, []);
|
|
10260
|
-
const start =
|
|
10264
|
+
const start = React130.useCallback(() => {
|
|
10261
10265
|
if (sessionRef.current || !supported) return;
|
|
10262
10266
|
stopSpeaking();
|
|
10263
10267
|
setError(null);
|
|
@@ -10278,28 +10282,28 @@ function useDictation({
|
|
|
10278
10282
|
}
|
|
10279
10283
|
);
|
|
10280
10284
|
}, [finish, resolvedLocale, supported, transcribeEndpoint]);
|
|
10281
|
-
const stop =
|
|
10285
|
+
const stop = React130.useCallback(() => {
|
|
10282
10286
|
if (!sessionRef.current) return;
|
|
10283
10287
|
if (transcribeEndpoint) setState("transcribing");
|
|
10284
10288
|
sessionRef.current.stop();
|
|
10285
10289
|
}, [transcribeEndpoint]);
|
|
10286
|
-
const cancel =
|
|
10290
|
+
const cancel = React130.useCallback(() => {
|
|
10287
10291
|
sessionRef.current?.cancel();
|
|
10288
10292
|
sessionRef.current = null;
|
|
10289
10293
|
setState("idle");
|
|
10290
10294
|
setError(null);
|
|
10291
10295
|
}, []);
|
|
10292
|
-
const toggle =
|
|
10296
|
+
const toggle = React130.useCallback(() => {
|
|
10293
10297
|
if (state === "listening" || state === "transcribing") stop();
|
|
10294
10298
|
else start();
|
|
10295
10299
|
}, [state, start, stop]);
|
|
10296
|
-
|
|
10300
|
+
React130.useEffect(() => () => sessionRef.current?.cancel(), []);
|
|
10297
10301
|
return { supported, state, error, start, stop, cancel, toggle, clearError: () => setError(null) };
|
|
10298
10302
|
}
|
|
10299
10303
|
function useMicLevels(active2, bandCount = 28, externalStream) {
|
|
10300
|
-
const levelsRef =
|
|
10301
|
-
const [available, setAvailable] =
|
|
10302
|
-
|
|
10304
|
+
const levelsRef = React130.useRef(new Float32Array(bandCount));
|
|
10305
|
+
const [available, setAvailable] = React130.useState(false);
|
|
10306
|
+
React130.useEffect(() => {
|
|
10303
10307
|
if (!active2) {
|
|
10304
10308
|
levelsRef.current.fill(0);
|
|
10305
10309
|
setAvailable(false);
|
|
@@ -10368,8 +10372,8 @@ var KIND_ICON = {
|
|
|
10368
10372
|
binary: File$1
|
|
10369
10373
|
};
|
|
10370
10374
|
function useFileDrop(enabled, onFiles) {
|
|
10371
|
-
const [dragging, setDragging] =
|
|
10372
|
-
const depth =
|
|
10375
|
+
const [dragging, setDragging] = React130.useState(false);
|
|
10376
|
+
const depth = React130.useRef(0);
|
|
10373
10377
|
const carriesFiles = (event) => Array.from(event.dataTransfer?.types ?? []).includes("Files");
|
|
10374
10378
|
const reset = () => {
|
|
10375
10379
|
depth.current = 0;
|
|
@@ -10429,7 +10433,7 @@ function AttachmentChips({
|
|
|
10429
10433
|
onRemove
|
|
10430
10434
|
}) {
|
|
10431
10435
|
const { t } = useTranslation$1();
|
|
10432
|
-
const [openId, setOpenId] =
|
|
10436
|
+
const [openId, setOpenId] = React130.useState(null);
|
|
10433
10437
|
if (!attachments.length) return null;
|
|
10434
10438
|
const opened = attachments.find((a) => a.id === openId);
|
|
10435
10439
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -10570,8 +10574,8 @@ function ChatComposer({
|
|
|
10570
10574
|
autoFocus
|
|
10571
10575
|
}) {
|
|
10572
10576
|
const { t } = useTranslation$1();
|
|
10573
|
-
const [input, setInput] =
|
|
10574
|
-
const textareaRef =
|
|
10577
|
+
const [input, setInput] = React130.useState("");
|
|
10578
|
+
const textareaRef = React130.useRef(null);
|
|
10575
10579
|
const voiceStartRequested = useChatStore((s) => s.voiceStartRequested);
|
|
10576
10580
|
const consumeVoiceStart = useChatStore((s) => s.consumeVoiceStart);
|
|
10577
10581
|
const draft = useChatStore((s) => s.draft);
|
|
@@ -10584,13 +10588,13 @@ function ChatComposer({
|
|
|
10584
10588
|
const removeAttachment = useChatStore((s) => s.removeAttachment);
|
|
10585
10589
|
const composerMedia = useChatStore((s) => s.composerMedia);
|
|
10586
10590
|
const clearComposerMedia = useChatStore((s) => s.clearComposerMedia);
|
|
10587
|
-
const fileInputRef =
|
|
10591
|
+
const fileInputRef = React130.useRef(null);
|
|
10588
10592
|
const autoSend = voice?.autoSend === true;
|
|
10589
10593
|
const micEnabled = voice?.input !== false;
|
|
10590
10594
|
const canAttach = isConfigured && !blocked && !isStreaming;
|
|
10591
10595
|
const parsing = attachments.some((a) => a.status === "parsing");
|
|
10592
10596
|
const readyAttachments = attachments.filter((a) => a.status === "ready").length;
|
|
10593
|
-
const submit =
|
|
10597
|
+
const submit = React130.useCallback(
|
|
10594
10598
|
(text2) => {
|
|
10595
10599
|
const trimmed = text2.trim();
|
|
10596
10600
|
const media = useChatStore.getState().composerMedia;
|
|
@@ -10620,7 +10624,7 @@ function ChatComposer({
|
|
|
10620
10624
|
}
|
|
10621
10625
|
}
|
|
10622
10626
|
});
|
|
10623
|
-
|
|
10627
|
+
React130.useEffect(() => {
|
|
10624
10628
|
if (!autoFocus) return;
|
|
10625
10629
|
const id = requestAnimationFrame(() => textareaRef.current?.focus());
|
|
10626
10630
|
return () => cancelAnimationFrame(id);
|
|
@@ -10632,7 +10636,7 @@ function ChatComposer({
|
|
|
10632
10636
|
const WAVEFORM_BANDS = 56;
|
|
10633
10637
|
const activity = useAssistantActivity();
|
|
10634
10638
|
const sessionRecording = activity?.kind === "recording" && activity.state === "running";
|
|
10635
|
-
const sessionStream =
|
|
10639
|
+
const sessionStream = React130.useMemo(
|
|
10636
10640
|
() => sessionRecording ? activity?.stream?.() ?? null : null,
|
|
10637
10641
|
[sessionRecording, activity]
|
|
10638
10642
|
);
|
|
@@ -10644,12 +10648,12 @@ function ChatComposer({
|
|
|
10644
10648
|
);
|
|
10645
10649
|
const sessionPause = activity?.actions?.find((a) => a.intent === "pause" || a.intent === "resume");
|
|
10646
10650
|
const sessionOwnsMic = activity?.kind === "recording" && (activity.state === "running" || activity.state === "paused");
|
|
10647
|
-
|
|
10651
|
+
React130.useEffect(() => {
|
|
10648
10652
|
if (!voiceStartRequested) return;
|
|
10649
10653
|
consumeVoiceStart();
|
|
10650
10654
|
if (showMic) dictation.start();
|
|
10651
10655
|
}, [voiceStartRequested, showMic]);
|
|
10652
|
-
|
|
10656
|
+
React130.useEffect(() => {
|
|
10653
10657
|
if (!focusRequested) return;
|
|
10654
10658
|
let frames = 0;
|
|
10655
10659
|
let raf = 0;
|
|
@@ -10666,7 +10670,7 @@ function ChatComposer({
|
|
|
10666
10670
|
raf = requestAnimationFrame(tick);
|
|
10667
10671
|
return () => cancelAnimationFrame(raf);
|
|
10668
10672
|
}, [focusRequested, consumeComposerFocus]);
|
|
10669
|
-
|
|
10673
|
+
React130.useEffect(() => {
|
|
10670
10674
|
if (!draft) return;
|
|
10671
10675
|
setInput(draft);
|
|
10672
10676
|
setDraft("");
|
|
@@ -10676,7 +10680,7 @@ function ChatComposer({
|
|
|
10676
10680
|
el.setSelectionRange(draft.length, draft.length);
|
|
10677
10681
|
}
|
|
10678
10682
|
}, [draft, setDraft]);
|
|
10679
|
-
|
|
10683
|
+
React130.useLayoutEffect(() => {
|
|
10680
10684
|
const el = textareaRef.current;
|
|
10681
10685
|
if (!el) return;
|
|
10682
10686
|
const style = getComputedStyle(el);
|
|
@@ -10879,8 +10883,8 @@ function UploadRequestCard() {
|
|
|
10879
10883
|
const removeUploadFile = useChatStore((s) => s.removeUploadFile);
|
|
10880
10884
|
const submitUpload = useChatStore((s) => s.submitUpload);
|
|
10881
10885
|
const clearUploadRequest = useChatStore((s) => s.clearUploadRequest);
|
|
10882
|
-
const cameraRef =
|
|
10883
|
-
const browseRef =
|
|
10886
|
+
const cameraRef = React130.useRef(null);
|
|
10887
|
+
const browseRef = React130.useRef(null);
|
|
10884
10888
|
if (!request) return null;
|
|
10885
10889
|
const working = request.status === "working";
|
|
10886
10890
|
const accept = request.accept ?? "image/*";
|
|
@@ -11022,8 +11026,8 @@ function LiveWaveform({
|
|
|
11022
11026
|
compact,
|
|
11023
11027
|
tone = "primary"
|
|
11024
11028
|
}) {
|
|
11025
|
-
const barsRef =
|
|
11026
|
-
|
|
11029
|
+
const barsRef = React130.useRef([]);
|
|
11030
|
+
React130.useEffect(() => {
|
|
11027
11031
|
if (!live) return;
|
|
11028
11032
|
let frame = 0;
|
|
11029
11033
|
const draw = () => {
|
|
@@ -11172,7 +11176,7 @@ function ChatMarkdown({ content }) {
|
|
|
11172
11176
|
}
|
|
11173
11177
|
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}`);
|
|
11174
11178
|
const prev = items.pop();
|
|
11175
|
-
if (prev &&
|
|
11179
|
+
if (prev && React130.isValidElement(prev)) {
|
|
11176
11180
|
items.push(
|
|
11177
11181
|
/* @__PURE__ */ jsxs("li", { children: [
|
|
11178
11182
|
prev.props.children,
|
|
@@ -11269,7 +11273,7 @@ var CARD_CTA = {
|
|
|
11269
11273
|
function useConnectorJourney(card) {
|
|
11270
11274
|
const panelAvailable = useConnectorsPanelAvailable();
|
|
11271
11275
|
useChatStore((s) => s.setOpen);
|
|
11272
|
-
return
|
|
11276
|
+
return React130.useCallback(() => {
|
|
11273
11277
|
if (panelAvailable && card.id) {
|
|
11274
11278
|
openConnectorsPanel({ id: card.id });
|
|
11275
11279
|
return;
|
|
@@ -11359,7 +11363,7 @@ function ConnectorSuggestionRow({ card }) {
|
|
|
11359
11363
|
] });
|
|
11360
11364
|
}
|
|
11361
11365
|
function ConnectorSuggestionGroup({ cards }) {
|
|
11362
|
-
const shelves =
|
|
11366
|
+
const shelves = React130.useMemo(() => shelveByCategory(cards), [cards]);
|
|
11363
11367
|
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: [
|
|
11364
11368
|
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 }),
|
|
11365
11369
|
/* @__PURE__ */ jsx("div", { className: "divide-y divide-border/40", children: shelf.items.map((card) => /* @__PURE__ */ jsx(ConnectorSuggestionRow, { card }, card.slug ?? card.id ?? card.name)) })
|
|
@@ -11369,8 +11373,8 @@ function ChoiceCard({ card }) {
|
|
|
11369
11373
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
11370
11374
|
const isStreaming = useChatStore((s) => s.isStreaming);
|
|
11371
11375
|
const messages = useChatStore((s) => s.messages);
|
|
11372
|
-
const [optimistic, setOptimistic] =
|
|
11373
|
-
const answeredInThread =
|
|
11376
|
+
const [optimistic, setOptimistic] = React130.useState(null);
|
|
11377
|
+
const answeredInThread = React130.useMemo(
|
|
11374
11378
|
() => answeredOptionId(messages, card.options),
|
|
11375
11379
|
[messages, card.options]
|
|
11376
11380
|
);
|
|
@@ -11425,7 +11429,7 @@ function humanizeToolName(name) {
|
|
|
11425
11429
|
}
|
|
11426
11430
|
function ToolCallRow({ call: call2 }) {
|
|
11427
11431
|
const { t } = useTranslation$1();
|
|
11428
|
-
const [open, setOpen] =
|
|
11432
|
+
const [open, setOpen] = React130.useState(false);
|
|
11429
11433
|
const failed = call2.declined || /"error"\s*:/.test(call2.result ?? "");
|
|
11430
11434
|
return /* @__PURE__ */ jsxs("div", { className: "overflow-hidden rounded-xl border border-border/50 bg-muted/30", children: [
|
|
11431
11435
|
/* @__PURE__ */ jsxs(
|
|
@@ -11502,15 +11506,15 @@ function HandoffNotice({ notice }) {
|
|
|
11502
11506
|
}
|
|
11503
11507
|
function MessageBubble({ message, isPending }) {
|
|
11504
11508
|
const isUser = message.role === "user";
|
|
11505
|
-
const connectorCards =
|
|
11509
|
+
const connectorCards = React130.useMemo(
|
|
11506
11510
|
() => (message.cards ?? []).filter((card) => card.kind === "connector"),
|
|
11507
11511
|
[message.cards]
|
|
11508
11512
|
);
|
|
11509
|
-
const choiceCards =
|
|
11513
|
+
const choiceCards = React130.useMemo(
|
|
11510
11514
|
() => (message.cards ?? []).filter((card) => card.kind === "choice"),
|
|
11511
11515
|
[message.cards]
|
|
11512
11516
|
);
|
|
11513
|
-
const routedLinks =
|
|
11517
|
+
const routedLinks = React130.useMemo(
|
|
11514
11518
|
() => (message.links ?? []).filter(
|
|
11515
11519
|
(l) => !!l.path || !!resolveEntityRoute(l.archetype, l.kind, l.entityKey)
|
|
11516
11520
|
),
|
|
@@ -11601,9 +11605,9 @@ function ConfirmActionCard({
|
|
|
11601
11605
|
onResolveAll
|
|
11602
11606
|
}) {
|
|
11603
11607
|
const { t } = useTranslation$1();
|
|
11604
|
-
const schema =
|
|
11608
|
+
const schema = React130.useMemo(() => action.fields ?? [], [action.fields]);
|
|
11605
11609
|
const partial = action.partial === true;
|
|
11606
|
-
const seedValues =
|
|
11610
|
+
const seedValues = React130.useCallback(
|
|
11607
11611
|
(params) => {
|
|
11608
11612
|
if (partial) return { ...params };
|
|
11609
11613
|
const seeded = {};
|
|
@@ -11612,18 +11616,18 @@ function ConfirmActionCard({
|
|
|
11612
11616
|
},
|
|
11613
11617
|
[schema, partial]
|
|
11614
11618
|
);
|
|
11615
|
-
const [values, setValues] =
|
|
11616
|
-
const [showAll, setShowAll] =
|
|
11619
|
+
const [values, setValues] = React130.useState(() => seedValues(action.params));
|
|
11620
|
+
const [showAll, setShowAll] = React130.useState(false);
|
|
11617
11621
|
const batch = Math.max(0, sameToolQueued);
|
|
11618
|
-
|
|
11622
|
+
React130.useEffect(() => setValues(seedValues(action.params)), [action.params, seedValues]);
|
|
11619
11623
|
const isSet = (v) => v !== void 0 && v !== null && v !== "";
|
|
11620
|
-
const primaryKeys =
|
|
11624
|
+
const primaryKeys = React130.useMemo(() => {
|
|
11621
11625
|
const keys = Object.keys(action.params).filter((k) => isSet(action.params[k]));
|
|
11622
11626
|
if (partial) return keys;
|
|
11623
11627
|
for (const f of schema) if (f.required && !keys.includes(f.key)) keys.push(f.key);
|
|
11624
11628
|
return keys;
|
|
11625
11629
|
}, [action.params, schema, partial]);
|
|
11626
|
-
const extraKeys =
|
|
11630
|
+
const extraKeys = React130.useMemo(
|
|
11627
11631
|
() => schema.map((f) => f.key).filter((k) => !primaryKeys.includes(k) && k !== "id"),
|
|
11628
11632
|
[schema, primaryKeys]
|
|
11629
11633
|
);
|
|
@@ -11650,20 +11654,20 @@ function ConfirmActionCard({
|
|
|
11650
11654
|
if (sharedLabel !== shared) return sharedLabel;
|
|
11651
11655
|
return humanizeKey(key);
|
|
11652
11656
|
};
|
|
11653
|
-
const missingRequiredKeys =
|
|
11657
|
+
const missingRequiredKeys = React130.useMemo(
|
|
11654
11658
|
() => partial ? [] : schema.filter((f) => f.required && !isSet(values[f.key])).map((f) => f.key),
|
|
11655
11659
|
[schema, values, partial]
|
|
11656
11660
|
);
|
|
11657
11661
|
const canConfirm = missingRequiredKeys.length === 0;
|
|
11658
|
-
const submitted =
|
|
11662
|
+
const submitted = React130.useCallback(
|
|
11659
11663
|
() => partial ? Object.fromEntries(Object.entries(values).filter(([, v]) => isSet(v))) : values,
|
|
11660
11664
|
[partial, values]
|
|
11661
11665
|
);
|
|
11662
|
-
const approve =
|
|
11666
|
+
const approve = React130.useCallback(() => {
|
|
11663
11667
|
if (canConfirm) onResolve(true, submitted());
|
|
11664
11668
|
}, [canConfirm, onResolve, submitted]);
|
|
11665
|
-
const decline =
|
|
11666
|
-
const approveAlways =
|
|
11669
|
+
const decline = React130.useCallback(() => onResolve(false), [onResolve]);
|
|
11670
|
+
const approveAlways = React130.useCallback(() => {
|
|
11667
11671
|
if (!canConfirm) return;
|
|
11668
11672
|
grantAutoApproval({
|
|
11669
11673
|
toolName: action.toolName,
|
|
@@ -11673,7 +11677,7 @@ function ConfirmActionCard({
|
|
|
11673
11677
|
});
|
|
11674
11678
|
onResolve(true, submitted());
|
|
11675
11679
|
}, [canConfirm, action.toolName, action.scope, ruleLabel, destructive, onResolve, submitted]);
|
|
11676
|
-
|
|
11680
|
+
React130.useEffect(() => {
|
|
11677
11681
|
const handler = (event) => {
|
|
11678
11682
|
const target = event.target;
|
|
11679
11683
|
const typing = target?.tagName === "INPUT" || target?.tagName === "TEXTAREA" || target?.tagName === "SELECT";
|
|
@@ -12010,8 +12014,8 @@ var TYPE_MS = 620;
|
|
|
12010
12014
|
var MIN_CHAR_MS = 12;
|
|
12011
12015
|
var MAX_CHAR_MS = 34;
|
|
12012
12016
|
function usePrefersReducedMotion() {
|
|
12013
|
-
const [reduced, setReduced] =
|
|
12014
|
-
|
|
12017
|
+
const [reduced, setReduced] = React130.useState(false);
|
|
12018
|
+
React130.useEffect(() => {
|
|
12015
12019
|
if (typeof matchMedia !== "function") return;
|
|
12016
12020
|
const query = matchMedia("(prefers-reduced-motion: reduce)");
|
|
12017
12021
|
const sync = () => setReduced(query.matches);
|
|
@@ -12030,10 +12034,10 @@ function TypedText({
|
|
|
12030
12034
|
onDone
|
|
12031
12035
|
}) {
|
|
12032
12036
|
const reduced = usePrefersReducedMotion();
|
|
12033
|
-
const [count, setCount] =
|
|
12034
|
-
const done =
|
|
12037
|
+
const [count, setCount] = React130.useState(reduced ? text2.length : 0);
|
|
12038
|
+
const done = React130.useRef(onDone);
|
|
12035
12039
|
done.current = onDone;
|
|
12036
|
-
|
|
12040
|
+
React130.useEffect(() => {
|
|
12037
12041
|
if (!start) {
|
|
12038
12042
|
setCount(0);
|
|
12039
12043
|
return;
|
|
@@ -12073,9 +12077,9 @@ function RevealSequence({
|
|
|
12073
12077
|
children
|
|
12074
12078
|
}) {
|
|
12075
12079
|
const reduced = usePrefersReducedMotion();
|
|
12076
|
-
const items =
|
|
12077
|
-
const [shown, setShown] =
|
|
12078
|
-
|
|
12080
|
+
const items = React130.Children.toArray(children);
|
|
12081
|
+
const [shown, setShown] = React130.useState(0);
|
|
12082
|
+
React130.useEffect(() => {
|
|
12079
12083
|
if (!start) {
|
|
12080
12084
|
setShown(0);
|
|
12081
12085
|
return;
|
|
@@ -12137,7 +12141,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
12137
12141
|
const currentPlan = plans.find((p) => p.id === currentPlanId);
|
|
12138
12142
|
const currentPrice = currentPlan?.price ?? 0;
|
|
12139
12143
|
const currentPlanName = currentPlan?.name ?? tr("billing.free", "Free");
|
|
12140
|
-
const featureName =
|
|
12144
|
+
const featureName = React130.useMemo(() => {
|
|
12141
12145
|
if (!feature) return null;
|
|
12142
12146
|
const label3 = features.find((f) => f.id === feature)?.label;
|
|
12143
12147
|
if (label3) return featureDisplayName(label3);
|
|
@@ -12145,7 +12149,7 @@ function UpgradePrompt({ feature, inline, className }) {
|
|
|
12145
12149
|
const named = t(key);
|
|
12146
12150
|
return named && named !== key ? named : featureDisplayName(feature);
|
|
12147
12151
|
}, [features, feature, t]);
|
|
12148
|
-
const unlockingPlans =
|
|
12152
|
+
const unlockingPlans = React130.useMemo(
|
|
12149
12153
|
() => plans.filter((p) => p.id !== currentPlanId && p.price > currentPrice && planUnlocks(p, feature)).sort((a, b) => a.price - b.price),
|
|
12150
12154
|
[plans, currentPlanId, currentPrice, feature]
|
|
12151
12155
|
);
|
|
@@ -12327,26 +12331,26 @@ function ChatConversation({
|
|
|
12327
12331
|
usable && !pendingAction && !isStreaming,
|
|
12328
12332
|
receiveFiles
|
|
12329
12333
|
);
|
|
12330
|
-
|
|
12331
|
-
const [view, setView] =
|
|
12334
|
+
React130.useEffect(ensureIntroStyles, []);
|
|
12335
|
+
const [view, setView] = React130.useState(
|
|
12332
12336
|
() => useChatStore.getState().messages.length > 0 ? "thread" : "list"
|
|
12333
12337
|
);
|
|
12334
|
-
const [drawer, setDrawer] =
|
|
12335
|
-
const [introStep, setIntroStep] =
|
|
12336
|
-
const [atBottom, setAtBottom] =
|
|
12337
|
-
const scrollRef =
|
|
12338
|
+
const [drawer, setDrawer] = React130.useState("none");
|
|
12339
|
+
const [introStep, setIntroStep] = React130.useState(0);
|
|
12340
|
+
const [atBottom, setAtBottom] = React130.useState(true);
|
|
12341
|
+
const scrollRef = React130.useRef(null);
|
|
12338
12342
|
const hasMessages = messages.length > 0;
|
|
12339
12343
|
const showThread = view === "thread" && hasMessages;
|
|
12340
12344
|
const totalTools = toolGroups.reduce((sum, g) => sum + g.tools.length, 0);
|
|
12341
|
-
const scrollToBottom =
|
|
12345
|
+
const scrollToBottom = React130.useCallback((behavior = "smooth") => {
|
|
12342
12346
|
const el = scrollRef.current;
|
|
12343
12347
|
if (!el) return;
|
|
12344
12348
|
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
12345
12349
|
}, []);
|
|
12346
|
-
|
|
12350
|
+
React130.useEffect(() => {
|
|
12347
12351
|
if (atBottom) scrollToBottom();
|
|
12348
12352
|
}, [messages, activeTools, pendingAction, atBottom, scrollToBottom]);
|
|
12349
|
-
|
|
12353
|
+
React130.useEffect(() => {
|
|
12350
12354
|
loadConversations();
|
|
12351
12355
|
setSuggestionsOpen(useChatStore.getState().messages.length === 0);
|
|
12352
12356
|
return () => stopSpeaking();
|
|
@@ -12363,7 +12367,7 @@ function ChatConversation({
|
|
|
12363
12367
|
};
|
|
12364
12368
|
const queuedPrompt = useChatStore((s) => s.queuedPrompt);
|
|
12365
12369
|
const consumeQueuedPrompt = useChatStore((s) => s.consumeQueuedPrompt);
|
|
12366
|
-
|
|
12370
|
+
React130.useEffect(() => {
|
|
12367
12371
|
if (!queuedPrompt) return;
|
|
12368
12372
|
const prompt = consumeQueuedPrompt();
|
|
12369
12373
|
if (prompt && usable) send(prompt);
|
|
@@ -12399,7 +12403,7 @@ function ChatConversation({
|
|
|
12399
12403
|
);
|
|
12400
12404
|
const connectorsPending = useConnectorsSurface((s) => s.pending);
|
|
12401
12405
|
const consumeConnectorsRequest = useConnectorsSurface((s) => s.consume);
|
|
12402
|
-
|
|
12406
|
+
React130.useEffect(() => {
|
|
12403
12407
|
if (!connectorsPending) return;
|
|
12404
12408
|
setDrawer("connectors");
|
|
12405
12409
|
consumeConnectorsRequest();
|
|
@@ -12407,7 +12411,7 @@ function ChatConversation({
|
|
|
12407
12411
|
const greetingName = (user?.fullName || user?.email || "").split(/[\s@]/)[0];
|
|
12408
12412
|
const invite = useAssistantInviteStore((s) => s.invite);
|
|
12409
12413
|
const introKey = `${onDuty?.role ?? "solo"}:${invite?.id ?? ""}`;
|
|
12410
|
-
|
|
12414
|
+
React130.useEffect(() => setIntroStep(0), [introKey]);
|
|
12411
12415
|
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");
|
|
12412
12416
|
const greetingHint = invite?.description ?? onDuty?.goal ?? t("chat.greetingHint");
|
|
12413
12417
|
const openers2 = invite?.suggestions?.length ? invite.suggestions : onDuty?.suggestions?.length ? onDuty.suggestions : suggestions.length ? suggestions : [
|
|
@@ -12729,7 +12733,7 @@ function AgentAvatar({
|
|
|
12729
12733
|
size = "md",
|
|
12730
12734
|
className
|
|
12731
12735
|
}) {
|
|
12732
|
-
const [failed, setFailed] =
|
|
12736
|
+
const [failed, setFailed] = React130.useState(false);
|
|
12733
12737
|
const { box, text: text2, px } = SIZES[size];
|
|
12734
12738
|
if (Face) {
|
|
12735
12739
|
return /* @__PURE__ */ jsx(
|
|
@@ -13517,7 +13521,7 @@ function TaskStatusGroup({ status, tasks }) {
|
|
|
13517
13521
|
function useDelegateToAssistant() {
|
|
13518
13522
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
13519
13523
|
const openPanel = useRightRailStore((s) => s.openPanel);
|
|
13520
|
-
return
|
|
13524
|
+
return React130.useCallback(
|
|
13521
13525
|
(prompt) => {
|
|
13522
13526
|
queuePrompt(prompt);
|
|
13523
13527
|
openPanel("chat");
|
|
@@ -13754,12 +13758,12 @@ function TasksPanel() {
|
|
|
13754
13758
|
const fetchTasks = useTasksStore((s) => s.fetchTasks);
|
|
13755
13759
|
const fetchLabels = useTasksStore((s) => s.fetchLabels);
|
|
13756
13760
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13757
|
-
|
|
13761
|
+
React130__default.useEffect(() => {
|
|
13758
13762
|
void fetchTasks();
|
|
13759
13763
|
void fetchLabels();
|
|
13760
13764
|
void fetchSummary();
|
|
13761
13765
|
}, [fetchTasks, fetchLabels, fetchSummary]);
|
|
13762
|
-
const { onboarding, grouped } =
|
|
13766
|
+
const { onboarding, grouped } = React130__default.useMemo(() => {
|
|
13763
13767
|
const split = splitOnboardingTasks(tasks);
|
|
13764
13768
|
const map = /* @__PURE__ */ new Map();
|
|
13765
13769
|
for (const s of STATUS_ORDER) map.set(s, []);
|
|
@@ -13794,7 +13798,7 @@ function TasksPanel() {
|
|
|
13794
13798
|
function useTasksSummaryLine() {
|
|
13795
13799
|
const t = useTranslation();
|
|
13796
13800
|
const summary = useTasksStore((s) => s.summary);
|
|
13797
|
-
return
|
|
13801
|
+
return React130__default.useMemo(() => {
|
|
13798
13802
|
if (!summary) return "";
|
|
13799
13803
|
const parts = [];
|
|
13800
13804
|
if (summary.overdue > 0) parts.push(`${summary.overdue} ${t("tasks.summary.overdue")}`);
|
|
@@ -13819,16 +13823,16 @@ function TasksRailPanel() {
|
|
|
13819
13823
|
const fetchSummary = useTasksStore((s) => s.fetchSummary);
|
|
13820
13824
|
const setCurrentUserId = useTasksStore((s) => s.setCurrentUserId);
|
|
13821
13825
|
const userId = useAuthStore6((s) => s.user?.id);
|
|
13822
|
-
|
|
13826
|
+
React130__default.useEffect(() => {
|
|
13823
13827
|
void fetchSummary();
|
|
13824
13828
|
}, [fetchSummary]);
|
|
13825
|
-
|
|
13829
|
+
React130__default.useEffect(() => {
|
|
13826
13830
|
setCurrentUserId(userId ?? null);
|
|
13827
13831
|
}, [userId, setCurrentUserId]);
|
|
13828
13832
|
const openCount = summary ? summary.todo + summary.inProgress : 0;
|
|
13829
13833
|
const defer = tasksSurfaceOwner() === "plugin";
|
|
13830
13834
|
useRightRailPanel(
|
|
13831
|
-
|
|
13835
|
+
React130__default.useMemo(
|
|
13832
13836
|
() => defer ? null : {
|
|
13833
13837
|
id: "tasks",
|
|
13834
13838
|
label: t("tasks.drawer.title") || "Tasks",
|
|
@@ -13852,15 +13856,15 @@ var useSettingsTabsStore = create((set, get) => ({
|
|
|
13852
13856
|
}));
|
|
13853
13857
|
function usePublishSettingsTabs(ids) {
|
|
13854
13858
|
const key = ids.join(",");
|
|
13855
|
-
|
|
13859
|
+
React130.useEffect(() => {
|
|
13856
13860
|
useSettingsTabsStore.getState().setIds(key ? key.split(",") : []);
|
|
13857
13861
|
}, [key]);
|
|
13858
13862
|
}
|
|
13859
13863
|
function useAgentSurface(contribution) {
|
|
13860
|
-
const ref =
|
|
13864
|
+
const ref = React130.useRef(contribution);
|
|
13861
13865
|
ref.current = contribution;
|
|
13862
13866
|
const id = contribution.id;
|
|
13863
|
-
|
|
13867
|
+
React130.useEffect(() => {
|
|
13864
13868
|
registerSurface({ id, get: () => ref.current });
|
|
13865
13869
|
const names = (ref.current.tools ?? []).map((t) => t.tool.name);
|
|
13866
13870
|
for (const name of names) {
|
|
@@ -14640,9 +14644,9 @@ function featureMap() {
|
|
|
14640
14644
|
}));
|
|
14641
14645
|
}
|
|
14642
14646
|
function ActivationAgentSurface({ programs }) {
|
|
14643
|
-
const programsRef =
|
|
14647
|
+
const programsRef = React130.useRef(programs);
|
|
14644
14648
|
programsRef.current = programs;
|
|
14645
|
-
const contribution =
|
|
14649
|
+
const contribution = React130.useMemo(
|
|
14646
14650
|
() => ({
|
|
14647
14651
|
id: "onboarding.activation",
|
|
14648
14652
|
pluginId: "onboarding",
|
|
@@ -14963,7 +14967,7 @@ Quando a pessoa perguntar COMO fazer algo que tem guia em \`setupGuides\` ("como
|
|
|
14963
14967
|
- Termine dizendo o que isso destrava e oferecendo a pr\xF3xima, uma vez s\xF3.`
|
|
14964
14968
|
);
|
|
14965
14969
|
function SetupAgentSurface() {
|
|
14966
|
-
const contribution =
|
|
14970
|
+
const contribution = React130.useMemo(
|
|
14967
14971
|
() => ({
|
|
14968
14972
|
id: "setup.guides",
|
|
14969
14973
|
pluginId: "setup",
|
|
@@ -15079,7 +15083,7 @@ function SetupAgentSurface() {
|
|
|
15079
15083
|
}
|
|
15080
15084
|
var DEBOUNCE_MS = 1200;
|
|
15081
15085
|
function useActivationWatch() {
|
|
15082
|
-
|
|
15086
|
+
React130.useEffect(() => {
|
|
15083
15087
|
let timer = null;
|
|
15084
15088
|
let running = false;
|
|
15085
15089
|
const sweep = async () => {
|
|
@@ -15118,7 +15122,7 @@ function useActivationWatch() {
|
|
|
15118
15122
|
off();
|
|
15119
15123
|
};
|
|
15120
15124
|
}, []);
|
|
15121
|
-
|
|
15125
|
+
React130.useEffect(() => {
|
|
15122
15126
|
useActivationStore.setState({
|
|
15123
15127
|
onStepCompleted: (step, by) => {
|
|
15124
15128
|
const state = useActivationStore.getState();
|
|
@@ -15775,7 +15779,7 @@ function ActivationProvider() {
|
|
|
15775
15779
|
const programs = runtime?.onboardingPrograms ?? [];
|
|
15776
15780
|
const settingsIds = useSettingsTabsStore((s) => s.ids);
|
|
15777
15781
|
const routeKey = (runtime?.routes.length ?? 0) + ":" + settingsIds.join(",");
|
|
15778
|
-
const hasRoute =
|
|
15782
|
+
const hasRoute = React130.useMemo(() => {
|
|
15779
15783
|
const known = /* @__PURE__ */ new Set(["/", "/settings"]);
|
|
15780
15784
|
for (const route of runtime?.routes ?? []) known.add(route.path);
|
|
15781
15785
|
for (const id of settingsIds) known.add(`/settings/${id}`);
|
|
@@ -15783,14 +15787,14 @@ function ActivationProvider() {
|
|
|
15783
15787
|
}, [routeKey]);
|
|
15784
15788
|
const answers = useBusinessProfileStore((s) => s.profile?.answers);
|
|
15785
15789
|
const programKey = programs.map((p) => p.id).join(",");
|
|
15786
|
-
const catalog =
|
|
15790
|
+
const catalog = React130.useMemo(
|
|
15787
15791
|
() => buildActivationCatalog({ verticalId, programs, hasRoute, answers }),
|
|
15788
15792
|
[verticalId, programKey, hasRoute, answers]
|
|
15789
15793
|
);
|
|
15790
|
-
|
|
15794
|
+
React130.useEffect(() => {
|
|
15791
15795
|
setCatalog(catalog);
|
|
15792
15796
|
}, [catalog, setCatalog]);
|
|
15793
|
-
|
|
15797
|
+
React130.useEffect(() => {
|
|
15794
15798
|
if (!tenantId2) return;
|
|
15795
15799
|
let cancelled = false;
|
|
15796
15800
|
void (async () => {
|
|
@@ -15822,14 +15826,14 @@ function ActivationProvider() {
|
|
|
15822
15826
|
cancelled = true;
|
|
15823
15827
|
};
|
|
15824
15828
|
}, [tenantId2, catalog, answers, hasRoute, settingsIds, user?.id, load]);
|
|
15825
|
-
|
|
15829
|
+
React130.useEffect(() => {
|
|
15826
15830
|
if (!tenantId2) {
|
|
15827
15831
|
useBusinessProfileStore.getState().clear();
|
|
15828
15832
|
return;
|
|
15829
15833
|
}
|
|
15830
15834
|
void useBusinessProfileStore.getState().load(tenantId2, orgName);
|
|
15831
15835
|
}, [tenantId2, orgName]);
|
|
15832
|
-
|
|
15836
|
+
React130.useEffect(() => {
|
|
15833
15837
|
if (!tenantId2) return;
|
|
15834
15838
|
const key = `${GREETING_FLAG}:${tenantId2}`;
|
|
15835
15839
|
let pending2 = false;
|
|
@@ -15851,10 +15855,10 @@ function ActivationProvider() {
|
|
|
15851
15855
|
return () => window.clearTimeout(timer);
|
|
15852
15856
|
}, [tenantId2]);
|
|
15853
15857
|
const guides = runtime?.setupGuides;
|
|
15854
|
-
|
|
15858
|
+
React130.useEffect(() => {
|
|
15855
15859
|
setRuntimeSetupGuides(guides ?? []);
|
|
15856
15860
|
}, [guides]);
|
|
15857
|
-
|
|
15861
|
+
React130.useEffect(() => {
|
|
15858
15862
|
setTourNavigator(navigateTo);
|
|
15859
15863
|
return () => setTourNavigator(void 0);
|
|
15860
15864
|
}, []);
|
|
@@ -16027,7 +16031,7 @@ Escrita:
|
|
|
16027
16031
|
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.`
|
|
16028
16032
|
);
|
|
16029
16033
|
function HandbookAgentSurface() {
|
|
16030
|
-
const contribution =
|
|
16034
|
+
const contribution = React130.useMemo(
|
|
16031
16035
|
() => ({
|
|
16032
16036
|
id: "handbook",
|
|
16033
16037
|
pluginId: "handbook",
|
|
@@ -16138,18 +16142,18 @@ function NotebookPanel() {
|
|
|
16138
16142
|
const userId = useHandbookStore((s) => s.userId);
|
|
16139
16143
|
const write3 = useHandbookStore((s) => s.write);
|
|
16140
16144
|
const remove = useHandbookStore((s) => s.remove);
|
|
16141
|
-
const [filter, setFilter] =
|
|
16142
|
-
const [search, setSearch] =
|
|
16143
|
-
const [draft, setDraft] =
|
|
16144
|
-
const [preview, setPreview] =
|
|
16145
|
-
const [confirming, setConfirming] =
|
|
16146
|
-
const entries2 =
|
|
16145
|
+
const [filter, setFilter] = React130.useState("all");
|
|
16146
|
+
const [search, setSearch] = React130.useState("");
|
|
16147
|
+
const [draft, setDraft] = React130.useState(null);
|
|
16148
|
+
const [preview, setPreview] = React130.useState(false);
|
|
16149
|
+
const [confirming, setConfirming] = React130.useState(null);
|
|
16150
|
+
const entries2 = React130.useMemo(
|
|
16147
16151
|
() => (pages ?? []).map((p) => ({ page: p, entry: toEntry2(p) })),
|
|
16148
16152
|
[pages]
|
|
16149
16153
|
);
|
|
16150
|
-
const timer =
|
|
16151
|
-
const inFlight =
|
|
16152
|
-
const persist =
|
|
16154
|
+
const timer = React130.useRef(null);
|
|
16155
|
+
const inFlight = React130.useRef(false);
|
|
16156
|
+
const persist = React130.useCallback(async (d) => {
|
|
16153
16157
|
const title = titleFromBody(d.body);
|
|
16154
16158
|
if (!title && !d.body.trim()) return d.id;
|
|
16155
16159
|
const filed = d.folder !== null;
|
|
@@ -16171,7 +16175,7 @@ function NotebookPanel() {
|
|
|
16171
16175
|
});
|
|
16172
16176
|
return saved?.id ?? d.id;
|
|
16173
16177
|
}, [write3, userId]);
|
|
16174
|
-
const schedule =
|
|
16178
|
+
const schedule = React130.useCallback((next) => {
|
|
16175
16179
|
setDraft(next);
|
|
16176
16180
|
if (timer.current) clearTimeout(timer.current);
|
|
16177
16181
|
timer.current = setTimeout(() => {
|
|
@@ -16203,7 +16207,7 @@ function NotebookPanel() {
|
|
|
16203
16207
|
legacyId: null
|
|
16204
16208
|
});
|
|
16205
16209
|
};
|
|
16206
|
-
const folders =
|
|
16210
|
+
const folders = React130.useMemo(() => {
|
|
16207
16211
|
const set = /* @__PURE__ */ new Set();
|
|
16208
16212
|
for (const { page } of entries2) {
|
|
16209
16213
|
if (page.kind !== "doc" || !page.path) continue;
|
|
@@ -16595,10 +16599,10 @@ ${body}`
|
|
|
16595
16599
|
}
|
|
16596
16600
|
function NoteTodosSection({ noteId, noteTitle }) {
|
|
16597
16601
|
const adapter = useNotesTasksBridge((s) => s.adapter);
|
|
16598
|
-
const [todos, setTodos] =
|
|
16599
|
-
const [draft, setDraft] =
|
|
16600
|
-
const [busy, setBusy] =
|
|
16601
|
-
|
|
16602
|
+
const [todos, setTodos] = React130.useState([]);
|
|
16603
|
+
const [draft, setDraft] = React130.useState("");
|
|
16604
|
+
const [busy, setBusy] = React130.useState(false);
|
|
16605
|
+
React130.useEffect(() => {
|
|
16602
16606
|
if (!adapter) return;
|
|
16603
16607
|
let alive = true;
|
|
16604
16608
|
adapter.listTodos(noteId).then((rows) => {
|
|
@@ -16728,7 +16732,7 @@ function NotebookRailPanel() {
|
|
|
16728
16732
|
const pages = useHandbookStore((s) => s.pages);
|
|
16729
16733
|
const count = pages?.length ?? 0;
|
|
16730
16734
|
useRightRailPanel(
|
|
16731
|
-
|
|
16735
|
+
React130.useMemo(
|
|
16732
16736
|
() => ({
|
|
16733
16737
|
id: "notes",
|
|
16734
16738
|
label: tl("Notes", "Notas"),
|
|
@@ -16747,10 +16751,10 @@ function HandbookProvider() {
|
|
|
16747
16751
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16748
16752
|
const load = useHandbookStore((s) => s.load);
|
|
16749
16753
|
const setUser = useHandbookStore((s) => s.setUser);
|
|
16750
|
-
|
|
16754
|
+
React130.useEffect(() => {
|
|
16751
16755
|
setUser(userId);
|
|
16752
16756
|
}, [userId, setUser]);
|
|
16753
|
-
|
|
16757
|
+
React130.useEffect(() => {
|
|
16754
16758
|
if (tenantId2) void load(tenantId2);
|
|
16755
16759
|
}, [tenantId2, load]);
|
|
16756
16760
|
useLocalNotesImport(tenantId2, userId);
|
|
@@ -16760,7 +16764,7 @@ function HandbookProvider() {
|
|
|
16760
16764
|
] });
|
|
16761
16765
|
}
|
|
16762
16766
|
function useLocalNotesImport(tenantId2, userId) {
|
|
16763
|
-
|
|
16767
|
+
React130.useEffect(() => {
|
|
16764
16768
|
if (!tenantId2 || !userId) return;
|
|
16765
16769
|
const source = `fayz.notes.${tenantId2}.${userId}`;
|
|
16766
16770
|
const flag = `fayz.notes.imported.${tenantId2}.${userId}`;
|
|
@@ -16808,7 +16812,7 @@ function useUnitBootstrap() {
|
|
|
16808
16812
|
const tenant = useTenantOptional();
|
|
16809
16813
|
const userId = useAuthStore((s) => s.user?.id);
|
|
16810
16814
|
const orgId = tenant?.org?.id;
|
|
16811
|
-
|
|
16815
|
+
React130.useEffect(() => {
|
|
16812
16816
|
if (!orgId) return;
|
|
16813
16817
|
const { loadedFor, load, reset } = useUnitStore.getState();
|
|
16814
16818
|
if (loadedFor && loadedFor !== orgId) reset();
|
|
@@ -16847,19 +16851,19 @@ function UnitMembersTab({ item }) {
|
|
|
16847
16851
|
const orgMembers = useOrganizationStore((s) => s.members);
|
|
16848
16852
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
16849
16853
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
16850
|
-
const [rows, setRows] =
|
|
16851
|
-
const [activity, setActivity] =
|
|
16852
|
-
const [adding, setAdding] =
|
|
16853
|
-
const [busy, setBusy] =
|
|
16854
|
-
const reload =
|
|
16854
|
+
const [rows, setRows] = React130.useState(null);
|
|
16855
|
+
const [activity, setActivity] = React130.useState({});
|
|
16856
|
+
const [adding, setAdding] = React130.useState(false);
|
|
16857
|
+
const [busy, setBusy] = React130.useState(null);
|
|
16858
|
+
const reload = React130.useCallback(async () => {
|
|
16855
16859
|
if (!unitId) return;
|
|
16856
16860
|
setRows(await fetchUnitMembers(unitId));
|
|
16857
16861
|
}, [unitId]);
|
|
16858
16862
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
16859
|
-
|
|
16863
|
+
React130.useEffect(() => {
|
|
16860
16864
|
void reload();
|
|
16861
16865
|
}, [reload, version5]);
|
|
16862
|
-
|
|
16866
|
+
React130.useEffect(() => {
|
|
16863
16867
|
if (!orgId) return;
|
|
16864
16868
|
let alive = true;
|
|
16865
16869
|
void fetchMemberActivity(orgId).then((a) => {
|
|
@@ -16869,7 +16873,7 @@ function UnitMembersTab({ item }) {
|
|
|
16869
16873
|
alive = false;
|
|
16870
16874
|
};
|
|
16871
16875
|
}, [orgId]);
|
|
16872
|
-
const byUser =
|
|
16876
|
+
const byUser = React130.useMemo(() => {
|
|
16873
16877
|
const map = /* @__PURE__ */ new Map();
|
|
16874
16878
|
for (const m of orgMembers) {
|
|
16875
16879
|
map.set(m.userId, {
|
|
@@ -16881,7 +16885,7 @@ function UnitMembersTab({ item }) {
|
|
|
16881
16885
|
}
|
|
16882
16886
|
return map;
|
|
16883
16887
|
}, [orgMembers]);
|
|
16884
|
-
const available =
|
|
16888
|
+
const available = React130.useMemo(
|
|
16885
16889
|
() => orgMembers.filter((m) => !(rows ?? []).some((r) => r.userId === m.userId)),
|
|
16886
16890
|
[orgMembers, rows]
|
|
16887
16891
|
);
|
|
@@ -17087,15 +17091,15 @@ function MemberAccessBody({
|
|
|
17087
17091
|
const units = useUnitStore((s) => s.units);
|
|
17088
17092
|
const byId = useUnitStore((s) => s.byId);
|
|
17089
17093
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
17090
|
-
const [bindings, setBindings] =
|
|
17091
|
-
const [loading, setLoading] =
|
|
17092
|
-
const [adding, setAdding] =
|
|
17093
|
-
const branches =
|
|
17094
|
-
const unbound =
|
|
17094
|
+
const [bindings, setBindings] = React130.useState([]);
|
|
17095
|
+
const [loading, setLoading] = React130.useState(false);
|
|
17096
|
+
const [adding, setAdding] = React130.useState(false);
|
|
17097
|
+
const branches = React130.useMemo(() => units.filter((u) => u.isActive !== false), [units]);
|
|
17098
|
+
const unbound = React130.useMemo(
|
|
17095
17099
|
() => branches.filter((u) => !bindings.some((b) => b.locationId === u.id)),
|
|
17096
17100
|
[branches, bindings]
|
|
17097
17101
|
);
|
|
17098
|
-
const reload =
|
|
17102
|
+
const reload = React130.useCallback(async () => {
|
|
17099
17103
|
if (!userId) return;
|
|
17100
17104
|
setLoading(true);
|
|
17101
17105
|
try {
|
|
@@ -17105,7 +17109,7 @@ function MemberAccessBody({
|
|
|
17105
17109
|
}
|
|
17106
17110
|
}, [userId]);
|
|
17107
17111
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
17108
|
-
|
|
17112
|
+
React130.useEffect(() => {
|
|
17109
17113
|
void reload();
|
|
17110
17114
|
}, [reload, version5]);
|
|
17111
17115
|
async function add(unitId) {
|
|
@@ -17787,12 +17791,118 @@ function createThemeStore() {
|
|
|
17787
17791
|
return store;
|
|
17788
17792
|
}
|
|
17789
17793
|
var useThemeStore = createThemeStore();
|
|
17794
|
+
var FALLBACK_TTL_SECONDS = 30 * 60;
|
|
17795
|
+
function reloadTo(hash2) {
|
|
17796
|
+
window.location.hash = hash2;
|
|
17797
|
+
window.location.reload();
|
|
17798
|
+
}
|
|
17799
|
+
async function startImpersonation(input) {
|
|
17800
|
+
const supabase = getFayzSupabaseClient();
|
|
17801
|
+
const { data: current2 } = await supabase.auth.getSession();
|
|
17802
|
+
const origin = current2.session;
|
|
17803
|
+
if (!origin?.refresh_token) throw new Error("Sua sess\xE3o expirou. Entre de novo.");
|
|
17804
|
+
const { data, error } = await supabase.functions.invoke("platform-admin", {
|
|
17805
|
+
body: { verb: "member.impersonate", params: { tenant_id: input.tenantId, user_id: input.userId, reason: input.reason } }
|
|
17806
|
+
});
|
|
17807
|
+
if (error) {
|
|
17808
|
+
const body = await error.context?.json?.().catch(() => null);
|
|
17809
|
+
throw new Error(body?.error ?? error.message);
|
|
17810
|
+
}
|
|
17811
|
+
const { token_hash, target, expires_in } = data;
|
|
17812
|
+
const now2 = Date.now();
|
|
17813
|
+
const person = { userId: target.user_id, email: target.email, name: target.name, role: target.role };
|
|
17814
|
+
writeImpersonation({
|
|
17815
|
+
tenantId: input.tenantId,
|
|
17816
|
+
target: person,
|
|
17817
|
+
startedAt: now2,
|
|
17818
|
+
expiresAt: now2 + (expires_in ?? FALLBACK_TTL_SECONDS) * 1e3,
|
|
17819
|
+
returnTo: input.returnTo,
|
|
17820
|
+
origin: { access_token: origin.access_token, refresh_token: origin.refresh_token }
|
|
17821
|
+
});
|
|
17822
|
+
const { error: verifyErr } = await supabase.auth.verifyOtp({ type: "magiclink", token_hash });
|
|
17823
|
+
if (verifyErr) {
|
|
17824
|
+
writeImpersonation(null);
|
|
17825
|
+
await supabase.auth.setSession({ access_token: origin.access_token, refresh_token: origin.refresh_token });
|
|
17826
|
+
throw new Error(verifyErr.message);
|
|
17827
|
+
}
|
|
17828
|
+
markWorkspaceSwitch(input.tenantId);
|
|
17829
|
+
reloadTo("#/");
|
|
17830
|
+
}
|
|
17831
|
+
async function stopImpersonation() {
|
|
17832
|
+
const state = readImpersonation();
|
|
17833
|
+
if (!state) return;
|
|
17834
|
+
const supabase = getFayzSupabaseClient();
|
|
17835
|
+
try {
|
|
17836
|
+
await supabase.auth.signOut({ scope: "local" });
|
|
17837
|
+
} catch {
|
|
17838
|
+
}
|
|
17839
|
+
writeImpersonation(null);
|
|
17840
|
+
const { error } = await supabase.auth.setSession(state.origin);
|
|
17841
|
+
markWorkspaceSwitch(state.tenantId);
|
|
17842
|
+
reloadTo(error ? "#/login" : state.returnTo ?? "#/settings/team");
|
|
17843
|
+
}
|
|
17844
|
+
function minutesLeft(expiresAt) {
|
|
17845
|
+
return Math.max(0, Math.ceil((expiresAt - Date.now()) / 6e4));
|
|
17846
|
+
}
|
|
17847
|
+
function ImpersonationBanner() {
|
|
17848
|
+
const { t } = useTranslation$1();
|
|
17849
|
+
const [state] = React130__default.useState(readImpersonation);
|
|
17850
|
+
const [left, setLeft] = React130__default.useState(() => state ? minutesLeft(state.expiresAt) : 0);
|
|
17851
|
+
const [leaving, setLeaving] = React130__default.useState(false);
|
|
17852
|
+
const leave = React130__default.useCallback(() => {
|
|
17853
|
+
setLeaving(true);
|
|
17854
|
+
void stopImpersonation();
|
|
17855
|
+
}, []);
|
|
17856
|
+
React130__default.useEffect(() => {
|
|
17857
|
+
if (!state) return;
|
|
17858
|
+
document.documentElement.classList.add("fz-has-top-strip");
|
|
17859
|
+
const timer = window.setInterval(() => {
|
|
17860
|
+
const next = minutesLeft(state.expiresAt);
|
|
17861
|
+
setLeft(next);
|
|
17862
|
+
if (next === 0) leave();
|
|
17863
|
+
}, 15e3);
|
|
17864
|
+
if (minutesLeft(state.expiresAt) === 0) leave();
|
|
17865
|
+
return () => {
|
|
17866
|
+
window.clearInterval(timer);
|
|
17867
|
+
document.documentElement.classList.remove("fz-has-top-strip");
|
|
17868
|
+
};
|
|
17869
|
+
}, [state, leave]);
|
|
17870
|
+
if (!state) return null;
|
|
17871
|
+
const who = state.target.role ? `${state.target.name} (${state.target.role})` : state.target.name;
|
|
17872
|
+
return /* @__PURE__ */ jsxs(
|
|
17873
|
+
"div",
|
|
17874
|
+
{
|
|
17875
|
+
role: "status",
|
|
17876
|
+
className: "flex h-8 items-center justify-center gap-2 bg-warning px-3 text-xs font-medium text-warning-foreground",
|
|
17877
|
+
children: [
|
|
17878
|
+
/* @__PURE__ */ jsx(Eye, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
17879
|
+
/* @__PURE__ */ jsxs("span", { className: "truncate", children: [
|
|
17880
|
+
t("impersonation.banner", { name: who }),
|
|
17881
|
+
/* @__PURE__ */ jsxs("span", { className: "hidden opacity-80 sm:inline", children: [
|
|
17882
|
+
" \xB7 ",
|
|
17883
|
+
t("impersonation.minutesLeft", { count: String(left) })
|
|
17884
|
+
] })
|
|
17885
|
+
] }),
|
|
17886
|
+
/* @__PURE__ */ jsx(
|
|
17887
|
+
"button",
|
|
17888
|
+
{
|
|
17889
|
+
type: "button",
|
|
17890
|
+
onClick: leave,
|
|
17891
|
+
disabled: leaving,
|
|
17892
|
+
className: "ml-2 shrink-0 rounded-md border border-current/40 px-2 py-0.5 font-semibold hover:bg-black/10 disabled:opacity-60",
|
|
17893
|
+
children: leaving ? t("impersonation.leaving") : t("impersonation.leave")
|
|
17894
|
+
}
|
|
17895
|
+
)
|
|
17896
|
+
]
|
|
17897
|
+
}
|
|
17898
|
+
);
|
|
17899
|
+
}
|
|
17790
17900
|
function useWrongApp() {
|
|
17791
17901
|
const apps = useAppConfigStore((s) => s.config.apps);
|
|
17792
17902
|
const tenantId2 = useAppConfigStore((s) => s.tenantId);
|
|
17793
17903
|
const activeTenantId = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
17794
17904
|
const appId = resolveAppId();
|
|
17795
|
-
return
|
|
17905
|
+
return React130.useMemo(() => {
|
|
17796
17906
|
if (!appId || !activeTenantId || tenantId2 !== activeTenantId) return { app: null };
|
|
17797
17907
|
const list = (apps ?? []).filter((a) => !a.house);
|
|
17798
17908
|
if (!list.length) return { app: null };
|
|
@@ -17915,13 +18025,13 @@ function surveyTokenFromPath(pathname) {
|
|
|
17915
18025
|
return m ? decodeURIComponent(m[1]) : null;
|
|
17916
18026
|
}
|
|
17917
18027
|
function PublicSurveyPage({ token, appName }) {
|
|
17918
|
-
const [loaded2, setLoaded] =
|
|
17919
|
-
const [draft, setDraft] =
|
|
17920
|
-
const [name, setName] =
|
|
17921
|
-
const [sending, setSending] =
|
|
17922
|
-
const [sent, setSent] =
|
|
17923
|
-
const [failed, setFailed] =
|
|
17924
|
-
|
|
18028
|
+
const [loaded2, setLoaded] = React130__default.useState(null);
|
|
18029
|
+
const [draft, setDraft] = React130__default.useState({});
|
|
18030
|
+
const [name, setName] = React130__default.useState("");
|
|
18031
|
+
const [sending, setSending] = React130__default.useState(false);
|
|
18032
|
+
const [sent, setSent] = React130__default.useState(null);
|
|
18033
|
+
const [failed, setFailed] = React130__default.useState(null);
|
|
18034
|
+
React130__default.useEffect(() => {
|
|
17925
18035
|
let alive = true;
|
|
17926
18036
|
const client3 = getFayzSupabaseClientOptional();
|
|
17927
18037
|
if (!client3) {
|
|
@@ -18219,7 +18329,7 @@ function isServed2(route) {
|
|
|
18219
18329
|
function getPersonActions(kind) {
|
|
18220
18330
|
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));
|
|
18221
18331
|
}
|
|
18222
|
-
var RouteErrorBoundary = class extends
|
|
18332
|
+
var RouteErrorBoundary = class extends React130.Component {
|
|
18223
18333
|
constructor() {
|
|
18224
18334
|
super(...arguments);
|
|
18225
18335
|
this.state = { crashed: false, report: null };
|
|
@@ -18261,7 +18371,7 @@ var RouteErrorBoundary = class extends React128.Component {
|
|
|
18261
18371
|
}
|
|
18262
18372
|
};
|
|
18263
18373
|
function RouteErrorScreen({ report, tr, onBack, onRetry, backLabel }) {
|
|
18264
|
-
const [copied, setCopied] =
|
|
18374
|
+
const [copied, setCopied] = React130.useState(false);
|
|
18265
18375
|
const copyDetails = () => {
|
|
18266
18376
|
if (!report || typeof navigator === "undefined" || !navigator.clipboard) return;
|
|
18267
18377
|
const details = [
|
|
@@ -18366,9 +18476,9 @@ function UnitSwitching({ unitName, isAll, onDone }) {
|
|
|
18366
18476
|
const v = t(key);
|
|
18367
18477
|
return !v || v === key ? fallback : v;
|
|
18368
18478
|
};
|
|
18369
|
-
const doneRef =
|
|
18479
|
+
const doneRef = React130.useRef(onDone);
|
|
18370
18480
|
doneRef.current = onDone;
|
|
18371
|
-
|
|
18481
|
+
React130.useEffect(() => {
|
|
18372
18482
|
const id = window.setTimeout(() => doneRef.current(), HOLD_MS);
|
|
18373
18483
|
return () => window.clearTimeout(id);
|
|
18374
18484
|
}, []);
|
|
@@ -18425,11 +18535,11 @@ function UnitPickerDialog() {
|
|
|
18425
18535
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
18426
18536
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
18427
18537
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
18428
|
-
const reachable =
|
|
18538
|
+
const reachable = React130.useMemo(
|
|
18429
18539
|
() => myUnitIds.length > 0 ? myUnitIds : units.filter((u) => u.kind !== "region").map((u) => u.id),
|
|
18430
18540
|
[myUnitIds, units]
|
|
18431
18541
|
);
|
|
18432
|
-
const groups =
|
|
18542
|
+
const groups = React130.useMemo(() => {
|
|
18433
18543
|
const out = [];
|
|
18434
18544
|
if (reachable.length > 1) {
|
|
18435
18545
|
out.push({ id: "_all", options: [{ id: ALL_UNITS, label: "Todas as unidades" }] });
|
|
@@ -18628,16 +18738,16 @@ function WorkspaceSetupFlow({
|
|
|
18628
18738
|
const user = useAuthStore((s) => s.user);
|
|
18629
18739
|
const { switchOrg } = useTenant();
|
|
18630
18740
|
const closeSetup = useWorkspaceSetupStore((s) => s.close);
|
|
18631
|
-
const uploadLogo =
|
|
18741
|
+
const uploadLogo = React130.useMemo(
|
|
18632
18742
|
() => user ? createLogoUploader(user.id) : void 0,
|
|
18633
18743
|
[user?.id]
|
|
18634
18744
|
);
|
|
18635
|
-
const country =
|
|
18745
|
+
const country = React130.useMemo(
|
|
18636
18746
|
() => currency === "BRL" || (locale ?? "").toLowerCase().startsWith("pt") ? "BR" : void 0,
|
|
18637
18747
|
[currency, locale]
|
|
18638
18748
|
);
|
|
18639
|
-
const stepsRef =
|
|
18640
|
-
const analyzeSite =
|
|
18749
|
+
const stepsRef = React130.useRef([]);
|
|
18750
|
+
const analyzeSite = React130.useMemo(
|
|
18641
18751
|
() => createSiteAnalyzer({
|
|
18642
18752
|
apiBaseUrl: resolveFayzApiBaseUrl(),
|
|
18643
18753
|
steps: () => stepsRef.current,
|
|
@@ -18645,7 +18755,7 @@ function WorkspaceSetupFlow({
|
|
|
18645
18755
|
}),
|
|
18646
18756
|
[locale]
|
|
18647
18757
|
);
|
|
18648
|
-
const steps =
|
|
18758
|
+
const steps = React130.useMemo(
|
|
18649
18759
|
() => buildWorkspaceSetupSteps({
|
|
18650
18760
|
verticalId,
|
|
18651
18761
|
uploadLogo,
|
|
@@ -18657,13 +18767,13 @@ function WorkspaceSetupFlow({
|
|
|
18657
18767
|
[verticalId, uploadLogo, media, country, analyzeSite]
|
|
18658
18768
|
);
|
|
18659
18769
|
stepsRef.current = steps;
|
|
18660
|
-
const initialValues2 =
|
|
18770
|
+
const initialValues2 = React130.useMemo(
|
|
18661
18771
|
// Seeding the contact email with the account's own is one field fewer to
|
|
18662
18772
|
// type, and it is right far more often than it is wrong.
|
|
18663
18773
|
() => user?.email ? { "workspace.email": user.email } : {},
|
|
18664
18774
|
[user?.email]
|
|
18665
18775
|
);
|
|
18666
|
-
const onSubmit =
|
|
18776
|
+
const onSubmit = React130.useCallback(
|
|
18667
18777
|
async (values) => {
|
|
18668
18778
|
if (!user) throw new Error(tl("You are signed out.", "Sua sess\xE3o terminou."));
|
|
18669
18779
|
const org = await submitWorkspaceSetup({
|
|
@@ -18780,16 +18890,16 @@ function GettingStartedWidget() {
|
|
|
18780
18890
|
const t = useTranslation();
|
|
18781
18891
|
const rows = useActivationStore((s) => s.rows);
|
|
18782
18892
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18783
|
-
const steps =
|
|
18893
|
+
const steps = React130.useMemo(
|
|
18784
18894
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18785
18895
|
[rows, catalog]
|
|
18786
18896
|
);
|
|
18787
|
-
const onNavigate =
|
|
18897
|
+
const onNavigate = React130.useCallback((path) => {
|
|
18788
18898
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18789
18899
|
navigateTo(path);
|
|
18790
18900
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18791
18901
|
}, []);
|
|
18792
|
-
const onAskAgent =
|
|
18902
|
+
const onAskAgent = React130.useCallback((step) => {
|
|
18793
18903
|
void startGuidedRun(step.id);
|
|
18794
18904
|
}, []);
|
|
18795
18905
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18814,16 +18924,16 @@ function ActivationChecklistCard({
|
|
|
18814
18924
|
}) {
|
|
18815
18925
|
const rows = useActivationStore((s) => s.rows);
|
|
18816
18926
|
const catalog = useActivationStore((s) => s.catalog);
|
|
18817
|
-
const steps =
|
|
18927
|
+
const steps = React130.useMemo(
|
|
18818
18928
|
() => selectSteps({ ...useActivationStore.getState(), rows, catalog }),
|
|
18819
18929
|
[rows, catalog]
|
|
18820
18930
|
);
|
|
18821
|
-
const onNavigate =
|
|
18931
|
+
const onNavigate = React130.useCallback((path) => {
|
|
18822
18932
|
const step = useActivationStore.getState().catalog.find((s) => s.route === path);
|
|
18823
18933
|
navigateTo(path);
|
|
18824
18934
|
if (step?.tour) useTourStore.getState().start(step.tour);
|
|
18825
18935
|
}, []);
|
|
18826
|
-
const onAskAgent =
|
|
18936
|
+
const onAskAgent = React130.useCallback((step) => {
|
|
18827
18937
|
void startGuidedRun(step.id);
|
|
18828
18938
|
}, []);
|
|
18829
18939
|
if (!rows || rows.length === 0) return null;
|
|
@@ -18857,12 +18967,12 @@ function rememberCompleted(storageKey2) {
|
|
|
18857
18967
|
}
|
|
18858
18968
|
}
|
|
18859
18969
|
function usePluginOnboardingGate(storageKey2, checkExistingData) {
|
|
18860
|
-
const checkRef =
|
|
18970
|
+
const checkRef = React130.useRef(checkExistingData);
|
|
18861
18971
|
checkRef.current = checkExistingData;
|
|
18862
|
-
const [status, setStatus] =
|
|
18972
|
+
const [status, setStatus] = React130.useState(
|
|
18863
18973
|
() => wasCompleted(storageKey2) ? "complete" : "checking"
|
|
18864
18974
|
);
|
|
18865
|
-
|
|
18975
|
+
React130.useEffect(() => {
|
|
18866
18976
|
if (status !== "checking") return;
|
|
18867
18977
|
let cancelled = false;
|
|
18868
18978
|
void checkRef.current().then((hasData) => {
|
|
@@ -18876,7 +18986,7 @@ function usePluginOnboardingGate(storageKey2, checkExistingData) {
|
|
|
18876
18986
|
cancelled = true;
|
|
18877
18987
|
};
|
|
18878
18988
|
}, [status, storageKey2]);
|
|
18879
|
-
const complete =
|
|
18989
|
+
const complete = React130.useCallback(() => {
|
|
18880
18990
|
rememberCompleted(storageKey2);
|
|
18881
18991
|
setStatus("complete");
|
|
18882
18992
|
}, [storageKey2]);
|
|
@@ -18896,9 +19006,9 @@ function PluginOnboardingGateSkeleton() {
|
|
|
18896
19006
|
/* @__PURE__ */ jsx(Skeleton, { className: "h-72 rounded-card" })
|
|
18897
19007
|
] });
|
|
18898
19008
|
}
|
|
18899
|
-
var WidgetSurfaceContext =
|
|
19009
|
+
var WidgetSurfaceContext = React130.createContext("rail");
|
|
18900
19010
|
function useWidgetSurface() {
|
|
18901
|
-
return
|
|
19011
|
+
return React130.useContext(WidgetSurfaceContext);
|
|
18902
19012
|
}
|
|
18903
19013
|
function WidgetSlot({
|
|
18904
19014
|
zone,
|
|
@@ -18942,7 +19052,7 @@ function useNavContribution(id, entries2) {
|
|
|
18942
19052
|
const setContribution = useNavContributionsStore((s) => s.setContribution);
|
|
18943
19053
|
const clearContribution = useNavContributionsStore((s) => s.clearContribution);
|
|
18944
19054
|
const key = JSON.stringify(entries2);
|
|
18945
|
-
|
|
19055
|
+
React130.useEffect(() => {
|
|
18946
19056
|
setContribution(id, entries2);
|
|
18947
19057
|
return () => clearContribution(id);
|
|
18948
19058
|
}, [id, key]);
|
|
@@ -19012,7 +19122,7 @@ function useAppDirectory() {
|
|
|
19012
19122
|
const tenantId2 = useActiveTenantId();
|
|
19013
19123
|
const apps = useAppDirectoryStore((s) => s.apps);
|
|
19014
19124
|
const load = useAppDirectoryStore((s) => s.load);
|
|
19015
|
-
|
|
19125
|
+
React130.useEffect(() => {
|
|
19016
19126
|
if (tenantId2) void load(tenantId2, resolveAppId());
|
|
19017
19127
|
}, [tenantId2, load]);
|
|
19018
19128
|
return { apps };
|
|
@@ -19104,7 +19214,7 @@ var CSS2 = `
|
|
|
19104
19214
|
}
|
|
19105
19215
|
`;
|
|
19106
19216
|
function useWordmarkStyle() {
|
|
19107
|
-
|
|
19217
|
+
React130.useEffect(() => {
|
|
19108
19218
|
if (typeof document === "undefined") return;
|
|
19109
19219
|
const existing = document.getElementById(STYLE_ID2);
|
|
19110
19220
|
if (existing) {
|
|
@@ -19338,7 +19448,7 @@ var SWAP_CSS = `
|
|
|
19338
19448
|
}
|
|
19339
19449
|
`;
|
|
19340
19450
|
function useSwapStyle() {
|
|
19341
|
-
|
|
19451
|
+
React130.useEffect(() => {
|
|
19342
19452
|
if (typeof document === "undefined" || document.getElementById(SWAP_STYLE_ID)) return;
|
|
19343
19453
|
const el = document.createElement("style");
|
|
19344
19454
|
el.id = SWAP_STYLE_ID;
|
|
@@ -19347,9 +19457,9 @@ function useSwapStyle() {
|
|
|
19347
19457
|
}, []);
|
|
19348
19458
|
}
|
|
19349
19459
|
function AppSwitcherView({ apps, mark, logo, collapsed = false, label: label3, onSelect, brandedByTenant = false }) {
|
|
19350
|
-
const [hovered, setHovered] =
|
|
19351
|
-
const [open, setOpen] =
|
|
19352
|
-
const [pending2, setPending] =
|
|
19460
|
+
const [hovered, setHovered] = React130.useState(false);
|
|
19461
|
+
const [open, setOpen] = React130.useState(false);
|
|
19462
|
+
const [pending2, setPending] = React130.useState(null);
|
|
19353
19463
|
const active2 = hovered || open;
|
|
19354
19464
|
useSwapStyle();
|
|
19355
19465
|
const brand = /* @__PURE__ */ jsx(BrandFace, { mark, logo, collapsed });
|
|
@@ -19496,7 +19606,7 @@ function useContextualNav(nav) {
|
|
|
19496
19606
|
const setNav = useContextualNavStore((s) => s.setNav);
|
|
19497
19607
|
const clearNav = useContextualNavStore((s) => s.clearNav);
|
|
19498
19608
|
const key = nav ? JSON.stringify(nav) : null;
|
|
19499
|
-
|
|
19609
|
+
React130.useEffect(() => {
|
|
19500
19610
|
if (!nav) return;
|
|
19501
19611
|
setNav(nav);
|
|
19502
19612
|
return () => clearNav(nav.base);
|
|
@@ -19568,7 +19678,7 @@ async function findNearestUnit(units, reachable) {
|
|
|
19568
19678
|
}
|
|
19569
19679
|
var UNIT_SEARCH_THRESHOLD = 8;
|
|
19570
19680
|
function WorkspaceUnitSheet({ onClose, canCreate = true }) {
|
|
19571
|
-
const [level, setLevel] =
|
|
19681
|
+
const [level, setLevel] = React130.useState("root");
|
|
19572
19682
|
return /* @__PURE__ */ jsxs(
|
|
19573
19683
|
BottomSheet,
|
|
19574
19684
|
{
|
|
@@ -19631,9 +19741,9 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19631
19741
|
const closeSheet = useSheetClose();
|
|
19632
19742
|
const beginSwitch = useWorkspaceSwitchingStore((s) => s.begin);
|
|
19633
19743
|
const openSetup = useWorkspaceSetupStore((s) => s.open);
|
|
19634
|
-
const [query, setQuery] =
|
|
19744
|
+
const [query, setQuery] = React130.useState("");
|
|
19635
19745
|
const org = tenant?.org ?? null;
|
|
19636
|
-
const options =
|
|
19746
|
+
const options = React130.useMemo(() => {
|
|
19637
19747
|
const list = tenant?.userOrgs ?? [];
|
|
19638
19748
|
if (list.length) return list;
|
|
19639
19749
|
return org ? [{ orgId: org.id, orgName: org.name, orgSlug: org.slug, orgLogoUrl: org.logoUrl }] : [];
|
|
@@ -19642,7 +19752,7 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19642
19752
|
const v = t.t(key);
|
|
19643
19753
|
return !v || v === key ? fallback : v;
|
|
19644
19754
|
};
|
|
19645
|
-
const search =
|
|
19755
|
+
const search = React130.useMemo(
|
|
19646
19756
|
() => searchWorkspaces(options, query, org?.id),
|
|
19647
19757
|
[options, query, org?.id]
|
|
19648
19758
|
);
|
|
@@ -19694,8 +19804,8 @@ function WorkspaceLevel({ canCreate }) {
|
|
|
19694
19804
|
function UnitLevel() {
|
|
19695
19805
|
useUnitBootstrap();
|
|
19696
19806
|
const closeSheet = useSheetClose();
|
|
19697
|
-
const [locating, setLocating] =
|
|
19698
|
-
const [query, setQuery] =
|
|
19807
|
+
const [locating, setLocating] = React130.useState(false);
|
|
19808
|
+
const [query, setQuery] = React130.useState("");
|
|
19699
19809
|
const units = useUnitStore((s) => s.units);
|
|
19700
19810
|
const tree = useUnitStore((s) => s.tree);
|
|
19701
19811
|
const byId = useUnitStore((s) => s.byId);
|
|
@@ -19732,7 +19842,7 @@ function UnitLevel() {
|
|
|
19732
19842
|
const leaves = node.children.filter((c) => c.kind !== "region" && reachable.includes(c.id));
|
|
19733
19843
|
const regions = node.children.filter((c) => c.kind === "region");
|
|
19734
19844
|
if (leaves.length === 0 && regions.length === 0) return null;
|
|
19735
|
-
return /* @__PURE__ */ jsxs(
|
|
19845
|
+
return /* @__PURE__ */ jsxs(React130.Fragment, { children: [
|
|
19736
19846
|
/* @__PURE__ */ jsx("p", { className: "px-4 pb-1 pt-3 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
19737
19847
|
leaves.length > 0 && /* @__PURE__ */ jsx(SheetCard, { children: leaves.map(leaf) }),
|
|
19738
19848
|
regions.map(group)
|
|
@@ -19802,7 +19912,7 @@ function UnitLevel() {
|
|
|
19802
19912
|
}
|
|
19803
19913
|
function WorkspaceUnitRow({ canCreate = true }) {
|
|
19804
19914
|
useUnitBootstrap();
|
|
19805
|
-
const [open, setOpen] =
|
|
19915
|
+
const [open, setOpen] = React130.useState(false);
|
|
19806
19916
|
const tenant = useTenantOptional();
|
|
19807
19917
|
const org = tenant?.org ?? null;
|
|
19808
19918
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
@@ -19989,10 +20099,10 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
19989
20099
|
const load = useFayzProjectsStore((s) => s.load);
|
|
19990
20100
|
const loadedFor = useFayzProjectsStore((s) => s.loadedFor);
|
|
19991
20101
|
const collapsed = useLayoutStore((s) => s.sidebarCollapsed);
|
|
19992
|
-
const [selectedId, setSelectedId] =
|
|
19993
|
-
const [hovered, setHovered] =
|
|
19994
|
-
const [primed, setPrimed] =
|
|
19995
|
-
const closeTimer =
|
|
20102
|
+
const [selectedId, setSelectedId] = React130.useState(null);
|
|
20103
|
+
const [hovered, setHovered] = React130.useState(false);
|
|
20104
|
+
const [primed, setPrimed] = React130.useState(false);
|
|
20105
|
+
const closeTimer = React130.useRef(null);
|
|
19996
20106
|
const cancelClose = () => {
|
|
19997
20107
|
if (closeTimer.current) {
|
|
19998
20108
|
clearTimeout(closeTimer.current);
|
|
@@ -20008,8 +20118,8 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
20008
20118
|
cancelClose();
|
|
20009
20119
|
closeTimer.current = setTimeout(() => setHovered(false), 140);
|
|
20010
20120
|
};
|
|
20011
|
-
|
|
20012
|
-
|
|
20121
|
+
React130.useEffect(() => () => cancelClose(), []);
|
|
20122
|
+
React130.useEffect(() => {
|
|
20013
20123
|
if (loadedFor !== (currentOrgId ?? null)) void load(currentOrgId);
|
|
20014
20124
|
}, [currentOrgId, loadedFor, load]);
|
|
20015
20125
|
const active2 = projects.find((p) => p.id === selectedId) ?? defaultProjectOf(projects) ?? synthFromFallback(fallback);
|
|
@@ -20120,10 +20230,10 @@ function SitePreview({
|
|
|
20120
20230
|
onEdit,
|
|
20121
20231
|
tr
|
|
20122
20232
|
}) {
|
|
20123
|
-
const [nonce, setNonce] =
|
|
20124
|
-
const [loading, setLoading] =
|
|
20233
|
+
const [nonce, setNonce] = React130.useState(0);
|
|
20234
|
+
const [loading, setLoading] = React130.useState(true);
|
|
20125
20235
|
const url = previewSourceOf(project);
|
|
20126
|
-
|
|
20236
|
+
React130.useEffect(() => {
|
|
20127
20237
|
setLoading(true);
|
|
20128
20238
|
}, [nonce, url]);
|
|
20129
20239
|
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";
|
|
@@ -20233,10 +20343,10 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
20233
20343
|
const pageOpen = useRightRailStore((s) => s.pageOpen);
|
|
20234
20344
|
const setPageSlot = useRightRailStore((s) => s.setPageSlot);
|
|
20235
20345
|
const setWidth = useRightRailStore((s) => s.setWidth);
|
|
20236
|
-
const rootRef =
|
|
20237
|
-
const [actionsSlot, setActionsSlot] =
|
|
20238
|
-
const [leadingSlot, setLeadingSlot] =
|
|
20239
|
-
|
|
20346
|
+
const rootRef = React130.useRef(null);
|
|
20347
|
+
const [actionsSlot, setActionsSlot] = React130.useState(null);
|
|
20348
|
+
const [leadingSlot, setLeadingSlot] = React130.useState(null);
|
|
20349
|
+
React130.useEffect(() => {
|
|
20240
20350
|
if (!open) return;
|
|
20241
20351
|
const el = rootRef.current;
|
|
20242
20352
|
if (!el) return;
|
|
@@ -20258,8 +20368,8 @@ function RightRail({ frame = true, attached = true }) {
|
|
|
20258
20368
|
el.removeEventListener("transitionend", publish);
|
|
20259
20369
|
};
|
|
20260
20370
|
}, [open, setWidth]);
|
|
20261
|
-
const [narrow, setNarrow] =
|
|
20262
|
-
|
|
20371
|
+
const [narrow, setNarrow] = React130.useState(false);
|
|
20372
|
+
React130.useEffect(() => {
|
|
20263
20373
|
if (!open) return;
|
|
20264
20374
|
const el = rootRef.current;
|
|
20265
20375
|
if (!el) return;
|
|
@@ -20622,9 +20732,9 @@ var TYPE_COLORS = {
|
|
|
20622
20732
|
fix: "text-success"
|
|
20623
20733
|
};
|
|
20624
20734
|
function ChangelogFeed({ changelogUrl, className }) {
|
|
20625
|
-
const [entries2, setEntries] =
|
|
20626
|
-
const [loading, setLoading] =
|
|
20627
|
-
|
|
20735
|
+
const [entries2, setEntries] = React130.useState([]);
|
|
20736
|
+
const [loading, setLoading] = React130.useState(false);
|
|
20737
|
+
React130.useEffect(() => {
|
|
20628
20738
|
if (!changelogUrl) return;
|
|
20629
20739
|
setLoading(true);
|
|
20630
20740
|
fetch(changelogUrl).then((r) => r.json()).then((data) => setEntries(data)).catch(() => setEntries([])).finally(() => setLoading(false));
|
|
@@ -20684,7 +20794,7 @@ function NotificationInbox({
|
|
|
20684
20794
|
changelogUrl,
|
|
20685
20795
|
className
|
|
20686
20796
|
}) {
|
|
20687
|
-
const [activeTab, setActiveTab] =
|
|
20797
|
+
const [activeTab, setActiveTab] = React130.useState("inbox");
|
|
20688
20798
|
const unreadCount = notifications.filter((n) => !n.read).length;
|
|
20689
20799
|
const inboxNotifications = notifications.filter((n) => n.category !== "changelog");
|
|
20690
20800
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex w-80 flex-col", className), children: [
|
|
@@ -20781,11 +20891,11 @@ function NotificationInbox({
|
|
|
20781
20891
|
}
|
|
20782
20892
|
function BrandAgentSurface() {
|
|
20783
20893
|
const org = useOrganizationStore((s) => s.currentOrg);
|
|
20784
|
-
const brand =
|
|
20894
|
+
const brand = React130__default.useMemo(
|
|
20785
20895
|
() => normalizeBrand(org?.settings?.branding, { name: org?.name, logoUrl: org?.logoUrl }),
|
|
20786
20896
|
[org?.settings, org?.name, org?.logoUrl]
|
|
20787
20897
|
);
|
|
20788
|
-
const surface =
|
|
20898
|
+
const surface = React130__default.useMemo(() => ({
|
|
20789
20899
|
id: "core.brand",
|
|
20790
20900
|
describe: () => ({
|
|
20791
20901
|
title: "Marca da casa",
|
|
@@ -20798,15 +20908,15 @@ function BrandAgentSurface() {
|
|
|
20798
20908
|
return null;
|
|
20799
20909
|
}
|
|
20800
20910
|
function ConnectConsentPage({ appName, logo }) {
|
|
20801
|
-
const [state, setState] =
|
|
20802
|
-
const [tenantId2, setTenantId] =
|
|
20803
|
-
const request =
|
|
20911
|
+
const [state, setState] = React130__default.useState({ status: "loading" });
|
|
20912
|
+
const [tenantId2, setTenantId] = React130__default.useState("");
|
|
20913
|
+
const request = React130__default.useMemo(
|
|
20804
20914
|
() => new URLSearchParams(window.location.search).get("request") ?? "",
|
|
20805
20915
|
[]
|
|
20806
20916
|
);
|
|
20807
|
-
const connection =
|
|
20917
|
+
const connection = React130__default.useMemo(() => resolveFayzAgentConnection(), []);
|
|
20808
20918
|
const product = appName ?? document.title ?? "este app";
|
|
20809
|
-
const authorizedFetch =
|
|
20919
|
+
const authorizedFetch = React130__default.useCallback(
|
|
20810
20920
|
async (path, init) => {
|
|
20811
20921
|
if (!connection) throw new Error("Este app n\xE3o est\xE1 ligado a um projeto Fayz.");
|
|
20812
20922
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -20830,7 +20940,7 @@ function ConnectConsentPage({ appName, logo }) {
|
|
|
20830
20940
|
},
|
|
20831
20941
|
[connection]
|
|
20832
20942
|
);
|
|
20833
|
-
|
|
20943
|
+
React130__default.useEffect(() => {
|
|
20834
20944
|
let cancelled = false;
|
|
20835
20945
|
(async () => {
|
|
20836
20946
|
if (!request) {
|
|
@@ -21074,7 +21184,7 @@ function Row2({ label: label3, value }) {
|
|
|
21074
21184
|
function PageActions({ actions, className }) {
|
|
21075
21185
|
const access = useAccessOptional();
|
|
21076
21186
|
const openUpgrade = useUpgradeModalStore((s) => s.open);
|
|
21077
|
-
const resolved =
|
|
21187
|
+
const resolved = React130__default.useMemo(
|
|
21078
21188
|
() => actions.map((a) => {
|
|
21079
21189
|
const { permission, limitKey, onSelect, ...rest } = a;
|
|
21080
21190
|
let hidden = false;
|
|
@@ -21104,25 +21214,25 @@ function AddConnectorPanel({
|
|
|
21104
21214
|
onSelect
|
|
21105
21215
|
}) {
|
|
21106
21216
|
const { t } = useTranslation$1();
|
|
21107
|
-
const [query, setQuery] =
|
|
21217
|
+
const [query, setQuery] = React130__default.useState("");
|
|
21108
21218
|
const modules = useInstalledModuleIds();
|
|
21109
21219
|
const catalog = useConnectorCatalog();
|
|
21110
21220
|
const scoped = !!categories?.length;
|
|
21111
|
-
const addable =
|
|
21221
|
+
const addable = React130__default.useMemo(
|
|
21112
21222
|
() => inCategories(addableConnectors(connectors ?? []), categories),
|
|
21113
21223
|
[connectors, categories]
|
|
21114
21224
|
);
|
|
21115
|
-
const shelf =
|
|
21225
|
+
const shelf = React130__default.useMemo(() => {
|
|
21116
21226
|
if (connectors === null) return [];
|
|
21117
21227
|
return inCategories(
|
|
21118
21228
|
shelfIntegrations({ present: connectors, installedModules: modules, catalog: catalog ?? [] }),
|
|
21119
21229
|
categories
|
|
21120
21230
|
);
|
|
21121
21231
|
}, [connectors, modules, catalog, categories]);
|
|
21122
|
-
const filtered =
|
|
21123
|
-
const filteredShelf =
|
|
21124
|
-
const soon =
|
|
21125
|
-
const elsewhere =
|
|
21232
|
+
const filtered = React130__default.useMemo(() => filterConnectors(addable, "all", query), [addable, query]);
|
|
21233
|
+
const filteredShelf = React130__default.useMemo(() => filterAvailable(shelf, query), [shelf, query]);
|
|
21234
|
+
const soon = React130__default.useMemo(() => comingSoonHere(filteredShelf), [filteredShelf]);
|
|
21235
|
+
const elsewhere = React130__default.useMemo(() => withAnotherModule(filteredShelf), [filteredShelf]);
|
|
21126
21236
|
const searchable = addable.length + shelf.length > 6;
|
|
21127
21237
|
return /* @__PURE__ */ jsx(Modal, { open, onOpenChange, children: /* @__PURE__ */ jsxs(ModalContent, { size: "2xl", children: [
|
|
21128
21238
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
@@ -21281,22 +21391,22 @@ function AddConnectorButton({ onClick }) {
|
|
|
21281
21391
|
function ConnectorsTab() {
|
|
21282
21392
|
const { t } = useTranslation$1();
|
|
21283
21393
|
const { connectors, error, reload, revokeGrant, agentAvailable, tenantReady } = useConnectors();
|
|
21284
|
-
const [adding, setAdding] =
|
|
21285
|
-
const [selected, setSelected] =
|
|
21286
|
-
const [filter, setFilter] =
|
|
21287
|
-
const [failure, setFailure] =
|
|
21288
|
-
const [revoking, setRevoking] =
|
|
21394
|
+
const [adding, setAdding] = React130__default.useState(false);
|
|
21395
|
+
const [selected, setSelected] = React130__default.useState(null);
|
|
21396
|
+
const [filter, setFilter] = React130__default.useState("all");
|
|
21397
|
+
const [failure, setFailure] = React130__default.useState(null);
|
|
21398
|
+
const [revoking, setRevoking] = React130__default.useState(null);
|
|
21289
21399
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
21290
|
-
const openJourney =
|
|
21400
|
+
const openJourney = React130__default.useCallback(
|
|
21291
21401
|
(connector) => {
|
|
21292
21402
|
if (assistantAvailable) openConnectorsPanel(connector);
|
|
21293
21403
|
else setSelected(connector);
|
|
21294
21404
|
},
|
|
21295
21405
|
[assistantAvailable]
|
|
21296
21406
|
);
|
|
21297
|
-
const visible =
|
|
21298
|
-
const groups =
|
|
21299
|
-
|
|
21407
|
+
const visible = React130__default.useMemo(() => filterConnectors(connectors ?? [], filter), [connectors, filter]);
|
|
21408
|
+
const groups = React130__default.useMemo(() => groupConnectors(visible), [visible]);
|
|
21409
|
+
React130__default.useEffect(() => {
|
|
21300
21410
|
if (!selected || !connectors) return;
|
|
21301
21411
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
21302
21412
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -21331,7 +21441,7 @@ function ConnectorsTab() {
|
|
|
21331
21441
|
(connectors?.length ?? 0) > 4 && /* @__PURE__ */ jsx(Filters, { value: filter, onChange: setFilter }),
|
|
21332
21442
|
connectors === null && /* @__PURE__ */ jsx(ConnectionsSkeleton, {}),
|
|
21333
21443
|
connectors !== null && visible.length === 0 && /* @__PURE__ */ jsx(Empty2, { title: t("connectors.emptyTitle"), body: t("connectors.emptyBody") }),
|
|
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(
|
|
21444
|
+
visible.length > 0 && /* @__PURE__ */ jsx("ul", { className: "fayz-glass-surface divide-y divide-border overflow-hidden rounded-card border bg-card text-card-foreground shadow-sm", children: groups.map((group) => /* @__PURE__ */ jsxs(React130__default.Fragment, { children: [
|
|
21335
21445
|
groups.length > 1 && /* @__PURE__ */ jsx(
|
|
21336
21446
|
"li",
|
|
21337
21447
|
{
|
|
@@ -21469,7 +21579,7 @@ function oauthFailureMessage(t, result) {
|
|
|
21469
21579
|
function useConnectorOAuthReturn() {
|
|
21470
21580
|
const { t } = useTranslation$1();
|
|
21471
21581
|
const runtime = usePluginRuntimeOptional();
|
|
21472
|
-
|
|
21582
|
+
React130__default.useEffect(() => {
|
|
21473
21583
|
if (typeof window === "undefined") return;
|
|
21474
21584
|
const result = readConnectorOAuthReturn(window.location.search);
|
|
21475
21585
|
if (!result) return;
|
|
@@ -21504,8 +21614,8 @@ function ConnectorDeliveries({
|
|
|
21504
21614
|
limit = 10
|
|
21505
21615
|
}) {
|
|
21506
21616
|
const { t } = useTranslation$1();
|
|
21507
|
-
const [rows, setRows] =
|
|
21508
|
-
|
|
21617
|
+
const [rows, setRows] = React130__default.useState(null);
|
|
21618
|
+
React130__default.useEffect(() => {
|
|
21509
21619
|
let cancelled = false;
|
|
21510
21620
|
void load({ limit }).then((r) => {
|
|
21511
21621
|
if (!cancelled) setRows(r);
|
|
@@ -21579,11 +21689,11 @@ var CURRENCIES = [
|
|
|
21579
21689
|
function CompanySettings({ tenant, onSave }) {
|
|
21580
21690
|
const { t } = useTranslation$1();
|
|
21581
21691
|
const { locale: uiLocale, setLocale: setUiLocale } = useLocaleStore();
|
|
21582
|
-
const [name, setName] =
|
|
21583
|
-
const [timezone, setTimezone] =
|
|
21584
|
-
const [currency, setCurrency] =
|
|
21585
|
-
const [saving, setSaving] =
|
|
21586
|
-
|
|
21692
|
+
const [name, setName] = React130.useState(tenant?.name ?? "");
|
|
21693
|
+
const [timezone, setTimezone] = React130.useState(tenant?.settings?.timezone ?? "UTC");
|
|
21694
|
+
const [currency, setCurrency] = React130.useState(tenant?.settings?.currency ?? "USD");
|
|
21695
|
+
const [saving, setSaving] = React130.useState(false);
|
|
21696
|
+
React130.useEffect(() => {
|
|
21587
21697
|
if (tenant) {
|
|
21588
21698
|
setName(tenant.name);
|
|
21589
21699
|
setTimezone(tenant.settings?.timezone ?? "UTC");
|
|
@@ -21675,15 +21785,15 @@ function UnitModeCard() {
|
|
|
21675
21785
|
const units = useUnitStore((s) => s.units);
|
|
21676
21786
|
const setMode = useUnitStore((s) => s.setMode);
|
|
21677
21787
|
const load = useUnitStore((s) => s.load);
|
|
21678
|
-
const [unbound, setUnbound] =
|
|
21679
|
-
const [bindEveryone, setBindEveryone] =
|
|
21680
|
-
const [pending2, setPending] =
|
|
21681
|
-
const [saving, setSaving] =
|
|
21682
|
-
const headquarters =
|
|
21788
|
+
const [unbound, setUnbound] = React130.useState(null);
|
|
21789
|
+
const [bindEveryone, setBindEveryone] = React130.useState(true);
|
|
21790
|
+
const [pending2, setPending] = React130.useState(null);
|
|
21791
|
+
const [saving, setSaving] = React130.useState(false);
|
|
21792
|
+
const headquarters = React130.useMemo(
|
|
21683
21793
|
() => units.find((u) => u.isHeadquarters && u.kind !== "region") ?? units.find((u) => u.kind !== "region"),
|
|
21684
21794
|
[units]
|
|
21685
21795
|
);
|
|
21686
|
-
|
|
21796
|
+
React130.useEffect(() => {
|
|
21687
21797
|
if (!org?.id || unitMode) return;
|
|
21688
21798
|
let alive = true;
|
|
21689
21799
|
void countUnboundMembers(org.id).then((n) => {
|
|
@@ -21847,10 +21957,10 @@ function getInitials(name) {
|
|
|
21847
21957
|
}
|
|
21848
21958
|
function UserProfile({ user, onSave, onAvatarChange }) {
|
|
21849
21959
|
const { t } = useTranslation$1();
|
|
21850
|
-
const [fullName, setFullName] =
|
|
21851
|
-
const [saving, setSaving] =
|
|
21852
|
-
const fileInputRef =
|
|
21853
|
-
|
|
21960
|
+
const [fullName, setFullName] = React130.useState(user?.fullName ?? "");
|
|
21961
|
+
const [saving, setSaving] = React130.useState(false);
|
|
21962
|
+
const fileInputRef = React130.useRef(null);
|
|
21963
|
+
React130.useEffect(() => {
|
|
21854
21964
|
if (user) {
|
|
21855
21965
|
setFullName(user.fullName);
|
|
21856
21966
|
}
|
|
@@ -21990,8 +22100,8 @@ async function fetchMyPersonId(tenantId2, userId) {
|
|
|
21990
22100
|
function useMyPersonId(enabled = true) {
|
|
21991
22101
|
const orgId = useOrganizationStore((s) => s.currentOrg?.id);
|
|
21992
22102
|
const userId = useAuthStore((s) => s.user?.id);
|
|
21993
|
-
const [personId, setPersonId] =
|
|
21994
|
-
|
|
22103
|
+
const [personId, setPersonId] = React130.useState(void 0);
|
|
22104
|
+
React130.useEffect(() => {
|
|
21995
22105
|
if (!enabled || !orgId || !userId) return;
|
|
21996
22106
|
let alive = true;
|
|
21997
22107
|
void dedup(`self:person:${orgId}:${userId}`, () => fetchMyPersonId(orgId, userId)).then((id) => {
|
|
@@ -22051,18 +22161,18 @@ function MyWorkspaceCard() {
|
|
|
22051
22161
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
22052
22162
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
22053
22163
|
const entryReason = useUnitStore((s) => s.entryReason);
|
|
22054
|
-
const [person, setPerson] =
|
|
22055
|
-
const [candidate, setCandidate] =
|
|
22056
|
-
const [linking, setLinking] =
|
|
22164
|
+
const [person, setPerson] = React130.useState(void 0);
|
|
22165
|
+
const [candidate, setCandidate] = React130.useState(null);
|
|
22166
|
+
const [linking, setLinking] = React130.useState(false);
|
|
22057
22167
|
const orgId = currentOrg?.id;
|
|
22058
22168
|
const userId = user?.id;
|
|
22059
|
-
const load =
|
|
22169
|
+
const load = React130.useCallback(async () => {
|
|
22060
22170
|
if (!orgId || !userId) return;
|
|
22061
22171
|
const linked = await fetchMyPersonRecord(orgId, userId);
|
|
22062
22172
|
setPerson(linked);
|
|
22063
22173
|
setCandidate(linked ? null : await findMyPersonCandidate(orgId, user?.email, staffKinds));
|
|
22064
22174
|
}, [orgId, userId, user?.email, staffKinds]);
|
|
22065
|
-
|
|
22175
|
+
React130.useEffect(() => {
|
|
22066
22176
|
void load();
|
|
22067
22177
|
}, [load]);
|
|
22068
22178
|
if (!currentOrg) return null;
|
|
@@ -22156,10 +22266,10 @@ var useStore = create((set) => ({
|
|
|
22156
22266
|
function useHeaderAction(zone, action) {
|
|
22157
22267
|
const register = useStore((s) => s.register);
|
|
22158
22268
|
const unregister = useStore((s) => s.unregister);
|
|
22159
|
-
const latest =
|
|
22269
|
+
const latest = React130.useRef(action);
|
|
22160
22270
|
latest.current = action;
|
|
22161
22271
|
const id = action?.id;
|
|
22162
|
-
|
|
22272
|
+
React130.useEffect(() => {
|
|
22163
22273
|
if (!zone || !id) return;
|
|
22164
22274
|
const current2 = latest.current;
|
|
22165
22275
|
if (current2) register(zone, { ...current2, onSelect: () => latest.current?.onSelect() });
|
|
@@ -22168,7 +22278,7 @@ function useHeaderAction(zone, action) {
|
|
|
22168
22278
|
}
|
|
22169
22279
|
function useHeaderActions(zone) {
|
|
22170
22280
|
const byZone = useStore((s) => s.byZone);
|
|
22171
|
-
return
|
|
22281
|
+
return React130.useMemo(() => Object.values(byZone[zone] ?? {}), [byZone, zone]);
|
|
22172
22282
|
}
|
|
22173
22283
|
function useUserLabel(userId) {
|
|
22174
22284
|
const members = useOrganizationStore((s) => s.members);
|
|
@@ -23175,12 +23285,12 @@ function CrudRecordModal({
|
|
|
23175
23285
|
essentialFirst,
|
|
23176
23286
|
notice
|
|
23177
23287
|
}) {
|
|
23178
|
-
const [record, setRecord] =
|
|
23179
|
-
const [loading, setLoading] =
|
|
23180
|
-
const [saving, setSaving] =
|
|
23181
|
-
const [error, setError] =
|
|
23182
|
-
const formId =
|
|
23183
|
-
|
|
23288
|
+
const [record, setRecord] = React130.useState(null);
|
|
23289
|
+
const [loading, setLoading] = React130.useState(false);
|
|
23290
|
+
const [saving, setSaving] = React130.useState(false);
|
|
23291
|
+
const [error, setError] = React130.useState(null);
|
|
23292
|
+
const formId = React130.useId();
|
|
23293
|
+
React130.useEffect(() => {
|
|
23184
23294
|
if (!open) return;
|
|
23185
23295
|
setError(null);
|
|
23186
23296
|
if (mode === "create" || !load) {
|
|
@@ -23358,10 +23468,10 @@ function resolveRelation(relation, row) {
|
|
|
23358
23468
|
}
|
|
23359
23469
|
return { ...relation, filter: { ...relation.filter ?? {}, ...extra } };
|
|
23360
23470
|
}
|
|
23361
|
-
var PendingChildrenContext =
|
|
23471
|
+
var PendingChildrenContext = React130.createContext(null);
|
|
23362
23472
|
function usePendingChildren() {
|
|
23363
|
-
const pending2 =
|
|
23364
|
-
const provider2 =
|
|
23473
|
+
const pending2 = React130.useRef(/* @__PURE__ */ new Set());
|
|
23474
|
+
const provider2 = React130.useMemo(() => ({
|
|
23365
23475
|
register: (f) => {
|
|
23366
23476
|
pending2.current.add(f);
|
|
23367
23477
|
return () => {
|
|
@@ -23369,7 +23479,7 @@ function usePendingChildren() {
|
|
|
23369
23479
|
};
|
|
23370
23480
|
}
|
|
23371
23481
|
}), []);
|
|
23372
|
-
const flush =
|
|
23482
|
+
const flush = React130.useCallback(async (parentId) => {
|
|
23373
23483
|
for (const f of [...pending2.current]) await f(parentId);
|
|
23374
23484
|
}, []);
|
|
23375
23485
|
return { provider: provider2, flush };
|
|
@@ -23385,7 +23495,7 @@ function money(value) {
|
|
|
23385
23495
|
}
|
|
23386
23496
|
}
|
|
23387
23497
|
function GridRelationCell({ field, value, row, onChange }) {
|
|
23388
|
-
const relation =
|
|
23498
|
+
const relation = React130.useMemo(() => resolveRelation(field.relation, row), [field.relation, row]);
|
|
23389
23499
|
const { labelFor: labelFor2 } = useRelationOptions(relation);
|
|
23390
23500
|
const label3 = value ? labelFor2(value) : "";
|
|
23391
23501
|
return /* @__PURE__ */ jsx(
|
|
@@ -23416,11 +23526,11 @@ function columnOf(entity, key) {
|
|
|
23416
23526
|
}
|
|
23417
23527
|
function RelatedSection({ parentId, related, compact }) {
|
|
23418
23528
|
const orfa = !parentId;
|
|
23419
|
-
const pendentes =
|
|
23529
|
+
const pendentes = React130.useContext(PendingChildrenContext);
|
|
23420
23530
|
const fkColumn = columnOf(related.entity, related.foreignKey);
|
|
23421
23531
|
const label3 = related.label ?? related.entity.namePlural ?? related.entity.name;
|
|
23422
23532
|
const Icon = related.icon ? ICON_MAP[related.icon] ?? null : null;
|
|
23423
|
-
const child =
|
|
23533
|
+
const child = React130.useMemo(() => ({
|
|
23424
23534
|
...related.entity,
|
|
23425
23535
|
fields: related.entity.fields.filter((f) => f.key !== related.foreignKey),
|
|
23426
23536
|
data: related.entity.data ? {
|
|
@@ -23429,13 +23539,13 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23429
23539
|
defaults: { ...related.entity.data.defaults ?? {}, [fkColumn]: parentId }
|
|
23430
23540
|
} : void 0
|
|
23431
23541
|
}), [related, parentId, fkColumn]);
|
|
23432
|
-
const provider2 =
|
|
23433
|
-
const [rows, setRows] =
|
|
23434
|
-
const [loading, setLoading] =
|
|
23435
|
-
const [error, setError] =
|
|
23436
|
-
const [adding, setAdding] =
|
|
23437
|
-
const [draft, setDraft] =
|
|
23438
|
-
const load =
|
|
23542
|
+
const provider2 = React130.useMemo(() => resolveDataProvider(child, [], { cache: false }), [child]);
|
|
23543
|
+
const [rows, setRows] = React130.useState([]);
|
|
23544
|
+
const [loading, setLoading] = React130.useState(true);
|
|
23545
|
+
const [error, setError] = React130.useState(null);
|
|
23546
|
+
const [adding, setAdding] = React130.useState(false);
|
|
23547
|
+
const [draft, setDraft] = React130.useState(null);
|
|
23548
|
+
const load = React130.useCallback(async () => {
|
|
23439
23549
|
if (orfa) {
|
|
23440
23550
|
setLoading(false);
|
|
23441
23551
|
return;
|
|
@@ -23451,12 +23561,12 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23451
23561
|
setLoading(false);
|
|
23452
23562
|
}
|
|
23453
23563
|
}, [provider2, orfa]);
|
|
23454
|
-
|
|
23564
|
+
React130.useEffect(() => {
|
|
23455
23565
|
void load();
|
|
23456
23566
|
}, [load]);
|
|
23457
|
-
const guardadas =
|
|
23567
|
+
const guardadas = React130.useRef([]);
|
|
23458
23568
|
guardadas.current = rows;
|
|
23459
|
-
|
|
23569
|
+
React130.useEffect(() => {
|
|
23460
23570
|
if (!orfa || !pendentes) return;
|
|
23461
23571
|
return pendentes.register(async (novoPai) => {
|
|
23462
23572
|
if (!guardadas.current.length) return;
|
|
@@ -23480,7 +23590,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23480
23590
|
}
|
|
23481
23591
|
const shown = child.fields.filter((f) => f.showInTable !== false);
|
|
23482
23592
|
const groupKey = related.duplicable ? child.fields.find((f) => f.type === "relation")?.key : void 0;
|
|
23483
|
-
const [lastEdit, setLastEdit] =
|
|
23593
|
+
const [lastEdit, setLastEdit] = React130.useState(null);
|
|
23484
23594
|
function siblingsToSync(row, key) {
|
|
23485
23595
|
if (!groupKey || key === groupKey || row[groupKey] == null) return [];
|
|
23486
23596
|
return rows.filter((r) => r.id !== row.id && r[groupKey] === row[groupKey] && r[key] !== row[key]);
|
|
@@ -23511,7 +23621,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23511
23621
|
if (orfa) return;
|
|
23512
23622
|
queueWrite(id, mudanca, antes);
|
|
23513
23623
|
}
|
|
23514
|
-
const escritas =
|
|
23624
|
+
const escritas = React130.useRef(/* @__PURE__ */ new Map());
|
|
23515
23625
|
function queueWrite(id, mudanca, antes) {
|
|
23516
23626
|
const atual = escritas.current.get(id);
|
|
23517
23627
|
const entry = atual ?? { mudanca: {}, antes, fila: Promise.resolve() };
|
|
@@ -23540,7 +23650,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23540
23650
|
if (e && e.fila === fila && !e.timer) escritas.current.delete(id);
|
|
23541
23651
|
});
|
|
23542
23652
|
}
|
|
23543
|
-
|
|
23653
|
+
React130.useEffect(() => () => {
|
|
23544
23654
|
for (const [id, e] of escritas.current) {
|
|
23545
23655
|
if (e.timer) {
|
|
23546
23656
|
clearTimeout(e.timer);
|
|
@@ -23549,7 +23659,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
23549
23659
|
}
|
|
23550
23660
|
}, []);
|
|
23551
23661
|
const required = child.fields.filter((f) => f.required);
|
|
23552
|
-
const criando =
|
|
23662
|
+
const criando = React130.useRef(false);
|
|
23553
23663
|
async function commitDraft(key, next, price) {
|
|
23554
23664
|
const completo = { ...next, ...heranca(key, price, next) };
|
|
23555
23665
|
setDraft(completo);
|
|
@@ -23997,7 +24107,7 @@ function ServiceFormLayout({ fields, fieldGroups, values, onChange, renderField:
|
|
|
23997
24107
|
] })
|
|
23998
24108
|
] }) }) }),
|
|
23999
24109
|
pricingFields.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
24000
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: "
|
|
24110
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: tl("Price & duration", "Pre\xE7o e dura\xE7\xE3o") }),
|
|
24001
24111
|
/* @__PURE__ */ jsx(Card, { className: "mt-1", children: /* @__PURE__ */ jsx(CardContent, { className: "pt-5", children: /* @__PURE__ */ jsx("div", { className: "fz-fields fz-fields-2 gap-4", children: pricingFields.map((field) => /* @__PURE__ */ jsx(FieldItem3, { field, value: values[field.key], onChange: (val) => onChange(field.key, val), renderField: renderField2 }, field.key)) }) }) })
|
|
24002
24112
|
] }),
|
|
24003
24113
|
fieldGroups.map((group) => {
|
|
@@ -24010,7 +24120,7 @@ function ServiceFormLayout({ fields, fieldGroups, values, onChange, renderField:
|
|
|
24010
24120
|
] }, group.id);
|
|
24011
24121
|
}),
|
|
24012
24122
|
ungroupedProject.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
24013
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: "Details" }),
|
|
24123
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground", children: tl("Details", "Detalhes") }),
|
|
24014
24124
|
/* @__PURE__ */ jsx(Card, { className: "mt-1", children: /* @__PURE__ */ jsx(CardContent, { className: "pt-5", children: /* @__PURE__ */ jsx("div", { className: "fz-fields fz-fields-2 gap-4", children: ungroupedProject.map((field) => /* @__PURE__ */ jsx(FieldItem3, { field, value: values[field.key], onChange: (val) => onChange(field.key, val), renderField: renderField2, colSpan: field.span === 2 }, field.key)) }) }) })
|
|
24015
24125
|
] })
|
|
24016
24126
|
] });
|
|
@@ -24382,7 +24492,7 @@ function SubjectFormLayout({ fields, allFields, fieldGroups, values, onChange, r
|
|
|
24382
24492
|
const IconComponent = getLucideIcon(entityIcon ?? "Heart") ?? Heart;
|
|
24383
24493
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
24384
24494
|
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: "pt-5", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-5", 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:
|
|
24495
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-20 w-20 shrink-0 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: React130__default.createElement(IconComponent, { className: "h-8 w-8" }) }),
|
|
24386
24496
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-4", children: [
|
|
24387
24497
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-4", children: [
|
|
24388
24498
|
nameField && /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-1.5", children: [
|
|
@@ -24864,7 +24974,7 @@ function getDefaultValues(fields) {
|
|
|
24864
24974
|
}
|
|
24865
24975
|
return values;
|
|
24866
24976
|
}
|
|
24867
|
-
var SetFieldValueContext =
|
|
24977
|
+
var SetFieldValueContext = React130__default.createContext(void 0);
|
|
24868
24978
|
function renderField(field, value, onChange, allValues = {}, selectPlaceholder, setValue) {
|
|
24869
24979
|
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";
|
|
24870
24980
|
switch (field.type) {
|
|
@@ -25111,14 +25221,14 @@ function ImageSlot({
|
|
|
25111
25221
|
onDraftFile
|
|
25112
25222
|
}) {
|
|
25113
25223
|
const t = useTranslation();
|
|
25114
|
-
const inputRef =
|
|
25115
|
-
const [url, setUrl] =
|
|
25116
|
-
const [busy, setBusy] =
|
|
25117
|
-
const [error, setError] =
|
|
25118
|
-
const draftUrlRef =
|
|
25224
|
+
const inputRef = React130__default.useRef(null);
|
|
25225
|
+
const [url, setUrl] = React130__default.useState(() => image.get(row));
|
|
25226
|
+
const [busy, setBusy] = React130__default.useState(false);
|
|
25227
|
+
const [error, setError] = React130__default.useState(null);
|
|
25228
|
+
const draftUrlRef = React130__default.useRef(null);
|
|
25119
25229
|
const currentUrl = image.get(row);
|
|
25120
25230
|
const draftFile = image.draftField ? row[image.draftField] : void 0;
|
|
25121
|
-
|
|
25231
|
+
React130__default.useEffect(() => {
|
|
25122
25232
|
if (draftFile) return;
|
|
25123
25233
|
if (draftUrlRef.current) {
|
|
25124
25234
|
URL.revokeObjectURL(draftUrlRef.current);
|
|
@@ -25126,7 +25236,7 @@ function ImageSlot({
|
|
|
25126
25236
|
}
|
|
25127
25237
|
setUrl(currentUrl);
|
|
25128
25238
|
}, [currentUrl, draftFile]);
|
|
25129
|
-
|
|
25239
|
+
React130__default.useEffect(() => () => {
|
|
25130
25240
|
if (draftUrlRef.current) URL.revokeObjectURL(draftUrlRef.current);
|
|
25131
25241
|
}, []);
|
|
25132
25242
|
const acceptsDraft = !canEdit && Boolean(image.draftField && onDraftFile);
|
|
@@ -25276,7 +25386,7 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25276
25386
|
const [values, setValues] = useState(computeInit);
|
|
25277
25387
|
const [saving, setSaving] = useState(false);
|
|
25278
25388
|
const [invalidKeys, setInvalidKeys] = useState(EMPTY_KEYS);
|
|
25279
|
-
const initialRef =
|
|
25389
|
+
const initialRef = React130__default.useRef(JSON.stringify(values));
|
|
25280
25390
|
useEffect(() => {
|
|
25281
25391
|
const init = computeInit();
|
|
25282
25392
|
setValues(init);
|
|
@@ -25336,7 +25446,7 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25336
25446
|
if (submitRef) submitRef.current = () => {
|
|
25337
25447
|
void submit();
|
|
25338
25448
|
};
|
|
25339
|
-
|
|
25449
|
+
React130__default.useEffect(() => () => {
|
|
25340
25450
|
if (submitRef) submitRef.current = null;
|
|
25341
25451
|
}, [submitRef]);
|
|
25342
25452
|
const dirty = JSON.stringify(values) !== initialRef.current;
|
|
@@ -25905,16 +26015,16 @@ function useUnitFilter(options = {}) {
|
|
|
25905
26015
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
25906
26016
|
const can = usePermissionOptional();
|
|
25907
26017
|
const canManageUnits = can("units", "manage");
|
|
25908
|
-
const reachable =
|
|
25909
|
-
const [local2, setLocal] =
|
|
25910
|
-
|
|
26018
|
+
const reachable = React130.useMemo(() => unitFilterOptions(units, myUnitIds), [units, myUnitIds]);
|
|
26019
|
+
const [local2, setLocal] = React130.useState(activeUnitId);
|
|
26020
|
+
React130.useEffect(() => {
|
|
25911
26021
|
setLocal(activeUnitId);
|
|
25912
26022
|
}, [activeUnitId]);
|
|
25913
26023
|
const raw = scope === "global" ? activeUnitId : local2;
|
|
25914
26024
|
const value = standableUnit(raw, reachable);
|
|
25915
26025
|
const filterLabel = label(t, "units.filterLabel", "Unidade");
|
|
25916
26026
|
const allLabel = label(t, "units.filterAll", "Todas as minhas unidades");
|
|
25917
|
-
const setValue =
|
|
26027
|
+
const setValue = React130.useCallback((next) => {
|
|
25918
26028
|
if (scope === "global") {
|
|
25919
26029
|
if (next === activeUnitId) return;
|
|
25920
26030
|
beginSwitch({ unitId: next, unitName: next ? byId[next]?.name ?? "" : allLabel });
|
|
@@ -25923,7 +26033,7 @@ function useUnitFilter(options = {}) {
|
|
|
25923
26033
|
setLocal(next);
|
|
25924
26034
|
}, [scope, activeUnitId, beginSwitch, byId, allLabel]);
|
|
25925
26035
|
const visible = unitFilterVisible(unitMode, reachable);
|
|
25926
|
-
const def =
|
|
26036
|
+
const def = React130.useMemo(() => visible ? {
|
|
25927
26037
|
id: "unit",
|
|
25928
26038
|
label: filterLabel,
|
|
25929
26039
|
icon: Building2,
|
|
@@ -26065,7 +26175,7 @@ function CrudListView({
|
|
|
26065
26175
|
if (onImport) {
|
|
26066
26176
|
createRoutes.push({ id: "import", label: t("crud.import.action"), description: t("crud.import.hint"), icon: "Upload", action: onImport });
|
|
26067
26177
|
}
|
|
26068
|
-
const createActions =
|
|
26178
|
+
const createActions = React130__default.useMemo(() => {
|
|
26069
26179
|
const out = createRoutes.map((qa, i) => ({
|
|
26070
26180
|
id: qa.id,
|
|
26071
26181
|
label: qa.label,
|
|
@@ -26478,9 +26588,9 @@ function buildCrudSurfaceContribution(read3) {
|
|
|
26478
26588
|
};
|
|
26479
26589
|
}
|
|
26480
26590
|
function CrudAgentSurface(props) {
|
|
26481
|
-
const ref =
|
|
26591
|
+
const ref = React130.useRef(props);
|
|
26482
26592
|
ref.current = props;
|
|
26483
|
-
const contribution =
|
|
26593
|
+
const contribution = React130.useMemo(
|
|
26484
26594
|
() => buildCrudSurfaceContribution(() => ref.current),
|
|
26485
26595
|
[]
|
|
26486
26596
|
);
|
|
@@ -26533,7 +26643,7 @@ function useFieldRules(entityKey) {
|
|
|
26533
26643
|
};
|
|
26534
26644
|
}, [entityKey, fieldRules]);
|
|
26535
26645
|
}
|
|
26536
|
-
var ImportWizard2 =
|
|
26646
|
+
var ImportWizard2 = React130__default.lazy(
|
|
26537
26647
|
() => import('./ImportWizard-7UFB2PPF.js').then((m) => ({ default: m.ImportWizard }))
|
|
26538
26648
|
);
|
|
26539
26649
|
var PAGE_SIZE = 50;
|
|
@@ -27105,7 +27215,7 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
27105
27215
|
mode: softDelete ? "deactivate" : "delete"
|
|
27106
27216
|
}
|
|
27107
27217
|
),
|
|
27108
|
-
/* @__PURE__ */ jsx(
|
|
27218
|
+
/* @__PURE__ */ jsx(React130__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
27109
27219
|
ImportWizard2,
|
|
27110
27220
|
{
|
|
27111
27221
|
open: importOpen,
|
|
@@ -27446,7 +27556,7 @@ function columnOf2(entity, key) {
|
|
|
27446
27556
|
function RelatedListTab({ item, related, parentTabId }) {
|
|
27447
27557
|
const parentId = item?.id;
|
|
27448
27558
|
const pathname = useHashPath();
|
|
27449
|
-
const Page =
|
|
27559
|
+
const Page = React130.useMemo(() => {
|
|
27450
27560
|
if (!parentId) return null;
|
|
27451
27561
|
const child = related.entity;
|
|
27452
27562
|
const fkColumn = columnOf2(child, related.foreignKey);
|
|
@@ -27486,8 +27596,8 @@ function nestedBasePath(pathname, parentTabId, childId) {
|
|
|
27486
27596
|
}
|
|
27487
27597
|
function useHashPath() {
|
|
27488
27598
|
const read3 = () => typeof window === "undefined" ? "/" : window.location.hash.slice(1) || "/";
|
|
27489
|
-
const [path, setPath] =
|
|
27490
|
-
|
|
27599
|
+
const [path, setPath] = React130.useState(read3);
|
|
27600
|
+
React130.useEffect(() => {
|
|
27491
27601
|
const handler = () => setPath(read3());
|
|
27492
27602
|
window.addEventListener("hashchange", handler);
|
|
27493
27603
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -27567,7 +27677,7 @@ function RoleSummary({ roleId }) {
|
|
|
27567
27677
|
const profile = usePermissionsStore((s) => s.profiles.find((p) => p.id === roleId));
|
|
27568
27678
|
const features = usePermissionsStore((s) => s.features);
|
|
27569
27679
|
const canEditRoles = useSystemPermission()("manage_permissions");
|
|
27570
|
-
const groups =
|
|
27680
|
+
const groups = React130.useMemo(() => {
|
|
27571
27681
|
const map = /* @__PURE__ */ new Map();
|
|
27572
27682
|
for (const feature of features) {
|
|
27573
27683
|
const group = feature.group ?? t("crud.archetype.access.generalGroup");
|
|
@@ -27620,33 +27730,33 @@ function AccessTab({ item }) {
|
|
|
27620
27730
|
const hasSystemPermission = useSystemPermission();
|
|
27621
27731
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
27622
27732
|
const guardSeats = useLimitGuard("users");
|
|
27623
|
-
const [access, setAccess] =
|
|
27624
|
-
const [email, setEmail] =
|
|
27625
|
-
const [roleId, setRoleId] =
|
|
27626
|
-
const [busy, setBusy] =
|
|
27627
|
-
const [confirmRemove, setConfirmRemove] =
|
|
27733
|
+
const [access, setAccess] = React130.useState(void 0);
|
|
27734
|
+
const [email, setEmail] = React130.useState(person?.email ?? "");
|
|
27735
|
+
const [roleId, setRoleId] = React130.useState("");
|
|
27736
|
+
const [busy, setBusy] = React130.useState(false);
|
|
27737
|
+
const [confirmRemove, setConfirmRemove] = React130.useState(false);
|
|
27628
27738
|
const suggestedRoleId = person?.metadata?.access?.suggested_role_id;
|
|
27629
|
-
|
|
27739
|
+
React130.useEffect(() => {
|
|
27630
27740
|
if (roleId || !profiles.length) return;
|
|
27631
27741
|
const sugerido = suggestedRoleId ? profiles.find((p) => p.id === suggestedRoleId) : void 0;
|
|
27632
27742
|
setRoleId(sugerido ? sugerido.id : profiles[1]?.id ?? profiles[0].id);
|
|
27633
27743
|
}, [profiles, roleId, suggestedRoleId]);
|
|
27634
|
-
|
|
27744
|
+
React130.useEffect(() => {
|
|
27635
27745
|
setEmail(person?.email ?? "");
|
|
27636
27746
|
}, [person?.email]);
|
|
27637
|
-
const reload =
|
|
27747
|
+
const reload = React130.useCallback(async () => {
|
|
27638
27748
|
if (!personId) return;
|
|
27639
27749
|
setAccess(await fetchPersonAccess(personId));
|
|
27640
27750
|
}, [personId]);
|
|
27641
|
-
|
|
27751
|
+
React130.useEffect(() => {
|
|
27642
27752
|
void reload();
|
|
27643
27753
|
}, [reload]);
|
|
27644
|
-
|
|
27754
|
+
React130.useEffect(() => {
|
|
27645
27755
|
if (!adapter || !currentOrg || invites.length > 0) return;
|
|
27646
27756
|
adapter.listInvites(currentOrg.id).then(setInvites).catch(() => {
|
|
27647
27757
|
});
|
|
27648
27758
|
}, [adapter, currentOrg?.id]);
|
|
27649
|
-
const pendingInvite =
|
|
27759
|
+
const pendingInvite = React130.useMemo(() => {
|
|
27650
27760
|
const target = (person?.email ?? "").trim().toLowerCase();
|
|
27651
27761
|
if (!target) return void 0;
|
|
27652
27762
|
return invites.find((i) => i.status === "pending" && i.email.toLowerCase() === target);
|
|
@@ -27861,11 +27971,11 @@ function PersonUnitsTab({ item }) {
|
|
|
27861
27971
|
const units = useUnitStore((s) => s.units);
|
|
27862
27972
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
27863
27973
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
27864
|
-
const [userId, setUserId] =
|
|
27865
|
-
const [bindings, setBindings] =
|
|
27866
|
-
const [busy, setBusy] =
|
|
27974
|
+
const [userId, setUserId] = React130.useState(void 0);
|
|
27975
|
+
const [bindings, setBindings] = React130.useState({});
|
|
27976
|
+
const [busy, setBusy] = React130.useState(null);
|
|
27867
27977
|
const bindingsVersion = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
27868
|
-
|
|
27978
|
+
React130.useEffect(() => {
|
|
27869
27979
|
if (!personId) return;
|
|
27870
27980
|
let alive = true;
|
|
27871
27981
|
void fetchUserIdForPerson(personId).then((uid2) => {
|
|
@@ -27875,11 +27985,11 @@ function PersonUnitsTab({ item }) {
|
|
|
27875
27985
|
alive = false;
|
|
27876
27986
|
};
|
|
27877
27987
|
}, [personId]);
|
|
27878
|
-
const reload =
|
|
27988
|
+
const reload = React130.useCallback(async (uid2) => {
|
|
27879
27989
|
const rows = await fetchMemberUnits(uid2);
|
|
27880
27990
|
setBindings(Object.fromEntries(rows.map((r) => [r.locationId, r.role])));
|
|
27881
27991
|
}, []);
|
|
27882
|
-
|
|
27992
|
+
React130.useEffect(() => {
|
|
27883
27993
|
if (userId) void reload(userId);
|
|
27884
27994
|
}, [userId, reload, bindingsVersion]);
|
|
27885
27995
|
async function toggle(unitId, on) {
|
|
@@ -27977,13 +28087,13 @@ function PersonUnitsTab({ item }) {
|
|
|
27977
28087
|
function PersonAvailabilityTab({ item }) {
|
|
27978
28088
|
const person = item;
|
|
27979
28089
|
const personId = person?.id;
|
|
27980
|
-
const [units, setUnits] =
|
|
27981
|
-
const [selected, setSelected] =
|
|
27982
|
-
const [loading, setLoading] =
|
|
27983
|
-
const [busy, setBusy] =
|
|
27984
|
-
const [availabilityReady, setAvailabilityReady] =
|
|
28090
|
+
const [units, setUnits] = React130.useState([]);
|
|
28091
|
+
const [selected, setSelected] = React130.useState(/* @__PURE__ */ new Set());
|
|
28092
|
+
const [loading, setLoading] = React130.useState(true);
|
|
28093
|
+
const [busy, setBusy] = React130.useState(false);
|
|
28094
|
+
const [availabilityReady, setAvailabilityReady] = React130.useState(true);
|
|
27985
28095
|
const db2 = () => getSupabaseClientOptional();
|
|
27986
|
-
const load =
|
|
28096
|
+
const load = React130.useCallback(async () => {
|
|
27987
28097
|
const client3 = db2();
|
|
27988
28098
|
if (!client3 || !personId) {
|
|
27989
28099
|
setLoading(false);
|
|
@@ -28012,7 +28122,7 @@ function PersonAvailabilityTab({ item }) {
|
|
|
28012
28122
|
setLoading(false);
|
|
28013
28123
|
}
|
|
28014
28124
|
}, [personId]);
|
|
28015
|
-
|
|
28125
|
+
React130.useEffect(() => {
|
|
28016
28126
|
void load();
|
|
28017
28127
|
}, [load]);
|
|
28018
28128
|
async function makeOrganizationWide() {
|
|
@@ -28090,10 +28200,10 @@ function PersonAvailabilityTab({ item }) {
|
|
|
28090
28200
|
/* @__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." })
|
|
28091
28201
|
] }) });
|
|
28092
28202
|
}
|
|
28093
|
-
var ScheduleEditor2 =
|
|
28094
|
-
() => import('./ScheduleEditor-
|
|
28203
|
+
var ScheduleEditor2 = React130__default.lazy(
|
|
28204
|
+
() => import('./ScheduleEditor-ZEG6PG3Z.js').then((m) => ({ default: m.ScheduleEditor }))
|
|
28095
28205
|
);
|
|
28096
|
-
var PersonTimeline2 =
|
|
28206
|
+
var PersonTimeline2 = React130__default.lazy(
|
|
28097
28207
|
() => import('./timeline-LECYQ4IA.js').then((m) => ({ default: m.PersonTimeline }))
|
|
28098
28208
|
);
|
|
28099
28209
|
function ComingSoon({ icon: Icon, title, description }) {
|
|
@@ -28117,7 +28227,7 @@ function ActivityTab({ item, recordPath }) {
|
|
|
28117
28227
|
}
|
|
28118
28228
|
);
|
|
28119
28229
|
}
|
|
28120
|
-
return /* @__PURE__ */ jsx(
|
|
28230
|
+
return /* @__PURE__ */ jsx(React130__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(PersonTimeline2, { personId: item.id, recordPath }) });
|
|
28121
28231
|
}
|
|
28122
28232
|
function DocumentsTab({ item }) {
|
|
28123
28233
|
const t = useTranslation();
|
|
@@ -28229,7 +28339,7 @@ function ScheduleTab({ item }) {
|
|
|
28229
28339
|
return (
|
|
28230
28340
|
// O interruptor "Aparece na agenda" agora vem DENTRO do editor: era a
|
|
28231
28341
|
// única coisa que esta porta mostrava e a da agenda não.
|
|
28232
|
-
/* @__PURE__ */ jsx(
|
|
28342
|
+
/* @__PURE__ */ jsx(React130__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(ScheduleEditor2, { assigneeId: item.id }) })
|
|
28233
28343
|
);
|
|
28234
28344
|
}
|
|
28235
28345
|
var PERSON_DETAIL_TABS = [
|
|
@@ -28716,7 +28826,7 @@ function InlineEditor({
|
|
|
28716
28826
|
}) {
|
|
28717
28827
|
const [draft, setDraft] = useState(value ?? "");
|
|
28718
28828
|
const [saving, setSaving] = useState(false);
|
|
28719
|
-
const inputRef =
|
|
28829
|
+
const inputRef = React130__default.useRef(null);
|
|
28720
28830
|
useEffect(() => {
|
|
28721
28831
|
inputRef.current?.focus();
|
|
28722
28832
|
if (inputRef.current instanceof HTMLInputElement) inputRef.current.select();
|
|
@@ -29087,9 +29197,9 @@ function CrudDetailPage({
|
|
|
29087
29197
|
const t = useTranslation();
|
|
29088
29198
|
const [pending2, setPending] = useState({});
|
|
29089
29199
|
const [savingDraft, setSavingDraft] = useState(false);
|
|
29090
|
-
const pendingKeys =
|
|
29200
|
+
const pendingKeys = React130__default.useMemo(() => new Set(Object.keys(pending2)), [pending2]);
|
|
29091
29201
|
const dirty = pendingKeys.size > 0;
|
|
29092
|
-
const view =
|
|
29202
|
+
const view = React130__default.useMemo(
|
|
29093
29203
|
() => dirty ? { ...item, ...pending2 } : item,
|
|
29094
29204
|
[item, pending2, dirty]
|
|
29095
29205
|
);
|
|
@@ -29139,7 +29249,7 @@ function CrudDetailPage({
|
|
|
29139
29249
|
const isMyRecord = Boolean(myPersonId) && myPersonId === item.id;
|
|
29140
29250
|
const nameEditable = Boolean(onFieldSave || onFieldsSave) && Boolean(displayFieldDef) && isInlineEditable(displayFieldDef);
|
|
29141
29251
|
const [editingName, setEditingName] = useState(false);
|
|
29142
|
-
const imageInputRef =
|
|
29252
|
+
const imageInputRef = React130__default.useRef(null);
|
|
29143
29253
|
const runtime = usePluginRuntimeOptional();
|
|
29144
29254
|
const archetypeTabs = getArchetypeTabs(entityDef.layout, entityDef.data?.archetypeKind);
|
|
29145
29255
|
const relatedTabs = (entityDef.relatedLists ?? []).map((related) => ({
|
|
@@ -29149,7 +29259,7 @@ function CrudDetailPage({
|
|
|
29149
29259
|
component: (props) => /* @__PURE__ */ jsx(RelatedListTab, { ...props, related })
|
|
29150
29260
|
}));
|
|
29151
29261
|
const unitMode = useUnitMode();
|
|
29152
|
-
const fieldGroupTabs =
|
|
29262
|
+
const fieldGroupTabs = React130__default.useMemo(() => {
|
|
29153
29263
|
const groups = entityDef.fieldGroups ?? [];
|
|
29154
29264
|
if (!groups.some((g) => g.tab) || !item) return [];
|
|
29155
29265
|
const applicable = new Set(visibleDetailFields(entityDef, item).map((f) => f.group));
|
|
@@ -29232,7 +29342,7 @@ function CrudDetailPage({
|
|
|
29232
29342
|
window.history.replaceState(null, "", `#${segments.length ? `${base}/${segments.join("/")}` : base}`);
|
|
29233
29343
|
}, [basePath, item.id, selectedTab, embedded]);
|
|
29234
29344
|
const parentLabel = usePresetLabel(basePath, namePlural);
|
|
29235
|
-
const headerNode =
|
|
29345
|
+
const headerNode = React130__default.useMemo(
|
|
29236
29346
|
() => embedded ? null : /* @__PURE__ */ jsx(SubpageHeader, { title: displayValue, parentLabel, onBack }),
|
|
29237
29347
|
[embedded, displayValue, parentLabel, onBack]
|
|
29238
29348
|
);
|
|
@@ -29364,7 +29474,7 @@ function CrudDetailPage({
|
|
|
29364
29474
|
})
|
|
29365
29475
|
] }),
|
|
29366
29476
|
/* @__PURE__ */ jsxs(TabsContent, { value: "overview", className: embedded ? "mt-2" : "mt-4", children: [
|
|
29367
|
-
entityDef.overviewComponent ?
|
|
29477
|
+
entityDef.overviewComponent ? React130__default.createElement(entityDef.overviewComponent, { item, entityDef }) : /* @__PURE__ */ jsx(
|
|
29368
29478
|
OverviewTab,
|
|
29369
29479
|
{
|
|
29370
29480
|
entityDef,
|
|
@@ -29383,7 +29493,7 @@ function CrudDetailPage({
|
|
|
29383
29493
|
// `tabPath` only to the tab the URL is actually addressing —
|
|
29384
29494
|
// handing it to every tab would have the documents tab trying to
|
|
29385
29495
|
// open a recording id when the user switches across.
|
|
29386
|
-
|
|
29496
|
+
React130__default.createElement(tab.component, {
|
|
29387
29497
|
item,
|
|
29388
29498
|
entityDef,
|
|
29389
29499
|
// A rota DESTE registro. Uma aba que lista eventos precisa
|
|
@@ -29424,8 +29534,8 @@ function MyRecordPanel() {
|
|
|
29424
29534
|
const userId = useAuthStore((s) => s.user?.id);
|
|
29425
29535
|
const members = useOrganizationStore((s) => s.members);
|
|
29426
29536
|
const myRole = members.find((m) => m.userId === userId)?.profileName;
|
|
29427
|
-
const [state, setState] =
|
|
29428
|
-
const load =
|
|
29537
|
+
const [state, setState] = React130.useState({ status: "loading" });
|
|
29538
|
+
const load = React130.useCallback(async () => {
|
|
29429
29539
|
if (!orgId || !userId) return;
|
|
29430
29540
|
const person = await dedup(`self:record:${orgId}:${userId}`, () => fetchMyPersonRecord(orgId, userId));
|
|
29431
29541
|
if (!person) return setState({ status: "none" });
|
|
@@ -29442,10 +29552,10 @@ function MyRecordPanel() {
|
|
|
29442
29552
|
setState({ status: "none" });
|
|
29443
29553
|
}
|
|
29444
29554
|
}, [orgId, userId]);
|
|
29445
|
-
|
|
29555
|
+
React130.useEffect(() => {
|
|
29446
29556
|
void load();
|
|
29447
29557
|
}, [load]);
|
|
29448
|
-
const changePhoto =
|
|
29558
|
+
const changePhoto = React130.useCallback(async (file) => {
|
|
29449
29559
|
if (state.status !== "ready") return;
|
|
29450
29560
|
const supabase = getFayzSupabaseClientOptional();
|
|
29451
29561
|
if (!supabase) return;
|
|
@@ -29501,8 +29611,8 @@ function ConnectedUserProfile() {
|
|
|
29501
29611
|
const myPersonId = useMyPersonId();
|
|
29502
29612
|
const hasRecord = Boolean(myPersonId);
|
|
29503
29613
|
const setUser = useAuthStore((s) => s.setUser);
|
|
29504
|
-
const [profile, setProfile] =
|
|
29505
|
-
|
|
29614
|
+
const [profile, setProfile] = React130.useState(null);
|
|
29615
|
+
React130.useEffect(() => {
|
|
29506
29616
|
const supabase = getFayzSupabaseClientOptional();
|
|
29507
29617
|
if (!user || !supabase) return;
|
|
29508
29618
|
let cancelled = false;
|
|
@@ -29613,9 +29723,9 @@ function SecuritySettings({
|
|
|
29613
29723
|
onTenantSecurityChange
|
|
29614
29724
|
}) {
|
|
29615
29725
|
const { t } = useTranslation$1();
|
|
29616
|
-
const [resetting, setResetting] =
|
|
29617
|
-
const [resetSent, setResetSent] =
|
|
29618
|
-
const [savingTenant, setSavingTenant] =
|
|
29726
|
+
const [resetting, setResetting] = React130.useState(false);
|
|
29727
|
+
const [resetSent, setResetSent] = React130.useState(false);
|
|
29728
|
+
const [savingTenant, setSavingTenant] = React130.useState(false);
|
|
29619
29729
|
const handleResetPassword = async () => {
|
|
29620
29730
|
if (!onResetPassword) return;
|
|
29621
29731
|
setResetting(true);
|
|
@@ -29789,8 +29899,8 @@ function FileUploadField({
|
|
|
29789
29899
|
hint
|
|
29790
29900
|
}) {
|
|
29791
29901
|
const { t } = useTranslation$1();
|
|
29792
|
-
const inputRef =
|
|
29793
|
-
const [preview, setPreview] =
|
|
29902
|
+
const inputRef = React130.useRef(null);
|
|
29903
|
+
const [preview, setPreview] = React130.useState(null);
|
|
29794
29904
|
const handleChange = (e) => {
|
|
29795
29905
|
const file = e.target.files?.[0];
|
|
29796
29906
|
if (file) {
|
|
@@ -30012,13 +30122,13 @@ function SkinGate({ children }) {
|
|
|
30012
30122
|
}
|
|
30013
30123
|
function BrandingSettings({ brand, onSave }) {
|
|
30014
30124
|
const { t } = useTranslation$1();
|
|
30015
|
-
const [section, setSection] =
|
|
30016
|
-
const [saved, setSaved] =
|
|
30017
|
-
const [draft, setDraft] =
|
|
30018
|
-
const [logoFile, setLogoFile] =
|
|
30019
|
-
const [faviconFile, setFaviconFile] =
|
|
30020
|
-
const [saving, setSaving] =
|
|
30021
|
-
|
|
30125
|
+
const [section, setSection] = React130.useState("identity");
|
|
30126
|
+
const [saved, setSaved] = React130.useState(brand ?? EMPTY_BRAND);
|
|
30127
|
+
const [draft, setDraft] = React130.useState(brand ?? EMPTY_BRAND);
|
|
30128
|
+
const [logoFile, setLogoFile] = React130.useState(null);
|
|
30129
|
+
const [faviconFile, setFaviconFile] = React130.useState(null);
|
|
30130
|
+
const [saving, setSaving] = React130.useState(false);
|
|
30131
|
+
React130.useEffect(() => {
|
|
30022
30132
|
if (brand) {
|
|
30023
30133
|
setSaved(brand);
|
|
30024
30134
|
setDraft(brand);
|
|
@@ -30392,11 +30502,11 @@ function ConnectedBrandingSettings() {
|
|
|
30392
30502
|
toast.error("N\xE3o foi poss\xEDvel salvar a marca", { description: err?.message });
|
|
30393
30503
|
}
|
|
30394
30504
|
};
|
|
30395
|
-
const [brand, setBrand] =
|
|
30505
|
+
const [brand, setBrand] = React130.useState(() => normalizeBrand(
|
|
30396
30506
|
(currentOrg?.settings ?? {}).branding,
|
|
30397
30507
|
{ name: currentOrg?.name, logoUrl: currentOrg?.logoUrl }
|
|
30398
30508
|
));
|
|
30399
|
-
|
|
30509
|
+
React130.useEffect(() => {
|
|
30400
30510
|
let alive = true;
|
|
30401
30511
|
void (async () => {
|
|
30402
30512
|
try {
|
|
@@ -30517,12 +30627,12 @@ function ProjectsSettings() {
|
|
|
30517
30627
|
const projects = useFayzProjectsStore((s) => s.projects);
|
|
30518
30628
|
const load = useFayzProjectsStore((s) => s.load);
|
|
30519
30629
|
const refresh = useFayzProjectsStore((s) => s.refresh);
|
|
30520
|
-
const [linking, setLinking] =
|
|
30630
|
+
const [linking, setLinking] = React130.useState(false);
|
|
30521
30631
|
const connected = isPlatformConnected();
|
|
30522
|
-
|
|
30632
|
+
React130.useEffect(() => {
|
|
30523
30633
|
void load(currentOrgId);
|
|
30524
30634
|
}, [currentOrgId, load]);
|
|
30525
|
-
|
|
30635
|
+
React130.useEffect(() => {
|
|
30526
30636
|
if (!connected || projects.length === 0) return;
|
|
30527
30637
|
let cancelled = false;
|
|
30528
30638
|
void (async () => {
|
|
@@ -30594,7 +30704,7 @@ function SiteRow({
|
|
|
30594
30704
|
showDefaultAction,
|
|
30595
30705
|
onChanged
|
|
30596
30706
|
}) {
|
|
30597
|
-
const [busy, setBusy] =
|
|
30707
|
+
const [busy, setBusy] = React130.useState(false);
|
|
30598
30708
|
const editorUrl = editorUrlOf(project);
|
|
30599
30709
|
const run = async (action) => {
|
|
30600
30710
|
setBusy(true);
|
|
@@ -30665,7 +30775,7 @@ function SiteRow({
|
|
|
30665
30775
|
] });
|
|
30666
30776
|
}
|
|
30667
30777
|
function LinkSiteModal({ onClose, onLinked }) {
|
|
30668
|
-
const [mode, setMode] =
|
|
30778
|
+
const [mode, setMode] = React130.useState("import");
|
|
30669
30779
|
return /* @__PURE__ */ jsx(Modal, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs(ModalContent, { size: "lg", children: [
|
|
30670
30780
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
30671
30781
|
/* @__PURE__ */ jsx(ModalTitle, { children: "Vincular um site" }),
|
|
@@ -30701,11 +30811,11 @@ function ModeTab({
|
|
|
30701
30811
|
}
|
|
30702
30812
|
function ImportPane({ onLinked }) {
|
|
30703
30813
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
30704
|
-
const [search, setSearch] =
|
|
30705
|
-
const [remote, setRemote] =
|
|
30706
|
-
const [error, setError] =
|
|
30707
|
-
const [linkingId, setLinkingId] =
|
|
30708
|
-
|
|
30814
|
+
const [search, setSearch] = React130.useState("");
|
|
30815
|
+
const [remote, setRemote] = React130.useState(null);
|
|
30816
|
+
const [error, setError] = React130.useState(null);
|
|
30817
|
+
const [linkingId, setLinkingId] = React130.useState(null);
|
|
30818
|
+
React130.useEffect(() => {
|
|
30709
30819
|
let cancelled = false;
|
|
30710
30820
|
setError(null);
|
|
30711
30821
|
const timer = setTimeout(() => {
|
|
@@ -30787,9 +30897,9 @@ function ImportPane({ onLinked }) {
|
|
|
30787
30897
|
}
|
|
30788
30898
|
function CreatePane({ onLinked, onCancel }) {
|
|
30789
30899
|
const linked = useFayzProjectsStore((s) => s.projects);
|
|
30790
|
-
const [prompt, setPrompt] =
|
|
30791
|
-
const [busy, setBusy] =
|
|
30792
|
-
const [error, setError] =
|
|
30900
|
+
const [prompt, setPrompt] = React130.useState("");
|
|
30901
|
+
const [busy, setBusy] = React130.useState(false);
|
|
30902
|
+
const [error, setError] = React130.useState(null);
|
|
30793
30903
|
const tooShort = prompt.trim().length < PROMPT_MIN_CHARS;
|
|
30794
30904
|
const submit = async () => {
|
|
30795
30905
|
setBusy(true);
|
|
@@ -30978,10 +31088,10 @@ function ModuleCatalogSections({
|
|
|
30978
31088
|
onToggle,
|
|
30979
31089
|
busy
|
|
30980
31090
|
}) {
|
|
30981
|
-
const [query, setQuery] =
|
|
31091
|
+
const [query, setQuery] = React130.useState("");
|
|
30982
31092
|
const total = categories.reduce((n, c) => n + c.rows.length, 0);
|
|
30983
31093
|
const searchable = total > 6;
|
|
30984
|
-
const filtered =
|
|
31094
|
+
const filtered = React130.useMemo(() => filterCategories(categories, query), [categories, query]);
|
|
30985
31095
|
if (categories.length === 0) {
|
|
30986
31096
|
return /* @__PURE__ */ jsxs("div", { className: "py-8 text-center", children: [
|
|
30987
31097
|
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Nada a adicionar" }),
|
|
@@ -31023,7 +31133,7 @@ function CategorySection({
|
|
|
31023
31133
|
onToggle,
|
|
31024
31134
|
busy
|
|
31025
31135
|
}) {
|
|
31026
|
-
const [open, setOpen] =
|
|
31136
|
+
const [open, setOpen] = React130.useState(category.mine);
|
|
31027
31137
|
const expanded = open || forceOpen;
|
|
31028
31138
|
const Chevron = expanded ? ChevronDown : ChevronRight;
|
|
31029
31139
|
return /* @__PURE__ */ jsxs("section", { children: [
|
|
@@ -31154,8 +31264,8 @@ function buildCategories(catalog, rows) {
|
|
|
31154
31264
|
}
|
|
31155
31265
|
function useModuleCatalog() {
|
|
31156
31266
|
const tenantId2 = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
31157
|
-
const [catalog, setCatalog] =
|
|
31158
|
-
|
|
31267
|
+
const [catalog, setCatalog] = React130.useState([]);
|
|
31268
|
+
React130.useEffect(() => {
|
|
31159
31269
|
const supabase = getSupabaseClientOptional$1();
|
|
31160
31270
|
if (!supabase) return;
|
|
31161
31271
|
let alive = true;
|
|
@@ -31172,7 +31282,7 @@ function useModuleCatalog() {
|
|
|
31172
31282
|
function ModulesPreview() {
|
|
31173
31283
|
const runtime = usePluginRuntime();
|
|
31174
31284
|
const preset = useAppPreset();
|
|
31175
|
-
const rows =
|
|
31285
|
+
const rows = React130.useMemo(() => {
|
|
31176
31286
|
const flat = runtime.navigation.filter((entry) => entry.section !== "settings").map((entry) => toRailRow(entry, preset.labels));
|
|
31177
31287
|
return applyRailPreset(flat, preset.rail, preset.hide, preset.whole);
|
|
31178
31288
|
}, [runtime.navigation, preset.rail, preset.hide, preset.whole, preset.labels]);
|
|
@@ -31216,15 +31326,15 @@ function PreviewRow({ row, depth = 0 }) {
|
|
|
31216
31326
|
function ModulesSettings({ hidden = [], onToggle, permits, busy, catalog = [] }) {
|
|
31217
31327
|
const runtime = usePluginRuntime();
|
|
31218
31328
|
const offered = useOfferedPlugins();
|
|
31219
|
-
const [adding, setAdding] =
|
|
31220
|
-
const rows =
|
|
31329
|
+
const [adding, setAdding] = React130.useState(false);
|
|
31330
|
+
const rows = React130.useMemo(() => {
|
|
31221
31331
|
const known = catalog.length ? new Set(catalog.flatMap((app) => app.modules)) : new Set(offered);
|
|
31222
31332
|
const inCatalogue = known.size ? runtime.plugins.filter((p) => known.has(p.id) || p.isActive) : runtime.plugins;
|
|
31223
31333
|
return buildRows(inCatalogue, new Set(hidden), permits);
|
|
31224
31334
|
}, [runtime.plugins, hidden, permits, offered, catalog]);
|
|
31225
31335
|
const on = rows.filter((r) => r.plugin.isActive);
|
|
31226
|
-
const off =
|
|
31227
|
-
const categories =
|
|
31336
|
+
const off = React130.useMemo(() => rows.filter((r) => !r.plugin.isActive), [rows]);
|
|
31337
|
+
const categories = React130.useMemo(() => buildCategories(catalog, off), [catalog, off]);
|
|
31228
31338
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-8", children: [
|
|
31229
31339
|
/* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsxs(Button, { size: "sm", className: "shrink-0 gap-1.5", onClick: () => setAdding(true), children: [
|
|
31230
31340
|
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
|
|
@@ -31444,8 +31554,8 @@ function ConnectedModulesSettings({ hidden = SHELL_PLUGINS }) {
|
|
|
31444
31554
|
const access = useAccessOptional();
|
|
31445
31555
|
const catalog = useModuleCatalog();
|
|
31446
31556
|
const tenantId2 = useOrganizationStore((s) => s.currentOrg?.id ?? null);
|
|
31447
|
-
const [busy, setBusy] =
|
|
31448
|
-
const onToggle =
|
|
31557
|
+
const [busy, setBusy] = React130.useState(false);
|
|
31558
|
+
const onToggle = React130.useCallback(
|
|
31449
31559
|
async (plugin, status, facet) => {
|
|
31450
31560
|
const supabase = getSupabaseClientOptional$1();
|
|
31451
31561
|
if (!supabase) return;
|
|
@@ -31471,7 +31581,7 @@ function ConnectedModulesSettings({ hidden = SHELL_PLUGINS }) {
|
|
|
31471
31581
|
},
|
|
31472
31582
|
[refresh, tenantId2]
|
|
31473
31583
|
);
|
|
31474
|
-
const permits =
|
|
31584
|
+
const permits = React130.useCallback(
|
|
31475
31585
|
(plugin) => access ? access.can(plugin, "read").allowed || access.entitled(plugin) : true,
|
|
31476
31586
|
[access]
|
|
31477
31587
|
);
|
|
@@ -31482,7 +31592,7 @@ function useCoreSettingsTabs({
|
|
|
31482
31592
|
showBranding = true
|
|
31483
31593
|
} = {}) {
|
|
31484
31594
|
const { t } = useTranslation$1();
|
|
31485
|
-
return
|
|
31595
|
+
return React130.useMemo(() => [
|
|
31486
31596
|
...showCompany ? [{ id: "general", label: t("settings.general"), icon: /* @__PURE__ */ jsx(Building2, { className: "h-4 w-4" }), iconName: "Building2", component: /* @__PURE__ */ jsx(ConnectedCompanySettings, {}) }] : [],
|
|
31487
31597
|
{ id: "profile", label: t("settings.profile"), icon: /* @__PURE__ */ jsx(User, { className: "h-4 w-4" }), iconName: "User", component: /* @__PURE__ */ jsx(ConnectedUserProfile, {}) },
|
|
31488
31598
|
{ id: "security", label: t("settings.security"), icon: /* @__PURE__ */ jsx(Shield, { className: "h-4 w-4" }), iconName: "Shield", component: /* @__PURE__ */ jsx(ConnectedSecuritySettings, {}) },
|
|
@@ -31527,10 +31637,10 @@ function SettingsPage({
|
|
|
31527
31637
|
}
|
|
31528
31638
|
return null;
|
|
31529
31639
|
}
|
|
31530
|
-
const [activeTab, setActiveTab] =
|
|
31640
|
+
const [activeTab, setActiveTab] = React130.useState(() => {
|
|
31531
31641
|
return getTabFromHash() ?? defaultTab ?? null;
|
|
31532
31642
|
});
|
|
31533
|
-
|
|
31643
|
+
React130.useEffect(() => {
|
|
31534
31644
|
const handler = () => {
|
|
31535
31645
|
const tab = getTabFromHash();
|
|
31536
31646
|
if (tab) setActiveTab(tab);
|
|
@@ -31557,8 +31667,8 @@ function SettingsPage({
|
|
|
31557
31667
|
setActiveTab(null);
|
|
31558
31668
|
window.location.hash = "/settings";
|
|
31559
31669
|
};
|
|
31560
|
-
const [query, setQuery] =
|
|
31561
|
-
const sections =
|
|
31670
|
+
const [query, setQuery] = React130.useState("");
|
|
31671
|
+
const sections = React130.useMemo(() => {
|
|
31562
31672
|
const q = query.trim().toLowerCase();
|
|
31563
31673
|
const out = [];
|
|
31564
31674
|
for (const tab of resolvedTabs) {
|
|
@@ -31643,14 +31753,14 @@ function InviteMemberDialog({ open, onOpenChange, defaultEmail }) {
|
|
|
31643
31753
|
const profiles = usePermissionsStore((s) => s.profiles);
|
|
31644
31754
|
const setInvites = useInviteStore((s) => s.setInvites);
|
|
31645
31755
|
const { user } = useAuthStore();
|
|
31646
|
-
const [emails, setEmails] =
|
|
31647
|
-
const [profileId, setProfileId] =
|
|
31648
|
-
const [sending, setSending] =
|
|
31649
|
-
const [sent, setSent] =
|
|
31650
|
-
|
|
31756
|
+
const [emails, setEmails] = React130.useState([defaultEmail ?? ""]);
|
|
31757
|
+
const [profileId, setProfileId] = React130.useState(profiles[1]?.id ?? profiles[0]?.id ?? "");
|
|
31758
|
+
const [sending, setSending] = React130.useState(false);
|
|
31759
|
+
const [sent, setSent] = React130.useState(false);
|
|
31760
|
+
React130.useEffect(() => {
|
|
31651
31761
|
if (open) setEmails([defaultEmail ?? ""]);
|
|
31652
31762
|
}, [open, defaultEmail]);
|
|
31653
|
-
|
|
31763
|
+
React130.useEffect(() => {
|
|
31654
31764
|
if (!profileId && profiles.length) setProfileId(profiles[1]?.id ?? profiles[0].id);
|
|
31655
31765
|
}, [profiles, profileId]);
|
|
31656
31766
|
const addEmail = () => setEmails((prev) => [...prev, ""]);
|
|
@@ -31754,7 +31864,7 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
31754
31864
|
const myUnitIds = useUnitStore((s) => s.myUnitIds);
|
|
31755
31865
|
const activeUnitId = useUnitStore((s) => s.activeUnitId);
|
|
31756
31866
|
const beginSwitch = useUnitSwitchingStore((s) => s.begin);
|
|
31757
|
-
const [query, setQuery] =
|
|
31867
|
+
const [query, setQuery] = React130.useState("");
|
|
31758
31868
|
const singular = label2(t, "unit.singular", "unidade");
|
|
31759
31869
|
const plural = label2(t, "unit.plural", "unidades");
|
|
31760
31870
|
if (!unitMode) return null;
|
|
@@ -31779,13 +31889,13 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
31779
31889
|
}
|
|
31780
31890
|
const renderNode = (node, depth) => {
|
|
31781
31891
|
if (node.kind === "region") {
|
|
31782
|
-
return /* @__PURE__ */ jsxs(
|
|
31892
|
+
return /* @__PURE__ */ jsxs(React130.Fragment, { children: [
|
|
31783
31893
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
31784
31894
|
node.children.map((child) => renderNode(child, depth + 1))
|
|
31785
31895
|
] }, node.id);
|
|
31786
31896
|
}
|
|
31787
31897
|
if (!reachable.includes(node.id)) return null;
|
|
31788
|
-
return /* @__PURE__ */ jsxs(
|
|
31898
|
+
return /* @__PURE__ */ jsxs(React130.Fragment, { children: [
|
|
31789
31899
|
/* @__PURE__ */ jsxs(
|
|
31790
31900
|
DropdownItem,
|
|
31791
31901
|
{
|
|
@@ -31868,7 +31978,7 @@ function UnitSwitcher({ collapsed = false, className }) {
|
|
|
31868
31978
|
var MENU_LIST_CAP = 5;
|
|
31869
31979
|
function UnitMenuSection() {
|
|
31870
31980
|
useUnitBootstrap();
|
|
31871
|
-
const [locating, setLocating] =
|
|
31981
|
+
const [locating, setLocating] = React130.useState(false);
|
|
31872
31982
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
31873
31983
|
const units = useUnitStore((s) => s.units);
|
|
31874
31984
|
const tree = useUnitStore((s) => s.tree);
|
|
@@ -31919,13 +32029,13 @@ function UnitMenuSection() {
|
|
|
31919
32029
|
if (node.kind === "region") {
|
|
31920
32030
|
const visibleChildren = node.children.filter((c) => c.kind === "region" || reachable.includes(c.id));
|
|
31921
32031
|
if (visibleChildren.length === 0) return null;
|
|
31922
|
-
return /* @__PURE__ */ jsxs(
|
|
32032
|
+
return /* @__PURE__ */ jsxs(React130.Fragment, { children: [
|
|
31923
32033
|
/* @__PURE__ */ jsx(DropdownLabel, { className: "px-2 pt-2 text-[10px] uppercase tracking-wide text-muted-foreground", children: node.name }),
|
|
31924
32034
|
visibleChildren.map((child) => renderNode(child, depth + 1))
|
|
31925
32035
|
] }, node.id);
|
|
31926
32036
|
}
|
|
31927
32037
|
if (!reachable.includes(node.id)) return null;
|
|
31928
|
-
return /* @__PURE__ */ jsxs(
|
|
32038
|
+
return /* @__PURE__ */ jsxs(React130.Fragment, { children: [
|
|
31929
32039
|
/* @__PURE__ */ jsxs(
|
|
31930
32040
|
DropdownItem,
|
|
31931
32041
|
{
|
|
@@ -32044,7 +32154,7 @@ var UNIT_DETAIL_TABS = [
|
|
|
32044
32154
|
{ id: "activity", label: "Activity", hidden: true }
|
|
32045
32155
|
];
|
|
32046
32156
|
function SuggestInput({ column, value, onChange, placeholder }) {
|
|
32047
|
-
const search =
|
|
32157
|
+
const search = React130__default.useCallback(async (query) => {
|
|
32048
32158
|
const supabase = getSupabaseClientOptional();
|
|
32049
32159
|
if (!supabase) return [];
|
|
32050
32160
|
const { data } = await supabase.from("v_units").select(column).not(column, "is", null).limit(500);
|
|
@@ -32321,9 +32431,9 @@ function MemberUnitsCell({
|
|
|
32321
32431
|
const byId = useUnitStore((s) => s.byId);
|
|
32322
32432
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
32323
32433
|
const openUnit = useUnitPanel((s) => s.openUnit);
|
|
32324
|
-
const [unitIds, setUnitIds] =
|
|
32434
|
+
const [unitIds, setUnitIds] = React130.useState(null);
|
|
32325
32435
|
const version5 = useDataVersion(UNIT_ACCESS_CHANGED);
|
|
32326
|
-
|
|
32436
|
+
React130.useEffect(() => {
|
|
32327
32437
|
if (!userId) {
|
|
32328
32438
|
setUnitIds([]);
|
|
32329
32439
|
return;
|
|
@@ -32367,6 +32477,57 @@ function MemberUnitsCell({
|
|
|
32367
32477
|
] }) })
|
|
32368
32478
|
] });
|
|
32369
32479
|
}
|
|
32480
|
+
function ImpersonateDialog({ tenantId: tenantId2, target, onClose }) {
|
|
32481
|
+
const { t } = useTranslation$1();
|
|
32482
|
+
const [reason, setReason] = React130.useState("");
|
|
32483
|
+
const [busy, setBusy] = React130.useState(false);
|
|
32484
|
+
const [error, setError] = React130.useState(null);
|
|
32485
|
+
React130.useEffect(() => {
|
|
32486
|
+
if (target) {
|
|
32487
|
+
setReason("");
|
|
32488
|
+
setError(null);
|
|
32489
|
+
setBusy(false);
|
|
32490
|
+
}
|
|
32491
|
+
}, [target]);
|
|
32492
|
+
async function enter() {
|
|
32493
|
+
if (!target) return;
|
|
32494
|
+
setBusy(true);
|
|
32495
|
+
setError(null);
|
|
32496
|
+
try {
|
|
32497
|
+
await startImpersonation({
|
|
32498
|
+
tenantId: tenantId2,
|
|
32499
|
+
userId: target.userId,
|
|
32500
|
+
reason: reason.trim() || void 0,
|
|
32501
|
+
returnTo: window.location.hash || void 0
|
|
32502
|
+
});
|
|
32503
|
+
} catch (err) {
|
|
32504
|
+
setError(err.message || t("impersonation.failed"));
|
|
32505
|
+
setBusy(false);
|
|
32506
|
+
}
|
|
32507
|
+
}
|
|
32508
|
+
return /* @__PURE__ */ jsx(Modal, { open: !!target, onOpenChange: (open) => {
|
|
32509
|
+
if (!open && !busy) onClose();
|
|
32510
|
+
}, children: /* @__PURE__ */ jsxs(ModalContent, { children: [
|
|
32511
|
+
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
32512
|
+
/* @__PURE__ */ jsx(ModalTitle, { children: t("impersonation.confirmTitle", { name: target?.name ?? "" }) }),
|
|
32513
|
+
/* @__PURE__ */ jsx(ModalDescription, { children: t("impersonation.confirmBody") })
|
|
32514
|
+
] }),
|
|
32515
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
32516
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: t("impersonation.reasonLabel") }),
|
|
32517
|
+
/* @__PURE__ */ jsx(Input, { value: reason, onChange: (e) => setReason(e.target.value), disabled: busy }),
|
|
32518
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: error })
|
|
32519
|
+
] }),
|
|
32520
|
+
/* @__PURE__ */ jsxs(ModalFooter, { children: [
|
|
32521
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: onClose, disabled: busy, children: t("common.cancel") }),
|
|
32522
|
+
/* @__PURE__ */ jsxs(Button, { onClick: () => {
|
|
32523
|
+
void enter();
|
|
32524
|
+
}, disabled: busy, children: [
|
|
32525
|
+
/* @__PURE__ */ jsx(Eye, { className: "mr-2 h-4 w-4" }),
|
|
32526
|
+
t("impersonation.confirm")
|
|
32527
|
+
] })
|
|
32528
|
+
] })
|
|
32529
|
+
] }) });
|
|
32530
|
+
}
|
|
32370
32531
|
var useOrgAdapterOptional4 = () => useOrgAdapterOptional();
|
|
32371
32532
|
var capitalize = (s) => s ? s.charAt(0).toUpperCase() + s.slice(1) : s;
|
|
32372
32533
|
function TeamTab() {
|
|
@@ -32381,10 +32542,10 @@ function TeamTab() {
|
|
|
32381
32542
|
const { user } = useAuthStore();
|
|
32382
32543
|
const hasSystemPermission = useSystemPermission();
|
|
32383
32544
|
const personMode = teamPersonKinds.length > 0 && typeof adapter?.listTeam === "function";
|
|
32384
|
-
const [team, setTeam] =
|
|
32385
|
-
const [inviteOpen, setInviteOpen] =
|
|
32545
|
+
const [team, setTeam] = React130.useState(null);
|
|
32546
|
+
const [inviteOpen, setInviteOpen] = React130.useState(false);
|
|
32386
32547
|
const guardSeats = useLimitGuard("users");
|
|
32387
|
-
const [inviteEmail, setInviteEmail] =
|
|
32548
|
+
const [inviteEmail, setInviteEmail] = React130.useState(void 0);
|
|
32388
32549
|
const handleOpenInvite = async (row) => {
|
|
32389
32550
|
if (row && !row.email && row.personId && entityRouteHasDetail("person", row.kind)) {
|
|
32390
32551
|
openEntity(row.personId, "person", row.kind, "access");
|
|
@@ -32394,7 +32555,7 @@ function TeamTab() {
|
|
|
32394
32555
|
setInviteEmail(row?.email || void 0);
|
|
32395
32556
|
setInviteOpen(true);
|
|
32396
32557
|
};
|
|
32397
|
-
const reloadTeam =
|
|
32558
|
+
const reloadTeam = React130.useCallback(async () => {
|
|
32398
32559
|
if (!adapter || !currentOrg) return;
|
|
32399
32560
|
if (personMode && adapter.listTeam) {
|
|
32400
32561
|
setTeam(await adapter.listTeam(currentOrg.id, teamPersonKinds));
|
|
@@ -32402,12 +32563,12 @@ function TeamTab() {
|
|
|
32402
32563
|
setMembers(await adapter.listMembers(currentOrg.id));
|
|
32403
32564
|
}
|
|
32404
32565
|
}, [adapter, currentOrg?.id, personMode, teamPersonKinds, setMembers]);
|
|
32405
|
-
|
|
32566
|
+
React130.useEffect(() => {
|
|
32406
32567
|
if (personMode && adapter?.listTeam && currentOrg) {
|
|
32407
32568
|
dedup("team:people:" + currentOrg.id, () => adapter.listTeam(currentOrg.id, teamPersonKinds)).then(setTeam).catch(() => setTeam([]));
|
|
32408
32569
|
}
|
|
32409
32570
|
}, [personMode, adapter, currentOrg?.id, teamPersonKinds.join(",")]);
|
|
32410
|
-
|
|
32571
|
+
React130.useEffect(() => {
|
|
32411
32572
|
if (adapter && currentOrg) {
|
|
32412
32573
|
dedup("team:invites:" + currentOrg.id, () => adapter.listInvites(currentOrg.id)).then(setInvites).catch(() => {
|
|
32413
32574
|
});
|
|
@@ -32488,7 +32649,8 @@ function TeamTab() {
|
|
|
32488
32649
|
};
|
|
32489
32650
|
const { t } = useTranslation$1();
|
|
32490
32651
|
const canManageTeam = hasSystemPermission("manage_team");
|
|
32491
|
-
const
|
|
32652
|
+
const [viewAs, setViewAs] = React130.useState(null);
|
|
32653
|
+
const inviteActions = React130.useMemo(() => [{
|
|
32492
32654
|
id: "invite",
|
|
32493
32655
|
label: t("organization.team.invite"),
|
|
32494
32656
|
icon: UserPlus,
|
|
@@ -32501,6 +32663,7 @@ function TeamTab() {
|
|
|
32501
32663
|
}], [t]);
|
|
32502
32664
|
const pendingInvites = invites.filter((i) => i.status === "pending");
|
|
32503
32665
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
32666
|
+
currentOrg && /* @__PURE__ */ jsx(ImpersonateDialog, { tenantId: currentOrg.id, target: viewAs, onClose: () => setViewAs(null) }),
|
|
32504
32667
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
32505
32668
|
canManageTeam && /* @__PURE__ */ jsx(PageHeaderActions, { children: /* @__PURE__ */ jsx(PageActions, { actions: inviteActions }) }),
|
|
32506
32669
|
/* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: t("organization.team.memberCount", { count: String(rows.length), plural: rows.length !== 1 ? "s" : "" }) }),
|
|
@@ -32591,6 +32754,14 @@ function TeamTab() {
|
|
|
32591
32754
|
hidden: !unitMode || !row.userId || !row.hasAccess,
|
|
32592
32755
|
onSelect: () => openMemberAccess({ userId: row.userId, name: row.name, email: row.email })
|
|
32593
32756
|
},
|
|
32757
|
+
{
|
|
32758
|
+
id: "impersonate",
|
|
32759
|
+
label: t("impersonation.action"),
|
|
32760
|
+
icon: Eye,
|
|
32761
|
+
// The owner is out of reach on the server too.
|
|
32762
|
+
hidden: !row.hasAccess || row.isCurrentUser || !row.userId || row.roleId === "owner",
|
|
32763
|
+
onSelect: () => setViewAs({ userId: row.userId, name: row.name })
|
|
32764
|
+
},
|
|
32594
32765
|
{
|
|
32595
32766
|
id: "remove",
|
|
32596
32767
|
label: t("organization.team.removeMember"),
|
|
@@ -32675,13 +32846,13 @@ var SYSTEM_PERMISSIONS2 = [
|
|
|
32675
32846
|
];
|
|
32676
32847
|
function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, isNew, parentLabel }) {
|
|
32677
32848
|
const { t } = useTranslation$1();
|
|
32678
|
-
const [name, setName] =
|
|
32679
|
-
const [description, setDescription] =
|
|
32680
|
-
const [systemPerms, setSystemPerms] =
|
|
32681
|
-
const [grants, setGrants] =
|
|
32682
|
-
const [collapsed, setCollapsed] =
|
|
32683
|
-
const [search, setSearch] =
|
|
32684
|
-
const initial =
|
|
32849
|
+
const [name, setName] = React130.useState(profile?.name ?? "");
|
|
32850
|
+
const [description, setDescription] = React130.useState(profile?.description ?? "");
|
|
32851
|
+
const [systemPerms, setSystemPerms] = React130.useState(profile?.systemPermissions ?? []);
|
|
32852
|
+
const [grants, setGrants] = React130.useState(profile?.grants ?? {});
|
|
32853
|
+
const [collapsed, setCollapsed] = React130.useState(/* @__PURE__ */ new Set());
|
|
32854
|
+
const [search, setSearch] = React130.useState("");
|
|
32855
|
+
const initial = React130.useRef({
|
|
32685
32856
|
name: profile?.name ?? "",
|
|
32686
32857
|
description: profile?.description ?? "",
|
|
32687
32858
|
systemPerms: JSON.stringify(profile?.systemPermissions ?? []),
|
|
@@ -32718,7 +32889,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
32718
32889
|
onDiscard: onCancel,
|
|
32719
32890
|
saveLabel: isNew ? t("organization.permissions.createProfile") : t("organization.permissions.updateProfile")
|
|
32720
32891
|
});
|
|
32721
|
-
const groups =
|
|
32892
|
+
const groups = React130.useMemo(() => {
|
|
32722
32893
|
const filtered = search ? features.filter((f) => f.label.toLowerCase().includes(search.toLowerCase())) : features;
|
|
32723
32894
|
const map = /* @__PURE__ */ new Map();
|
|
32724
32895
|
for (const f of filtered) {
|
|
@@ -32787,7 +32958,7 @@ function PermissionMatrixEditor({ features, profile, onSave, onCancel, saving, i
|
|
|
32787
32958
|
}
|
|
32788
32959
|
) }) })
|
|
32789
32960
|
] }, sp.id)),
|
|
32790
|
-
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(
|
|
32961
|
+
Array.from(groups.entries()).map(([groupName, groupFeatures]) => /* @__PURE__ */ jsxs(React130.Fragment, { children: [
|
|
32791
32962
|
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: 5, className: "p-2 px-3", children: /* @__PURE__ */ jsxs(
|
|
32792
32963
|
"button",
|
|
32793
32964
|
{
|
|
@@ -32856,15 +33027,15 @@ function PermissionProfilesTab() {
|
|
|
32856
33027
|
const setProfiles = usePermissionsStore((s) => s.setProfiles);
|
|
32857
33028
|
const members = useOrganizationStore((s) => s.members);
|
|
32858
33029
|
const realProfile = usePermissionsStore((s) => s.realProfile);
|
|
32859
|
-
const
|
|
33030
|
+
const startImpersonation2 = usePermissionsStore((s) => s.startImpersonation);
|
|
32860
33031
|
const canPreview = (realProfile?.systemPermissions ?? []).includes("manage_permissions") ?? false;
|
|
32861
33032
|
const { t } = useTranslation$1();
|
|
32862
|
-
const [editingProfile, setEditingProfile] =
|
|
32863
|
-
const [creating, setCreating] =
|
|
32864
|
-
const [duplicateSource, setDuplicateSource] =
|
|
32865
|
-
const [saving, setSaving] =
|
|
32866
|
-
const [error, setError] =
|
|
32867
|
-
const [deleting, setDeleting] =
|
|
33033
|
+
const [editingProfile, setEditingProfile] = React130.useState(null);
|
|
33034
|
+
const [creating, setCreating] = React130.useState(false);
|
|
33035
|
+
const [duplicateSource, setDuplicateSource] = React130.useState(null);
|
|
33036
|
+
const [saving, setSaving] = React130.useState(false);
|
|
33037
|
+
const [error, setError] = React130.useState(null);
|
|
33038
|
+
const [deleting, setDeleting] = React130.useState(null);
|
|
32868
33039
|
const handleDuplicate = (profile) => {
|
|
32869
33040
|
setEditingProfile(null);
|
|
32870
33041
|
setCreating(false);
|
|
@@ -32874,9 +33045,9 @@ function PermissionProfilesTab() {
|
|
|
32874
33045
|
isSystem: false
|
|
32875
33046
|
});
|
|
32876
33047
|
};
|
|
32877
|
-
const surfaceRef =
|
|
33048
|
+
const surfaceRef = React130.useRef({ features, profiles, adapter, currentOrg, setProfiles });
|
|
32878
33049
|
surfaceRef.current = { features, profiles, adapter, currentOrg, setProfiles };
|
|
32879
|
-
const agentSurface =
|
|
33050
|
+
const agentSurface = React130.useMemo(() => ({
|
|
32880
33051
|
id: "org.permissions",
|
|
32881
33052
|
instructions: PERMISSIONS_INSTRUCTIONS,
|
|
32882
33053
|
describe: () => {
|
|
@@ -32930,7 +33101,7 @@ function PermissionProfilesTab() {
|
|
|
32930
33101
|
}]
|
|
32931
33102
|
}), []);
|
|
32932
33103
|
useAgentSurface(agentSurface);
|
|
32933
|
-
const createActions =
|
|
33104
|
+
const createActions = React130.useMemo(() => [
|
|
32934
33105
|
{
|
|
32935
33106
|
id: "new",
|
|
32936
33107
|
label: t("organization.permissions.createProfile"),
|
|
@@ -32959,7 +33130,7 @@ function PermissionProfilesTab() {
|
|
|
32959
33130
|
})
|
|
32960
33131
|
}
|
|
32961
33132
|
], [t]);
|
|
32962
|
-
const memberCountByProfile =
|
|
33133
|
+
const memberCountByProfile = React130.useMemo(() => {
|
|
32963
33134
|
const counts = {};
|
|
32964
33135
|
for (const m of members) {
|
|
32965
33136
|
counts[m.profileId] = (counts[m.profileId] ?? 0) + 1;
|
|
@@ -33047,7 +33218,7 @@ function PermissionProfilesTab() {
|
|
|
33047
33218
|
label: t("organization.permissions.previewAs"),
|
|
33048
33219
|
icon: Eye,
|
|
33049
33220
|
hidden: !canPreview || profile.id === realProfile?.id,
|
|
33050
|
-
onSelect: () =>
|
|
33221
|
+
onSelect: () => startImpersonation2(profile)
|
|
33051
33222
|
},
|
|
33052
33223
|
// Duplicate — always available; the primary (and only) way to
|
|
33053
33224
|
// customize a static system role.
|
|
@@ -33264,7 +33435,7 @@ function FieldRulesSettings({ entities, rules: initialRules, onSave }) {
|
|
|
33264
33435
|
const [saving, setSaving] = useState(false);
|
|
33265
33436
|
const [search, setSearch] = useState("");
|
|
33266
33437
|
const [showMore, setShowMore] = useState(false);
|
|
33267
|
-
|
|
33438
|
+
React130.useEffect(() => {
|
|
33268
33439
|
setDraft(initialRules);
|
|
33269
33440
|
}, [initialRules]);
|
|
33270
33441
|
const isDirty = useMemo(
|
|
@@ -33441,6 +33612,15 @@ function FieldRulesSettings({ entities, rules: initialRules, onSave }) {
|
|
|
33441
33612
|
|
|
33442
33613
|
// src/lib/entity-registry.ts
|
|
33443
33614
|
var registry2 = /* @__PURE__ */ new Map();
|
|
33615
|
+
function deriveEntityKey5(entityDef) {
|
|
33616
|
+
if (entityDef.data?.archetypeKind) {
|
|
33617
|
+
return `${entityDef.data.archetype ?? ""}:${entityDef.data.archetypeKind}`;
|
|
33618
|
+
}
|
|
33619
|
+
if (entityDef.data?.archetype) {
|
|
33620
|
+
return entityDef.data.archetype;
|
|
33621
|
+
}
|
|
33622
|
+
return entityDef.data?.table ?? entityDef.name;
|
|
33623
|
+
}
|
|
33444
33624
|
function getRegisteredEntities() {
|
|
33445
33625
|
return Array.from(registry2.values());
|
|
33446
33626
|
}
|
|
@@ -33664,20 +33844,20 @@ function SoftLimitWidget() {
|
|
|
33664
33844
|
function LimitProbe({ limitKey }) {
|
|
33665
33845
|
const info = useLimit(limitKey);
|
|
33666
33846
|
const report = useSoftLimitStore((s) => s.report);
|
|
33667
|
-
|
|
33847
|
+
React130.useEffect(() => {
|
|
33668
33848
|
report(limitKey, info);
|
|
33669
33849
|
}, [limitKey, info, report]);
|
|
33670
33850
|
return null;
|
|
33671
33851
|
}
|
|
33672
33852
|
function SoftLimitProbes({ keys }) {
|
|
33673
|
-
const monitored =
|
|
33853
|
+
const monitored = React130.useMemo(() => Array.from(new Set(keys)), [keys]);
|
|
33674
33854
|
return /* @__PURE__ */ jsx(Fragment, { children: monitored.map((k) => /* @__PURE__ */ jsx(LimitProbe, { limitKey: k }, k)) });
|
|
33675
33855
|
}
|
|
33676
|
-
var CommandPalette =
|
|
33856
|
+
var CommandPalette = React130.lazy(
|
|
33677
33857
|
() => import('./CommandPalette-B5PMQFDG.js').then((m) => ({ default: m.CommandPalette }))
|
|
33678
33858
|
);
|
|
33679
|
-
var SubscriptionPage =
|
|
33680
|
-
() => import('./SubscriptionPage-
|
|
33859
|
+
var SubscriptionPage = React130.lazy(
|
|
33860
|
+
() => import('./SubscriptionPage-VXZ37WZZ.js').then((m) => ({ default: m.SubscriptionPage }))
|
|
33681
33861
|
);
|
|
33682
33862
|
function WorkspaceSwitcher({
|
|
33683
33863
|
variant = "sidebar",
|
|
@@ -33726,8 +33906,8 @@ function WorkspaceSwitcher({
|
|
|
33726
33906
|
const v = t(key);
|
|
33727
33907
|
return !v || v === key ? fallback : v;
|
|
33728
33908
|
};
|
|
33729
|
-
const [query, setQuery] =
|
|
33730
|
-
const search =
|
|
33909
|
+
const [query, setQuery] = React130.useState("");
|
|
33910
|
+
const search = React130.useMemo(
|
|
33731
33911
|
() => searchWorkspaces(
|
|
33732
33912
|
options,
|
|
33733
33913
|
query,
|
|
@@ -34041,9 +34221,9 @@ function PluginHeaderControls() {
|
|
|
34041
34221
|
}
|
|
34042
34222
|
function AdminNotifications() {
|
|
34043
34223
|
const { notifications, unreadCount, fetchNotifications, markAsRead, markAllAsRead } = useNotifications();
|
|
34044
|
-
const [open, setOpen] =
|
|
34045
|
-
const fetchedRef =
|
|
34046
|
-
|
|
34224
|
+
const [open, setOpen] = React130.useState(false);
|
|
34225
|
+
const fetchedRef = React130.useRef(false);
|
|
34226
|
+
React130.useEffect(() => {
|
|
34047
34227
|
if (fetchedRef.current) return;
|
|
34048
34228
|
fetchedRef.current = true;
|
|
34049
34229
|
void fetchNotifications();
|
|
@@ -34189,7 +34369,7 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
34189
34369
|
// sidebar ICON_MAP, which made the settings rail fall back to Home.
|
|
34190
34370
|
icon: /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
|
|
34191
34371
|
iconName: "CreditCard",
|
|
34192
|
-
component: /* @__PURE__ */ jsx(
|
|
34372
|
+
component: /* @__PURE__ */ jsx(React130.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(SubscriptionPage, {}) })
|
|
34193
34373
|
});
|
|
34194
34374
|
}
|
|
34195
34375
|
if (showOrgSettings) {
|
|
@@ -34217,9 +34397,9 @@ function buildSettingsTabs(pluginTabs, can, hasSystem, t, showOrgSettings, hasBi
|
|
|
34217
34397
|
settingsTabs.push({
|
|
34218
34398
|
id: tab.id,
|
|
34219
34399
|
label: translated === labelKey ? tab.label : translated,
|
|
34220
|
-
icon:
|
|
34400
|
+
icon: React130.createElement(IconComp, { className: "h-4 w-4" }),
|
|
34221
34401
|
iconName,
|
|
34222
|
-
component:
|
|
34402
|
+
component: React130.createElement(tab.component),
|
|
34223
34403
|
// Flag plugin-contributed tabs so SettingsPage draws the core/plugins divider.
|
|
34224
34404
|
isPlugin: true,
|
|
34225
34405
|
group: tab.group,
|
|
@@ -34271,12 +34451,12 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34271
34451
|
profileKnown: !activeTenantId || profileKnownFor === activeTenantId
|
|
34272
34452
|
});
|
|
34273
34453
|
const navError = configError ?? tenantCtx?.loadError ?? null;
|
|
34274
|
-
const onNavRetry =
|
|
34454
|
+
const onNavRetry = React130.useCallback(() => {
|
|
34275
34455
|
if (tenantCtx?.loadError) tenantCtx.retryOrgs();
|
|
34276
34456
|
else window.location.reload();
|
|
34277
34457
|
}, [tenantCtx]);
|
|
34278
34458
|
const currentProfile = usePermissionsStore((s) => s.currentProfile);
|
|
34279
|
-
const hasSystem =
|
|
34459
|
+
const hasSystem = React130.useCallback(
|
|
34280
34460
|
(perm) => {
|
|
34281
34461
|
if (!currentProfile) return false;
|
|
34282
34462
|
if (currentProfile.id === "owner" || currentProfile.name?.toLowerCase() === "owner") return true;
|
|
@@ -34290,8 +34470,8 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34290
34470
|
};
|
|
34291
34471
|
const path = useAdminPath();
|
|
34292
34472
|
const { user, signOut } = useAuth();
|
|
34293
|
-
|
|
34294
|
-
|
|
34473
|
+
React130.useEffect(() => installGlobalErrorHandlers(), []);
|
|
34474
|
+
React130.useEffect(() => registerErrorReporter((report) => {
|
|
34295
34475
|
if (report.source !== "data") return;
|
|
34296
34476
|
const alvo = report.extra?.operation;
|
|
34297
34477
|
toast.error(
|
|
@@ -34309,15 +34489,15 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34309
34489
|
const hasChatPanel = useRightRailStore((s) => s.panels.some((pn) => pn.id === "chat"));
|
|
34310
34490
|
const rightRail = railHasPanels ? /* @__PURE__ */ jsx(RightRail, { frame: contentFrame, attached: layout !== "topbar" }) : null;
|
|
34311
34491
|
const setRailMounted = useRightRailStore((s) => s.setMounted);
|
|
34312
|
-
|
|
34492
|
+
React130.useEffect(() => {
|
|
34313
34493
|
setRailMounted(true);
|
|
34314
34494
|
return () => setRailMounted(false);
|
|
34315
34495
|
}, [setRailMounted]);
|
|
34316
34496
|
useConnectorOAuthReturn();
|
|
34317
34497
|
const railWidthLive = useRightRailStore((s) => s.width);
|
|
34318
34498
|
const setSidebarCollapsed = useLayoutStore((s) => s.setSidebarCollapsed);
|
|
34319
|
-
const railAutoCollapsedRef =
|
|
34320
|
-
|
|
34499
|
+
const railAutoCollapsedRef = React130.useRef(false);
|
|
34500
|
+
React130.useEffect(() => {
|
|
34321
34501
|
if (layout !== "sidebar") return;
|
|
34322
34502
|
const SIDEBAR_EXPANDED = 224;
|
|
34323
34503
|
const MIN_CONTENT = 620;
|
|
@@ -34339,22 +34519,22 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34339
34519
|
window.addEventListener("resize", apply);
|
|
34340
34520
|
return () => window.removeEventListener("resize", apply);
|
|
34341
34521
|
}, [railOpen, railWidthLive, layout, setSidebarCollapsed]);
|
|
34342
|
-
const [railWidth] =
|
|
34522
|
+
const [railWidth] = React130.useState(() => readRightRailWidth());
|
|
34343
34523
|
const billingPlans = useBillingStore((s) => s.plans);
|
|
34344
34524
|
const hasBilling = billingPlans.length > 0;
|
|
34345
34525
|
const orgPlan = useTenantOptional()?.org?.plan;
|
|
34346
|
-
const planBadge =
|
|
34526
|
+
const planBadge = React130.useMemo(
|
|
34347
34527
|
() => hasBilling ? resolvePlanBadge(orgPlan, billingPlans) : null,
|
|
34348
34528
|
[hasBilling, orgPlan, billingPlans]
|
|
34349
34529
|
);
|
|
34350
|
-
const softLimitKeys =
|
|
34530
|
+
const softLimitKeys = React130.useMemo(() => {
|
|
34351
34531
|
const plan = billingPlans.find((p) => p.id === (orgPlan || "free"));
|
|
34352
34532
|
return Object.keys(getPlanEntitlements(plan)?.limits ?? {});
|
|
34353
34533
|
}, [billingPlans, orgPlan]);
|
|
34354
34534
|
const overshoots = useOvershoots();
|
|
34355
34535
|
const navContributions = useNavContributionsStore((s) => s.contributions);
|
|
34356
34536
|
const appConfigNav = useAppConfigStore((state) => state.config.nav);
|
|
34357
|
-
const navigation =
|
|
34537
|
+
const navigation = React130.useMemo(() => {
|
|
34358
34538
|
const contributed = Object.values(navContributions).flat();
|
|
34359
34539
|
const flat = dedupeByRoute(
|
|
34360
34540
|
[...runtime.navigation, ...contributed].map((entry) => ({
|
|
@@ -34425,7 +34605,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34425
34605
|
}).filter((item) => item !== null).sort(compareNavigation);
|
|
34426
34606
|
return applyRailPreset(gated, presetRail, presetHide, presetWhole);
|
|
34427
34607
|
}, [runtime.navigation, runtime.routes, navContributions, pages, access, navWaiting, presetRail, presetHide, presetWhole, presetLabels]);
|
|
34428
|
-
const composedNavigation =
|
|
34608
|
+
const composedNavigation = React130.useMemo(() => {
|
|
34429
34609
|
if (!appConfigNav.length) return navigation;
|
|
34430
34610
|
const keyed = navigation.map((item) => ({ ...item, key: item.route }));
|
|
34431
34611
|
return applyNavComposition(keyed, appConfigNav).map((item) => {
|
|
@@ -34441,13 +34621,13 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34441
34621
|
};
|
|
34442
34622
|
});
|
|
34443
34623
|
}, [navigation, appConfigNav]);
|
|
34444
|
-
const resolvedBottomNav =
|
|
34624
|
+
const resolvedBottomNav = React130.useMemo(
|
|
34445
34625
|
() => deriveBottomNav(navigation, bottomNav, { assistant: hasChatPanel }),
|
|
34446
34626
|
[navigation, bottomNav, hasChatPanel]
|
|
34447
34627
|
);
|
|
34448
34628
|
const commandPaletteOpen = useLayoutStore((s) => s.commandPaletteOpen);
|
|
34449
34629
|
const setCommandPaletteOpen = useLayoutStore((s) => s.setCommandPaletteOpen);
|
|
34450
|
-
const commandItems =
|
|
34630
|
+
const commandItems = React130.useMemo(() => {
|
|
34451
34631
|
const navGroup = tr("layout.commandPalette.navigation", "Navigation");
|
|
34452
34632
|
const items = [];
|
|
34453
34633
|
for (const nav of navigation) {
|
|
@@ -34459,7 +34639,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34459
34639
|
return items;
|
|
34460
34640
|
}, [navigation]);
|
|
34461
34641
|
const globalSearch = useGlobalSearch();
|
|
34462
|
-
const routes =
|
|
34642
|
+
const routes = React130.useMemo(() => {
|
|
34463
34643
|
const list = [];
|
|
34464
34644
|
const entityRouteMap = /* @__PURE__ */ new Map();
|
|
34465
34645
|
for (const r of runtime.routes) {
|
|
@@ -34482,14 +34662,14 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34482
34662
|
setEntityRouteMap(entityRouteMap);
|
|
34483
34663
|
return list.sort((a, b) => routeScore(b.path) - routeScore(a.path));
|
|
34484
34664
|
}, [runtime.routes, pages, showSettings]);
|
|
34485
|
-
const match =
|
|
34665
|
+
const match = React130.useMemo(() => {
|
|
34486
34666
|
for (const r of routes) {
|
|
34487
34667
|
const params = matchRoute(r.path, path);
|
|
34488
34668
|
if (params) return { route: r, params };
|
|
34489
34669
|
}
|
|
34490
34670
|
return null;
|
|
34491
34671
|
}, [routes, path]);
|
|
34492
|
-
|
|
34672
|
+
React130.useEffect(() => {
|
|
34493
34673
|
if (!match && (path === "/" || path === "") && navigation.length > 0) {
|
|
34494
34674
|
navigateTo(navigation[0].route);
|
|
34495
34675
|
}
|
|
@@ -34497,11 +34677,11 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34497
34677
|
const ActiveComponent = match?.route.Component;
|
|
34498
34678
|
const activeParams = match?.params ?? {};
|
|
34499
34679
|
const routeKey = (match?.route.path ?? path).replace(/\/\*$/, "");
|
|
34500
|
-
const settingsTabs =
|
|
34680
|
+
const settingsTabs = React130.useMemo(
|
|
34501
34681
|
() => buildSettingsTabs(runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling),
|
|
34502
34682
|
[runtime.settingsTabs, can, hasSystem, t, showOrgSettings, hasBilling]
|
|
34503
34683
|
);
|
|
34504
|
-
const profileRoute =
|
|
34684
|
+
const profileRoute = React130.useMemo(() => {
|
|
34505
34685
|
const explicit = routes.find((r) => r.path === "/perfil" || r.path === "/profile");
|
|
34506
34686
|
if (explicit) return explicit.path;
|
|
34507
34687
|
return showSettings ? "/settings/profile" : null;
|
|
@@ -34510,8 +34690,8 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34510
34690
|
const onBilling = hasBilling && showSettings ? () => navigateTo("/settings/subscription") : void 0;
|
|
34511
34691
|
const coreSettingsTabs = useCoreSettingsTabs({ showCompany: showBranding, showBranding });
|
|
34512
34692
|
const catalog = useModuleCatalog();
|
|
34513
|
-
const verticalByPlugin =
|
|
34514
|
-
const allSettingsTabs =
|
|
34693
|
+
const verticalByPlugin = React130.useMemo(() => pluginVerticalIndex(catalog), [catalog]);
|
|
34694
|
+
const allSettingsTabs = React130.useMemo(
|
|
34515
34695
|
() => {
|
|
34516
34696
|
const hidden = new Set(hiddenSettingsTabs ?? []);
|
|
34517
34697
|
const visible = [...coreSettingsTabs, ...settingsTabs].filter((tab) => !hidden.has(tab.id));
|
|
@@ -34534,7 +34714,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34534
34714
|
[coreSettingsTabs, settingsTabs, hiddenSettingsTabs, settingsGroups, verticalByPlugin]
|
|
34535
34715
|
);
|
|
34536
34716
|
usePublishSettingsTabs(allSettingsTabs.map((tab) => tab.id));
|
|
34537
|
-
const navWithSettings =
|
|
34717
|
+
const navWithSettings = React130.useMemo(() => {
|
|
34538
34718
|
if (!showSettings || allSettingsTabs.length === 0) return composedNavigation;
|
|
34539
34719
|
if (composedNavigation.some((item) => item.route === "/settings")) return composedNavigation;
|
|
34540
34720
|
return [...composedNavigation, {
|
|
@@ -34552,7 +34732,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34552
34732
|
const moduleRail = !inSettings && layout === "sidebar" && contextualNav && (path === contextualNav.base || path.startsWith(contextualNav.base + "/")) ? contextualNav : null;
|
|
34553
34733
|
const settingsPathActive = showSettings && (path === "/settings" || path.startsWith("/settings/"));
|
|
34554
34734
|
const activeSettingsTab = settingsPathActive ? path === "/settings" ? null : path.slice("/settings/".length).split("/")[0] : void 0;
|
|
34555
|
-
const settingsTabDef =
|
|
34735
|
+
const settingsTabDef = React130.useMemo(() => {
|
|
34556
34736
|
if (!showSettings || !path.startsWith("/settings/")) return void 0;
|
|
34557
34737
|
const id = path.slice("/settings/".length).split("/")[0];
|
|
34558
34738
|
return allSettingsTabs.find((tab) => tab.id === id);
|
|
@@ -34560,11 +34740,11 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34560
34740
|
const shellUser = user ? { fullName: user.fullName ?? user.email, email: user.email, avatarUrl: user.avatarUrl } : void 0;
|
|
34561
34741
|
const moduleVariant = moduleNav ?? (layout === "sidebar" ? "tabs" : "rail");
|
|
34562
34742
|
const setRailAvailable = useContextualNavStore((s) => s.setRailAvailable);
|
|
34563
|
-
|
|
34743
|
+
React130.useEffect(() => {
|
|
34564
34744
|
setRailAvailable(layout === "sidebar" && moduleVariant !== "rail");
|
|
34565
34745
|
}, [layout, moduleVariant, setRailAvailable]);
|
|
34566
34746
|
const moduleViewLabel = useModuleViewLabel();
|
|
34567
|
-
const activePageTitle =
|
|
34747
|
+
const activePageTitle = React130.useMemo(() => {
|
|
34568
34748
|
if (settingsTabDef) return settingsTabDef.label;
|
|
34569
34749
|
if (path === "/settings" || path.startsWith("/settings/")) return tr("common.settings", "Settings");
|
|
34570
34750
|
if (moduleViewLabel) return moduleViewLabel;
|
|
@@ -34579,7 +34759,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34579
34759
|
if (hiddenHit?.label) return hiddenHit.label;
|
|
34580
34760
|
return candidates.find((n) => n.route === "/")?.label ?? "";
|
|
34581
34761
|
}, [navigation, pages, path, tr, match, settingsTabDef, moduleViewLabel]);
|
|
34582
|
-
const parentBack =
|
|
34762
|
+
const parentBack = React130.useMemo(() => {
|
|
34583
34763
|
if (settingsTabDef) {
|
|
34584
34764
|
const first = allSettingsTabs[0]?.id;
|
|
34585
34765
|
return {
|
|
@@ -34622,9 +34802,9 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34622
34802
|
]
|
|
34623
34803
|
}
|
|
34624
34804
|
);
|
|
34625
|
-
const [railQuery, setRailQuery] =
|
|
34805
|
+
const [railQuery, setRailQuery] = React130.useState("");
|
|
34626
34806
|
const railBase = moduleRail?.base ?? null;
|
|
34627
|
-
|
|
34807
|
+
React130.useEffect(() => {
|
|
34628
34808
|
setRailQuery("");
|
|
34629
34809
|
}, [railBase]);
|
|
34630
34810
|
const railSearch = (placeholder) => /* @__PURE__ */ jsxs("div", { className: "relative px-0.5 pt-1", children: [
|
|
@@ -34658,6 +34838,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34658
34838
|
const railRows = contextualRail?.navigation ?? navWithSettings;
|
|
34659
34839
|
const railWaiting = navWaiting || railRows.length === 0;
|
|
34660
34840
|
return /* @__PURE__ */ jsxs(ModuleLayoutProvider, { variant: moduleVariant, children: [
|
|
34841
|
+
/* @__PURE__ */ jsx(ImpersonationBanner, {}),
|
|
34661
34842
|
/* @__PURE__ */ jsxs(
|
|
34662
34843
|
AppShell,
|
|
34663
34844
|
{
|
|
@@ -34808,7 +34989,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34808
34989
|
// Less air at the top than at the sides: the bar above already
|
|
34809
34990
|
// ends in a hairline, so a full 24px under it read as a gap
|
|
34810
34991
|
// before the page started rather than as the page's margin.
|
|
34811
|
-
/* @__PURE__ */ jsx("div", { className: "space-y-4 p-3 md:space-y-6 md:px-6 md:pb-
|
|
34992
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-4 p-3 md:space-y-6 md:px-6 md:pb-[calc(1.5rem+var(--fz-fab-clearance,0px))] md:pt-4", children: activeContent })
|
|
34812
34993
|
)
|
|
34813
34994
|
},
|
|
34814
34995
|
routeKey
|
|
@@ -34828,7 +35009,7 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34828
35009
|
]
|
|
34829
35010
|
}
|
|
34830
35011
|
),
|
|
34831
|
-
/* @__PURE__ */ jsx(
|
|
35012
|
+
/* @__PURE__ */ jsx(React130.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
34832
35013
|
CommandPalette,
|
|
34833
35014
|
{
|
|
34834
35015
|
commands: commandItems,
|
|
@@ -35068,7 +35249,8 @@ function resolveOrgAdapter(config, authAdapter) {
|
|
|
35068
35249
|
const declaredRoles = config.permissions?.defaultProfiles?.map((p) => ({
|
|
35069
35250
|
id: p.id,
|
|
35070
35251
|
name: p.name,
|
|
35071
|
-
description: p.description
|
|
35252
|
+
description: p.description,
|
|
35253
|
+
grants: p.grants
|
|
35072
35254
|
}));
|
|
35073
35255
|
if (strategy === "supabase")
|
|
35074
35256
|
return createSupabaseOrgAdapter({
|
|
@@ -35095,7 +35277,7 @@ function buildI18nConfig(config) {
|
|
|
35095
35277
|
function BillingInitializer({ config }) {
|
|
35096
35278
|
const setPlans = useBillingStore((s) => s.setPlans);
|
|
35097
35279
|
const setCheckout = useBillingStore((s) => s.setCheckout);
|
|
35098
|
-
|
|
35280
|
+
React130.useEffect(() => {
|
|
35099
35281
|
if (config.billing?.plans) setPlans(config.billing.plans.map(normalizeBillingPlan));
|
|
35100
35282
|
setCheckout(config.billing?.onCheckout ?? null);
|
|
35101
35283
|
}, [config.billing, setPlans, setCheckout]);
|
|
@@ -35214,13 +35396,13 @@ function ThemeInitializer({ config }) {
|
|
|
35214
35396
|
const rawBranding = useOrganizationStore((s) => s.currentOrg?.settings?.branding);
|
|
35215
35397
|
const access = useAccessOptional();
|
|
35216
35398
|
const wearsOwnSkin = access.entitled("branding.theme");
|
|
35217
|
-
const brandTokens =
|
|
35399
|
+
const brandTokens = React130.useMemo(
|
|
35218
35400
|
() => wearsOwnSkin ? normalizeBrand(rawBranding).tokens : EMPTY_BRAND.tokens,
|
|
35219
35401
|
[rawBranding, wearsOwnSkin]
|
|
35220
35402
|
);
|
|
35221
35403
|
const brandKey = JSON.stringify(brandTokens);
|
|
35222
35404
|
const appTheme = useAppTheme();
|
|
35223
|
-
|
|
35405
|
+
React130.useEffect(() => {
|
|
35224
35406
|
const tokens = JSON.parse(brandKey);
|
|
35225
35407
|
const brand = tokens.color?.primary ? hexToHslTriplet(tokens.color.primary) : null;
|
|
35226
35408
|
const base = appTheme ?? config.theme;
|
|
@@ -35238,20 +35420,20 @@ function ThemeInitializer({ config }) {
|
|
|
35238
35420
|
return null;
|
|
35239
35421
|
}
|
|
35240
35422
|
function PersistentCacheInitializer() {
|
|
35241
|
-
|
|
35423
|
+
React130.useEffect(() => {
|
|
35242
35424
|
attachPersistentCache();
|
|
35243
35425
|
void getPersistentCache()?.hydrate();
|
|
35244
35426
|
}, []);
|
|
35245
35427
|
return null;
|
|
35246
35428
|
}
|
|
35247
35429
|
function FayzEventBridgeInitializer({ config }) {
|
|
35248
|
-
|
|
35430
|
+
React130.useEffect(() => startFayzEventBridge(config.chat?.agent), [config.chat?.agent]);
|
|
35249
35431
|
return null;
|
|
35250
35432
|
}
|
|
35251
35433
|
function TeamInitializer({ config }) {
|
|
35252
35434
|
const setTeamPersonKinds = useOrganizationStore((s) => s.setTeamPersonKinds);
|
|
35253
35435
|
const kinds = config.team?.personKinds;
|
|
35254
|
-
|
|
35436
|
+
React130.useEffect(() => {
|
|
35255
35437
|
setTeamPersonKinds(kinds ?? []);
|
|
35256
35438
|
}, [setTeamPersonKinds, kinds]);
|
|
35257
35439
|
return null;
|
|
@@ -35268,7 +35450,7 @@ function ChatRailPanel({ config }) {
|
|
|
35268
35450
|
const agent = config.chat?.agent;
|
|
35269
35451
|
const voice = config.chat?.voice;
|
|
35270
35452
|
const whatsapp = config.chat?.whatsapp;
|
|
35271
|
-
const Component2 =
|
|
35453
|
+
const Component2 = React130.useMemo(() => {
|
|
35272
35454
|
const Panel = () => /* @__PURE__ */ jsx(
|
|
35273
35455
|
ChatConversation,
|
|
35274
35456
|
{
|
|
@@ -35285,8 +35467,8 @@ function ChatRailPanel({ config }) {
|
|
|
35285
35467
|
const conversations = useChatStore((s) => s.conversations);
|
|
35286
35468
|
const setConversations = useChatStore((s) => s.setConversations);
|
|
35287
35469
|
const user = useAuthStore((s) => s.user);
|
|
35288
|
-
const connection =
|
|
35289
|
-
|
|
35470
|
+
const connection = React130.useMemo(() => resolveFayzAgentConnection(agent), [agent]);
|
|
35471
|
+
React130.useEffect(() => {
|
|
35290
35472
|
if (!connection) return;
|
|
35291
35473
|
getFayzAgentClient(connection).listConversations(user?.id).then(setConversations).catch(() => {
|
|
35292
35474
|
});
|
|
@@ -35295,7 +35477,7 @@ function ChatRailPanel({ config }) {
|
|
|
35295
35477
|
useAssistantInviteStore((s) => s.invite?.id === ASK_AI_HANDOFF_ID);
|
|
35296
35478
|
const activeAgent = useAgent();
|
|
35297
35479
|
const persona = activeAgent?.name ?? invitePersona;
|
|
35298
|
-
const icon =
|
|
35480
|
+
const icon = React130.useMemo(
|
|
35299
35481
|
() => activeAgent ? function AgentTabIcon() {
|
|
35300
35482
|
return /* @__PURE__ */ jsx(
|
|
35301
35483
|
AgentAvatar,
|
|
@@ -35310,7 +35492,7 @@ function ChatRailPanel({ config }) {
|
|
|
35310
35492
|
[activeAgent]
|
|
35311
35493
|
);
|
|
35312
35494
|
useRightRailPanel(
|
|
35313
|
-
|
|
35495
|
+
React130.useMemo(
|
|
35314
35496
|
() => ({
|
|
35315
35497
|
id: "chat",
|
|
35316
35498
|
// "Chat" nomeia o CANO, não o que está do outro lado — e era a única
|
|
@@ -35326,22 +35508,22 @@ function ChatRailPanel({ config }) {
|
|
|
35326
35508
|
[Component2, conversations.length, persona, icon, activeAgent, t]
|
|
35327
35509
|
)
|
|
35328
35510
|
);
|
|
35329
|
-
|
|
35511
|
+
React130.useEffect(() => {
|
|
35330
35512
|
if (chatOpen) openPanel("chat");
|
|
35331
35513
|
}, [chatOpen, openPanel]);
|
|
35332
|
-
|
|
35514
|
+
React130.useEffect(() => {
|
|
35333
35515
|
if (!(railOpen && railActive === "chat")) setChatOpen(false);
|
|
35334
35516
|
}, [railOpen, railActive, setChatOpen]);
|
|
35335
35517
|
return null;
|
|
35336
35518
|
}
|
|
35337
35519
|
function AdminProviders({ config, children }) {
|
|
35338
35520
|
const currentOrg = useOrganizationStore((s) => s.currentOrg);
|
|
35339
|
-
const hasFayzAgent =
|
|
35521
|
+
const hasFayzAgent = React130.useMemo(
|
|
35340
35522
|
() => !!resolveFayzAgentConnection(config.chat?.agent),
|
|
35341
35523
|
[config.chat?.agent]
|
|
35342
35524
|
);
|
|
35343
35525
|
const assistantEnabled = config.chat?.enabled !== false && (!!config.chat || hasFayzAgent);
|
|
35344
|
-
|
|
35526
|
+
React130.useEffect(() => {
|
|
35345
35527
|
if (!config.chat || config.chat.enabled === false || config.chat.apiEndpoint || hasFayzAgent) return;
|
|
35346
35528
|
const gap = describeFayzAgentGap(config.chat.agent);
|
|
35347
35529
|
if (!gap) return;
|
|
@@ -35353,7 +35535,7 @@ function AdminProviders({ config, children }) {
|
|
|
35353
35535
|
const surface = config.chat?.surface ?? "dock";
|
|
35354
35536
|
const onConsentScreen = typeof window !== "undefined" && window.location.pathname.replace(/\/+$/, "").endsWith("/connect");
|
|
35355
35537
|
const showFab = assistantEnabled && surface === "dock" && !onConsentScreen;
|
|
35356
|
-
const resolved =
|
|
35538
|
+
const resolved = React130.useMemo(() => {
|
|
35357
35539
|
if (config.supabaseUrl && config.supabaseAnonKey) {
|
|
35358
35540
|
createFayzSupabaseClient(config.supabaseUrl, config.supabaseAnonKey);
|
|
35359
35541
|
}
|
|
@@ -35371,7 +35553,7 @@ function AdminProviders({ config, children }) {
|
|
|
35371
35553
|
const { bindings, ready: configReady } = useAppConfig();
|
|
35372
35554
|
const offeredPlugins = useOfferedPlugins();
|
|
35373
35555
|
const path = useAdminPath();
|
|
35374
|
-
const runtime =
|
|
35556
|
+
const runtime = React130.useMemo(
|
|
35375
35557
|
() => resolvePluginRuntime({
|
|
35376
35558
|
plugins: resolved.plugins,
|
|
35377
35559
|
// Só as ligações DESTA conta. Na janela da troca o config em mãos ainda
|
|
@@ -35411,7 +35593,7 @@ function AdminProviders({ config, children }) {
|
|
|
35411
35593
|
}),
|
|
35412
35594
|
[resolved.plugins, bindings, offeredPlugins, configReady, path, config.layout, currentOrg]
|
|
35413
35595
|
);
|
|
35414
|
-
|
|
35596
|
+
React130.useEffect(() => {
|
|
35415
35597
|
if (!import.meta.env?.DEV || !currentOrg) return;
|
|
35416
35598
|
const registered = new Set(resolved.plugins.map((p) => p.id));
|
|
35417
35599
|
const bound = new Set(bindings.map((b) => b.pluginId));
|
|
@@ -35765,8 +35947,8 @@ function manifestToFayzConfig(manifest, surfaceName) {
|
|
|
35765
35947
|
};
|
|
35766
35948
|
}
|
|
35767
35949
|
function AdminScaffold({ manifest, surface }) {
|
|
35768
|
-
const config =
|
|
35769
|
-
const authShellProps =
|
|
35950
|
+
const config = React130.useMemo(() => manifestToFayzConfig(manifest, surface), [manifest, surface]);
|
|
35951
|
+
const authShellProps = React130.useMemo(() => getAuthShellProps(config.auth), [config.auth]);
|
|
35770
35952
|
return /* @__PURE__ */ jsx(AdminProviders, { config, children: /* @__PURE__ */ jsx(ScaffoldShell, { config, authShellProps }) });
|
|
35771
35953
|
}
|
|
35772
35954
|
function ScaffoldShell({
|
|
@@ -36204,9 +36386,9 @@ function LookupCreateInline({
|
|
|
36204
36386
|
className
|
|
36205
36387
|
}) {
|
|
36206
36388
|
const t = useTranslation();
|
|
36207
|
-
const [saving, setSaving] =
|
|
36208
|
-
const [error, setError] =
|
|
36209
|
-
const submitForm =
|
|
36389
|
+
const [saving, setSaving] = React130.useState(false);
|
|
36390
|
+
const [error, setError] = React130.useState(null);
|
|
36391
|
+
const submitForm = React130.useRef(null);
|
|
36210
36392
|
async function submit(data) {
|
|
36211
36393
|
setSaving(true);
|
|
36212
36394
|
setError(null);
|
|
@@ -36283,20 +36465,20 @@ function LookupCreateInline({
|
|
|
36283
36465
|
);
|
|
36284
36466
|
}
|
|
36285
36467
|
function useLookupCreate(lookup, onCreated, options = {}) {
|
|
36286
|
-
const [draftName, setDraftName] =
|
|
36468
|
+
const [draftName, setDraftName] = React130.useState(null);
|
|
36287
36469
|
const can = usePermissionOptional();
|
|
36288
36470
|
const entityDef = lookup?.entityDef;
|
|
36289
36471
|
const feature = entityDef?.permission?.feature;
|
|
36290
36472
|
const allowed = !feature || can(feature, "create");
|
|
36291
36473
|
const canCreate = !!lookup?.create && allowed;
|
|
36292
36474
|
const canEdit = !!entityDef && !!lookup?.load && !!lookup?.update && (!feature || can(feature, "edit"));
|
|
36293
|
-
const [editingId, setEditingId] =
|
|
36294
|
-
const onEdit =
|
|
36295
|
-
const createByName =
|
|
36475
|
+
const [editingId, setEditingId] = React130.useState(null);
|
|
36476
|
+
const onEdit = React130.useMemo(() => canEdit ? (id) => setEditingId(id) : void 0, [canEdit]);
|
|
36477
|
+
const createByName = React130.useCallback(async (name) => {
|
|
36296
36478
|
if (!lookup?.create) return;
|
|
36297
36479
|
onCreated(await lookup.create({ name }));
|
|
36298
36480
|
}, [lookup, onCreated]);
|
|
36299
|
-
const onCreate =
|
|
36481
|
+
const onCreate = React130.useMemo(() => {
|
|
36300
36482
|
if (!canCreate) return void 0;
|
|
36301
36483
|
if (!entityDef) return (name) => {
|
|
36302
36484
|
void createByName(name);
|
|
@@ -36405,8 +36587,8 @@ function OrderFormItemRow({
|
|
|
36405
36587
|
const rawKindLabel = itemTypes.find((tp) => tp.value === itemKind)?.label ?? itemKind;
|
|
36406
36588
|
const kindLabel = !itemKind || itemKind === "other" ? null : rawKindLabel;
|
|
36407
36589
|
const hasAdjustments = (discount ?? 0) > 0 || (surcharge ?? 0) > 0;
|
|
36408
|
-
const [showAdjustments, setShowAdjustments] =
|
|
36409
|
-
const [openExtras, setOpenExtras] =
|
|
36590
|
+
const [showAdjustments, setShowAdjustments] = React130.useState(hasAdjustments);
|
|
36591
|
+
const [openExtras, setOpenExtras] = React130.useState(
|
|
36410
36592
|
() => (extraFieldGroups ?? []).filter((g) => g.filled).map((g) => g.id)
|
|
36411
36593
|
);
|
|
36412
36594
|
const lookup = entityLookups[itemKind];
|
|
@@ -36676,9 +36858,9 @@ function OrderFormItemRow({
|
|
|
36676
36858
|
}
|
|
36677
36859
|
OrderFormItemRow.displayName = "OrderFormItemRow";
|
|
36678
36860
|
function CodeLookupField({ byCode, resolvedLabel, clearLabel, onResolved, onClear }) {
|
|
36679
|
-
const [code, setCode] =
|
|
36680
|
-
const [busy, setBusy] =
|
|
36681
|
-
const [error, setError] =
|
|
36861
|
+
const [code, setCode] = React130.useState("");
|
|
36862
|
+
const [busy, setBusy] = React130.useState(false);
|
|
36863
|
+
const [error, setError] = React130.useState(null);
|
|
36682
36864
|
async function submit() {
|
|
36683
36865
|
if (!code.trim() || busy) return;
|
|
36684
36866
|
setBusy(true);
|
|
@@ -36899,13 +37081,13 @@ function OrderFormSkeleton({ parentLabel, onBack } = {}) {
|
|
|
36899
37081
|
] });
|
|
36900
37082
|
}
|
|
36901
37083
|
function useCatalogedItemTypes(itemTypes, lookups) {
|
|
36902
|
-
const countable =
|
|
37084
|
+
const countable = React130.useMemo(
|
|
36903
37085
|
() => itemTypes.filter((tp) => typeof lookups[tp.value]?.count === "function").map((tp) => tp.value),
|
|
36904
37086
|
[itemTypes, lookups]
|
|
36905
37087
|
);
|
|
36906
|
-
const [empty, setEmpty] =
|
|
37088
|
+
const [empty, setEmpty] = React130.useState([]);
|
|
36907
37089
|
const key = countable.join(",");
|
|
36908
|
-
|
|
37090
|
+
React130.useEffect(() => {
|
|
36909
37091
|
if (!countable.length) {
|
|
36910
37092
|
setEmpty([]);
|
|
36911
37093
|
return;
|
|
@@ -36924,7 +37106,7 @@ function useCatalogedItemTypes(itemTypes, lookups) {
|
|
|
36924
37106
|
cancelled = true;
|
|
36925
37107
|
};
|
|
36926
37108
|
}, [key, lookups]);
|
|
36927
|
-
return
|
|
37109
|
+
return React130.useMemo(
|
|
36928
37110
|
() => empty.length ? itemTypes.filter((tp) => !empty.includes(tp.value)) : itemTypes,
|
|
36929
37111
|
[itemTypes, empty]
|
|
36930
37112
|
);
|
|
@@ -37196,7 +37378,7 @@ function OrderCreateScreen({
|
|
|
37196
37378
|
errorActions,
|
|
37197
37379
|
saveBar
|
|
37198
37380
|
}) {
|
|
37199
|
-
const subtotal =
|
|
37381
|
+
const subtotal = React130.useMemo(
|
|
37200
37382
|
() => lines.reduce((sum, line) => sum + line.unitPrice * line.quantity, 0),
|
|
37201
37383
|
[lines]
|
|
37202
37384
|
);
|
|
@@ -37347,7 +37529,7 @@ function mergeLines(current2, incoming) {
|
|
|
37347
37529
|
return merged;
|
|
37348
37530
|
}
|
|
37349
37531
|
function ItemPicker({ search, onPick }) {
|
|
37350
|
-
const [open, setOpen] =
|
|
37532
|
+
const [open, setOpen] = React130.useState(false);
|
|
37351
37533
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
37352
37534
|
/* @__PURE__ */ jsxs(
|
|
37353
37535
|
"button",
|
|
@@ -37425,9 +37607,9 @@ function KanbanBoard({
|
|
|
37425
37607
|
toolbarActions
|
|
37426
37608
|
}) {
|
|
37427
37609
|
const collapsible = !!onToggleColumn;
|
|
37428
|
-
const frameRef =
|
|
37429
|
-
const [hoveredCol, setHoveredCol] =
|
|
37430
|
-
const centerFocused =
|
|
37610
|
+
const frameRef = React130.useRef(null);
|
|
37611
|
+
const [hoveredCol, setHoveredCol] = React130.useState(null);
|
|
37612
|
+
const centerFocused = React130.useCallback((event) => {
|
|
37431
37613
|
const frame = frameRef.current;
|
|
37432
37614
|
const column = event.target?.closest("[data-kanban-column]");
|
|
37433
37615
|
if (!frame || !column || frame.scrollWidth <= frame.clientWidth) return;
|
|
@@ -37436,14 +37618,14 @@ function KanbanBoard({
|
|
|
37436
37618
|
const delta = columnBox.left + columnBox.width / 2 - (frameBox.left + frameBox.width / 2);
|
|
37437
37619
|
if (Math.abs(delta) > 1) frame.scrollBy({ left: delta, behavior: "smooth" });
|
|
37438
37620
|
}, []);
|
|
37439
|
-
const autoScroll =
|
|
37440
|
-
const scrollStep =
|
|
37441
|
-
const stopAutoScroll =
|
|
37621
|
+
const autoScroll = React130.useRef(null);
|
|
37622
|
+
const scrollStep = React130.useRef(0);
|
|
37623
|
+
const stopAutoScroll = React130.useCallback(() => {
|
|
37442
37624
|
if (autoScroll.current !== null) cancelAnimationFrame(autoScroll.current);
|
|
37443
37625
|
autoScroll.current = null;
|
|
37444
37626
|
scrollStep.current = 0;
|
|
37445
37627
|
}, []);
|
|
37446
|
-
const tickAutoScroll =
|
|
37628
|
+
const tickAutoScroll = React130.useCallback(() => {
|
|
37447
37629
|
const frame = frameRef.current;
|
|
37448
37630
|
if (!frame || scrollStep.current === 0) {
|
|
37449
37631
|
stopAutoScroll();
|
|
@@ -37457,7 +37639,7 @@ function KanbanBoard({
|
|
|
37457
37639
|
}
|
|
37458
37640
|
autoScroll.current = requestAnimationFrame(tickAutoScroll);
|
|
37459
37641
|
}, [stopAutoScroll]);
|
|
37460
|
-
const onFrameDragOver =
|
|
37642
|
+
const onFrameDragOver = React130.useCallback((event) => {
|
|
37461
37643
|
const frame = frameRef.current;
|
|
37462
37644
|
if (!frame || frame.scrollWidth <= frame.clientWidth) return;
|
|
37463
37645
|
const box = frame.getBoundingClientRect();
|
|
@@ -37475,12 +37657,12 @@ function KanbanBoard({
|
|
|
37475
37657
|
}
|
|
37476
37658
|
if (autoScroll.current === null) autoScroll.current = requestAnimationFrame(tickAutoScroll);
|
|
37477
37659
|
}, [stopAutoScroll, tickAutoScroll]);
|
|
37478
|
-
const onFrameDragLeave =
|
|
37660
|
+
const onFrameDragLeave = React130.useCallback((event) => {
|
|
37479
37661
|
const indo = event.relatedTarget;
|
|
37480
37662
|
if (indo && event.currentTarget.contains(indo)) return;
|
|
37481
37663
|
stopAutoScroll();
|
|
37482
37664
|
}, [stopAutoScroll]);
|
|
37483
|
-
|
|
37665
|
+
React130.useEffect(() => stopAutoScroll, [stopAutoScroll]);
|
|
37484
37666
|
const hasToolbar = !!onSearchChange || !!onRefresh || !!toolbarActions;
|
|
37485
37667
|
const board = /* @__PURE__ */ jsx(
|
|
37486
37668
|
"div",
|
|
@@ -37588,10 +37770,10 @@ function BoardFrame({
|
|
|
37588
37770
|
toolbarActions,
|
|
37589
37771
|
className = ""
|
|
37590
37772
|
}) {
|
|
37591
|
-
const [open, setOpen] =
|
|
37592
|
-
const inputRef =
|
|
37773
|
+
const [open, setOpen] = React130.useState(false);
|
|
37774
|
+
const inputRef = React130.useRef(null);
|
|
37593
37775
|
const expanded = open || !!search;
|
|
37594
|
-
|
|
37776
|
+
React130.useEffect(() => {
|
|
37595
37777
|
if (open) inputRef.current?.focus();
|
|
37596
37778
|
}, [open]);
|
|
37597
37779
|
function collapse() {
|
|
@@ -37670,14 +37852,14 @@ function OrderBoardView({
|
|
|
37670
37852
|
rowId,
|
|
37671
37853
|
selectedRowId
|
|
37672
37854
|
}) {
|
|
37673
|
-
const getId =
|
|
37855
|
+
const getId = React130.useCallback(
|
|
37674
37856
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
37675
37857
|
[rowId]
|
|
37676
37858
|
);
|
|
37677
|
-
const [lastClicked, setLastClicked] =
|
|
37678
|
-
const [advancing, setAdvancing] =
|
|
37859
|
+
const [lastClicked, setLastClicked] = React130.useState(null);
|
|
37860
|
+
const [advancing, setAdvancing] = React130.useState({});
|
|
37679
37861
|
const selected = selectedRowId !== void 0 ? selectedRowId : lastClicked;
|
|
37680
|
-
const grouped =
|
|
37862
|
+
const grouped = React130.useMemo(() => {
|
|
37681
37863
|
const map = /* @__PURE__ */ new Map();
|
|
37682
37864
|
for (const col of board.columns) map.set(col.id, []);
|
|
37683
37865
|
for (const row of rows) {
|
|
@@ -37801,24 +37983,24 @@ function OrderListView({
|
|
|
37801
37983
|
boards,
|
|
37802
37984
|
viewKey
|
|
37803
37985
|
}) {
|
|
37804
|
-
const [search, setSearch] =
|
|
37805
|
-
const [page, setPage] =
|
|
37806
|
-
const [rawSelection, setRawSelection] =
|
|
37807
|
-
const offered =
|
|
37986
|
+
const [search, setSearch] = React130.useState("");
|
|
37987
|
+
const [page, setPage] = React130.useState(1);
|
|
37988
|
+
const [rawSelection, setRawSelection] = React130.useState([]);
|
|
37989
|
+
const offered = React130.useMemo(
|
|
37808
37990
|
() => views && views.length > 0 ? views : ["list"],
|
|
37809
37991
|
[views]
|
|
37810
37992
|
);
|
|
37811
|
-
const customFor =
|
|
37993
|
+
const customFor = React130.useCallback(
|
|
37812
37994
|
(id) => boards?.[id]?.render ?? null,
|
|
37813
37995
|
[boards]
|
|
37814
37996
|
);
|
|
37815
|
-
const boardFor =
|
|
37997
|
+
const boardFor = React130.useCallback(
|
|
37816
37998
|
(id) => (id === "board" ? board : boards?.[id]?.config) ?? null,
|
|
37817
37999
|
[board, boards]
|
|
37818
38000
|
);
|
|
37819
38001
|
const canBoard = offered.length > 1 && offered.some((id) => id !== "list" && (!!boardFor(id) || !!customFor(id)));
|
|
37820
38002
|
const storageKey2 = viewKey ? `fayz.orderView.${viewKey}` : null;
|
|
37821
|
-
const [view, setView] =
|
|
38003
|
+
const [view, setView] = React130.useState(() => {
|
|
37822
38004
|
const fallback = offered.includes(defaultView) ? defaultView : offered[0];
|
|
37823
38005
|
if (!storageKey2) return fallback;
|
|
37824
38006
|
try {
|
|
@@ -37828,7 +38010,7 @@ function OrderListView({
|
|
|
37828
38010
|
return fallback;
|
|
37829
38011
|
}
|
|
37830
38012
|
});
|
|
37831
|
-
const viewTabs =
|
|
38013
|
+
const viewTabs = React130.useMemo(
|
|
37832
38014
|
() => offered.map((option) => ({
|
|
37833
38015
|
value: option,
|
|
37834
38016
|
label: option === "list" ? "Lista" : boards?.[option]?.label ?? "Quadro",
|
|
@@ -37836,7 +38018,7 @@ function OrderListView({
|
|
|
37836
38018
|
})),
|
|
37837
38019
|
[offered, boards]
|
|
37838
38020
|
);
|
|
37839
|
-
const chooseView =
|
|
38021
|
+
const chooseView = React130.useCallback((next) => {
|
|
37840
38022
|
setView(next);
|
|
37841
38023
|
if (!storageKey2) return;
|
|
37842
38024
|
try {
|
|
@@ -37854,7 +38036,7 @@ function OrderListView({
|
|
|
37854
38036
|
const activeBoard = view === "list" ? null : boardFor(view);
|
|
37855
38037
|
const activeCustom = view === "list" ? null : customFor(view);
|
|
37856
38038
|
const showingBoard = !!activeBoard || !!activeCustom;
|
|
37857
|
-
const cols =
|
|
38039
|
+
const cols = React130.useMemo(
|
|
37858
38040
|
() => columns.map((c) => ({
|
|
37859
38041
|
id: c.key,
|
|
37860
38042
|
header: () => /* @__PURE__ */ jsx("div", { className: c.align === "right" ? "text-right" : "", children: c.header }),
|
|
@@ -37862,25 +38044,25 @@ function OrderListView({
|
|
|
37862
38044
|
})),
|
|
37863
38045
|
[columns]
|
|
37864
38046
|
);
|
|
37865
|
-
const filtered =
|
|
38047
|
+
const filtered = React130.useMemo(() => {
|
|
37866
38048
|
const term = search.trim().toLowerCase();
|
|
37867
38049
|
if (!term || !searchText) return rows;
|
|
37868
38050
|
return rows.filter((row) => searchText(row).toLowerCase().includes(term));
|
|
37869
38051
|
}, [rows, search, searchText]);
|
|
37870
|
-
|
|
38052
|
+
React130.useEffect(() => {
|
|
37871
38053
|
setPage(1);
|
|
37872
38054
|
}, [search]);
|
|
37873
38055
|
const paged = pageSize > 0 ? filtered.slice((page - 1) * pageSize, page * pageSize) : filtered;
|
|
37874
|
-
const getId =
|
|
38056
|
+
const getId = React130.useCallback(
|
|
37875
38057
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
37876
38058
|
[rowId]
|
|
37877
38059
|
);
|
|
37878
|
-
const pageIds =
|
|
37879
|
-
const selectedIds =
|
|
38060
|
+
const pageIds = React130.useMemo(() => paged.map(getId), [paged, getId]);
|
|
38061
|
+
const selectedIds = React130.useMemo(
|
|
37880
38062
|
() => rawSelection.filter((id) => pageIds.includes(id)),
|
|
37881
38063
|
[rawSelection, pageIds]
|
|
37882
38064
|
);
|
|
37883
|
-
const selectedRows =
|
|
38065
|
+
const selectedRows = React130.useMemo(
|
|
37884
38066
|
() => paged.filter((row) => selectedIds.includes(getId(row))),
|
|
37885
38067
|
[paged, selectedIds, getId]
|
|
37886
38068
|
);
|
|
@@ -38030,13 +38212,13 @@ function PaymentStatusBadge({
|
|
|
38030
38212
|
receiveLabel = "Receber",
|
|
38031
38213
|
onOpenDetails
|
|
38032
38214
|
}) {
|
|
38033
|
-
const [open, setOpen] =
|
|
38034
|
-
const [lines, setLines] =
|
|
38035
|
-
const timer =
|
|
38036
|
-
|
|
38215
|
+
const [open, setOpen] = React130__default.useState(false);
|
|
38216
|
+
const [lines, setLines] = React130__default.useState(null);
|
|
38217
|
+
const timer = React130__default.useRef(null);
|
|
38218
|
+
React130__default.useEffect(() => {
|
|
38037
38219
|
setLines(null);
|
|
38038
38220
|
}, [status, paidAmount]);
|
|
38039
|
-
const load =
|
|
38221
|
+
const load = React130__default.useCallback(() => {
|
|
38040
38222
|
if (lines || !onLoadDetails) return;
|
|
38041
38223
|
void onLoadDetails().then(setLines).catch(() => setLines([]));
|
|
38042
38224
|
}, [lines, onLoadDetails]);
|
|
@@ -38171,13 +38353,13 @@ function invalidateOrdersPaymentStatus(orderId) {
|
|
|
38171
38353
|
else cache2.clear();
|
|
38172
38354
|
}
|
|
38173
38355
|
function useOrdersPaymentStatus(orderIds) {
|
|
38174
|
-
const key =
|
|
38356
|
+
const key = React130.useMemo(
|
|
38175
38357
|
() => Array.from(new Set(orderIds.filter(Boolean))).sort().join(","),
|
|
38176
38358
|
[orderIds]
|
|
38177
38359
|
);
|
|
38178
|
-
const [byOrder, setByOrder] =
|
|
38179
|
-
const [loading, setLoading] =
|
|
38180
|
-
const load =
|
|
38360
|
+
const [byOrder, setByOrder] = React130.useState(() => /* @__PURE__ */ new Map());
|
|
38361
|
+
const [loading, setLoading] = React130.useState(false);
|
|
38362
|
+
const load = React130.useCallback(async (force = false) => {
|
|
38181
38363
|
const ids = key ? key.split(",") : [];
|
|
38182
38364
|
if (ids.length === 0) {
|
|
38183
38365
|
setByOrder(/* @__PURE__ */ new Map());
|
|
@@ -38208,7 +38390,7 @@ function useOrdersPaymentStatus(orderIds) {
|
|
|
38208
38390
|
}
|
|
38209
38391
|
setByOrder(new Map(ids.map((id) => [id, cache2.get(id)]).filter(([, v]) => Boolean(v))));
|
|
38210
38392
|
}, [key]);
|
|
38211
|
-
|
|
38393
|
+
React130.useEffect(() => {
|
|
38212
38394
|
void load();
|
|
38213
38395
|
}, [load]);
|
|
38214
38396
|
return { byOrder, loading, reload: () => load(true) };
|
|
@@ -38275,12 +38457,12 @@ function money2(value, currency) {
|
|
|
38275
38457
|
return value.toLocaleString("pt-BR", { style: "currency", currency: currency || "BRL" });
|
|
38276
38458
|
}
|
|
38277
38459
|
function useOrderDetail(orderId) {
|
|
38278
|
-
const [order, setOrder] =
|
|
38279
|
-
const [loading, setLoading] =
|
|
38280
|
-
const [error, setError] =
|
|
38281
|
-
const [nonce, setNonce] =
|
|
38282
|
-
const reload =
|
|
38283
|
-
|
|
38460
|
+
const [order, setOrder] = React130.useState(null);
|
|
38461
|
+
const [loading, setLoading] = React130.useState(false);
|
|
38462
|
+
const [error, setError] = React130.useState(null);
|
|
38463
|
+
const [nonce, setNonce] = React130.useState(0);
|
|
38464
|
+
const reload = React130.useCallback(() => setNonce((n) => n + 1), []);
|
|
38465
|
+
React130.useEffect(() => {
|
|
38284
38466
|
if (!orderId) {
|
|
38285
38467
|
setOrder(null);
|
|
38286
38468
|
setError(null);
|
|
@@ -38397,8 +38579,8 @@ function OrderDetailRail({
|
|
|
38397
38579
|
}) {
|
|
38398
38580
|
const { order, loading, error, reload } = useOrderDetail(orderId);
|
|
38399
38581
|
const { byOrder: paymentByOrder } = useOrdersPaymentStatus([orderId]);
|
|
38400
|
-
const [running, setRunning] =
|
|
38401
|
-
const [pending2, setPending] =
|
|
38582
|
+
const [running, setRunning] = React130.useState(null);
|
|
38583
|
+
const [pending2, setPending] = React130.useState(null);
|
|
38402
38584
|
const perform = async (action) => {
|
|
38403
38585
|
if (!order) return;
|
|
38404
38586
|
setRunning(action.id);
|
|
@@ -38556,11 +38738,11 @@ function receivableTone(value) {
|
|
|
38556
38738
|
return "warning";
|
|
38557
38739
|
}
|
|
38558
38740
|
function useOrderReceivable(orderId) {
|
|
38559
|
-
const [receivable, setReceivable] =
|
|
38741
|
+
const [receivable, setReceivable] = React130.useState(
|
|
38560
38742
|
() => orderId ? cache3.get(orderId) ?? null : null
|
|
38561
38743
|
);
|
|
38562
|
-
const [loading, setLoading] =
|
|
38563
|
-
const reload =
|
|
38744
|
+
const [loading, setLoading] = React130.useState(() => Boolean(orderId) && !cache3.has(orderId));
|
|
38745
|
+
const reload = React130.useCallback(async (force = false) => {
|
|
38564
38746
|
if (!orderId) return;
|
|
38565
38747
|
const db2 = getSupabaseClientOptional();
|
|
38566
38748
|
if (!db2) {
|
|
@@ -38583,7 +38765,7 @@ function useOrderReceivable(orderId) {
|
|
|
38583
38765
|
setReceivable(next);
|
|
38584
38766
|
setLoading(false);
|
|
38585
38767
|
}, [orderId]);
|
|
38586
|
-
|
|
38768
|
+
React130.useEffect(() => {
|
|
38587
38769
|
void reload();
|
|
38588
38770
|
}, [reload]);
|
|
38589
38771
|
return { receivable, loading, reload };
|
|
@@ -38736,15 +38918,15 @@ function linesOf(order) {
|
|
|
38736
38918
|
}
|
|
38737
38919
|
function useOrderEditor(orderId) {
|
|
38738
38920
|
const { order, loading, error } = useOrderDetail(orderId);
|
|
38739
|
-
const [lines, setLines] =
|
|
38740
|
-
const [saving, setSaving] =
|
|
38741
|
-
const originalRef =
|
|
38742
|
-
|
|
38921
|
+
const [lines, setLines] = React130.useState([]);
|
|
38922
|
+
const [saving, setSaving] = React130.useState(false);
|
|
38923
|
+
const originalRef = React130.useRef([]);
|
|
38924
|
+
React130.useEffect(() => {
|
|
38743
38925
|
const seeded = linesOf(order);
|
|
38744
38926
|
originalRef.current = seeded;
|
|
38745
38927
|
setLines(seeded);
|
|
38746
38928
|
}, [order]);
|
|
38747
|
-
const dirty =
|
|
38929
|
+
const dirty = React130.useMemo(() => {
|
|
38748
38930
|
const before = originalRef.current;
|
|
38749
38931
|
if (before.length !== lines.length) return true;
|
|
38750
38932
|
return lines.some((line, i) => {
|
|
@@ -38752,7 +38934,7 @@ function useOrderEditor(orderId) {
|
|
|
38752
38934
|
return !was || was.key !== line.key || was.quantity !== line.quantity || was.unitPrice !== line.unitPrice;
|
|
38753
38935
|
});
|
|
38754
38936
|
}, [lines]);
|
|
38755
|
-
const save =
|
|
38937
|
+
const save = React130.useCallback(async () => {
|
|
38756
38938
|
if (!orderId || !order) return { ok: false, error: "Pedido n\xE3o carregado" };
|
|
38757
38939
|
const db2 = getSupabaseClientOptional();
|
|
38758
38940
|
if (!db2) return { ok: false, error: "Sem conex\xE3o" };
|
|
@@ -38909,19 +39091,19 @@ function createClientOrdersProvider() {
|
|
|
38909
39091
|
}
|
|
38910
39092
|
function createPlaceholder(title, description) {
|
|
38911
39093
|
return function PlaceholderPage() {
|
|
38912
|
-
return
|
|
39094
|
+
return React130__default.createElement(
|
|
38913
39095
|
"div",
|
|
38914
39096
|
{ className: "mx-auto max-w-4xl" },
|
|
38915
|
-
|
|
38916
|
-
description ?
|
|
38917
|
-
|
|
39097
|
+
React130__default.createElement("h1", { className: "text-3xl font-bold text-foreground" }, title),
|
|
39098
|
+
description ? React130__default.createElement("p", { className: "mt-1 text-muted-foreground" }, description) : null,
|
|
39099
|
+
React130__default.createElement(
|
|
38918
39100
|
"div",
|
|
38919
39101
|
{ className: "mt-8 flex items-center justify-center rounded-card border border-dashed border-border bg-card p-16" },
|
|
38920
|
-
|
|
39102
|
+
React130__default.createElement(
|
|
38921
39103
|
"div",
|
|
38922
39104
|
{ className: "text-center" },
|
|
38923
|
-
|
|
38924
|
-
|
|
39105
|
+
React130__default.createElement("p", { className: "text-lg font-medium text-muted-foreground" }, "Coming Soon"),
|
|
39106
|
+
React130__default.createElement(
|
|
38925
39107
|
"p",
|
|
38926
39108
|
{ className: "mt-1 text-sm text-muted-foreground/70" },
|
|
38927
39109
|
"This module is being built as a plugin."
|
|
@@ -39002,7 +39184,7 @@ function ModuleActionBar({
|
|
|
39002
39184
|
trailing
|
|
39003
39185
|
}) {
|
|
39004
39186
|
const t = useTranslation();
|
|
39005
|
-
const actions =
|
|
39187
|
+
const actions = React130__default.useMemo(() => {
|
|
39006
39188
|
const out = (quickActions ?? []).map((qa, i) => ({
|
|
39007
39189
|
id: qa.id,
|
|
39008
39190
|
label: qa.label,
|
|
@@ -39034,9 +39216,9 @@ function ModuleActionBar({
|
|
|
39034
39216
|
] });
|
|
39035
39217
|
}
|
|
39036
39218
|
function createPluginContext(displayName) {
|
|
39037
|
-
const ConfigContext =
|
|
39038
|
-
const ProviderContext =
|
|
39039
|
-
const StoreContext =
|
|
39219
|
+
const ConfigContext = React130__default.createContext(null);
|
|
39220
|
+
const ProviderContext = React130__default.createContext(null);
|
|
39221
|
+
const StoreContext = React130__default.createContext(null);
|
|
39040
39222
|
const ContextProvider = ({
|
|
39041
39223
|
config,
|
|
39042
39224
|
provider: provider2,
|
|
@@ -39045,17 +39227,17 @@ function createPluginContext(displayName) {
|
|
|
39045
39227
|
}) => /* @__PURE__ */ jsx(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsx(ProviderContext.Provider, { value: provider2, children: /* @__PURE__ */ jsx(StoreContext.Provider, { value: store, children }) }) });
|
|
39046
39228
|
ContextProvider.displayName = `${displayName}ContextProvider`;
|
|
39047
39229
|
function useConfig() {
|
|
39048
|
-
const ctx =
|
|
39230
|
+
const ctx = React130__default.useContext(ConfigContext);
|
|
39049
39231
|
if (!ctx) throw new Error(`useConfig must be used within ${displayName}`);
|
|
39050
39232
|
return ctx;
|
|
39051
39233
|
}
|
|
39052
39234
|
function useProvider() {
|
|
39053
|
-
const ctx =
|
|
39235
|
+
const ctx = React130__default.useContext(ProviderContext);
|
|
39054
39236
|
if (!ctx) throw new Error(`useProvider must be used within ${displayName}`);
|
|
39055
39237
|
return ctx;
|
|
39056
39238
|
}
|
|
39057
39239
|
function useStore2(selector) {
|
|
39058
|
-
const store =
|
|
39240
|
+
const store = React130__default.useContext(StoreContext);
|
|
39059
39241
|
if (!store) throw new Error(`useStore must be used within ${displayName}`);
|
|
39060
39242
|
return useStore$1(store, selector);
|
|
39061
39243
|
}
|
|
@@ -39112,7 +39294,7 @@ function PluginRegistryManager({ registries, routeBase, className }) {
|
|
|
39112
39294
|
return registries[0]?.id ?? "";
|
|
39113
39295
|
};
|
|
39114
39296
|
const [activeTab, setActiveTab] = useState(getTabFromHash);
|
|
39115
|
-
|
|
39297
|
+
React130__default.useEffect(() => {
|
|
39116
39298
|
if (!routeBase) return;
|
|
39117
39299
|
const handler = () => setActiveTab(getTabFromHash());
|
|
39118
39300
|
window.addEventListener("hashchange", handler);
|
|
@@ -39323,7 +39505,7 @@ function PersonLink2({ personId, name, avatarUrl, lookup, kind, profileHref, tab
|
|
|
39323
39505
|
const email = data?.email;
|
|
39324
39506
|
const phone = data?.phone;
|
|
39325
39507
|
const resolvedKind = kind ?? data?.kind ?? person?.group;
|
|
39326
|
-
const actions =
|
|
39508
|
+
const actions = React130__default.useMemo(
|
|
39327
39509
|
() => personId ? getPersonActions(resolvedKind) : [],
|
|
39328
39510
|
[personId, resolvedKind]
|
|
39329
39511
|
);
|
|
@@ -40148,10 +40330,10 @@ function useTeachMe(def) {
|
|
|
40148
40330
|
return useFeatureHelp(def).teach;
|
|
40149
40331
|
}
|
|
40150
40332
|
function useFeatureHelp(def) {
|
|
40151
|
-
const ref =
|
|
40333
|
+
const ref = React130.useRef(def);
|
|
40152
40334
|
ref.current = def;
|
|
40153
40335
|
const id = `teach.${def.feature}`;
|
|
40154
|
-
const contribution =
|
|
40336
|
+
const contribution = React130.useMemo(
|
|
40155
40337
|
() => ({
|
|
40156
40338
|
id,
|
|
40157
40339
|
pluginId: "teach-me",
|
|
@@ -40185,7 +40367,7 @@ function useFeatureHelp(def) {
|
|
|
40185
40367
|
[id]
|
|
40186
40368
|
);
|
|
40187
40369
|
useAgentSurface(contribution);
|
|
40188
|
-
return
|
|
40370
|
+
return React130.useMemo(
|
|
40189
40371
|
() => ({
|
|
40190
40372
|
help: () => helpWith(ref.current),
|
|
40191
40373
|
teach: () => teachMe(ref.current),
|
|
@@ -40351,21 +40533,21 @@ function ConnectorsHub({ hostPluginId }) {
|
|
|
40351
40533
|
const { t } = useTranslation$1();
|
|
40352
40534
|
const { connectors, reload } = useConnectors({ includeGrants: false });
|
|
40353
40535
|
const assistantAvailable = useConnectorsPanelAvailable();
|
|
40354
|
-
const [selected, setSelected] =
|
|
40355
|
-
const [adding, setAdding] =
|
|
40356
|
-
const hosted =
|
|
40536
|
+
const [selected, setSelected] = React130__default.useState(null);
|
|
40537
|
+
const [adding, setAdding] = React130__default.useState(false);
|
|
40538
|
+
const hosted = React130__default.useMemo(
|
|
40357
40539
|
() => (connectors ?? []).filter((c) => c.hostPluginId === hostPluginId),
|
|
40358
40540
|
[connectors, hostPluginId]
|
|
40359
40541
|
);
|
|
40360
|
-
const categories =
|
|
40542
|
+
const categories = React130__default.useMemo(
|
|
40361
40543
|
() => [...new Set(hosted.map((c) => c.category).filter((c) => !!c))],
|
|
40362
40544
|
[hosted]
|
|
40363
40545
|
);
|
|
40364
|
-
const scoped =
|
|
40546
|
+
const scoped = React130__default.useMemo(() => {
|
|
40365
40547
|
const siblings = inCategories(connectors ?? [], categories).filter((c) => c.hostPluginId !== hostPluginId);
|
|
40366
40548
|
return [...hosted, ...siblings];
|
|
40367
40549
|
}, [connectors, hosted, categories, hostPluginId]);
|
|
40368
|
-
|
|
40550
|
+
React130__default.useEffect(() => {
|
|
40369
40551
|
if (!selected || !connectors) return;
|
|
40370
40552
|
const fresh = connectors.find((c) => c.id === selected.id);
|
|
40371
40553
|
if (fresh && fresh !== selected) setSelected(fresh);
|
|
@@ -40541,7 +40723,7 @@ function PluginSettingsPanel({ title, generalSettings, registries, customTabs, r
|
|
|
40541
40723
|
return tabs[0]?.id ?? "";
|
|
40542
40724
|
}
|
|
40543
40725
|
const [activeTab, setActiveTab] = useState(getActiveFromHash);
|
|
40544
|
-
|
|
40726
|
+
React130__default.useEffect(() => {
|
|
40545
40727
|
const handler = () => setActiveTab(getActiveFromHash());
|
|
40546
40728
|
window.addEventListener("hashchange", handler);
|
|
40547
40729
|
return () => window.removeEventListener("hashchange", handler);
|
|
@@ -40579,6 +40761,6 @@ var renderApp = (...args) => {
|
|
|
40579
40761
|
return renderApp$1(...args);
|
|
40580
40762
|
};
|
|
40581
40763
|
|
|
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 };
|
|
40764
|
+
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, applyFieldRules, 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, deriveEntityKey5 as deriveEntityKey, 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 };
|
|
40583
40765
|
//# sourceMappingURL=index.js.map
|
|
40584
40766
|
//# sourceMappingURL=index.js.map
|