important changes
This commit is contained in:
parent
e1f501fa48
commit
c75420a91c
1
dist/core.d.ts
vendored
1
dist/core.d.ts
vendored
@ -41,7 +41,6 @@ export type BiProviderProps = {
|
|||||||
permissionEnabled?: boolean;
|
permissionEnabled?: boolean;
|
||||||
theme?: any;
|
theme?: any;
|
||||||
remoteUiEnabled?: boolean;
|
remoteUiEnabled?: boolean;
|
||||||
remoteUiUrl?: string;
|
|
||||||
remoteUiChakraProviderProps?: Record<string, any>;
|
remoteUiChakraProviderProps?: Record<string, any>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
523
dist/core.js
vendored
523
dist/core.js
vendored
@ -1,78 +1,79 @@
|
|||||||
import j from "axios";
|
import Q from "axios";
|
||||||
import { jsx as q, jsxs as M } from "react/jsx-runtime";
|
import { jsx as Z, jsxs as A } from "react/jsx-runtime";
|
||||||
import _ from "keycloak-js";
|
import j from "keycloak-js";
|
||||||
import $, { createContext as V, useState as z, useRef as N, useCallback as X, useEffect as g, useMemo as x, useContext as ee } from "react";
|
import _, { createContext as C, useState as X, useRef as L, useCallback as K, useEffect as z, useMemo as g, useContext as $ } from "react";
|
||||||
import { useQueryClient as te, useMutation as re, useQuery as f, QueryClient as ne, QueryClientProvider as oe } from "@tanstack/react-query";
|
import { useQueryClient as ee, useMutation as te, useQuery as f, QueryClient as re, QueryClientProvider as ne } from "@tanstack/react-query";
|
||||||
import { extendTheme as ie, withDefaultColorScheme as se, ChakraProvider as R, Spinner as ae, Badge as ue } from "@chakra-ui/react";
|
import { createRoot as oe } from "react-dom/client";
|
||||||
|
import { extendTheme as ie, withDefaultColorScheme as se, ChakraProvider as V, Spinner as ae, Badge as ue } from "@chakra-ui/react";
|
||||||
import { Global as de } from "@emotion/react";
|
import { Global as de } from "@emotion/react";
|
||||||
let W = null, o = null, O = null, v = !1;
|
let W = null, o = null, Y = null, O = !1;
|
||||||
const ce = V(null), le = ({ url: e, realm: t, clientId: r }) => (o || (o = new _({
|
const ce = C(null), le = ({ url: e, realm: r, clientId: t }) => (o || (o = new j({
|
||||||
url: e,
|
url: e,
|
||||||
realm: t,
|
realm: r,
|
||||||
clientId: r
|
clientId: t
|
||||||
})), o), he = (e) => (W = e, W), Fe = () => v, I = () => !!(o != null && o.authenticated), w = () => (o == null ? void 0 : o.token) ?? null, D = async (e = 30) => o ? o.updateToken(e) : !1, G = (e) => o == null ? void 0 : o.logout(e), Ge = (e) => o == null ? void 0 : o.login(e), J = ({ config: e, initOptions: t = {} } = {}) => {
|
})), o), he = (e) => (W = e, W), Se = () => O, N = () => !!(o != null && o.authenticated), x = () => (o == null ? void 0 : o.token) ?? null, D = async (e = 30) => o ? o.updateToken(e) : !1, R = (e) => o == null ? void 0 : o.logout(e), Je = (e) => o == null ? void 0 : o.login(e), I = ({ config: e, initOptions: r = {} } = {}) => {
|
||||||
const r = e ?? W;
|
const t = e ?? W;
|
||||||
if (!(r != null && r.url) || !(r != null && r.realm) || !(r != null && r.clientId))
|
if (!(t != null && t.url) || !(t != null && t.realm) || !(t != null && t.clientId))
|
||||||
throw new Error("Keycloak config is required.");
|
throw new Error("Keycloak config is required.");
|
||||||
he(r);
|
he(t);
|
||||||
const n = le(r);
|
const n = le(t);
|
||||||
return O || (O = n.init({
|
return Y || (Y = n.init({
|
||||||
onLoad: "login-required",
|
onLoad: "login-required",
|
||||||
checkLoginIframe: !1,
|
checkLoginIframe: !1,
|
||||||
flow: "implicit",
|
flow: "implicit",
|
||||||
...t
|
...r
|
||||||
}).then((u) => (v = !0, u)).catch((u) => {
|
}).then((d) => (O = !0, d)).catch((d) => {
|
||||||
throw v = !0, u;
|
throw O = !0, d;
|
||||||
})), O;
|
})), Y;
|
||||||
}, Se = ({
|
}, Fe = ({
|
||||||
children: e,
|
children: e,
|
||||||
config: t,
|
config: r,
|
||||||
initOptions: r,
|
initOptions: t,
|
||||||
loading: n = null
|
loading: n = null
|
||||||
}) => {
|
}) => {
|
||||||
const [u, h] = z(!1), [d, s] = z(!1), [a, S] = z(null), p = N(!1), i = X(() => {
|
const [d, l] = X(!1), [u, s] = X(!1), [a, F] = X(null), p = L(!1), i = K(() => {
|
||||||
o && (s(!!o.authenticated), S(o.token ?? null));
|
o && (s(!!o.authenticated), F(o.token ?? null));
|
||||||
}, []);
|
}, []);
|
||||||
g(() => (p.current = !0, J({ config: t, initOptions: r }).then((c) => {
|
z(() => (p.current = !0, I({ config: r, initOptions: t }).then((h) => {
|
||||||
p.current && (s(!!c), S((o == null ? void 0 : o.token) ?? null), h(!0));
|
p.current && (s(!!h), F((o == null ? void 0 : o.token) ?? null), l(!0));
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
p.current && (s(!1), S(null), h(!0));
|
p.current && (s(!1), F(null), l(!0));
|
||||||
}), () => {
|
}), () => {
|
||||||
p.current = !1;
|
p.current = !1;
|
||||||
}), [t, r]);
|
}), [r, t]);
|
||||||
const l = X(() => o == null ? void 0 : o.login(), []), m = X((c) => o == null ? void 0 : o.logout(c), []), F = X(
|
const c = K(() => o == null ? void 0 : o.login(), []), m = K((h) => o == null ? void 0 : o.logout(h), []), S = K(
|
||||||
async (c = 30) => {
|
async (h = 30) => {
|
||||||
if (!o) return !1;
|
if (!o) return !1;
|
||||||
const Z = await o.updateToken(c);
|
const E = await o.updateToken(h);
|
||||||
return i(), Z;
|
return i(), E;
|
||||||
},
|
},
|
||||||
[i]
|
[i]
|
||||||
), E = x(
|
), q = g(
|
||||||
() => ({
|
() => ({
|
||||||
initialized: u,
|
initialized: d,
|
||||||
authenticated: d,
|
authenticated: u,
|
||||||
token: a,
|
token: a,
|
||||||
login: l,
|
login: c,
|
||||||
logout: m,
|
logout: m,
|
||||||
updateToken: F
|
updateToken: S
|
||||||
}),
|
}),
|
||||||
[u, d, a, l, m, F]
|
[d, u, a, c, m, S]
|
||||||
);
|
);
|
||||||
return u ? /* @__PURE__ */ q(ce.Provider, { value: E, children: e }) : n;
|
return d ? /* @__PURE__ */ Z(ce.Provider, { value: q, children: e }) : n;
|
||||||
};
|
};
|
||||||
let B = null;
|
let B = null;
|
||||||
const pe = (e) => {
|
const pe = (e) => {
|
||||||
const { api: t } = e, r = j.create({
|
const { api: r } = e, t = Q.create({
|
||||||
baseURL: t.baseUrl
|
baseURL: r.baseUrl
|
||||||
}), n = async () => {
|
}), n = async () => {
|
||||||
(!Fe() || !I()) && await J();
|
(!Se() || !N()) && await I();
|
||||||
}, u = !!e.keycloak, h = async (s) => {
|
}, d = !!e.keycloak, l = async (s) => {
|
||||||
if (!u) return s;
|
if (!d) return s;
|
||||||
await n();
|
await n();
|
||||||
let a = w();
|
let a = x();
|
||||||
if (a) {
|
if (a) {
|
||||||
try {
|
try {
|
||||||
await D(5), a = w();
|
await D(5), a = x();
|
||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
s.headers = {
|
s.headers = {
|
||||||
@ -81,271 +82,271 @@ const pe = (e) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}, d = async (s) => {
|
}, u = async (s) => {
|
||||||
var S;
|
var F;
|
||||||
const a = s.config;
|
const a = s.config;
|
||||||
if (((S = s == null ? void 0 : s.response) == null ? void 0 : S.status) === 401 && !(a != null && a._retry)) {
|
if (((F = s == null ? void 0 : s.response) == null ? void 0 : F.status) === 401 && !(a != null && a._retry)) {
|
||||||
a._retry = !0;
|
a._retry = !0;
|
||||||
try {
|
try {
|
||||||
await D(30);
|
await D(30);
|
||||||
const p = w();
|
const p = x();
|
||||||
return a.headers = {
|
return a.headers = {
|
||||||
...a.headers,
|
...a.headers,
|
||||||
Authorization: `Bearer ${p}`
|
Authorization: `Bearer ${p}`
|
||||||
}, r(a);
|
}, t(a);
|
||||||
} catch {
|
} catch {
|
||||||
G({ redirectUri: window.location.origin });
|
R({ redirectUri: window.location.origin });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Promise.reject(s);
|
return Promise.reject(s);
|
||||||
};
|
};
|
||||||
return r.interceptors.request.use(h), r.interceptors.response.use(
|
return t.interceptors.request.use(l), t.interceptors.response.use(
|
||||||
(s) => s,
|
(s) => s,
|
||||||
d
|
u
|
||||||
), {
|
), {
|
||||||
api: r
|
api: t
|
||||||
};
|
};
|
||||||
}, me = (e) => (B = pe(e), B), Ee = () => {
|
}, me = (e) => (B = pe(e), B), qe = () => {
|
||||||
if (!B)
|
if (!B)
|
||||||
throw new Error("api is not configured. Call configureApi(config) first.");
|
throw new Error("api is not configured. Call configureApi(config) first.");
|
||||||
return B.api;
|
return B.api;
|
||||||
}, H = new Proxy(
|
}, G = new Proxy(
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
get(e, t) {
|
get(e, r) {
|
||||||
return Ee()[t];
|
return qe()[r];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
), qe = async (e) => (await H.get(e)).data;
|
), Ee = async (e) => (await G.get(e)).data;
|
||||||
function P(e) {
|
function v(e) {
|
||||||
return Array.isArray(e) ? e : [e];
|
return Array.isArray(e) ? e : [e];
|
||||||
}
|
}
|
||||||
function Ze(e) {
|
function Ze(e) {
|
||||||
return [...P(e), "list"];
|
return [...v(e), "list"];
|
||||||
}
|
}
|
||||||
function C(e, t) {
|
function M(e, r) {
|
||||||
return [...P(e), t];
|
return [...v(e), r];
|
||||||
}
|
}
|
||||||
function be(e, t) {
|
function be(e, r) {
|
||||||
if (!t) return e;
|
if (!r) return e;
|
||||||
const r = new URLSearchParams();
|
const t = new URLSearchParams();
|
||||||
Object.entries(t).forEach(([u, h]) => {
|
Object.entries(r).forEach(([d, l]) => {
|
||||||
h != null && h !== "" && r.append(u, h);
|
l != null && l !== "" && t.append(d, l);
|
||||||
});
|
});
|
||||||
const n = r.toString();
|
const n = t.toString();
|
||||||
return n ? `${e}?${n}` : e;
|
return n ? `${e}?${n}` : e;
|
||||||
}
|
}
|
||||||
function ye(e, t) {
|
function ye(e, r) {
|
||||||
return typeof e == "function" ? e(t == null ? void 0 : t.id, t) : e;
|
return typeof e == "function" ? e(r == null ? void 0 : r.id, r) : e;
|
||||||
}
|
}
|
||||||
function Te(e = {}) {
|
function Te(e = {}) {
|
||||||
const { id: t, ...r } = e;
|
const { id: r, ...t } = e;
|
||||||
return r;
|
return t;
|
||||||
}
|
}
|
||||||
function Ke(e, t) {
|
function Ke(e, r) {
|
||||||
return `${e.replace(/\/$/, "")}/${t}`;
|
return `${e.replace(/\/$/, "")}/${r}`;
|
||||||
}
|
}
|
||||||
function Xe(e) {
|
function Xe(e) {
|
||||||
return `use${e.charAt(0).toUpperCase()}${e.slice(1)}`;
|
return `use${e.charAt(0).toUpperCase()}${e.slice(1)}`;
|
||||||
}
|
}
|
||||||
function Je({
|
function He({
|
||||||
key: e,
|
key: e,
|
||||||
url: t,
|
url: r,
|
||||||
actions: r = {},
|
actions: t = {},
|
||||||
axiosInstance: n = H,
|
axiosInstance: n = G,
|
||||||
fetcher: u = qe
|
fetcher: d = Ee
|
||||||
}) {
|
}) {
|
||||||
const h = P(e), d = Ze(e);
|
const l = v(e), u = Ze(e);
|
||||||
function s(i, l = {}) {
|
function s(i, c = {}) {
|
||||||
return f({
|
return f({
|
||||||
queryKey: i ? [...d, i] : d,
|
queryKey: i ? [...u, i] : u,
|
||||||
queryFn: () => u(be(t, i)),
|
queryFn: () => d(be(r, i)),
|
||||||
...l
|
...c
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function a(i, l = {}) {
|
function a(i, c = {}) {
|
||||||
return f({
|
return f({
|
||||||
queryKey: C(e, i),
|
queryKey: M(e, i),
|
||||||
queryFn: () => u(Ke(t, i)),
|
queryFn: () => d(Ke(r, i)),
|
||||||
enabled: !!i,
|
enabled: !!i,
|
||||||
...l
|
...c
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function S(i, l = {}) {
|
function F(i, c = {}) {
|
||||||
const m = te(), F = r[i];
|
const m = ee(), S = t[i];
|
||||||
if (!F)
|
if (!S)
|
||||||
throw new Error(`Action "${i}" is not defined.`);
|
throw new Error(`Action "${i}" is not defined.`);
|
||||||
return re({
|
return te({
|
||||||
mutationKey: [...h, i],
|
mutationKey: [...l, i],
|
||||||
mutationFn: async (E = {}) => {
|
mutationFn: async (q = {}) => {
|
||||||
const c = F.method || "post", Z = ye(F.url || t, E), b = F.body ? F.body(E) : F.sendRawPayload ? E : Te(E);
|
const h = S.method || "post", E = ye(S.url || r, q), b = S.body ? S.body(q) : S.sendRawPayload ? q : Te(q);
|
||||||
return (c === "delete" ? await n.delete(
|
return (h === "delete" ? await n.delete(
|
||||||
Z,
|
E,
|
||||||
b && Object.keys(b).length > 0 ? { data: b } : void 0
|
b && Object.keys(b).length > 0 ? { data: b } : void 0
|
||||||
) : await n[c](Z, b)).data;
|
) : await n[h](E, b)).data;
|
||||||
},
|
},
|
||||||
onSuccess: (...E) => {
|
onSuccess: (...q) => {
|
||||||
var T;
|
var T;
|
||||||
const [c, Z] = E;
|
const [h, E] = q;
|
||||||
m.invalidateQueries({
|
m.invalidateQueries({
|
||||||
queryKey: d
|
queryKey: u
|
||||||
});
|
});
|
||||||
const b = (Z == null ? void 0 : Z.id) ?? (c == null ? void 0 : c.id);
|
const b = (E == null ? void 0 : E.id) ?? (h == null ? void 0 : h.id);
|
||||||
b && m.invalidateQueries({
|
b && m.invalidateQueries({
|
||||||
queryKey: C(e, b)
|
queryKey: M(e, b)
|
||||||
});
|
});
|
||||||
const y = typeof F.invalidateKeys == "function" ? F.invalidateKeys(c, Z) : F.invalidateKeys;
|
const y = typeof S.invalidateKeys == "function" ? S.invalidateKeys(h, E) : S.invalidateKeys;
|
||||||
y == null || y.forEach((K) => {
|
y == null || y.forEach((k) => {
|
||||||
m.invalidateQueries({ queryKey: K });
|
m.invalidateQueries({ queryKey: k });
|
||||||
}), (T = l.onSuccess) == null || T.call(l, ...E);
|
}), (T = c.onSuccess) == null || T.call(c, ...q);
|
||||||
},
|
},
|
||||||
...l
|
...c
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const p = Object.keys(r).reduce((i, l) => (i[Xe(l)] = (m = {}) => S(l, m), i), {});
|
const p = Object.keys(t).reduce((i, c) => (i[Xe(c)] = (m = {}) => F(c, m), i), {});
|
||||||
return {
|
return {
|
||||||
key: h,
|
key: l,
|
||||||
listKey: d,
|
listKey: u,
|
||||||
useGet: s,
|
useGet: s,
|
||||||
useItem: a,
|
useItem: a,
|
||||||
useAction: S,
|
useAction: F,
|
||||||
...p
|
...p
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const k = V(null), Y = "permissions", ze = (e) => (e == null ? void 0 : e.storageKey) || Y, ge = ({
|
const J = C(null), w = "permissions", ze = (e) => (e == null ? void 0 : e.storageKey) || w, xe = ({
|
||||||
user: e = null,
|
user: e = null,
|
||||||
children: t,
|
children: r,
|
||||||
config: r,
|
config: t,
|
||||||
loading: n = /* @__PURE__ */ q("div", { children: "Loading permissions..." }),
|
loading: n = /* @__PURE__ */ Z("div", { children: "Loading permissions..." }),
|
||||||
errorFallback: u = /* @__PURE__ */ q("div", { children: "Error loading permissions" })
|
errorFallback: d = /* @__PURE__ */ Z("div", { children: "Error loading permissions" })
|
||||||
}) => {
|
}) => {
|
||||||
const h = ze(r), [d, s] = z(
|
const l = ze(t), [u, s] = X(
|
||||||
() => we(h)
|
() => ge(l)
|
||||||
), { data: a, isLoading: S, error: p } = fe(r), i = a ?? d;
|
), { data: a, isLoading: F, error: p } = We(t), i = a ?? u;
|
||||||
g(() => {
|
z(() => {
|
||||||
a && (xe(h, a), s(a));
|
a && (Be(l, a), s(a));
|
||||||
}, [a, h]);
|
}, [a, l]);
|
||||||
const l = x(
|
const c = g(
|
||||||
() => Be(i),
|
() => we(i),
|
||||||
[i]
|
[i]
|
||||||
), m = X(
|
), m = K(
|
||||||
(c = "") => Ye(l, c),
|
(h = "") => Ye(c, h),
|
||||||
[l]
|
[c]
|
||||||
), F = X((c = "") => !m(c), [m]), E = x(
|
), S = K((h = "") => !m(h), [m]), q = g(
|
||||||
() => ({
|
() => ({
|
||||||
user: e,
|
user: e,
|
||||||
can: m,
|
can: m,
|
||||||
cannot: F,
|
cannot: S,
|
||||||
permissions: i,
|
permissions: i,
|
||||||
isLoading: S,
|
isLoading: F,
|
||||||
error: p
|
error: p
|
||||||
}),
|
}),
|
||||||
[e, m, F, i, S, p]
|
[e, m, S, i, F, p]
|
||||||
);
|
);
|
||||||
return p && !i ? u : S && !i ? n : /* @__PURE__ */ q(k.Provider, { value: E, children: t });
|
return p && !i ? d : F && !i ? n : /* @__PURE__ */ Z(J.Provider, { value: q, children: r });
|
||||||
}, we = (e = Y) => {
|
}, ge = (e = w) => {
|
||||||
if (!(typeof window > "u"))
|
if (!(typeof window > "u"))
|
||||||
try {
|
try {
|
||||||
const t = localStorage.getItem(e);
|
const r = localStorage.getItem(e);
|
||||||
return t ? JSON.parse(t) : void 0;
|
return r ? JSON.parse(r) : void 0;
|
||||||
} catch {
|
} catch {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}, xe = (e = Y, t) => {
|
}, Be = (e = w, r) => {
|
||||||
if (!(typeof window > "u"))
|
if (!(typeof window > "u"))
|
||||||
try {
|
try {
|
||||||
localStorage.setItem(e, JSON.stringify(t));
|
localStorage.setItem(e, JSON.stringify(r));
|
||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
}, He = (e = Y) => {
|
}, ke = (e = w) => {
|
||||||
if (!(typeof window > "u"))
|
if (!(typeof window > "u"))
|
||||||
try {
|
try {
|
||||||
localStorage.removeItem(e);
|
localStorage.removeItem(e);
|
||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
}, Be = (e) => e ? new Set(e.map((t) => t.name)) : /* @__PURE__ */ new Set(), Ye = (e, t = "") => {
|
}, we = (e) => e ? new Set(e.map((r) => r.name)) : /* @__PURE__ */ new Set(), Ye = (e, r = "") => {
|
||||||
if (!t) return !1;
|
if (!r) return !1;
|
||||||
if (e.has(t) || [...e].some((n) => n.startsWith(t))) return !0;
|
if (e.has(r) || [...e].some((n) => n.startsWith(r))) return !0;
|
||||||
let r = t;
|
let t = r;
|
||||||
for (; r.includes(":"); )
|
for (; t.includes(":"); )
|
||||||
if (r = r.slice(0, r.lastIndexOf(":")), e.has(`${r}:*`)) return !0;
|
if (t = t.slice(0, t.lastIndexOf(":")), e.has(`${t}:*`)) return !0;
|
||||||
return !1;
|
return !1;
|
||||||
}, Q = {
|
}, H = {
|
||||||
all: ["permissions"],
|
all: ["permissions"],
|
||||||
list: (e) => [...Q.all, e]
|
list: (e) => [...H.all, e]
|
||||||
}, Oe = async (e) => {
|
}, fe = async (e) => {
|
||||||
if (!(e != null && e.url) || !(e != null && e.clientId))
|
if (!(e != null && e.url) || !(e != null && e.clientId))
|
||||||
throw new Error("Permission config requires url and clientId.");
|
throw new Error("Permission config requires url and clientId.");
|
||||||
const t = w(), r = new URL(e.url);
|
const r = x(), t = new URL(e.url);
|
||||||
r.searchParams.set("client_id", e.clientId);
|
t.searchParams.set("client_id", e.clientId);
|
||||||
const n = await fetch(r.toString(), {
|
const n = await fetch(t.toString(), {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
...t ? { Authorization: `Bearer ${t}` } : {}
|
...r ? { Authorization: `Bearer ${r}` } : {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!n.ok)
|
if (!n.ok)
|
||||||
throw new Error("Failed to load permissions");
|
throw new Error("Failed to load permissions");
|
||||||
return n.json();
|
return n.json();
|
||||||
}, A = () => {
|
}, P = () => {
|
||||||
const e = ee(k);
|
const e = $(J);
|
||||||
if (!e)
|
if (!e)
|
||||||
throw new Error("usePermission must be used within PermissionProvider");
|
throw new Error("usePermission must be used within PermissionProvider");
|
||||||
return e;
|
return e;
|
||||||
}, fe = (e) => f({
|
}, We = (e) => f({
|
||||||
queryKey: Q.list(e == null ? void 0 : e.clientId),
|
queryKey: H.list(e == null ? void 0 : e.clientId),
|
||||||
queryFn: () => Oe(e),
|
queryFn: () => fe(e),
|
||||||
enabled: !!(e != null && e.url) && !!(e != null && e.clientId) && I(),
|
enabled: !!(e != null && e.url) && !!(e != null && e.clientId) && N(),
|
||||||
staleTime: 1 / 0,
|
staleTime: 1 / 0,
|
||||||
refetchOnWindowFocus: !1,
|
refetchOnWindowFocus: !1,
|
||||||
refetchOnReconnect: !1
|
refetchOnReconnect: !1
|
||||||
}), ke = ({
|
}), Qe = ({
|
||||||
perm: e,
|
perm: e,
|
||||||
children: t,
|
children: r,
|
||||||
fallback: r = /* @__PURE__ */ q("div", { children: "You are not allowed to do this" })
|
fallback: t = /* @__PURE__ */ Z("div", { children: "You are not allowed to do this" })
|
||||||
}) => {
|
}) => {
|
||||||
const { can: n } = A();
|
const { can: n } = P();
|
||||||
return n(e) ? t : r;
|
return n(e) ? r : t;
|
||||||
}, Qe = ({ children: e }) => {
|
}, je = ({ children: e }) => {
|
||||||
const { can: t, permissions: r } = A();
|
const { can: r, permissions: t } = P();
|
||||||
return r && t("admin") ? e : null;
|
return t && r("admin") ? e : null;
|
||||||
}, je = ({ children: e, forceNoAccess: t = !1 }) => {
|
}, _e = ({ children: e, forceNoAccess: r = !1 }) => {
|
||||||
const { can: r, isLoading: n } = A();
|
const { can: t, isLoading: n } = P();
|
||||||
return g(() => {
|
return z(() => {
|
||||||
n || (t || !r("panel_access")) && G();
|
n || (r || !t("panel_access")) && R();
|
||||||
}, [n, r, t]), e;
|
}, [n, t, r]), e;
|
||||||
};
|
};
|
||||||
function We() {
|
function Oe() {
|
||||||
const [e, t] = z(!1), r = N(null);
|
const [e, r] = X(!1), t = L(null);
|
||||||
return g(() => {
|
return z(() => {
|
||||||
if (process.env.NODE_ENV !== "production") return;
|
if (process.env.NODE_ENV !== "production") return;
|
||||||
let n;
|
let n;
|
||||||
const u = async () => {
|
const d = async () => {
|
||||||
const d = await fetch(`/version.json?t=${Date.now()}`, {
|
const u = await fetch(`/version.json?t=${Date.now()}`, {
|
||||||
cache: "no-store"
|
cache: "no-store"
|
||||||
});
|
});
|
||||||
if (!d.ok)
|
if (!u.ok)
|
||||||
throw new Error(`Failed to fetch version: ${d.status}`);
|
throw new Error(`Failed to fetch version: ${u.status}`);
|
||||||
const s = await d.json();
|
const s = await u.json();
|
||||||
return String(s.version);
|
return String(s.version);
|
||||||
};
|
};
|
||||||
return (async () => {
|
return (async () => {
|
||||||
try {
|
try {
|
||||||
r.current = await u(), n = setInterval(async () => {
|
t.current = await d(), n = setInterval(async () => {
|
||||||
try {
|
try {
|
||||||
const d = await u();
|
const u = await d();
|
||||||
r.current && d !== r.current && (t(!0), clearInterval(n));
|
t.current && u !== t.current && (r(!0), clearInterval(n));
|
||||||
} catch (d) {
|
} catch (u) {
|
||||||
console.error("Update check failed:", d);
|
console.error("Update check failed:", u);
|
||||||
}
|
}
|
||||||
}, 3e4);
|
}, 3e4);
|
||||||
} catch (d) {
|
} catch (u) {
|
||||||
console.error("Initial version fetch failed:", d);
|
console.error("Initial version fetch failed:", u);
|
||||||
}
|
}
|
||||||
})(), () => {
|
})(), () => {
|
||||||
n && clearInterval(n);
|
n && clearInterval(n);
|
||||||
};
|
};
|
||||||
}, []), e ? /* @__PURE__ */ q(
|
}, []), e ? /* @__PURE__ */ Z(
|
||||||
"div",
|
"div",
|
||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
@ -364,7 +365,7 @@ function We() {
|
|||||||
}
|
}
|
||||||
) : null;
|
) : null;
|
||||||
}
|
}
|
||||||
const ve = new ne({
|
const ve = new re({
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
queries: {
|
queries: {
|
||||||
retry: 1,
|
retry: 1,
|
||||||
@ -395,7 +396,7 @@ const ve = new ne({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
se({ colorScheme: "facebook" })
|
se({ colorScheme: "facebook" })
|
||||||
), Me = () => /* @__PURE__ */ q(
|
), De = () => /* @__PURE__ */ Z(
|
||||||
de,
|
de,
|
||||||
{
|
{
|
||||||
styles: `
|
styles: `
|
||||||
@ -408,115 +409,111 @@ const ve = new ne({
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
), U = "__UIKIT_REMOTE_DEPS__", L = "__UIKIT_REMOTE_CONFIG__";
|
), U = "__UIKIT_REMOTE_DEPS__";
|
||||||
function De({ theme: e, remoteUiUrl: t, chakraProviderProps: r } = {}) {
|
function Me({ theme: e, chakraProviderProps: r } = {}) {
|
||||||
if (typeof window > "u") return;
|
if (typeof window > "u") return;
|
||||||
const n = window[U] || {}, u = window[L] || {};
|
const t = window[U] || {};
|
||||||
window[U] = {
|
window[U] = {
|
||||||
...n,
|
...t,
|
||||||
React: n.React || $,
|
React: t.React || _,
|
||||||
ChakraProvider: n.ChakraProvider || R,
|
createRoot: t.createRoot || oe,
|
||||||
Badge: n.Badge || ue,
|
ChakraProvider: t.ChakraProvider || V,
|
||||||
theme: e ?? n.theme,
|
Badge: t.Badge || ue,
|
||||||
|
theme: e ?? t.theme,
|
||||||
chakraProviderProps: {
|
chakraProviderProps: {
|
||||||
...n.chakraProviderProps || {},
|
...t.chakraProviderProps || {},
|
||||||
...r || {}
|
...r || {}
|
||||||
}
|
}
|
||||||
}, window[L] = {
|
|
||||||
...u,
|
|
||||||
...t ? { GBadgeUrl: t } : {}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function _e({
|
function $e({
|
||||||
children: e,
|
children: e,
|
||||||
apiBaseUrl: t,
|
apiBaseUrl: r,
|
||||||
keycloakClientId: r,
|
keycloakClientId: t,
|
||||||
permissionClientId: n,
|
permissionClientId: n,
|
||||||
loading: u = /* @__PURE__ */ q(ae, {}),
|
loading: d = /* @__PURE__ */ Z(ae, {}),
|
||||||
updateChecker: h = !1,
|
updateChecker: l = !1,
|
||||||
updateCheckerProps: d,
|
updateCheckerProps: u,
|
||||||
keycloakUrl: s = "https://auth.ibagher.ir",
|
keycloakUrl: s = "https://auth.ibagher.ir",
|
||||||
keycloakRealm: a = "bi",
|
keycloakRealm: a = "bi",
|
||||||
permissionUrl: S = "https://api.d.aiengines.ir/user_api/v1/permissions/list",
|
permissionUrl: F = "https://api.d.aiengines.ir/user_api/v1/permissions/list",
|
||||||
keycloakEnabled: p,
|
keycloakEnabled: p,
|
||||||
permissionEnabled: i,
|
permissionEnabled: i,
|
||||||
theme: l = Ae,
|
theme: c = Ae,
|
||||||
remoteUiEnabled: m = !0,
|
remoteUiEnabled: m = !0,
|
||||||
remoteUiUrl: F,
|
remoteUiChakraProviderProps: S
|
||||||
remoteUiChakraProviderProps: E
|
|
||||||
}) {
|
}) {
|
||||||
const [c, Z] = z(!1), b = p ?? !!r, y = i ?? !!n, T = x(
|
const [q, h] = X(!1), E = p ?? !!t, b = i ?? !!n, y = g(
|
||||||
() => ({
|
() => ({
|
||||||
api: {
|
api: {
|
||||||
baseUrl: t || ""
|
baseUrl: r || ""
|
||||||
},
|
},
|
||||||
keycloak: b ? {
|
keycloak: E ? {
|
||||||
url: s,
|
url: s,
|
||||||
realm: a,
|
realm: a,
|
||||||
clientId: r
|
clientId: t
|
||||||
} : null,
|
} : null,
|
||||||
permission: y ? {
|
permission: b ? {
|
||||||
url: S,
|
url: F,
|
||||||
clientId: n
|
clientId: n
|
||||||
} : null
|
} : null
|
||||||
}),
|
}),
|
||||||
[
|
[
|
||||||
t,
|
r,
|
||||||
|
E,
|
||||||
b,
|
b,
|
||||||
y,
|
|
||||||
s,
|
s,
|
||||||
a,
|
a,
|
||||||
r,
|
t,
|
||||||
S,
|
F,
|
||||||
n
|
n
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
if (g(() => {
|
if (z(() => {
|
||||||
Z(!0);
|
h(!0);
|
||||||
}, []), g(() => {
|
}, []), z(() => {
|
||||||
c && me(T);
|
q && me(y);
|
||||||
}, [c, T]), !c)
|
}, [q, y]), !q)
|
||||||
return null;
|
return null;
|
||||||
m && De({
|
m && Me({
|
||||||
theme: l,
|
theme: c,
|
||||||
remoteUiUrl: F,
|
chakraProviderProps: S
|
||||||
chakraProviderProps: E
|
|
||||||
});
|
});
|
||||||
let K = e;
|
let T = e;
|
||||||
return y && (K = /* @__PURE__ */ q(ge, { config: T.permission, loading: u, children: K })), b && (K = /* @__PURE__ */ q(Se, { config: T.keycloak, loading: u, children: K })), /* @__PURE__ */ M(R, { theme: l, children: [
|
return b && (T = /* @__PURE__ */ Z(xe, { config: y.permission, loading: d, children: T })), E && (T = /* @__PURE__ */ Z(Fe, { config: y.keycloak, loading: d, children: T })), /* @__PURE__ */ A(V, { theme: c, children: [
|
||||||
/* @__PURE__ */ q(Me, {}),
|
/* @__PURE__ */ Z(De, {}),
|
||||||
/* @__PURE__ */ M(oe, { client: ve, children: [
|
/* @__PURE__ */ A(ne, { client: ve, children: [
|
||||||
h && /* @__PURE__ */ q(We, { ...d }),
|
l && /* @__PURE__ */ Z(Oe, { ...u }),
|
||||||
K
|
T
|
||||||
] })
|
] })
|
||||||
] });
|
] });
|
||||||
}
|
}
|
||||||
export {
|
export {
|
||||||
Qe as AdminGuard,
|
je as AdminGuard,
|
||||||
_e as BiProvider,
|
$e as BiProvider,
|
||||||
ke as Can,
|
Qe as Can,
|
||||||
Se as KeycloakProvider,
|
Fe as KeycloakProvider,
|
||||||
je as PanelAccessGuard,
|
_e as PanelAccessGuard,
|
||||||
ge as PermissionProvider,
|
xe as PermissionProvider,
|
||||||
H as api,
|
G as api,
|
||||||
Ye as checkPermission,
|
Ye as checkPermission,
|
||||||
He as clearCachedPermissions,
|
ke as clearCachedPermissions,
|
||||||
me as configureApi,
|
me as configureApi,
|
||||||
Je as createApi,
|
He as createApi,
|
||||||
Be as createPermissionSet,
|
we as createPermissionSet,
|
||||||
qe as fetcher,
|
Ee as fetcher,
|
||||||
Ee as getApi,
|
qe as getApi,
|
||||||
we as getCachedPermissions,
|
ge as getCachedPermissions,
|
||||||
w as getKeycloakToken,
|
x as getKeycloakToken,
|
||||||
Oe as getPermissions,
|
fe as getPermissions,
|
||||||
J as initKeycloak,
|
I as initKeycloak,
|
||||||
I as isKeycloakAuthenticated,
|
N as isKeycloakAuthenticated,
|
||||||
Fe as isKeycloakInitialized,
|
Se as isKeycloakInitialized,
|
||||||
Ge as loginKeycloak,
|
Je as loginKeycloak,
|
||||||
G as logoutKeycloak,
|
R as logoutKeycloak,
|
||||||
Q as permissionKeys,
|
H as permissionKeys,
|
||||||
xe as setCachedPermissions,
|
Be as setCachedPermissions,
|
||||||
D as updateKeycloakToken,
|
D as updateKeycloakToken,
|
||||||
A as usePermission,
|
P as usePermission,
|
||||||
fe as usePermissionsQuery
|
We as usePermissionsQuery
|
||||||
};
|
};
|
||||||
|
|||||||
68
dist/remote-ui.d.ts
vendored
68
dist/remote-ui.d.ts
vendored
@ -1,54 +1,24 @@
|
|||||||
import type { BadgeProps, StackProps } from "@chakra-ui/react";
|
export {
|
||||||
import type { ReactNode } from "react";
|
setupUikitRemoteDeps,
|
||||||
|
} from "./_core/setupRemoteDeps";
|
||||||
|
|
||||||
export type UikitRemoteLevel = "full" | "compact" | "simple";
|
export type {
|
||||||
|
UikitRemoteSetupOptions,
|
||||||
|
} from "./_core/setupRemoteDeps";
|
||||||
|
|
||||||
export interface UikitRemoteSetupOptions {
|
export {
|
||||||
React?: any;
|
GBadge,
|
||||||
createRoot?: any;
|
} from "./GBadge";
|
||||||
ChakraProvider?: any;
|
|
||||||
Badge?: any;
|
|
||||||
Button?: any;
|
|
||||||
HStack?: any;
|
|
||||||
IconButton?: any;
|
|
||||||
Input?: any;
|
|
||||||
Text?: any;
|
|
||||||
theme?: any;
|
|
||||||
chakraProviderProps?: Record<string, any>;
|
|
||||||
|
|
||||||
/** Backward compatible alias for GBadgeUrl. */
|
export type {
|
||||||
remoteUrl?: string;
|
GBadgeProps,
|
||||||
GBadgeUrl?: string;
|
} from "./GBadge";
|
||||||
PaginationUrl?: string;
|
|
||||||
remoteUrls?: {
|
|
||||||
GBadge?: string;
|
|
||||||
Pagination?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare function setupUikitRemoteDeps(
|
export {
|
||||||
options?: UikitRemoteSetupOptions,
|
Pagination,
|
||||||
): void;
|
} from "./Pagination";
|
||||||
|
|
||||||
export interface GBadgeProps extends BadgeProps {
|
export type {
|
||||||
children?: ReactNode;
|
PaginationLevel,
|
||||||
remoteUrl?: string;
|
PaginationProps,
|
||||||
theme?: any;
|
} from "./Pagination";
|
||||||
chakraProviderProps?: Record<string, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare const GBadge: (props: GBadgeProps) => JSX.Element;
|
|
||||||
|
|
||||||
export interface PaginationProps extends Omit<StackProps, "onChange"> {
|
|
||||||
currentPage?: number;
|
|
||||||
totalCount?: number;
|
|
||||||
totalPages?: number;
|
|
||||||
pageSize?: number;
|
|
||||||
onPageChange?: (page: number) => void;
|
|
||||||
level?: UikitRemoteLevel;
|
|
||||||
remoteUrl?: string;
|
|
||||||
theme?: any;
|
|
||||||
chakraProviderProps?: Record<string, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare const Pagination: (props: PaginationProps) => JSX.Element;
|
|
||||||
|
|||||||
236
dist/remote-ui.js
vendored
236
dist/remote-ui.js
vendored
@ -1,13 +1,120 @@
|
|||||||
import { jsx as E } from "react/jsx-runtime";
|
import B, { useRef as d, useEffect as g } from "react";
|
||||||
import p, { useRef as s, useEffect as R } from "react";
|
|
||||||
import { createRoot as k } from "react-dom/client";
|
import { createRoot as k } from "react-dom/client";
|
||||||
import { Text as U, Input as _, IconButton as I, HStack as v, Button as G, Badge as C, ChakraProvider as T } from "@chakra-ui/react";
|
import { Text as v, Input as w, IconButton as E, HStack as y, Button as I, Badge as C, ChakraProvider as T } from "@chakra-ui/react";
|
||||||
|
import { jsx as _ } from "react/jsx-runtime";
|
||||||
const h = {
|
const h = {
|
||||||
GBadge: "https://uikit.d.aiengines.ir/GBadge.js",
|
GBadge: "https://uikit.d.aiengines.ir/GBadge.js",
|
||||||
Pagination: "https://uikit.d.aiengines.ir/Pagination.js"
|
Pagination: "https://uikit.d.aiengines.ir/Pagination.js"
|
||||||
}, l = "__UIKIT_REMOTE_DEPS__", g = "__UIKIT_REMOTE_CONFIG__", u = /* @__PURE__ */ new Map(), y = {
|
}, s = "__UIKIT_REMOTE_DEPS__";
|
||||||
GBadge: ["React", "createRoot", "ChakraProvider", "Badge"],
|
function D(e = {}) {
|
||||||
Pagination: [
|
if (typeof window > "u") return;
|
||||||
|
const t = window[s] || {};
|
||||||
|
window[s] = {
|
||||||
|
...t,
|
||||||
|
React: e.React || t.React || B,
|
||||||
|
createRoot: e.createRoot || t.createRoot || k,
|
||||||
|
ChakraProvider: e.ChakraProvider || t.ChakraProvider || T,
|
||||||
|
Badge: e.Badge || t.Badge || C,
|
||||||
|
Button: e.Button || t.Button || I,
|
||||||
|
HStack: e.HStack || t.HStack || y,
|
||||||
|
IconButton: e.IconButton || t.IconButton || E,
|
||||||
|
Input: e.Input || t.Input || w,
|
||||||
|
Text: e.Text || t.Text || v,
|
||||||
|
...e.deps || {},
|
||||||
|
theme: Object.prototype.hasOwnProperty.call(e, "theme") ? e.theme : t.theme,
|
||||||
|
chakraProviderProps: {
|
||||||
|
...t.chakraProviderProps || {},
|
||||||
|
...e.chakraProviderProps || {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const a = /* @__PURE__ */ new Map();
|
||||||
|
function x(e = []) {
|
||||||
|
if (typeof window > "u") return !1;
|
||||||
|
const t = window[s];
|
||||||
|
return e.every((r) => t == null ? void 0 : t[r]);
|
||||||
|
}
|
||||||
|
function S(e = []) {
|
||||||
|
typeof window > "u" || x(e) || D();
|
||||||
|
}
|
||||||
|
function G(e, t) {
|
||||||
|
const r = `${e}:${t}`;
|
||||||
|
return a.has(r) || a.set(
|
||||||
|
r,
|
||||||
|
import(
|
||||||
|
/* webpackIgnore: true */
|
||||||
|
/* @vite-ignore */
|
||||||
|
t
|
||||||
|
).catch((u) => {
|
||||||
|
throw a.delete(r), u;
|
||||||
|
})
|
||||||
|
), a.get(r);
|
||||||
|
}
|
||||||
|
function P({
|
||||||
|
componentName: e,
|
||||||
|
tagName: t,
|
||||||
|
defaultRemoteUrl: r,
|
||||||
|
requiredDeps: u,
|
||||||
|
normalizeProps: f
|
||||||
|
}) {
|
||||||
|
return function({
|
||||||
|
theme: m,
|
||||||
|
chakraProviderProps: l,
|
||||||
|
...p
|
||||||
|
}) {
|
||||||
|
const i = d(null), n = d(null), c = d(null);
|
||||||
|
return c.current = {
|
||||||
|
...f ? f(p) : p,
|
||||||
|
...m !== void 0 ? { theme: m } : {},
|
||||||
|
...l ? { chakraProviderProps: l } : {}
|
||||||
|
}, g(() => {
|
||||||
|
let R = !0;
|
||||||
|
return S(u), G(e, r).then(() => {
|
||||||
|
if (!R || !i.current) return;
|
||||||
|
const o = document.createElement(t);
|
||||||
|
o.componentProps = c.current, i.current.appendChild(o), n.current = o;
|
||||||
|
}).catch((o) => {
|
||||||
|
console.error(
|
||||||
|
`[uikit/remote/ui] Failed to load ${e}:`,
|
||||||
|
o
|
||||||
|
);
|
||||||
|
}), () => {
|
||||||
|
R = !1, n.current && (n.current.remove(), n.current = null);
|
||||||
|
};
|
||||||
|
}, [e, r, t]), g(() => {
|
||||||
|
n.current && (n.current.componentProps = c.current);
|
||||||
|
}), /* @__PURE__ */ _(
|
||||||
|
"span",
|
||||||
|
{
|
||||||
|
ref: i,
|
||||||
|
style: {
|
||||||
|
display: "contents"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function b(e) {
|
||||||
|
if (typeof e == "string" || typeof e == "number")
|
||||||
|
return e;
|
||||||
|
e != null && console.warn(
|
||||||
|
"[uikit/remote/ui] GBadge only accepts text/number children across the remote boundary."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const q = P({
|
||||||
|
componentName: "GBadge",
|
||||||
|
tagName: "uikit-g-badge",
|
||||||
|
defaultRemoteUrl: h.GBadge,
|
||||||
|
requiredDeps: ["React", "createRoot", "ChakraProvider", "Badge"],
|
||||||
|
normalizeProps: ({ children: e, ...t }) => ({
|
||||||
|
...t,
|
||||||
|
children: b(e)
|
||||||
|
})
|
||||||
|
}), K = P({
|
||||||
|
componentName: "Pagination",
|
||||||
|
tagName: "uikit-pagination",
|
||||||
|
defaultRemoteUrl: h.Pagination,
|
||||||
|
requiredDeps: [
|
||||||
"React",
|
"React",
|
||||||
"createRoot",
|
"createRoot",
|
||||||
"ChakraProvider",
|
"ChakraProvider",
|
||||||
@ -17,122 +124,9 @@ const h = {
|
|||||||
"Input",
|
"Input",
|
||||||
"Text"
|
"Text"
|
||||||
]
|
]
|
||||||
};
|
|
||||||
function D(e = {}) {
|
|
||||||
if (typeof window > "u") return;
|
|
||||||
const t = window[l] || {}, r = window[g] || {};
|
|
||||||
window[l] = {
|
|
||||||
...t,
|
|
||||||
React: e.React || t.React || p,
|
|
||||||
createRoot: e.createRoot || t.createRoot || k,
|
|
||||||
ChakraProvider: e.ChakraProvider || t.ChakraProvider || T,
|
|
||||||
Badge: e.Badge || t.Badge || C,
|
|
||||||
Button: e.Button || t.Button || G,
|
|
||||||
HStack: e.HStack || t.HStack || v,
|
|
||||||
IconButton: e.IconButton || t.IconButton || I,
|
|
||||||
Input: e.Input || t.Input || _,
|
|
||||||
Text: e.Text || t.Text || U,
|
|
||||||
theme: Object.prototype.hasOwnProperty.call(e, "theme") ? e.theme : t.theme,
|
|
||||||
chakraProviderProps: {
|
|
||||||
...t.chakraProviderProps || {},
|
|
||||||
...e.chakraProviderProps || {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const n = e.remoteUrls || {};
|
|
||||||
window[g] = {
|
|
||||||
...r,
|
|
||||||
...e.remoteUrl ? { GBadgeUrl: e.remoteUrl } : {},
|
|
||||||
...e.GBadgeUrl ? { GBadgeUrl: e.GBadgeUrl } : {},
|
|
||||||
...e.PaginationUrl ? { PaginationUrl: e.PaginationUrl } : {},
|
|
||||||
...n.GBadge ? { GBadgeUrl: n.GBadge } : {},
|
|
||||||
...n.Pagination ? { PaginationUrl: n.Pagination } : {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function O(e) {
|
|
||||||
if (typeof window > "u") return;
|
|
||||||
const t = window[l];
|
|
||||||
(y[e] || []).some((o) => !(t != null && t[o])) && D();
|
|
||||||
}
|
|
||||||
function S(e, t) {
|
|
||||||
var r;
|
|
||||||
return t || (typeof window > "u" ? h[e] : ((r = window[g]) == null ? void 0 : r[`${e}Url`]) || h[e]);
|
|
||||||
}
|
|
||||||
function M(e, t) {
|
|
||||||
const r = S(e, t), n = `${e}:${r}`;
|
|
||||||
return u.has(n) || u.set(
|
|
||||||
n,
|
|
||||||
import(
|
|
||||||
/* webpackIgnore: true */
|
|
||||||
/* @vite-ignore */
|
|
||||||
r
|
|
||||||
).catch((o) => {
|
|
||||||
throw u.delete(n), o;
|
|
||||||
})
|
|
||||||
), u.get(n);
|
|
||||||
}
|
|
||||||
function x(e) {
|
|
||||||
if (typeof e == "string" || typeof e == "number")
|
|
||||||
return e;
|
|
||||||
e != null && console.warn(
|
|
||||||
"[uikit/remote/ui] GBadge only accepts text/number children across the remote boundary."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
function w({
|
|
||||||
componentName: e,
|
|
||||||
tagName: t,
|
|
||||||
normalizeProps: r
|
|
||||||
}) {
|
|
||||||
return function({
|
|
||||||
remoteUrl: o,
|
|
||||||
theme: f,
|
|
||||||
chakraProviderProps: m,
|
|
||||||
...B
|
|
||||||
}) {
|
|
||||||
const c = s(null), a = s(null), d = s(null);
|
|
||||||
return d.current = {
|
|
||||||
...r ? r(B) : B,
|
|
||||||
...f !== void 0 ? { theme: f } : {},
|
|
||||||
...m ? { chakraProviderProps: m } : {}
|
|
||||||
}, R(() => {
|
|
||||||
let P = !0;
|
|
||||||
return O(e), M(e, o).then(() => {
|
|
||||||
if (!P || !c.current) return;
|
|
||||||
const i = document.createElement(t);
|
|
||||||
i.componentProps = d.current, c.current.appendChild(i), a.current = i;
|
|
||||||
}).catch((i) => {
|
|
||||||
console.error(
|
|
||||||
`[uikit/remote/ui] Failed to load ${e}:`,
|
|
||||||
i
|
|
||||||
);
|
|
||||||
}), () => {
|
|
||||||
P = !1, a.current && (a.current.remove(), a.current = null);
|
|
||||||
};
|
|
||||||
}, [e, o, t]), R(() => {
|
|
||||||
a.current && (a.current.componentProps = d.current);
|
|
||||||
}), /* @__PURE__ */ E(
|
|
||||||
"span",
|
|
||||||
{
|
|
||||||
ref: c,
|
|
||||||
style: {
|
|
||||||
display: "contents"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const F = w({
|
|
||||||
componentName: "GBadge",
|
|
||||||
tagName: "uikit-g-badge",
|
|
||||||
normalizeProps: ({ children: e, ...t }) => ({
|
|
||||||
...t,
|
|
||||||
children: x(e)
|
|
||||||
})
|
|
||||||
}), $ = w({
|
|
||||||
componentName: "Pagination",
|
|
||||||
tagName: "uikit-pagination"
|
|
||||||
});
|
});
|
||||||
export {
|
export {
|
||||||
F as GBadge,
|
q as GBadge,
|
||||||
$ as Pagination,
|
K as Pagination,
|
||||||
D as setupUikitRemoteDeps
|
D as setupUikitRemoteDeps
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
|
import { createRoot } from "react-dom/client";
|
||||||
import { Badge, ChakraProvider, Spinner } from "@chakra-ui/react";
|
import { Badge, ChakraProvider, Spinner } from "@chakra-ui/react";
|
||||||
import { QueryClientProvider } from "@tanstack/react-query";
|
import { QueryClientProvider } from "@tanstack/react-query";
|
||||||
import { KeycloakProvider } from "./keycloak.jsx";
|
import { KeycloakProvider } from "./keycloak.jsx";
|
||||||
@ -9,17 +10,14 @@ import { queryClient } from "./query.js";
|
|||||||
import { Fonts, theme as defaultTheme } from "./style.jsx";
|
import { Fonts, theme as defaultTheme } from "./style.jsx";
|
||||||
|
|
||||||
const REMOTE_DEPS_KEY = "__UIKIT_REMOTE_DEPS__";
|
const REMOTE_DEPS_KEY = "__UIKIT_REMOTE_DEPS__";
|
||||||
const REMOTE_CONFIG_KEY = "__UIKIT_REMOTE_CONFIG__";
|
function setupBiRemoteUiDeps({ theme, chakraProviderProps } = {}) {
|
||||||
|
|
||||||
function setupBiRemoteUiDeps({ theme, remoteUiUrl, chakraProviderProps } = {}) {
|
|
||||||
if (typeof window === "undefined") return;
|
if (typeof window === "undefined") return;
|
||||||
|
|
||||||
const previousDeps = window[REMOTE_DEPS_KEY] || {};
|
const previousDeps = window[REMOTE_DEPS_KEY] || {};
|
||||||
const previousConfig = window[REMOTE_CONFIG_KEY] || {};
|
|
||||||
|
|
||||||
window[REMOTE_DEPS_KEY] = {
|
window[REMOTE_DEPS_KEY] = {
|
||||||
...previousDeps,
|
...previousDeps,
|
||||||
React: previousDeps.React || React,
|
React: previousDeps.React || React,
|
||||||
|
createRoot: previousDeps.createRoot || createRoot,
|
||||||
ChakraProvider: previousDeps.ChakraProvider || ChakraProvider,
|
ChakraProvider: previousDeps.ChakraProvider || ChakraProvider,
|
||||||
Badge: previousDeps.Badge || Badge,
|
Badge: previousDeps.Badge || Badge,
|
||||||
theme: theme ?? previousDeps.theme,
|
theme: theme ?? previousDeps.theme,
|
||||||
@ -28,11 +26,6 @@ function setupBiRemoteUiDeps({ theme, remoteUiUrl, chakraProviderProps } = {}) {
|
|||||||
...(chakraProviderProps || {}),
|
...(chakraProviderProps || {}),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
window[REMOTE_CONFIG_KEY] = {
|
|
||||||
...previousConfig,
|
|
||||||
...(remoteUiUrl ? { GBadgeUrl: remoteUiUrl } : {}),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BiProvider({
|
export function BiProvider({
|
||||||
@ -57,7 +50,6 @@ export function BiProvider({
|
|||||||
|
|
||||||
theme = defaultTheme,
|
theme = defaultTheme,
|
||||||
remoteUiEnabled = true,
|
remoteUiEnabled = true,
|
||||||
remoteUiUrl,
|
|
||||||
remoteUiChakraProviderProps,
|
remoteUiChakraProviderProps,
|
||||||
}) {
|
}) {
|
||||||
const [mounted, setMounted] = useState(false);
|
const [mounted, setMounted] = useState(false);
|
||||||
@ -115,7 +107,6 @@ export function BiProvider({
|
|||||||
if (remoteUiEnabled) {
|
if (remoteUiEnabled) {
|
||||||
setupBiRemoteUiDeps({
|
setupBiRemoteUiDeps({
|
||||||
theme,
|
theme,
|
||||||
remoteUiUrl,
|
|
||||||
chakraProviderProps: remoteUiChakraProviderProps,
|
chakraProviderProps: remoteUiChakraProviderProps,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/core/index.d.ts
vendored
1
src/core/index.d.ts
vendored
@ -41,7 +41,6 @@ export type BiProviderProps = {
|
|||||||
permissionEnabled?: boolean;
|
permissionEnabled?: boolean;
|
||||||
theme?: any;
|
theme?: any;
|
||||||
remoteUiEnabled?: boolean;
|
remoteUiEnabled?: boolean;
|
||||||
remoteUiUrl?: string;
|
|
||||||
remoteUiChakraProviderProps?: Record<string, any>;
|
remoteUiChakraProviderProps?: Record<string, any>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
10
src/remote/ui/GBadge/index.d.ts
vendored
Normal file
10
src/remote/ui/GBadge/index.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import type { BadgeProps } from "@chakra-ui/react";
|
||||||
|
import type { ReactNode } from "react";
|
||||||
|
|
||||||
|
export interface GBadgeProps extends BadgeProps {
|
||||||
|
children?: ReactNode;
|
||||||
|
theme?: any;
|
||||||
|
chakraProviderProps?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare const GBadge: (props: GBadgeProps) => JSX.Element;
|
||||||
31
src/remote/ui/GBadge/index.jsx
Normal file
31
src/remote/ui/GBadge/index.jsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { DEFAULT_REMOTE_URLS } from "../_core/constants";
|
||||||
|
import { createRemoteElementComponent } from "../_core/createRemoteElementComponent";
|
||||||
|
|
||||||
|
function normalizeChildren(children) {
|
||||||
|
if (typeof children === "string" || typeof children === "number") {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (children === null || children === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn(
|
||||||
|
"[uikit/remote/ui] GBadge only accepts text/number children across the remote boundary.",
|
||||||
|
);
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GBadge = createRemoteElementComponent({
|
||||||
|
componentName: "GBadge",
|
||||||
|
tagName: "uikit-g-badge",
|
||||||
|
defaultRemoteUrl: DEFAULT_REMOTE_URLS.GBadge,
|
||||||
|
requiredDeps: ["React", "createRoot", "ChakraProvider", "Badge"],
|
||||||
|
normalizeProps: ({ children, ...props }) => ({
|
||||||
|
...props,
|
||||||
|
children: normalizeChildren(children),
|
||||||
|
}),
|
||||||
|
});
|
||||||
16
src/remote/ui/Pagination/index.d.ts
vendored
Normal file
16
src/remote/ui/Pagination/index.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import type { StackProps } from "@chakra-ui/react";
|
||||||
|
|
||||||
|
export type PaginationLevel = "full" | "compact" | "simple";
|
||||||
|
|
||||||
|
export interface PaginationProps extends Omit<StackProps, "onChange"> {
|
||||||
|
currentPage?: number;
|
||||||
|
totalCount?: number;
|
||||||
|
totalPages?: number;
|
||||||
|
pageSize?: number;
|
||||||
|
onPageChange?: (page: number) => void;
|
||||||
|
level?: PaginationLevel;
|
||||||
|
theme?: any;
|
||||||
|
chakraProviderProps?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare const Pagination: (props: PaginationProps) => JSX.Element;
|
||||||
20
src/remote/ui/Pagination/index.jsx
Normal file
20
src/remote/ui/Pagination/index.jsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { DEFAULT_REMOTE_URLS } from "../_core/constants";
|
||||||
|
import { createRemoteElementComponent } from "../_core/createRemoteElementComponent";
|
||||||
|
|
||||||
|
export const Pagination = createRemoteElementComponent({
|
||||||
|
componentName: "Pagination",
|
||||||
|
tagName: "uikit-pagination",
|
||||||
|
defaultRemoteUrl: DEFAULT_REMOTE_URLS.Pagination,
|
||||||
|
requiredDeps: [
|
||||||
|
"React",
|
||||||
|
"createRoot",
|
||||||
|
"ChakraProvider",
|
||||||
|
"Button",
|
||||||
|
"HStack",
|
||||||
|
"IconButton",
|
||||||
|
"Input",
|
||||||
|
"Text",
|
||||||
|
],
|
||||||
|
});
|
||||||
6
src/remote/ui/_core/constants.js
Normal file
6
src/remote/ui/_core/constants.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export const DEFAULT_REMOTE_URLS = {
|
||||||
|
GBadge: "https://uikit.d.aiengines.ir/GBadge.js",
|
||||||
|
Pagination: "https://uikit.d.aiengines.ir/Pagination.js",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const REMOTE_DEPS_KEY = "__UIKIT_REMOTE_DEPS__";
|
||||||
117
src/remote/ui/_core/createRemoteElementComponent.jsx
Normal file
117
src/remote/ui/_core/createRemoteElementComponent.jsx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { useEffect, useRef } from "react";
|
||||||
|
|
||||||
|
import { REMOTE_DEPS_KEY } from "./constants";
|
||||||
|
import { setupUikitRemoteDeps } from "./setupRemoteDeps";
|
||||||
|
|
||||||
|
const remotePromises = new Map();
|
||||||
|
|
||||||
|
function hasRequiredDeps(requiredDeps = []) {
|
||||||
|
if (typeof window === "undefined") return false;
|
||||||
|
|
||||||
|
const deps = window[REMOTE_DEPS_KEY];
|
||||||
|
|
||||||
|
return requiredDeps.every((key) => deps?.[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureRemoteDeps(requiredDeps = []) {
|
||||||
|
if (typeof window === "undefined") return;
|
||||||
|
|
||||||
|
if (!hasRequiredDeps(requiredDeps)) {
|
||||||
|
setupUikitRemoteDeps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadRemote(componentName, remoteFileUrl) {
|
||||||
|
const cacheKey = `${componentName}:${remoteFileUrl}`;
|
||||||
|
|
||||||
|
if (!remotePromises.has(cacheKey)) {
|
||||||
|
remotePromises.set(
|
||||||
|
cacheKey,
|
||||||
|
import(
|
||||||
|
/* webpackIgnore: true */
|
||||||
|
/* @vite-ignore */
|
||||||
|
remoteFileUrl
|
||||||
|
).catch((error) => {
|
||||||
|
remotePromises.delete(cacheKey);
|
||||||
|
throw error;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return remotePromises.get(cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createRemoteElementComponent({
|
||||||
|
componentName,
|
||||||
|
tagName,
|
||||||
|
defaultRemoteUrl,
|
||||||
|
requiredDeps,
|
||||||
|
normalizeProps,
|
||||||
|
}) {
|
||||||
|
return function RemoteElementComponent({
|
||||||
|
theme,
|
||||||
|
chakraProviderProps,
|
||||||
|
...props
|
||||||
|
}) {
|
||||||
|
const containerRef = useRef(null);
|
||||||
|
const elementRef = useRef(null);
|
||||||
|
const latestPropsRef = useRef(null);
|
||||||
|
|
||||||
|
latestPropsRef.current = {
|
||||||
|
...(normalizeProps ? normalizeProps(props) : props),
|
||||||
|
...(theme !== undefined ? { theme } : {}),
|
||||||
|
...(chakraProviderProps ? { chakraProviderProps } : {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let active = true;
|
||||||
|
|
||||||
|
ensureRemoteDeps(requiredDeps);
|
||||||
|
|
||||||
|
loadRemote(componentName, defaultRemoteUrl)
|
||||||
|
.then(() => {
|
||||||
|
if (!active) return;
|
||||||
|
if (!containerRef.current) return;
|
||||||
|
|
||||||
|
const element = document.createElement(tagName);
|
||||||
|
|
||||||
|
element.componentProps = latestPropsRef.current;
|
||||||
|
|
||||||
|
containerRef.current.appendChild(element);
|
||||||
|
elementRef.current = element;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(
|
||||||
|
`[uikit/remote/ui] Failed to load ${componentName}:`,
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
active = false;
|
||||||
|
|
||||||
|
if (elementRef.current) {
|
||||||
|
elementRef.current.remove();
|
||||||
|
elementRef.current = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [componentName, defaultRemoteUrl, tagName]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!elementRef.current) return;
|
||||||
|
|
||||||
|
elementRef.current.componentProps = latestPropsRef.current;
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
ref={containerRef}
|
||||||
|
style={{
|
||||||
|
display: "contents",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
22
src/remote/ui/_core/setupRemoteDeps.d.ts
vendored
Normal file
22
src/remote/ui/_core/setupRemoteDeps.d.ts
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export interface UikitRemoteSetupOptions {
|
||||||
|
React?: any;
|
||||||
|
createRoot?: any;
|
||||||
|
|
||||||
|
ChakraProvider?: any;
|
||||||
|
|
||||||
|
Badge?: any;
|
||||||
|
Button?: any;
|
||||||
|
HStack?: any;
|
||||||
|
IconButton?: any;
|
||||||
|
Input?: any;
|
||||||
|
Text?: any;
|
||||||
|
|
||||||
|
deps?: Record<string, any>;
|
||||||
|
|
||||||
|
theme?: any;
|
||||||
|
chakraProviderProps?: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare function setupUikitRemoteDeps(
|
||||||
|
options?: UikitRemoteSetupOptions,
|
||||||
|
): void;
|
||||||
49
src/remote/ui/_core/setupRemoteDeps.js
Normal file
49
src/remote/ui/_core/setupRemoteDeps.js
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { createRoot } from "react-dom/client";
|
||||||
|
import {
|
||||||
|
Badge,
|
||||||
|
Button,
|
||||||
|
ChakraProvider,
|
||||||
|
HStack,
|
||||||
|
IconButton,
|
||||||
|
Input,
|
||||||
|
Text,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
|
||||||
|
import { REMOTE_DEPS_KEY } from "./constants";
|
||||||
|
|
||||||
|
export function setupUikitRemoteDeps(options = {}) {
|
||||||
|
if (typeof window === "undefined") return;
|
||||||
|
|
||||||
|
const previousDeps = window[REMOTE_DEPS_KEY] || {};
|
||||||
|
|
||||||
|
window[REMOTE_DEPS_KEY] = {
|
||||||
|
...previousDeps,
|
||||||
|
|
||||||
|
React: options.React || previousDeps.React || React,
|
||||||
|
createRoot: options.createRoot || previousDeps.createRoot || createRoot,
|
||||||
|
|
||||||
|
ChakraProvider:
|
||||||
|
options.ChakraProvider || previousDeps.ChakraProvider || ChakraProvider,
|
||||||
|
|
||||||
|
Badge: options.Badge || previousDeps.Badge || Badge,
|
||||||
|
Button: options.Button || previousDeps.Button || Button,
|
||||||
|
HStack: options.HStack || previousDeps.HStack || HStack,
|
||||||
|
IconButton: options.IconButton || previousDeps.IconButton || IconButton,
|
||||||
|
Input: options.Input || previousDeps.Input || Input,
|
||||||
|
Text: options.Text || previousDeps.Text || Text,
|
||||||
|
|
||||||
|
...(options.deps || {}),
|
||||||
|
|
||||||
|
theme: Object.prototype.hasOwnProperty.call(options, "theme")
|
||||||
|
? options.theme
|
||||||
|
: previousDeps.theme,
|
||||||
|
|
||||||
|
chakraProviderProps: {
|
||||||
|
...(previousDeps.chakraProviderProps || {}),
|
||||||
|
...(options.chakraProviderProps || {}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
68
src/remote/ui/index.d.ts
vendored
68
src/remote/ui/index.d.ts
vendored
@ -1,54 +1,24 @@
|
|||||||
import type { BadgeProps, StackProps } from "@chakra-ui/react";
|
export {
|
||||||
import type { ReactNode } from "react";
|
setupUikitRemoteDeps,
|
||||||
|
} from "./_core/setupRemoteDeps";
|
||||||
|
|
||||||
export type UikitRemoteLevel = "full" | "compact" | "simple";
|
export type {
|
||||||
|
UikitRemoteSetupOptions,
|
||||||
|
} from "./_core/setupRemoteDeps";
|
||||||
|
|
||||||
export interface UikitRemoteSetupOptions {
|
export {
|
||||||
React?: any;
|
GBadge,
|
||||||
createRoot?: any;
|
} from "./GBadge";
|
||||||
ChakraProvider?: any;
|
|
||||||
Badge?: any;
|
|
||||||
Button?: any;
|
|
||||||
HStack?: any;
|
|
||||||
IconButton?: any;
|
|
||||||
Input?: any;
|
|
||||||
Text?: any;
|
|
||||||
theme?: any;
|
|
||||||
chakraProviderProps?: Record<string, any>;
|
|
||||||
|
|
||||||
/** Backward compatible alias for GBadgeUrl. */
|
export type {
|
||||||
remoteUrl?: string;
|
GBadgeProps,
|
||||||
GBadgeUrl?: string;
|
} from "./GBadge";
|
||||||
PaginationUrl?: string;
|
|
||||||
remoteUrls?: {
|
|
||||||
GBadge?: string;
|
|
||||||
Pagination?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare function setupUikitRemoteDeps(
|
export {
|
||||||
options?: UikitRemoteSetupOptions,
|
Pagination,
|
||||||
): void;
|
} from "./Pagination";
|
||||||
|
|
||||||
export interface GBadgeProps extends BadgeProps {
|
export type {
|
||||||
children?: ReactNode;
|
PaginationLevel,
|
||||||
remoteUrl?: string;
|
PaginationProps,
|
||||||
theme?: any;
|
} from "./Pagination";
|
||||||
chakraProviderProps?: Record<string, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare const GBadge: (props: GBadgeProps) => JSX.Element;
|
|
||||||
|
|
||||||
export interface PaginationProps extends Omit<StackProps, "onChange"> {
|
|
||||||
currentPage?: number;
|
|
||||||
totalCount?: number;
|
|
||||||
totalPages?: number;
|
|
||||||
pageSize?: number;
|
|
||||||
onPageChange?: (page: number) => void;
|
|
||||||
level?: UikitRemoteLevel;
|
|
||||||
remoteUrl?: string;
|
|
||||||
theme?: any;
|
|
||||||
chakraProviderProps?: Record<string, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export declare const Pagination: (props: PaginationProps) => JSX.Element;
|
|
||||||
|
|||||||
@ -1,225 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useEffect, useRef } from "react";
|
export { setupUikitRemoteDeps } from "./_core/setupRemoteDeps";
|
||||||
import { createRoot } from "react-dom/client";
|
|
||||||
import {
|
|
||||||
Badge,
|
|
||||||
Button,
|
|
||||||
ChakraProvider,
|
|
||||||
HStack,
|
|
||||||
IconButton,
|
|
||||||
Input,
|
|
||||||
Text,
|
|
||||||
} from "@chakra-ui/react";
|
|
||||||
|
|
||||||
const DEFAULT_REMOTE_URLS = {
|
export { GBadge } from "./GBadge";
|
||||||
GBadge: "https://uikit.d.aiengines.ir/GBadge.js",
|
export { Pagination } from "./Pagination";
|
||||||
Pagination: "https://uikit.d.aiengines.ir/Pagination.js",
|
|
||||||
};
|
|
||||||
|
|
||||||
const REMOTE_DEPS_KEY = "__UIKIT_REMOTE_DEPS__";
|
|
||||||
const REMOTE_CONFIG_KEY = "__UIKIT_REMOTE_CONFIG__";
|
|
||||||
|
|
||||||
const remotePromises = new Map();
|
|
||||||
|
|
||||||
const REQUIRED_DEPS = {
|
|
||||||
GBadge: ["React", "createRoot", "ChakraProvider", "Badge"],
|
|
||||||
Pagination: [
|
|
||||||
"React",
|
|
||||||
"createRoot",
|
|
||||||
"ChakraProvider",
|
|
||||||
"Button",
|
|
||||||
"HStack",
|
|
||||||
"IconButton",
|
|
||||||
"Input",
|
|
||||||
"Text",
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
export function setupUikitRemoteDeps(options = {}) {
|
|
||||||
if (typeof window === "undefined") return;
|
|
||||||
|
|
||||||
const previousDeps = window[REMOTE_DEPS_KEY] || {};
|
|
||||||
const previousConfig = window[REMOTE_CONFIG_KEY] || {};
|
|
||||||
|
|
||||||
window[REMOTE_DEPS_KEY] = {
|
|
||||||
...previousDeps,
|
|
||||||
React: options.React || previousDeps.React || React,
|
|
||||||
createRoot: options.createRoot || previousDeps.createRoot || createRoot,
|
|
||||||
ChakraProvider:
|
|
||||||
options.ChakraProvider || previousDeps.ChakraProvider || ChakraProvider,
|
|
||||||
Badge: options.Badge || previousDeps.Badge || Badge,
|
|
||||||
Button: options.Button || previousDeps.Button || Button,
|
|
||||||
HStack: options.HStack || previousDeps.HStack || HStack,
|
|
||||||
IconButton: options.IconButton || previousDeps.IconButton || IconButton,
|
|
||||||
Input: options.Input || previousDeps.Input || Input,
|
|
||||||
Text: options.Text || previousDeps.Text || Text,
|
|
||||||
theme: Object.prototype.hasOwnProperty.call(options, "theme")
|
|
||||||
? options.theme
|
|
||||||
: previousDeps.theme,
|
|
||||||
chakraProviderProps: {
|
|
||||||
...(previousDeps.chakraProviderProps || {}),
|
|
||||||
...(options.chakraProviderProps || {}),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const remoteUrls = options.remoteUrls || {};
|
|
||||||
|
|
||||||
window[REMOTE_CONFIG_KEY] = {
|
|
||||||
...previousConfig,
|
|
||||||
...(options.remoteUrl ? { GBadgeUrl: options.remoteUrl } : {}),
|
|
||||||
...(options.GBadgeUrl ? { GBadgeUrl: options.GBadgeUrl } : {}),
|
|
||||||
...(options.PaginationUrl ? { PaginationUrl: options.PaginationUrl } : {}),
|
|
||||||
...(remoteUrls.GBadge ? { GBadgeUrl: remoteUrls.GBadge } : {}),
|
|
||||||
...(remoteUrls.Pagination ? { PaginationUrl: remoteUrls.Pagination } : {}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureRemoteDeps(componentName) {
|
|
||||||
if (typeof window === "undefined") return;
|
|
||||||
|
|
||||||
const deps = window[REMOTE_DEPS_KEY];
|
|
||||||
const requiredDeps = REQUIRED_DEPS[componentName] || [];
|
|
||||||
const hasMissingDeps = requiredDeps.some((key) => !deps?.[key]);
|
|
||||||
|
|
||||||
if (hasMissingDeps) {
|
|
||||||
setupUikitRemoteDeps();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRemoteUrl(componentName, explicitRemoteUrl) {
|
|
||||||
if (explicitRemoteUrl) return explicitRemoteUrl;
|
|
||||||
|
|
||||||
if (typeof window === "undefined") {
|
|
||||||
return DEFAULT_REMOTE_URLS[componentName];
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
window[REMOTE_CONFIG_KEY]?.[`${componentName}Url`] ||
|
|
||||||
DEFAULT_REMOTE_URLS[componentName]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadRemote(componentName, explicitRemoteUrl) {
|
|
||||||
const remoteUrl = getRemoteUrl(componentName, explicitRemoteUrl);
|
|
||||||
const cacheKey = `${componentName}:${remoteUrl}`;
|
|
||||||
|
|
||||||
if (!remotePromises.has(cacheKey)) {
|
|
||||||
remotePromises.set(
|
|
||||||
cacheKey,
|
|
||||||
import(
|
|
||||||
/* webpackIgnore: true */
|
|
||||||
/* @vite-ignore */
|
|
||||||
remoteUrl
|
|
||||||
).catch((error) => {
|
|
||||||
remotePromises.delete(cacheKey);
|
|
||||||
throw error;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return remotePromises.get(cacheKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
function normalizeBadgeChildren(children) {
|
|
||||||
if (typeof children === "string" || typeof children === "number") {
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (children === null || children === undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.warn(
|
|
||||||
"[uikit/remote/ui] GBadge only accepts text/number children across the remote boundary.",
|
|
||||||
);
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createRemoteElementComponent({
|
|
||||||
componentName,
|
|
||||||
tagName,
|
|
||||||
normalizeProps,
|
|
||||||
}) {
|
|
||||||
return function RemoteElementComponent({
|
|
||||||
remoteUrl,
|
|
||||||
theme,
|
|
||||||
chakraProviderProps,
|
|
||||||
...props
|
|
||||||
}) {
|
|
||||||
const containerRef = useRef(null);
|
|
||||||
const elementRef = useRef(null);
|
|
||||||
const latestPropsRef = useRef(null);
|
|
||||||
|
|
||||||
latestPropsRef.current = {
|
|
||||||
...(normalizeProps ? normalizeProps(props) : props),
|
|
||||||
...(theme !== undefined ? { theme } : {}),
|
|
||||||
...(chakraProviderProps ? { chakraProviderProps } : {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
let active = true;
|
|
||||||
|
|
||||||
ensureRemoteDeps(componentName);
|
|
||||||
|
|
||||||
loadRemote(componentName, remoteUrl)
|
|
||||||
.then(() => {
|
|
||||||
if (!active) return;
|
|
||||||
if (!containerRef.current) return;
|
|
||||||
|
|
||||||
const element = document.createElement(tagName);
|
|
||||||
|
|
||||||
element.componentProps = latestPropsRef.current;
|
|
||||||
|
|
||||||
containerRef.current.appendChild(element);
|
|
||||||
|
|
||||||
elementRef.current = element;
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error(
|
|
||||||
`[uikit/remote/ui] Failed to load ${componentName}:`,
|
|
||||||
error,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
active = false;
|
|
||||||
|
|
||||||
if (elementRef.current) {
|
|
||||||
elementRef.current.remove();
|
|
||||||
elementRef.current = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}, [componentName, remoteUrl, tagName]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!elementRef.current) return;
|
|
||||||
|
|
||||||
elementRef.current.componentProps = latestPropsRef.current;
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<span
|
|
||||||
ref={containerRef}
|
|
||||||
style={{
|
|
||||||
display: "contents",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export const GBadge = createRemoteElementComponent({
|
|
||||||
componentName: "GBadge",
|
|
||||||
tagName: "uikit-g-badge",
|
|
||||||
normalizeProps: ({ children, ...props }) => ({
|
|
||||||
...props,
|
|
||||||
children: normalizeBadgeChildren(children),
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const Pagination = createRemoteElementComponent({
|
|
||||||
componentName: "Pagination",
|
|
||||||
tagName: "uikit-pagination",
|
|
||||||
});
|
|
||||||
|
|||||||
@ -51,11 +51,11 @@ export default defineConfig(({ mode }) => {
|
|||||||
entry: {
|
entry: {
|
||||||
GBadge: path.resolve(
|
GBadge: path.resolve(
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
"src/remote/ui/GBadge.remote.jsx",
|
"src/remote/ui/GBadge/GBadge.remote.jsx",
|
||||||
),
|
),
|
||||||
Pagination: path.resolve(
|
Pagination: path.resolve(
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
"src/remote/ui/Pagination.remote.jsx",
|
"src/remote/ui/Pagination/Pagination.remote.jsx",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user