@fayz-ai/admin 0.44.1 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/AdminShell.d.ts.map +1 -1
- package/dist/crud/CrudDetailPage.d.ts +10 -4
- package/dist/crud/CrudDetailPage.d.ts.map +1 -1
- package/dist/crud/CrudFormPage.d.ts +6 -0
- package/dist/crud/CrudFormPage.d.ts.map +1 -1
- package/dist/crud/CrudPage.d.ts.map +1 -1
- package/dist/crud/CrudSkeletons.d.ts +4 -2
- package/dist/crud/CrudSkeletons.d.ts.map +1 -1
- package/dist/crud/archetypes/PersonFormLayout.d.ts.map +1 -1
- package/dist/crud/record-chrome.d.ts +33 -0
- package/dist/crud/record-chrome.d.ts.map +1 -0
- package/dist/index.js +364 -249
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -21,13 +21,13 @@ export { getPersistedOrgId, useOrganizationStore } from './chunk-QOS6UAQ4.js';
|
|
|
21
21
|
import * as React133 from 'react';
|
|
22
22
|
import React133__default, { createContext, useMemo, useState, useRef, useCallback, useEffect, useLayoutEffect, useContext, createElement } from 'react';
|
|
23
23
|
import * as LucideIcons from 'lucide-react';
|
|
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,
|
|
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, Edit, Camera, 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';
|
|
25
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';
|
|
26
26
|
export { ConnectorRuntimeTokenUnavailableError, createSafeDataProvider, formatDate, formatDateTime, getActiveLocale, getActiveTenantId, getConnectorRuntimeTokenSource, getCurrentLocale, getSupabaseClientOptional, preloadLocale, resolveBackendEnv, setConnectorRuntimeTokenSource, setCurrentLocale, tl, useActiveTenantId } from '@fayz-ai/core';
|
|
27
27
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
28
28
|
import { usePasswordSetupGate, SetPasswordPage, AuthGate, AuthProvider, createAuthRuntime } from '@fayz-ai/plugin-auth';
|
|
29
29
|
export { LoginPage } from '@fayz-ai/plugin-auth';
|
|
30
|
-
import { Input, SearchSelect, toast, usePageTrailParent, navigateToCrumb, Button, PageHeader, ConfirmDialog, RowActions, useRowSelection, getLucideIcon, ListFilterBar, Dropdown, DropdownTrigger, Hint, cn as cn$1, DropdownContent, DropdownLabel, DropdownItem, DropdownSeparator, RefreshButton, PageHeaderActions, PageTabs, StatTiles, Card, BulkActionBar, DataTable, Modal, ModalContent, ModalHeader, ModalTitle, ModalDescription, ModalFooter, Badge, PersonAvatar, PageActionBar, ICON_MAP, Sheet, SheetContent, SheetBody, useIsWide, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Checkbox, useTourStore, setTourNavigator, TourSpotlight, PracticeOverlay, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Wizard, SidebarOnboarding, OnboardingWidget, Skeleton, useLayoutStore, ModalPortal, ModalOverlay, ModalBody, useSaveBar, useBackHandler, SubpageHeader,
|
|
30
|
+
import { Input, SearchSelect, toast, usePageTrailParent, navigateToCrumb, Button, PageHeader, ConfirmDialog, RowActions, useRowSelection, getLucideIcon, ListFilterBar, Dropdown, DropdownTrigger, Hint, cn as cn$1, DropdownContent, DropdownLabel, DropdownItem, DropdownSeparator, RefreshButton, PageHeaderActions, PageTabs, StatTiles, Card, BulkActionBar, DataTable, Modal, ModalContent, ModalHeader, ModalTitle, ModalDescription, ModalFooter, Badge, PersonAvatar, PageActionBar, ICON_MAP, Sheet, SheetContent, SheetBody, useIsWide, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Checkbox, useTourStore, setTourNavigator, TourSpotlight, PracticeOverlay, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Wizard, SidebarOnboarding, OnboardingWidget, Skeleton, useLayoutStore, ModalPortal, ModalOverlay, ModalBody, useSaveBar, useBackHandler, SubpageHeader, Tabs, TabsContent, CardContent, ToastProvider, NavTransitionProvider, ListView, Thumbnail, CurrencyInput, TabsList, TabsTrigger, SearchField, ChevronPager, Popover, PopoverTrigger, PopoverContent, useModuleLayout, PhoneLink, normalizePhone, SearchCombobox, HeaderTabs, usePageTrail, PageHeaderOutlet, AppShellSkeleton, usePracticeStore, ViewTabs, Switch, ModalTask, setPrintBrand, useModuleViewLabel, ModuleLayoutProvider, AppShell, PageTransition, PickerDialog, MarkdownEditor, PhoneField, isCreateRoute, PageSubNav, MobileScrim, createFayzTheme, Avatar, AvatarImage, AvatarFallback, Markdown, PageTrail, CardTitle, CardDescription, DropdownSub, DropdownSubTrigger, DropdownSubContent, DropdownRadioGroup, DropdownRadioItem, BottomSheet, CardHeader, CardFooter, SegmentedControl, Separator, SheetCard, SheetRow, useSheetClose } from '@fayz-ai/ui';
|
|
31
31
|
export { createFayzTheme, fayzThemePresets } from '@fayz-ai/ui';
|
|
32
32
|
import { useAuthStore, useAuth, buildAppHandoffUrl } from '@fayz-ai/auth';
|
|
33
33
|
export { useAuth } from '@fayz-ai/auth';
|
|
@@ -22345,6 +22345,84 @@ function RecordMetaFooter({
|
|
|
22345
22345
|
}
|
|
22346
22346
|
);
|
|
22347
22347
|
}
|
|
22348
|
+
function resolveTabIcon(name) {
|
|
22349
|
+
const icon = LucideIcons[name];
|
|
22350
|
+
return typeof icon === "function" || typeof icon === "object" ? icon ?? null : null;
|
|
22351
|
+
}
|
|
22352
|
+
function statusLabel(entityDef, value) {
|
|
22353
|
+
const options = entityDef.fields.find((f) => f.key === "status")?.options;
|
|
22354
|
+
if (Array.isArray(options)) {
|
|
22355
|
+
for (const option of options) {
|
|
22356
|
+
if (typeof option === "string") {
|
|
22357
|
+
if (option === value) return option;
|
|
22358
|
+
} else if (option.value === value) {
|
|
22359
|
+
return option.label;
|
|
22360
|
+
}
|
|
22361
|
+
}
|
|
22362
|
+
}
|
|
22363
|
+
return typeof value === "string" ? value.charAt(0).toUpperCase() + value.slice(1) : value;
|
|
22364
|
+
}
|
|
22365
|
+
function RecordHeader({ entityDef, item, title, parentLabel, onBack, badges, actions }) {
|
|
22366
|
+
const t = useTranslation();
|
|
22367
|
+
const myPersonId = useMyPersonId(entityDef.layout === "person");
|
|
22368
|
+
const isMyRecord = Boolean(myPersonId) && myPersonId === item.id;
|
|
22369
|
+
const imageValue = entityDef.image?.get(item) ?? (entityDef.imageField ? item[entityDef.imageField] : null);
|
|
22370
|
+
const customAvatar = entityDef.renderAvatar ? entityDef.renderAvatar(item) : null;
|
|
22371
|
+
const subtitle = entityDef.subtitleField ? item[entityDef.subtitleField] : null;
|
|
22372
|
+
const activeValue = item.isActive ?? item.is_active;
|
|
22373
|
+
const showStatus = Boolean(item.status) && entityDef.fields.some((f) => f.key === "status");
|
|
22374
|
+
const hasChips = isMyRecord || showStatus || activeValue !== void 0 || Boolean(badges);
|
|
22375
|
+
const chips = hasChips ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22376
|
+
isMyRecord && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0", children: t("common.you") }),
|
|
22377
|
+
showStatus && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0", children: statusLabel(entityDef, item.status) }),
|
|
22378
|
+
activeValue !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: activeValue ? "success" : "destructive", className: "shrink-0", children: activeValue ? t("common.active") : t("common.inactive") }),
|
|
22379
|
+
badges
|
|
22380
|
+
] }) : null;
|
|
22381
|
+
const thumb = !customAvatar && imageValue ? /* @__PURE__ */ jsx("img", { src: imageValue, alt: "", className: "mr-0.5 h-6 w-6 rounded-md object-cover" }) : void 0;
|
|
22382
|
+
const trailing = subtitle || chips ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22383
|
+
subtitle && /* @__PURE__ */ jsx("span", { className: "truncate text-muted-foreground", children: subtitle }),
|
|
22384
|
+
chips
|
|
22385
|
+
] }) : void 0;
|
|
22386
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22387
|
+
/* @__PURE__ */ jsx(
|
|
22388
|
+
SubpageHeader,
|
|
22389
|
+
{
|
|
22390
|
+
title,
|
|
22391
|
+
parentLabel,
|
|
22392
|
+
onBack,
|
|
22393
|
+
actions,
|
|
22394
|
+
titleLeading: thumb,
|
|
22395
|
+
titleTrailing: trailing
|
|
22396
|
+
}
|
|
22397
|
+
),
|
|
22398
|
+
customAvatar && /* @__PURE__ */ jsx("div", { className: "mb-4 flex items-center", children: customAvatar }),
|
|
22399
|
+
(thumb || trailing) && /* @__PURE__ */ jsxs("div", { className: "mb-3 flex flex-wrap items-center gap-2 text-sm md:hidden", children: [
|
|
22400
|
+
thumb,
|
|
22401
|
+
trailing
|
|
22402
|
+
] })
|
|
22403
|
+
] });
|
|
22404
|
+
}
|
|
22405
|
+
function RecordTabStrip({ tabs, compact }) {
|
|
22406
|
+
const t = useTranslation();
|
|
22407
|
+
const trigger = `gap-1.5 ${compact ? "text-xs px-2 py-1" : ""}`;
|
|
22408
|
+
const iconSize = compact ? "h-3 w-3" : "h-3.5 w-3.5";
|
|
22409
|
+
return /* @__PURE__ */ jsxs(TabsList, { className: `max-w-full justify-start overflow-x-auto scrollbar-none${compact ? " h-8" : ""}`, children: [
|
|
22410
|
+
/* @__PURE__ */ jsxs(TabsTrigger, { value: "overview", className: trigger, children: [
|
|
22411
|
+
/* @__PURE__ */ jsx(Eye, { className: iconSize }),
|
|
22412
|
+
t("common.overview")
|
|
22413
|
+
] }),
|
|
22414
|
+
tabs.map((tab) => {
|
|
22415
|
+
const translated = t(`crud.tabs.${tab.id}`);
|
|
22416
|
+
const label3 = translated.startsWith("crud.tabs.") ? tab.label : translated;
|
|
22417
|
+
const TabIcon = tab.icon ? resolveTabIcon(tab.icon) : null;
|
|
22418
|
+
return /* @__PURE__ */ jsxs(TabsTrigger, { value: tab.id, className: trigger, children: [
|
|
22419
|
+
TabIcon && /* @__PURE__ */ jsx(TabIcon, { className: iconSize }),
|
|
22420
|
+
label3,
|
|
22421
|
+
tab.count ? /* @__PURE__ */ jsx("span", { className: `rounded-full bg-muted px-1.5 tabular-nums text-muted-foreground ${compact ? "text-[9px]" : "text-[10px]"}`, children: tab.count }) : null
|
|
22422
|
+
] }, tab.id);
|
|
22423
|
+
})
|
|
22424
|
+
] });
|
|
22425
|
+
}
|
|
22348
22426
|
|
|
22349
22427
|
// src/crud/entity-zone.ts
|
|
22350
22428
|
function entityZoneId(entityDef) {
|
|
@@ -23218,7 +23296,7 @@ function PersonFormLayout({ fields: allFields, fieldGroups, values, onChange, re
|
|
|
23218
23296
|
] }),
|
|
23219
23297
|
recordId && /* @__PURE__ */ jsxs("div", { children: [
|
|
23220
23298
|
/* @__PURE__ */ jsx(AddressesSection, { item: { id: recordId } }),
|
|
23221
|
-
/* @__PURE__ */ jsx("div", { className: "mt-5", children: /* @__PURE__ */ jsx(PayeeAccountsSection, { item: { id: recordId } }) })
|
|
23299
|
+
allFields.some((f) => f.type === "bank") && /* @__PURE__ */ jsx("div", { className: "mt-5", children: /* @__PURE__ */ jsx(PayeeAccountsSection, { item: { id: recordId } }) })
|
|
23222
23300
|
] }),
|
|
23223
23301
|
notesField && /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: cardPad, children: /* @__PURE__ */ jsx(FieldItem, { field: notesField, value: values[notesField.key], values, onChange: (val) => onChange(notesField.key, val), renderField: renderField2, compact }) }) })
|
|
23224
23302
|
] });
|
|
@@ -25428,7 +25506,7 @@ function CrudFormPage(props) {
|
|
|
25428
25506
|
const { provider: provider2, flush } = usePendingChildren();
|
|
25429
25507
|
return /* @__PURE__ */ jsx(PendingChildrenProvider, { value: provider2, children: /* @__PURE__ */ jsx(CrudFormPageBody, { ...props, flushPending: flush }) });
|
|
25430
25508
|
}
|
|
25431
|
-
function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onCancel, namePlural, embedded, hideBreadcrumb, formId, hideActions, essentialFirst, noForm, submitRef, flushPending }) {
|
|
25509
|
+
function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onCancel, namePlural, embedded, hideBreadcrumb, onRecordTab, formId, hideActions, essentialFirst, noForm, submitRef, flushPending }) {
|
|
25432
25510
|
const t = useTranslation();
|
|
25433
25511
|
const formFields = entityDef.fields.filter((f) => f.showInForm !== false);
|
|
25434
25512
|
const displayField = entityDef.displayField ?? entityDef.fields[0]?.key ?? "id";
|
|
@@ -25592,6 +25670,35 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25592
25670
|
}
|
|
25593
25671
|
}, [invalidKeys]);
|
|
25594
25672
|
const groupsOfTab = (name) => groups.filter((g) => !sideGroupIds.has(g.id) && (g.tab ?? FIRST_TAB) === name);
|
|
25673
|
+
const recordItem = React133__default.useMemo(() => ({ ...initialData ?? {}, ...values }), [initialData, values]);
|
|
25674
|
+
const record = useRecordTabs(entityDef, mode === "edit" ? recordItem : null);
|
|
25675
|
+
const showRecordTabs = !embedded && mode === "edit" && Boolean(onRecordTab) && Boolean(initialData?.id);
|
|
25676
|
+
const formHoldsTabs = tabbed && tabNames.length > 1 && (!entityDef.layout || entityDef.layout === "location");
|
|
25677
|
+
const FORM_TAB = "form:";
|
|
25678
|
+
const stripTabs = [];
|
|
25679
|
+
if (showRecordTabs) {
|
|
25680
|
+
const sections = formHoldsTabs ? tabNames.filter((name) => name !== FIRST_TAB) : [];
|
|
25681
|
+
const placed = /* @__PURE__ */ new Set();
|
|
25682
|
+
let afterSections = 0;
|
|
25683
|
+
for (const tab of record.customTabs) {
|
|
25684
|
+
if (tab.id.startsWith("fields:")) {
|
|
25685
|
+
if (!sections.includes(tab.label)) continue;
|
|
25686
|
+
stripTabs.push({ id: FORM_TAB + tab.label, label: tab.label, icon: tab.icon });
|
|
25687
|
+
placed.add(tab.label);
|
|
25688
|
+
afterSections = stripTabs.length;
|
|
25689
|
+
} else {
|
|
25690
|
+
stripTabs.push({ id: tab.id, label: tab.label, icon: tab.icon, count: record.tabCounts[tab.id] });
|
|
25691
|
+
}
|
|
25692
|
+
}
|
|
25693
|
+
const missing = sections.filter((name) => !placed.has(name)).map((name) => ({ id: FORM_TAB + name, label: name }));
|
|
25694
|
+
stripTabs.splice(afterSections, 0, ...missing);
|
|
25695
|
+
}
|
|
25696
|
+
const stripValue = formHoldsTabs && currentTab !== FIRST_TAB ? FORM_TAB + currentTab : "overview";
|
|
25697
|
+
const onStripChange = (id) => {
|
|
25698
|
+
if (id === "overview") setActiveTab(FIRST_TAB);
|
|
25699
|
+
else if (id.startsWith(FORM_TAB)) setActiveTab(id.slice(FORM_TAB.length));
|
|
25700
|
+
else onRecordTab?.(id);
|
|
25701
|
+
};
|
|
25595
25702
|
const archetypeLayoutProps = {
|
|
25596
25703
|
fields: archetypeFields,
|
|
25597
25704
|
allFields: entityDef.fields,
|
|
@@ -25653,7 +25760,7 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25653
25760
|
if (tabbed && tabNames.length > 1) {
|
|
25654
25761
|
return withSideRail(
|
|
25655
25762
|
/* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
|
|
25656
|
-
/* @__PURE__ */ jsx(
|
|
25763
|
+
!showRecordTabs && /* @__PURE__ */ jsx(
|
|
25657
25764
|
ViewTabs,
|
|
25658
25765
|
{
|
|
25659
25766
|
value: currentTab,
|
|
@@ -25677,18 +25784,32 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25677
25784
|
}
|
|
25678
25785
|
}
|
|
25679
25786
|
const trailParent = usePageTrailParent();
|
|
25680
|
-
const
|
|
25787
|
+
const cancelAction = /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: onCancel, disabled: saving, children: t("common.cancel") });
|
|
25788
|
+
const headerBack = trailParent ? () => navigateToCrumb(trailParent) : onCancel;
|
|
25789
|
+
const header = embedded || hideBreadcrumb ? null : mode === "edit" ? /* @__PURE__ */ jsx(
|
|
25790
|
+
RecordHeader,
|
|
25791
|
+
{
|
|
25792
|
+
entityDef,
|
|
25793
|
+
item: recordItem,
|
|
25794
|
+
title: String(breadcrumbLabel),
|
|
25795
|
+
parentLabel: trailParent?.label ?? namePlural,
|
|
25796
|
+
onBack: headerBack,
|
|
25797
|
+
actions: cancelAction
|
|
25798
|
+
}
|
|
25799
|
+
) : /* @__PURE__ */ jsx(
|
|
25681
25800
|
SubpageHeader,
|
|
25682
25801
|
{
|
|
25683
25802
|
title: breadcrumbLabel,
|
|
25684
25803
|
parentLabel: trailParent?.label ?? namePlural,
|
|
25685
|
-
onBack:
|
|
25804
|
+
onBack: headerBack,
|
|
25805
|
+
actions: cancelAction
|
|
25686
25806
|
}
|
|
25687
|
-
)
|
|
25807
|
+
);
|
|
25688
25808
|
const FieldsTag = noForm ? "div" : "form";
|
|
25689
|
-
return /* @__PURE__ */ jsx(SetFieldValueContext.Provider, { value: handleChange, children: /* @__PURE__ */
|
|
25690
|
-
header,
|
|
25691
|
-
/* @__PURE__ */
|
|
25809
|
+
return /* @__PURE__ */ jsx(SetFieldValueContext.Provider, { value: handleChange, children: /* @__PURE__ */ jsxs("div", { className: `w-full flex flex-col items-center ${embedded ? "text-sm" : "pb-28"}`, children: [
|
|
25810
|
+
header && /* @__PURE__ */ jsx("div", { className: "w-full", children: header }),
|
|
25811
|
+
showRecordTabs && /* @__PURE__ */ jsx(Tabs, { value: stripValue, onValueChange: onStripChange, className: "mb-4 w-full", children: /* @__PURE__ */ jsx(RecordTabStrip, { tabs: stripTabs }) }),
|
|
25812
|
+
/* @__PURE__ */ jsx("div", { className: `fz-container w-full pb-24 ${embedded ? "space-y-3" : entityDef.formColumns === 2 ? "max-w-6xl space-y-5" : "max-w-3xl space-y-5"}`, children: /* @__PURE__ */ jsxs(
|
|
25692
25813
|
FieldsTag,
|
|
25693
25814
|
{
|
|
25694
25815
|
...noForm ? {} : { id: formId, onSubmit: handleSubmit },
|
|
@@ -25735,31 +25856,27 @@ function CrudFormPageBody({ entityDef, mode, initialData, onSubmit, onSaved, onC
|
|
|
25735
25856
|
] })
|
|
25736
25857
|
]
|
|
25737
25858
|
}
|
|
25738
|
-
)
|
|
25739
|
-
] }) })
|
|
25859
|
+
) })
|
|
25860
|
+
] }) });
|
|
25861
|
+
}
|
|
25862
|
+
function TabStripSkeleton() {
|
|
25863
|
+
return /* @__PURE__ */ jsxs("div", { className: "inline-flex h-10 items-center gap-1 rounded-button bg-muted p-1", children: [
|
|
25864
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 w-28 rounded-button bg-background" }),
|
|
25865
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 w-16 mx-3 rounded bg-muted-foreground/15" }),
|
|
25866
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 w-20 mx-3 rounded bg-muted-foreground/15" }),
|
|
25867
|
+
/* @__PURE__ */ jsx("div", { className: "h-3 w-14 mx-3 rounded bg-muted-foreground/15" })
|
|
25868
|
+
] });
|
|
25740
25869
|
}
|
|
25741
25870
|
function CrudDetailSkeleton(_props = {}) {
|
|
25742
25871
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-6 animate-pulse", children: [
|
|
25743
|
-
/* @__PURE__ */
|
|
25744
|
-
/* @__PURE__ */ jsx("div", { className: "h-20 w-20 shrink-0 rounded-2xl bg-muted" }),
|
|
25745
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2 pt-1", children: [
|
|
25746
|
-
/* @__PURE__ */ jsx("div", { className: "h-7 w-48 rounded bg-muted" }),
|
|
25747
|
-
/* @__PURE__ */ jsx("div", { className: "h-4 w-32 rounded bg-muted" }),
|
|
25748
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1 h-5 w-16 rounded-full bg-muted" })
|
|
25749
|
-
] })
|
|
25750
|
-
] }),
|
|
25751
|
-
/* @__PURE__ */ jsx("div", { className: "h-px bg-border" }),
|
|
25752
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
25753
|
-
/* @__PURE__ */ jsx("div", { className: "h-8 w-20 rounded bg-muted" }),
|
|
25754
|
-
/* @__PURE__ */ jsx("div", { className: "h-8 w-24 rounded bg-muted" })
|
|
25755
|
-
] }),
|
|
25872
|
+
/* @__PURE__ */ jsx(TabStripSkeleton, {}),
|
|
25756
25873
|
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx("div", { className: "divide-y", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-4 px-5 py-3", children: [
|
|
25757
25874
|
/* @__PURE__ */ jsx("div", { className: "h-4 w-20 rounded bg-muted" }),
|
|
25758
25875
|
/* @__PURE__ */ jsx("div", { className: "col-span-2 h-4 w-32 rounded bg-muted" })
|
|
25759
25876
|
] }, i)) }) })
|
|
25760
25877
|
] });
|
|
25761
25878
|
}
|
|
25762
|
-
function CrudFormSkeleton({ groups = 2, twoColumn } = {}) {
|
|
25879
|
+
function CrudFormSkeleton({ groups = 2, twoColumn, tabs } = {}) {
|
|
25763
25880
|
const section = (key, rows) => /* @__PURE__ */ jsxs(Card, { className: "p-5", children: [
|
|
25764
25881
|
/* @__PURE__ */ jsx("div", { className: "mb-4 h-4 w-32 rounded bg-muted" }),
|
|
25765
25882
|
/* @__PURE__ */ jsx("div", { className: "fz-fields fz-fields-2 gap-4", children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
@@ -25768,10 +25885,13 @@ function CrudFormSkeleton({ groups = 2, twoColumn } = {}) {
|
|
|
25768
25885
|
] }, i)) })
|
|
25769
25886
|
] }, key);
|
|
25770
25887
|
const main = /* @__PURE__ */ jsx("div", { className: "space-y-5", children: Array.from({ length: groups }).map((_, i) => section(i, i === 0 ? 4 : 2)) });
|
|
25771
|
-
return /* @__PURE__ */
|
|
25772
|
-
/* @__PURE__ */ jsx("div", { children:
|
|
25773
|
-
/* @__PURE__ */ jsx("div", { className:
|
|
25774
|
-
|
|
25888
|
+
return /* @__PURE__ */ jsxs("div", { className: "w-full animate-pulse", children: [
|
|
25889
|
+
tabs && /* @__PURE__ */ jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsx(TabStripSkeleton, {}) }),
|
|
25890
|
+
/* @__PURE__ */ jsx("div", { className: `fz-container mx-auto w-full space-y-5 ${twoColumn ? "max-w-6xl" : "max-w-3xl"}`, children: twoColumn ? /* @__PURE__ */ jsxs("div", { className: "fz-split", children: [
|
|
25891
|
+
/* @__PURE__ */ jsx("div", { children: main }),
|
|
25892
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-5", children: section(99, 2) })
|
|
25893
|
+
] }) : main })
|
|
25894
|
+
] });
|
|
25775
25895
|
}
|
|
25776
25896
|
function formatValue2(field, value) {
|
|
25777
25897
|
if (value == null || value === "") return null;
|
|
@@ -27027,7 +27147,7 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
27027
27147
|
const item = store.getById(id);
|
|
27028
27148
|
viewKey = `edit-${id}`;
|
|
27029
27149
|
if (!item && store.items === null) {
|
|
27030
|
-
content = /* @__PURE__ */ jsx(CrudFormSkeleton, { twoColumn: entityDef.formColumns === 2 });
|
|
27150
|
+
content = /* @__PURE__ */ jsx(CrudFormSkeleton, { twoColumn: entityDef.formColumns === 2, tabs: true });
|
|
27031
27151
|
} else if (!item) {
|
|
27032
27152
|
content = /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
27033
27153
|
/* @__PURE__ */ jsxs("nav", { className: "flex items-center gap-1.5 text-sm text-muted-foreground", children: [
|
|
@@ -27052,6 +27172,9 @@ function CrudPage({ entityDef: rawEntityDef, useStore: useStore2, basePath, disp
|
|
|
27052
27172
|
onCancel: () => {
|
|
27053
27173
|
setCrudHash(normalizedBasePath, id);
|
|
27054
27174
|
},
|
|
27175
|
+
onRecordTab: (tab) => {
|
|
27176
|
+
setCrudHash(normalizedBasePath, id, tab);
|
|
27177
|
+
},
|
|
27055
27178
|
onSubmit: async (data) => {
|
|
27056
27179
|
await store.update(id, data);
|
|
27057
27180
|
setCrudHash(normalizedBasePath, id);
|
|
@@ -29214,22 +29337,52 @@ function resolveActiveTab(initialTab, tabs) {
|
|
|
29214
29337
|
const alias = tabs.find((tab) => tab.aliases?.includes(normalized));
|
|
29215
29338
|
return alias?.id ?? "overview";
|
|
29216
29339
|
}
|
|
29217
|
-
function
|
|
29218
|
-
const
|
|
29219
|
-
|
|
29220
|
-
|
|
29221
|
-
|
|
29222
|
-
|
|
29223
|
-
|
|
29224
|
-
|
|
29225
|
-
|
|
29226
|
-
|
|
29227
|
-
|
|
29228
|
-
|
|
29229
|
-
|
|
29340
|
+
function useRecordTabs(entityDef, item) {
|
|
29341
|
+
const runtime = usePluginRuntimeOptional();
|
|
29342
|
+
const archetypeTabs = getArchetypeTabs(entityDef.layout, entityDef.data?.archetypeKind);
|
|
29343
|
+
const relatedTabs = (entityDef.relatedLists ?? []).map((related) => ({
|
|
29344
|
+
id: relatedListTabId(related),
|
|
29345
|
+
label: related.label ?? related.entity.namePlural ?? related.entity.name,
|
|
29346
|
+
icon: related.icon ?? related.entity.icon,
|
|
29347
|
+
component: (props) => /* @__PURE__ */ jsx(RelatedListTab, { ...props, related })
|
|
29348
|
+
}));
|
|
29349
|
+
const unitMode = useUnitMode();
|
|
29350
|
+
const fieldGroupTabs = React133__default.useMemo(() => {
|
|
29351
|
+
const groups = entityDef.fieldGroups ?? [];
|
|
29352
|
+
if (!groups.some((g) => g.tab) || !item) return [];
|
|
29353
|
+
const applicable = new Set(visibleDetailFields(entityDef, item).map((f) => f.group));
|
|
29354
|
+
const byTab = /* @__PURE__ */ new Map();
|
|
29355
|
+
const iconOf = /* @__PURE__ */ new Map();
|
|
29356
|
+
for (const g of groups) {
|
|
29357
|
+
if (!g.tab || !applicable.has(g.id)) continue;
|
|
29358
|
+
byTab.set(g.tab, [...byTab.get(g.tab) ?? [], g.id]);
|
|
29359
|
+
if (!iconOf.has(g.tab)) iconOf.set(g.tab, g.tabIcon);
|
|
29230
29360
|
}
|
|
29231
|
-
|
|
29232
|
-
|
|
29361
|
+
return [...byTab.entries()].map(([label3, groupIds]) => ({
|
|
29362
|
+
id: `fields:${groupIds[0]}`,
|
|
29363
|
+
label: label3,
|
|
29364
|
+
icon: iconOf.get(label3),
|
|
29365
|
+
component: (props) => /* @__PURE__ */ jsx(
|
|
29366
|
+
FieldGroupTab,
|
|
29367
|
+
{
|
|
29368
|
+
entityDef: props.entityDef,
|
|
29369
|
+
item: props.item,
|
|
29370
|
+
groupIds,
|
|
29371
|
+
onFieldSave: props.onFieldSave,
|
|
29372
|
+
pendingKeys: props.pendingKeys
|
|
29373
|
+
}
|
|
29374
|
+
)
|
|
29375
|
+
}));
|
|
29376
|
+
}, [entityDef, item]);
|
|
29377
|
+
const customTabs = filterRuntimeTabs(
|
|
29378
|
+
mergeDetailTabs(archetypeTabs, [...fieldGroupTabs, ...relatedTabs, ...entityDef.detailTabs ?? []]),
|
|
29379
|
+
{
|
|
29380
|
+
hasWidget: (zone) => runtime ? getWidgetsForZone(runtime, zone).length > 0 : false,
|
|
29381
|
+
unitMode
|
|
29382
|
+
}
|
|
29383
|
+
);
|
|
29384
|
+
const tabCounts = usePersonTabCounts(entityDef.layout === "person" ? item?.id : void 0);
|
|
29385
|
+
return { customTabs, tabCounts };
|
|
29233
29386
|
}
|
|
29234
29387
|
function CrudDetailPage({
|
|
29235
29388
|
entityDef,
|
|
@@ -29305,50 +29458,7 @@ function CrudDetailPage({
|
|
|
29305
29458
|
const nameEditable = Boolean(onFieldSave || onFieldsSave) && Boolean(displayFieldDef) && isInlineEditable(displayFieldDef);
|
|
29306
29459
|
const [editingName, setEditingName] = useState(false);
|
|
29307
29460
|
const imageInputRef = React133__default.useRef(null);
|
|
29308
|
-
const
|
|
29309
|
-
const archetypeTabs = getArchetypeTabs(entityDef.layout, entityDef.data?.archetypeKind);
|
|
29310
|
-
const relatedTabs = (entityDef.relatedLists ?? []).map((related) => ({
|
|
29311
|
-
id: relatedListTabId(related),
|
|
29312
|
-
label: related.label ?? related.entity.namePlural ?? related.entity.name,
|
|
29313
|
-
icon: related.icon ?? related.entity.icon,
|
|
29314
|
-
component: (props) => /* @__PURE__ */ jsx(RelatedListTab, { ...props, related })
|
|
29315
|
-
}));
|
|
29316
|
-
const unitMode = useUnitMode();
|
|
29317
|
-
const fieldGroupTabs = React133__default.useMemo(() => {
|
|
29318
|
-
const groups = entityDef.fieldGroups ?? [];
|
|
29319
|
-
if (!groups.some((g) => g.tab) || !item) return [];
|
|
29320
|
-
const applicable = new Set(visibleDetailFields(entityDef, item).map((f) => f.group));
|
|
29321
|
-
const byTab = /* @__PURE__ */ new Map();
|
|
29322
|
-
const iconOf = /* @__PURE__ */ new Map();
|
|
29323
|
-
for (const g of groups) {
|
|
29324
|
-
if (!g.tab || !applicable.has(g.id)) continue;
|
|
29325
|
-
byTab.set(g.tab, [...byTab.get(g.tab) ?? [], g.id]);
|
|
29326
|
-
if (!iconOf.has(g.tab)) iconOf.set(g.tab, g.tabIcon);
|
|
29327
|
-
}
|
|
29328
|
-
return [...byTab.entries()].map(([label3, groupIds]) => ({
|
|
29329
|
-
id: `fields:${groupIds[0]}`,
|
|
29330
|
-
label: label3,
|
|
29331
|
-
icon: iconOf.get(label3),
|
|
29332
|
-
component: (props) => /* @__PURE__ */ jsx(
|
|
29333
|
-
FieldGroupTab,
|
|
29334
|
-
{
|
|
29335
|
-
entityDef: props.entityDef,
|
|
29336
|
-
item: props.item,
|
|
29337
|
-
groupIds,
|
|
29338
|
-
onFieldSave: props.onFieldSave,
|
|
29339
|
-
pendingKeys: props.pendingKeys
|
|
29340
|
-
}
|
|
29341
|
-
)
|
|
29342
|
-
}));
|
|
29343
|
-
}, [entityDef, item]);
|
|
29344
|
-
const customTabs = filterRuntimeTabs(
|
|
29345
|
-
mergeDetailTabs(archetypeTabs, [...fieldGroupTabs, ...relatedTabs, ...entityDef.detailTabs ?? []]),
|
|
29346
|
-
{
|
|
29347
|
-
hasWidget: (zone) => runtime ? getWidgetsForZone(runtime, zone).length > 0 : false,
|
|
29348
|
-
unitMode
|
|
29349
|
-
}
|
|
29350
|
-
);
|
|
29351
|
-
const tabCounts = usePersonTabCounts(entityDef.layout === "person" ? item?.id : void 0);
|
|
29461
|
+
const { customTabs, tabCounts } = useRecordTabs(entityDef, item);
|
|
29352
29462
|
const entityId = entityZoneId(entityDef);
|
|
29353
29463
|
const legacyEntityId = legacyEntityZoneId(entityDef);
|
|
29354
29464
|
const widgetZone = `${entityId}.detail.tabs`;
|
|
@@ -29398,176 +29508,169 @@ function CrudDetailPage({
|
|
|
29398
29508
|
}, [basePath, item.id, selectedTab, embedded]);
|
|
29399
29509
|
const parentLabel = usePresetLabel(basePath, namePlural);
|
|
29400
29510
|
const headerNode = React133__default.useMemo(
|
|
29401
|
-
() => embedded ? null : /* @__PURE__ */ jsx(
|
|
29402
|
-
[embedded, displayValue, parentLabel, onBack]
|
|
29511
|
+
() => embedded ? null : /* @__PURE__ */ jsx(RecordHeader, { entityDef, item: view, title: String(displayValue), parentLabel, onBack, badges }),
|
|
29512
|
+
[embedded, entityDef, view, displayValue, parentLabel, onBack, badges]
|
|
29403
29513
|
);
|
|
29514
|
+
const actionsNode = /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(ActionSlot, { embedded, children: [
|
|
29515
|
+
/* @__PURE__ */ jsx(WidgetSlot, { zone: headerActionsZone, item, entityId, embedded }),
|
|
29516
|
+
/* @__PURE__ */ jsx(
|
|
29517
|
+
PageActions,
|
|
29518
|
+
{
|
|
29519
|
+
actions: [
|
|
29520
|
+
...onEdit ? [{ id: "edit", label: t("common.edit"), icon: Edit, intent: "primary", onSelect: onEdit }] : [],
|
|
29521
|
+
...extraActions ?? [],
|
|
29522
|
+
...declared,
|
|
29523
|
+
// Plugin contributions join the set instead of standing beside it,
|
|
29524
|
+
// so they fold into the caret and the phone's menu like the rest.
|
|
29525
|
+
...contributed,
|
|
29526
|
+
...onDelete ? [{ id: "delete", label: t("common.delete"), icon: Trash2, intent: "danger", onSelect: onDelete }] : []
|
|
29527
|
+
]
|
|
29528
|
+
}
|
|
29529
|
+
)
|
|
29530
|
+
] }) });
|
|
29404
29531
|
return (
|
|
29405
29532
|
// A largura que importa é a desta coluna — o assistente ocupa metade da
|
|
29406
29533
|
// tela e o `lg:` da janela nunca soube disso.
|
|
29407
|
-
/* @__PURE__ */ jsxs(
|
|
29534
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
29408
29535
|
headerNode,
|
|
29409
|
-
/* @__PURE__ */ jsxs("div", { className: `
|
|
29410
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
29411
|
-
|
|
29412
|
-
|
|
29413
|
-
|
|
29414
|
-
src: imageValue,
|
|
29415
|
-
alt: displayValue,
|
|
29416
|
-
className: `shrink-0 object-cover shadow-sm ${embedded ? "h-10 w-10 rounded-xl" : "h-20 w-20 rounded-2xl"}`
|
|
29417
|
-
}
|
|
29418
|
-
) : /* @__PURE__ */ jsx("div", { className: `flex shrink-0 items-center justify-center bg-primary/10 text-primary font-bold shadow-sm ${embedded ? "h-10 w-10 rounded-xl text-sm" : "h-20 w-20 rounded-2xl text-2xl"}`, children: initial }),
|
|
29419
|
-
onImageChange && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
29420
|
-
/* @__PURE__ */ jsx(
|
|
29421
|
-
"button",
|
|
29536
|
+
/* @__PURE__ */ jsxs("div", { className: `fz-container ${embedded ? "space-y-4" : "space-y-6"}`, children: [
|
|
29537
|
+
embedded && /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
29538
|
+
/* @__PURE__ */ jsxs("div", { className: "relative shrink-0", children: [
|
|
29539
|
+
entityDef.renderAvatar ? entityDef.renderAvatar(item) : imageValue ? /* @__PURE__ */ jsx(
|
|
29540
|
+
"img",
|
|
29422
29541
|
{
|
|
29423
|
-
|
|
29424
|
-
|
|
29425
|
-
"
|
|
29426
|
-
className: `absolute -bottom-1 -right-1 flex items-center justify-center rounded-full border-2 border-background bg-primary text-primary-foreground transition-colors hover:bg-primary/90 ${embedded ? "h-6 w-6" : "h-8 w-8"}`,
|
|
29427
|
-
children: /* @__PURE__ */ jsx(Camera, { className: embedded ? "h-3 w-3" : "h-3.5 w-3.5" })
|
|
29542
|
+
src: imageValue,
|
|
29543
|
+
alt: displayValue,
|
|
29544
|
+
className: `shrink-0 object-cover shadow-sm ${embedded ? "h-10 w-10 rounded-xl" : "h-20 w-20 rounded-2xl"}`
|
|
29428
29545
|
}
|
|
29429
|
-
),
|
|
29430
|
-
/* @__PURE__ */
|
|
29431
|
-
|
|
29432
|
-
|
|
29433
|
-
|
|
29434
|
-
|
|
29435
|
-
|
|
29436
|
-
|
|
29437
|
-
|
|
29438
|
-
|
|
29439
|
-
|
|
29440
|
-
|
|
29546
|
+
) : /* @__PURE__ */ jsx("div", { className: `flex shrink-0 items-center justify-center bg-primary/10 text-primary font-bold shadow-sm ${embedded ? "h-10 w-10 rounded-xl text-sm" : "h-20 w-20 rounded-2xl text-2xl"}`, children: initial }),
|
|
29547
|
+
onImageChange && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
29548
|
+
/* @__PURE__ */ jsx(
|
|
29549
|
+
"button",
|
|
29550
|
+
{
|
|
29551
|
+
type: "button",
|
|
29552
|
+
onClick: () => imageInputRef.current?.click(),
|
|
29553
|
+
"aria-label": t("common.edit"),
|
|
29554
|
+
className: `absolute -bottom-1 -right-1 flex items-center justify-center rounded-full border-2 border-background bg-primary text-primary-foreground transition-colors hover:bg-primary/90 ${embedded ? "h-6 w-6" : "h-8 w-8"}`,
|
|
29555
|
+
children: /* @__PURE__ */ jsx(Camera, { className: embedded ? "h-3 w-3" : "h-3.5 w-3.5" })
|
|
29556
|
+
}
|
|
29557
|
+
),
|
|
29558
|
+
/* @__PURE__ */ jsx(
|
|
29559
|
+
"input",
|
|
29560
|
+
{
|
|
29561
|
+
ref: imageInputRef,
|
|
29562
|
+
type: "file",
|
|
29563
|
+
accept: "image/*",
|
|
29564
|
+
className: "hidden",
|
|
29565
|
+
onChange: (e) => {
|
|
29566
|
+
const file = e.target.files?.[0];
|
|
29567
|
+
if (file) void onImageChange(file);
|
|
29568
|
+
if (e.target) e.target.value = "";
|
|
29569
|
+
}
|
|
29441
29570
|
}
|
|
29571
|
+
)
|
|
29572
|
+
] })
|
|
29573
|
+
] }),
|
|
29574
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
29575
|
+
/* @__PURE__ */ jsx("div", { className: "group flex items-center gap-2", children: editingName && nameEditable && displayFieldDef ? /* @__PURE__ */ jsx(
|
|
29576
|
+
InlineEditor,
|
|
29577
|
+
{
|
|
29578
|
+
field: displayFieldDef,
|
|
29579
|
+
value: displayValue,
|
|
29580
|
+
onCancel: () => setEditingName(false),
|
|
29581
|
+
onSave: async (next) => {
|
|
29582
|
+
stageField(displayField, next);
|
|
29583
|
+
},
|
|
29584
|
+
cancelLabel: t("common.cancel")
|
|
29442
29585
|
}
|
|
29443
|
-
)
|
|
29444
|
-
|
|
29586
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
29587
|
+
/* @__PURE__ */ jsx("h1", { className: `font-bold text-foreground truncate ${embedded ? "text-base" : "text-2xl"}`, children: displayValue }),
|
|
29588
|
+
nameEditable && /* @__PURE__ */ jsx(
|
|
29589
|
+
"button",
|
|
29590
|
+
{
|
|
29591
|
+
type: "button",
|
|
29592
|
+
onClick: () => setEditingName(true),
|
|
29593
|
+
"aria-label": `${t("common.edit")} ${displayFieldDef?.label ?? ""}`,
|
|
29594
|
+
title: `${t("common.edit")} ${displayFieldDef?.label ?? ""}`,
|
|
29595
|
+
className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground opacity-0 transition-opacity hover:bg-muted hover:text-foreground focus:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover:opacity-100",
|
|
29596
|
+
children: /* @__PURE__ */ jsx(Pencil, { className: "h-3 w-3" })
|
|
29597
|
+
}
|
|
29598
|
+
),
|
|
29599
|
+
isMyRecord && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0", children: t("common.you") }),
|
|
29600
|
+
item.status && entityDef.fields.some((f) => f.key === "status") && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0", children: statusLabel(entityDef, item.status) }),
|
|
29601
|
+
activeValue !== void 0 && /* @__PURE__ */ jsx(Badge, { variant: activeValue ? "success" : "destructive", className: "shrink-0", children: activeValue ? t("common.active") : t("common.inactive") }),
|
|
29602
|
+
badges
|
|
29603
|
+
] }) }),
|
|
29604
|
+
subtitleValue && /* @__PURE__ */ jsx("p", { className: `text-muted-foreground mt-0.5 ${embedded ? "text-xs" : ""}`, children: subtitleValue })
|
|
29605
|
+
] }),
|
|
29606
|
+
actionsNode
|
|
29445
29607
|
] }),
|
|
29446
|
-
|
|
29447
|
-
|
|
29448
|
-
|
|
29608
|
+
!embedded && actionsNode,
|
|
29609
|
+
pendingAction && /* @__PURE__ */ jsx(
|
|
29610
|
+
ConfirmDialog,
|
|
29611
|
+
{
|
|
29612
|
+
open: true,
|
|
29613
|
+
title: pendingAction.label,
|
|
29614
|
+
description: pendingAction.confirm,
|
|
29615
|
+
confirmLabel: pendingAction.label,
|
|
29616
|
+
cancelLabel: t("common.cancel"),
|
|
29617
|
+
variant: pendingAction.intent === "danger" ? "destructive" : "default",
|
|
29618
|
+
loading: runningAction === pendingAction.id,
|
|
29619
|
+
onConfirm: () => executeAction(pendingAction),
|
|
29620
|
+
onCancel: () => setPendingAction(null)
|
|
29621
|
+
}
|
|
29622
|
+
),
|
|
29623
|
+
/* @__PURE__ */ jsx(WidgetSlot, { zone: aboveTabsZone, item, entityId, embedded }),
|
|
29624
|
+
archetypeAboveTabsZone && archetypeAboveTabsZone !== aboveTabsZone && /* @__PURE__ */ jsx(WidgetSlot, { zone: archetypeAboveTabsZone, item, entityId, embedded }),
|
|
29625
|
+
/* @__PURE__ */ jsxs(Tabs, { value: selectedTab, onValueChange: handleTabChange, children: [
|
|
29626
|
+
/* @__PURE__ */ jsx(
|
|
29627
|
+
RecordTabStrip,
|
|
29449
29628
|
{
|
|
29450
|
-
|
|
29451
|
-
|
|
29452
|
-
onCancel: () => setEditingName(false),
|
|
29453
|
-
onSave: async (next) => {
|
|
29454
|
-
stageField(displayField, next);
|
|
29455
|
-
},
|
|
29456
|
-
cancelLabel: t("common.cancel")
|
|
29629
|
+
compact: embedded,
|
|
29630
|
+
tabs: customTabs.map((tab) => ({ id: tab.id, label: tab.label, icon: tab.icon, count: tabCounts[tab.id] }))
|
|
29457
29631
|
}
|
|
29458
|
-
)
|
|
29459
|
-
|
|
29460
|
-
|
|
29461
|
-
|
|
29632
|
+
),
|
|
29633
|
+
/* @__PURE__ */ jsxs(TabsContent, { value: "overview", className: embedded ? "mt-2" : "mt-4", children: [
|
|
29634
|
+
entityDef.overviewComponent ? React133__default.createElement(entityDef.overviewComponent, { item, entityDef }) : /* @__PURE__ */ jsx(
|
|
29635
|
+
OverviewTab,
|
|
29462
29636
|
{
|
|
29463
|
-
|
|
29464
|
-
|
|
29465
|
-
|
|
29466
|
-
|
|
29467
|
-
|
|
29468
|
-
children: /* @__PURE__ */ jsx(Pencil, { className: "h-3 w-3" })
|
|
29637
|
+
entityDef,
|
|
29638
|
+
item: view,
|
|
29639
|
+
compact: embedded,
|
|
29640
|
+
onFieldSave: onFieldSave || onFieldsSave ? (key, value) => stageField(key, value) : void 0,
|
|
29641
|
+
pendingKeys
|
|
29469
29642
|
}
|
|
29470
29643
|
),
|
|
29471
|
-
|
|
29472
|
-
|
|
29473
|
-
|
|
29474
|
-
|
|
29475
|
-
] }) }),
|
|
29476
|
-
subtitleValue && /* @__PURE__ */ jsx("p", { className: `text-muted-foreground mt-0.5 ${embedded ? "text-xs" : ""}`, children: subtitleValue })
|
|
29477
|
-
] }),
|
|
29478
|
-
/* @__PURE__ */ jsxs(ActionSlot, { embedded, children: [
|
|
29479
|
-
/* @__PURE__ */ jsx(WidgetSlot, { zone: headerActionsZone, item, entityId, embedded }),
|
|
29480
|
-
/* @__PURE__ */ jsx(
|
|
29481
|
-
PageActions,
|
|
29482
|
-
{
|
|
29483
|
-
actions: [
|
|
29484
|
-
...onEdit ? [{ id: "edit", label: t("common.edit"), icon: Edit, intent: "primary", onSelect: onEdit }] : [],
|
|
29485
|
-
...extraActions ?? [],
|
|
29486
|
-
...declared,
|
|
29487
|
-
// Plugin contributions join the set instead of standing beside it,
|
|
29488
|
-
// so they fold into the caret and the phone's menu like the rest.
|
|
29489
|
-
...contributed,
|
|
29490
|
-
...onDelete ? [{ id: "delete", label: t("common.delete"), icon: Trash2, intent: "danger", onSelect: onDelete }] : []
|
|
29491
|
-
]
|
|
29492
|
-
}
|
|
29493
|
-
)
|
|
29494
|
-
] })
|
|
29495
|
-
] }),
|
|
29496
|
-
pendingAction && /* @__PURE__ */ jsx(
|
|
29497
|
-
ConfirmDialog,
|
|
29498
|
-
{
|
|
29499
|
-
open: true,
|
|
29500
|
-
title: pendingAction.label,
|
|
29501
|
-
description: pendingAction.confirm,
|
|
29502
|
-
confirmLabel: pendingAction.label,
|
|
29503
|
-
cancelLabel: t("common.cancel"),
|
|
29504
|
-
variant: pendingAction.intent === "danger" ? "destructive" : "default",
|
|
29505
|
-
loading: runningAction === pendingAction.id,
|
|
29506
|
-
onConfirm: () => executeAction(pendingAction),
|
|
29507
|
-
onCancel: () => setPendingAction(null)
|
|
29508
|
-
}
|
|
29509
|
-
),
|
|
29510
|
-
/* @__PURE__ */ jsx(WidgetSlot, { zone: aboveTabsZone, item, entityId, embedded }),
|
|
29511
|
-
archetypeAboveTabsZone && archetypeAboveTabsZone !== aboveTabsZone && /* @__PURE__ */ jsx(WidgetSlot, { zone: archetypeAboveTabsZone, item, entityId, embedded }),
|
|
29512
|
-
!embedded && /* @__PURE__ */ jsx(Separator, {}),
|
|
29513
|
-
/* @__PURE__ */ jsxs(Tabs, { value: selectedTab, onValueChange: handleTabChange, children: [
|
|
29514
|
-
/* @__PURE__ */ jsxs(TabsList, { className: `max-w-full justify-start overflow-x-auto scrollbar-none${embedded ? " h-8" : ""}`, children: [
|
|
29515
|
-
/* @__PURE__ */ jsxs(TabsTrigger, { value: "overview", className: `gap-1.5 ${embedded ? "text-xs px-2 py-1" : ""}`, children: [
|
|
29516
|
-
/* @__PURE__ */ jsx(Eye, { className: embedded ? "h-3 w-3" : "h-3.5 w-3.5" }),
|
|
29517
|
-
t("common.overview")
|
|
29644
|
+
entityDef.layout === "person" && item?.id && /* @__PURE__ */ jsx("div", { className: embedded ? "mt-3" : "mt-5", children: /* @__PURE__ */ jsx(AddressesTab, { item }) }),
|
|
29645
|
+
entityDef.layout === "person" && item?.id && entityDef.fields.some((f) => f.type === "bank") && /* @__PURE__ */ jsx("div", { className: embedded ? "mt-3" : "mt-5", children: /* @__PURE__ */ jsx(PayeeAccountsSection, { item }) }),
|
|
29646
|
+
entityDef.layout === "location" && item?.id && /* @__PURE__ */ jsx("div", { className: embedded ? "mt-3" : "mt-5", children: /* @__PURE__ */ jsx(AddressesTab, { item, ownerType: "unit", single: true }) }),
|
|
29647
|
+
item?.id && (entityDef.relatedSections ?? []).map((related) => /* @__PURE__ */ jsx("div", { className: embedded ? "mt-3" : "mt-5", children: /* @__PURE__ */ jsx(RelatedSection, { parentId: item.id, related, compact: embedded }) }, relatedListTabId(related)))
|
|
29518
29648
|
] }),
|
|
29519
|
-
customTabs.map((tab) => {
|
|
29520
|
-
|
|
29521
|
-
|
|
29522
|
-
|
|
29523
|
-
|
|
29524
|
-
|
|
29525
|
-
TabIcon && /* @__PURE__ */ jsx(TabIcon, { className: embedded ? "h-3 w-3" : "h-3.5 w-3.5" }),
|
|
29526
|
-
label3,
|
|
29527
|
-
count ? /* @__PURE__ */ jsx("span", { className: `rounded-full bg-muted px-1.5 tabular-nums text-muted-foreground ${embedded ? "text-[9px]" : "text-[10px]"}`, children: count }) : null
|
|
29528
|
-
] }, tab.id);
|
|
29529
|
-
})
|
|
29530
|
-
] }),
|
|
29531
|
-
/* @__PURE__ */ jsxs(TabsContent, { value: "overview", className: embedded ? "mt-2" : "mt-4", children: [
|
|
29532
|
-
entityDef.overviewComponent ? React133__default.createElement(entityDef.overviewComponent, { item, entityDef }) : /* @__PURE__ */ jsx(
|
|
29533
|
-
OverviewTab,
|
|
29534
|
-
{
|
|
29649
|
+
customTabs.map((tab) => /* @__PURE__ */ jsx(TabsContent, { value: tab.id, className: "mt-4", children: tab.component ? (
|
|
29650
|
+
// `tabPath` only to the tab the URL is actually addressing —
|
|
29651
|
+
// handing it to every tab would have the documents tab trying to
|
|
29652
|
+
// open a recording id when the user switches across.
|
|
29653
|
+
React133__default.createElement(tab.component, {
|
|
29654
|
+
item,
|
|
29535
29655
|
entityDef,
|
|
29536
|
-
|
|
29537
|
-
|
|
29538
|
-
|
|
29539
|
-
|
|
29540
|
-
|
|
29541
|
-
|
|
29542
|
-
|
|
29543
|
-
|
|
29544
|
-
|
|
29545
|
-
|
|
29656
|
+
// A rota DESTE registro. Uma aba que lista eventos precisa
|
|
29657
|
+
// saber para onde apontar cada um (`#/clients/:id/:aba`), e
|
|
29658
|
+
// só esta página sabe em que caminho o app pendurou o
|
|
29659
|
+
// cadastro — a aba não tem como descobrir.
|
|
29660
|
+
recordPath: `${basePath}/${item.id}`,
|
|
29661
|
+
// Edição inline para quem a desenha (as abas das fichas). Uma
|
|
29662
|
+
// aba que não usa isto simplesmente ignora as duas chaves.
|
|
29663
|
+
onFieldSave: onFieldSave || onFieldsSave ? stageField : void 0,
|
|
29664
|
+
pendingKeys,
|
|
29665
|
+
...tab.id === selectedTab ? { tabPath, setTabPath } : {},
|
|
29666
|
+
...tab.props ?? {}
|
|
29667
|
+
})
|
|
29668
|
+
) : /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: t("common.noContent") }) }) }) }, tab.id))
|
|
29546
29669
|
] }),
|
|
29547
|
-
|
|
29548
|
-
|
|
29549
|
-
|
|
29550
|
-
|
|
29551
|
-
React133__default.createElement(tab.component, {
|
|
29552
|
-
item,
|
|
29553
|
-
entityDef,
|
|
29554
|
-
// A rota DESTE registro. Uma aba que lista eventos precisa
|
|
29555
|
-
// saber para onde apontar cada um (`#/clients/:id/:aba`), e
|
|
29556
|
-
// só esta página sabe em que caminho o app pendurou o
|
|
29557
|
-
// cadastro — a aba não tem como descobrir.
|
|
29558
|
-
recordPath: `${basePath}/${item.id}`,
|
|
29559
|
-
// Edição inline para quem a desenha (as abas das fichas). Uma
|
|
29560
|
-
// aba que não usa isto simplesmente ignora as duas chaves.
|
|
29561
|
-
onFieldSave: onFieldSave || onFieldsSave ? stageField : void 0,
|
|
29562
|
-
pendingKeys,
|
|
29563
|
-
...tab.id === selectedTab ? { tabPath, setTabPath } : {},
|
|
29564
|
-
...tab.props ?? {}
|
|
29565
|
-
})
|
|
29566
|
-
) : /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CardContent, { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: t("common.noContent") }) }) }) }, tab.id))
|
|
29567
|
-
] }),
|
|
29568
|
-
/* @__PURE__ */ jsx(WidgetSlot, { zone: widgetZone }),
|
|
29569
|
-
legacyWidgetZone !== widgetZone && /* @__PURE__ */ jsx(WidgetSlot, { zone: legacyWidgetZone }),
|
|
29570
|
-
/* @__PURE__ */ jsx(RecordMetaFooter, { item, compact: embedded })
|
|
29670
|
+
/* @__PURE__ */ jsx(WidgetSlot, { zone: widgetZone }),
|
|
29671
|
+
legacyWidgetZone !== widgetZone && /* @__PURE__ */ jsx(WidgetSlot, { zone: legacyWidgetZone }),
|
|
29672
|
+
/* @__PURE__ */ jsx(RecordMetaFooter, { item, compact: embedded })
|
|
29673
|
+
] })
|
|
29571
29674
|
] })
|
|
29572
29675
|
);
|
|
29573
29676
|
}
|
|
@@ -34846,6 +34949,18 @@ function AdminShellInner({ appName, brandedByTenant = false, layout = "sidebar",
|
|
|
34846
34949
|
return { onBack: () => navigateTo(parent), label: label3 };
|
|
34847
34950
|
}, [match, navigation, routes, tr, settingsTabDef]);
|
|
34848
34951
|
const routeDecision = match?.route.permission && !navWaiting ? access.can(match.route.permission.feature, match.route.permission.action) : { allowed: true };
|
|
34952
|
+
const tenantIdForRoute = activeTenantId;
|
|
34953
|
+
const lastTenantRef = React133.useRef(tenantIdForRoute);
|
|
34954
|
+
const switchedTenantRef = React133.useRef(false);
|
|
34955
|
+
if (lastTenantRef.current !== tenantIdForRoute) {
|
|
34956
|
+
if (lastTenantRef.current && tenantIdForRoute) switchedTenantRef.current = true;
|
|
34957
|
+
lastTenantRef.current = tenantIdForRoute;
|
|
34958
|
+
}
|
|
34959
|
+
React133.useEffect(() => {
|
|
34960
|
+
if (!switchedTenantRef.current || navWaiting || navigation.length === 0) return;
|
|
34961
|
+
switchedTenantRef.current = false;
|
|
34962
|
+
if ((!match || !routeDecision.allowed) && path !== homeRoute) navigateTo(homeRoute);
|
|
34963
|
+
}, [tenantIdForRoute, navWaiting, navigation.length, match, routeDecision.allowed, path, homeRoute]);
|
|
34849
34964
|
const activeContent = navWaiting ? (
|
|
34850
34965
|
// O conteúdo espera pela MESMA condição que o rail.
|
|
34851
34966
|
//
|
|
@@ -36259,7 +36374,7 @@ var TONE_CLASS = {
|
|
|
36259
36374
|
info: "bg-sky-100 text-sky-800 dark:bg-sky-900/40 dark:text-sky-300",
|
|
36260
36375
|
muted: "bg-muted text-muted-foreground"
|
|
36261
36376
|
};
|
|
36262
|
-
function
|
|
36377
|
+
function Badge27({ badge, className = "" }) {
|
|
36263
36378
|
return (
|
|
36264
36379
|
// shrink-0: in the crumb it sits beside a truncating title, and without it
|
|
36265
36380
|
// a long record name eats the status instead of ellipsing itself.
|
|
@@ -36337,7 +36452,7 @@ function OrderDetailView(props) {
|
|
|
36337
36452
|
const hasBadges = badges.length > 0 || !!props.badgesNode;
|
|
36338
36453
|
const titleNode = hasBadges ? /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
36339
36454
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: title }),
|
|
36340
|
-
props.badgesNode ?? badges.map((b, i) => /* @__PURE__ */ jsx(
|
|
36455
|
+
props.badgesNode ?? badges.map((b, i) => /* @__PURE__ */ jsx(Badge27, { badge: b, className: i > 0 ? "hidden sm:inline-flex" : "" }, i))
|
|
36341
36456
|
] }) : title;
|
|
36342
36457
|
return (
|
|
36343
36458
|
// A coluna decide o layout, não a janela: com o assistente aberto ao lado,
|
|
@@ -36435,7 +36550,7 @@ function OrderDetailView(props) {
|
|
|
36435
36550
|
!receivable || receivable.rows.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: receivable?.emptyLabel ?? "Sem conta a receber." }) : /* @__PURE__ */ jsxs("div", { className: "text-sm", children: [
|
|
36436
36551
|
(receivable.referenceNumber || receivable.statusBadge) && /* @__PURE__ */ jsxs("div", { className: "mb-2 flex flex-wrap items-center gap-2", children: [
|
|
36437
36552
|
receivable.referenceNumber && /* @__PURE__ */ jsx("span", { className: "font-mono font-semibold", children: receivable.referenceNumber }),
|
|
36438
|
-
receivable.statusBadge && /* @__PURE__ */ jsx(
|
|
36553
|
+
receivable.statusBadge && /* @__PURE__ */ jsx(Badge27, { badge: receivable.statusBadge })
|
|
36439
36554
|
] }),
|
|
36440
36555
|
receivable.rows.map((r, i) => /* @__PURE__ */ jsx(OrderDetailRow, { label: r.label, value: r.value, strong: r.strong, muted: r.muted }, i)),
|
|
36441
36556
|
/* @__PURE__ */ jsx("div", { className: "mt-3 space-y-1.5 border-t pt-2", children: receivable.installments.map((inst) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -38585,7 +38700,7 @@ var ORDER_CHANNEL_LABELS = {
|
|
|
38585
38700
|
retirada: "Retirada",
|
|
38586
38701
|
ticketing: "Bilheteria"
|
|
38587
38702
|
};
|
|
38588
|
-
function
|
|
38703
|
+
function Badge29({ children }) {
|
|
38589
38704
|
return /* @__PURE__ */ jsx("span", { className: "inline-flex items-center rounded-full bg-muted px-2 py-0.5 text-[11px] font-medium", children });
|
|
38590
38705
|
}
|
|
38591
38706
|
function orderKindColumn(kindOf, header = "Tipo") {
|
|
@@ -38595,7 +38710,7 @@ function orderKindColumn(kindOf, header = "Tipo") {
|
|
|
38595
38710
|
render: (row) => {
|
|
38596
38711
|
const kind = kindOf(row);
|
|
38597
38712
|
if (!kind) return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
38598
|
-
return /* @__PURE__ */ jsx(
|
|
38713
|
+
return /* @__PURE__ */ jsx(Badge29, { children: ORDER_KIND_LABELS[kind] ?? kind });
|
|
38599
38714
|
}
|
|
38600
38715
|
};
|
|
38601
38716
|
}
|
|
@@ -38606,7 +38721,7 @@ function orderChannelColumn(channelOf, header = "Canal") {
|
|
|
38606
38721
|
render: (row) => {
|
|
38607
38722
|
const channel = channelOf(row);
|
|
38608
38723
|
if (!channel) return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
38609
|
-
return /* @__PURE__ */ jsx(
|
|
38724
|
+
return /* @__PURE__ */ jsx(Badge29, { children: ORDER_CHANNEL_LABELS[channel] ?? channel });
|
|
38610
38725
|
}
|
|
38611
38726
|
};
|
|
38612
38727
|
}
|