@oondemand/oon-core-front 0.4.10 → 0.4.12
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/index.d.ts +9 -4
- package/dist/index.js +100 -166
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -237,11 +237,14 @@ interface OonModule {
|
|
|
237
237
|
views?: OonViewDefinition[];
|
|
238
238
|
}
|
|
239
239
|
type CollectionMode = "full" | "minimal" | "dynamic";
|
|
240
|
+
type OonValueFormat = "text" | "number" | "currency" | "percent" | "date" | "datetime" | "badge";
|
|
240
241
|
interface OonColumnDef {
|
|
241
242
|
field: string;
|
|
242
243
|
label?: string;
|
|
243
244
|
/** kind sobrescreve o inferido da metadata. */
|
|
244
245
|
kind?: FieldKind;
|
|
246
|
+
/** Formato de apresentação; datetime preserva data e hora no locale do usuário. */
|
|
247
|
+
format?: OonValueFormat;
|
|
245
248
|
sortable?: boolean;
|
|
246
249
|
width?: number;
|
|
247
250
|
renderer?: string;
|
|
@@ -362,7 +365,7 @@ type OonRelationDef = {
|
|
|
362
365
|
type OonRelatedGridColumnDef = OonColumnDef & {
|
|
363
366
|
editable?: boolean;
|
|
364
367
|
readonly?: boolean;
|
|
365
|
-
format?:
|
|
368
|
+
format?: OonValueFormat;
|
|
366
369
|
editor?: "string" | "number" | "currency" | "date" | "enum" | "select" | "ref" | "boolean" | "textarea";
|
|
367
370
|
hidden?: boolean;
|
|
368
371
|
roles?: string[];
|
|
@@ -375,7 +378,7 @@ type OonSummaryCardDef = {
|
|
|
375
378
|
field?: string;
|
|
376
379
|
relation?: string | OonRelationDef;
|
|
377
380
|
metric?: string;
|
|
378
|
-
format?:
|
|
381
|
+
format?: OonValueFormat;
|
|
379
382
|
};
|
|
380
383
|
type OonDetailTabDef = {
|
|
381
384
|
id: string;
|
|
@@ -1135,8 +1138,10 @@ interface TenantStorage {
|
|
|
1135
1138
|
clear(): void;
|
|
1136
1139
|
}
|
|
1137
1140
|
/**
|
|
1138
|
-
*
|
|
1139
|
-
*
|
|
1141
|
+
* Mantém o tenant no escopo da aba. Isso permite abrir Tenant A e Tenant B em
|
|
1142
|
+
* janelas diferentes sem uma aba trocar o contexto da outra. O query param
|
|
1143
|
+
* `tenant` transporta somente o identificador selecionado; o backend continua
|
|
1144
|
+
* validando o membership em todas as requisições.
|
|
1140
1145
|
*/
|
|
1141
1146
|
declare function createTenantStorage(appId: string): TenantStorage;
|
|
1142
1147
|
|
package/dist/index.js
CHANGED
|
@@ -160,24 +160,37 @@ function normalize(value3) {
|
|
|
160
160
|
const normalized3 = String(value3 ?? "").trim();
|
|
161
161
|
return normalized3 || null;
|
|
162
162
|
}
|
|
163
|
+
function tenantFromUrl(key) {
|
|
164
|
+
if (typeof window === "undefined") return null;
|
|
165
|
+
const url = new URL(window.location.href);
|
|
166
|
+
const tenantId = normalize(url.searchParams.get("tenant"));
|
|
167
|
+
if (!tenantId) return null;
|
|
168
|
+
window.sessionStorage.setItem(key, tenantId);
|
|
169
|
+
url.searchParams.delete("tenant");
|
|
170
|
+
window.history.replaceState(window.history.state, "", `${url.pathname}${url.search}${url.hash}`);
|
|
171
|
+
return tenantId;
|
|
172
|
+
}
|
|
163
173
|
function createTenantStorage(appId) {
|
|
164
174
|
const key = `oon:${appId}:tenant`;
|
|
165
175
|
return {
|
|
166
176
|
get() {
|
|
167
177
|
if (typeof window === "undefined") return null;
|
|
168
|
-
|
|
178
|
+
const incoming = tenantFromUrl(key);
|
|
179
|
+
if (incoming) return incoming;
|
|
180
|
+
window.localStorage.removeItem(key);
|
|
181
|
+
return normalize(window.sessionStorage.getItem(key));
|
|
169
182
|
},
|
|
170
183
|
set(tenantId) {
|
|
171
184
|
if (typeof window === "undefined") return;
|
|
172
185
|
const value3 = normalize(tenantId);
|
|
173
186
|
if (!value3) {
|
|
174
|
-
window.
|
|
187
|
+
window.sessionStorage.removeItem(key);
|
|
175
188
|
return;
|
|
176
189
|
}
|
|
177
|
-
window.
|
|
190
|
+
window.sessionStorage.setItem(key, value3);
|
|
178
191
|
},
|
|
179
192
|
clear() {
|
|
180
|
-
if (typeof window !== "undefined") window.
|
|
193
|
+
if (typeof window !== "undefined") window.sessionStorage.removeItem(key);
|
|
181
194
|
}
|
|
182
195
|
};
|
|
183
196
|
}
|
|
@@ -1053,7 +1066,7 @@ function formFieldsFromMeta(fields) {
|
|
|
1053
1066
|
};
|
|
1054
1067
|
});
|
|
1055
1068
|
}
|
|
1056
|
-
function formatCell(value3, kind) {
|
|
1069
|
+
function formatCell(value3, kind, format2) {
|
|
1057
1070
|
if (value3 == null || value3 === "") return "\u2014";
|
|
1058
1071
|
if (value3 && typeof value3 === "object" && !Array.isArray(value3) && kind !== "date") {
|
|
1059
1072
|
return referenceOptionLabel(value3);
|
|
@@ -1063,7 +1076,8 @@ function formatCell(value3, kind) {
|
|
|
1063
1076
|
return value3 ? "Sim" : "N\xE3o";
|
|
1064
1077
|
case "date":
|
|
1065
1078
|
try {
|
|
1066
|
-
|
|
1079
|
+
const date = new Date(value3);
|
|
1080
|
+
return format2 === "datetime" ? date.toLocaleString("pt-BR", { dateStyle: "short", timeStyle: "short" }) : date.toLocaleDateString("pt-BR");
|
|
1067
1081
|
} catch {
|
|
1068
1082
|
return String(value3);
|
|
1069
1083
|
}
|
|
@@ -1140,8 +1154,8 @@ function ChevronIcon({ direction }) {
|
|
|
1140
1154
|
function PlusIcon() {
|
|
1141
1155
|
return /* @__PURE__ */ jsx11("svg", { viewBox: "0 0 20 20", width: "17", height: "17", "aria-hidden": "true", children: /* @__PURE__ */ jsx11("path", { d: "M10 4v12M4 10h12", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round" }) });
|
|
1142
1156
|
}
|
|
1143
|
-
function renderCell(value3, kind) {
|
|
1144
|
-
const formatted = formatCell(value3, kind);
|
|
1157
|
+
function renderCell(value3, kind, format2) {
|
|
1158
|
+
const formatted = formatCell(value3, kind, format2);
|
|
1145
1159
|
if (kind === "enum") {
|
|
1146
1160
|
const normalized3 = String(value3 ?? "").toLowerCase();
|
|
1147
1161
|
const palette = /erro|cancel|inativo|recus|critica/.test(normalized3) ? "red" : /pendente|aguardando|rascunho/.test(normalized3) ? "orange" : /processando|conferencia|integrando|validando/.test(normalized3) ? "blue" : /ativo|sucesso|conclu|aplicada|disponivel|aprov/.test(normalized3) ? "green" : "gray";
|
|
@@ -1157,7 +1171,7 @@ function renderColumnCell(row, column, cellRenderers) {
|
|
|
1157
1171
|
const value3 = row[column.field];
|
|
1158
1172
|
const Renderer = column.renderer ? cellRenderers?.[column.renderer] : void 0;
|
|
1159
1173
|
if (Renderer) return /* @__PURE__ */ jsx11(Renderer, { value: value3, row, column });
|
|
1160
|
-
return renderCell(value3, column.kind);
|
|
1174
|
+
return renderCell(value3, column.kind, column.format);
|
|
1161
1175
|
}
|
|
1162
1176
|
function DataGrid({
|
|
1163
1177
|
resource,
|
|
@@ -2539,7 +2553,7 @@ import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs10 } from "react/jsx-r
|
|
|
2539
2553
|
function format(value3, format2) {
|
|
2540
2554
|
if (format2 === "currency") return new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(Number(value3 ?? 0));
|
|
2541
2555
|
if (format2 === "percent") return `${Number(value3 ?? 0).toLocaleString("pt-BR")}%`;
|
|
2542
|
-
if (format2 === "date") return formatCell(value3, "date");
|
|
2556
|
+
if (format2 === "date" || format2 === "datetime") return formatCell(value3, "date", format2);
|
|
2543
2557
|
return value3 == null || value3 === "" ? "\u2014" : String(value3);
|
|
2544
2558
|
}
|
|
2545
2559
|
function RelatedMetric({ card, relation, parent }) {
|
|
@@ -5277,7 +5291,7 @@ function Sidebar({ app, menu, registry }) {
|
|
|
5277
5291
|
// package.json
|
|
5278
5292
|
var package_default = {
|
|
5279
5293
|
name: "@oondemand/oon-core-front",
|
|
5280
|
-
version: "0.4.
|
|
5294
|
+
version: "0.4.12",
|
|
5281
5295
|
repository: {
|
|
5282
5296
|
type: "git",
|
|
5283
5297
|
url: "git+https://github.com/oondemand/oon-platform.git",
|
|
@@ -5733,16 +5747,7 @@ function AppAccessGuard({ children }) {
|
|
|
5733
5747
|
|
|
5734
5748
|
// src/security/LoginPage.tsx
|
|
5735
5749
|
import { useState as useState18 } from "react";
|
|
5736
|
-
import {
|
|
5737
|
-
Box as Box25,
|
|
5738
|
-
Button as Button18,
|
|
5739
|
-
Flex as Flex18,
|
|
5740
|
-
Heading as Heading14,
|
|
5741
|
-
Input as Input10,
|
|
5742
|
-
SimpleGrid as SimpleGrid6,
|
|
5743
|
-
Text as Text26,
|
|
5744
|
-
VStack as VStack5
|
|
5745
|
-
} from "@chakra-ui/react";
|
|
5750
|
+
import { Box as Box25, Button as Button18, Flex as Flex18, Heading as Heading14, Input as Input10, SimpleGrid as SimpleGrid6, Text as Text26, VStack as VStack5 } from "@chakra-ui/react";
|
|
5746
5751
|
import { Link as Link3, Navigate as Navigate2, useLocation as useLocation4 } from "react-router-dom";
|
|
5747
5752
|
import { jsx as jsx37, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5748
5753
|
function tenantOptions(error) {
|
|
@@ -5753,17 +5758,22 @@ function tenantOptions(error) {
|
|
|
5753
5758
|
return tenants.filter((tenant) => Boolean(tenant) && typeof tenant === "object").map((tenant) => ({
|
|
5754
5759
|
id: String(tenant.id || ""),
|
|
5755
5760
|
nome: String(tenant.nome || tenant.slug || tenant.id || ""),
|
|
5756
|
-
slug: tenant.slug ? String(tenant.slug) : void 0
|
|
5761
|
+
slug: tenant.slug ? String(tenant.slug) : void 0,
|
|
5762
|
+
tipo: tenant.tipo ? String(tenant.tipo) : void 0,
|
|
5763
|
+
status: tenant.status ? String(tenant.status) : void 0
|
|
5757
5764
|
})).filter((tenant) => tenant.id && tenant.nome);
|
|
5758
5765
|
}
|
|
5759
5766
|
function safeRedirect(search) {
|
|
5760
5767
|
const value3 = new URLSearchParams(search).get("redirect") || "/";
|
|
5761
5768
|
if (!value3.startsWith("/") || value3.startsWith("//")) return "/";
|
|
5762
|
-
if (value3.startsWith("/login") || value3.startsWith("/acesso-negado"))
|
|
5763
|
-
return "/";
|
|
5764
|
-
}
|
|
5769
|
+
if (value3.startsWith("/login") || value3.startsWith("/acesso-negado")) return "/";
|
|
5765
5770
|
return value3;
|
|
5766
5771
|
}
|
|
5772
|
+
function tenantUrl(path, tenantId) {
|
|
5773
|
+
const target = new URL(path, window.location.origin);
|
|
5774
|
+
target.searchParams.set("tenant", tenantId);
|
|
5775
|
+
return target.toString();
|
|
5776
|
+
}
|
|
5767
5777
|
function LoginPage({ app, onboardingEnabled = false }) {
|
|
5768
5778
|
const { status, login } = useOonAuth();
|
|
5769
5779
|
const location = useLocation4();
|
|
@@ -5772,168 +5782,92 @@ function LoginPage({ app, onboardingEnabled = false }) {
|
|
|
5772
5782
|
const [submitting, setSubmitting] = useState18(false);
|
|
5773
5783
|
const [message, setMessage] = useState18(null);
|
|
5774
5784
|
const [tenants, setTenants] = useState18([]);
|
|
5775
|
-
const [
|
|
5785
|
+
const [selectorMode, setSelectorMode] = useState18(false);
|
|
5786
|
+
const [openingTenant, setOpeningTenant] = useState18(null);
|
|
5776
5787
|
const redirect = safeRedirect(location.search);
|
|
5777
|
-
if (status === "authenticated") {
|
|
5778
|
-
|
|
5779
|
-
}
|
|
5780
|
-
if (status === "forbidden") {
|
|
5781
|
-
return /* @__PURE__ */ jsx37(Navigate2, { to: "/acesso-negado", replace: true });
|
|
5782
|
-
}
|
|
5788
|
+
if (status === "authenticated" && !selectorMode) return /* @__PURE__ */ jsx37(Navigate2, { to: redirect, replace: true });
|
|
5789
|
+
if (status === "forbidden") return /* @__PURE__ */ jsx37(Navigate2, { to: "/acesso-negado", replace: true });
|
|
5783
5790
|
async function handleSubmit(event) {
|
|
5784
5791
|
event.preventDefault();
|
|
5792
|
+
if (tenants.length > 1) return;
|
|
5785
5793
|
setSubmitting(true);
|
|
5786
5794
|
setMessage(null);
|
|
5787
5795
|
try {
|
|
5788
|
-
|
|
5789
|
-
setMessage("Selecione a organiza\xE7\xE3o para continuar.");
|
|
5790
|
-
return;
|
|
5791
|
-
}
|
|
5792
|
-
await login(email.trim(), password, tenantId || void 0);
|
|
5796
|
+
await login(email.trim(), password);
|
|
5793
5797
|
} catch (error) {
|
|
5794
5798
|
const authError = error;
|
|
5795
5799
|
if (authError.code === "TENANT_SELECTION_REQUIRED") {
|
|
5796
5800
|
const options = tenantOptions(authError);
|
|
5797
5801
|
if (options.length > 1) {
|
|
5798
5802
|
setTenants(options);
|
|
5799
|
-
|
|
5800
|
-
setMessage("Seu usu\xE1rio possui acesso a mais de uma organiza\xE7\xE3o. Selecione uma para continuar.");
|
|
5803
|
+
setMessage("Escolha uma organiza\xE7\xE3o. O tenant ser\xE1 aberto em uma nova aba.");
|
|
5801
5804
|
return;
|
|
5802
5805
|
}
|
|
5803
5806
|
}
|
|
5804
5807
|
if (authError.status === 403) return;
|
|
5805
|
-
setMessage(
|
|
5806
|
-
authError.status === 401 ? "E-mail ou senha inv\xE1lidos." : authError.message || "N\xE3o foi poss\xEDvel entrar. Tente novamente."
|
|
5807
|
-
);
|
|
5808
|
+
setMessage(authError.status === 401 ? "E-mail ou senha inv\xE1lidos." : authError.message || "N\xE3o foi poss\xEDvel entrar. Tente novamente.");
|
|
5808
5809
|
} finally {
|
|
5809
5810
|
setSubmitting(false);
|
|
5810
5811
|
}
|
|
5811
5812
|
}
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
borderWidth: "1px",
|
|
5819
|
-
borderColor: "#E4EBEF",
|
|
5820
|
-
borderRadius: "18px",
|
|
5821
|
-
boxShadow: "0 24px 70px rgba(7, 38, 46, 0.10)",
|
|
5822
|
-
p: { base: 6, md: 9 },
|
|
5823
|
-
children: /* @__PURE__ */ jsx37("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs26(VStack5, { align: "stretch", gap: 6, children: [
|
|
5824
|
-
/* @__PURE__ */ jsxs26(Box25, { children: [
|
|
5825
|
-
/* @__PURE__ */ jsx37(
|
|
5826
|
-
Text26,
|
|
5827
|
-
{
|
|
5828
|
-
color: "#39BFED",
|
|
5829
|
-
fontSize: "xs",
|
|
5830
|
-
fontWeight: "700",
|
|
5831
|
-
letterSpacing: "0.12em",
|
|
5832
|
-
textTransform: "uppercase",
|
|
5833
|
-
children: "Central Oon"
|
|
5834
|
-
}
|
|
5835
|
-
),
|
|
5836
|
-
/* @__PURE__ */ jsx37(Heading14, { mt: 2, size: "lg", color: "#07262E", children: app.title ?? app.name }),
|
|
5837
|
-
/* @__PURE__ */ jsx37(Text26, { mt: 2, color: "gray.600", fontSize: "sm", children: "Entre com seu usu\xE1rio autorizado para acessar este aplicativo." })
|
|
5838
|
-
] }),
|
|
5839
|
-
/* @__PURE__ */ jsxs26(VStack5, { align: "stretch", gap: 4, children: [
|
|
5840
|
-
/* @__PURE__ */ jsxs26(Box25, { children: [
|
|
5841
|
-
/* @__PURE__ */ jsx37(Text26, { mb: 2, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "E-mail" }),
|
|
5842
|
-
/* @__PURE__ */ jsx37(
|
|
5843
|
-
Input10,
|
|
5844
|
-
{
|
|
5845
|
-
type: "email",
|
|
5846
|
-
value: email,
|
|
5847
|
-
onChange: (event) => {
|
|
5848
|
-
setEmail(event.target.value);
|
|
5849
|
-
setTenants([]);
|
|
5850
|
-
setTenantId("");
|
|
5851
|
-
},
|
|
5852
|
-
autoComplete: "email",
|
|
5853
|
-
placeholder: "voce@empresa.com.br",
|
|
5854
|
-
required: true
|
|
5855
|
-
}
|
|
5856
|
-
)
|
|
5857
|
-
] }),
|
|
5858
|
-
/* @__PURE__ */ jsxs26(Box25, { children: [
|
|
5859
|
-
/* @__PURE__ */ jsx37(Text26, { mb: 2, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "Senha" }),
|
|
5860
|
-
/* @__PURE__ */ jsx37(
|
|
5861
|
-
Input10,
|
|
5862
|
-
{
|
|
5863
|
-
type: "password",
|
|
5864
|
-
value: password,
|
|
5865
|
-
onChange: (event) => setPassword(event.target.value),
|
|
5866
|
-
autoComplete: "current-password",
|
|
5867
|
-
placeholder: "Sua senha",
|
|
5868
|
-
required: true
|
|
5869
|
-
}
|
|
5870
|
-
)
|
|
5871
|
-
] }),
|
|
5872
|
-
tenants.length > 1 ? /* @__PURE__ */ jsxs26(Box25, { children: [
|
|
5873
|
-
/* @__PURE__ */ jsx37(Text26, { mb: 3, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "Escolha o tenant para acessar" }),
|
|
5874
|
-
/* @__PURE__ */ jsx37(SimpleGrid6, { columns: { base: 1, md: 2 }, gap: 3, children: tenants.map((tenant) => {
|
|
5875
|
-
const selected = tenantId === tenant.id;
|
|
5876
|
-
return /* @__PURE__ */ jsx37(
|
|
5877
|
-
Button18,
|
|
5878
|
-
{
|
|
5879
|
-
type: "button",
|
|
5880
|
-
variant: "outline",
|
|
5881
|
-
height: "auto",
|
|
5882
|
-
minH: "88px",
|
|
5883
|
-
justifyContent: "flex-start",
|
|
5884
|
-
whiteSpace: "normal",
|
|
5885
|
-
textAlign: "left",
|
|
5886
|
-
borderWidth: "2px",
|
|
5887
|
-
borderColor: selected ? "#39BFED" : "#D9E2E7",
|
|
5888
|
-
bg: selected ? "#EFFAFF" : "white",
|
|
5889
|
-
color: "#24323A",
|
|
5890
|
-
"aria-pressed": selected,
|
|
5891
|
-
onClick: () => {
|
|
5892
|
-
setTenantId(tenant.id);
|
|
5893
|
-
setMessage(null);
|
|
5894
|
-
},
|
|
5895
|
-
_hover: { borderColor: "#39BFED", bg: "#F6FCFE" },
|
|
5896
|
-
children: /* @__PURE__ */ jsxs26(VStack5, { align: "start", gap: 1, py: 3, children: [
|
|
5897
|
-
/* @__PURE__ */ jsx37(Text26, { fontWeight: "700", children: tenant.nome }),
|
|
5898
|
-
tenant.slug ? /* @__PURE__ */ jsx37(Text26, { fontSize: "xs", color: "gray.500", children: tenant.slug }) : null
|
|
5899
|
-
] })
|
|
5900
|
-
},
|
|
5901
|
-
tenant.id
|
|
5902
|
-
);
|
|
5903
|
-
}) })
|
|
5904
|
-
] }) : null
|
|
5905
|
-
] }),
|
|
5906
|
-
message ? /* @__PURE__ */ jsx37(
|
|
5907
|
-
Box25,
|
|
5908
|
-
{
|
|
5909
|
-
role: "alert",
|
|
5910
|
-
borderRadius: "10px",
|
|
5911
|
-
bg: "red.50",
|
|
5912
|
-
color: "red.700",
|
|
5913
|
-
px: 4,
|
|
5914
|
-
py: 3,
|
|
5915
|
-
fontSize: "sm",
|
|
5916
|
-
children: message
|
|
5917
|
-
}
|
|
5918
|
-
) : null,
|
|
5919
|
-
/* @__PURE__ */ jsx37(
|
|
5920
|
-
Button18,
|
|
5921
|
-
{
|
|
5922
|
-
type: "submit",
|
|
5923
|
-
bg: "#07262E",
|
|
5924
|
-
color: "white",
|
|
5925
|
-
_hover: { bg: "#0B3843" },
|
|
5926
|
-
disabled: submitting || !email.trim() || !password || tenants.length > 1 && !tenantId,
|
|
5927
|
-
children: submitting ? "Validando acesso..." : "Entrar"
|
|
5928
|
-
}
|
|
5929
|
-
),
|
|
5930
|
-
app.kind === "portal-cockpit" && onboardingEnabled ? /* @__PURE__ */ jsxs26(Text26, { textAlign: "center", fontSize: "sm", color: "gray.600", children: [
|
|
5931
|
-
"Ainda n\xE3o possui acesso? ",
|
|
5932
|
-
/* @__PURE__ */ jsx37(Link3, { to: "/cadastro", children: "Criar cadastro" })
|
|
5933
|
-
] }) : null
|
|
5934
|
-
] }) })
|
|
5813
|
+
async function openTenant(tenant) {
|
|
5814
|
+
if (openingTenant) return;
|
|
5815
|
+
const popup = window.open("about:blank", "_blank");
|
|
5816
|
+
if (!popup) {
|
|
5817
|
+
setMessage("Permita pop-ups para abrir o tenant em uma nova aba.");
|
|
5818
|
+
return;
|
|
5935
5819
|
}
|
|
5936
|
-
|
|
5820
|
+
popup.opener = null;
|
|
5821
|
+
setOpeningTenant(tenant.id);
|
|
5822
|
+
setSelectorMode(true);
|
|
5823
|
+
setMessage(null);
|
|
5824
|
+
try {
|
|
5825
|
+
if (status !== "authenticated") await login(email.trim(), password, tenant.id);
|
|
5826
|
+
popup.location.replace(tenantUrl(redirect, tenant.id));
|
|
5827
|
+
setPassword("");
|
|
5828
|
+
setMessage(`${tenant.nome} foi aberto em uma nova aba. Escolha outro tenant quando precisar.`);
|
|
5829
|
+
} catch (error) {
|
|
5830
|
+
popup.close();
|
|
5831
|
+
const authError = error;
|
|
5832
|
+
setMessage(authError.message || "N\xE3o foi poss\xEDvel abrir o tenant.");
|
|
5833
|
+
} finally {
|
|
5834
|
+
setOpeningTenant(null);
|
|
5835
|
+
}
|
|
5836
|
+
}
|
|
5837
|
+
return /* @__PURE__ */ jsx37(Flex18, { minH: "100vh", align: "center", justify: "center", bg: "#F5F8FA", px: 4, children: /* @__PURE__ */ jsx37(Box25, { width: "100%", maxW: tenants.length > 1 ? "760px" : "440px", bg: "white", borderWidth: "1px", borderColor: "#E4EBEF", borderRadius: "18px", boxShadow: "0 24px 70px rgba(7, 38, 46, 0.10)", p: { base: 6, md: 9 }, children: /* @__PURE__ */ jsx37("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs26(VStack5, { align: "stretch", gap: 6, children: [
|
|
5838
|
+
/* @__PURE__ */ jsxs26(Box25, { children: [
|
|
5839
|
+
/* @__PURE__ */ jsx37(Text26, { color: "#39BFED", fontSize: "xs", fontWeight: "700", letterSpacing: "0.12em", textTransform: "uppercase", children: "Central Oon" }),
|
|
5840
|
+
/* @__PURE__ */ jsx37(Heading14, { mt: 2, size: "lg", color: "#07262E", children: app.title ?? app.name }),
|
|
5841
|
+
/* @__PURE__ */ jsx37(Text26, { mt: 2, color: "gray.600", fontSize: "sm", children: tenants.length > 1 ? "Abra uma ou mais organiza\xE7\xF5es para trabalhar em contextos separados." : "Entre com seu usu\xE1rio autorizado para acessar este aplicativo." })
|
|
5842
|
+
] }),
|
|
5843
|
+
tenants.length <= 1 ? /* @__PURE__ */ jsxs26(VStack5, { align: "stretch", gap: 4, children: [
|
|
5844
|
+
/* @__PURE__ */ jsxs26(Box25, { children: [
|
|
5845
|
+
/* @__PURE__ */ jsx37(Text26, { mb: 2, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "E-mail" }),
|
|
5846
|
+
/* @__PURE__ */ jsx37(Input10, { type: "email", value: email, onChange: (event) => {
|
|
5847
|
+
setEmail(event.target.value);
|
|
5848
|
+
setTenants([]);
|
|
5849
|
+
setSelectorMode(false);
|
|
5850
|
+
}, autoComplete: "email", placeholder: "voce@empresa.com.br", required: true })
|
|
5851
|
+
] }),
|
|
5852
|
+
/* @__PURE__ */ jsxs26(Box25, { children: [
|
|
5853
|
+
/* @__PURE__ */ jsx37(Text26, { mb: 2, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "Senha" }),
|
|
5854
|
+
/* @__PURE__ */ jsx37(Input10, { type: "password", value: password, onChange: (event) => setPassword(event.target.value), autoComplete: "current-password", placeholder: "Sua senha", required: true })
|
|
5855
|
+
] })
|
|
5856
|
+
] }) : /* @__PURE__ */ jsxs26(Box25, { children: [
|
|
5857
|
+
/* @__PURE__ */ jsx37(Text26, { mb: 3, fontSize: "sm", fontWeight: "600", color: "#24323A", children: "Escolha o tenant para acessar" }),
|
|
5858
|
+
/* @__PURE__ */ jsx37(SimpleGrid6, { columns: { base: 1, md: 2 }, gap: 3, children: tenants.map((tenant) => /* @__PURE__ */ jsx37(Button18, { type: "button", variant: "outline", height: "auto", minH: "104px", justifyContent: "flex-start", whiteSpace: "normal", textAlign: "left", borderWidth: "2px", borderColor: "#D9E2E7", bg: "white", color: "#24323A", disabled: Boolean(openingTenant), "aria-label": `Abrir ${tenant.nome} em nova aba`, onClick: () => void openTenant(tenant), _hover: { borderColor: "#39BFED", bg: "#F6FCFE" }, children: /* @__PURE__ */ jsxs26(VStack5, { align: "start", gap: 1, py: 3, children: [
|
|
5859
|
+
/* @__PURE__ */ jsx37(Text26, { fontWeight: "700", children: tenant.nome }),
|
|
5860
|
+
/* @__PURE__ */ jsx37(Text26, { fontSize: "xs", color: "gray.500", children: [tenant.slug, tenant.tipo, tenant.status].filter(Boolean).join(" \xB7 ") }),
|
|
5861
|
+
/* @__PURE__ */ jsx37(Text26, { fontSize: "xs", color: "#168EB9", children: openingTenant === tenant.id ? "Abrindo..." : "Abrir em nova aba" })
|
|
5862
|
+
] }) }, tenant.id)) })
|
|
5863
|
+
] }),
|
|
5864
|
+
message ? /* @__PURE__ */ jsx37(Box25, { role: "status", borderRadius: "10px", bg: "blue.50", color: "blue.800", px: 4, py: 3, fontSize: "sm", children: message }) : null,
|
|
5865
|
+
tenants.length <= 1 ? /* @__PURE__ */ jsx37(Button18, { type: "submit", bg: "#07262E", color: "white", _hover: { bg: "#0B3843" }, disabled: submitting || !email.trim() || !password, children: submitting ? "Validando acesso..." : "Entrar" }) : null,
|
|
5866
|
+
app.kind === "portal-cockpit" && onboardingEnabled && tenants.length <= 1 ? /* @__PURE__ */ jsxs26(Text26, { textAlign: "center", fontSize: "sm", color: "gray.600", children: [
|
|
5867
|
+
"Ainda n\xE3o possui acesso? ",
|
|
5868
|
+
/* @__PURE__ */ jsx37(Link3, { to: "/cadastro", children: "Criar conta" })
|
|
5869
|
+
] }) : null
|
|
5870
|
+
] }) }) }) });
|
|
5937
5871
|
}
|
|
5938
5872
|
|
|
5939
5873
|
// src/security/FirstAccessPage.tsx
|