@fayz-ai/admin 0.43.4 → 0.44.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-MNHZCQIG.js +6 -0
- package/dist/{ScheduleEditor-ZEG6PG3Z.js.map → ScheduleEditor-MNHZCQIG.js.map} +1 -1
- package/dist/SubscriptionPage-JWWS44SE.js +9 -0
- package/dist/{SubscriptionPage-VXZ37WZZ.js.map → SubscriptionPage-JWWS44SE.js.map} +1 -1
- package/dist/{chunk-A5UZL52H.js → chunk-OINP2UYL.js} +3 -3
- package/dist/{chunk-A5UZL52H.js.map → chunk-OINP2UYL.js.map} +1 -1
- package/dist/{chunk-KP3LNCNP.js → chunk-V2IBAF4O.js} +954 -23
- package/dist/chunk-V2IBAF4O.js.map +1 -0
- package/dist/{chunk-HOMD2MAG.js → chunk-VH4LLIMH.js} +3 -3
- package/dist/{chunk-HOMD2MAG.js.map → chunk-VH4LLIMH.js.map} +1 -1
- package/dist/components/settings/ConnectedCompanySettings.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderDeliveryBlock.d.ts +32 -0
- package/dist/crud/archetypes/OrderDeliveryBlock.d.ts.map +1 -0
- package/dist/crud/archetypes/OrderDetailPage.d.ts +4 -2
- package/dist/crud/archetypes/OrderDetailPage.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderDetailRail.d.ts +2 -0
- package/dist/crud/archetypes/OrderDetailRail.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderDetailView.d.ts +11 -1
- package/dist/crud/archetypes/OrderDetailView.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderFormView.d.ts +10 -2
- package/dist/crud/archetypes/OrderFormView.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderListView.d.ts +20 -1
- package/dist/crud/archetypes/OrderListView.d.ts.map +1 -1
- package/dist/crud/archetypes/orderStage.d.ts +16 -0
- package/dist/crud/archetypes/orderStage.d.ts.map +1 -0
- package/dist/crud/archetypes/orderVocabulary.d.ts.map +1 -1
- package/dist/crud/archetypes/useOrderKindTransitions.d.ts +10 -0
- package/dist/crud/archetypes/useOrderKindTransitions.d.ts.map +1 -0
- package/dist/crud/relation-field.d.ts.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +737 -916
- package/dist/index.js.map +1 -1
- package/dist/lib/currency.d.ts +33 -5
- package/dist/lib/currency.d.ts.map +1 -1
- package/dist/lib/format.d.ts.map +1 -1
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/index.js +1 -2
- package/dist/plugins/createPluginContext.d.ts.map +1 -1
- package/dist/theme/utils.d.ts +9 -0
- package/dist/theme/utils.d.ts.map +1 -1
- package/dist/units/useHouseCurrencySync.d.ts +9 -0
- package/dist/units/useHouseCurrencySync.d.ts.map +1 -0
- package/dist/units/useUnitBootstrap.d.ts.map +1 -1
- package/package.json +6 -6
- package/dist/ScheduleEditor-ZEG6PG3Z.js +0 -7
- package/dist/SubscriptionPage-VXZ37WZZ.js +0 -9
- package/dist/chunk-3C5Q4OGJ.js +0 -375
- package/dist/chunk-3C5Q4OGJ.js.map +0 -1
- package/dist/chunk-KP3LNCNP.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-VH4LLIMH.js';
|
|
3
|
+
export { AccessProvider, UPGRADE_URL, agentDenial, checkAccess, getAccessSnapshot, guardLimit, invalidateLimit, isEntitledByPlan, resolveAccess, useAccess, useAccessOptional, useLimit, useLimitGuard, useModuleNavAccess, useUpgradeModalStore } from './chunk-VH4LLIMH.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,12 +10,10 @@ 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, markWorkspaceSwitch } from './chunk-3C5Q4OGJ.js';
|
|
18
|
-
export { ORG_CACHE_TTL_MS, OrgProvider, clearOrgSnapshot, readOrgSnapshot, useOrgAdapter, useOrgAdapterOptional, useTenant, useTenantOptional } from './chunk-3C5Q4OGJ.js';
|
|
13
|
+
import { createArchetypeLookup, getPersonLookup } from './chunk-OINP2UYL.js';
|
|
14
|
+
export { ScheduleDateExceptions, ScheduleEditor, ScheduleGridPanel, createArchetypeLookup, deleteSchedule, getPersonBookable, getPersonLookup, getScheduleBlockConfig, getSchedules, mergeBlockSettings, parseBlockSettings, registerPersonLookup, replaceWeeklySchedules, saveSchedule, setPersonBookable, setScheduleBlockConfig, subscribeScheduleBlockConfig } from './chunk-OINP2UYL.js';
|
|
15
|
+
import { dedup, useUnitStore, getFayzSupabaseClientOptional, getSupabaseClientOptional as getSupabaseClientOptional$1, useTenantOptional, fetchMemberUnits, UNIT_ACCESS_CHANGED, useAppConfigStore, useOrgAdapter, useTenant, activePluginIds, hasPlugin, useWorkspaceSwitchingStore, searchWorkspaces, OrgMark, WorkspaceChooserGate, WorkspaceSwitchingHost, createFayzSupabaseClient, OrgProvider, useOrgAdapterOptional, bindUserToUnit, unbindUserFromUnit, resolveAppId, createSupabaseOrgAdapter, createMockOrgAdapter, fetchUnitMembers, fetchMemberActivity, getFayzSupabaseClient, markWorkspaceSwitch, countUnboundMembers, bindAllMembersTo, setUnitModeRemote, fetchUserIdForPerson } from './chunk-V2IBAF4O.js';
|
|
16
|
+
export { ORG_CACHE_TTL_MS, OrgMark, OrgProvider, activePluginIds, clearOrgSnapshot, createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, dedup, getFayzSupabaseClient, getFayzSupabaseClientOptional, hasPlugin, orgInitials, readOrgSnapshot, useAppConfigStore, useOrgAdapter, useOrgAdapterOptional, useTenant, useTenantOptional, useUnitStore } from './chunk-V2IBAF4O.js';
|
|
19
17
|
import { usePermissionOptional, usePermissionsStore, PermissionsProvider } from './chunk-UQ2NTFQC.js';
|
|
20
18
|
export { PermissionsProvider, useHasPermission, usePermission, usePermissionOptional, usePermissions, usePermissionsStore } from './chunk-UQ2NTFQC.js';
|
|
21
19
|
import { cn, useOrganizationStore } from './chunk-QOS6UAQ4.js';
|
|
@@ -24,7 +22,7 @@ import * as React133 from 'react';
|
|
|
24
22
|
import React133__default, { createContext, useMemo, useState, useRef, useCallback, useEffect, useLayoutEffect, useContext, createElement } from 'react';
|
|
25
23
|
import * as LucideIcons from 'lucide-react';
|
|
26
24
|
import { RotateCcw, WifiOff, Pencil, Copy, Trash2, Upload, Search, ArrowDown, ArrowUp, ArrowUpDown, Check, Download, ChevronLeft, ChevronRight, AlertTriangle, Building2, Inbox, Package, Sparkles, Plug, DollarSign, Clock, X, WandSparkles, Loader2, ArrowDownToLine, ArrowUpFromLine, CheckCircle2, Crown, ArrowRight, History, SquarePen, Settings2, Mic, User, Plus, Minus, ListChecks, ChevronDown, ArrowLeft, Calendar, ClipboardList, BookOpen, Lock, PinOff, Pin, Eye, Users, StickyNote, CheckSquare2, Square, Globe, LayoutTemplate, Store, ChevronsUpDown, ExternalLink, PenSquare, RefreshCw, XCircle, Camera, Edit, Star, Link2Off, Layers, ShoppingBag, MoreHorizontal, ChevronUp, List, LayoutGrid, CircleDollarSign, Receipt, Settings, Mail, MessageCircle, Cake, HelpCircle, Wrench, ShieldCheck, MessageSquare, Paperclip, Infinity, CheckCheck, PartyPopper, Compass, Play, MapPin, Landmark, LocateFixed, ArrowUpCircle, ArrowUpRight, Pause, CalendarDays, CircleCheckBig, UserX, Ban, CircleAlert, CircleEllipsis, FileText, CircleDashed, Power, ArrowRightLeft, File as File$1, FileImage, FileSpreadsheet, AlertCircle, CreditCard, SlidersHorizontal, Puzzle, Shield, Palette, Blocks, ShieldAlert, UserCog, LogOut, Bell, Database, Radio, Zap, Save, ImagePlus, UserPlus, Contact, UserMinus, Send, Sun, Moon, Monitor, Languages, Info, Link2, KeyRound, Ellipsis, Phone, Bug, Home, Heart, Briefcase, BarChart3, Tag, Truck, Globe2 } from 'lucide-react';
|
|
27
|
-
import { reportAppError, toDataError, tl, createDebug,
|
|
25
|
+
import { reportAppError, toDataError, tl, createDebug, fetchAppConfig, getSupabaseClientOptional, payeeAccountFields, maskCpfCnpj, recordRailFields, RECORD_GROUP, activeFacet, createSafeDataProvider, isKnownMissing, rememberIfMissing, deriveEntityKey, registerEntity, getActiveTenantId, resolveDataProvider, bulkRemove, emitDomainEvent, entityEventKey, errorMessage, useTranslation, describeError, useDataChanged, emitDataChanged, exportCSV, getScopedResource, formatDateTime as formatDateTime$1, formatDate as formatDate$1, formatCurrency as formatCurrency$1, bulkCreate, matchesRange, isConnectorCategory, usePluginRuntimeOptional, useDataVersion, getWidgetsForZone, resolvePluginComponent, useUnitMode, invalidateAppConfig, toTenantPluginBindings, setCurrentLocale, resolveLocale, resolvePluginRuntime, PluginRuntimeProvider, I18nProvider, getAllEntities, resolveIntegrationSurface, defineApp, registerScaffold, subscribeHouseCurrency, getHouseCurrency, resolveCurrency, useActiveTenantId, onDataChanged, useConnectorsForPlugin, renderApp as renderApp$1, parseRangeFilter, isFilterObject, connectionKey, useManifest, registerEventSink, formatPostalCode, isValidPostalCode, lookupPostalCode, usePluginRuntime, useConnectivity, RECONNECTED_EVENT, installGlobalErrorHandlers, registerErrorReporter, getConnectivity, applyNavComposition, mergeTranslations, coreTranslations, attachPersistentCache, getPersistentCache, createMockProvider, listConnections, connectorPlanes, connectorPermissions, connectorEntities, preferredPlane, connectorDirection, countByTenant, isAddressIncomplete, isBankIncomplete, payeeMethodOf, getCurrentLocale, searchEverything, readImpersonation, getComponent, getPluginFactory, connectorSettings, groupedPermissions, invocationPlane, missingRequiredSettings, isBankEmpty, isAddressEmpty, writeImpersonation, isSettingSet, getEntityByKey, connectorSubscribesTo, eventKeyMatches } from '@fayz-ai/core';
|
|
28
26
|
export { ConnectorRuntimeTokenUnavailableError, createSafeDataProvider, formatDate, formatDateTime, getActiveLocale, getActiveTenantId, getConnectorRuntimeTokenSource, getCurrentLocale, getSupabaseClientOptional, preloadLocale, resolveBackendEnv, setConnectorRuntimeTokenSource, setCurrentLocale, tl, useActiveTenantId } from '@fayz-ai/core';
|
|
29
27
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
30
28
|
import { usePasswordSetupGate, SetPasswordPage, AuthGate, AuthProvider, createAuthRuntime } from '@fayz-ai/plugin-auth';
|
|
@@ -1134,8 +1132,8 @@ ${buildToolIndex(searchable)}`,
|
|
|
1134
1132
|
}
|
|
1135
1133
|
];
|
|
1136
1134
|
}
|
|
1137
|
-
function words(
|
|
1138
|
-
return
|
|
1135
|
+
function words(text3) {
|
|
1136
|
+
return text3.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter((w) => w.length > 2);
|
|
1139
1137
|
}
|
|
1140
1138
|
function matches(tool, query) {
|
|
1141
1139
|
const terms = words(query);
|
|
@@ -1256,9 +1254,9 @@ async function readAllRows(digest) {
|
|
|
1256
1254
|
if (digest.kind !== "csv") {
|
|
1257
1255
|
throw new Error("Only CSV files can be read in full here. Ask the user to save the sheet as CSV.");
|
|
1258
1256
|
}
|
|
1259
|
-
const
|
|
1260
|
-
const delimiter = detectDelimiter(
|
|
1261
|
-
const { rows } = parseDelimited(
|
|
1257
|
+
const text3 = await entry.file.text();
|
|
1258
|
+
const delimiter = detectDelimiter(text3, /\.tsv$/i.test(entry.file.name) ? " " : void 0);
|
|
1259
|
+
const { rows } = parseDelimited(text3, delimiter);
|
|
1262
1260
|
if (!rows.length) return [];
|
|
1263
1261
|
const headers = rows[0].map((h) => h.trim());
|
|
1264
1262
|
return rows.slice(1).filter((row) => row.some((cell) => cell.trim())).map((row) => {
|
|
@@ -1320,22 +1318,22 @@ async function readTextBounded(file) {
|
|
|
1320
1318
|
return { text: await file.slice(0, HEAD_SLICE).text(), partial: true };
|
|
1321
1319
|
}
|
|
1322
1320
|
async function parseTextFile(file, base) {
|
|
1323
|
-
const { text:
|
|
1324
|
-
const preview =
|
|
1321
|
+
const { text: text3 } = await readTextBounded(file);
|
|
1322
|
+
const preview = text3.slice(0, PREVIEW_CHARS);
|
|
1325
1323
|
return {
|
|
1326
1324
|
...base,
|
|
1327
1325
|
preview,
|
|
1328
|
-
...
|
|
1326
|
+
...text3.length > PREVIEW_CHARS ? { warnings: [`preview truncated to ${PREVIEW_CHARS} characters`] } : {}
|
|
1329
1327
|
};
|
|
1330
1328
|
}
|
|
1331
1329
|
async function parseDelimitedFile(file, base) {
|
|
1332
|
-
const { text:
|
|
1330
|
+
const { text: text3, partial } = await readTextBounded(file);
|
|
1333
1331
|
const warnings = [];
|
|
1334
1332
|
if (partial) {
|
|
1335
1333
|
warnings.push("file too large \u2014 only the first rows were read, row count unknown");
|
|
1336
1334
|
}
|
|
1337
|
-
const delimiter = detectDelimiter(
|
|
1338
|
-
const sheet = buildSheet(file.name.replace(CSV_EXT, ""), parseDelimited(
|
|
1335
|
+
const delimiter = detectDelimiter(text3, /\.tsv$/i.test(file.name) ? " " : void 0);
|
|
1336
|
+
const sheet = buildSheet(file.name.replace(CSV_EXT, ""), parseDelimited(text3, delimiter), warnings);
|
|
1339
1337
|
if (partial) delete sheet.rowCount;
|
|
1340
1338
|
return {
|
|
1341
1339
|
...base,
|
|
@@ -1391,9 +1389,9 @@ async function parseSpreadsheetFile(file, base) {
|
|
|
1391
1389
|
...warnings.length ? { warnings } : {}
|
|
1392
1390
|
};
|
|
1393
1391
|
}
|
|
1394
|
-
function detectDelimiter(
|
|
1392
|
+
function detectDelimiter(text3, forced) {
|
|
1395
1393
|
if (forced) return forced;
|
|
1396
|
-
const firstLine =
|
|
1394
|
+
const firstLine = text3.slice(0, 4e3).split(/\r?\n/)[0] ?? "";
|
|
1397
1395
|
let best = ",";
|
|
1398
1396
|
let bestCount = 0;
|
|
1399
1397
|
for (const candidate of [",", ";", " ", "|"]) {
|
|
@@ -1415,7 +1413,7 @@ function countOutsideQuotes(line, char) {
|
|
|
1415
1413
|
}
|
|
1416
1414
|
return count;
|
|
1417
1415
|
}
|
|
1418
|
-
function parseDelimited(
|
|
1416
|
+
function parseDelimited(text3, delimiter) {
|
|
1419
1417
|
const rows = [];
|
|
1420
1418
|
let count = 0;
|
|
1421
1419
|
let row = [];
|
|
@@ -1431,7 +1429,7 @@ function parseDelimited(text2, delimiter) {
|
|
|
1431
1429
|
if (rows.length < SCAN_ROWS) rows.push(row);
|
|
1432
1430
|
row = [];
|
|
1433
1431
|
};
|
|
1434
|
-
const source =
|
|
1432
|
+
const source = text3.charCodeAt(0) === 65279 ? text3.slice(1) : text3;
|
|
1435
1433
|
for (let i = 0; i < source.length; i++) {
|
|
1436
1434
|
const c = source[i];
|
|
1437
1435
|
if (inQuotes) {
|
|
@@ -1465,8 +1463,8 @@ function buildSheet(name, parsed, warnings) {
|
|
|
1465
1463
|
return { name, headers, rowCount: Math.max(0, parsed.count - 1), sample, columnTypes };
|
|
1466
1464
|
}
|
|
1467
1465
|
function truncateCell(value) {
|
|
1468
|
-
const
|
|
1469
|
-
return
|
|
1466
|
+
const text3 = String(value ?? "");
|
|
1467
|
+
return text3.length > MAX_CELL_CHARS ? `${text3.slice(0, MAX_CELL_CHARS)}\u2026` : text3;
|
|
1470
1468
|
}
|
|
1471
1469
|
var SLASH_DATE = /^(\d{1,2})[/.-](\d{1,2})[/.-](\d{2,4})$/;
|
|
1472
1470
|
var ISO_DATE = /^\d{4}-\d{2}-\d{2}([T ]\d{2}:\d{2}(:\d{2})?)?/;
|
|
@@ -1629,16 +1627,16 @@ function formatBytes(bytes) {
|
|
|
1629
1627
|
// src/lib/assistant-text.ts
|
|
1630
1628
|
var TOOL_IN_BRACES = /\{\s*[a-z][A-Za-z0-9_]{2,}\s*(?:\([^()]*\))?\s*\}/g;
|
|
1631
1629
|
var FAKE_BUTTON_LINE = /^[ \t]*\[[^\][\n]{2,60}\][ \t]*$(?!\()/gm;
|
|
1632
|
-
function mapOutsideCode(
|
|
1633
|
-
return
|
|
1630
|
+
function mapOutsideCode(text3, transform) {
|
|
1631
|
+
return text3.split(/(```[\s\S]*?```|`[^`\n]*`)/g).map((chunk, index) => index % 2 === 1 ? chunk : transform(chunk)).join("");
|
|
1634
1632
|
}
|
|
1635
|
-
function sanitizeAssistantText(
|
|
1636
|
-
if (!
|
|
1633
|
+
function sanitizeAssistantText(text3) {
|
|
1634
|
+
if (!text3 || !text3.includes("{") && !text3.includes("[")) return text3;
|
|
1637
1635
|
const cleaned = mapOutsideCode(
|
|
1638
|
-
|
|
1636
|
+
text3,
|
|
1639
1637
|
(chunk) => chunk.replace(TOOL_IN_BRACES, "").replace(FAKE_BUTTON_LINE, "")
|
|
1640
1638
|
);
|
|
1641
|
-
if (cleaned ===
|
|
1639
|
+
if (cleaned === text3) return text3;
|
|
1642
1640
|
return cleaned.replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, "\n\n").replace(/^\n+/, "");
|
|
1643
1641
|
}
|
|
1644
1642
|
|
|
@@ -2567,8 +2565,8 @@ function useAsk() {
|
|
|
2567
2565
|
const queuePrompt = useChatStore((s) => s.queuePrompt);
|
|
2568
2566
|
const dismiss = useAssistantInviteStore((s) => s.dismiss);
|
|
2569
2567
|
return React133.useCallback(
|
|
2570
|
-
(
|
|
2571
|
-
const trimmed =
|
|
2568
|
+
(text3) => {
|
|
2569
|
+
const trimmed = text3.trim();
|
|
2572
2570
|
if (!trimmed) return;
|
|
2573
2571
|
dismiss();
|
|
2574
2572
|
queuePrompt(trimmed);
|
|
@@ -4210,539 +4208,6 @@ registerAIToolHandler(
|
|
|
4210
4208
|
"findTools",
|
|
4211
4209
|
(args, ctx) => resolveToolSearch(args, ctx.searchableTools ?? [], new Set(ctx.carriedTools ?? []))
|
|
4212
4210
|
);
|
|
4213
|
-
var UNIT_BOOTSTRAP_OBJECT = "rpc:unit_bootstrap";
|
|
4214
|
-
var UNIT_MODE_OBJECT = "tenants.unit_scoping_enabled";
|
|
4215
|
-
var SCOPED_RESOURCES_OBJECT = "scoped_resources";
|
|
4216
|
-
var UNIT_ACCESS_CHANGED = "core.unit-access.changed";
|
|
4217
|
-
function emitUnitAccessChanged(userId, unitId) {
|
|
4218
|
-
emitDomainEvent(
|
|
4219
|
-
UNIT_ACCESS_CHANGED,
|
|
4220
|
-
{ user_id: userId, unit_id: unitId },
|
|
4221
|
-
{ tenantId: getActiveTenantId() ?? null, subject: { type: "location", id: unitId } }
|
|
4222
|
-
);
|
|
4223
|
-
}
|
|
4224
|
-
function client() {
|
|
4225
|
-
return getSupabaseClientOptional();
|
|
4226
|
-
}
|
|
4227
|
-
function mapUnit(row) {
|
|
4228
|
-
return {
|
|
4229
|
-
id: row.id,
|
|
4230
|
-
tenantId: row.tenant_id,
|
|
4231
|
-
kind: row.kind ?? "branch",
|
|
4232
|
-
name: row.name,
|
|
4233
|
-
email: row.email ?? void 0,
|
|
4234
|
-
phone: row.phone ?? void 0,
|
|
4235
|
-
address: row.address ?? void 0,
|
|
4236
|
-
city: row.city ?? void 0,
|
|
4237
|
-
state: row.state ?? void 0,
|
|
4238
|
-
country: row.country ?? "BR",
|
|
4239
|
-
postalCode: row.postal_code ?? void 0,
|
|
4240
|
-
isHeadquarters: Boolean(row.is_headquarters),
|
|
4241
|
-
isActive: row.is_active !== false,
|
|
4242
|
-
tags: row.tags ?? [],
|
|
4243
|
-
notes: row.notes ?? void 0,
|
|
4244
|
-
metadata: row.metadata ?? {},
|
|
4245
|
-
createdAt: row.created_at,
|
|
4246
|
-
updatedAt: row.updated_at,
|
|
4247
|
-
parentId: row.parent_id ?? null,
|
|
4248
|
-
code: row.code ?? null,
|
|
4249
|
-
// numeric do Postgres chega como string no PostgREST; a aritmética de
|
|
4250
|
-
// distância precisa de número, e `Number(null)` é 0, que é uma coordenada
|
|
4251
|
-
// real no golfo da Guiné.
|
|
4252
|
-
latitude: row.latitude == null ? null : Number(row.latitude),
|
|
4253
|
-
longitude: row.longitude == null ? null : Number(row.longitude)
|
|
4254
|
-
};
|
|
4255
|
-
}
|
|
4256
|
-
async function fetchUnits(tenantId2) {
|
|
4257
|
-
const db2 = client();
|
|
4258
|
-
if (!db2) return [];
|
|
4259
|
-
const { data, error } = await db2.from("v_units").select("*").eq("tenant_id", tenantId2).order("is_headquarters", { ascending: false }).order("name");
|
|
4260
|
-
if (error) return [];
|
|
4261
|
-
return (data ?? []).map(mapUnit);
|
|
4262
|
-
}
|
|
4263
|
-
async function fetchMyBindings(userId, tenantId2) {
|
|
4264
|
-
const db2 = client();
|
|
4265
|
-
if (!db2) return [];
|
|
4266
|
-
const { data, error } = await db2.from("v_unit_members").select("location_id, role").eq("user_id", userId).eq("tenant_id", tenantId2);
|
|
4267
|
-
if (error) return [];
|
|
4268
|
-
return (data ?? []).map((r) => ({ locationId: r.location_id, role: r.role ?? null }));
|
|
4269
|
-
}
|
|
4270
|
-
async function fetchUnitBootstrap(tenantId2, deviceId) {
|
|
4271
|
-
const db2 = client();
|
|
4272
|
-
if (!db2) return null;
|
|
4273
|
-
if (isKnownMissing(UNIT_BOOTSTRAP_OBJECT)) return null;
|
|
4274
|
-
const { data, error } = await db2.rpc("unit_bootstrap", {
|
|
4275
|
-
p_tenant_id: tenantId2,
|
|
4276
|
-
p_device_id: deviceId ?? null
|
|
4277
|
-
});
|
|
4278
|
-
if (error) {
|
|
4279
|
-
rememberIfMissing(UNIT_BOOTSTRAP_OBJECT, error);
|
|
4280
|
-
return null;
|
|
4281
|
-
}
|
|
4282
|
-
if (!data) return null;
|
|
4283
|
-
const raw = data;
|
|
4284
|
-
return {
|
|
4285
|
-
mode: Boolean(raw.mode),
|
|
4286
|
-
units: (raw.units ?? []).map(mapUnit),
|
|
4287
|
-
bindings: (raw.bindings ?? []).map((r) => ({
|
|
4288
|
-
locationId: r.location_id,
|
|
4289
|
-
role: r.role ?? null
|
|
4290
|
-
})),
|
|
4291
|
-
scoped: Object.fromEntries(
|
|
4292
|
-
Object.entries(raw.scoped ?? {}).map(([table, v]) => [
|
|
4293
|
-
table,
|
|
4294
|
-
{ unitColumn: v?.unit_column ?? "unit_id", shareable: v?.shareable !== false }
|
|
4295
|
-
])
|
|
4296
|
-
),
|
|
4297
|
-
// user_unit_ids_in walks the tree with UNION over (id, depth): a branch
|
|
4298
|
-
// reached directly AND through its HQ comes back twice.
|
|
4299
|
-
reachable: Array.isArray(raw.reachable) ? [...new Set(raw.reachable)] : void 0,
|
|
4300
|
-
devicePin: { set: Boolean(raw.device_pin_set), unitId: raw.device_pin ?? null },
|
|
4301
|
-
accountPin: { set: Boolean(raw.account_pin_set), unitId: raw.account_pin ?? null }
|
|
4302
|
-
};
|
|
4303
|
-
}
|
|
4304
|
-
async function saveEntryUnit(tenantId2, unitId, deviceId) {
|
|
4305
|
-
const db2 = client();
|
|
4306
|
-
if (!db2 || !deviceId) return;
|
|
4307
|
-
await db2.rpc("set_entry_unit", {
|
|
4308
|
-
p_tenant_id: tenantId2,
|
|
4309
|
-
p_unit_id: unitId ?? null,
|
|
4310
|
-
p_device_id: deviceId
|
|
4311
|
-
});
|
|
4312
|
-
}
|
|
4313
|
-
async function fetchUnitMembers(unitId) {
|
|
4314
|
-
const db2 = client();
|
|
4315
|
-
if (!db2) return [];
|
|
4316
|
-
const { data, error } = await db2.from("v_unit_members").select("id, user_id, role, created_at").eq("location_id", unitId).order("created_at");
|
|
4317
|
-
if (error) return [];
|
|
4318
|
-
return (data ?? []).map((r) => ({
|
|
4319
|
-
id: r.id,
|
|
4320
|
-
userId: r.user_id,
|
|
4321
|
-
role: r.role ?? null,
|
|
4322
|
-
since: r.created_at ?? null
|
|
4323
|
-
}));
|
|
4324
|
-
}
|
|
4325
|
-
async function fetchMemberActivity(tenantId2) {
|
|
4326
|
-
const db2 = client();
|
|
4327
|
-
if (!db2) return {};
|
|
4328
|
-
const { data, error } = await db2.rpc("tenant_member_activity", { p_tenant_id: tenantId2 });
|
|
4329
|
-
if (error) return {};
|
|
4330
|
-
const out = {};
|
|
4331
|
-
for (const r of data ?? []) {
|
|
4332
|
-
out[r.user_id] = {
|
|
4333
|
-
lastSignInAt: r.last_sign_in_at ?? null,
|
|
4334
|
-
signedUpAt: r.signed_up_at ?? null
|
|
4335
|
-
};
|
|
4336
|
-
}
|
|
4337
|
-
return out;
|
|
4338
|
-
}
|
|
4339
|
-
async function fetchMemberUnits(userId, tenantId2) {
|
|
4340
|
-
const tenant = getActiveTenantId();
|
|
4341
|
-
if (!tenant) return [];
|
|
4342
|
-
return fetchMyBindings(userId, tenant);
|
|
4343
|
-
}
|
|
4344
|
-
async function bindUserToUnit(unitId, userId, role) {
|
|
4345
|
-
const db2 = client();
|
|
4346
|
-
if (!db2) throw new Error("sem conex\xE3o");
|
|
4347
|
-
const { error } = await db2.rpc("unit_member_set", { p_unit: unitId, p_user: userId, p_role: role });
|
|
4348
|
-
if (error) throw error;
|
|
4349
|
-
emitUnitAccessChanged(userId, unitId);
|
|
4350
|
-
}
|
|
4351
|
-
async function unbindUserFromUnit(unitId, userId) {
|
|
4352
|
-
const db2 = client();
|
|
4353
|
-
if (!db2) throw new Error("sem conex\xE3o");
|
|
4354
|
-
const { error } = await db2.rpc("unit_member_remove", { p_unit: unitId, p_user: userId });
|
|
4355
|
-
if (error) throw error;
|
|
4356
|
-
emitUnitAccessChanged(userId, unitId);
|
|
4357
|
-
}
|
|
4358
|
-
async function fetchUserIdForPerson(personId) {
|
|
4359
|
-
const db2 = client();
|
|
4360
|
-
if (!db2) return null;
|
|
4361
|
-
const { data, error } = await db2.from("v_team_members").select("user_id").eq("person_id", personId).maybeSingle();
|
|
4362
|
-
if (error || !data) return null;
|
|
4363
|
-
return data.user_id ?? null;
|
|
4364
|
-
}
|
|
4365
|
-
async function fetchScopedResources() {
|
|
4366
|
-
const db2 = client();
|
|
4367
|
-
if (!db2) return {};
|
|
4368
|
-
if (isKnownMissing(SCOPED_RESOURCES_OBJECT)) return {};
|
|
4369
|
-
const { data, error } = await db2.from("scoped_resources").select("resource_table, unit_column, shareable");
|
|
4370
|
-
if (error) {
|
|
4371
|
-
rememberIfMissing(SCOPED_RESOURCES_OBJECT, error);
|
|
4372
|
-
return {};
|
|
4373
|
-
}
|
|
4374
|
-
const out = {};
|
|
4375
|
-
for (const r of data ?? []) {
|
|
4376
|
-
out[r.resource_table] = {
|
|
4377
|
-
unitColumn: r.unit_column ?? "unit_id",
|
|
4378
|
-
shareable: r.shareable !== false
|
|
4379
|
-
};
|
|
4380
|
-
}
|
|
4381
|
-
return out;
|
|
4382
|
-
}
|
|
4383
|
-
async function fetchUnitMode(tenantId2) {
|
|
4384
|
-
const db2 = client();
|
|
4385
|
-
if (!db2) return { installed: false, on: false };
|
|
4386
|
-
if (isKnownMissing(UNIT_MODE_OBJECT)) return { installed: false, on: false };
|
|
4387
|
-
const { data, error } = await db2.from("tenants").select("unit_scoping_enabled").eq("id", tenantId2).maybeSingle();
|
|
4388
|
-
if (error) {
|
|
4389
|
-
rememberIfMissing(UNIT_MODE_OBJECT, error);
|
|
4390
|
-
return { installed: false, on: false };
|
|
4391
|
-
}
|
|
4392
|
-
return { installed: true, on: Boolean(data?.unit_scoping_enabled) };
|
|
4393
|
-
}
|
|
4394
|
-
async function setUnitModeRemote(tenantId2, on) {
|
|
4395
|
-
const db2 = client();
|
|
4396
|
-
if (!db2) throw new Error("sem conex\xE3o");
|
|
4397
|
-
const { error } = await db2.from("tenants").update({ unit_scoping_enabled: on }).eq("id", tenantId2);
|
|
4398
|
-
if (error) throw error;
|
|
4399
|
-
}
|
|
4400
|
-
async function bindAllMembersTo(tenantId2, unitId) {
|
|
4401
|
-
const db2 = client();
|
|
4402
|
-
if (!db2) return 0;
|
|
4403
|
-
const { data } = await db2.from("v_team_members").select("user_id").eq("tenant_id", tenantId2);
|
|
4404
|
-
const userIds = (data ?? []).map((m) => m.user_id);
|
|
4405
|
-
if (userIds.length === 0) return 0;
|
|
4406
|
-
for (const userId of userIds) {
|
|
4407
|
-
const { error } = await db2.rpc("unit_member_set", { p_unit: unitId, p_user: userId, p_role: null });
|
|
4408
|
-
if (error) throw error;
|
|
4409
|
-
}
|
|
4410
|
-
emitUnitAccessChanged(null, unitId);
|
|
4411
|
-
return userIds.length;
|
|
4412
|
-
}
|
|
4413
|
-
async function countUnboundMembers(tenantId2) {
|
|
4414
|
-
const db2 = client();
|
|
4415
|
-
if (!db2) return 0;
|
|
4416
|
-
const { data: members } = await db2.from("v_team_members").select("user_id").eq("tenant_id", tenantId2);
|
|
4417
|
-
const { data: units } = await db2.from("v_units").select("id").eq("tenant_id", tenantId2);
|
|
4418
|
-
const unitIds = (units ?? []).map((u) => u.id);
|
|
4419
|
-
if (unitIds.length === 0) return (members ?? []).length;
|
|
4420
|
-
const { data: bound } = await db2.from("v_unit_members").select("user_id").in("location_id", unitIds);
|
|
4421
|
-
const boundSet = new Set((bound ?? []).map((b) => b.user_id));
|
|
4422
|
-
return (members ?? []).filter((m) => !boundSet.has(m.user_id)).length;
|
|
4423
|
-
}
|
|
4424
|
-
|
|
4425
|
-
// src/units/cache.ts
|
|
4426
|
-
var STORAGE_KEY = "fayz:units-snapshot";
|
|
4427
|
-
var VERSION = 1;
|
|
4428
|
-
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
4429
|
-
var MAX_BYTES = 256 * 1024;
|
|
4430
|
-
function storage() {
|
|
4431
|
-
try {
|
|
4432
|
-
if (typeof localStorage === "undefined") return null;
|
|
4433
|
-
return localStorage;
|
|
4434
|
-
} catch {
|
|
4435
|
-
return null;
|
|
4436
|
-
}
|
|
4437
|
-
}
|
|
4438
|
-
function readUnitSnapshot() {
|
|
4439
|
-
const store = storage();
|
|
4440
|
-
if (!store) return null;
|
|
4441
|
-
try {
|
|
4442
|
-
const raw = store.getItem(STORAGE_KEY);
|
|
4443
|
-
if (!raw) return null;
|
|
4444
|
-
const snapshot = JSON.parse(raw);
|
|
4445
|
-
if (snapshot?.version !== VERSION || !snapshot.tenantId || !snapshot.userId) return null;
|
|
4446
|
-
const age = Date.now() - snapshot.savedAt;
|
|
4447
|
-
if (age < 0 || age > MAX_AGE_MS) {
|
|
4448
|
-
store.removeItem(STORAGE_KEY);
|
|
4449
|
-
return null;
|
|
4450
|
-
}
|
|
4451
|
-
return snapshot;
|
|
4452
|
-
} catch {
|
|
4453
|
-
return null;
|
|
4454
|
-
}
|
|
4455
|
-
}
|
|
4456
|
-
function saveUnitSnapshot(input) {
|
|
4457
|
-
const store = storage();
|
|
4458
|
-
if (!store) return;
|
|
4459
|
-
try {
|
|
4460
|
-
const raw = JSON.stringify({ ...input, version: VERSION, savedAt: Date.now() });
|
|
4461
|
-
if (raw.length > MAX_BYTES) return;
|
|
4462
|
-
store.setItem(STORAGE_KEY, raw);
|
|
4463
|
-
} catch {
|
|
4464
|
-
}
|
|
4465
|
-
}
|
|
4466
|
-
function patchUnitSnapshotActive(activeUnitId) {
|
|
4467
|
-
const store = storage();
|
|
4468
|
-
const current2 = readUnitSnapshot();
|
|
4469
|
-
if (!store || !current2) return;
|
|
4470
|
-
try {
|
|
4471
|
-
store.setItem(STORAGE_KEY, JSON.stringify({ ...current2, activeUnitId }));
|
|
4472
|
-
} catch {
|
|
4473
|
-
}
|
|
4474
|
-
}
|
|
4475
|
-
function clearUnitSnapshot() {
|
|
4476
|
-
try {
|
|
4477
|
-
storage()?.removeItem(STORAGE_KEY);
|
|
4478
|
-
} catch {
|
|
4479
|
-
}
|
|
4480
|
-
}
|
|
4481
|
-
|
|
4482
|
-
// src/units/device.ts
|
|
4483
|
-
var STORAGE_KEY2 = "fayz:device-id";
|
|
4484
|
-
var cached = null;
|
|
4485
|
-
function randomId() {
|
|
4486
|
-
try {
|
|
4487
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
4488
|
-
return crypto.randomUUID();
|
|
4489
|
-
}
|
|
4490
|
-
} catch {
|
|
4491
|
-
}
|
|
4492
|
-
return `d-${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
4493
|
-
}
|
|
4494
|
-
function getDeviceId() {
|
|
4495
|
-
if (cached) return cached;
|
|
4496
|
-
try {
|
|
4497
|
-
if (typeof localStorage === "undefined") return void 0;
|
|
4498
|
-
const existing = localStorage.getItem(STORAGE_KEY2);
|
|
4499
|
-
if (existing) {
|
|
4500
|
-
cached = existing;
|
|
4501
|
-
return existing;
|
|
4502
|
-
}
|
|
4503
|
-
const fresh = randomId();
|
|
4504
|
-
localStorage.setItem(STORAGE_KEY2, fresh);
|
|
4505
|
-
cached = fresh;
|
|
4506
|
-
return fresh;
|
|
4507
|
-
} catch {
|
|
4508
|
-
return void 0;
|
|
4509
|
-
}
|
|
4510
|
-
}
|
|
4511
|
-
|
|
4512
|
-
// src/lib/dedup.ts
|
|
4513
|
-
var inflight = /* @__PURE__ */ new Map();
|
|
4514
|
-
function dedup(key, fn) {
|
|
4515
|
-
const existing = inflight.get(key);
|
|
4516
|
-
if (existing) return existing;
|
|
4517
|
-
const promise = fn().finally(() => {
|
|
4518
|
-
inflight.delete(key);
|
|
4519
|
-
});
|
|
4520
|
-
inflight.set(key, promise);
|
|
4521
|
-
return promise;
|
|
4522
|
-
}
|
|
4523
|
-
|
|
4524
|
-
// src/units/entry.ts
|
|
4525
|
-
function resolveEntry(reachable, pins) {
|
|
4526
|
-
const canStand = (id) => id != null && reachable.includes(id);
|
|
4527
|
-
const ladder = [
|
|
4528
|
-
[pins.device, "device"],
|
|
4529
|
-
[pins.account, "account"]
|
|
4530
|
-
];
|
|
4531
|
-
for (const [pin, reason] of ladder) {
|
|
4532
|
-
if (!pin?.set) continue;
|
|
4533
|
-
if (pin.unitId === null) return { unitId: void 0, reason: "all", needsChoice: false };
|
|
4534
|
-
if (canStand(pin.unitId)) return { unitId: pin.unitId, reason, needsChoice: false };
|
|
4535
|
-
}
|
|
4536
|
-
if (canStand(pins.legacy)) return { unitId: pins.legacy, reason: "device", needsChoice: false };
|
|
4537
|
-
if (reachable.length === 1) return { unitId: reachable[0], reason: "only", needsChoice: false };
|
|
4538
|
-
return { unitId: void 0, reason: "all", needsChoice: reachable.length > 1 };
|
|
4539
|
-
}
|
|
4540
|
-
|
|
4541
|
-
// src/units/store.ts
|
|
4542
|
-
var LEGACY_KEY = "saas-core:current-location";
|
|
4543
|
-
function legacyPin() {
|
|
4544
|
-
try {
|
|
4545
|
-
return localStorage.getItem(LEGACY_KEY) ?? void 0;
|
|
4546
|
-
} catch {
|
|
4547
|
-
return void 0;
|
|
4548
|
-
}
|
|
4549
|
-
}
|
|
4550
|
-
function buildTree(units) {
|
|
4551
|
-
const nodes = /* @__PURE__ */ new Map();
|
|
4552
|
-
for (const u of units) nodes.set(u.id, { ...u, children: [] });
|
|
4553
|
-
const roots = [];
|
|
4554
|
-
for (const node of nodes.values()) {
|
|
4555
|
-
const parent = node.parentId ? nodes.get(node.parentId) : void 0;
|
|
4556
|
-
if (parent && parent.id !== node.id) parent.children.push(node);
|
|
4557
|
-
else roots.push(node);
|
|
4558
|
-
}
|
|
4559
|
-
return roots;
|
|
4560
|
-
}
|
|
4561
|
-
function expandDown(units, seeds) {
|
|
4562
|
-
const childrenOf = /* @__PURE__ */ new Map();
|
|
4563
|
-
for (const u of units) {
|
|
4564
|
-
if (!u.parentId) continue;
|
|
4565
|
-
const list = childrenOf.get(u.parentId) ?? [];
|
|
4566
|
-
list.push(u.id);
|
|
4567
|
-
childrenOf.set(u.parentId, list);
|
|
4568
|
-
}
|
|
4569
|
-
const out = /* @__PURE__ */ new Set();
|
|
4570
|
-
const queue = [...seeds];
|
|
4571
|
-
while (queue.length > 0) {
|
|
4572
|
-
const id = queue.shift();
|
|
4573
|
-
if (out.has(id)) continue;
|
|
4574
|
-
out.add(id);
|
|
4575
|
-
for (const child of childrenOf.get(id) ?? []) queue.push(child);
|
|
4576
|
-
}
|
|
4577
|
-
return [...out];
|
|
4578
|
-
}
|
|
4579
|
-
function branchesOnly(ids, byId) {
|
|
4580
|
-
return ids.filter((id) => byId[id]?.kind !== "region");
|
|
4581
|
-
}
|
|
4582
|
-
var useUnitStore = create((set, get) => ({
|
|
4583
|
-
units: [],
|
|
4584
|
-
byId: {},
|
|
4585
|
-
tree: [],
|
|
4586
|
-
myUnitIds: [],
|
|
4587
|
-
myBindings: [],
|
|
4588
|
-
activeUnitId: void 0,
|
|
4589
|
-
entryReason: "all",
|
|
4590
|
-
unitMode: false,
|
|
4591
|
-
loading: false,
|
|
4592
|
-
resolved: false,
|
|
4593
|
-
needsChoice: false,
|
|
4594
|
-
loadedFor: null,
|
|
4595
|
-
// Uma chamada por conta, por mais telas que peçam.
|
|
4596
|
-
//
|
|
4597
|
-
// Dez componentes chamam `useUnitBootstrap` — o seletor, a linha de
|
|
4598
|
-
// identidade, o rodapé do registro, a aba de unidades de uma pessoa — e todos
|
|
4599
|
-
// montam no mesmo quadro. A guarda anterior era `loadedFor === tenantId &&
|
|
4600
|
-
// !loading`, que deixa passar exatamente enquanto a primeira chamada está no
|
|
4601
|
-
// ar: o segundo componente via a conta já marcada, via `loading` ligado, e a
|
|
4602
|
-
// condição inteira dava falso. Resultado: uma requisição por tela, todas
|
|
4603
|
-
// idênticas. Juntar cinco viagens numa e depois disparar essa uma cinco vezes
|
|
4604
|
-
// não economiza nada.
|
|
4605
|
-
//
|
|
4606
|
-
// `dedup` é o mesmo utilitário que a tela de equipe já usa: quem chegar
|
|
4607
|
-
// enquanto a primeira está no ar recebe a MESMA promessa em vez de abrir
|
|
4608
|
-
// outra.
|
|
4609
|
-
async load(tenantId2, userId) {
|
|
4610
|
-
if (!tenantId2) return;
|
|
4611
|
-
if (get().loadedFor === tenantId2 && !get().loading) return;
|
|
4612
|
-
return dedup(`units:${tenantId2}:${userId ?? ""}`, () => loadOnce(tenantId2, userId, set, get));
|
|
4613
|
-
},
|
|
4614
|
-
setActive(unitId, reason = "manual") {
|
|
4615
|
-
setActiveUnitId(unitId);
|
|
4616
|
-
set({ activeUnitId: unitId, entryReason: reason, needsChoice: false });
|
|
4617
|
-
patchUnitSnapshotActive(unitId ?? null);
|
|
4618
|
-
const tenantId2 = get().loadedFor;
|
|
4619
|
-
if (tenantId2) void saveEntryUnit(tenantId2, unitId, getDeviceId());
|
|
4620
|
-
},
|
|
4621
|
-
setMode(on) {
|
|
4622
|
-
setUnitMode(on);
|
|
4623
|
-
set({ unitMode: on });
|
|
4624
|
-
if (!on) {
|
|
4625
|
-
setActiveUnitId(void 0);
|
|
4626
|
-
set({ activeUnitId: void 0, entryReason: "all", needsChoice: false });
|
|
4627
|
-
patchUnitSnapshotActive(null);
|
|
4628
|
-
}
|
|
4629
|
-
},
|
|
4630
|
-
reset() {
|
|
4631
|
-
clearUnitSnapshot();
|
|
4632
|
-
resetActiveUnit();
|
|
4633
|
-
set({
|
|
4634
|
-
units: [],
|
|
4635
|
-
byId: {},
|
|
4636
|
-
tree: [],
|
|
4637
|
-
myUnitIds: [],
|
|
4638
|
-
myBindings: [],
|
|
4639
|
-
activeUnitId: void 0,
|
|
4640
|
-
entryReason: "all",
|
|
4641
|
-
unitMode: false,
|
|
4642
|
-
loading: false,
|
|
4643
|
-
resolved: false,
|
|
4644
|
-
needsChoice: false,
|
|
4645
|
-
loadedFor: null
|
|
4646
|
-
});
|
|
4647
|
-
}
|
|
4648
|
-
}));
|
|
4649
|
-
async function loadOnce(tenantId2, userId, set, get) {
|
|
4650
|
-
set({ loading: true, loadedFor: tenantId2 });
|
|
4651
|
-
try {
|
|
4652
|
-
const deviceId = getDeviceId();
|
|
4653
|
-
const boot = await fetchUnitBootstrap(tenantId2, deviceId);
|
|
4654
|
-
let mode;
|
|
4655
|
-
let units;
|
|
4656
|
-
let bindings;
|
|
4657
|
-
let scoped;
|
|
4658
|
-
let reachableFromServer;
|
|
4659
|
-
if (boot) {
|
|
4660
|
-
;
|
|
4661
|
-
[mode, units, bindings, scoped] = [boot.mode, boot.units, boot.bindings, boot.scoped];
|
|
4662
|
-
reachableFromServer = boot.reachable;
|
|
4663
|
-
} else {
|
|
4664
|
-
const modeResult = await fetchUnitMode(tenantId2);
|
|
4665
|
-
mode = modeResult.on;
|
|
4666
|
-
if (!modeResult.installed) {
|
|
4667
|
-
units = [];
|
|
4668
|
-
bindings = [];
|
|
4669
|
-
scoped = {};
|
|
4670
|
-
} else {
|
|
4671
|
-
;
|
|
4672
|
-
[units, bindings, scoped] = await Promise.all([
|
|
4673
|
-
fetchUnits(tenantId2),
|
|
4674
|
-
userId ? fetchMyBindings(userId, tenantId2) : Promise.resolve([]),
|
|
4675
|
-
mode ? fetchScopedResources() : Promise.resolve({})
|
|
4676
|
-
]);
|
|
4677
|
-
}
|
|
4678
|
-
}
|
|
4679
|
-
setScopedResources(scoped);
|
|
4680
|
-
const byId = {};
|
|
4681
|
-
for (const u of units) byId[u.id] = u;
|
|
4682
|
-
const reachable = reachableFromServer ? branchesOnly(reachableFromServer.filter((id) => byId[id]), byId) : branchesOnly(expandDown(units, bindings.map((b) => b.locationId)), byId);
|
|
4683
|
-
const entry = resolveEntry(reachable, {
|
|
4684
|
-
device: boot?.devicePin,
|
|
4685
|
-
account: boot?.accountPin,
|
|
4686
|
-
legacy: legacyPin()
|
|
4687
|
-
});
|
|
4688
|
-
setUnitMode(mode);
|
|
4689
|
-
setActiveUnitId(entry.unitId);
|
|
4690
|
-
set({
|
|
4691
|
-
units,
|
|
4692
|
-
byId,
|
|
4693
|
-
tree: buildTree(units),
|
|
4694
|
-
myUnitIds: reachable,
|
|
4695
|
-
myBindings: bindings,
|
|
4696
|
-
unitMode: mode,
|
|
4697
|
-
activeUnitId: entry.unitId,
|
|
4698
|
-
entryReason: entry.reason,
|
|
4699
|
-
needsChoice: entry.needsChoice,
|
|
4700
|
-
loading: false,
|
|
4701
|
-
resolved: true
|
|
4702
|
-
});
|
|
4703
|
-
if (userId) {
|
|
4704
|
-
saveUnitSnapshot({
|
|
4705
|
-
userId,
|
|
4706
|
-
tenantId: tenantId2,
|
|
4707
|
-
mode,
|
|
4708
|
-
units,
|
|
4709
|
-
bindings,
|
|
4710
|
-
myUnitIds: reachable,
|
|
4711
|
-
activeUnitId: entry.unitId ?? null,
|
|
4712
|
-
scoped
|
|
4713
|
-
});
|
|
4714
|
-
}
|
|
4715
|
-
} finally {
|
|
4716
|
-
if (get().loading) set({ loading: false });
|
|
4717
|
-
}
|
|
4718
|
-
}
|
|
4719
|
-
(function hydrate() {
|
|
4720
|
-
const snapshot = readUnitSnapshot();
|
|
4721
|
-
if (!snapshot) return;
|
|
4722
|
-
const org = readOrgSnapshot();
|
|
4723
|
-
if (!org || org.org?.id !== snapshot.tenantId || org.userId !== snapshot.userId) {
|
|
4724
|
-
clearUnitSnapshot();
|
|
4725
|
-
return;
|
|
4726
|
-
}
|
|
4727
|
-
const byId = {};
|
|
4728
|
-
for (const u of snapshot.units) byId[u.id] = u;
|
|
4729
|
-
const active2 = snapshot.activeUnitId ?? void 0;
|
|
4730
|
-
const standable = active2 && snapshot.myUnitIds.includes(active2) ? active2 : void 0;
|
|
4731
|
-
setScopedResources(snapshot.scoped);
|
|
4732
|
-
setUnitMode(snapshot.mode);
|
|
4733
|
-
setActiveUnitId(standable);
|
|
4734
|
-
useUnitStore.setState({
|
|
4735
|
-
units: snapshot.units,
|
|
4736
|
-
byId,
|
|
4737
|
-
tree: buildTree(snapshot.units),
|
|
4738
|
-
myUnitIds: snapshot.myUnitIds,
|
|
4739
|
-
myBindings: snapshot.bindings,
|
|
4740
|
-
unitMode: snapshot.mode,
|
|
4741
|
-
activeUnitId: standable,
|
|
4742
|
-
entryReason: standable ? "device" : "all",
|
|
4743
|
-
resolved: true
|
|
4744
|
-
});
|
|
4745
|
-
})();
|
|
4746
4211
|
function useSystemPermission() {
|
|
4747
4212
|
const currentProfile = usePermissionsStore((s) => s.currentProfile);
|
|
4748
4213
|
return useCallback(
|
|
@@ -5702,10 +5167,10 @@ function toInstalled(definition, status) {
|
|
|
5702
5167
|
}
|
|
5703
5168
|
var connectionsFlight = null;
|
|
5704
5169
|
var statusFlights = /* @__PURE__ */ new Map();
|
|
5705
|
-
function loadConnections(tenantId2, ids,
|
|
5170
|
+
function loadConnections(tenantId2, ids, client2) {
|
|
5706
5171
|
const flight = connectionsFlight;
|
|
5707
5172
|
if (flight && flight.tenantId === tenantId2 && ids.every((id) => flight.ids.has(id))) return flight.promise;
|
|
5708
|
-
const promise = listConnections(ids, { tenantId: tenantId2, client:
|
|
5173
|
+
const promise = listConnections(ids, { tenantId: tenantId2, client: client2 }).catch(() => /* @__PURE__ */ new Map());
|
|
5709
5174
|
const entry = { tenantId: tenantId2, ids: new Set(ids), promise };
|
|
5710
5175
|
connectionsFlight = entry;
|
|
5711
5176
|
void promise.finally(() => {
|
|
@@ -5769,17 +5234,17 @@ function describeFayzAgentGap(override) {
|
|
|
5769
5234
|
if (!(override?.publishableKey ?? env("VITE_FAYZ_AGENT_KEY"))) missing.push("VITE_FAYZ_AGENT_KEY");
|
|
5770
5235
|
return missing.length ? { missing } : null;
|
|
5771
5236
|
}
|
|
5772
|
-
var
|
|
5237
|
+
var cached = null;
|
|
5773
5238
|
function getFayzAgentClient(connection) {
|
|
5774
5239
|
const key = `${connection.apiBaseUrl}|${connection.projectId}|${connection.publishableKey}`;
|
|
5775
|
-
if (
|
|
5776
|
-
const
|
|
5240
|
+
if (cached?.key === key) return cached.client;
|
|
5241
|
+
const client2 = createFayzAgentClient({
|
|
5777
5242
|
baseUrl: connection.apiBaseUrl,
|
|
5778
5243
|
projectId: connection.projectId,
|
|
5779
5244
|
publishableKey: connection.publishableKey
|
|
5780
5245
|
});
|
|
5781
|
-
|
|
5782
|
-
return
|
|
5246
|
+
cached = { key, client: client2 };
|
|
5247
|
+
return client2;
|
|
5783
5248
|
}
|
|
5784
5249
|
|
|
5785
5250
|
// src/components/connect/useConnectors.ts
|
|
@@ -6749,8 +6214,8 @@ function summaryRows(values) {
|
|
|
6749
6214
|
const rows = [];
|
|
6750
6215
|
const push = (label3, raw) => {
|
|
6751
6216
|
if (raw === void 0 || raw === null || raw === "") return;
|
|
6752
|
-
const
|
|
6753
|
-
if (
|
|
6217
|
+
const text3 = Array.isArray(raw) ? raw.join(", ") : String(raw);
|
|
6218
|
+
if (text3.trim()) rows.push({ label: label3, value: text3 });
|
|
6754
6219
|
};
|
|
6755
6220
|
push(tl("Workspace", "\xC1rea de trabalho"), values[NAME_FIELD]);
|
|
6756
6221
|
push(tl("Contact", "Contato"), values["workspace.email"]);
|
|
@@ -7181,9 +6646,9 @@ function startNativeDictation(locale, cb) {
|
|
|
7181
6646
|
let interim = "";
|
|
7182
6647
|
for (let i = event.resultIndex; i < event.results.length; i++) {
|
|
7183
6648
|
const result = event.results[i];
|
|
7184
|
-
const
|
|
7185
|
-
if (result.isFinal) finalText +=
|
|
7186
|
-
else interim +=
|
|
6649
|
+
const text3 = result[0]?.transcript ?? "";
|
|
6650
|
+
if (result.isFinal) finalText += text3;
|
|
6651
|
+
else interim += text3;
|
|
7187
6652
|
}
|
|
7188
6653
|
cb.onInterim?.((finalText + interim).trim());
|
|
7189
6654
|
};
|
|
@@ -7286,9 +6751,9 @@ function pickVoice(locale) {
|
|
|
7286
6751
|
function stopSpeaking() {
|
|
7287
6752
|
if (isSpeechOutputSupported()) window.speechSynthesis.cancel();
|
|
7288
6753
|
}
|
|
7289
|
-
function speak(
|
|
6754
|
+
function speak(text3, options = { locale: "pt-BR" }) {
|
|
7290
6755
|
if (!isSpeechOutputSupported()) return;
|
|
7291
|
-
const content =
|
|
6756
|
+
const content = text3.trim();
|
|
7292
6757
|
if (!content) return;
|
|
7293
6758
|
window.speechSynthesis.cancel();
|
|
7294
6759
|
const utterance = new SpeechSynthesisUtterance(content);
|
|
@@ -7418,7 +6883,7 @@ function useChat(options) {
|
|
|
7418
6883
|
searchableTools: searchable,
|
|
7419
6884
|
carriedTools: [...pinned]
|
|
7420
6885
|
};
|
|
7421
|
-
const
|
|
6886
|
+
const client2 = getFayzAgentClient(activeConnection);
|
|
7422
6887
|
const upcoming = Array.from({ length: 7 }, (_, i) => {
|
|
7423
6888
|
const d = new Date(Date.now() + (i + 1) * 864e5);
|
|
7424
6889
|
return `${d.toLocaleDateString("pt-BR", { weekday: "long" })}=${d.toISOString().slice(0, 10)}`;
|
|
@@ -7449,7 +6914,7 @@ function useChat(options) {
|
|
|
7449
6914
|
for (let round = 0; round <= MAX_TOOL_ROUNDS; round++) {
|
|
7450
6915
|
toolset = buildToolset();
|
|
7451
6916
|
toolContext.writeTools = toolset.map((t2) => toolByName.get(t2.name)).filter((d) => d?.mode === "persist").map((d) => ({ name: d.name, action: d.permission?.action }));
|
|
7452
|
-
const response = await
|
|
6917
|
+
const response = await client2.chatStream({
|
|
7453
6918
|
message,
|
|
7454
6919
|
toolResults,
|
|
7455
6920
|
confirmAction,
|
|
@@ -7661,8 +7126,8 @@ ${JSON.stringify(snapshot.length === 1 ? snapshot[0] : snapshot)}` : void 0
|
|
|
7661
7126
|
return;
|
|
7662
7127
|
}
|
|
7663
7128
|
const data = await response.json();
|
|
7664
|
-
const
|
|
7665
|
-
store.updateLastAssistant(
|
|
7129
|
+
const text3 = data.choices?.[0]?.message?.content ?? data.content ?? "No response.";
|
|
7130
|
+
store.updateLastAssistant(text3);
|
|
7666
7131
|
} catch {
|
|
7667
7132
|
store.updateLastAssistant("Sorry, I could not connect. Please try again later.");
|
|
7668
7133
|
} finally {
|
|
@@ -7813,12 +7278,12 @@ var AGENT_WAIT_MS = 2500;
|
|
|
7813
7278
|
function prefersReducedMotion2() {
|
|
7814
7279
|
return typeof window !== "undefined" && !!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
7815
7280
|
}
|
|
7816
|
-
function TypewriterText({ text:
|
|
7281
|
+
function TypewriterText({ text: text3, speed = 26, onDone }) {
|
|
7817
7282
|
const [displayed, setDisplayed] = React133.useState("");
|
|
7818
7283
|
const indexRef = React133.useRef(0);
|
|
7819
7284
|
React133.useEffect(() => {
|
|
7820
7285
|
if (prefersReducedMotion2()) {
|
|
7821
|
-
setDisplayed(
|
|
7286
|
+
setDisplayed(text3);
|
|
7822
7287
|
onDone?.();
|
|
7823
7288
|
return;
|
|
7824
7289
|
}
|
|
@@ -7826,18 +7291,18 @@ function TypewriterText({ text: text2, speed = 26, onDone }) {
|
|
|
7826
7291
|
indexRef.current = 0;
|
|
7827
7292
|
const interval = setInterval(() => {
|
|
7828
7293
|
indexRef.current++;
|
|
7829
|
-
if (indexRef.current >
|
|
7294
|
+
if (indexRef.current > text3.length) {
|
|
7830
7295
|
clearInterval(interval);
|
|
7831
7296
|
onDone?.();
|
|
7832
7297
|
return;
|
|
7833
7298
|
}
|
|
7834
|
-
setDisplayed(
|
|
7299
|
+
setDisplayed(text3.slice(0, indexRef.current));
|
|
7835
7300
|
}, speed);
|
|
7836
7301
|
return () => clearInterval(interval);
|
|
7837
|
-
}, [
|
|
7302
|
+
}, [text3, speed]);
|
|
7838
7303
|
return /* @__PURE__ */ jsxs("span", { children: [
|
|
7839
7304
|
displayed,
|
|
7840
|
-
displayed.length <
|
|
7305
|
+
displayed.length < text3.length && /* @__PURE__ */ jsx("span", { className: "ml-0.5 -mb-px inline-block h-3 w-[2px] bg-current/60 motion-safe:animate-pulse" })
|
|
7841
7306
|
] });
|
|
7842
7307
|
}
|
|
7843
7308
|
var STYLE_ID = "chat-fab-anims";
|
|
@@ -9816,14 +9281,14 @@ function SettingRow({
|
|
|
9816
9281
|
}
|
|
9817
9282
|
);
|
|
9818
9283
|
default: {
|
|
9819
|
-
const
|
|
9820
|
-
const bad = !matchesPattern(setting,
|
|
9284
|
+
const text3 = typeof value === "string" ? value : "";
|
|
9285
|
+
const bad = !matchesPattern(setting, text3);
|
|
9821
9286
|
return /* @__PURE__ */ jsx(
|
|
9822
9287
|
TextRow,
|
|
9823
9288
|
{
|
|
9824
9289
|
label: setting.label,
|
|
9825
9290
|
description: description || void 0,
|
|
9826
|
-
value:
|
|
9291
|
+
value: text3,
|
|
9827
9292
|
placeholder: setting.placeholder,
|
|
9828
9293
|
hint: setting.patternHint,
|
|
9829
9294
|
invalid: bad,
|
|
@@ -10566,10 +10031,10 @@ function useDictation({
|
|
|
10566
10031
|
sessionRef.current = startDictation(
|
|
10567
10032
|
{ locale: resolvedLocale, transcribeEndpoint },
|
|
10568
10033
|
{
|
|
10569
|
-
onInterim: (
|
|
10570
|
-
onFinal: (
|
|
10034
|
+
onInterim: (text3) => callbacks.current.onInterim?.(text3),
|
|
10035
|
+
onFinal: (text3) => {
|
|
10571
10036
|
finish();
|
|
10572
|
-
if (
|
|
10037
|
+
if (text3) callbacks.current.onTranscript(text3);
|
|
10573
10038
|
},
|
|
10574
10039
|
onError: (code) => {
|
|
10575
10040
|
sessionRef.current = null;
|
|
@@ -10892,8 +10357,8 @@ function ChatComposer({
|
|
|
10892
10357
|
const parsing = attachments.some((a) => a.status === "parsing");
|
|
10893
10358
|
const readyAttachments = attachments.filter((a) => a.status === "ready").length;
|
|
10894
10359
|
const submit = React133.useCallback(
|
|
10895
|
-
(
|
|
10896
|
-
const trimmed =
|
|
10360
|
+
(text3) => {
|
|
10361
|
+
const trimmed = text3.trim();
|
|
10897
10362
|
const media = useChatStore.getState().composerMedia;
|
|
10898
10363
|
if (!trimmed && !readyAttachments && !media || parsing || isStreaming || !isConfigured || blocked) return;
|
|
10899
10364
|
setInput("");
|
|
@@ -10907,17 +10372,17 @@ function ChatComposer({
|
|
|
10907
10372
|
const dictation = useDictation({
|
|
10908
10373
|
locale: voice?.locale,
|
|
10909
10374
|
transcribeEndpoint: voice?.transcribeEndpoint,
|
|
10910
|
-
onInterim: (
|
|
10911
|
-
onTranscript: (
|
|
10375
|
+
onInterim: (text3) => setInput(text3),
|
|
10376
|
+
onTranscript: (text3) => {
|
|
10912
10377
|
if (autoSend) {
|
|
10913
|
-
submit(
|
|
10378
|
+
submit(text3);
|
|
10914
10379
|
return;
|
|
10915
10380
|
}
|
|
10916
|
-
setInput(
|
|
10381
|
+
setInput(text3);
|
|
10917
10382
|
const el = textareaRef.current;
|
|
10918
10383
|
if (el) {
|
|
10919
10384
|
el.focus();
|
|
10920
|
-
requestAnimationFrame(() => el.setSelectionRange(
|
|
10385
|
+
requestAnimationFrame(() => el.setSelectionRange(text3.length, text3.length));
|
|
10921
10386
|
}
|
|
10922
10387
|
}
|
|
10923
10388
|
});
|
|
@@ -11070,8 +10535,8 @@ function ChatComposer({
|
|
|
11070
10535
|
if (!canAttach) return;
|
|
11071
10536
|
const files = Array.from(event.clipboardData?.files ?? []);
|
|
11072
10537
|
if (!files.length) return;
|
|
11073
|
-
const
|
|
11074
|
-
if (
|
|
10538
|
+
const text3 = event.clipboardData?.getData("text/plain");
|
|
10539
|
+
if (text3 && files.every((f) => f.type.startsWith("image/"))) return;
|
|
11075
10540
|
event.preventDefault();
|
|
11076
10541
|
receiveFiles(files);
|
|
11077
10542
|
},
|
|
@@ -11391,14 +10856,14 @@ function MdLink({ href, children }) {
|
|
|
11391
10856
|
}
|
|
11392
10857
|
);
|
|
11393
10858
|
}
|
|
11394
|
-
function renderInline(
|
|
10859
|
+
function renderInline(text3, keyBase) {
|
|
11395
10860
|
const out = [];
|
|
11396
10861
|
const pattern = /(`[^`]+`)|(\*\*[^*]+\*\*)|(\*[^*]+\*)|(\[[^\]]+\]\([^)\s]+\))/g;
|
|
11397
10862
|
let last = 0;
|
|
11398
10863
|
let match;
|
|
11399
10864
|
let i = 0;
|
|
11400
|
-
while ((match = pattern.exec(
|
|
11401
|
-
if (match.index > last) out.push(
|
|
10865
|
+
while ((match = pattern.exec(text3)) !== null) {
|
|
10866
|
+
if (match.index > last) out.push(text3.slice(last, match.index));
|
|
11402
10867
|
const token = match[0];
|
|
11403
10868
|
const key = `${keyBase}-${i++}`;
|
|
11404
10869
|
if (token.startsWith("`")) {
|
|
@@ -11421,7 +10886,7 @@ function renderInline(text2, keyBase) {
|
|
|
11421
10886
|
}
|
|
11422
10887
|
last = match.index + token.length;
|
|
11423
10888
|
}
|
|
11424
|
-
if (last <
|
|
10889
|
+
if (last < text3.length) out.push(text3.slice(last));
|
|
11425
10890
|
return out;
|
|
11426
10891
|
}
|
|
11427
10892
|
var LIST_RE = /^(\s*)([-*]|\d+[.)])\s+(.*)$/;
|
|
@@ -12202,13 +11667,13 @@ function formatValue(value) {
|
|
|
12202
11667
|
if (typeof value === "boolean") return value ? "\u2713" : "\u2014";
|
|
12203
11668
|
if (Array.isArray(value)) return value.map((v) => formatValue(v)).join(", ");
|
|
12204
11669
|
if (value && typeof value === "object") return JSON.stringify(value);
|
|
12205
|
-
const
|
|
12206
|
-
const iso = /^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2})/.exec(
|
|
11670
|
+
const text3 = String(value);
|
|
11671
|
+
const iso = /^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2})/.exec(text3);
|
|
12207
11672
|
if (iso) {
|
|
12208
|
-
const parsed = new Date(
|
|
11673
|
+
const parsed = new Date(text3);
|
|
12209
11674
|
if (!Number.isNaN(parsed.getTime())) return parsed.toLocaleString();
|
|
12210
11675
|
}
|
|
12211
|
-
return
|
|
11676
|
+
return text3;
|
|
12212
11677
|
}
|
|
12213
11678
|
var PLAIN_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
12214
11679
|
function toInputDate(value, type) {
|
|
@@ -12323,7 +11788,7 @@ function usePrefersReducedMotion() {
|
|
|
12323
11788
|
return reduced;
|
|
12324
11789
|
}
|
|
12325
11790
|
function TypedText({
|
|
12326
|
-
text:
|
|
11791
|
+
text: text3,
|
|
12327
11792
|
className,
|
|
12328
11793
|
as: Tag3 = "p",
|
|
12329
11794
|
start = true,
|
|
@@ -12331,7 +11796,7 @@ function TypedText({
|
|
|
12331
11796
|
onDone
|
|
12332
11797
|
}) {
|
|
12333
11798
|
const reduced = usePrefersReducedMotion();
|
|
12334
|
-
const [count, setCount] = React133.useState(reduced ?
|
|
11799
|
+
const [count, setCount] = React133.useState(reduced ? text3.length : 0);
|
|
12335
11800
|
const done = React133.useRef(onDone);
|
|
12336
11801
|
done.current = onDone;
|
|
12337
11802
|
React133.useEffect(() => {
|
|
@@ -12339,19 +11804,19 @@ function TypedText({
|
|
|
12339
11804
|
setCount(0);
|
|
12340
11805
|
return;
|
|
12341
11806
|
}
|
|
12342
|
-
if (reduced || !
|
|
12343
|
-
setCount(
|
|
11807
|
+
if (reduced || !text3) {
|
|
11808
|
+
setCount(text3.length);
|
|
12344
11809
|
const id = setTimeout(() => done.current?.(), 0);
|
|
12345
11810
|
return () => clearTimeout(id);
|
|
12346
11811
|
}
|
|
12347
11812
|
setCount(0);
|
|
12348
|
-
const step = Math.min(MAX_CHAR_MS, Math.max(MIN_CHAR_MS, Math.round(TYPE_MS /
|
|
11813
|
+
const step = Math.min(MAX_CHAR_MS, Math.max(MIN_CHAR_MS, Math.round(TYPE_MS / text3.length)));
|
|
12349
11814
|
let i = 0;
|
|
12350
11815
|
let timer;
|
|
12351
11816
|
const first = setTimeout(function tick() {
|
|
12352
11817
|
i += 1;
|
|
12353
11818
|
setCount(i);
|
|
12354
|
-
if (i >=
|
|
11819
|
+
if (i >= text3.length) {
|
|
12355
11820
|
done.current?.();
|
|
12356
11821
|
return;
|
|
12357
11822
|
}
|
|
@@ -12361,11 +11826,11 @@ function TypedText({
|
|
|
12361
11826
|
clearTimeout(first);
|
|
12362
11827
|
clearTimeout(timer);
|
|
12363
11828
|
};
|
|
12364
|
-
}, [
|
|
11829
|
+
}, [text3, reduced, start, startDelay]);
|
|
12365
11830
|
return /* @__PURE__ */ jsxs(Tag3, { className: cn("grid", className), children: [
|
|
12366
|
-
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "invisible", style: { gridArea: "1 / 1" }, children:
|
|
12367
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children:
|
|
12368
|
-
/* @__PURE__ */ jsx("span", { "aria-hidden": true, style: { gridArea: "1 / 1" }, children:
|
|
11831
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "invisible", style: { gridArea: "1 / 1" }, children: text3 }),
|
|
11832
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: text3 }),
|
|
11833
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, style: { gridArea: "1 / 1" }, children: text3.slice(0, count) })
|
|
12369
11834
|
] });
|
|
12370
11835
|
}
|
|
12371
11836
|
function RevealSequence({
|
|
@@ -12656,11 +12121,11 @@ function ChatConversation({
|
|
|
12656
12121
|
const el = event.currentTarget;
|
|
12657
12122
|
setAtBottom(el.scrollHeight - el.scrollTop - el.clientHeight < 48);
|
|
12658
12123
|
};
|
|
12659
|
-
const send = (
|
|
12124
|
+
const send = (text3) => {
|
|
12660
12125
|
setView("thread");
|
|
12661
12126
|
setAtBottom(true);
|
|
12662
12127
|
setSuggestionsOpen(false);
|
|
12663
|
-
sendMessage(
|
|
12128
|
+
sendMessage(text3);
|
|
12664
12129
|
};
|
|
12665
12130
|
const queuedPrompt = useChatStore((s) => s.queuedPrompt);
|
|
12666
12131
|
const consumeQueuedPrompt = useChatStore((s) => s.consumeQueuedPrompt);
|
|
@@ -13033,7 +12498,7 @@ function AgentAvatar({
|
|
|
13033
12498
|
className
|
|
13034
12499
|
}) {
|
|
13035
12500
|
const [failed, setFailed] = React133.useState(false);
|
|
13036
|
-
const { box, text:
|
|
12501
|
+
const { box, text: text3, px } = SIZES[size];
|
|
13037
12502
|
if (Face) {
|
|
13038
12503
|
return /* @__PURE__ */ jsx(
|
|
13039
12504
|
"span",
|
|
@@ -13052,7 +12517,7 @@ function AgentAvatar({
|
|
|
13052
12517
|
"relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden rounded-full",
|
|
13053
12518
|
"bg-muted font-medium text-muted-foreground",
|
|
13054
12519
|
box,
|
|
13055
|
-
|
|
12520
|
+
text3,
|
|
13056
12521
|
className
|
|
13057
12522
|
),
|
|
13058
12523
|
children: [
|
|
@@ -13597,10 +13062,10 @@ function TaskQuickAdd({ parentId }) {
|
|
|
13597
13062
|
)
|
|
13598
13063
|
] });
|
|
13599
13064
|
}
|
|
13600
|
-
var
|
|
13065
|
+
var STORAGE_KEY = "saas-core:locale";
|
|
13601
13066
|
function readPersistedLocale() {
|
|
13602
13067
|
try {
|
|
13603
|
-
return localStorage.getItem(
|
|
13068
|
+
return localStorage.getItem(STORAGE_KEY) ?? void 0;
|
|
13604
13069
|
} catch {
|
|
13605
13070
|
return void 0;
|
|
13606
13071
|
}
|
|
@@ -13612,7 +13077,7 @@ var useLocaleStore = create((set) => ({
|
|
|
13612
13077
|
locale: getPersistedLocale(),
|
|
13613
13078
|
setLocale: (locale) => {
|
|
13614
13079
|
try {
|
|
13615
|
-
localStorage.setItem(
|
|
13080
|
+
localStorage.setItem(STORAGE_KEY, locale);
|
|
13616
13081
|
} catch {
|
|
13617
13082
|
}
|
|
13618
13083
|
set({ locale });
|
|
@@ -14498,23 +13963,23 @@ var TYPING_LEAD_MS = 420;
|
|
|
14498
13963
|
var TYPING_MS_PER_WORD = 55;
|
|
14499
13964
|
var TYPING_CEILING_MS = 1200;
|
|
14500
13965
|
var TYPING_FRAME_MS = 45;
|
|
14501
|
-
function say(
|
|
13966
|
+
function say(text3, cards) {
|
|
14502
13967
|
const chat = useChatStore.getState();
|
|
14503
13968
|
const id = `guided-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
14504
|
-
const trimmed =
|
|
13969
|
+
const trimmed = text3.trim();
|
|
14505
13970
|
chat.addMessage({
|
|
14506
13971
|
id,
|
|
14507
13972
|
role: "assistant",
|
|
14508
13973
|
// Empty content is what renders the typing dots (see ChatMessages).
|
|
14509
|
-
content: trimmed ? "" :
|
|
13974
|
+
content: trimmed ? "" : text3,
|
|
14510
13975
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14511
13976
|
...cards ? { cards } : {}
|
|
14512
13977
|
});
|
|
14513
13978
|
chat.setOpen(true);
|
|
14514
|
-
if (trimmed) typeInto(id,
|
|
13979
|
+
if (trimmed) typeInto(id, text3);
|
|
14515
13980
|
}
|
|
14516
|
-
function typeInto(id,
|
|
14517
|
-
const words2 =
|
|
13981
|
+
function typeInto(id, text3) {
|
|
13982
|
+
const words2 = text3.split(/(\s+)/);
|
|
14518
13983
|
const wordCount = words2.filter((w) => w.trim()).length;
|
|
14519
13984
|
const total = Math.min(TYPING_CEILING_MS, wordCount * TYPING_MS_PER_WORD);
|
|
14520
13985
|
const frames = Math.max(1, Math.round(total / TYPING_FRAME_MS));
|
|
@@ -14524,7 +13989,7 @@ function typeInto(id, text2) {
|
|
|
14524
13989
|
const finish = () => {
|
|
14525
13990
|
if (timer) clearTimeout(timer);
|
|
14526
13991
|
typers.delete(finish);
|
|
14527
|
-
useChatStore.getState().setMessageContent(id,
|
|
13992
|
+
useChatStore.getState().setMessageContent(id, text3);
|
|
14528
13993
|
};
|
|
14529
13994
|
const step = () => {
|
|
14530
13995
|
cursor += perFrame;
|
|
@@ -14544,8 +14009,8 @@ function flushTyping() {
|
|
|
14544
14009
|
var BEAT_FLOOR_MS = 1400;
|
|
14545
14010
|
var MS_PER_WORD = 260;
|
|
14546
14011
|
var BEAT_CEILING_MS = 6e3;
|
|
14547
|
-
function readingTime(
|
|
14548
|
-
const words2 =
|
|
14012
|
+
function readingTime(text3) {
|
|
14013
|
+
const words2 = text3.trim().split(/\s+/).length;
|
|
14549
14014
|
return Math.min(BEAT_CEILING_MS, BEAT_FLOOR_MS + words2 * MS_PER_WORD);
|
|
14550
14015
|
}
|
|
14551
14016
|
var NAV_MS = 1e3;
|
|
@@ -16074,7 +15539,7 @@ function ActivationProvider() {
|
|
|
16074
15539
|
const orgName = useOrganizationStore((s) => s.currentOrg?.name);
|
|
16075
15540
|
const user = useAuthStore((s) => s.user);
|
|
16076
15541
|
const setCatalog = useActivationStore((s) => s.setCatalog);
|
|
16077
|
-
const
|
|
15542
|
+
const load2 = useActivationStore((s) => s.load);
|
|
16078
15543
|
const programs = runtime?.onboardingPrograms ?? [];
|
|
16079
15544
|
const settingsIds = useSettingsTabsStore((s) => s.ids);
|
|
16080
15545
|
const routeKey = (runtime?.routes.length ?? 0) + ":" + settingsIds.join(",");
|
|
@@ -16097,7 +15562,7 @@ function ActivationProvider() {
|
|
|
16097
15562
|
if (!tenantId2) return;
|
|
16098
15563
|
let cancelled = false;
|
|
16099
15564
|
void (async () => {
|
|
16100
|
-
await
|
|
15565
|
+
await load2(tenantId2);
|
|
16101
15566
|
if (cancelled || !user) return;
|
|
16102
15567
|
const rows = useActivationStore.getState().rows ?? [];
|
|
16103
15568
|
const stale = /* @__PURE__ */ new Set([
|
|
@@ -16119,12 +15584,12 @@ function ActivationProvider() {
|
|
|
16119
15584
|
userName: user.fullName || user.email,
|
|
16120
15585
|
items: missing
|
|
16121
15586
|
});
|
|
16122
|
-
if (ok && !cancelled) await
|
|
15587
|
+
if (ok && !cancelled) await load2(tenantId2);
|
|
16123
15588
|
})();
|
|
16124
15589
|
return () => {
|
|
16125
15590
|
cancelled = true;
|
|
16126
15591
|
};
|
|
16127
|
-
}, [tenantId2, catalog, answers, hasRoute, settingsIds, user?.id,
|
|
15592
|
+
}, [tenantId2, catalog, answers, hasRoute, settingsIds, user?.id, load2]);
|
|
16128
15593
|
React133.useEffect(() => {
|
|
16129
15594
|
if (!tenantId2) {
|
|
16130
15595
|
useBusinessProfileStore.getState().clear();
|
|
@@ -16201,8 +15666,8 @@ var useHandbookStore = create((set, get) => ({
|
|
|
16201
15666
|
open: async (path) => {
|
|
16202
15667
|
const { tenantId: tenantId2, pages } = get();
|
|
16203
15668
|
if (!tenantId2) return null;
|
|
16204
|
-
const
|
|
16205
|
-
if (
|
|
15669
|
+
const cached2 = (pages ?? []).find((p) => p.path === path);
|
|
15670
|
+
if (cached2) return cached2;
|
|
16206
15671
|
return readHandbookPage(tenantId2, path);
|
|
16207
15672
|
},
|
|
16208
15673
|
write: async (input) => {
|
|
@@ -17048,14 +16513,14 @@ function NotebookRailPanel() {
|
|
|
17048
16513
|
function HandbookProvider() {
|
|
17049
16514
|
const tenantId2 = useOrganizationStore((s) => s.currentOrg?.id);
|
|
17050
16515
|
const userId = useAuthStore((s) => s.user?.id);
|
|
17051
|
-
const
|
|
16516
|
+
const load2 = useHandbookStore((s) => s.load);
|
|
17052
16517
|
const setUser = useHandbookStore((s) => s.setUser);
|
|
17053
16518
|
React133.useEffect(() => {
|
|
17054
16519
|
setUser(userId);
|
|
17055
16520
|
}, [userId, setUser]);
|
|
17056
16521
|
React133.useEffect(() => {
|
|
17057
|
-
if (tenantId2) void
|
|
17058
|
-
}, [tenantId2,
|
|
16522
|
+
if (tenantId2) void load2(tenantId2);
|
|
16523
|
+
}, [tenantId2, load2]);
|
|
17059
16524
|
useLocalNotesImport(tenantId2, userId);
|
|
17060
16525
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
17061
16526
|
/* @__PURE__ */ jsx(NotebookRailPanel, {}),
|
|
@@ -17113,9 +16578,9 @@ function useUnitBootstrap() {
|
|
|
17113
16578
|
const orgId = tenant?.org?.id;
|
|
17114
16579
|
React133.useEffect(() => {
|
|
17115
16580
|
if (!orgId) return;
|
|
17116
|
-
const { loadedFor, load, reset } = useUnitStore.getState();
|
|
16581
|
+
const { loadedFor, load: load2, reset } = useUnitStore.getState();
|
|
17117
16582
|
if (loadedFor && loadedFor !== orgId) reset();
|
|
17118
|
-
void
|
|
16583
|
+
void load2(orgId, userId);
|
|
17119
16584
|
}, [orgId, userId]);
|
|
17120
16585
|
}
|
|
17121
16586
|
var NO_EXTRA_ROLE = "__none__";
|
|
@@ -17501,14 +16966,14 @@ function startFayzEventBridge(override) {
|
|
|
17501
16966
|
};
|
|
17502
16967
|
}
|
|
17503
16968
|
debug(`started \u2192 ${connection.apiBaseUrl} (project ${connection.projectId})`);
|
|
17504
|
-
const
|
|
16969
|
+
const client2 = createFayzEventsClient({
|
|
17505
16970
|
baseUrl: connection.apiBaseUrl,
|
|
17506
16971
|
projectId: connection.projectId,
|
|
17507
16972
|
publishableKey: connection.publishableKey
|
|
17508
16973
|
});
|
|
17509
16974
|
const off = registerEventSink((event) => {
|
|
17510
|
-
debug(`enqueue ${event.key}`, { tenantId: event.tenantId, pending:
|
|
17511
|
-
|
|
16975
|
+
debug(`enqueue ${event.key}`, { tenantId: event.tenantId, pending: client2.pending() + 1 });
|
|
16976
|
+
client2.enqueue({
|
|
17512
16977
|
// The dedupe id is minted at the sink, once per emission — a transport
|
|
17513
16978
|
// retry reuses it, so the server never runs the same fact twice.
|
|
17514
16979
|
id: crypto.randomUUID(),
|
|
@@ -17520,7 +16985,7 @@ function startFayzEventBridge(override) {
|
|
|
17520
16985
|
subject: event.subject
|
|
17521
16986
|
});
|
|
17522
16987
|
});
|
|
17523
|
-
active = { client:
|
|
16988
|
+
active = { client: client2, off };
|
|
17524
16989
|
return stopFayzEventBridge;
|
|
17525
16990
|
}
|
|
17526
16991
|
function stopFayzEventBridge() {
|
|
@@ -17773,6 +17238,24 @@ function tripletLuminance(triplet) {
|
|
|
17773
17238
|
});
|
|
17774
17239
|
return 0.2126 * lin[0] + 0.7152 * lin[1] + 0.0722 * lin[2];
|
|
17775
17240
|
}
|
|
17241
|
+
function contrast(a, b) {
|
|
17242
|
+
return (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05);
|
|
17243
|
+
}
|
|
17244
|
+
function readableInkOn(primary, surface) {
|
|
17245
|
+
const surfaceL = tripletLuminance(surface);
|
|
17246
|
+
const primaryL = tripletLuminance(primary);
|
|
17247
|
+
if (!primary || surfaceL == null || primaryL == null) return primary;
|
|
17248
|
+
if (contrast(primaryL, surfaceL) >= 3) return primary;
|
|
17249
|
+
const [h, sat, light] = primary.trim().split("/")[0].trim().split(/\s+/);
|
|
17250
|
+
const step = surfaceL > 0.5 ? -2 : 2;
|
|
17251
|
+
let l = parseFloat(light);
|
|
17252
|
+
for (let i = 0; i < 50; i++) {
|
|
17253
|
+
l = Math.min(100, Math.max(0, l + step));
|
|
17254
|
+
const candidate = `${h} ${sat} ${Math.round(l * 10) / 10}%`;
|
|
17255
|
+
if (contrast(tripletLuminance(candidate) ?? surfaceL, surfaceL) >= 4.5 || l === 0 || l === 100) return candidate;
|
|
17256
|
+
}
|
|
17257
|
+
return primary;
|
|
17258
|
+
}
|
|
17776
17259
|
function inkOnTriplet(triplet) {
|
|
17777
17260
|
const l = tripletLuminance(triplet);
|
|
17778
17261
|
return l != null && l > 0.45 ? "0 0% 10%" : "0 0% 100%";
|
|
@@ -17960,6 +17443,9 @@ function applyTheme(theme, element) {
|
|
|
17960
17443
|
target.style.setProperty(cssVar, value);
|
|
17961
17444
|
}
|
|
17962
17445
|
}
|
|
17446
|
+
const paper = tripletLuminance(theme.colors.content) != null ? theme.colors.content : theme.colors.background;
|
|
17447
|
+
const ink = readableInkOn(theme.colors.primary, paper);
|
|
17448
|
+
if (ink) target.style.setProperty("--primary-ink", ink);
|
|
17963
17449
|
persistBootPalette(theme.colors);
|
|
17964
17450
|
}
|
|
17965
17451
|
function hexToHslTriplet(hex) {
|
|
@@ -17986,14 +17472,14 @@ function hexToHslTriplet(hex) {
|
|
|
17986
17472
|
}
|
|
17987
17473
|
|
|
17988
17474
|
// src/stores/theme.store.ts
|
|
17989
|
-
var
|
|
17475
|
+
var STORAGE_KEY2 = "saas-core:theme-mode";
|
|
17990
17476
|
function getSystemPreference() {
|
|
17991
17477
|
if (typeof window === "undefined") return "light";
|
|
17992
17478
|
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
17993
17479
|
}
|
|
17994
17480
|
function getSavedMode() {
|
|
17995
17481
|
if (typeof window === "undefined") return "light";
|
|
17996
|
-
const saved = localStorage.getItem(
|
|
17482
|
+
const saved = localStorage.getItem(STORAGE_KEY2);
|
|
17997
17483
|
if (saved === "light" || saved === "dark" || saved === "system") return saved;
|
|
17998
17484
|
return "light";
|
|
17999
17485
|
}
|
|
@@ -18045,7 +17531,7 @@ function createThemeStore() {
|
|
|
18045
17531
|
const resolved = resolveMode(mode);
|
|
18046
17532
|
set({ mode, resolvedMode: resolved });
|
|
18047
17533
|
if (typeof window !== "undefined") {
|
|
18048
|
-
localStorage.setItem(
|
|
17534
|
+
localStorage.setItem(STORAGE_KEY2, mode);
|
|
18049
17535
|
}
|
|
18050
17536
|
const { overrides } = get();
|
|
18051
17537
|
const baseTheme = resolved === "dark" ? darkTheme : lightTheme;
|
|
@@ -18375,12 +17861,12 @@ function PublicSurveyPage({ token, appName }) {
|
|
|
18375
17861
|
const [failed, setFailed] = React133__default.useState(null);
|
|
18376
17862
|
React133__default.useEffect(() => {
|
|
18377
17863
|
let alive = true;
|
|
18378
|
-
const
|
|
18379
|
-
if (!
|
|
17864
|
+
const client2 = getFayzSupabaseClientOptional();
|
|
17865
|
+
if (!client2) {
|
|
18380
17866
|
setLoaded({ status: "not_found" });
|
|
18381
17867
|
return;
|
|
18382
17868
|
}
|
|
18383
|
-
|
|
17869
|
+
client2.rpc("crm_survey_invite_load", { p_token: token }).then(({ data, error }) => {
|
|
18384
17870
|
if (!alive) return;
|
|
18385
17871
|
setLoaded(error ? { status: "not_found" } : data);
|
|
18386
17872
|
});
|
|
@@ -18399,9 +17885,9 @@ function PublicSurveyPage({ token, appName }) {
|
|
|
18399
17885
|
if (missing.length > 0 || sending) return;
|
|
18400
17886
|
setSending(true);
|
|
18401
17887
|
setFailed(null);
|
|
18402
|
-
const
|
|
17888
|
+
const client2 = getFayzSupabaseClientOptional();
|
|
18403
17889
|
const answers = questions.map((q) => ({ question_id: q.id, rating: draft[q.id]?.rating ?? null, comment: draft[q.id]?.comment ?? null })).filter((a) => a.rating != null || (a.comment ?? "").trim() !== "");
|
|
18404
|
-
const { data, error } = await
|
|
17890
|
+
const { data, error } = await client2.rpc("crm_survey_invite_submit", {
|
|
18405
17891
|
p_token: token,
|
|
18406
17892
|
p_answers: answers,
|
|
18407
17893
|
p_respondent_name: name.trim() || null
|
|
@@ -19018,8 +18504,8 @@ function coerceField(field, value) {
|
|
|
19018
18504
|
}
|
|
19019
18505
|
const first = Array.isArray(value) ? value[0] : value;
|
|
19020
18506
|
if (typeof first !== "string") return void 0;
|
|
19021
|
-
const
|
|
19022
|
-
return
|
|
18507
|
+
const text3 = field.normalize ? field.normalize(first) : first.trim();
|
|
18508
|
+
return text3 || void 0;
|
|
19023
18509
|
}
|
|
19024
18510
|
|
|
19025
18511
|
// src/onboarding/analyze-site.ts
|
|
@@ -19440,14 +18926,14 @@ var useAppDirectoryStore = create((set, get) => ({
|
|
|
19440
18926
|
load: async (tenantId2, currentAppId, deps) => {
|
|
19441
18927
|
const state = get();
|
|
19442
18928
|
if (state.status !== "idle" && state.tenantId === tenantId2) return;
|
|
19443
|
-
const
|
|
19444
|
-
if (!
|
|
18929
|
+
const client2 = deps?.client === void 0 ? getFayzSupabaseClientOptional() : deps.client;
|
|
18930
|
+
if (!client2) {
|
|
19445
18931
|
set({ status: "done", tenantId: tenantId2 });
|
|
19446
18932
|
return;
|
|
19447
18933
|
}
|
|
19448
18934
|
set({ status: "loading", tenantId: tenantId2 });
|
|
19449
18935
|
try {
|
|
19450
|
-
const config = await fetchAppConfig(
|
|
18936
|
+
const config = await fetchAppConfig(client2, { tenantId: tenantId2 });
|
|
19451
18937
|
set({ apps: normalize(config.apps, currentAppId), status: "done", tenantId: tenantId2 });
|
|
19452
18938
|
} catch {
|
|
19453
18939
|
set({ status: "done", tenantId: tenantId2 });
|
|
@@ -19463,10 +18949,10 @@ function resetAppDirectory() {
|
|
|
19463
18949
|
function useAppDirectory() {
|
|
19464
18950
|
const tenantId2 = useActiveTenantId();
|
|
19465
18951
|
const apps = useAppDirectoryStore((s) => s.apps);
|
|
19466
|
-
const
|
|
18952
|
+
const load2 = useAppDirectoryStore((s) => s.load);
|
|
19467
18953
|
React133.useEffect(() => {
|
|
19468
|
-
if (tenantId2) void
|
|
19469
|
-
}, [tenantId2,
|
|
18954
|
+
if (tenantId2) void load2(tenantId2, resolveAppId());
|
|
18955
|
+
}, [tenantId2, load2]);
|
|
19470
18956
|
return { apps };
|
|
19471
18957
|
}
|
|
19472
18958
|
var FAMILY_SUFFIX = "Control";
|
|
@@ -20292,9 +19778,9 @@ function WorkspaceUnitRow({ canCreate = true }) {
|
|
|
20292
19778
|
}
|
|
20293
19779
|
var TABLE2 = "published_sites";
|
|
20294
19780
|
function db() {
|
|
20295
|
-
const
|
|
20296
|
-
if (!
|
|
20297
|
-
return
|
|
19781
|
+
const client2 = getSupabaseClientOptional();
|
|
19782
|
+
if (!client2) throw new Error("[fayz-projects] Supabase not initialized");
|
|
19783
|
+
return client2;
|
|
20298
19784
|
}
|
|
20299
19785
|
function tenantId() {
|
|
20300
19786
|
return useOrganizationStore.getState().currentOrg?.id ?? getActiveTenantId();
|
|
@@ -20438,7 +19924,7 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
20438
19924
|
const t = useTranslation();
|
|
20439
19925
|
const currentOrgId = useOrganizationStore((s) => s.currentOrg?.id);
|
|
20440
19926
|
const projects = useFayzProjectsStore((s) => s.projects);
|
|
20441
|
-
const
|
|
19927
|
+
const load2 = useFayzProjectsStore((s) => s.load);
|
|
20442
19928
|
const loadedFor = useFayzProjectsStore((s) => s.loadedFor);
|
|
20443
19929
|
const collapsed = useLayoutStore((s) => s.sidebarCollapsed);
|
|
20444
19930
|
const [selectedId, setSelectedId] = React133.useState(null);
|
|
@@ -20462,8 +19948,8 @@ function SeuSiteWidget({ fallback, onEdit }) {
|
|
|
20462
19948
|
};
|
|
20463
19949
|
React133.useEffect(() => () => cancelClose(), []);
|
|
20464
19950
|
React133.useEffect(() => {
|
|
20465
|
-
if (loadedFor !== (currentOrgId ?? null)) void
|
|
20466
|
-
}, [currentOrgId, loadedFor,
|
|
19951
|
+
if (loadedFor !== (currentOrgId ?? null)) void load2(currentOrgId);
|
|
19952
|
+
}, [currentOrgId, loadedFor, load2]);
|
|
20467
19953
|
const active2 = projects.find((p) => p.id === selectedId) ?? defaultProjectOf(projects) ?? synthFromFallback(fallback);
|
|
20468
19954
|
if (!active2) return null;
|
|
20469
19955
|
const Icon = KIND_ICON2[active2.kind] ?? Globe;
|
|
@@ -21537,17 +21023,17 @@ function ConsentBody({
|
|
|
21537
21023
|
busy
|
|
21538
21024
|
}) {
|
|
21539
21025
|
if (!payload) return /* @__PURE__ */ jsx(ConsentSkeleton, {});
|
|
21540
|
-
const { client:
|
|
21026
|
+
const { client: client2, access, organizations } = payload;
|
|
21541
21027
|
const org = organizations.find((o) => o.tenantId === tenantId2);
|
|
21542
|
-
const mark =
|
|
21028
|
+
const mark = client2.logoUri ?? knownClientMark(client2.website, client2.identityVerified === true, client2.name);
|
|
21543
21029
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
21544
21030
|
/* @__PURE__ */ jsxs("div", { className: "mb-6 flex items-center justify-center gap-3", children: [
|
|
21545
|
-
/* @__PURE__ */ jsx(MarkBadge, { fallback:
|
|
21031
|
+
/* @__PURE__ */ jsx(MarkBadge, { fallback: client2.name, children: mark ? /* @__PURE__ */ jsx("img", { src: mark, alt: "", className: "h-full w-full object-cover" }) : null }),
|
|
21546
21032
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u21C4" }),
|
|
21547
21033
|
/* @__PURE__ */ jsx(MarkBadge, { fallback: product, children: logo })
|
|
21548
21034
|
] }),
|
|
21549
21035
|
/* @__PURE__ */ jsxs("h1", { className: "text-center text-xl font-semibold text-foreground", children: [
|
|
21550
|
-
|
|
21036
|
+
client2.name,
|
|
21551
21037
|
" quer acessar seus dados"
|
|
21552
21038
|
] }),
|
|
21553
21039
|
/* @__PURE__ */ jsxs("dl", { className: "mt-6 divide-y divide-border overflow-hidden rounded-xl border border-border text-sm", children: [
|
|
@@ -21556,8 +21042,8 @@ function ConsentBody({
|
|
|
21556
21042
|
{
|
|
21557
21043
|
label: "Aplicativo",
|
|
21558
21044
|
value: /* @__PURE__ */ jsxs("span", { children: [
|
|
21559
|
-
|
|
21560
|
-
|
|
21045
|
+
client2.name,
|
|
21046
|
+
client2.identityVerified !== true && // Not an alarm — most CLI clients register themselves and are
|
|
21561
21047
|
// perfectly legitimate. But the user is about to hand over an
|
|
21562
21048
|
// organization's data, and "this name is self-declared" is a
|
|
21563
21049
|
// fact they are entitled to before deciding.
|
|
@@ -21565,14 +21051,14 @@ function ConsentBody({
|
|
|
21565
21051
|
] })
|
|
21566
21052
|
}
|
|
21567
21053
|
),
|
|
21568
|
-
|
|
21054
|
+
client2.website && /* @__PURE__ */ jsx(
|
|
21569
21055
|
Row2,
|
|
21570
21056
|
{
|
|
21571
21057
|
label: "Site",
|
|
21572
|
-
value: /* @__PURE__ */ jsx("a", { href:
|
|
21058
|
+
value: /* @__PURE__ */ jsx("a", { href: client2.website, target: "_blank", rel: "noreferrer noopener", className: "text-primary hover:underline", children: client2.website })
|
|
21573
21059
|
}
|
|
21574
21060
|
),
|
|
21575
|
-
/* @__PURE__ */ jsx(Row2, { label: "Retorna para", value: /* @__PURE__ */ jsx("span", { className: "break-all font-mono text-xs", children:
|
|
21061
|
+
/* @__PURE__ */ jsx(Row2, { label: "Retorna para", value: /* @__PURE__ */ jsx("span", { className: "break-all font-mono text-xs", children: client2.redirectUri }) }),
|
|
21576
21062
|
/* @__PURE__ */ jsx(
|
|
21577
21063
|
Row2,
|
|
21578
21064
|
{
|
|
@@ -21619,7 +21105,7 @@ function ConsentBody({
|
|
|
21619
21105
|
] }),
|
|
21620
21106
|
/* @__PURE__ */ jsxs("p", { className: "mt-5 text-xs leading-relaxed text-muted-foreground", children: [
|
|
21621
21107
|
"Ao aprovar, ",
|
|
21622
|
-
|
|
21108
|
+
client2.name,
|
|
21623
21109
|
" poder\xE1 ler os dados",
|
|
21624
21110
|
org ? ` de ${org.name}` : " da organiza\xE7\xE3o escolhida",
|
|
21625
21111
|
" at\xE9 voc\xEA desconectar. Voc\xEA pode desfazer isso a qualquer momento em ",
|
|
@@ -22117,7 +21603,7 @@ var ICON = {
|
|
|
22117
21603
|
failed: { Icon: XCircle, className: "text-destructive", label: "N\xE3o foi" }
|
|
22118
21604
|
};
|
|
22119
21605
|
function ConnectorDeliveries({
|
|
22120
|
-
load,
|
|
21606
|
+
load: load2,
|
|
22121
21607
|
providerName,
|
|
22122
21608
|
limit = 10
|
|
22123
21609
|
}) {
|
|
@@ -22125,7 +21611,7 @@ function ConnectorDeliveries({
|
|
|
22125
21611
|
const [rows, setRows] = React133__default.useState(null);
|
|
22126
21612
|
React133__default.useEffect(() => {
|
|
22127
21613
|
let cancelled = false;
|
|
22128
|
-
void
|
|
21614
|
+
void load2({ limit }).then((r) => {
|
|
22129
21615
|
if (!cancelled) setRows(r);
|
|
22130
21616
|
}).catch(() => {
|
|
22131
21617
|
if (!cancelled) setRows([]);
|
|
@@ -22133,7 +21619,7 @@ function ConnectorDeliveries({
|
|
|
22133
21619
|
return () => {
|
|
22134
21620
|
cancelled = true;
|
|
22135
21621
|
};
|
|
22136
|
-
}, [
|
|
21622
|
+
}, [load2, limit]);
|
|
22137
21623
|
if (rows === null) {
|
|
22138
21624
|
return /* @__PURE__ */ jsx("p", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) });
|
|
22139
21625
|
}
|
|
@@ -22292,7 +21778,7 @@ function UnitModeCard() {
|
|
|
22292
21778
|
const unitMode = useUnitStore((s) => s.unitMode);
|
|
22293
21779
|
const units = useUnitStore((s) => s.units);
|
|
22294
21780
|
const setMode = useUnitStore((s) => s.setMode);
|
|
22295
|
-
const
|
|
21781
|
+
const load2 = useUnitStore((s) => s.load);
|
|
22296
21782
|
const [unbound, setUnbound] = React133.useState(null);
|
|
22297
21783
|
const [bindEveryone, setBindEveryone] = React133.useState(true);
|
|
22298
21784
|
const [pending2, setPending] = React133.useState(null);
|
|
@@ -22322,7 +21808,7 @@ function UnitModeCard() {
|
|
|
22322
21808
|
await setUnitModeRemote(org.id, on);
|
|
22323
21809
|
setMode(on);
|
|
22324
21810
|
emitDataChanged();
|
|
22325
|
-
await
|
|
21811
|
+
await load2(org.id, user?.id);
|
|
22326
21812
|
toast.success(on ? "Gest\xE3o por unidades ligada" : "Gest\xE3o por unidades desligada");
|
|
22327
21813
|
} catch (err) {
|
|
22328
21814
|
toast.error("N\xE3o deu para mudar", { description: err?.message });
|
|
@@ -22440,11 +21926,11 @@ function ConnectedCompanySettings() {
|
|
|
22440
21926
|
const handleSave = async (data) => {
|
|
22441
21927
|
if (!adapter || !currentOrg) return;
|
|
22442
21928
|
try {
|
|
22443
|
-
const
|
|
21929
|
+
const raw = currentOrg.settings && typeof currentOrg.settings === "object" ? currentOrg.settings : {};
|
|
22444
21930
|
const updated = await adapter.updateOrg(currentOrg.id, {
|
|
22445
21931
|
name: data.name,
|
|
22446
21932
|
settings: {
|
|
22447
|
-
...
|
|
21933
|
+
...raw,
|
|
22448
21934
|
timezone: data.timezone,
|
|
22449
21935
|
currency: data.currency
|
|
22450
21936
|
}
|
|
@@ -22570,11 +22056,11 @@ function UserProfile({ user, onSave, onAvatarChange }) {
|
|
|
22570
22056
|
] }) })
|
|
22571
22057
|
] }) });
|
|
22572
22058
|
}
|
|
22573
|
-
function
|
|
22059
|
+
function client() {
|
|
22574
22060
|
return getSupabaseClientOptional();
|
|
22575
22061
|
}
|
|
22576
22062
|
async function fetchMyPersonRecord(tenantId2, userId) {
|
|
22577
|
-
const db2 =
|
|
22063
|
+
const db2 = client();
|
|
22578
22064
|
if (!db2) return null;
|
|
22579
22065
|
const { data, error } = await db2.from("v_team_members").select("person_id").eq("tenant_id", tenantId2).eq("user_id", userId).maybeSingle();
|
|
22580
22066
|
if (error || !data?.person_id) return null;
|
|
@@ -22583,7 +22069,7 @@ async function fetchMyPersonRecord(tenantId2, userId) {
|
|
|
22583
22069
|
return { id: person.id, name: person.name ?? "", kind: person.kind ?? null };
|
|
22584
22070
|
}
|
|
22585
22071
|
async function findMyPersonCandidate(tenantId2, email, staffKinds) {
|
|
22586
|
-
const db2 =
|
|
22072
|
+
const db2 = client();
|
|
22587
22073
|
if (!db2 || !email || staffKinds.length === 0) return null;
|
|
22588
22074
|
const { data, error } = await db2.from("people").select("id, name, kind, email").eq("tenant_id", tenantId2).in("kind", staffKinds).ilike("email", email).limit(2);
|
|
22589
22075
|
if (error || !data || data.length !== 1) return null;
|
|
@@ -22593,13 +22079,13 @@ async function findMyPersonCandidate(tenantId2, email, staffKinds) {
|
|
|
22593
22079
|
return { id: candidate.id, name: candidate.name ?? "", kind: candidate.kind ?? null };
|
|
22594
22080
|
}
|
|
22595
22081
|
async function linkPersonToLogin(tenantId2, userId, personId) {
|
|
22596
|
-
const db2 =
|
|
22082
|
+
const db2 = client();
|
|
22597
22083
|
if (!db2) throw new Error("sem conex\xE3o");
|
|
22598
22084
|
const { error } = await db2.rpc("people_link_membership", { p_person: personId, p_user: userId });
|
|
22599
22085
|
if (error) throw error;
|
|
22600
22086
|
}
|
|
22601
22087
|
async function fetchMyPersonId(tenantId2, userId) {
|
|
22602
|
-
const db2 =
|
|
22088
|
+
const db2 = client();
|
|
22603
22089
|
if (!db2) return null;
|
|
22604
22090
|
const { data, error } = await db2.from("v_team_members").select("person_id").eq("tenant_id", tenantId2).eq("user_id", userId).maybeSingle();
|
|
22605
22091
|
if (error) return null;
|
|
@@ -22622,7 +22108,7 @@ function useMyPersonId(enabled = true) {
|
|
|
22622
22108
|
return personId;
|
|
22623
22109
|
}
|
|
22624
22110
|
async function fetchPersonAccess(personId) {
|
|
22625
|
-
const db2 =
|
|
22111
|
+
const db2 = client();
|
|
22626
22112
|
if (!db2) return null;
|
|
22627
22113
|
const { data, error } = await db2.from("v_team_members").select("id, user_id, role, created_at").eq("person_id", personId).maybeSingle();
|
|
22628
22114
|
if (error || !data) return null;
|
|
@@ -22637,7 +22123,7 @@ async function fetchPersonAccess(personId) {
|
|
|
22637
22123
|
};
|
|
22638
22124
|
}
|
|
22639
22125
|
async function setPersonEmail(personId, email) {
|
|
22640
|
-
const db2 =
|
|
22126
|
+
const db2 = client();
|
|
22641
22127
|
if (!db2) throw new Error("sem conex\xE3o");
|
|
22642
22128
|
const { error } = await db2.from("people").update({ email }).eq("id", personId);
|
|
22643
22129
|
if (error) throw error;
|
|
@@ -22674,15 +22160,15 @@ function MyWorkspaceCard() {
|
|
|
22674
22160
|
const [linking, setLinking] = React133.useState(false);
|
|
22675
22161
|
const orgId = currentOrg?.id;
|
|
22676
22162
|
const userId = user?.id;
|
|
22677
|
-
const
|
|
22163
|
+
const load2 = React133.useCallback(async () => {
|
|
22678
22164
|
if (!orgId || !userId) return;
|
|
22679
22165
|
const linked = await fetchMyPersonRecord(orgId, userId);
|
|
22680
22166
|
setPerson(linked);
|
|
22681
22167
|
setCandidate(linked ? null : await findMyPersonCandidate(orgId, user?.email, staffKinds));
|
|
22682
22168
|
}, [orgId, userId, user?.email, staffKinds]);
|
|
22683
22169
|
React133.useEffect(() => {
|
|
22684
|
-
void
|
|
22685
|
-
}, [
|
|
22170
|
+
void load2();
|
|
22171
|
+
}, [load2]);
|
|
22686
22172
|
if (!currentOrg) return null;
|
|
22687
22173
|
const myRole = members.find((m) => m.userId === userId)?.profileName;
|
|
22688
22174
|
async function link() {
|
|
@@ -22691,7 +22177,7 @@ function MyWorkspaceCard() {
|
|
|
22691
22177
|
try {
|
|
22692
22178
|
await linkPersonToLogin(orgId, userId, candidate.id);
|
|
22693
22179
|
toast.success(`Login ligado ao cadastro de ${candidate.name}`);
|
|
22694
|
-
await
|
|
22180
|
+
await load2();
|
|
22695
22181
|
} catch (err) {
|
|
22696
22182
|
toast.error("S\xF3 um administrador pode ligar um login a um cadastro", { description: err?.message });
|
|
22697
22183
|
} finally {
|
|
@@ -22795,9 +22281,9 @@ function useUserLabel(userId) {
|
|
|
22795
22281
|
const [resolved, setResolved] = useState(null);
|
|
22796
22282
|
useEffect(() => {
|
|
22797
22283
|
if (!userId || fromMembers) return;
|
|
22798
|
-
const
|
|
22799
|
-
if (
|
|
22800
|
-
setResolved(
|
|
22284
|
+
const cached2 = userLabelCache.get(userId);
|
|
22285
|
+
if (cached2 !== void 0) {
|
|
22286
|
+
setResolved(cached2);
|
|
22801
22287
|
return;
|
|
22802
22288
|
}
|
|
22803
22289
|
let alive = true;
|
|
@@ -22983,15 +22469,15 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
22983
22469
|
const [deleting, setDeleting] = useState(null);
|
|
22984
22470
|
const ownerId = record?.id;
|
|
22985
22471
|
const db2 = () => getSupabaseClientOptional();
|
|
22986
|
-
const
|
|
22987
|
-
const
|
|
22988
|
-
if (!
|
|
22472
|
+
const load2 = useCallback(async () => {
|
|
22473
|
+
const client2 = db2();
|
|
22474
|
+
if (!client2 || !ownerId) {
|
|
22989
22475
|
setLoading(false);
|
|
22990
22476
|
return;
|
|
22991
22477
|
}
|
|
22992
22478
|
setLoading(true);
|
|
22993
22479
|
setError(null);
|
|
22994
|
-
let q =
|
|
22480
|
+
let q = client2.from("addresses").select("*").eq("owner_id", ownerId);
|
|
22995
22481
|
if (ownerType !== "person") q = q.eq("owner_type", ownerType);
|
|
22996
22482
|
const { data, error: err } = await q.order("is_default", { ascending: false });
|
|
22997
22483
|
if (err) setError(err.message);
|
|
@@ -22999,8 +22485,8 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
22999
22485
|
setLoading(false);
|
|
23000
22486
|
}, [ownerId, ownerType]);
|
|
23001
22487
|
useEffect(() => {
|
|
23002
|
-
void
|
|
23003
|
-
}, [
|
|
22488
|
+
void load2();
|
|
22489
|
+
}, [load2]);
|
|
23004
22490
|
const openCreate = () => {
|
|
23005
22491
|
setEditing(null);
|
|
23006
22492
|
setForm(single ? { ...EMPTY_FORM, kind: "main", is_default: true } : EMPTY_FORM);
|
|
@@ -23090,8 +22576,8 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
23090
22576
|
}
|
|
23091
22577
|
};
|
|
23092
22578
|
const handleSave = async () => {
|
|
23093
|
-
const
|
|
23094
|
-
if (!
|
|
22579
|
+
const client2 = db2();
|
|
22580
|
+
if (!client2 || !ownerId || !canSave) return;
|
|
23095
22581
|
const tenantId2 = getActiveTenantId();
|
|
23096
22582
|
if (!tenantId2) {
|
|
23097
22583
|
toast.error(t("crud.archetype.addresses.noTenant"));
|
|
@@ -23117,12 +22603,12 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
23117
22603
|
longitude: coordPair(form).lng
|
|
23118
22604
|
};
|
|
23119
22605
|
if (form.is_default) {
|
|
23120
|
-
let q =
|
|
22606
|
+
let q = client2.from("addresses").update({ is_default: false }).eq("owner_id", ownerId).eq("owner_type", ownerType).eq("kind", form.kind).eq("is_default", true);
|
|
23121
22607
|
if (editing) q = q.neq("id", editing.id);
|
|
23122
22608
|
const { error: clearErr } = await q;
|
|
23123
22609
|
if (clearErr) throw clearErr;
|
|
23124
22610
|
}
|
|
23125
|
-
const { error: err } = editing ? await
|
|
22611
|
+
const { error: err } = editing ? await client2.from("addresses").update(values).eq("id", editing.id) : await client2.from("addresses").insert({
|
|
23126
22612
|
...values,
|
|
23127
22613
|
tenant_id: tenantId2,
|
|
23128
22614
|
owner_type: ownerType,
|
|
@@ -23130,7 +22616,7 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
23130
22616
|
});
|
|
23131
22617
|
if (err) throw err;
|
|
23132
22618
|
setFormOpen(false);
|
|
23133
|
-
await
|
|
22619
|
+
await load2();
|
|
23134
22620
|
toast.success(editing ? t("crud.archetype.addresses.updated") : t("crud.archetype.addresses.created"));
|
|
23135
22621
|
} catch (e) {
|
|
23136
22622
|
toast.error(t("crud.archetype.addresses.saveFailed"), { description: e?.message });
|
|
@@ -23139,15 +22625,15 @@ function AddressesTab({ item, ownerType = "person", single = false }) {
|
|
|
23139
22625
|
}
|
|
23140
22626
|
};
|
|
23141
22627
|
const handleDelete = async () => {
|
|
23142
|
-
const
|
|
23143
|
-
if (!
|
|
23144
|
-
const { error: err } = await
|
|
22628
|
+
const client2 = db2();
|
|
22629
|
+
if (!client2 || !deleting) return;
|
|
22630
|
+
const { error: err } = await client2.from("addresses").delete().eq("id", deleting.id);
|
|
23145
22631
|
setDeleting(null);
|
|
23146
22632
|
if (err) {
|
|
23147
22633
|
toast.error(t("crud.archetype.addresses.deleteFailed"), { description: err.message });
|
|
23148
22634
|
return;
|
|
23149
22635
|
}
|
|
23150
|
-
await
|
|
22636
|
+
await load2();
|
|
23151
22637
|
toast.success(t("crud.archetype.addresses.deleted"));
|
|
23152
22638
|
};
|
|
23153
22639
|
if (loading) {
|
|
@@ -23424,28 +22910,28 @@ function PayeeAccountsSection({
|
|
|
23424
22910
|
const canEdit = can("financial", "edit");
|
|
23425
22911
|
const canDelete = can("financial", "delete");
|
|
23426
22912
|
const db2 = () => getSupabaseClientOptional();
|
|
23427
|
-
const
|
|
23428
|
-
const
|
|
23429
|
-
if (!
|
|
22913
|
+
const load2 = useCallback(async () => {
|
|
22914
|
+
const client2 = db2();
|
|
22915
|
+
if (!client2 || !ownerId) {
|
|
23430
22916
|
setLoading(false);
|
|
23431
22917
|
return;
|
|
23432
22918
|
}
|
|
23433
22919
|
setLoading(true);
|
|
23434
22920
|
setError(null);
|
|
23435
|
-
const { data, error: err } = await
|
|
22921
|
+
const { data, error: err } = await client2.from("payee_accounts").select("*").eq("owner_type", ownerType).eq("owner_id", ownerId).order("is_default", { ascending: false });
|
|
23436
22922
|
if (err) setError(err.message);
|
|
23437
22923
|
else setRows(data ?? []);
|
|
23438
22924
|
setLoading(false);
|
|
23439
22925
|
}, [ownerId, ownerType]);
|
|
23440
22926
|
useEffect(() => {
|
|
23441
|
-
void
|
|
23442
|
-
}, [
|
|
22927
|
+
void load2();
|
|
22928
|
+
}, [load2]);
|
|
23443
22929
|
const set = (key, value) => setForm((prev) => ({ ...prev, [key]: value }));
|
|
23444
22930
|
const canSave = !!blank(form.accountNumber ?? null) || !!blank(form.pixKey ?? null);
|
|
23445
22931
|
const handleSave = async () => {
|
|
23446
|
-
const
|
|
22932
|
+
const client2 = db2();
|
|
23447
22933
|
const tenantId2 = getActiveTenantId();
|
|
23448
|
-
if (!
|
|
22934
|
+
if (!client2 || !ownerId || !tenantId2 || !canSave) return;
|
|
23449
22935
|
setSaving(true);
|
|
23450
22936
|
try {
|
|
23451
22937
|
const pix = form.method === "pix";
|
|
@@ -23466,9 +22952,9 @@ function PayeeAccountsSection({
|
|
|
23466
22952
|
holder_document: b("holderDocument")
|
|
23467
22953
|
};
|
|
23468
22954
|
if (form.is_default) {
|
|
23469
|
-
await
|
|
22955
|
+
await client2.from("payee_accounts").update({ is_default: false }).eq("owner_type", ownerType).eq("owner_id", ownerId);
|
|
23470
22956
|
}
|
|
23471
|
-
const { error: err } = editing ? await
|
|
22957
|
+
const { error: err } = editing ? await client2.from("payee_accounts").update(values).eq("id", editing.id) : await client2.from("payee_accounts").insert({
|
|
23472
22958
|
...values,
|
|
23473
22959
|
tenant_id: tenantId2,
|
|
23474
22960
|
owner_type: ownerType,
|
|
@@ -23476,7 +22962,7 @@ function PayeeAccountsSection({
|
|
|
23476
22962
|
});
|
|
23477
22963
|
if (err) throw err;
|
|
23478
22964
|
setFormOpen(false);
|
|
23479
|
-
await
|
|
22965
|
+
await load2();
|
|
23480
22966
|
toast.success(t("crud.archetype.payeeAccounts.saved"));
|
|
23481
22967
|
} catch (e) {
|
|
23482
22968
|
toast.error(t("crud.archetype.payeeAccounts.saveFailed"), { description: e?.message });
|
|
@@ -23485,15 +22971,15 @@ function PayeeAccountsSection({
|
|
|
23485
22971
|
}
|
|
23486
22972
|
};
|
|
23487
22973
|
const handleDelete = async () => {
|
|
23488
|
-
const
|
|
23489
|
-
if (!
|
|
23490
|
-
const { error: err } = await
|
|
22974
|
+
const client2 = db2();
|
|
22975
|
+
if (!client2 || !deleting) return;
|
|
22976
|
+
const { error: err } = await client2.from("payee_accounts").delete().eq("id", deleting.id);
|
|
23491
22977
|
setDeleting(null);
|
|
23492
22978
|
if (err) {
|
|
23493
22979
|
toast.error(t("crud.archetype.payeeAccounts.deleteFailed"), { description: err.message });
|
|
23494
22980
|
return;
|
|
23495
22981
|
}
|
|
23496
|
-
await
|
|
22982
|
+
await load2();
|
|
23497
22983
|
toast.success(t("crud.archetype.payeeAccounts.deleted"));
|
|
23498
22984
|
};
|
|
23499
22985
|
if (!canRead) return null;
|
|
@@ -23784,7 +23270,7 @@ function CrudRecordModal({
|
|
|
23784
23270
|
onSaved,
|
|
23785
23271
|
entityDef,
|
|
23786
23272
|
mode = "edit",
|
|
23787
|
-
load,
|
|
23273
|
+
load: load2,
|
|
23788
23274
|
initialData,
|
|
23789
23275
|
save,
|
|
23790
23276
|
title,
|
|
@@ -23801,14 +23287,14 @@ function CrudRecordModal({
|
|
|
23801
23287
|
React133.useEffect(() => {
|
|
23802
23288
|
if (!open) return;
|
|
23803
23289
|
setError(null);
|
|
23804
|
-
if (mode === "create" || !
|
|
23290
|
+
if (mode === "create" || !load2) {
|
|
23805
23291
|
setRecord(initialData ?? {});
|
|
23806
23292
|
setLoading(false);
|
|
23807
23293
|
return;
|
|
23808
23294
|
}
|
|
23809
23295
|
let cancelled = false;
|
|
23810
23296
|
setLoading(true);
|
|
23811
|
-
|
|
23297
|
+
load2().then((found) => {
|
|
23812
23298
|
if (!cancelled) setRecord(found);
|
|
23813
23299
|
}).catch((err) => {
|
|
23814
23300
|
if (!cancelled) setError(errorMessage(err));
|
|
@@ -23939,6 +23425,57 @@ function useRelationOptions(r) {
|
|
|
23939
23425
|
const labelFor2 = (value) => options.find((o) => o.value === String(value))?.label ?? "";
|
|
23940
23426
|
return { options, loading, labelFor: labelFor2 };
|
|
23941
23427
|
}
|
|
23428
|
+
async function createOption(r, label3) {
|
|
23429
|
+
const supabase = getSupabaseClientOptional();
|
|
23430
|
+
if (!supabase) throw new Error("no client");
|
|
23431
|
+
const valueField = r.valueField ?? "id";
|
|
23432
|
+
const row = {
|
|
23433
|
+
...r.filter ?? {},
|
|
23434
|
+
...r.create?.defaults ?? {},
|
|
23435
|
+
[(r.labelFields ?? [r.labelField ?? "name"])[0]]: label3
|
|
23436
|
+
};
|
|
23437
|
+
if (r.tenantScoped !== false) row.tenant_id = getActiveTenantId();
|
|
23438
|
+
const { data, error } = await (r.schema ? supabase.schema(r.schema) : supabase).from(r.table).insert(row).select(valueField).single();
|
|
23439
|
+
if (error) throw error;
|
|
23440
|
+
invalidateRelationOptions();
|
|
23441
|
+
return String(data[valueField]);
|
|
23442
|
+
}
|
|
23443
|
+
function CreatableRelationSelect({ relation, value, onChange, required, placeholder }) {
|
|
23444
|
+
const [created, setCreated] = useState([]);
|
|
23445
|
+
const { options } = useRelationOptions(relation);
|
|
23446
|
+
const all = [...options, ...created.filter((c) => !options.some((o) => o.value === c.value))];
|
|
23447
|
+
return /* @__PURE__ */ jsx(
|
|
23448
|
+
SearchSelect,
|
|
23449
|
+
{
|
|
23450
|
+
value: value ? String(value) : void 0,
|
|
23451
|
+
displayValue: all.find((o) => o.value === String(value))?.label,
|
|
23452
|
+
required,
|
|
23453
|
+
placeholder,
|
|
23454
|
+
minChars: 0,
|
|
23455
|
+
noResultsLabel: "Nada encontrado",
|
|
23456
|
+
searchingLabel: "Buscando\u2026",
|
|
23457
|
+
createLabel: "Cadastrar",
|
|
23458
|
+
clearLabel: "Limpar",
|
|
23459
|
+
allowCreate: true,
|
|
23460
|
+
onSearch: (query) => {
|
|
23461
|
+
const q = query.trim().toLowerCase();
|
|
23462
|
+
return all.filter((o) => !q || o.label.toLowerCase().includes(q)).map((o) => ({ id: o.value, label: o.label }));
|
|
23463
|
+
},
|
|
23464
|
+
onChange: (id) => onChange(id || null),
|
|
23465
|
+
onCreate: async (query) => {
|
|
23466
|
+
const label3 = query.trim();
|
|
23467
|
+
if (!label3) return;
|
|
23468
|
+
try {
|
|
23469
|
+
const id = await createOption(relation, label3);
|
|
23470
|
+
setCreated((prev) => [...prev, { value: id, label: label3 }]);
|
|
23471
|
+
onChange(id);
|
|
23472
|
+
} catch (err) {
|
|
23473
|
+
toast.error(describeError(err));
|
|
23474
|
+
}
|
|
23475
|
+
}
|
|
23476
|
+
}
|
|
23477
|
+
);
|
|
23478
|
+
}
|
|
23942
23479
|
function RelationSelect({
|
|
23943
23480
|
relation,
|
|
23944
23481
|
value,
|
|
@@ -23948,6 +23485,11 @@ function RelationSelect({
|
|
|
23948
23485
|
placeholder
|
|
23949
23486
|
}) {
|
|
23950
23487
|
const { options, loading } = useRelationOptions(relation);
|
|
23488
|
+
const can = usePermissionOptional();
|
|
23489
|
+
const mayCreate = !!relation?.create && (!relation.create.permission || can(relation.create.permission.feature, relation.create.permission.action ?? "edit"));
|
|
23490
|
+
if (relation && mayCreate) {
|
|
23491
|
+
return /* @__PURE__ */ jsx(CreatableRelationSelect, { relation, value, onChange, required, placeholder });
|
|
23492
|
+
}
|
|
23951
23493
|
return /* @__PURE__ */ jsxs(
|
|
23952
23494
|
Select,
|
|
23953
23495
|
{
|
|
@@ -24053,7 +23595,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
24053
23595
|
const [error, setError] = React133.useState(null);
|
|
24054
23596
|
const [adding, setAdding] = React133.useState(false);
|
|
24055
23597
|
const [draft, setDraft] = React133.useState(null);
|
|
24056
|
-
const
|
|
23598
|
+
const load2 = React133.useCallback(async () => {
|
|
24057
23599
|
if (orfa) {
|
|
24058
23600
|
setLoading(false);
|
|
24059
23601
|
return;
|
|
@@ -24070,8 +23612,8 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
24070
23612
|
}
|
|
24071
23613
|
}, [provider2, orfa]);
|
|
24072
23614
|
React133.useEffect(() => {
|
|
24073
|
-
void
|
|
24074
|
-
}, [
|
|
23615
|
+
void load2();
|
|
23616
|
+
}, [load2]);
|
|
24075
23617
|
const guardadas = React133.useRef([]);
|
|
24076
23618
|
guardadas.current = rows;
|
|
24077
23619
|
React133.useEffect(() => {
|
|
@@ -24186,7 +23728,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
24186
23728
|
try {
|
|
24187
23729
|
await provider2.create(pronto);
|
|
24188
23730
|
setDraft(null);
|
|
24189
|
-
await
|
|
23731
|
+
await load2();
|
|
24190
23732
|
} catch (e) {
|
|
24191
23733
|
toast.error(errorMessage(e));
|
|
24192
23734
|
} finally {
|
|
@@ -24203,7 +23745,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
24203
23745
|
}
|
|
24204
23746
|
try {
|
|
24205
23747
|
await provider2.create(copia);
|
|
24206
|
-
await
|
|
23748
|
+
await load2();
|
|
24207
23749
|
} catch (e) {
|
|
24208
23750
|
toast.error(errorMessage(e));
|
|
24209
23751
|
}
|
|
@@ -24423,7 +23965,7 @@ function RelatedSection({ parentId, related, compact }) {
|
|
|
24423
23965
|
mode: "create",
|
|
24424
23966
|
save: async (data) => {
|
|
24425
23967
|
await provider2.create(data);
|
|
24426
|
-
await
|
|
23968
|
+
await load2();
|
|
24427
23969
|
},
|
|
24428
23970
|
onSaved: () => setAdding(false)
|
|
24429
23971
|
}
|
|
@@ -25167,10 +24709,10 @@ function useSuggestions(table) {
|
|
|
25167
24709
|
const [tags, setTags] = useState(() => table ? suggestionCache.get(table) ?? [] : []);
|
|
25168
24710
|
useEffect(() => {
|
|
25169
24711
|
if (!table || suggestionCache.has(table)) return;
|
|
25170
|
-
const
|
|
25171
|
-
if (!
|
|
24712
|
+
const client2 = getSupabaseClientOptional();
|
|
24713
|
+
if (!client2) return;
|
|
25172
24714
|
let alive = true;
|
|
25173
|
-
void
|
|
24715
|
+
void client2.from(table).select("tags").not("tags", "is", null).limit(500).then(({ data }) => {
|
|
25174
24716
|
const all = /* @__PURE__ */ new Set();
|
|
25175
24717
|
for (const r of data ?? []) for (const t of r.tags ?? []) all.add(t);
|
|
25176
24718
|
const list = [...all].sort();
|
|
@@ -28606,17 +28148,17 @@ function PersonAvailabilityTab({ item }) {
|
|
|
28606
28148
|
const [busy, setBusy] = React133.useState(false);
|
|
28607
28149
|
const [availabilityReady, setAvailabilityReady] = React133.useState(true);
|
|
28608
28150
|
const db2 = () => getSupabaseClientOptional();
|
|
28609
|
-
const
|
|
28610
|
-
const
|
|
28611
|
-
if (!
|
|
28151
|
+
const load2 = React133.useCallback(async () => {
|
|
28152
|
+
const client2 = db2();
|
|
28153
|
+
if (!client2 || !personId) {
|
|
28612
28154
|
setLoading(false);
|
|
28613
28155
|
return;
|
|
28614
28156
|
}
|
|
28615
28157
|
setLoading(true);
|
|
28616
28158
|
try {
|
|
28617
28159
|
const [{ data: unitRows, error: unitError }, { data: unitIds, error: grantError }] = await Promise.all([
|
|
28618
|
-
|
|
28619
|
-
|
|
28160
|
+
client2.from("v_units").select("id,name,city").eq("is_active", true).order("name"),
|
|
28161
|
+
client2.rpc("people_available_unit_ids", { p_person: personId })
|
|
28620
28162
|
]);
|
|
28621
28163
|
if (unitError) throw unitError;
|
|
28622
28164
|
setUnits(unitRows ?? []);
|
|
@@ -28636,14 +28178,14 @@ function PersonAvailabilityTab({ item }) {
|
|
|
28636
28178
|
}
|
|
28637
28179
|
}, [personId]);
|
|
28638
28180
|
React133.useEffect(() => {
|
|
28639
|
-
void
|
|
28640
|
-
}, [
|
|
28181
|
+
void load2();
|
|
28182
|
+
}, [load2]);
|
|
28641
28183
|
async function makeOrganizationWide() {
|
|
28642
|
-
const
|
|
28643
|
-
if (!
|
|
28184
|
+
const client2 = db2();
|
|
28185
|
+
if (!client2 || !personId || busy) return;
|
|
28644
28186
|
setBusy(true);
|
|
28645
28187
|
try {
|
|
28646
|
-
const { error } = await
|
|
28188
|
+
const { error } = await client2.rpc("people_set_available_units", {
|
|
28647
28189
|
p_person: personId,
|
|
28648
28190
|
p_unit_ids: []
|
|
28649
28191
|
});
|
|
@@ -28657,19 +28199,19 @@ function PersonAvailabilityTab({ item }) {
|
|
|
28657
28199
|
}
|
|
28658
28200
|
}
|
|
28659
28201
|
async function toggle(unitId, enabled) {
|
|
28660
|
-
const
|
|
28661
|
-
if (!
|
|
28202
|
+
const client2 = db2();
|
|
28203
|
+
if (!client2 || !personId || busy) return;
|
|
28662
28204
|
setBusy(true);
|
|
28663
28205
|
try {
|
|
28664
28206
|
const next = new Set(selected);
|
|
28665
28207
|
if (enabled) next.add(unitId);
|
|
28666
28208
|
else next.delete(unitId);
|
|
28667
|
-
const { error } = await
|
|
28209
|
+
const { error } = await client2.rpc("people_set_available_units", {
|
|
28668
28210
|
p_person: personId,
|
|
28669
28211
|
p_unit_ids: Array.from(next)
|
|
28670
28212
|
});
|
|
28671
28213
|
if (error) throw error;
|
|
28672
|
-
await
|
|
28214
|
+
await load2();
|
|
28673
28215
|
toast.success("Unidades atualizadas.");
|
|
28674
28216
|
} catch (error) {
|
|
28675
28217
|
toast.error("N\xE3o foi poss\xEDvel atualizar as unidades", { description: error?.message });
|
|
@@ -28714,7 +28256,7 @@ function PersonAvailabilityTab({ item }) {
|
|
|
28714
28256
|
] }) });
|
|
28715
28257
|
}
|
|
28716
28258
|
var ScheduleEditor2 = React133__default.lazy(
|
|
28717
|
-
() => import('./ScheduleEditor-
|
|
28259
|
+
() => import('./ScheduleEditor-MNHZCQIG.js').then((m) => ({ default: m.ScheduleEditor }))
|
|
28718
28260
|
);
|
|
28719
28261
|
var PersonTimeline2 = React133__default.lazy(
|
|
28720
28262
|
() => import('./timeline-LECYQ4IA.js').then((m) => ({ default: m.PersonTimeline }))
|
|
@@ -30048,7 +29590,7 @@ function MyRecordPanel() {
|
|
|
30048
29590
|
const members = useOrganizationStore((s) => s.members);
|
|
30049
29591
|
const myRole = members.find((m) => m.userId === userId)?.profileName;
|
|
30050
29592
|
const [state, setState] = React133.useState({ status: "loading" });
|
|
30051
|
-
const
|
|
29593
|
+
const load2 = React133.useCallback(async () => {
|
|
30052
29594
|
if (!orgId || !userId) return;
|
|
30053
29595
|
const person = await dedup(`self:record:${orgId}:${userId}`, () => fetchMyPersonRecord(orgId, userId));
|
|
30054
29596
|
if (!person) return setState({ status: "none" });
|
|
@@ -30066,8 +29608,8 @@ function MyRecordPanel() {
|
|
|
30066
29608
|
}
|
|
30067
29609
|
}, [orgId, userId]);
|
|
30068
29610
|
React133.useEffect(() => {
|
|
30069
|
-
void
|
|
30070
|
-
}, [
|
|
29611
|
+
void load2();
|
|
29612
|
+
}, [load2]);
|
|
30071
29613
|
const changePhoto = React133.useCallback(async (file) => {
|
|
30072
29614
|
if (state.status !== "ready") return;
|
|
30073
29615
|
const supabase = getFayzSupabaseClientOptional();
|
|
@@ -31138,13 +30680,13 @@ var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["READY", "ERROR", "ABANDONED",
|
|
|
31138
30680
|
function ProjectsSettings() {
|
|
31139
30681
|
const currentOrgId = useOrganizationStore((s) => s.currentOrg?.id);
|
|
31140
30682
|
const projects = useFayzProjectsStore((s) => s.projects);
|
|
31141
|
-
const
|
|
30683
|
+
const load2 = useFayzProjectsStore((s) => s.load);
|
|
31142
30684
|
const refresh = useFayzProjectsStore((s) => s.refresh);
|
|
31143
30685
|
const [linking, setLinking] = React133.useState(false);
|
|
31144
30686
|
const connected = isPlatformConnected();
|
|
31145
30687
|
React133.useEffect(() => {
|
|
31146
|
-
void
|
|
31147
|
-
}, [currentOrgId,
|
|
30688
|
+
void load2(currentOrgId);
|
|
30689
|
+
}, [currentOrgId, load2]);
|
|
31148
30690
|
React133.useEffect(() => {
|
|
31149
30691
|
if (!connected || projects.length === 0) return;
|
|
31150
30692
|
let cancelled = false;
|
|
@@ -31893,29 +31435,29 @@ function ModulesSettings({ hidden = [], onToggle, permits, busy, catalog = [] })
|
|
|
31893
31435
|
}
|
|
31894
31436
|
|
|
31895
31437
|
// src/app/app-config-cache.ts
|
|
31896
|
-
var
|
|
31897
|
-
var
|
|
31438
|
+
var STORAGE_KEY3 = "fayz:app-config";
|
|
31439
|
+
var VERSION = 1;
|
|
31898
31440
|
var APP_CONFIG_TTL_MS = 5 * 60 * 1e3;
|
|
31899
|
-
var
|
|
31900
|
-
var
|
|
31901
|
-
function
|
|
31441
|
+
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
31442
|
+
var MAX_BYTES = 256 * 1024;
|
|
31443
|
+
function storage() {
|
|
31902
31444
|
try {
|
|
31903
31445
|
return globalThis.localStorage ?? null;
|
|
31904
31446
|
} catch {
|
|
31905
31447
|
return null;
|
|
31906
31448
|
}
|
|
31907
31449
|
}
|
|
31908
|
-
var keyFor = (tenantId2) => `${
|
|
31450
|
+
var keyFor = (tenantId2) => `${STORAGE_KEY3}:${tenantId2}`;
|
|
31909
31451
|
function readAppConfigSnapshot(tenantId2) {
|
|
31910
|
-
const store =
|
|
31452
|
+
const store = storage();
|
|
31911
31453
|
if (!store) return null;
|
|
31912
31454
|
try {
|
|
31913
31455
|
const raw = store.getItem(keyFor(tenantId2));
|
|
31914
31456
|
if (!raw) return null;
|
|
31915
31457
|
const snap = JSON.parse(raw);
|
|
31916
|
-
if (snap.version !==
|
|
31458
|
+
if (snap.version !== VERSION || snap.tenantId !== tenantId2) return null;
|
|
31917
31459
|
const age = Date.now() - snap.savedAt;
|
|
31918
|
-
if (age >
|
|
31460
|
+
if (age > MAX_AGE_MS) {
|
|
31919
31461
|
store.removeItem(keyFor(tenantId2));
|
|
31920
31462
|
return null;
|
|
31921
31463
|
}
|
|
@@ -31925,17 +31467,17 @@ function readAppConfigSnapshot(tenantId2) {
|
|
|
31925
31467
|
}
|
|
31926
31468
|
}
|
|
31927
31469
|
function writeAppConfigSnapshot(tenantId2, config) {
|
|
31928
|
-
const store =
|
|
31470
|
+
const store = storage();
|
|
31929
31471
|
if (!store) return;
|
|
31930
31472
|
try {
|
|
31931
|
-
const payload = JSON.stringify({ version:
|
|
31932
|
-
if (payload.length >
|
|
31473
|
+
const payload = JSON.stringify({ version: VERSION, tenantId: tenantId2, savedAt: Date.now(), config });
|
|
31474
|
+
if (payload.length > MAX_BYTES) return;
|
|
31933
31475
|
store.setItem(keyFor(tenantId2), payload);
|
|
31934
31476
|
} catch {
|
|
31935
31477
|
}
|
|
31936
31478
|
}
|
|
31937
31479
|
function clearAppConfigSnapshot(tenantId2) {
|
|
31938
|
-
const store =
|
|
31480
|
+
const store = storage();
|
|
31939
31481
|
if (!store) return;
|
|
31940
31482
|
try {
|
|
31941
31483
|
if (tenantId2) {
|
|
@@ -31944,7 +31486,7 @@ function clearAppConfigSnapshot(tenantId2) {
|
|
|
31944
31486
|
}
|
|
31945
31487
|
for (let i = store.length - 1; i >= 0; i -= 1) {
|
|
31946
31488
|
const key = store.key(i);
|
|
31947
|
-
if (key?.startsWith(`${
|
|
31489
|
+
if (key?.startsWith(`${STORAGE_KEY3}:`)) store.removeItem(key);
|
|
31948
31490
|
}
|
|
31949
31491
|
} catch {
|
|
31950
31492
|
}
|
|
@@ -32591,19 +32133,19 @@ function UnitIndicator({
|
|
|
32591
32133
|
const reachable = myUnitIds.length > 0 ? myUnitIds : units.filter((u) => u.kind !== "region").map((u) => u.id);
|
|
32592
32134
|
if (reachable.length === 0) return null;
|
|
32593
32135
|
const current2 = activeUnitId ? byId[activeUnitId] : void 0;
|
|
32594
|
-
const
|
|
32595
|
-
if (!
|
|
32136
|
+
const text3 = current2?.name ?? (reachable.length > 1 ? "Todas as unidades" : byId[reachable[0]]?.name ?? "");
|
|
32137
|
+
if (!text3) return null;
|
|
32596
32138
|
if (collapsed) {
|
|
32597
|
-
return /* @__PURE__ */ jsx("div", { className: "flex justify-center pt-0.5", title:
|
|
32139
|
+
return /* @__PURE__ */ jsx("div", { className: "flex justify-center pt-0.5", title: text3, children: /* @__PURE__ */ jsx(Building2, { className: "h-3 w-3 text-sidebar-muted" }) });
|
|
32598
32140
|
}
|
|
32599
32141
|
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
32600
32142
|
/* @__PURE__ */ jsx(Building2, { className: "h-3 w-3 shrink-0 text-sidebar-muted/70" }),
|
|
32601
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-[11px] leading-none text-sidebar-muted/90", children:
|
|
32143
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-[11px] leading-none text-sidebar-muted/90", children: text3 })
|
|
32602
32144
|
] });
|
|
32603
32145
|
if (inline) {
|
|
32604
|
-
return /* @__PURE__ */ jsx("span", { className: "mt-0.5 flex min-w-0 items-center gap-1", title:
|
|
32146
|
+
return /* @__PURE__ */ jsx("span", { className: "mt-0.5 flex min-w-0 items-center gap-1", title: text3, children: body });
|
|
32605
32147
|
}
|
|
32606
|
-
return /* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-center gap-1.5 pl-12 pr-1.5 pb-1", title:
|
|
32148
|
+
return /* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-center gap-1.5 pl-12 pr-1.5 pb-1", title: text3, children: body });
|
|
32607
32149
|
}
|
|
32608
32150
|
var UNIT_DETAIL_ZONES = {
|
|
32609
32151
|
rooms: "unit.detail.rooms",
|
|
@@ -34371,7 +33913,7 @@ var CommandPalette = React133.lazy(
|
|
|
34371
33913
|
() => import('./CommandPalette-B5PMQFDG.js').then((m) => ({ default: m.CommandPalette }))
|
|
34372
33914
|
);
|
|
34373
33915
|
var SubscriptionPage = React133.lazy(
|
|
34374
|
-
() => import('./SubscriptionPage-
|
|
33916
|
+
() => import('./SubscriptionPage-JWWS44SE.js').then((m) => ({ default: m.SubscriptionPage }))
|
|
34375
33917
|
);
|
|
34376
33918
|
function WorkspaceSwitcher({
|
|
34377
33919
|
variant = "sidebar",
|
|
@@ -36721,11 +36263,14 @@ function Badge26({ badge, className = "" }) {
|
|
|
36721
36263
|
/* @__PURE__ */ jsx("span", { className: `inline-flex shrink-0 items-center rounded-full px-2 py-0.5 text-xs font-medium ${TONE_CLASS[badge.tone ?? "muted"]} ${className}`, children: badge.label })
|
|
36722
36264
|
);
|
|
36723
36265
|
}
|
|
36724
|
-
function OrderDetailBlock({ title, hint, children }) {
|
|
36266
|
+
function OrderDetailBlock({ title, hint, actions, children }) {
|
|
36725
36267
|
return /* @__PURE__ */ jsxs("div", { className: "rounded-card border bg-card p-4", children: [
|
|
36726
|
-
(title || hint) && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
36727
|
-
|
|
36728
|
-
|
|
36268
|
+
(title || hint || actions) && /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-start justify-between gap-2", children: [
|
|
36269
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
36270
|
+
title && /* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: title }),
|
|
36271
|
+
hint && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: hint })
|
|
36272
|
+
] }),
|
|
36273
|
+
actions && /* @__PURE__ */ jsx("div", { className: "shrink-0", children: actions })
|
|
36729
36274
|
] }),
|
|
36730
36275
|
children
|
|
36731
36276
|
] });
|
|
@@ -36784,7 +36329,8 @@ function OrderDetailView(props) {
|
|
|
36784
36329
|
banner,
|
|
36785
36330
|
embedded
|
|
36786
36331
|
} = props;
|
|
36787
|
-
const
|
|
36332
|
+
const itemMenu = !!props.itemActionsMenu;
|
|
36333
|
+
const actionSlots = itemMenu ? items.some((it) => (it.actions?.length ?? 0) > 0) ? 1 : 0 : Math.max(0, ...items.map((it) => it.actions?.length ?? 0));
|
|
36788
36334
|
const hasBadges = badges.length > 0 || !!props.badgesNode;
|
|
36789
36335
|
const titleNode = hasBadges ? /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
36790
36336
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: title }),
|
|
@@ -36826,7 +36372,8 @@ function OrderDetailView(props) {
|
|
|
36826
36372
|
/* @__PURE__ */ jsx(Thumbnail, { src: item.imageUrl, size: "sm", icon: item.icon }),
|
|
36827
36373
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
36828
36374
|
/* @__PURE__ */ jsx("p", { className: cn$1("truncate text-sm font-medium", item.struck && "text-muted-foreground line-through"), children: item.name }),
|
|
36829
|
-
item.description ? /* @__PURE__ */ jsx("p", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null
|
|
36375
|
+
item.description ? /* @__PURE__ */ jsx("p", { className: "truncate text-xs text-muted-foreground", children: item.description }) : null,
|
|
36376
|
+
item.note ? /* @__PURE__ */ jsx("p", { className: "truncate text-xs", children: item.note }) : null
|
|
36830
36377
|
] }),
|
|
36831
36378
|
item.account && /* @__PURE__ */ jsx(Badge, { variant: "secondary", title: item.account, className: "fz-tight-hide max-w-[12rem] shrink-0 truncate", children: item.account }),
|
|
36832
36379
|
/* @__PURE__ */ jsxs("span", { className: cn$1("shrink-0 text-xs text-muted-foreground tabular-nums", item.struck && "line-through"), children: [
|
|
@@ -36842,26 +36389,42 @@ function OrderDetailView(props) {
|
|
|
36842
36389
|
// ficam visíveis o tempo todo (`pointer: coarse`).
|
|
36843
36390
|
// Every row reserves the widest row's slot, so a line with fewer
|
|
36844
36391
|
// actions (a cancelled one has none) keeps its numbers in the column.
|
|
36845
|
-
/* @__PURE__ */
|
|
36392
|
+
/* @__PURE__ */ jsxs(
|
|
36846
36393
|
"span",
|
|
36847
36394
|
{
|
|
36848
|
-
style: { width: actionSlots * 28 + (actionSlots - 1) * 2 },
|
|
36395
|
+
style: { width: itemMenu ? 36 : actionSlots * 28 + (actionSlots - 1) * 2 },
|
|
36849
36396
|
className: "flex shrink-0 items-center justify-end gap-0.5 opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100 [@media(pointer:coarse)]:opacity-100",
|
|
36850
|
-
children:
|
|
36851
|
-
|
|
36852
|
-
|
|
36853
|
-
Button,
|
|
36397
|
+
children: [
|
|
36398
|
+
itemMenu && /* @__PURE__ */ jsx(
|
|
36399
|
+
RowActions,
|
|
36854
36400
|
{
|
|
36855
|
-
|
|
36856
|
-
|
|
36857
|
-
|
|
36858
|
-
|
|
36859
|
-
|
|
36860
|
-
|
|
36861
|
-
|
|
36401
|
+
inlineLimit: 0,
|
|
36402
|
+
actions: (item.actions ?? []).map((a) => ({
|
|
36403
|
+
id: a.id,
|
|
36404
|
+
label: a.label,
|
|
36405
|
+
icon: a.icon,
|
|
36406
|
+
intent: a.intent,
|
|
36407
|
+
disabled: a.disabled,
|
|
36408
|
+
onSelect: () => a.onSelect(item)
|
|
36409
|
+
}))
|
|
36862
36410
|
}
|
|
36863
|
-
)
|
|
36864
|
-
|
|
36411
|
+
),
|
|
36412
|
+
!itemMenu && (item.actions ?? []).map((a) => {
|
|
36413
|
+
const Icon = a.icon;
|
|
36414
|
+
return /* @__PURE__ */ jsx(Hint, { label: a.label, children: /* @__PURE__ */ jsx(
|
|
36415
|
+
Button,
|
|
36416
|
+
{
|
|
36417
|
+
type: "button",
|
|
36418
|
+
variant: "ghost",
|
|
36419
|
+
size: "icon",
|
|
36420
|
+
className: "h-7 w-7",
|
|
36421
|
+
"aria-label": a.label,
|
|
36422
|
+
onClick: () => a.onSelect(item),
|
|
36423
|
+
children: Icon ? /* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(MoreHorizontal, { className: "h-3.5 w-3.5" })
|
|
36424
|
+
}
|
|
36425
|
+
) }, a.id);
|
|
36426
|
+
})
|
|
36427
|
+
]
|
|
36865
36428
|
}
|
|
36866
36429
|
)
|
|
36867
36430
|
] }, item.id ?? i)) }) }),
|
|
@@ -37124,7 +36687,10 @@ function OrderFormItemRow({
|
|
|
37124
36687
|
labels,
|
|
37125
36688
|
extraFieldGroups,
|
|
37126
36689
|
readOnly = false,
|
|
37127
|
-
pickOnly = false
|
|
36690
|
+
pickOnly = false,
|
|
36691
|
+
note,
|
|
36692
|
+
imageUrl,
|
|
36693
|
+
icon
|
|
37128
36694
|
}) {
|
|
37129
36695
|
const l = { ...ITEM_LABELS, ...labels };
|
|
37130
36696
|
const total = quantity * unitPrice - (discount ?? 0) + (surcharge ?? 0);
|
|
@@ -37167,8 +36733,14 @@ function OrderFormItemRow({
|
|
|
37167
36733
|
index + 1,
|
|
37168
36734
|
"."
|
|
37169
36735
|
] }),
|
|
37170
|
-
|
|
37171
|
-
/* @__PURE__ */
|
|
36736
|
+
(imageUrl || icon) && /* @__PURE__ */ jsx(Thumbnail, { src: imageUrl, size: "sm", icon }),
|
|
36737
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1 text-sm", children: [
|
|
36738
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
36739
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: description || /* @__PURE__ */ jsx("span", { className: "italic text-muted-foreground", children: l.noDescription }) }),
|
|
36740
|
+
kindLabel && /* @__PURE__ */ jsx("span", { className: "inline-flex shrink-0 items-center rounded bg-muted px-1.5 py-0.5 text-[9px] font-medium text-muted-foreground", children: kindLabel })
|
|
36741
|
+
] }),
|
|
36742
|
+
note && /* @__PURE__ */ jsx("span", { className: "mt-0.5 block truncate text-xs", children: note })
|
|
36743
|
+
] }),
|
|
37172
36744
|
(extraFieldGroups ?? []).filter((g) => g.summary).map((g) => /* @__PURE__ */ jsx(
|
|
37173
36745
|
Badge,
|
|
37174
36746
|
{
|
|
@@ -37508,26 +37080,30 @@ function OrderFormItemsCard({
|
|
|
37508
37080
|
emptyLabel = "Nenhum item adicionado",
|
|
37509
37081
|
emptyActionLabel = "Adicione o primeiro item",
|
|
37510
37082
|
children,
|
|
37511
|
-
"data-tour": dataTour
|
|
37083
|
+
"data-tour": dataTour,
|
|
37084
|
+
headerExtra
|
|
37512
37085
|
}) {
|
|
37513
37086
|
return /* @__PURE__ */ jsxs("div", { "data-tour": dataTour, className: "flex flex-col overflow-hidden rounded-card border bg-card", children: [
|
|
37514
37087
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b px-4 py-3", children: [
|
|
37515
37088
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: label3 }),
|
|
37516
|
-
|
|
37517
|
-
|
|
37518
|
-
|
|
37519
|
-
|
|
37520
|
-
|
|
37521
|
-
|
|
37522
|
-
|
|
37523
|
-
|
|
37524
|
-
|
|
37525
|
-
|
|
37526
|
-
|
|
37527
|
-
|
|
37528
|
-
|
|
37529
|
-
|
|
37530
|
-
|
|
37089
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
37090
|
+
headerExtra,
|
|
37091
|
+
onAdd && /* @__PURE__ */ jsxs(
|
|
37092
|
+
"button",
|
|
37093
|
+
{
|
|
37094
|
+
type: "button",
|
|
37095
|
+
onClick: onAdd,
|
|
37096
|
+
disabled: addDisabled,
|
|
37097
|
+
title: addDisabled ? addDisabledHint : void 0,
|
|
37098
|
+
className: "fz-tap inline-flex items-center gap-2 rounded-button border border-primary bg-primary px-4 py-2 text-sm font-semibold text-primary-foreground shadow-button-primary transition-colors hover:bg-primary/90 active:shadow-button-inset disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-primary",
|
|
37099
|
+
children: [
|
|
37100
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
|
|
37101
|
+
" ",
|
|
37102
|
+
addLabel
|
|
37103
|
+
]
|
|
37104
|
+
}
|
|
37105
|
+
)
|
|
37106
|
+
] })
|
|
37531
37107
|
] }),
|
|
37532
37108
|
/* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
|
|
37533
37109
|
header,
|
|
@@ -38523,6 +38099,13 @@ function OrderListView({
|
|
|
38523
38099
|
searchText,
|
|
38524
38100
|
searchPlaceholder,
|
|
38525
38101
|
pageSize = 25,
|
|
38102
|
+
search: searchProp,
|
|
38103
|
+
onSearchChange,
|
|
38104
|
+
page: pageProp,
|
|
38105
|
+
total,
|
|
38106
|
+
onPageChange,
|
|
38107
|
+
filters,
|
|
38108
|
+
mobileLayout,
|
|
38526
38109
|
bulkActions,
|
|
38527
38110
|
rowId,
|
|
38528
38111
|
selectedRowId,
|
|
@@ -38532,8 +38115,15 @@ function OrderListView({
|
|
|
38532
38115
|
boards,
|
|
38533
38116
|
viewKey
|
|
38534
38117
|
}) {
|
|
38535
|
-
const [
|
|
38536
|
-
const [
|
|
38118
|
+
const [localSearch, setLocalSearch] = React133.useState("");
|
|
38119
|
+
const [localPage, setLocalPage] = React133.useState(1);
|
|
38120
|
+
const serverPaged = total != null;
|
|
38121
|
+
const search = onSearchChange ? searchProp ?? "" : localSearch;
|
|
38122
|
+
const setSearch = onSearchChange ?? setLocalSearch;
|
|
38123
|
+
const page = serverPaged ? pageProp ?? 1 : localPage;
|
|
38124
|
+
const setPage = serverPaged ? onPageChange ?? (() => {
|
|
38125
|
+
}) : setLocalPage;
|
|
38126
|
+
const searchable = !!searchText || !!onSearchChange;
|
|
38537
38127
|
const [rawSelection, setRawSelection] = React133.useState([]);
|
|
38538
38128
|
const offered = React133.useMemo(
|
|
38539
38129
|
() => views && views.length > 0 ? views : ["list"],
|
|
@@ -38588,6 +38178,7 @@ function OrderListView({
|
|
|
38588
38178
|
const cols = React133.useMemo(
|
|
38589
38179
|
() => columns.map((c) => ({
|
|
38590
38180
|
id: c.key,
|
|
38181
|
+
...c.mobile ? { meta: { mobile: c.mobile } } : {},
|
|
38591
38182
|
header: () => /* @__PURE__ */ jsx("div", { className: c.align === "right" ? "text-right" : "", children: c.header }),
|
|
38592
38183
|
cell: ({ row }) => /* @__PURE__ */ jsx("div", { className: c.align === "right" ? "text-right" : "", children: c.render(row.original) })
|
|
38593
38184
|
})),
|
|
@@ -38595,13 +38186,14 @@ function OrderListView({
|
|
|
38595
38186
|
);
|
|
38596
38187
|
const filtered = React133.useMemo(() => {
|
|
38597
38188
|
const term = search.trim().toLowerCase();
|
|
38598
|
-
if (!term || !searchText) return rows;
|
|
38189
|
+
if (!term || !searchText || onSearchChange) return rows;
|
|
38599
38190
|
return rows.filter((row) => searchText(row).toLowerCase().includes(term));
|
|
38600
38191
|
}, [rows, search, searchText]);
|
|
38601
38192
|
React133.useEffect(() => {
|
|
38602
|
-
|
|
38603
|
-
}, [
|
|
38604
|
-
const paged = pageSize
|
|
38193
|
+
setLocalPage(1);
|
|
38194
|
+
}, [localSearch]);
|
|
38195
|
+
const paged = serverPaged || pageSize <= 0 ? filtered : filtered.slice((page - 1) * pageSize, page * pageSize);
|
|
38196
|
+
const totalRows = serverPaged ? total : filtered.length;
|
|
38605
38197
|
const getId = React133.useCallback(
|
|
38606
38198
|
(row) => rowId ? rowId(row) : String(row.id ?? ""),
|
|
38607
38199
|
[rowId]
|
|
@@ -38659,19 +38251,26 @@ function OrderListView({
|
|
|
38659
38251
|
}
|
|
38660
38252
|
) : null,
|
|
38661
38253
|
tiles.length > 0 && /* @__PURE__ */ jsx(StatTiles, { tiles, loading }),
|
|
38662
|
-
activeCustom ? activeCustom() : showingBoard ? /* @__PURE__ */
|
|
38663
|
-
|
|
38664
|
-
|
|
38665
|
-
|
|
38666
|
-
|
|
38667
|
-
|
|
38668
|
-
|
|
38669
|
-
|
|
38670
|
-
|
|
38671
|
-
|
|
38672
|
-
|
|
38673
|
-
|
|
38674
|
-
|
|
38254
|
+
activeCustom ? activeCustom() : showingBoard ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
38255
|
+
(searchable || filters) && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
38256
|
+
searchable && /* @__PURE__ */ jsx("div", { className: "min-w-[10rem] flex-1", children: /* @__PURE__ */ jsx(SearchField, { value: search, onChange: setSearch, placeholder: searchPlaceholder ?? "Buscar\u2026" }) }),
|
|
38257
|
+
filters
|
|
38258
|
+
] }),
|
|
38259
|
+
/* @__PURE__ */ jsx(
|
|
38260
|
+
OrderBoardView,
|
|
38261
|
+
{
|
|
38262
|
+
board: activeBoard,
|
|
38263
|
+
rows: filtered,
|
|
38264
|
+
loading,
|
|
38265
|
+
empty,
|
|
38266
|
+
onRowClick,
|
|
38267
|
+
rowId,
|
|
38268
|
+
selectedRowId
|
|
38269
|
+
}
|
|
38270
|
+
),
|
|
38271
|
+
serverPaged && !loading && totalRows > pageSize && pageSize > 0 && /* @__PURE__ */ jsx(ChevronPager, { page, pageSize, total: totalRows, onPageChange: setPage })
|
|
38272
|
+
] }) : /* @__PURE__ */ jsxs(Card, { className: "overflow-hidden", children: [
|
|
38273
|
+
(searchable || filters || hasSelection) && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2 border-b border-border px-3 py-2", children: hasSelection ? /* @__PURE__ */ jsx(
|
|
38675
38274
|
BulkActionBar,
|
|
38676
38275
|
{
|
|
38677
38276
|
variant: "inline",
|
|
@@ -38681,14 +38280,17 @@ function OrderListView({
|
|
|
38681
38280
|
onClear: () => setRawSelection([]),
|
|
38682
38281
|
actions: barActions
|
|
38683
38282
|
}
|
|
38684
|
-
) : /* @__PURE__ */
|
|
38685
|
-
|
|
38686
|
-
|
|
38687
|
-
|
|
38688
|
-
|
|
38689
|
-
|
|
38690
|
-
|
|
38691
|
-
|
|
38283
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38284
|
+
searchable && /* @__PURE__ */ jsx("div", { className: "min-w-[10rem] flex-1", children: /* @__PURE__ */ jsx(
|
|
38285
|
+
SearchField,
|
|
38286
|
+
{
|
|
38287
|
+
value: search,
|
|
38288
|
+
onChange: setSearch,
|
|
38289
|
+
placeholder: searchPlaceholder ?? "Buscar\u2026"
|
|
38290
|
+
}
|
|
38291
|
+
) }),
|
|
38292
|
+
filters
|
|
38293
|
+
] }) }),
|
|
38692
38294
|
/* @__PURE__ */ jsx(
|
|
38693
38295
|
DataTable,
|
|
38694
38296
|
{
|
|
@@ -38701,15 +38303,16 @@ function OrderListView({
|
|
|
38701
38303
|
data: loading ? [] : paged,
|
|
38702
38304
|
emptyMessage: search.trim() ? "Nada encontrado para esta busca." : empty,
|
|
38703
38305
|
loading,
|
|
38704
|
-
onRowClick: onRowClick ? (row) => onRowClick(row) : void 0
|
|
38306
|
+
onRowClick: onRowClick ? (row) => onRowClick(row) : void 0,
|
|
38307
|
+
...mobileLayout ? { mobileLayout } : {}
|
|
38705
38308
|
}
|
|
38706
38309
|
),
|
|
38707
|
-
!loading &&
|
|
38310
|
+
!loading && totalRows > 0 && pageSize > 0 && /* @__PURE__ */ jsx(
|
|
38708
38311
|
ChevronPager,
|
|
38709
38312
|
{
|
|
38710
38313
|
page,
|
|
38711
38314
|
pageSize,
|
|
38712
|
-
total:
|
|
38315
|
+
total: totalRows,
|
|
38713
38316
|
onPageChange: setPage
|
|
38714
38317
|
}
|
|
38715
38318
|
)
|
|
@@ -38767,7 +38370,7 @@ function PaymentStatusBadge({
|
|
|
38767
38370
|
React133__default.useEffect(() => {
|
|
38768
38371
|
setLines(null);
|
|
38769
38372
|
}, [status, paidAmount]);
|
|
38770
|
-
const
|
|
38373
|
+
const load2 = React133__default.useCallback(() => {
|
|
38771
38374
|
if (lines || !onLoadDetails) return;
|
|
38772
38375
|
void onLoadDetails().then(setLines).catch(() => setLines([]));
|
|
38773
38376
|
}, [lines, onLoadDetails]);
|
|
@@ -38782,7 +38385,7 @@ function PaymentStatusBadge({
|
|
|
38782
38385
|
onMouseEnter: onLoadDetails ? () => {
|
|
38783
38386
|
timer.current = setTimeout(() => {
|
|
38784
38387
|
setOpen(true);
|
|
38785
|
-
|
|
38388
|
+
load2();
|
|
38786
38389
|
}, 500);
|
|
38787
38390
|
} : void 0,
|
|
38788
38391
|
onMouseLeave: onLoadDetails ? () => {
|
|
@@ -38803,7 +38406,7 @@ function PaymentStatusBadge({
|
|
|
38803
38406
|
const remaining = totalAmount != null && paidAmount != null ? totalAmount - paidAmount : null;
|
|
38804
38407
|
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: (v) => {
|
|
38805
38408
|
setOpen(v);
|
|
38806
|
-
if (v)
|
|
38409
|
+
if (v) load2();
|
|
38807
38410
|
}, children: [
|
|
38808
38411
|
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: trigger }),
|
|
38809
38412
|
/* @__PURE__ */ jsxs(PopoverContent, { align: "end", sideOffset: 6, className: "w-60 p-3", children: [
|
|
@@ -38908,7 +38511,7 @@ function useOrdersPaymentStatus(orderIds) {
|
|
|
38908
38511
|
);
|
|
38909
38512
|
const [byOrder, setByOrder] = React133.useState(() => /* @__PURE__ */ new Map());
|
|
38910
38513
|
const [loading, setLoading] = React133.useState(false);
|
|
38911
|
-
const
|
|
38514
|
+
const load2 = React133.useCallback(async (force = false) => {
|
|
38912
38515
|
const ids = key ? key.split(",") : [];
|
|
38913
38516
|
if (ids.length === 0) {
|
|
38914
38517
|
setByOrder(/* @__PURE__ */ new Map());
|
|
@@ -38940,9 +38543,9 @@ function useOrdersPaymentStatus(orderIds) {
|
|
|
38940
38543
|
setByOrder(new Map(ids.map((id) => [id, cache2.get(id)]).filter(([, v]) => Boolean(v))));
|
|
38941
38544
|
}, [key]);
|
|
38942
38545
|
React133.useEffect(() => {
|
|
38943
|
-
void
|
|
38944
|
-
}, [
|
|
38945
|
-
return { byOrder, loading, reload: () =>
|
|
38546
|
+
void load2();
|
|
38547
|
+
}, [load2]);
|
|
38548
|
+
return { byOrder, loading, reload: () => load2(true) };
|
|
38946
38549
|
}
|
|
38947
38550
|
var ORDER_KIND_LABELS = {
|
|
38948
38551
|
sale: "Venda",
|
|
@@ -38975,7 +38578,9 @@ var ORDER_CHANNEL_LABELS = {
|
|
|
38975
38578
|
balcao: "Balc\xE3o",
|
|
38976
38579
|
shop: "Loja",
|
|
38977
38580
|
dine_in: "Sal\xE3o",
|
|
38978
|
-
delivery: "Delivery"
|
|
38581
|
+
delivery: "Delivery",
|
|
38582
|
+
retirada: "Retirada",
|
|
38583
|
+
ticketing: "Bilheteria"
|
|
38979
38584
|
};
|
|
38980
38585
|
function Badge28({ children }) {
|
|
38981
38586
|
return /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium", children });
|
|
@@ -39024,7 +38629,7 @@ function useOrderDetail(orderId) {
|
|
|
39024
38629
|
try {
|
|
39025
38630
|
const db2 = getSupabaseClientOptional();
|
|
39026
38631
|
if (!db2) throw new Error("Supabase client is not configured");
|
|
39027
|
-
const { data: row, error: rowError } = await db2.from("v_orders").select("id, reference_number, kind, channel, status, party_id, subtotal, discount, tax, total, currency, notes, created_at").eq("id", orderId).maybeSingle();
|
|
38632
|
+
const { data: row, error: rowError } = await db2.from("v_orders").select("id, reference_number, kind, channel, status, fulfillment_status, party_id, subtotal, discount, tax, total, currency, notes, created_at").eq("id", orderId).maybeSingle();
|
|
39028
38633
|
if (rowError) throw new Error(rowError.message);
|
|
39029
38634
|
if (!row) throw new Error("Pedido n\xE3o encontrado");
|
|
39030
38635
|
const [{ data: items }, { data: party }] = await Promise.all([
|
|
@@ -39047,6 +38652,7 @@ function useOrderDetail(orderId) {
|
|
|
39047
38652
|
kind: row.kind ?? void 0,
|
|
39048
38653
|
channel: row.channel ?? void 0,
|
|
39049
38654
|
status: row.status ?? void 0,
|
|
38655
|
+
fulfillmentStatus: row.fulfillment_status ?? void 0,
|
|
39050
38656
|
partyName: party?.name ?? void 0,
|
|
39051
38657
|
notes: row.notes ?? void 0,
|
|
39052
38658
|
currency: row.currency ?? "BRL",
|
|
@@ -39343,6 +38949,155 @@ function toOrderDetailReceivable(receivable, money4, options = {}) {
|
|
|
39343
38949
|
...options.actions ? { actions: options.actions } : {}
|
|
39344
38950
|
};
|
|
39345
38951
|
}
|
|
38952
|
+
|
|
38953
|
+
// src/crud/archetypes/orderStage.ts
|
|
38954
|
+
var ORDER_STAGES = ["to_receive", "to_ship", "shipped", "done", "cancelled"];
|
|
38955
|
+
var ORDER_STAGE_LABELS = {
|
|
38956
|
+
to_receive: "A receber",
|
|
38957
|
+
to_ship: "A enviar",
|
|
38958
|
+
shipped: "Enviado",
|
|
38959
|
+
done: "Conclu\xEDdo",
|
|
38960
|
+
cancelled: "Cancelado"
|
|
38961
|
+
};
|
|
38962
|
+
var ORDER_STAGE_COLORS = {
|
|
38963
|
+
to_receive: "bg-amber-500",
|
|
38964
|
+
to_ship: "bg-blue-500",
|
|
38965
|
+
shipped: "bg-cyan-500",
|
|
38966
|
+
done: "bg-emerald-500",
|
|
38967
|
+
cancelled: "bg-gray-400"
|
|
38968
|
+
};
|
|
38969
|
+
var SHIPPING_CHANNELS = /* @__PURE__ */ new Set(["shop", "delivery"]);
|
|
38970
|
+
function orderStage(order) {
|
|
38971
|
+
if (order.status === "cancelled") return "cancelled";
|
|
38972
|
+
const owed = ["pending", "open", "partial", "overdue"].includes(order.paymentStatus ?? "");
|
|
38973
|
+
if (order.status === "completed") return owed ? "to_receive" : "done";
|
|
38974
|
+
if (order.paymentStatus !== "paid") return "to_receive";
|
|
38975
|
+
const shipments = (order.shipmentStatuses ?? []).filter((s) => s !== "cancelled");
|
|
38976
|
+
const delivered = shipments.length > 0 && shipments.every((s) => s === "delivered" || s === "completed");
|
|
38977
|
+
if (shipments.some((s) => s === "in_transit")) return "shipped";
|
|
38978
|
+
if (order.fulfillmentStatus === "fulfilled" || delivered) return "done";
|
|
38979
|
+
const ships = shipments.length > 0 || SHIPPING_CHANNELS.has(order.channel ?? "");
|
|
38980
|
+
return ships ? "to_ship" : "done";
|
|
38981
|
+
}
|
|
38982
|
+
var STATUS_LABEL = {
|
|
38983
|
+
pending: "Aguardando envio",
|
|
38984
|
+
in_progress: "Em preparo",
|
|
38985
|
+
in_transit: "Em tr\xE2nsito",
|
|
38986
|
+
delivered: "Entregue",
|
|
38987
|
+
completed: "Entregue",
|
|
38988
|
+
failed: "Falhou",
|
|
38989
|
+
returned: "Devolvido",
|
|
38990
|
+
cancelled: "Cancelado"
|
|
38991
|
+
};
|
|
38992
|
+
var KIND_LABEL = { shipment: "Envio", pickup: "Retirada" };
|
|
38993
|
+
function text2(value) {
|
|
38994
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
38995
|
+
}
|
|
38996
|
+
function useOrderFulfillments(orderId) {
|
|
38997
|
+
const [fulfillments, setFulfillments] = React133.useState([]);
|
|
38998
|
+
const [loading, setLoading] = React133.useState(false);
|
|
38999
|
+
const [error, setError] = React133.useState(null);
|
|
39000
|
+
const [nonce, setNonce] = React133.useState(0);
|
|
39001
|
+
const reload2 = React133.useCallback(() => setNonce((n) => n + 1), []);
|
|
39002
|
+
React133.useEffect(() => {
|
|
39003
|
+
if (!orderId) {
|
|
39004
|
+
setFulfillments([]);
|
|
39005
|
+
setError(null);
|
|
39006
|
+
return;
|
|
39007
|
+
}
|
|
39008
|
+
let cancelled = false;
|
|
39009
|
+
setLoading(true);
|
|
39010
|
+
setError(null);
|
|
39011
|
+
void (async () => {
|
|
39012
|
+
try {
|
|
39013
|
+
const db2 = getSupabaseClientOptional();
|
|
39014
|
+
if (!db2) return;
|
|
39015
|
+
const { data: rows, error: rowsError } = await db2.from("fulfillments").select("id, kind, status, carrier, tracking_code, tracking_url, shipped_at, delivered_at, estimated_delivery_at, address_id, metadata").eq("order_id", orderId).in("kind", ["shipment", "pickup"]).order("occurred_at", { ascending: true });
|
|
39016
|
+
if (rowsError) throw new Error(rowsError.message);
|
|
39017
|
+
const addressIds = [...new Set((rows ?? []).map((r) => r.address_id).filter(Boolean))];
|
|
39018
|
+
const { data: addresses, error: addressError } = addressIds.length ? await db2.from("addresses").select("id, recipient, phone, postal_code, street, number, complement, district, city, state").in("id", addressIds) : { data: [], error: null };
|
|
39019
|
+
if (addressError) throw new Error(addressError.message);
|
|
39020
|
+
if (cancelled) return;
|
|
39021
|
+
const addressById = new Map((addresses ?? []).map((a) => [a.id, a]));
|
|
39022
|
+
setFulfillments((rows ?? []).map((r) => {
|
|
39023
|
+
const meta = r.metadata ?? {};
|
|
39024
|
+
const a = r.address_id ? addressById.get(r.address_id) : void 0;
|
|
39025
|
+
return {
|
|
39026
|
+
id: r.id,
|
|
39027
|
+
kind: r.kind,
|
|
39028
|
+
status: r.status,
|
|
39029
|
+
// Older rows carry these in metadata; the columns win when set.
|
|
39030
|
+
carrier: text2(r.carrier) ?? text2(meta.carrier),
|
|
39031
|
+
trackingCode: text2(r.tracking_code) ?? text2(meta.tracking_code),
|
|
39032
|
+
trackingUrl: text2(r.tracking_url) ?? text2(meta.tracking_url),
|
|
39033
|
+
shippedAt: r.shipped_at ?? void 0,
|
|
39034
|
+
deliveredAt: r.delivered_at ?? void 0,
|
|
39035
|
+
estimatedDeliveryAt: r.estimated_delivery_at ?? void 0,
|
|
39036
|
+
address: a ? {
|
|
39037
|
+
recipient: text2(a.recipient),
|
|
39038
|
+
phone: text2(a.phone),
|
|
39039
|
+
line1: [a.street, a.number].filter(Boolean).join(", ") + (a.complement ? ` \u2014 ${a.complement}` : ""),
|
|
39040
|
+
line2: [a.district, [a.city, a.state].filter(Boolean).join("/"), a.postal_code].filter(Boolean).join(" \xB7 ")
|
|
39041
|
+
} : void 0
|
|
39042
|
+
};
|
|
39043
|
+
}));
|
|
39044
|
+
} catch (err) {
|
|
39045
|
+
if (!cancelled) {
|
|
39046
|
+
setFulfillments([]);
|
|
39047
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
39048
|
+
}
|
|
39049
|
+
} finally {
|
|
39050
|
+
if (!cancelled) setLoading(false);
|
|
39051
|
+
}
|
|
39052
|
+
})();
|
|
39053
|
+
return () => {
|
|
39054
|
+
cancelled = true;
|
|
39055
|
+
};
|
|
39056
|
+
}, [orderId, nonce]);
|
|
39057
|
+
return { fulfillments, loading, error, reload: reload2 };
|
|
39058
|
+
}
|
|
39059
|
+
function day(value) {
|
|
39060
|
+
return value ? new Date(value).toLocaleDateString("pt-BR") : void 0;
|
|
39061
|
+
}
|
|
39062
|
+
function OrderDeliveryBlock({ fulfillments, error }) {
|
|
39063
|
+
if (error) {
|
|
39064
|
+
return /* @__PURE__ */ jsx(OrderDetailBlock, { title: "Entrega", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", role: "alert", "data-testid": "order-delivery-error", children: "N\xE3o foi poss\xEDvel carregar a entrega deste pedido." }) });
|
|
39065
|
+
}
|
|
39066
|
+
if (fulfillments.length === 0) {
|
|
39067
|
+
return /* @__PURE__ */ jsx(OrderDetailBlock, { title: "Entrega", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", "data-testid": "order-delivery-empty", children: "Nenhum endere\xE7o ou envio registrado neste pedido." }) });
|
|
39068
|
+
}
|
|
39069
|
+
return /* @__PURE__ */ jsx(OrderDetailBlock, { title: "Entrega", children: /* @__PURE__ */ jsx("ul", { className: "divide-y text-sm", children: fulfillments.map((f) => /* @__PURE__ */ jsxs("li", { className: "space-y-1 py-2 first:pt-0 last:pb-0", "data-testid": "order-fulfillment", children: [
|
|
39070
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
39071
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
39072
|
+
KIND_LABEL[f.kind] ?? f.kind,
|
|
39073
|
+
f.carrier ? ` \xB7 ${f.carrier}` : ""
|
|
39074
|
+
] }),
|
|
39075
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: STATUS_LABEL[f.status] ?? f.status })
|
|
39076
|
+
] }),
|
|
39077
|
+
f.trackingCode && /* @__PURE__ */ jsxs("p", { className: "text-muted-foreground", children: [
|
|
39078
|
+
"Rastreio:",
|
|
39079
|
+
" ",
|
|
39080
|
+
f.trackingUrl ? /* @__PURE__ */ jsx("a", { href: f.trackingUrl, target: "_blank", rel: "noreferrer", className: "text-primary underline-offset-2 hover:underline", children: f.trackingCode }) : /* @__PURE__ */ jsx("span", { className: "text-foreground", children: f.trackingCode })
|
|
39081
|
+
] }),
|
|
39082
|
+
(f.shippedAt || f.deliveredAt || f.estimatedDeliveryAt) && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: [
|
|
39083
|
+
f.shippedAt && `Enviado em ${day(f.shippedAt)}`,
|
|
39084
|
+
f.deliveredAt ? `Entregue em ${day(f.deliveredAt)}` : f.estimatedDeliveryAt && `Previs\xE3o ${day(f.estimatedDeliveryAt)}`
|
|
39085
|
+
].filter(Boolean).join(" \xB7 ") }),
|
|
39086
|
+
f.address && /* @__PURE__ */ jsxs("address", { className: "not-italic text-muted-foreground", children: [
|
|
39087
|
+
f.address.recipient && /* @__PURE__ */ jsx("span", { className: "block text-foreground", children: f.address.recipient }),
|
|
39088
|
+
/* @__PURE__ */ jsx("span", { className: "block", children: f.address.line1 }),
|
|
39089
|
+
/* @__PURE__ */ jsx("span", { className: "block", children: f.address.line2 }),
|
|
39090
|
+
f.address.phone && /* @__PURE__ */ jsx("span", { className: "block", children: f.address.phone })
|
|
39091
|
+
] })
|
|
39092
|
+
] }, f.id)) }) });
|
|
39093
|
+
}
|
|
39094
|
+
var STAGE_TONE = {
|
|
39095
|
+
to_receive: "warning",
|
|
39096
|
+
to_ship: "info",
|
|
39097
|
+
shipped: "info",
|
|
39098
|
+
done: "success",
|
|
39099
|
+
cancelled: "destructive"
|
|
39100
|
+
};
|
|
39346
39101
|
function money3(value, currency) {
|
|
39347
39102
|
return value.toLocaleString("pt-BR", { style: "currency", currency: currency || "BRL" });
|
|
39348
39103
|
}
|
|
@@ -39355,9 +39110,10 @@ function OrderDetailPage({
|
|
|
39355
39110
|
mapData,
|
|
39356
39111
|
receivableActions
|
|
39357
39112
|
}) {
|
|
39358
|
-
const { order, loading, error } = useOrderDetail(orderId);
|
|
39113
|
+
const { order, loading, error, reload: reload2 } = useOrderDetail(orderId);
|
|
39114
|
+
const { fulfillments, error: fulfillmentsError } = useOrderFulfillments(orderId);
|
|
39359
39115
|
const { receivable, reload: reloadReceivable } = useOrderReceivable(orderId);
|
|
39360
|
-
if (loading) return /* @__PURE__ */ jsx(OrderDetailSkeleton, {});
|
|
39116
|
+
if (loading && !order) return /* @__PURE__ */ jsx(OrderDetailSkeleton, {});
|
|
39361
39117
|
if (error || !order) {
|
|
39362
39118
|
return /* @__PURE__ */ jsxs("div", { className: "p-6", children: [
|
|
39363
39119
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: error ?? "Pedido n\xE3o encontrado" }),
|
|
@@ -39374,27 +39130,18 @@ function OrderDetailPage({
|
|
|
39374
39130
|
}
|
|
39375
39131
|
const currency = order.currency;
|
|
39376
39132
|
const verbs = receivableActions?.(order, { receivable, reload: reloadReceivable });
|
|
39133
|
+
const stage = orderStage({
|
|
39134
|
+
status: order.status,
|
|
39135
|
+
channel: order.channel,
|
|
39136
|
+
paymentStatus: receivable?.balance.status ?? "none",
|
|
39137
|
+
fulfillmentStatus: order.fulfillmentStatus,
|
|
39138
|
+
shipmentStatuses: fulfillments.map((f) => f.status)
|
|
39139
|
+
});
|
|
39377
39140
|
const base = {
|
|
39378
39141
|
title: order.referenceNumber,
|
|
39379
|
-
//
|
|
39380
|
-
//
|
|
39381
|
-
|
|
39382
|
-
// `dine_in`, `balcao` — machine words, and printing them is how a screen
|
|
39383
|
-
// ends up saying "dine_in" to a waiter. Anything the vocabulary has not
|
|
39384
|
-
// named falls through to the raw value rather than being guessed at.
|
|
39385
|
-
badges: [
|
|
39386
|
-
...order.status ? [{ label: ORDER_STATUS_LABELS[order.status] ?? order.status, tone: orderStatusTone(order.status) }] : [],
|
|
39387
|
-
...order.kind ? [{ label: ORDER_KIND_LABELS[order.kind] ?? order.kind, tone: "muted" }] : [],
|
|
39388
|
-
...order.channel ? [{ label: ORDER_CHANNEL_LABELS[order.channel] ?? order.channel, tone: "muted" }] : [],
|
|
39389
|
-
// O estado do DINHEIRO ao lado do estado do PEDIDO. Ate aqui a resposta
|
|
39390
|
-
// existia so no bloco de baixo, e quem abre a ficha para saber se ja
|
|
39391
|
-
// recebeu tinha de rolar a tela para descobrir. So aparece depois de
|
|
39392
|
-
// faturado — sem fatura nao ha o que dizer, e o bloco de baixo ja diz.
|
|
39393
|
-
...receivable ? [{
|
|
39394
|
-
label: RECEIVABLE_LABEL[receivable.balance.status] ?? receivable.balance.status,
|
|
39395
|
-
tone: receivableTone(receivable.balance.status)
|
|
39396
|
-
}] : []
|
|
39397
|
-
],
|
|
39142
|
+
// ONE badge, the same word the list and the board use for this order.
|
|
39143
|
+
// Status, kind, channel and money as four chips read as four states.
|
|
39144
|
+
badges: [{ label: ORDER_STAGE_LABELS[stage], tone: STAGE_TONE[stage] }],
|
|
39398
39145
|
// The date belongs in the provenance footer, where every other ficha in the
|
|
39399
39146
|
// app keeps "criado em" — beside the order number it competes with what the
|
|
39400
39147
|
// person opened the screen to read. `meta` is what RecordMetaFooter reads.
|
|
@@ -39425,8 +39172,12 @@ function OrderDetailPage({
|
|
|
39425
39172
|
// dois ramos: dois `createElement` distintos remontariam o componente na
|
|
39426
39173
|
// troca de ramo, e com ele o modal aberto.
|
|
39427
39174
|
receivable: toOrderDetailReceivable(receivable, (value) => money3(value, currency), { actions: verbs }) ?? { rows: [], installments: [], actions: verbs },
|
|
39428
|
-
...actions ? { actions: actions(order) } : {},
|
|
39429
|
-
|
|
39175
|
+
...actions ? { actions: actions(order, { reload: reload2 }) } : {},
|
|
39176
|
+
// Beside the customer, where the shop's own page keeps it.
|
|
39177
|
+
extraSections: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
39178
|
+
/* @__PURE__ */ jsx(OrderDeliveryBlock, { fulfillments, error: fulfillmentsError }),
|
|
39179
|
+
extraSections?.(order)
|
|
39180
|
+
] }),
|
|
39430
39181
|
backLabel,
|
|
39431
39182
|
onBack: () => navigateTo(backTo)
|
|
39432
39183
|
};
|
|
@@ -39544,6 +39295,43 @@ function useOrderEditor(orderId) {
|
|
|
39544
39295
|
save
|
|
39545
39296
|
};
|
|
39546
39297
|
}
|
|
39298
|
+
var cache4 = null;
|
|
39299
|
+
function load() {
|
|
39300
|
+
cache4 ?? (cache4 = (async () => {
|
|
39301
|
+
const db2 = getSupabaseClientOptional();
|
|
39302
|
+
if (!db2) return /* @__PURE__ */ new Map();
|
|
39303
|
+
const { data, error } = await db2.from("order_kinds").select("kind, transitions");
|
|
39304
|
+
if (error) {
|
|
39305
|
+
cache4 = null;
|
|
39306
|
+
return /* @__PURE__ */ new Map();
|
|
39307
|
+
}
|
|
39308
|
+
return new Map((data ?? []).map((r) => [r.kind, r.transitions ?? {}]));
|
|
39309
|
+
})());
|
|
39310
|
+
return cache4;
|
|
39311
|
+
}
|
|
39312
|
+
var TERMINAL = /* @__PURE__ */ new Set(["completed", "cancelled"]);
|
|
39313
|
+
function nextOrderStatuses(transitions, status) {
|
|
39314
|
+
if (!transitions || !status) return [];
|
|
39315
|
+
const declared = transitions[status] ?? transitions["*"] ?? [];
|
|
39316
|
+
if (declared.includes("*")) return TERMINAL.has(status) ? [] : ["cancelled"];
|
|
39317
|
+
return declared;
|
|
39318
|
+
}
|
|
39319
|
+
function useOrderKindTransitions(kind, status) {
|
|
39320
|
+
const [byKind, setByKind] = React133.useState(null);
|
|
39321
|
+
React133.useEffect(() => {
|
|
39322
|
+
let live = true;
|
|
39323
|
+
void load().then((map) => {
|
|
39324
|
+
if (live) setByKind(map);
|
|
39325
|
+
});
|
|
39326
|
+
return () => {
|
|
39327
|
+
live = false;
|
|
39328
|
+
};
|
|
39329
|
+
}, []);
|
|
39330
|
+
return React133.useMemo(
|
|
39331
|
+
() => nextOrderStatuses(kind ? byKind?.get(kind) : void 0, status),
|
|
39332
|
+
[byKind, kind, status]
|
|
39333
|
+
);
|
|
39334
|
+
}
|
|
39547
39335
|
|
|
39548
39336
|
// src/lib/create-client-orders-provider.ts
|
|
39549
39337
|
var STAGE_FILTER_MAP = {
|
|
@@ -39764,6 +39552,39 @@ function ModuleActionBar({
|
|
|
39764
39552
|
trailing
|
|
39765
39553
|
] });
|
|
39766
39554
|
}
|
|
39555
|
+
function formatCurrency4(value, currency) {
|
|
39556
|
+
if (!currency) return formatCurrency$1(value);
|
|
39557
|
+
return new Intl.NumberFormat(currency.locale, {
|
|
39558
|
+
style: "currency",
|
|
39559
|
+
currency: currency.code,
|
|
39560
|
+
minimumFractionDigits: 2
|
|
39561
|
+
}).format(value);
|
|
39562
|
+
}
|
|
39563
|
+
function useHouseCurrency() {
|
|
39564
|
+
return React133.useSyncExternalStore(subscribeHouseCurrency, getHouseCurrency, getHouseCurrency);
|
|
39565
|
+
}
|
|
39566
|
+
var CurrencyScopeContext = React133.createContext(null);
|
|
39567
|
+
function CurrencyScope({ code, children }) {
|
|
39568
|
+
const outer = React133.useContext(CurrencyScopeContext);
|
|
39569
|
+
return React133.createElement(CurrencyScopeContext.Provider, { value: code || outer }, children);
|
|
39570
|
+
}
|
|
39571
|
+
function useCurrencyScope() {
|
|
39572
|
+
return React133.useContext(CurrencyScopeContext);
|
|
39573
|
+
}
|
|
39574
|
+
function useCurrency(declared, documentCode) {
|
|
39575
|
+
const house = useHouseCurrency();
|
|
39576
|
+
const scope = useCurrencyScope();
|
|
39577
|
+
const code = documentCode || scope;
|
|
39578
|
+
return React133.useMemo(
|
|
39579
|
+
() => resolveCurrency(declared, code),
|
|
39580
|
+
// `house` is read inside resolveCurrency; listed so a switch re-resolves.
|
|
39581
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
39582
|
+
[declared, code, house]
|
|
39583
|
+
);
|
|
39584
|
+
}
|
|
39585
|
+
function isCurrencyConfig(value) {
|
|
39586
|
+
return !!value && typeof value === "object" && typeof value.code === "string" && typeof value.locale === "string";
|
|
39587
|
+
}
|
|
39767
39588
|
function createPluginContext(displayName) {
|
|
39768
39589
|
const ConfigContext = React133__default.createContext(null);
|
|
39769
39590
|
const ProviderContext = React133__default.createContext(null);
|
|
@@ -39777,8 +39598,16 @@ function createPluginContext(displayName) {
|
|
|
39777
39598
|
ContextProvider.displayName = `${displayName}ContextProvider`;
|
|
39778
39599
|
function useConfig() {
|
|
39779
39600
|
const ctx = React133__default.useContext(ConfigContext);
|
|
39780
|
-
|
|
39781
|
-
|
|
39601
|
+
const house = useHouseCurrency();
|
|
39602
|
+
const scope = useCurrencyScope();
|
|
39603
|
+
const resolved = React133__default.useMemo(() => {
|
|
39604
|
+
const declared = ctx?.currency;
|
|
39605
|
+
const code = scope || house;
|
|
39606
|
+
if (!ctx || !code || !isCurrencyConfig(declared) || declared.code === code) return ctx;
|
|
39607
|
+
return { ...ctx, currency: resolveCurrency(declared, scope) };
|
|
39608
|
+
}, [ctx, house, scope]);
|
|
39609
|
+
if (!resolved) throw new Error(`useConfig must be used within ${displayName}`);
|
|
39610
|
+
return resolved;
|
|
39782
39611
|
}
|
|
39783
39612
|
function useProvider() {
|
|
39784
39613
|
const ctx = React133__default.useContext(ProviderContext);
|
|
@@ -39806,14 +39635,6 @@ function createViewRouter(routes, fallbackId) {
|
|
|
39806
39635
|
return route ? route.render({ id }) : null;
|
|
39807
39636
|
};
|
|
39808
39637
|
}
|
|
39809
|
-
function formatCurrency4(value, currency) {
|
|
39810
|
-
if (!currency) return formatCurrency$1(value);
|
|
39811
|
-
return new Intl.NumberFormat(currency.locale, {
|
|
39812
|
-
style: "currency",
|
|
39813
|
-
currency: currency.code,
|
|
39814
|
-
minimumFractionDigits: 2
|
|
39815
|
-
}).format(value);
|
|
39816
|
-
}
|
|
39817
39638
|
function RegistryCrudView({ registry: registry4, basePath }) {
|
|
39818
39639
|
const useStore2 = useMemo(() => {
|
|
39819
39640
|
const data = registry4.mockData ?? registry4.seedData ?? [];
|
|
@@ -40211,7 +40032,7 @@ function ContactPicker({
|
|
|
40211
40032
|
() => lookup ?? createArchetypeLookup({ archetype: "person", kind }),
|
|
40212
40033
|
[lookup, kind]
|
|
40213
40034
|
);
|
|
40214
|
-
const
|
|
40035
|
+
const create31 = useMemo(() => {
|
|
40215
40036
|
if (createEntityDef?.data?.table) {
|
|
40216
40037
|
const def2 = createEntityDef;
|
|
40217
40038
|
return {
|
|
@@ -40247,8 +40068,8 @@ function ContactPicker({
|
|
|
40247
40068
|
}
|
|
40248
40069
|
};
|
|
40249
40070
|
}, [createEntityDef, resolvedLookup]);
|
|
40250
|
-
const createFeature =
|
|
40251
|
-
const canCreate = !!
|
|
40071
|
+
const createFeature = create31?.def.permission?.feature;
|
|
40072
|
+
const canCreate = !!create31 && (!createFeature || can(createFeature, "create"));
|
|
40252
40073
|
const [search, setSearch] = useState(value?.id ? value.name : value?.name ?? "");
|
|
40253
40074
|
const [options, setOptions] = useState([]);
|
|
40254
40075
|
const [searching, setSearching] = useState(false);
|
|
@@ -40371,17 +40192,17 @@ function ContactPicker({
|
|
|
40371
40192
|
] })
|
|
40372
40193
|
);
|
|
40373
40194
|
}
|
|
40374
|
-
if (creating &&
|
|
40375
|
-
const nameKey =
|
|
40195
|
+
if (creating && create31) {
|
|
40196
|
+
const nameKey = create31.def.displayField ?? create31.def.fields[0]?.key ?? "name";
|
|
40376
40197
|
return frame(
|
|
40377
40198
|
/* @__PURE__ */ jsx(
|
|
40378
40199
|
LookupCreateInline,
|
|
40379
40200
|
{
|
|
40380
|
-
entityDef:
|
|
40201
|
+
entityDef: create31.def,
|
|
40381
40202
|
initialData: { [nameKey]: newName },
|
|
40382
40203
|
onCancel: () => setCreating(false),
|
|
40383
40204
|
save: async (data) => {
|
|
40384
|
-
const person = await
|
|
40205
|
+
const person = await create31.write(data);
|
|
40385
40206
|
setSearch(person.name || newName);
|
|
40386
40207
|
setCreating(false);
|
|
40387
40208
|
onChange({ ...person, name: person.name || newName });
|
|
@@ -40699,9 +40520,9 @@ function clearDocumentOpeners() {
|
|
|
40699
40520
|
function createOneShotAsk(override) {
|
|
40700
40521
|
const connection = resolveFayzAgentConnection(override);
|
|
40701
40522
|
if (!connection) return null;
|
|
40702
|
-
const
|
|
40523
|
+
const client2 = getFayzAgentClient(connection);
|
|
40703
40524
|
return async ({ message, inlineFiles, signal }) => {
|
|
40704
|
-
const reply = await
|
|
40525
|
+
const reply = await client2.chat({
|
|
40705
40526
|
message,
|
|
40706
40527
|
...inlineFiles?.length ? { inlineFiles } : {},
|
|
40707
40528
|
...signal ? { signal } : {},
|
|
@@ -40927,7 +40748,7 @@ function useFeatureHelp(def) {
|
|
|
40927
40748
|
}
|
|
40928
40749
|
function HelpButton({
|
|
40929
40750
|
icon: Icon,
|
|
40930
|
-
text:
|
|
40751
|
+
text: text3,
|
|
40931
40752
|
hint,
|
|
40932
40753
|
ariaLabel,
|
|
40933
40754
|
className,
|
|
@@ -40945,7 +40766,7 @@ function HelpButton({
|
|
|
40945
40766
|
onClick,
|
|
40946
40767
|
children: [
|
|
40947
40768
|
/* @__PURE__ */ jsx(Icon, { className: "h-3.5 w-3.5" }),
|
|
40948
|
-
|
|
40769
|
+
text3
|
|
40949
40770
|
]
|
|
40950
40771
|
}
|
|
40951
40772
|
) }),
|
|
@@ -41310,6 +41131,6 @@ var renderApp = (...args) => {
|
|
|
41310
41131
|
return renderApp$1(...args);
|
|
41311
41132
|
};
|
|
41312
41133
|
|
|
41313
|
-
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,
|
|
41134
|
+
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, CurrencyScope, 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, ORDER_STAGES, ORDER_STAGE_COLORS, ORDER_STAGE_LABELS, ORDER_STATUS_LABELS, OTHER_CONNECTOR, OrderAmount, OrderBoardView, OrderCreateScreen, OrderDeliveryBlock, 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, TagChip, TagsField, 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, 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, nextOrderStatuses, normalizePath, openAssistant, openAssistantAs, openConnectorsPanel, orderChannelColumn, orderIsEditable, orderKindColumn, orderStage, orderStatusTone, 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, useCurrency, useCurrencyScope, useDelegateToAssistant, useFayzProjectsStore, useFeatureHelp, useFieldRules, useHandbookStore, useHasRightRail, useHeaderAction, useHeaderActions, useHouseCurrency, useLaunchersForRole, useLookupCreate, useMemberAccessPanel, useModuleNavigation, useNavContribution, useNavContributionsStore, useNotesTasksBridge, useOfferedPlugins, useOrderDetail, useOrderEditor, useOrderFulfillments, useOrderKindTransitions, useOrderReceivable, useOrdersPaymentStatus, usePersistedState, usePersonTabCounts, usePluginOnboardingGate, usePluginPrefs, usePresetLabel, usePublishAssistantActivity, useRegisterAssistantLauncher, useRememberedList, useRightRailDrill, useRightRailHosted, useRightRailMenu, useRightRailPanel, useRightRailStore, useScrollMemory, useSettingsTabsStore, useShellRailAvailable, useTasksStore, useTasksSummaryLine, useTeachMe, useTenantPluginSettings, useUnitBootstrap, useUnitFilter, useWidgetSurface, useWorkspaceSetupBusy, useWorkspaceSetupGate, useWorkspaceSetupStore, validateSetupGuides, withdrawAssistantActivity, writeHandbookPage };
|
|
41314
41135
|
//# sourceMappingURL=index.js.map
|
|
41315
41136
|
//# sourceMappingURL=index.js.map
|