@fayz-ai/admin 0.18.0 → 0.19.1
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/CommandPalette-GQ6SPITD.js +297 -0
- package/dist/CommandPalette-GQ6SPITD.js.map +1 -0
- package/dist/{ScheduleEditor-63TVSCJC.js → ScheduleEditor-YZPOCBTW.js} +6 -6
- package/dist/{ScheduleEditor-63TVSCJC.js.map → ScheduleEditor-YZPOCBTW.js.map} +1 -1
- package/dist/SubscriptionPage-JXJ56OOH.js +8 -0
- package/dist/{SubscriptionPage-5PJ25YAD.js.map → SubscriptionPage-JXJ56OOH.js.map} +1 -1
- package/dist/access/headless.d.ts +2 -2
- package/dist/access/limits-registry.d.ts +6 -3
- package/dist/access/limits-registry.d.ts.map +1 -1
- package/dist/app/AdminShell.d.ts.map +1 -1
- package/dist/app/admin-app.d.ts.map +1 -1
- package/dist/app/settings-tabs.store.d.ts +21 -0
- package/dist/app/settings-tabs.store.d.ts.map +1 -0
- package/dist/billing/index.js +2 -2
- package/dist/{chunk-7DFJEXCR.js → chunk-5GWUM4SM.js} +3 -3
- package/dist/{chunk-7DFJEXCR.js.map → chunk-5GWUM4SM.js.map} +1 -1
- package/dist/{chunk-ERDS4OJS.js → chunk-HYDNIBN6.js} +3 -3
- package/dist/{chunk-ERDS4OJS.js.map → chunk-HYDNIBN6.js.map} +1 -1
- package/dist/{chunk-WN6PGQSG.js → chunk-NB6X5O5L.js} +81 -10
- package/dist/chunk-NB6X5O5L.js.map +1 -0
- package/dist/{chunk-LZRLWKJ2.js → chunk-UHHEPU4A.js} +379 -88
- package/dist/chunk-UHHEPU4A.js.map +1 -0
- package/dist/{chunk-VTEP2AQX.js → chunk-WJ3H3RJN.js} +5 -3
- package/dist/chunk-WJ3H3RJN.js.map +1 -0
- package/dist/{chunk-G5PBC5OB.js → chunk-ZNV7Q2TO.js} +8 -8
- package/dist/chunk-ZNV7Q2TO.js.map +1 -0
- package/dist/components/GetStarted.d.ts +45 -0
- package/dist/components/GetStarted.d.ts.map +1 -0
- package/dist/components/RightRail.d.ts.map +1 -1
- package/dist/components/TeachMe.d.ts +83 -0
- package/dist/components/TeachMe.d.ts.map +1 -0
- package/dist/components/auth/SplitLogin.d.ts.map +1 -1
- package/dist/components/billing/SoftLimitProbes.d.ts +5 -0
- package/dist/components/billing/SoftLimitProbes.d.ts.map +1 -0
- package/dist/components/billing/SoftLimitWidget.d.ts +3 -0
- package/dist/components/billing/SoftLimitWidget.d.ts.map +1 -0
- package/dist/components/billing/index.d.ts +3 -1
- package/dist/components/billing/index.d.ts.map +1 -1
- package/dist/components/billing/soft-limit.store.d.ts +23 -0
- package/dist/components/billing/soft-limit.store.d.ts.map +1 -0
- package/dist/components/chat/ChatConversation.d.ts.map +1 -1
- package/dist/components/chat/ChatHistory.d.ts.map +1 -1
- package/dist/components/chat/ChatMessages.d.ts.map +1 -1
- package/dist/components/chat/ConfirmActionCard.d.ts +5 -1
- package/dist/components/chat/ConfirmActionCard.d.ts.map +1 -1
- package/dist/components/chat/index.d.ts +0 -1
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/connect/ConnectorRuns.d.ts +1 -1
- package/dist/components/connect/ConnectorsPanel.d.ts.map +1 -1
- package/dist/components/connect/ConnectorsTab.d.ts.map +1 -1
- package/dist/components/connect/connector-status.d.ts +1 -1
- package/dist/components/connect/model.d.ts +1 -1
- package/dist/components/layout/CommandPalette.d.ts.map +1 -1
- package/dist/components/organization/PermissionProfilesTab.d.ts.map +1 -1
- package/dist/components/settings/LocationsCrudPage.d.ts.map +1 -1
- package/dist/components/settings/SettingsPage.d.ts.map +1 -1
- package/dist/components/shared/RecordPickerModal.d.ts +24 -1
- package/dist/components/shared/RecordPickerModal.d.ts.map +1 -1
- package/dist/components/survey/PublicSurveyPage.d.ts +8 -0
- package/dist/components/survey/PublicSurveyPage.d.ts.map +1 -0
- package/dist/crud/CrudDetailPage.d.ts.map +1 -1
- package/dist/crud/CrudFormPage.d.ts.map +1 -1
- package/dist/crud/CrudListView.d.ts +3 -1
- package/dist/crud/CrudListView.d.ts.map +1 -1
- package/dist/crud/CrudPage.d.ts.map +1 -1
- package/dist/crud/CrudRecordModal.d.ts.map +1 -1
- package/dist/crud/LookupCreateInline.d.ts.map +1 -1
- package/dist/crud/RelatedListTab.d.ts +10 -0
- package/dist/crud/RelatedListTab.d.ts.map +1 -0
- package/dist/crud/archetypes/BookableToggle.d.ts +12 -0
- package/dist/crud/archetypes/BookableToggle.d.ts.map +1 -0
- package/dist/crud/archetypes/DetailTabHeader.d.ts +23 -0
- package/dist/crud/archetypes/DetailTabHeader.d.ts.map +1 -0
- package/dist/crud/archetypes/KanbanBoard.d.ts +89 -0
- package/dist/crud/archetypes/KanbanBoard.d.ts.map +1 -0
- package/dist/crud/archetypes/OrderAmount.d.ts +25 -0
- package/dist/crud/archetypes/OrderAmount.d.ts.map +1 -0
- package/dist/crud/archetypes/OrderBoardView.d.ts +61 -0
- package/dist/crud/archetypes/OrderBoardView.d.ts.map +1 -0
- package/dist/crud/archetypes/OrderCreateScreen.d.ts +116 -0
- package/dist/crud/archetypes/OrderCreateScreen.d.ts.map +1 -0
- package/dist/crud/archetypes/OrderDetailPage.d.ts +35 -0
- package/dist/crud/archetypes/OrderDetailPage.d.ts.map +1 -0
- package/dist/crud/archetypes/OrderDetailRail.d.ts +97 -0
- package/dist/crud/archetypes/OrderDetailRail.d.ts.map +1 -0
- package/dist/crud/archetypes/OrderDetailView.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderFormView.d.ts +20 -1
- package/dist/crud/archetypes/OrderFormView.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderListView.d.ts +59 -1
- package/dist/crud/archetypes/OrderListView.d.ts.map +1 -1
- package/dist/crud/archetypes/OrderPaymentChip.d.ts +8 -0
- package/dist/crud/archetypes/OrderPaymentChip.d.ts.map +1 -0
- package/dist/crud/archetypes/PaymentStatusBadge.d.ts +47 -0
- package/dist/crud/archetypes/PaymentStatusBadge.d.ts.map +1 -0
- package/dist/crud/archetypes/PersonDetailTabs.d.ts.map +1 -1
- package/dist/crud/archetypes/orderVocabulary.d.ts +19 -0
- package/dist/crud/archetypes/orderVocabulary.d.ts.map +1 -0
- package/dist/crud/archetypes/useOrderEditor.d.ts +20 -0
- package/dist/crud/archetypes/useOrderEditor.d.ts.map +1 -0
- package/dist/crud/archetypes/useOrderReceivable.d.ts +46 -0
- package/dist/crud/archetypes/useOrderReceivable.d.ts.map +1 -0
- package/dist/crud/archetypes/useOrdersPaymentStatus.d.ts +15 -0
- package/dist/crud/archetypes/useOrdersPaymentStatus.d.ts.map +1 -0
- package/dist/crud/createCrudPage.d.ts +3 -0
- package/dist/crud/createCrudPage.d.ts.map +1 -1
- package/dist/crud/relation-field.d.ts.map +1 -1
- package/dist/directory/AppSwitcher.d.ts +48 -0
- package/dist/directory/AppSwitcher.d.ts.map +1 -0
- package/dist/directory/FamilyWordmark.d.ts +20 -0
- package/dist/directory/FamilyWordmark.d.ts.map +1 -0
- package/dist/directory/app-id.d.ts +21 -0
- package/dist/directory/app-id.d.ts.map +1 -0
- package/dist/directory/directory.store.d.ts +20 -0
- package/dist/directory/directory.store.d.ts.map +1 -0
- package/dist/directory/index.d.ts +7 -0
- package/dist/directory/index.d.ts.map +1 -0
- package/dist/directory/types.d.ts +43 -0
- package/dist/directory/types.d.ts.map +1 -0
- package/dist/directory/useAppDirectory.d.ts +14 -0
- package/dist/directory/useAppDirectory.d.ts.map +1 -0
- package/dist/hooks/useAITools.d.ts +7 -0
- package/dist/hooks/useAITools.d.ts.map +1 -1
- package/dist/hooks/useAppConfig.d.ts.map +1 -1
- package/dist/hooks/useChat.d.ts +4 -0
- package/dist/hooks/useChat.d.ts.map +1 -1
- package/dist/hooks/useTenant.d.ts +12 -12
- package/dist/hooks/useTenant.d.ts.map +1 -1
- package/dist/index.d.ts +43 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25069 -21491
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-staff.d.ts +46 -96
- package/dist/lib/agent-staff.d.ts.map +1 -1
- package/dist/lib/ai-tool-handlers.d.ts +24 -7
- package/dist/lib/ai-tool-handlers.d.ts.map +1 -1
- package/dist/lib/assistant-invite.d.ts.map +1 -1
- package/dist/lib/bookable-service.d.ts +7 -0
- package/dist/lib/bookable-service.d.ts.map +1 -0
- package/dist/lib/core-ai-tools.d.ts +0 -17
- package/dist/lib/core-ai-tools.d.ts.map +1 -1
- package/dist/lib/fayz-agent.d.ts +2 -0
- package/dist/lib/fayz-agent.d.ts.map +1 -1
- package/dist/lib/product-name.d.ts +38 -0
- package/dist/lib/product-name.d.ts.map +1 -0
- package/dist/lib/tool-search.d.ts +82 -0
- package/dist/lib/tool-search.d.ts.map +1 -0
- package/dist/onboarding/ActivationAgentSurface.d.ts.map +1 -1
- package/dist/onboarding/ActivationChecklistCard.d.ts +11 -1
- package/dist/onboarding/ActivationChecklistCard.d.ts.map +1 -1
- package/dist/onboarding/ActivationProvider.d.ts.map +1 -1
- package/dist/onboarding/WorkspaceSetupFlow.d.ts.map +1 -1
- package/dist/onboarding/business-profile.d.ts +67 -0
- package/dist/onboarding/business-profile.d.ts.map +1 -0
- package/dist/onboarding/checklist.d.ts +10 -0
- package/dist/onboarding/checklist.d.ts.map +1 -1
- package/dist/onboarding/decide.d.ts +23 -0
- package/dist/onboarding/decide.d.ts.map +1 -1
- package/dist/onboarding/guided-runner.d.ts +11 -0
- package/dist/onboarding/guided-runner.d.ts.map +1 -1
- package/dist/onboarding/guided.d.ts +21 -1
- package/dist/onboarding/guided.d.ts.map +1 -1
- package/dist/onboarding/index.d.ts +4 -2
- package/dist/onboarding/index.d.ts.map +1 -1
- package/dist/onboarding/packs/retail.d.ts.map +1 -1
- package/dist/onboarding/programs.d.ts +25 -1
- package/dist/onboarding/programs.d.ts.map +1 -1
- package/dist/onboarding/useWorkspaceSetupGate.d.ts.map +1 -1
- package/dist/onboarding/welcome.d.ts +27 -0
- package/dist/onboarding/welcome.d.ts.map +1 -0
- package/dist/org/WorkspaceChooser.d.ts +20 -0
- package/dist/org/WorkspaceChooser.d.ts.map +1 -0
- package/dist/org/WorkspaceChooserGate.d.ts +21 -0
- package/dist/org/WorkspaceChooserGate.d.ts.map +1 -0
- package/dist/org/WorkspaceSwitching.d.ts +25 -0
- package/dist/org/WorkspaceSwitching.d.ts.map +1 -0
- package/dist/org/WorkspaceSwitchingHost.d.ts +11 -0
- package/dist/org/WorkspaceSwitchingHost.d.ts.map +1 -0
- package/dist/org/adapters/supabase.d.ts +1 -1
- package/dist/org/adapters/supabase.d.ts.map +1 -1
- package/dist/org/choice.d.ts +41 -0
- package/dist/org/choice.d.ts.map +1 -0
- package/dist/org/context.d.ts +8 -0
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/index.d.ts +12 -1
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +4 -4
- package/dist/org/self.d.ts.map +1 -1
- package/dist/org/store.d.ts +2 -1
- package/dist/org/store.d.ts.map +1 -1
- package/dist/org/switching.store.d.ts +27 -0
- package/dist/org/switching.store.d.ts.map +1 -0
- package/dist/permissions/context.d.ts +26 -0
- package/dist/permissions/context.d.ts.map +1 -1
- package/dist/permissions/index.js +1 -1
- package/dist/projects/SeuSiteWidget.d.ts.map +1 -1
- package/dist/setup/SetupAgentSurface.d.ts +2 -0
- package/dist/setup/SetupAgentSurface.d.ts.map +1 -0
- package/dist/setup/format.d.ts +21 -0
- package/dist/setup/format.d.ts.map +1 -0
- package/dist/setup/registry.d.ts +29 -0
- package/dist/setup/registry.d.ts.map +1 -0
- package/dist/setup/validate.d.ts +26 -0
- package/dist/setup/validate.d.ts.map +1 -0
- package/dist/stores/chat.store.d.ts +15 -18
- package/dist/stores/chat.store.d.ts.map +1 -1
- package/dist/stores/createCrudStore.d.ts +2 -0
- package/dist/stores/createCrudStore.d.ts.map +1 -1
- package/dist/tasks/components/TaskDetail.d.ts.map +1 -1
- package/dist/units/UnitMenuSection.d.ts.map +1 -1
- package/dist/units/UnitSwitcher.d.ts.map +1 -1
- package/dist/units/UnitSwitching.d.ts +24 -0
- package/dist/units/UnitSwitching.d.ts.map +1 -0
- package/dist/units/UnitSwitchingHost.d.ts +11 -0
- package/dist/units/UnitSwitchingHost.d.ts.map +1 -0
- package/dist/units/data.d.ts +30 -4
- package/dist/units/data.d.ts.map +1 -1
- package/dist/units/index.d.ts +2 -0
- package/dist/units/index.d.ts.map +1 -1
- package/dist/units/switching.store.d.ts +31 -0
- package/dist/units/switching.store.d.ts.map +1 -0
- package/package.json +7 -7
- package/dist/CommandPalette-XY3VOEAV.js +0 -291
- package/dist/CommandPalette-XY3VOEAV.js.map +0 -1
- package/dist/SubscriptionPage-5PJ25YAD.js +0 -8
- package/dist/chunk-G5PBC5OB.js.map +0 -1
- package/dist/chunk-LZRLWKJ2.js.map +0 -1
- package/dist/chunk-VTEP2AQX.js.map +0 -1
- package/dist/chunk-WN6PGQSG.js.map +0 -1
- package/dist/components/billing/SoftLimitBanner.d.ts +0 -5
- package/dist/components/billing/SoftLimitBanner.d.ts.map +0 -1
- package/dist/components/chat/StaffHireView.d.ts +0 -21
- package/dist/components/chat/StaffHireView.d.ts.map +0 -1
- package/dist/components/chat/StaffPitchCard.d.ts +0 -15
- package/dist/components/chat/StaffPitchCard.d.ts.map +0 -1
- package/dist/components/chat/StaffSwitcher.d.ts +0 -23
- package/dist/components/chat/StaffSwitcher.d.ts.map +0 -1
- package/dist/lib/staff-cards.d.ts +0 -11
- package/dist/lib/staff-cards.d.ts.map +0 -1
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import { markWorkspaceSwitch, clearOrgSnapshot, useTenant, useTenantOptional, setAutoPick } from './chunk-NB6X5O5L.js';
|
|
2
|
+
import { persistOrgId, getPersistedOrgId } from './chunk-5GWUM4SM.js';
|
|
1
3
|
import { createClient } from '@supabase/supabase-js';
|
|
2
|
-
import { getActiveUnitId, getActiveTenantId, setGlobalSupabaseClient } from '@fayz-ai/core';
|
|
4
|
+
import { getActiveUnitId, getActiveTenantId, setGlobalSupabaseClient, useTranslation } from '@fayz-ai/core';
|
|
3
5
|
import { createDedupedFetch } from '@fayz-ai/sdk';
|
|
6
|
+
import * as React2 from 'react';
|
|
7
|
+
import { cn, Checkbox, Button } from '@fayz-ai/ui';
|
|
8
|
+
import { Check, Building2, ShieldCheck } from 'lucide-react';
|
|
9
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
|
+
import { create } from 'zustand';
|
|
4
11
|
|
|
5
|
-
// src/data/client.ts
|
|
6
12
|
var _client = null;
|
|
7
13
|
function requestUrl(input) {
|
|
8
14
|
if (typeof input === "string") return input;
|
|
@@ -110,6 +116,14 @@ function buildTeamRows(people, members, profiles, currentUser) {
|
|
|
110
116
|
return [...loginRows, ...personRows];
|
|
111
117
|
}
|
|
112
118
|
|
|
119
|
+
// src/directory/app-id.ts
|
|
120
|
+
function resolveAppId() {
|
|
121
|
+
const env = import.meta.env;
|
|
122
|
+
const id = env?.VITE_APP_ID ?? env?.PUBLIC_APP_ID;
|
|
123
|
+
const trimmed = id?.trim();
|
|
124
|
+
return trimmed ? trimmed : null;
|
|
125
|
+
}
|
|
126
|
+
|
|
113
127
|
// src/org/adapters/supabase.ts
|
|
114
128
|
var inflightRequests = /* @__PURE__ */ new Map();
|
|
115
129
|
function dedup(key, fn) {
|
|
@@ -249,7 +263,7 @@ function buildPermissionProfiles(roles, permissions, rolePerms, overrides) {
|
|
|
249
263
|
read: "read",
|
|
250
264
|
create: "create",
|
|
251
265
|
update: "edit",
|
|
252
|
-
manage: "
|
|
266
|
+
manage: "manage",
|
|
253
267
|
delete: "delete",
|
|
254
268
|
configure: "edit",
|
|
255
269
|
invite: "create"
|
|
@@ -306,16 +320,30 @@ function createSupabaseOrgAdapter(config) {
|
|
|
306
320
|
},
|
|
307
321
|
async listUserOrgs(userId) {
|
|
308
322
|
return dedup(`listUserOrgs:${userId}`, async () => {
|
|
309
|
-
const { data, error } = await core().from("
|
|
323
|
+
const { data, error } = await core().from("v_team_members").select("tenant_id, role, tenant:tenants(id, name, slug, logo_url)").eq("user_id", userId);
|
|
310
324
|
if (error) throw error;
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
325
|
+
let rows = data ?? [];
|
|
326
|
+
const appId = resolveAppId();
|
|
327
|
+
if (appId && rows.length > 1) {
|
|
328
|
+
const { data: scoped, error: scopeError } = await core().from("v_tenant_apps").select("tenant_id").eq("app_id", appId);
|
|
329
|
+
if (!scopeError && Array.isArray(scoped)) {
|
|
330
|
+
const runsThisApp = new Set(scoped.map((r) => r.tenant_id));
|
|
331
|
+
const kept = rows.filter((row) => runsThisApp.has(row["tenant_id"]));
|
|
332
|
+
if (kept.length > 0) rows = kept;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return rows.map((row) => {
|
|
336
|
+
const tenant = row["tenant"] ?? {};
|
|
337
|
+
const role = row["role"] ?? "";
|
|
338
|
+
return {
|
|
339
|
+
orgId: row["tenant_id"],
|
|
340
|
+
orgName: tenant["name"] ?? "",
|
|
341
|
+
orgSlug: tenant["slug"] ?? "",
|
|
342
|
+
orgLogoUrl: tenant["logo_url"] ?? void 0,
|
|
343
|
+
profileId: role,
|
|
344
|
+
profileName: capitalize2(role)
|
|
345
|
+
};
|
|
346
|
+
});
|
|
319
347
|
});
|
|
320
348
|
},
|
|
321
349
|
async getOrg(orgId) {
|
|
@@ -354,7 +382,7 @@ function createSupabaseOrgAdapter(config) {
|
|
|
354
382
|
return mapTenantToOrg(data);
|
|
355
383
|
},
|
|
356
384
|
async listMembers(orgId) {
|
|
357
|
-
const { data, error } = await core().from("
|
|
385
|
+
const { data, error } = await core().from("v_team_members").select("*").eq("tenant_id", orgId);
|
|
358
386
|
if (error) throw error;
|
|
359
387
|
const userIds = (data ?? []).map((m) => m["user_id"]);
|
|
360
388
|
const { data: profiles } = userIds.length > 0 ? await core().from("profiles").select("id, full_name, avatar_url, email").in("id", userIds) : { data: [] };
|
|
@@ -374,7 +402,7 @@ function createSupabaseOrgAdapter(config) {
|
|
|
374
402
|
if (!personKinds || personKinds.length === 0) return [];
|
|
375
403
|
const [peopleResult, membersResult] = await Promise.all([
|
|
376
404
|
core().from("people").select("id, name, kind, email, avatar_url, is_active").eq("tenant_id", orgId).in("kind", personKinds).not("is_active", "is", false),
|
|
377
|
-
core().from("
|
|
405
|
+
core().from("v_team_members").select("id, user_id, role, person_id, created_at").eq("tenant_id", orgId)
|
|
378
406
|
]);
|
|
379
407
|
if (peopleResult.error) throw peopleResult.error;
|
|
380
408
|
const people = peopleResult.data ?? [];
|
|
@@ -392,64 +420,80 @@ function createSupabaseOrgAdapter(config) {
|
|
|
392
420
|
} : null;
|
|
393
421
|
return buildTeamRows(people, members, profilesResult.data ?? [], currentUser);
|
|
394
422
|
},
|
|
395
|
-
|
|
396
|
-
|
|
423
|
+
// Verbs, not writes into the projection: v_team_members is a JOINed view
|
|
424
|
+
// and accepts neither UPDATE nor DELETE, and each RPC checks the permission
|
|
425
|
+
// in one place. `_orgId` stays in the signature for the adapter contract —
|
|
426
|
+
// the RPCs take the tenant from the session, not from a parameter.
|
|
427
|
+
async updateMemberProfile(_orgId, memberId, profileId) {
|
|
428
|
+
const { error } = await core().rpc("member_set_role", { p_membership: memberId, p_role: profileId });
|
|
397
429
|
if (error) throw error;
|
|
398
430
|
},
|
|
399
|
-
async removeMember(
|
|
400
|
-
const { error } = await core().
|
|
431
|
+
async removeMember(_orgId, memberId) {
|
|
432
|
+
const { error } = await core().rpc("member_remove", { p_membership: memberId });
|
|
401
433
|
if (error) throw error;
|
|
402
434
|
},
|
|
435
|
+
// #136 moved authorization into app.*, reachable through the v_authz_*
|
|
436
|
+
// views (security_invoker, so RLS still decides what a caller sees) and a
|
|
437
|
+
// small set of RPCs. The four public mirrors this used to read and write —
|
|
438
|
+
// permissions, role_permissions, tenant_roles, tenant_role_overrides — are
|
|
439
|
+
// dropped by @fayz-ai/db 003.
|
|
440
|
+
//
|
|
441
|
+
// The RPCs take the tenant from the SESSION, not a parameter, so orgId is
|
|
442
|
+
// asserted against the active tenant rather than passed down: writing to
|
|
443
|
+
// one org while another is active was never possible and should fail
|
|
444
|
+
// loudly rather than silently touch the wrong one.
|
|
403
445
|
async listProfiles(orgId) {
|
|
404
|
-
const [permsResult,
|
|
405
|
-
core().from("
|
|
406
|
-
core().from("
|
|
407
|
-
core().from("
|
|
408
|
-
// Custom roles the tenant created by duplicating a system role. Tolerate a
|
|
409
|
-
// missing table (pre-seed) — just show the system roles in that case.
|
|
410
|
-
core().from("tenant_roles").select("key, name, description").eq("tenant_id", orgId)
|
|
446
|
+
const [permsResult, rolesResult, grantsResult] = await Promise.all([
|
|
447
|
+
core().from("v_authz_permissions").select("key, plugin"),
|
|
448
|
+
core().from("v_authz_roles").select("id, key, name, description, is_system").eq("tenant_id", orgId),
|
|
449
|
+
core().from("v_authz_role_permissions").select("role_id, permission").eq("tenant_id", orgId)
|
|
411
450
|
]);
|
|
412
451
|
if (permsResult.error) throw permsResult.error;
|
|
413
|
-
if (
|
|
414
|
-
if (
|
|
415
|
-
const
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
452
|
+
if (rolesResult.error) throw rolesResult.error;
|
|
453
|
+
if (grantsResult.error) throw grantsResult.error;
|
|
454
|
+
const dbRoles = rolesResult.data ?? [];
|
|
455
|
+
const keyOf = new Map(dbRoles.map((r) => [r.id, r.key]));
|
|
456
|
+
const declared = roles.map((r) => ({ ...r, isSystem: true }));
|
|
457
|
+
const declaredIds = new Set(declared.map((r) => r.id));
|
|
458
|
+
const fromDb = dbRoles.filter((r) => !declaredIds.has(r.key)).map((r) => ({ id: r.key, name: r.name, description: r.description ?? void 0, isSystem: r.is_system }));
|
|
459
|
+
const overrides = (grantsResult.data ?? []).flatMap((g) => {
|
|
460
|
+
const role = keyOf.get(g.role_id);
|
|
461
|
+
return role ? [{ role, permission_id: g.permission, granted: true }] : [];
|
|
462
|
+
});
|
|
422
463
|
return buildPermissionProfiles(
|
|
423
|
-
[...
|
|
424
|
-
permsResult.data ?? [],
|
|
425
|
-
|
|
426
|
-
|
|
464
|
+
[...declared, ...fromDb],
|
|
465
|
+
(permsResult.data ?? []).map((p) => ({ id: p.key, category: p.plugin })),
|
|
466
|
+
[],
|
|
467
|
+
overrides
|
|
427
468
|
);
|
|
428
469
|
},
|
|
429
470
|
async createProfile(orgId, profile) {
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
|
|
471
|
+
const existingRoles = await core().from("v_authz_roles").select("key, is_system").eq("tenant_id", orgId);
|
|
472
|
+
if (existingRoles.error) throw existingRoles.error;
|
|
473
|
+
const rows = existingRoles.data ?? [];
|
|
474
|
+
const existing = new Set(rows.map((r) => r.key));
|
|
433
475
|
let key = slugifyRole(profile.name);
|
|
434
476
|
if (existing.has(key) || roles.some((r) => r.id === key)) {
|
|
435
477
|
let n = 2;
|
|
436
478
|
while (existing.has(`${key}-${n}`) || roles.some((r) => r.id === `${key}-${n}`)) n++;
|
|
437
479
|
key = `${key}-${n}`;
|
|
438
480
|
}
|
|
439
|
-
const
|
|
440
|
-
if (
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
481
|
+
const seed = rows.find((r) => r.is_system && r.key === "viewer")?.key ?? rows.find((r) => r.is_system)?.key ?? rows[0]?.key;
|
|
482
|
+
if (!seed) throw new Error("createProfile: the tenant has no role to clone from");
|
|
483
|
+
const created = await core().rpc("role_create_from_template", {
|
|
484
|
+
p_role_key: key,
|
|
485
|
+
p_name: profile.name,
|
|
486
|
+
p_template_role: seed,
|
|
487
|
+
p_template: null,
|
|
488
|
+
p_description: profile.description ?? null
|
|
489
|
+
});
|
|
490
|
+
if (created.error) throw created.error;
|
|
491
|
+
const roleId = created.data;
|
|
492
|
+
const keys = Object.entries(profile.grants ?? {}).flatMap(
|
|
493
|
+
([category, actions]) => actions.map((action) => `${category}.${DB_ACTION[action] ?? action}`)
|
|
448
494
|
);
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
if (error) throw error;
|
|
452
|
-
}
|
|
495
|
+
const set = await core().rpc("role_set_permissions", { p_role_id: roleId, p_keys: keys });
|
|
496
|
+
if (set.error) throw set.error;
|
|
453
497
|
const profiles = await this.listProfiles(orgId);
|
|
454
498
|
return profiles.find((p) => p.id === key) ?? {
|
|
455
499
|
id: key,
|
|
@@ -461,27 +505,26 @@ function createSupabaseOrgAdapter(config) {
|
|
|
461
505
|
};
|
|
462
506
|
},
|
|
463
507
|
async updateProfile(orgId, profileId, data) {
|
|
508
|
+
const found = await core().from("v_authz_roles").select("id, name, description, is_system").eq("tenant_id", orgId).eq("key", profileId).maybeSingle();
|
|
509
|
+
if (found.error) throw found.error;
|
|
510
|
+
if (!found.data) throw new Error(`Profile not found: ${profileId}`);
|
|
511
|
+
const role = found.data;
|
|
464
512
|
if (data.name !== void 0 || data.description !== void 0) {
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
513
|
+
const { error } = await core().rpc("role_rename", {
|
|
514
|
+
p_role_id: role.id,
|
|
515
|
+
p_name: data.name ?? role.name,
|
|
516
|
+
// Explicit, not coalesced: role_rename treats NULL as "clear it", so
|
|
517
|
+
// an untouched description has to be sent back as it was.
|
|
518
|
+
p_description: data.description !== void 0 ? data.description ?? null : role.description
|
|
519
|
+
});
|
|
469
520
|
if (error) throw error;
|
|
470
521
|
}
|
|
471
522
|
if (data.grants) {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
([category, actions]) => actions.map((action) => ({
|
|
475
|
-
tenant_id: orgId,
|
|
476
|
-
role: profileId,
|
|
477
|
-
permission_id: `${category}.${DB_ACTION[action] ?? action}`,
|
|
478
|
-
granted: true
|
|
479
|
-
}))
|
|
523
|
+
const keys = Object.entries(data.grants).flatMap(
|
|
524
|
+
([category, actions]) => actions.map((action) => `${category}.${DB_ACTION[action] ?? action}`)
|
|
480
525
|
);
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
if (error) throw error;
|
|
484
|
-
}
|
|
526
|
+
const { error } = await core().rpc("role_set_permissions", { p_role_id: role.id, p_keys: keys });
|
|
527
|
+
if (error) throw error;
|
|
485
528
|
}
|
|
486
529
|
const profiles = await this.listProfiles(orgId);
|
|
487
530
|
const updated = profiles.find((p) => p.id === profileId);
|
|
@@ -489,11 +532,12 @@ function createSupabaseOrgAdapter(config) {
|
|
|
489
532
|
return updated;
|
|
490
533
|
},
|
|
491
534
|
async deleteProfile(orgId, profileId) {
|
|
492
|
-
const found = await core().from("
|
|
535
|
+
const found = await core().from("v_authz_roles").select("id, is_system").eq("tenant_id", orgId).eq("key", profileId).maybeSingle();
|
|
493
536
|
if (found.error) throw found.error;
|
|
494
537
|
if (!found.data) throw new Error("System roles cannot be deleted.");
|
|
495
|
-
|
|
496
|
-
|
|
538
|
+
const role = found.data;
|
|
539
|
+
if (role.is_system) throw new Error("System roles cannot be deleted.");
|
|
540
|
+
const { error } = await core().rpc("role_delete", { p_role_id: role.id });
|
|
497
541
|
if (error) throw error;
|
|
498
542
|
},
|
|
499
543
|
async listInvites(orgId) {
|
|
@@ -552,23 +596,29 @@ function createSupabaseOrgAdapter(config) {
|
|
|
552
596
|
return mapInviteRow(row);
|
|
553
597
|
},
|
|
554
598
|
async listLocations(orgId) {
|
|
555
|
-
const { data, error } = await core().from("
|
|
599
|
+
const { data, error } = await core().from("v_units").select("*").eq("tenant_id", orgId).order("is_headquarters", { ascending: false }).order("name");
|
|
556
600
|
if (error) throw error;
|
|
557
601
|
return (data ?? []).map(mapLocationRow);
|
|
558
602
|
},
|
|
559
603
|
async createLocation(orgId, input) {
|
|
560
|
-
const { data, error } = await core().
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
604
|
+
const { data, error } = await core().rpc("unit_create", {
|
|
605
|
+
p_name: input.name,
|
|
606
|
+
p_kind: input.isHeadquarters ? "hq" : "branch",
|
|
607
|
+
p_parent_unit: null,
|
|
608
|
+
// app.units keeps a unit's contact details in metadata; v_units reads
|
|
609
|
+
// them back out under the flat names this screen already uses.
|
|
610
|
+
p_metadata: {
|
|
611
|
+
address: input.address ?? null,
|
|
612
|
+
city: input.city ?? null,
|
|
613
|
+
state: input.state ?? null,
|
|
614
|
+
country: input.country ?? "BR",
|
|
615
|
+
phone: input.phone ?? null
|
|
616
|
+
}
|
|
617
|
+
});
|
|
570
618
|
if (error) throw error;
|
|
571
|
-
|
|
619
|
+
const created = await core().from("v_units").select("*").eq("id", data).single();
|
|
620
|
+
if (created.error) throw created.error;
|
|
621
|
+
return mapLocationRow(created.data);
|
|
572
622
|
}
|
|
573
623
|
};
|
|
574
624
|
}
|
|
@@ -842,7 +892,248 @@ function createMockOrgAdapter(defaultProfiles) {
|
|
|
842
892
|
}
|
|
843
893
|
};
|
|
844
894
|
}
|
|
895
|
+
function WorkspaceChooser({ memberships, suggestedId, onCancel }) {
|
|
896
|
+
const t = useTranslation();
|
|
897
|
+
const tr = (key, fallback) => {
|
|
898
|
+
const v = t(key);
|
|
899
|
+
return !v || v === key ? fallback : v;
|
|
900
|
+
};
|
|
901
|
+
const { switchOrg } = useTenant();
|
|
902
|
+
const [selected, setSelected] = React2.useState(
|
|
903
|
+
suggestedId ?? memberships[0]?.orgId ?? null
|
|
904
|
+
);
|
|
905
|
+
const [remember, setRemember] = React2.useState(false);
|
|
906
|
+
const [entering, setEntering] = React2.useState(false);
|
|
907
|
+
const enter = async (orgId) => {
|
|
908
|
+
if (entering) return;
|
|
909
|
+
setEntering(true);
|
|
910
|
+
setAutoPick(remember);
|
|
911
|
+
try {
|
|
912
|
+
await switchOrg(orgId);
|
|
913
|
+
} finally {
|
|
914
|
+
setEntering(false);
|
|
915
|
+
}
|
|
916
|
+
};
|
|
917
|
+
return /* @__PURE__ */ jsx("div", { className: "flex min-h-screen items-center justify-center bg-background p-4", children: /* @__PURE__ */ jsxs("div", { className: "w-full max-w-md", children: [
|
|
918
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-6 text-center", children: [
|
|
919
|
+
/* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold text-foreground", children: tr("organization.chooseWorkspace", "Escolha uma \xE1rea de trabalho") }),
|
|
920
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: tr(
|
|
921
|
+
"organization.chooseWorkspaceDescription",
|
|
922
|
+
"Voc\xEA tem acesso a mais de uma. Selecione em qual deseja entrar."
|
|
923
|
+
) })
|
|
924
|
+
] }),
|
|
925
|
+
/* @__PURE__ */ jsx(
|
|
926
|
+
"div",
|
|
927
|
+
{
|
|
928
|
+
role: "radiogroup",
|
|
929
|
+
"aria-label": tr("organization.workspaces", "Workspaces"),
|
|
930
|
+
className: "space-y-2",
|
|
931
|
+
children: memberships.map((m) => {
|
|
932
|
+
const isSelected = m.orgId === selected;
|
|
933
|
+
const isSuggested = m.orgId === suggestedId;
|
|
934
|
+
return /* @__PURE__ */ jsxs(
|
|
935
|
+
"button",
|
|
936
|
+
{
|
|
937
|
+
type: "button",
|
|
938
|
+
role: "radio",
|
|
939
|
+
"aria-checked": isSelected,
|
|
940
|
+
disabled: entering,
|
|
941
|
+
onClick: () => setSelected(m.orgId),
|
|
942
|
+
onDoubleClick: () => void enter(m.orgId),
|
|
943
|
+
className: cn(
|
|
944
|
+
"flex w-full items-center gap-3 rounded-lg border p-3 text-left transition-colors",
|
|
945
|
+
"disabled:opacity-60",
|
|
946
|
+
isSelected ? "border-primary bg-primary/5" : "border-border hover:border-primary/50 hover:bg-muted/50"
|
|
947
|
+
),
|
|
948
|
+
children: [
|
|
949
|
+
/* @__PURE__ */ jsx(WorkspaceMark, { name: m.orgName, logoUrl: m.orgLogoUrl }),
|
|
950
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
951
|
+
/* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-medium text-foreground", children: m.orgName || m.orgSlug || m.orgId }),
|
|
952
|
+
/* @__PURE__ */ jsxs("span", { className: "block truncate text-xs text-muted-foreground", children: [
|
|
953
|
+
m.profileName,
|
|
954
|
+
isSuggested && ` \xB7 ${tr("organization.lastUsed", "\xFAltimo acesso")}`
|
|
955
|
+
] })
|
|
956
|
+
] }),
|
|
957
|
+
isSelected && /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 shrink-0 text-primary" })
|
|
958
|
+
]
|
|
959
|
+
},
|
|
960
|
+
m.orgId
|
|
961
|
+
);
|
|
962
|
+
})
|
|
963
|
+
}
|
|
964
|
+
),
|
|
965
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-5 flex items-center gap-2.5 text-sm text-muted-foreground", children: [
|
|
966
|
+
/* @__PURE__ */ jsx(
|
|
967
|
+
Checkbox,
|
|
968
|
+
{
|
|
969
|
+
checked: remember,
|
|
970
|
+
onChange: setRemember,
|
|
971
|
+
disabled: entering,
|
|
972
|
+
"aria-label": tr("organization.rememberChoice", "N\xE3o perguntar novamente neste dispositivo")
|
|
973
|
+
}
|
|
974
|
+
),
|
|
975
|
+
/* @__PURE__ */ jsx("span", { className: "cursor-pointer select-none", onClick: () => !entering && setRemember(!remember), children: tr("organization.rememberChoice", "N\xE3o perguntar novamente neste dispositivo") })
|
|
976
|
+
] }),
|
|
977
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-5 flex gap-2", children: [
|
|
978
|
+
onCancel && /* @__PURE__ */ jsx(Button, { variant: "outline", className: "flex-1", onClick: onCancel, disabled: entering, children: tr("common.cancel", "Cancelar") }),
|
|
979
|
+
/* @__PURE__ */ jsx(
|
|
980
|
+
Button,
|
|
981
|
+
{
|
|
982
|
+
className: "flex-1",
|
|
983
|
+
disabled: !selected || entering,
|
|
984
|
+
onClick: () => selected && void enter(selected),
|
|
985
|
+
children: entering ? tr("common.loading", "Entrando\u2026") : tr("organization.enter", "Entrar")
|
|
986
|
+
}
|
|
987
|
+
)
|
|
988
|
+
] }),
|
|
989
|
+
/* @__PURE__ */ jsx("p", { className: "mt-4 text-center text-xs text-muted-foreground", children: tr(
|
|
990
|
+
"organization.switchLaterHint",
|
|
991
|
+
"Voc\xEA pode trocar a qualquer momento pelo seletor no topo da tela."
|
|
992
|
+
) })
|
|
993
|
+
] }) });
|
|
994
|
+
}
|
|
995
|
+
function WorkspaceMark({ name, logoUrl }) {
|
|
996
|
+
if (logoUrl) {
|
|
997
|
+
return /* @__PURE__ */ jsx("img", { src: logoUrl, alt: "", className: "h-9 w-9 shrink-0 rounded-lg object-cover" });
|
|
998
|
+
}
|
|
999
|
+
const initials = name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join("").toUpperCase();
|
|
1000
|
+
return /* @__PURE__ */ jsx("span", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-xs font-semibold text-primary", children: initials || /* @__PURE__ */ jsx(Building2, { className: "h-4 w-4" }) });
|
|
1001
|
+
}
|
|
1002
|
+
function WorkspaceChooserGate({ fallback, children }) {
|
|
1003
|
+
const tenant = useTenantOptional();
|
|
1004
|
+
if (!tenant) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1005
|
+
const { org, userOrgs, orgsKnown, settled } = tenant;
|
|
1006
|
+
if (org) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1007
|
+
if (!settled) return /* @__PURE__ */ jsx(Fragment, { children: fallback ?? null });
|
|
1008
|
+
if (!orgsKnown || userOrgs.length <= 1) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1009
|
+
return /* @__PURE__ */ jsx(
|
|
1010
|
+
WorkspaceChooser,
|
|
1011
|
+
{
|
|
1012
|
+
memberships: userOrgs,
|
|
1013
|
+
suggestedId: userOrgs.some((m) => m.orgId === getPersistedOrgId()) ? getPersistedOrgId() : null
|
|
1014
|
+
}
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
1017
|
+
var useWorkspaceSwitchingStore = create((set) => ({
|
|
1018
|
+
target: null,
|
|
1019
|
+
begin: (target) => {
|
|
1020
|
+
markWorkspaceSwitch(target.orgId);
|
|
1021
|
+
persistOrgId(target.orgId);
|
|
1022
|
+
clearOrgSnapshot();
|
|
1023
|
+
set({ target });
|
|
1024
|
+
},
|
|
1025
|
+
cancel: () => set({ target: null })
|
|
1026
|
+
}));
|
|
1027
|
+
var STEP_MS = 850;
|
|
1028
|
+
function WorkspaceSwitching({ orgName, orgLogoUrl, onDone }) {
|
|
1029
|
+
const t = useTranslation();
|
|
1030
|
+
const tr = (key, fallback) => {
|
|
1031
|
+
const v = t(key);
|
|
1032
|
+
return !v || v === key ? fallback : v;
|
|
1033
|
+
};
|
|
1034
|
+
const steps = React2.useMemo(
|
|
1035
|
+
() => [
|
|
1036
|
+
tr("organization.switching.step1", "Alterando organiza\xE7\xE3o"),
|
|
1037
|
+
tr("organization.switching.step2", "Garantindo seguran\xE7a dos dados"),
|
|
1038
|
+
tr("organization.switching.step3", "Carregando suas informa\xE7\xF5es")
|
|
1039
|
+
],
|
|
1040
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1041
|
+
[]
|
|
1042
|
+
);
|
|
1043
|
+
const [step, setStep] = React2.useState(0);
|
|
1044
|
+
const doneRef = React2.useRef(onDone);
|
|
1045
|
+
doneRef.current = onDone;
|
|
1046
|
+
React2.useEffect(() => {
|
|
1047
|
+
const id = window.setInterval(() => {
|
|
1048
|
+
setStep((s) => {
|
|
1049
|
+
if (s < steps.length - 1) return s + 1;
|
|
1050
|
+
window.clearInterval(id);
|
|
1051
|
+
window.setTimeout(() => doneRef.current(), STEP_MS);
|
|
1052
|
+
return s;
|
|
1053
|
+
});
|
|
1054
|
+
}, STEP_MS);
|
|
1055
|
+
return () => window.clearInterval(id);
|
|
1056
|
+
}, [steps.length]);
|
|
1057
|
+
return /* @__PURE__ */ jsx(
|
|
1058
|
+
"div",
|
|
1059
|
+
{
|
|
1060
|
+
role: "status",
|
|
1061
|
+
"aria-live": "polite",
|
|
1062
|
+
"aria-label": `${steps[step]} \u2014 ${orgName}`,
|
|
1063
|
+
className: "saas-switch-veil fixed inset-0 z-[100] flex items-center justify-center bg-background px-6",
|
|
1064
|
+
children: /* @__PURE__ */ jsxs("div", { className: "saas-switch-rise flex w-full max-w-sm flex-col items-center", children: [
|
|
1065
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex h-20 w-20 items-center justify-center", children: [
|
|
1066
|
+
/* @__PURE__ */ jsx(
|
|
1067
|
+
"span",
|
|
1068
|
+
{
|
|
1069
|
+
"aria-hidden": true,
|
|
1070
|
+
className: "saas-switch-pulse absolute inset-0 rounded-2xl bg-primary/25"
|
|
1071
|
+
}
|
|
1072
|
+
),
|
|
1073
|
+
/* @__PURE__ */ jsx(WorkspaceMark2, { name: orgName, logoUrl: orgLogoUrl })
|
|
1074
|
+
] }),
|
|
1075
|
+
/* @__PURE__ */ jsx("p", { className: "mt-7 text-xs font-medium uppercase tracking-[0.14em] text-muted-foreground", children: tr("organization.switching.eyebrow", "Entrando em") }),
|
|
1076
|
+
/* @__PURE__ */ jsx("h1", { className: "mt-1.5 text-pretty text-center text-3xl font-semibold leading-tight tracking-tight text-foreground sm:text-4xl", children: orgName }),
|
|
1077
|
+
/* @__PURE__ */ jsx("ul", { className: "mt-9 flex w-full min-h-[7.5rem] flex-col items-start sm:min-h-[8.5rem]", children: steps.slice(0, step + 1).map((label, i) => {
|
|
1078
|
+
const done = i < step;
|
|
1079
|
+
const isSecurity = i === 1;
|
|
1080
|
+
return /* @__PURE__ */ jsxs("li", { className: "saas-switch-step flex w-full gap-3", children: [
|
|
1081
|
+
/* @__PURE__ */ jsxs("span", { className: "flex w-6 shrink-0 flex-col items-center", children: [
|
|
1082
|
+
i > 0 && // Tinted, not `bg-border`: on a light surface the border
|
|
1083
|
+
// token is invisible at 1px, and this thread is the part
|
|
1084
|
+
// that makes three rows read as one advancing sequence
|
|
1085
|
+
// rather than three unrelated lines.
|
|
1086
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "saas-switch-link h-5 w-0.5 rounded-full bg-primary/30" }),
|
|
1087
|
+
/* @__PURE__ */ jsx("span", { className: "flex h-7 w-6 items-center justify-center", children: done ? /* @__PURE__ */ jsx(Check, { className: "h-5 w-5 text-primary", strokeWidth: 2.5 }) : isSecurity ? /* @__PURE__ */ jsx(ShieldCheck, { className: "saas-switch-dot h-5 w-5 text-primary", strokeWidth: 2 }) : /* @__PURE__ */ jsx("span", { className: "saas-switch-dot h-2 w-2 rounded-full bg-primary" }) })
|
|
1088
|
+
] }),
|
|
1089
|
+
/* @__PURE__ */ jsx(
|
|
1090
|
+
"span",
|
|
1091
|
+
{
|
|
1092
|
+
className: cn(
|
|
1093
|
+
"flex h-7 items-center text-base transition-colors duration-300 sm:text-lg",
|
|
1094
|
+
// Only ever two states now — done, or happening. Nothing is
|
|
1095
|
+
// on screen before its turn, so there is no "ahead" tone.
|
|
1096
|
+
done ? "text-muted-foreground" : "font-medium text-foreground",
|
|
1097
|
+
// Push the label down past the connector so it stays level
|
|
1098
|
+
// with its own marker rather than with the thread above it.
|
|
1099
|
+
i > 0 && "mt-5"
|
|
1100
|
+
),
|
|
1101
|
+
children: label
|
|
1102
|
+
}
|
|
1103
|
+
)
|
|
1104
|
+
] }, label);
|
|
1105
|
+
}) })
|
|
1106
|
+
] })
|
|
1107
|
+
}
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
function WorkspaceMark2({ name, logoUrl }) {
|
|
1111
|
+
if (logoUrl) {
|
|
1112
|
+
return /* @__PURE__ */ jsx(
|
|
1113
|
+
"img",
|
|
1114
|
+
{
|
|
1115
|
+
src: logoUrl,
|
|
1116
|
+
alt: "",
|
|
1117
|
+
className: "relative h-16 w-16 rounded-2xl object-cover shadow-sm"
|
|
1118
|
+
}
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
const initials = name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join("").toUpperCase();
|
|
1122
|
+
return /* @__PURE__ */ jsx("span", { className: "relative flex h-16 w-16 items-center justify-center rounded-2xl bg-primary text-xl font-semibold text-primary-foreground shadow-sm", children: initials || /* @__PURE__ */ jsx(Building2, { className: "h-7 w-7" }) });
|
|
1123
|
+
}
|
|
1124
|
+
function WorkspaceSwitchingHost() {
|
|
1125
|
+
const target = useWorkspaceSwitchingStore((s) => s.target);
|
|
1126
|
+
if (!target) return null;
|
|
1127
|
+
return /* @__PURE__ */ jsx(
|
|
1128
|
+
WorkspaceSwitching,
|
|
1129
|
+
{
|
|
1130
|
+
orgName: target.orgName,
|
|
1131
|
+
orgLogoUrl: target.orgLogoUrl,
|
|
1132
|
+
onDone: () => window.location.reload()
|
|
1133
|
+
}
|
|
1134
|
+
);
|
|
1135
|
+
}
|
|
845
1136
|
|
|
846
|
-
export { createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, getFayzSupabaseClient, getFayzSupabaseClientOptional };
|
|
847
|
-
//# sourceMappingURL=chunk-
|
|
848
|
-
//# sourceMappingURL=chunk-
|
|
1137
|
+
export { WorkspaceChooser, WorkspaceChooserGate, WorkspaceSwitching, WorkspaceSwitchingHost, createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, getFayzSupabaseClient, getFayzSupabaseClientOptional, resolveAppId, useWorkspaceSwitchingStore };
|
|
1138
|
+
//# sourceMappingURL=chunk-UHHEPU4A.js.map
|
|
1139
|
+
//# sourceMappingURL=chunk-UHHEPU4A.js.map
|