@carlonicora/nextjs-jsonapi 0.0.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/README.md +889 -0
- package/dist/AbstractService-BKlpJA61.d.mts +109 -0
- package/dist/AbstractService-D9eSVKNa.d.ts +109 -0
- package/dist/ApiData-DPKNfY-9.d.mts +10 -0
- package/dist/ApiData-DPKNfY-9.d.ts +10 -0
- package/dist/ApiDataInterface-DPP8s46n.d.mts +21 -0
- package/dist/ApiDataInterface-DPP8s46n.d.ts +21 -0
- package/dist/ApiRequestDataTypeInterface-CUKFDBx2.d.mts +20 -0
- package/dist/ApiRequestDataTypeInterface-CUKFDBx2.d.ts +20 -0
- package/dist/ApiResponseInterface-BHN5D9r5.d.mts +16 -0
- package/dist/ApiResponseInterface-DDI7QQPR.d.ts +16 -0
- package/dist/BlockNoteEditor-UVO3VZZE.mjs +396 -0
- package/dist/BlockNoteEditor-UVO3VZZE.mjs.map +1 -0
- package/dist/BlockNoteEditor-VFWG6LXI.js +396 -0
- package/dist/BlockNoteEditor-VFWG6LXI.js.map +1 -0
- package/dist/JsonApiRequest-S3ICLM7B.mjs +20 -0
- package/dist/JsonApiRequest-S3ICLM7B.mjs.map +1 -0
- package/dist/JsonApiRequest-ZZLSP26T.js +20 -0
- package/dist/JsonApiRequest-ZZLSP26T.js.map +1 -0
- package/dist/atoms/index.d.mts +12 -0
- package/dist/atoms/index.d.ts +12 -0
- package/dist/atoms/index.js +9 -0
- package/dist/atoms/index.js.map +1 -0
- package/dist/atoms/index.mjs +9 -0
- package/dist/atoms/index.mjs.map +1 -0
- package/dist/breadcrumb.item.data.interface-CgB4_1EE.d.mts +6 -0
- package/dist/breadcrumb.item.data.interface-CgB4_1EE.d.ts +6 -0
- package/dist/chunk-2K3Q24UF.js +89 -0
- package/dist/chunk-2K3Q24UF.js.map +1 -0
- package/dist/chunk-2LM6LCJW.mjs +1091 -0
- package/dist/chunk-2LM6LCJW.mjs.map +1 -0
- package/dist/chunk-366S2JCC.mjs +31 -0
- package/dist/chunk-366S2JCC.mjs.map +1 -0
- package/dist/chunk-3FBCC4G3.js +8 -0
- package/dist/chunk-3FBCC4G3.js.map +1 -0
- package/dist/chunk-4HCRAOS5.js +28 -0
- package/dist/chunk-4HCRAOS5.js.map +1 -0
- package/dist/chunk-5W6AKZE6.mjs +131 -0
- package/dist/chunk-5W6AKZE6.mjs.map +1 -0
- package/dist/chunk-6GKHCVF6.js +98 -0
- package/dist/chunk-6GKHCVF6.js.map +1 -0
- package/dist/chunk-7QVYU63E.js +7 -0
- package/dist/chunk-7QVYU63E.js.map +1 -0
- package/dist/chunk-A3J3AAYM.mjs +97 -0
- package/dist/chunk-A3J3AAYM.mjs.map +1 -0
- package/dist/chunk-A5DDIABK.js +4209 -0
- package/dist/chunk-A5DDIABK.js.map +1 -0
- package/dist/chunk-AUXK7QSA.mjs +15 -0
- package/dist/chunk-AUXK7QSA.mjs.map +1 -0
- package/dist/chunk-AWONBQQP.js +97 -0
- package/dist/chunk-AWONBQQP.js.map +1 -0
- package/dist/chunk-BLWVZK6J.mjs +28 -0
- package/dist/chunk-BLWVZK6J.mjs.map +1 -0
- package/dist/chunk-C7C7VY4F.mjs +77 -0
- package/dist/chunk-C7C7VY4F.mjs.map +1 -0
- package/dist/chunk-CXQOWQSY.js +55 -0
- package/dist/chunk-CXQOWQSY.js.map +1 -0
- package/dist/chunk-DD3KISNB.mjs +98 -0
- package/dist/chunk-DD3KISNB.mjs.map +1 -0
- package/dist/chunk-DKKMWBP4.mjs +1 -0
- package/dist/chunk-DKKMWBP4.mjs.map +1 -0
- package/dist/chunk-DO2HLAZO.js +48 -0
- package/dist/chunk-DO2HLAZO.js.map +1 -0
- package/dist/chunk-DZXDB3K2.mjs +17 -0
- package/dist/chunk-DZXDB3K2.mjs.map +1 -0
- package/dist/chunk-ECDTZBYO.mjs +230 -0
- package/dist/chunk-ECDTZBYO.mjs.map +1 -0
- package/dist/chunk-EFJEWLRL.js +16 -0
- package/dist/chunk-EFJEWLRL.js.map +1 -0
- package/dist/chunk-FY4SXJGU.js +806 -0
- package/dist/chunk-FY4SXJGU.js.map +1 -0
- package/dist/chunk-GYWPEPOH.mjs +1354 -0
- package/dist/chunk-GYWPEPOH.mjs.map +1 -0
- package/dist/chunk-H6FMOA6B.js +1 -0
- package/dist/chunk-H6FMOA6B.js.map +1 -0
- package/dist/chunk-HR4H2FP7.mjs +89 -0
- package/dist/chunk-HR4H2FP7.mjs.map +1 -0
- package/dist/chunk-I2REI7OA.js +462 -0
- package/dist/chunk-I2REI7OA.js.map +1 -0
- package/dist/chunk-IBS6NI7D.js +77 -0
- package/dist/chunk-IBS6NI7D.js.map +1 -0
- package/dist/chunk-IWFGEPAA.mjs +4209 -0
- package/dist/chunk-IWFGEPAA.mjs.map +1 -0
- package/dist/chunk-J4Q36PMP.js +31 -0
- package/dist/chunk-J4Q36PMP.js.map +1 -0
- package/dist/chunk-JC3WJK65.js +1091 -0
- package/dist/chunk-JC3WJK65.js.map +1 -0
- package/dist/chunk-L6EQEAXU.mjs +462 -0
- package/dist/chunk-L6EQEAXU.mjs.map +1 -0
- package/dist/chunk-LXKSUWAV.js +15 -0
- package/dist/chunk-LXKSUWAV.js.map +1 -0
- package/dist/chunk-MFO27OHB.mjs +48 -0
- package/dist/chunk-MFO27OHB.mjs.map +1 -0
- package/dist/chunk-PAWJFY3S.mjs +7 -0
- package/dist/chunk-PAWJFY3S.mjs.map +1 -0
- package/dist/chunk-Q2N6SQYW.mjs +8 -0
- package/dist/chunk-Q2N6SQYW.mjs.map +1 -0
- package/dist/chunk-RAF7PNLG.js +131 -0
- package/dist/chunk-RAF7PNLG.js.map +1 -0
- package/dist/chunk-RUR22SVM.js +17 -0
- package/dist/chunk-RUR22SVM.js.map +1 -0
- package/dist/chunk-TEGF6ZWG.js +109 -0
- package/dist/chunk-TEGF6ZWG.js.map +1 -0
- package/dist/chunk-TMVHSY3Y.js +230 -0
- package/dist/chunk-TMVHSY3Y.js.map +1 -0
- package/dist/chunk-V2JJPI7N.js +1354 -0
- package/dist/chunk-V2JJPI7N.js.map +1 -0
- package/dist/chunk-WWWMJZEF.mjs +806 -0
- package/dist/chunk-WWWMJZEF.mjs.map +1 -0
- package/dist/chunk-X4BIHJ2B.mjs +55 -0
- package/dist/chunk-X4BIHJ2B.mjs.map +1 -0
- package/dist/chunk-YDVTFM7X.mjs +109 -0
- package/dist/chunk-YDVTFM7X.mjs.map +1 -0
- package/dist/chunk-YF5XQZDR.mjs +16 -0
- package/dist/chunk-YF5XQZDR.mjs.map +1 -0
- package/dist/client/index.d.mts +252 -0
- package/dist/client/index.d.ts +252 -0
- package/dist/client/index.js +275 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +274 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/components/index.d.mts +441 -0
- package/dist/components/index.d.ts +441 -0
- package/dist/components/index.js +2474 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +2474 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/config-hXufftVS.d.mts +34 -0
- package/dist/config-hXufftVS.d.ts +34 -0
- package/dist/content.interface-BhyAiOFq.d.ts +35 -0
- package/dist/content.interface-Dg2lt_An.d.mts +35 -0
- package/dist/contexts/index.d.mts +56 -0
- package/dist/contexts/index.d.ts +56 -0
- package/dist/contexts/index.js +21 -0
- package/dist/contexts/index.js.map +1 -0
- package/dist/contexts/index.mjs +21 -0
- package/dist/contexts/index.mjs.map +1 -0
- package/dist/core/index.d.mts +152 -0
- package/dist/core/index.d.ts +152 -0
- package/dist/core/index.js +47 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/index.mjs +47 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/d3.link.interface-QMdB22bC.d.mts +20 -0
- package/dist/d3.link.interface-QMdB22bC.d.ts +20 -0
- package/dist/features/index.d.mts +553 -0
- package/dist/features/index.d.ts +553 -0
- package/dist/features/index.js +94 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/index.mjs +94 -0
- package/dist/features/index.mjs.map +1 -0
- package/dist/hooks/index.d.mts +94 -0
- package/dist/hooks/index.d.ts +94 -0
- package/dist/hooks/index.js +43 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +43 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index.d.mts +72 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +84 -0
- package/dist/index.mjs.map +1 -0
- package/dist/interfaces/index.d.mts +3 -0
- package/dist/interfaces/index.d.ts +3 -0
- package/dist/interfaces/index.js +2 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/index.mjs +2 -0
- package/dist/interfaces/index.mjs.map +1 -0
- package/dist/permissions/index.d.mts +41 -0
- package/dist/permissions/index.d.ts +41 -0
- package/dist/permissions/index.js +14 -0
- package/dist/permissions/index.js.map +1 -0
- package/dist/permissions/index.mjs +14 -0
- package/dist/permissions/index.mjs.map +1 -0
- package/dist/request-7FE3LJLV.mjs +9 -0
- package/dist/request-7FE3LJLV.mjs.map +1 -0
- package/dist/request-FYMQK5CX.mjs +9 -0
- package/dist/request-FYMQK5CX.mjs.map +1 -0
- package/dist/request-QFS7NEIE.js +9 -0
- package/dist/request-QFS7NEIE.js.map +1 -0
- package/dist/request-ZYY6RI5X.js +9 -0
- package/dist/request-ZYY6RI5X.js.map +1 -0
- package/dist/roles/index.d.mts +33 -0
- package/dist/roles/index.d.ts +33 -0
- package/dist/roles/index.js +12 -0
- package/dist/roles/index.js.map +1 -0
- package/dist/roles/index.mjs +12 -0
- package/dist/roles/index.mjs.map +1 -0
- package/dist/server/index.d.mts +44 -0
- package/dist/server/index.d.ts +44 -0
- package/dist/server/index.js +29 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +29 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/shadcnui/index.d.mts +698 -0
- package/dist/shadcnui/index.d.ts +698 -0
- package/dist/shadcnui/index.js +466 -0
- package/dist/shadcnui/index.js.map +1 -0
- package/dist/shadcnui/index.mjs +465 -0
- package/dist/shadcnui/index.mjs.map +1 -0
- package/dist/token-IJSPOMW6.mjs +9 -0
- package/dist/token-IJSPOMW6.mjs.map +1 -0
- package/dist/token-MJMC26ON.js +9 -0
- package/dist/token-MJMC26ON.js.map +1 -0
- package/dist/token-UADJQ7VC.mjs +9 -0
- package/dist/token-UADJQ7VC.mjs.map +1 -0
- package/dist/token-UYE7CV6X.js +9 -0
- package/dist/token-UYE7CV6X.js.map +1 -0
- package/dist/types-DluCaP1I.d.ts +95 -0
- package/dist/types-lQVA8d_P.d.mts +95 -0
- package/dist/useDataListRetriever-futhx3OP.d.mts +32 -0
- package/dist/useDataListRetriever-futhx3OP.d.ts +32 -0
- package/dist/user.interface-CAsTIbuQ.d.mts +85 -0
- package/dist/user.interface-CbWqMaaU.d.ts +85 -0
- package/dist/utils/index.d.mts +201 -0
- package/dist/utils/index.d.ts +201 -0
- package/dist/utils/index.js +32 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +32 -0
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +205 -0
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractService
|
|
3
|
+
} from "./chunk-L6EQEAXU.mjs";
|
|
4
|
+
import {
|
|
5
|
+
__name
|
|
6
|
+
} from "./chunk-PAWJFY3S.mjs";
|
|
7
|
+
|
|
8
|
+
// src/hooks/TableGeneratorRegistry.ts
|
|
9
|
+
var TableGeneratorRegistry = class _TableGeneratorRegistry {
|
|
10
|
+
static {
|
|
11
|
+
__name(this, "TableGeneratorRegistry");
|
|
12
|
+
}
|
|
13
|
+
static instance;
|
|
14
|
+
registry = /* @__PURE__ */ new Map();
|
|
15
|
+
constructor() {
|
|
16
|
+
}
|
|
17
|
+
static getInstance() {
|
|
18
|
+
if (!_TableGeneratorRegistry.instance) {
|
|
19
|
+
_TableGeneratorRegistry.instance = new _TableGeneratorRegistry();
|
|
20
|
+
}
|
|
21
|
+
return _TableGeneratorRegistry.instance;
|
|
22
|
+
}
|
|
23
|
+
register(type, hook) {
|
|
24
|
+
if (!this.registry.has(type)) this.registry.set(type, hook);
|
|
25
|
+
}
|
|
26
|
+
get(type, params) {
|
|
27
|
+
const hook = this.registry.get(type);
|
|
28
|
+
if (!hook) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Table generator for type "${type}" is not registered. Available types: ${Array.from(this.registry.keys()).join(
|
|
31
|
+
", "
|
|
32
|
+
)}`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return hook(params);
|
|
36
|
+
}
|
|
37
|
+
isRegistered(type) {
|
|
38
|
+
return this.registry.has(type);
|
|
39
|
+
}
|
|
40
|
+
getRegisteredTypes() {
|
|
41
|
+
return Array.from(this.registry.keys());
|
|
42
|
+
}
|
|
43
|
+
unregister(type) {
|
|
44
|
+
return this.registry.delete(type);
|
|
45
|
+
}
|
|
46
|
+
clear() {
|
|
47
|
+
this.registry.clear();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
var tableGeneratorRegistry = TableGeneratorRegistry.getInstance();
|
|
51
|
+
|
|
52
|
+
// src/hooks/url.rewriter.ts
|
|
53
|
+
import { useLocale } from "next-intl";
|
|
54
|
+
import { useCallback } from "react";
|
|
55
|
+
|
|
56
|
+
// src/hooks/usePageUrlGenerator.ts
|
|
57
|
+
function usePageUrlGenerator() {
|
|
58
|
+
const generateUrl = /* @__PURE__ */ __name((params) => {
|
|
59
|
+
if (!params.page) return "/";
|
|
60
|
+
const pathParams = [
|
|
61
|
+
`${params.language ? `/${params.language}` : ""}${typeof params.page === "string" ? params.page : params.page.pageUrl}`
|
|
62
|
+
];
|
|
63
|
+
if (params.id) {
|
|
64
|
+
pathParams.push(params.id);
|
|
65
|
+
if (params.childPage) {
|
|
66
|
+
pathParams.push(typeof params.childPage === "string" ? params.childPage : params.childPage.pageUrl ?? "");
|
|
67
|
+
if (params.childId) {
|
|
68
|
+
pathParams.push(params.childId);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const response = pathParams.join(`/`);
|
|
73
|
+
if (params.additionalParameters) {
|
|
74
|
+
const searchParams = new URLSearchParams();
|
|
75
|
+
for (const key in params.additionalParameters) {
|
|
76
|
+
if (params.additionalParameters[key]) {
|
|
77
|
+
searchParams.append(key, params.additionalParameters[key]);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return `${response}?${searchParams.toString()}`;
|
|
81
|
+
}
|
|
82
|
+
return response;
|
|
83
|
+
}, "generateUrl");
|
|
84
|
+
return generateUrl;
|
|
85
|
+
}
|
|
86
|
+
__name(usePageUrlGenerator, "usePageUrlGenerator");
|
|
87
|
+
|
|
88
|
+
// src/hooks/url.rewriter.ts
|
|
89
|
+
function useUrlRewriter() {
|
|
90
|
+
const locale = useLocale();
|
|
91
|
+
const generateUrl = usePageUrlGenerator();
|
|
92
|
+
return useCallback(
|
|
93
|
+
(params) => {
|
|
94
|
+
window.history.replaceState(
|
|
95
|
+
null,
|
|
96
|
+
"",
|
|
97
|
+
generateUrl({ page: params.page, id: params.id, childPage: params.childPage, language: locale })
|
|
98
|
+
);
|
|
99
|
+
},
|
|
100
|
+
[locale, generateUrl]
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
__name(useUrlRewriter, "useUrlRewriter");
|
|
104
|
+
|
|
105
|
+
// src/hooks/useDataListRetriever.ts
|
|
106
|
+
import { useCallback as useCallback2, useEffect, useMemo, useRef, useState } from "react";
|
|
107
|
+
function useDataListRetriever(params) {
|
|
108
|
+
const [data, setData] = useState(void 0);
|
|
109
|
+
const [nextPage, setNextPage] = useState(void 0);
|
|
110
|
+
const [previousPage, setPreviousPage] = useState(void 0);
|
|
111
|
+
const [isLoaded, setIsLoaded] = useState(false);
|
|
112
|
+
const [ready, setReady] = useState(params.ready ?? true);
|
|
113
|
+
const searchTermRef = useRef("");
|
|
114
|
+
const additionalParamsRef = useRef({});
|
|
115
|
+
const requestIdRef = useRef(0);
|
|
116
|
+
const abortControllerRef = useRef(null);
|
|
117
|
+
const isFetchingRef = useRef(false);
|
|
118
|
+
const resolvedType = params.module;
|
|
119
|
+
const resolvedService = AbstractService;
|
|
120
|
+
const parsePageParams = useCallback2((url) => {
|
|
121
|
+
if (!url) return null;
|
|
122
|
+
try {
|
|
123
|
+
const urlObj = new URL(url);
|
|
124
|
+
const offset = parseInt(urlObj.searchParams.get("page[offset]") || "0", 10);
|
|
125
|
+
const size = parseInt(urlObj.searchParams.get("page[size]") || "25", 10);
|
|
126
|
+
return { offset, size };
|
|
127
|
+
} catch {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}, []);
|
|
131
|
+
const adjustPaginationUrl = useCallback2((url, delta) => {
|
|
132
|
+
if (!url) return void 0;
|
|
133
|
+
try {
|
|
134
|
+
const urlObj = new URL(url);
|
|
135
|
+
const currentOffset = parseInt(urlObj.searchParams.get("page[offset]") || "0", 10);
|
|
136
|
+
const newOffset = Math.max(0, currentOffset + delta);
|
|
137
|
+
urlObj.searchParams.set("page[offset]", String(newOffset));
|
|
138
|
+
return urlObj.toString();
|
|
139
|
+
} catch {
|
|
140
|
+
return url;
|
|
141
|
+
}
|
|
142
|
+
}, []);
|
|
143
|
+
const pageInfo = useMemo(() => {
|
|
144
|
+
if (!data || data.length === 0) return void 0;
|
|
145
|
+
const nextParams = parsePageParams(nextPage);
|
|
146
|
+
const prevParams = parsePageParams(previousPage);
|
|
147
|
+
let currentOffset = 0;
|
|
148
|
+
let pageSize = 25;
|
|
149
|
+
if (nextParams) {
|
|
150
|
+
pageSize = nextParams.size;
|
|
151
|
+
currentOffset = Math.max(0, nextParams.offset - pageSize);
|
|
152
|
+
} else if (prevParams) {
|
|
153
|
+
pageSize = prevParams.size;
|
|
154
|
+
currentOffset = prevParams.offset + pageSize;
|
|
155
|
+
}
|
|
156
|
+
const startItem = currentOffset + 1;
|
|
157
|
+
const endItem = currentOffset + data.length;
|
|
158
|
+
return { startItem, endItem, pageSize };
|
|
159
|
+
}, [data, nextPage, previousPage, parsePageParams]);
|
|
160
|
+
const stableParams = useMemo(
|
|
161
|
+
() => ({
|
|
162
|
+
service: resolvedService,
|
|
163
|
+
type: resolvedType,
|
|
164
|
+
retriever: params.retriever,
|
|
165
|
+
retrieverParams: params.retrieverParams,
|
|
166
|
+
requiresSearch: params.requiresSearch
|
|
167
|
+
}),
|
|
168
|
+
[resolvedService, resolvedType, params.retriever, params.retrieverParams, params.requiresSearch]
|
|
169
|
+
);
|
|
170
|
+
const fetchData = useCallback2(
|
|
171
|
+
async (fetchParams) => {
|
|
172
|
+
if (ready === false) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (isFetchingRef.current && !fetchParams?.callNext && !fetchParams?.callPrevious) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const thisRequestId = ++requestIdRef.current;
|
|
179
|
+
isFetchingRef.current = true;
|
|
180
|
+
if (stableParams.requiresSearch === true && fetchParams?.isRefine !== true && fetchParams?.isRefresh !== true)
|
|
181
|
+
return;
|
|
182
|
+
if (!nextPage && !previousPage && isLoaded && fetchParams?.callNext !== true && fetchParams?.callPrevious !== true && params.search === searchTermRef.current)
|
|
183
|
+
return;
|
|
184
|
+
const currentSearchTerm = searchTermRef.current;
|
|
185
|
+
setIsLoaded(false);
|
|
186
|
+
try {
|
|
187
|
+
let response;
|
|
188
|
+
const nextRef = { next: void 0 };
|
|
189
|
+
const previousRef = { previous: void 0 };
|
|
190
|
+
const selfRef = { self: void 0 };
|
|
191
|
+
if (nextPage && fetchParams?.callNext && fetchParams?.isRefine !== true) {
|
|
192
|
+
const ServiceClass = stableParams.service;
|
|
193
|
+
response = await ServiceClass.next({
|
|
194
|
+
type: stableParams.type,
|
|
195
|
+
endpoint: nextPage,
|
|
196
|
+
next: nextRef,
|
|
197
|
+
previous: previousRef,
|
|
198
|
+
self: selfRef
|
|
199
|
+
});
|
|
200
|
+
} else if (previousPage && fetchParams?.callPrevious && fetchParams?.isRefine !== true) {
|
|
201
|
+
const ServiceClass = stableParams.service;
|
|
202
|
+
response = await ServiceClass.previous({
|
|
203
|
+
type: stableParams.type,
|
|
204
|
+
endpoint: previousPage,
|
|
205
|
+
next: nextRef,
|
|
206
|
+
previous: previousRef,
|
|
207
|
+
self: selfRef
|
|
208
|
+
});
|
|
209
|
+
} else {
|
|
210
|
+
let retrieverParams = stableParams.retrieverParams ? { ...stableParams.retrieverParams } : {};
|
|
211
|
+
retrieverParams = {
|
|
212
|
+
...retrieverParams,
|
|
213
|
+
...additionalParamsRef.current
|
|
214
|
+
};
|
|
215
|
+
retrieverParams.search = currentSearchTerm;
|
|
216
|
+
retrieverParams.next = nextRef;
|
|
217
|
+
retrieverParams.previous = previousRef;
|
|
218
|
+
retrieverParams.self = selfRef;
|
|
219
|
+
response = await stableParams.retriever(retrieverParams);
|
|
220
|
+
}
|
|
221
|
+
if (thisRequestId === requestIdRef.current && !abortControllerRef.current?.signal.aborted) {
|
|
222
|
+
if (fetchParams?.isRefresh === true) {
|
|
223
|
+
setData(response);
|
|
224
|
+
} else {
|
|
225
|
+
setData((prevData) => [...prevData ? prevData : [], ...response]);
|
|
226
|
+
}
|
|
227
|
+
setIsLoaded(true);
|
|
228
|
+
setNextPage(nextRef.next ? nextRef.next : void 0);
|
|
229
|
+
setPreviousPage(previousRef.previous ? previousRef.previous : void 0);
|
|
230
|
+
}
|
|
231
|
+
} catch (error) {
|
|
232
|
+
if (thisRequestId === requestIdRef.current) {
|
|
233
|
+
setIsLoaded(true);
|
|
234
|
+
console.error("Error fetching data:", error);
|
|
235
|
+
}
|
|
236
|
+
} finally {
|
|
237
|
+
if (thisRequestId === requestIdRef.current) {
|
|
238
|
+
isFetchingRef.current = false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
[stableParams, ready, params.search]
|
|
243
|
+
);
|
|
244
|
+
const setRefreshedElement = useCallback2(
|
|
245
|
+
(element) => {
|
|
246
|
+
setData((prevData) => {
|
|
247
|
+
if (!prevData) return prevData;
|
|
248
|
+
const index = prevData.findIndex((data2) => data2.id === element.id);
|
|
249
|
+
if (index === -1) return prevData;
|
|
250
|
+
return prevData.map((item, i) => i === index ? element : item);
|
|
251
|
+
});
|
|
252
|
+
},
|
|
253
|
+
[setData]
|
|
254
|
+
);
|
|
255
|
+
const removeElement = useCallback2(
|
|
256
|
+
(element) => {
|
|
257
|
+
setData((prevData) => {
|
|
258
|
+
if (!prevData) return prevData;
|
|
259
|
+
const index = prevData.findIndex((data2) => data2.id === element.id);
|
|
260
|
+
if (index === -1) return prevData;
|
|
261
|
+
setNextPage((prev) => adjustPaginationUrl(prev, -1));
|
|
262
|
+
const newData = [...prevData];
|
|
263
|
+
newData.splice(index, 1);
|
|
264
|
+
return newData;
|
|
265
|
+
});
|
|
266
|
+
},
|
|
267
|
+
[adjustPaginationUrl]
|
|
268
|
+
);
|
|
269
|
+
useEffect(() => {
|
|
270
|
+
if (ready && !isLoaded) {
|
|
271
|
+
fetchData({ isRefresh: true });
|
|
272
|
+
}
|
|
273
|
+
}, [ready, fetchData]);
|
|
274
|
+
const loadNext = useCallback2(
|
|
275
|
+
async (onlyNewRecords) => {
|
|
276
|
+
if (nextPage) fetchData({ isRefresh: onlyNewRecords, callNext: true });
|
|
277
|
+
},
|
|
278
|
+
[fetchData, nextPage]
|
|
279
|
+
);
|
|
280
|
+
const loadPrevious = useCallback2(
|
|
281
|
+
async (onlyNewRecords) => {
|
|
282
|
+
if (previousPage) fetchData({ isRefresh: onlyNewRecords, callPrevious: true });
|
|
283
|
+
},
|
|
284
|
+
[fetchData, previousPage]
|
|
285
|
+
);
|
|
286
|
+
const addAdditionalParameter = useCallback2(
|
|
287
|
+
(key, value) => {
|
|
288
|
+
if (value === null) {
|
|
289
|
+
delete additionalParamsRef.current[key];
|
|
290
|
+
} else {
|
|
291
|
+
additionalParamsRef.current[key] = value;
|
|
292
|
+
}
|
|
293
|
+
setReady(true);
|
|
294
|
+
setNextPage(void 0);
|
|
295
|
+
setPreviousPage(void 0);
|
|
296
|
+
fetchData({ isRefine: true, isRefresh: true });
|
|
297
|
+
},
|
|
298
|
+
[fetchData]
|
|
299
|
+
);
|
|
300
|
+
const removeAdditionalParameter = useCallback2(
|
|
301
|
+
(key) => {
|
|
302
|
+
if (additionalParamsRef.current[key] !== void 0) {
|
|
303
|
+
delete additionalParamsRef.current[key];
|
|
304
|
+
setNextPage(void 0);
|
|
305
|
+
setPreviousPage(void 0);
|
|
306
|
+
fetchData({ isRefine: true, isRefresh: true });
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
[fetchData]
|
|
310
|
+
);
|
|
311
|
+
const search = useCallback2(
|
|
312
|
+
async (search2) => {
|
|
313
|
+
if (search2 === searchTermRef.current) return;
|
|
314
|
+
setNextPage(void 0);
|
|
315
|
+
setPreviousPage(void 0);
|
|
316
|
+
searchTermRef.current = search2;
|
|
317
|
+
fetchData({ isRefine: true, isRefresh: true });
|
|
318
|
+
},
|
|
319
|
+
[fetchData]
|
|
320
|
+
);
|
|
321
|
+
const isSearch = !!searchTermRef.current;
|
|
322
|
+
const refresh = useCallback2(async () => {
|
|
323
|
+
setNextPage(void 0);
|
|
324
|
+
setPreviousPage(void 0);
|
|
325
|
+
fetchData({ isRefresh: true });
|
|
326
|
+
}, [fetchData]);
|
|
327
|
+
useEffect(() => {
|
|
328
|
+
return () => {
|
|
329
|
+
if (abortControllerRef.current) {
|
|
330
|
+
abortControllerRef.current.abort();
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}, []);
|
|
334
|
+
return {
|
|
335
|
+
ready,
|
|
336
|
+
setReady,
|
|
337
|
+
isLoaded,
|
|
338
|
+
data,
|
|
339
|
+
next: nextPage ? loadNext : void 0,
|
|
340
|
+
previous: previousPage ? loadPrevious : void 0,
|
|
341
|
+
search,
|
|
342
|
+
addAdditionalParameter,
|
|
343
|
+
removeAdditionalParameter,
|
|
344
|
+
refresh,
|
|
345
|
+
setRefreshedElement,
|
|
346
|
+
isSearch,
|
|
347
|
+
removeElement,
|
|
348
|
+
pageInfo
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
__name(useDataListRetriever, "useDataListRetriever");
|
|
352
|
+
|
|
353
|
+
// src/hooks/useDebounce.ts
|
|
354
|
+
import { useCallback as useCallback3, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
355
|
+
function useDebounce(callback, delay) {
|
|
356
|
+
const timeoutRef = useRef2(null);
|
|
357
|
+
const callbackRef = useRef2(callback);
|
|
358
|
+
useEffect2(() => {
|
|
359
|
+
callbackRef.current = callback;
|
|
360
|
+
}, [callback]);
|
|
361
|
+
const debouncedFunction = useCallback3(
|
|
362
|
+
(...args) => {
|
|
363
|
+
if (timeoutRef.current) {
|
|
364
|
+
clearTimeout(timeoutRef.current);
|
|
365
|
+
}
|
|
366
|
+
timeoutRef.current = setTimeout(() => {
|
|
367
|
+
callbackRef.current(...args);
|
|
368
|
+
}, delay);
|
|
369
|
+
},
|
|
370
|
+
[delay]
|
|
371
|
+
);
|
|
372
|
+
const cancel = /* @__PURE__ */ __name(() => {
|
|
373
|
+
if (timeoutRef.current) {
|
|
374
|
+
clearTimeout(timeoutRef.current);
|
|
375
|
+
}
|
|
376
|
+
}, "cancel");
|
|
377
|
+
return Object.assign(debouncedFunction, { cancel });
|
|
378
|
+
}
|
|
379
|
+
__name(useDebounce, "useDebounce");
|
|
380
|
+
|
|
381
|
+
// src/hooks/useTableGenerator.ts
|
|
382
|
+
function registerTableGenerator(type, hook) {
|
|
383
|
+
tableGeneratorRegistry.register(type.name, hook);
|
|
384
|
+
}
|
|
385
|
+
__name(registerTableGenerator, "registerTableGenerator");
|
|
386
|
+
function useTableGenerator(type, params) {
|
|
387
|
+
return tableGeneratorRegistry.get(type.name, params);
|
|
388
|
+
}
|
|
389
|
+
__name(useTableGenerator, "useTableGenerator");
|
|
390
|
+
|
|
391
|
+
// src/hooks/useCustomD3Graph.tsx
|
|
392
|
+
import * as d3 from "d3";
|
|
393
|
+
import { Loader2 } from "lucide-react";
|
|
394
|
+
import { useCallback as useCallback4, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3 } from "react";
|
|
395
|
+
import { renderToStaticMarkup } from "react-dom/server";
|
|
396
|
+
import { jsx } from "react/jsx-runtime";
|
|
397
|
+
function useCustomD3Graph(nodes, links, onNodeClick, visibleNodeIds, loadingNodeIds, containerKey) {
|
|
398
|
+
const svgRef = useRef3(null);
|
|
399
|
+
const zoomRef = useRef3(null);
|
|
400
|
+
const zoomBehaviorRef = useRef3(null);
|
|
401
|
+
const nodePositionsRef = useRef3(/* @__PURE__ */ new Map());
|
|
402
|
+
const prevContainerKeyRef = useRef3(containerKey);
|
|
403
|
+
const zoomToNode = useCallback4(
|
|
404
|
+
(nodeId, childIds = []) => {
|
|
405
|
+
if (!svgRef.current || !zoomBehaviorRef.current) return;
|
|
406
|
+
const svg = d3.select(svgRef.current);
|
|
407
|
+
const zoom2 = zoomBehaviorRef.current;
|
|
408
|
+
const targetNode = nodes.find((n) => n.id === nodeId);
|
|
409
|
+
const childNodes = nodes.filter((n) => childIds.includes(n.id));
|
|
410
|
+
if (!targetNode) return;
|
|
411
|
+
const positions = [];
|
|
412
|
+
if (targetNode.fx !== void 0 && targetNode.fy !== void 0 && targetNode.fx !== null && targetNode.fy !== null) {
|
|
413
|
+
positions.push({ x: targetNode.fx, y: targetNode.fy });
|
|
414
|
+
} else if (targetNode.x !== void 0 && targetNode.y !== void 0 && targetNode.x !== null && targetNode.y !== null) {
|
|
415
|
+
positions.push({ x: targetNode.x, y: targetNode.y });
|
|
416
|
+
}
|
|
417
|
+
childNodes.forEach((child) => {
|
|
418
|
+
if (child.fx !== void 0 && child.fy !== void 0 && child.fx !== null && child.fy !== null) {
|
|
419
|
+
positions.push({ x: child.fx, y: child.fy });
|
|
420
|
+
} else if (child.x !== void 0 && child.y !== void 0 && child.x !== null && child.y !== null) {
|
|
421
|
+
positions.push({ x: child.x, y: child.y });
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
if (positions.length === 0) return;
|
|
425
|
+
const bounds = {
|
|
426
|
+
xMin: Math.min(...positions.map((p) => p.x)),
|
|
427
|
+
xMax: Math.max(...positions.map((p) => p.x)),
|
|
428
|
+
yMin: Math.min(...positions.map((p) => p.y)),
|
|
429
|
+
yMax: Math.max(...positions.map((p) => p.y))
|
|
430
|
+
};
|
|
431
|
+
const padding = 150;
|
|
432
|
+
bounds.xMin -= padding;
|
|
433
|
+
bounds.xMax += padding;
|
|
434
|
+
bounds.yMin -= padding;
|
|
435
|
+
bounds.yMax += padding;
|
|
436
|
+
const width = svgRef.current.clientWidth;
|
|
437
|
+
const height = svgRef.current.clientHeight;
|
|
438
|
+
const contentWidth = bounds.xMax - bounds.xMin;
|
|
439
|
+
const contentHeight = bounds.yMax - bounds.yMin;
|
|
440
|
+
const scaleX = width / contentWidth;
|
|
441
|
+
const scaleY = height / contentHeight;
|
|
442
|
+
let scale = Math.min(scaleX, scaleY);
|
|
443
|
+
scale = Math.min(Math.max(scale, 0.2), 1.5);
|
|
444
|
+
const centerX = (bounds.xMin + bounds.xMax) / 2;
|
|
445
|
+
const centerY = (bounds.yMin + bounds.yMax) / 2;
|
|
446
|
+
const translateX = width / 2 - centerX * scale;
|
|
447
|
+
const translateY = height / 2 - centerY * scale;
|
|
448
|
+
svg.transition().duration(750).call(zoom2.transform, d3.zoomIdentity.translate(translateX, translateY).scale(scale));
|
|
449
|
+
},
|
|
450
|
+
[nodes]
|
|
451
|
+
);
|
|
452
|
+
const colorScale = useMemo2(() => {
|
|
453
|
+
const accentColor = "var(--accent)";
|
|
454
|
+
const contentColor = "hsl(30, 80%, 55%)";
|
|
455
|
+
const groupTypes = /* @__PURE__ */ new Set();
|
|
456
|
+
nodes.forEach((node) => {
|
|
457
|
+
groupTypes.add(node.instanceType);
|
|
458
|
+
});
|
|
459
|
+
const typeColorMap = /* @__PURE__ */ new Map();
|
|
460
|
+
Array.from(groupTypes).forEach((type, index) => {
|
|
461
|
+
if (type === nodes[0]?.instanceType) {
|
|
462
|
+
typeColorMap.set(type, accentColor);
|
|
463
|
+
} else if (type === "documents" || type === "articles" || type === "hyperlinks") {
|
|
464
|
+
typeColorMap.set(type, contentColor);
|
|
465
|
+
} else {
|
|
466
|
+
const hueShift = index * 137.508 % 360;
|
|
467
|
+
typeColorMap.set(type, `hsl(${hueShift}, 32%, 52%)`);
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
return typeColorMap;
|
|
471
|
+
}, [nodes]);
|
|
472
|
+
const washOutColor = useCallback4((color) => {
|
|
473
|
+
const hslMatch = color.match(/hsl\((\d+\.?\d*),\s*(\d+\.?\d*)%,\s*(\d+\.?\d*)%\)/);
|
|
474
|
+
if (hslMatch) {
|
|
475
|
+
const hue = parseFloat(hslMatch[1]);
|
|
476
|
+
return `hsl(${hue}, 15%, 80%)`;
|
|
477
|
+
}
|
|
478
|
+
if (color.includes("var(--accent)")) {
|
|
479
|
+
return "hsl(0, 0%, 80%)";
|
|
480
|
+
}
|
|
481
|
+
return "hsl(0, 0%, 80%)";
|
|
482
|
+
}, []);
|
|
483
|
+
const getNodeColor = useCallback4(
|
|
484
|
+
(node) => {
|
|
485
|
+
const baseColor = colorScale.get(node.instanceType) || "gray";
|
|
486
|
+
if (node.washedOut) {
|
|
487
|
+
return washOutColor(baseColor);
|
|
488
|
+
}
|
|
489
|
+
return baseColor;
|
|
490
|
+
},
|
|
491
|
+
[colorScale, washOutColor]
|
|
492
|
+
);
|
|
493
|
+
useEffect3(() => {
|
|
494
|
+
if (!nodes.length || !svgRef.current) return;
|
|
495
|
+
const visibleNodes = visibleNodeIds ? nodes.filter((node2) => visibleNodeIds.has(node2.id)) : nodes.filter((node2) => node2.visible !== false);
|
|
496
|
+
const visibleNodeIdSet = new Set(visibleNodes.map((node2) => node2.id));
|
|
497
|
+
const visibleLinks = links.filter((link2) => {
|
|
498
|
+
const sourceId = typeof link2.source === "string" ? link2.source : link2.source.id;
|
|
499
|
+
const targetId = typeof link2.target === "string" ? link2.target : link2.target.id;
|
|
500
|
+
return visibleNodeIdSet.has(sourceId) && visibleNodeIdSet.has(targetId);
|
|
501
|
+
});
|
|
502
|
+
const svg = d3.select(svgRef.current);
|
|
503
|
+
svg.selectAll("*").remove();
|
|
504
|
+
const container = svgRef.current?.parentElement;
|
|
505
|
+
if (!container) return;
|
|
506
|
+
const width = container.clientWidth;
|
|
507
|
+
const height = container.clientHeight;
|
|
508
|
+
svg.attr("width", width).attr("height", height).attr("viewBox", `0 0 ${width} ${height}`);
|
|
509
|
+
const graphGroup = svg.append("g").attr("class", "graph-content");
|
|
510
|
+
const zoom2 = d3.zoom().scaleExtent([0.1, 4]).on("zoom", (event) => {
|
|
511
|
+
const transform = event.transform;
|
|
512
|
+
graphGroup.attr("transform", transform.toString());
|
|
513
|
+
zoomRef.current = transform;
|
|
514
|
+
});
|
|
515
|
+
zoomBehaviorRef.current = zoom2;
|
|
516
|
+
svg.call(zoom2).on("wheel.zoom", null).on("dblclick.zoom", null);
|
|
517
|
+
const nodeRadius = 40;
|
|
518
|
+
const childDistanceFromRoot = Math.min(width, height) * 0.4;
|
|
519
|
+
const grandchildDistanceFromChild = nodeRadius * 10;
|
|
520
|
+
const centralNodeId = nodes[0].id;
|
|
521
|
+
const nodeHierarchy = /* @__PURE__ */ new Map();
|
|
522
|
+
nodeHierarchy.set(centralNodeId, {
|
|
523
|
+
depth: 0,
|
|
524
|
+
parent: null,
|
|
525
|
+
children: []
|
|
526
|
+
});
|
|
527
|
+
visibleLinks.forEach((link2) => {
|
|
528
|
+
const sourceId = typeof link2.source === "string" ? link2.source : link2.source.id;
|
|
529
|
+
const targetId = typeof link2.target === "string" ? link2.target : link2.target.id;
|
|
530
|
+
if (sourceId === centralNodeId) {
|
|
531
|
+
nodeHierarchy.set(targetId, { depth: 1, parent: centralNodeId, children: [] });
|
|
532
|
+
const rootNode = nodeHierarchy.get(centralNodeId);
|
|
533
|
+
if (rootNode) {
|
|
534
|
+
rootNode.children.push(targetId);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
visibleLinks.forEach((link2) => {
|
|
539
|
+
const sourceId = typeof link2.source === "string" ? link2.source : link2.source.id;
|
|
540
|
+
const targetId = typeof link2.target === "string" ? link2.target : link2.target.id;
|
|
541
|
+
const sourceNode = nodeHierarchy.get(sourceId);
|
|
542
|
+
if (sourceNode && sourceNode.depth === 1 && !nodeHierarchy.has(targetId)) {
|
|
543
|
+
nodeHierarchy.set(targetId, { depth: 2, parent: sourceId, children: [] });
|
|
544
|
+
sourceNode.children.push(targetId);
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
const rootChildren = nodeHierarchy.get(centralNodeId)?.children || [];
|
|
548
|
+
const childAngleStep = 2 * Math.PI / Math.max(rootChildren.length, 1);
|
|
549
|
+
rootChildren.forEach((childId, index) => {
|
|
550
|
+
const childNode = nodeHierarchy.get(childId);
|
|
551
|
+
if (childNode) {
|
|
552
|
+
const angle = index * childAngleStep;
|
|
553
|
+
childNode.angle = angle;
|
|
554
|
+
childNode.x = width / 2 + childDistanceFromRoot * Math.cos(angle);
|
|
555
|
+
childNode.y = height / 2 + childDistanceFromRoot * Math.sin(angle);
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
for (const [nodeId, node2] of nodeHierarchy.entries()) {
|
|
559
|
+
if (node2.depth === 1 && node2.angle !== void 0 && node2.x !== void 0 && node2.y !== void 0) {
|
|
560
|
+
const childAngle = node2.angle;
|
|
561
|
+
const childX = node2.x;
|
|
562
|
+
const childY = node2.y;
|
|
563
|
+
const grandchildren = node2.children;
|
|
564
|
+
if (grandchildren.length === 0) continue;
|
|
565
|
+
const dirX = childX - width / 2;
|
|
566
|
+
const dirY = childY - height / 2;
|
|
567
|
+
const dirLength = Math.sqrt(dirX * dirX + dirY * dirY);
|
|
568
|
+
const normDirX = dirX / dirLength;
|
|
569
|
+
const normDirY = dirY / dirLength;
|
|
570
|
+
if (grandchildren.length === 1) {
|
|
571
|
+
const grandchildId = grandchildren[0];
|
|
572
|
+
const grandchildNode = nodeHierarchy.get(grandchildId);
|
|
573
|
+
if (grandchildNode) {
|
|
574
|
+
grandchildNode.x = childX + normDirX * grandchildDistanceFromChild;
|
|
575
|
+
grandchildNode.y = childY + normDirY * grandchildDistanceFromChild;
|
|
576
|
+
grandchildNode.angle = childAngle;
|
|
577
|
+
}
|
|
578
|
+
} else {
|
|
579
|
+
const numChildren = grandchildren.length;
|
|
580
|
+
const minArc = Math.PI / 3;
|
|
581
|
+
const maxArc = Math.PI;
|
|
582
|
+
const arcProgress = Math.min(1, (numChildren - 2) / 5);
|
|
583
|
+
const arcSpan = minArc + arcProgress * (maxArc - minArc);
|
|
584
|
+
const startAngle = childAngle - arcSpan / 2;
|
|
585
|
+
grandchildren.forEach((grandchildId, index) => {
|
|
586
|
+
const grandchildNode = nodeHierarchy.get(grandchildId);
|
|
587
|
+
if (!grandchildNode) return;
|
|
588
|
+
const angleOffset = numChildren > 1 ? index / (numChildren - 1) * arcSpan : 0;
|
|
589
|
+
const angle = startAngle + angleOffset;
|
|
590
|
+
grandchildNode.x = childX + grandchildDistanceFromChild * Math.cos(angle);
|
|
591
|
+
grandchildNode.y = childY + grandchildDistanceFromChild * Math.sin(angle);
|
|
592
|
+
grandchildNode.angle = angle;
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
visibleNodes.forEach((node2) => {
|
|
598
|
+
const savedPosition = nodePositionsRef.current.get(node2.id);
|
|
599
|
+
if (savedPosition) {
|
|
600
|
+
node2.fx = savedPosition.x;
|
|
601
|
+
node2.fy = savedPosition.y;
|
|
602
|
+
} else {
|
|
603
|
+
const hierarchyNode = nodeHierarchy.get(node2.id);
|
|
604
|
+
if (hierarchyNode && hierarchyNode.x !== void 0 && hierarchyNode.y !== void 0) {
|
|
605
|
+
node2.fx = hierarchyNode.x;
|
|
606
|
+
node2.fy = hierarchyNode.y;
|
|
607
|
+
nodePositionsRef.current.set(node2.id, { x: hierarchyNode.x, y: hierarchyNode.y });
|
|
608
|
+
} else if (node2.id === centralNodeId) {
|
|
609
|
+
node2.fx = width / 2;
|
|
610
|
+
node2.fy = height / 2;
|
|
611
|
+
nodePositionsRef.current.set(node2.id, { x: width / 2, y: height / 2 });
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
});
|
|
615
|
+
const simulation = d3.forceSimulation(visibleNodes).force(
|
|
616
|
+
"link",
|
|
617
|
+
d3.forceLink(visibleLinks).id((d) => d.id).distance(nodeRadius * 3).strength(0.1)
|
|
618
|
+
).force("charge", d3.forceManyBody().strength(-500).distanceMax(300)).force("collision", d3.forceCollide().radius(nodeRadius * 1.2)).force("center", d3.forceCenter(width / 2, height / 2).strength(0.1));
|
|
619
|
+
simulation.stop();
|
|
620
|
+
for (let i = 0; i < 100; i++) {
|
|
621
|
+
simulation.tick();
|
|
622
|
+
}
|
|
623
|
+
visibleNodes.forEach((node2) => {
|
|
624
|
+
if (node2.fx === void 0) {
|
|
625
|
+
node2.fx = node2.x;
|
|
626
|
+
node2.fy = node2.y;
|
|
627
|
+
}
|
|
628
|
+
});
|
|
629
|
+
const link = graphGroup.append("g").attr("stroke", "#999").attr("stroke-opacity", 0.6).selectAll("line").data(visibleLinks).join("line").attr("x1", (d) => d.source.x || 0).attr("y1", (d) => d.source.y || 0).attr("x2", (d) => d.target.x || 0).attr("y2", (d) => d.target.y || 0).attr("stroke-width", 1.5);
|
|
630
|
+
const node = graphGroup.append("g").selectAll("g").data(visibleNodes).join("g").attr("class", "node-group").attr("cursor", "pointer").attr("transform", (d) => `translate(${d.x || 0}, ${d.y || 0})`).call(
|
|
631
|
+
d3.drag().subject(function(d) {
|
|
632
|
+
return d;
|
|
633
|
+
}).on("start", function(event, d) {
|
|
634
|
+
d.fx = d.x;
|
|
635
|
+
d.fy = d.y;
|
|
636
|
+
}).on("drag", function(event, d) {
|
|
637
|
+
d.fx = event.x;
|
|
638
|
+
d.fy = event.y;
|
|
639
|
+
d3.select(this).attr("transform", `translate(${event.x}, ${event.y})`);
|
|
640
|
+
d3.select(this).attr("transform", `translate(${event.x}, ${event.y})`);
|
|
641
|
+
nodePositionsRef.current.set(d.id, { x: event.x, y: event.y });
|
|
642
|
+
link.attr("x1", (l) => {
|
|
643
|
+
const source = l.source;
|
|
644
|
+
return source.fx || source.x || 0;
|
|
645
|
+
}).attr("y1", (l) => {
|
|
646
|
+
const source = l.source;
|
|
647
|
+
return source.fy || source.y || 0;
|
|
648
|
+
}).attr("x2", (l) => {
|
|
649
|
+
const target = l.target;
|
|
650
|
+
return target.fx || target.x || 0;
|
|
651
|
+
}).attr("y2", (l) => {
|
|
652
|
+
const target = l.target;
|
|
653
|
+
return target.fy || target.y || 0;
|
|
654
|
+
});
|
|
655
|
+
}).on("end", function(event, d) {
|
|
656
|
+
d.fx = event.x;
|
|
657
|
+
d.fy = event.y;
|
|
658
|
+
})
|
|
659
|
+
).on("mouseenter", function(_event, d) {
|
|
660
|
+
if (d.instanceType === "root") return;
|
|
661
|
+
const currentNode = d3.select(this);
|
|
662
|
+
currentNode.raise();
|
|
663
|
+
const currentZoom = zoomRef.current?.k || 1;
|
|
664
|
+
const targetScreenFontSize = 20;
|
|
665
|
+
const baseFontSize = 12;
|
|
666
|
+
const textScale = targetScreenFontSize / (baseFontSize * currentZoom);
|
|
667
|
+
const hoverTextOffset = nodeRadius * 1.4 + 5 / currentZoom;
|
|
668
|
+
currentNode.select("circle").transition().duration(250).ease(d3.easeExpOut).attr("r", nodeRadius * 1.4).attr("filter", "drop-shadow(0px 4px 12px rgba(0, 0, 0, 0.3))");
|
|
669
|
+
currentNode.select("text").transition().duration(250).ease(d3.easeExpOut).attr("dy", -hoverTextOffset).attr("transform", `translate(0, ${-hoverTextOffset}) scale(${textScale}) translate(0, ${hoverTextOffset})`);
|
|
670
|
+
}).on("mouseleave", function(_event, d) {
|
|
671
|
+
if (d.instanceType === "root") return;
|
|
672
|
+
const currentNode = d3.select(this);
|
|
673
|
+
currentNode.select("circle").transition().duration(250).ease(d3.easeExpOut).attr("r", nodeRadius).attr("filter", null);
|
|
674
|
+
const normalOffset = nodeRadius + 5;
|
|
675
|
+
currentNode.select("text").transition().duration(250).ease(d3.easeExpOut).attr("dy", -normalOffset).attr("transform", `translate(0, ${-normalOffset}) scale(1) translate(0, ${normalOffset})`);
|
|
676
|
+
});
|
|
677
|
+
node.append("circle").attr("r", nodeRadius).attr("fill", (d) => getNodeColor(d)).attr("stroke", "#fff").attr("stroke-width", 1.5).on("click", (event, d) => {
|
|
678
|
+
event.preventDefault();
|
|
679
|
+
event.stopPropagation();
|
|
680
|
+
if (zoomBehaviorRef.current) {
|
|
681
|
+
svg.on(".zoom", null);
|
|
682
|
+
setTimeout(() => {
|
|
683
|
+
if (zoomBehaviorRef.current) {
|
|
684
|
+
svg.call(zoomBehaviorRef.current).on("wheel.zoom", null).on("dblclick.zoom", null);
|
|
685
|
+
}
|
|
686
|
+
}, 100);
|
|
687
|
+
}
|
|
688
|
+
onNodeClick(d.id);
|
|
689
|
+
});
|
|
690
|
+
node.each(function(d) {
|
|
691
|
+
if (d.icon) {
|
|
692
|
+
const Icon = d.icon;
|
|
693
|
+
const iconSvg = renderToStaticMarkup(/* @__PURE__ */ jsx(Icon, { size: nodeRadius / 2, color: "white" }));
|
|
694
|
+
const iconGroup = d3.select(this).append("g").html(iconSvg).attr("transform", `translate(${-nodeRadius / 4}, ${-nodeRadius / 4})`).style("pointer-events", "all").on("click", (event) => {
|
|
695
|
+
event.stopPropagation();
|
|
696
|
+
onNodeClick(d.id);
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
node.each(function(d) {
|
|
701
|
+
if (loadingNodeIds && loadingNodeIds.has(d.id)) {
|
|
702
|
+
d3.select(this).selectAll("g").remove();
|
|
703
|
+
const spinnerSvg = renderToStaticMarkup(/* @__PURE__ */ jsx(Loader2, { size: nodeRadius / 2, color: "white" }));
|
|
704
|
+
d3.select(this).append("g").html(spinnerSvg).attr("class", "animate-spin").attr("transform", `translate(${-nodeRadius / 4}, ${-nodeRadius / 4})`).style("pointer-events", "none");
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
node.each(function(d) {
|
|
708
|
+
const textElement = d3.select(this).append("text").attr("text-anchor", "middle").attr("font-size", 12).attr("pointer-events", "none");
|
|
709
|
+
if (d.instanceType === "root") {
|
|
710
|
+
const words = d.name.split(" ");
|
|
711
|
+
const lineHeight = 1.2;
|
|
712
|
+
const numLines = words.length;
|
|
713
|
+
const startY = -((numLines - 1) * lineHeight) / 2;
|
|
714
|
+
textElement.attr("fill", "var(--accent-foreground)").attr("dominant-baseline", "middle");
|
|
715
|
+
words.forEach((word, index) => {
|
|
716
|
+
textElement.append("tspan").attr("x", 0).attr("dy", index === 0 ? `${startY}em` : `${lineHeight}em`).text(word);
|
|
717
|
+
});
|
|
718
|
+
} else {
|
|
719
|
+
textElement.attr("dy", -nodeRadius - 5).attr("fill", "currentColor").text(d.name);
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
return () => {
|
|
723
|
+
simulation.stop();
|
|
724
|
+
};
|
|
725
|
+
}, [nodes, links, colorScale, visibleNodeIds, loadingNodeIds, onNodeClick]);
|
|
726
|
+
const zoomIn = useCallback4(() => {
|
|
727
|
+
if (!svgRef.current || !zoomBehaviorRef.current) return;
|
|
728
|
+
const svg = d3.select(svgRef.current);
|
|
729
|
+
const zoom2 = zoomBehaviorRef.current;
|
|
730
|
+
const currentTransform = zoomRef.current || d3.zoomIdentity;
|
|
731
|
+
const newScale = Math.min(currentTransform.k * 1.3, 4);
|
|
732
|
+
svg.transition().duration(300).call(zoom2.transform, d3.zoomIdentity.translate(currentTransform.x, currentTransform.y).scale(newScale));
|
|
733
|
+
}, []);
|
|
734
|
+
const zoomOut = useCallback4(() => {
|
|
735
|
+
if (!svgRef.current || !zoomBehaviorRef.current) return;
|
|
736
|
+
const svg = d3.select(svgRef.current);
|
|
737
|
+
const zoom2 = zoomBehaviorRef.current;
|
|
738
|
+
const currentTransform = zoomRef.current || d3.zoomIdentity;
|
|
739
|
+
const newScale = Math.max(currentTransform.k * 0.7, 0.1);
|
|
740
|
+
svg.transition().duration(300).call(zoom2.transform, d3.zoomIdentity.translate(currentTransform.x, currentTransform.y).scale(newScale));
|
|
741
|
+
}, []);
|
|
742
|
+
const zoomToFitAll = useCallback4(() => {
|
|
743
|
+
if (!svgRef.current || !zoomBehaviorRef.current) return;
|
|
744
|
+
const svg = d3.select(svgRef.current);
|
|
745
|
+
const zoom2 = zoomBehaviorRef.current;
|
|
746
|
+
const visibleNodes = visibleNodeIds ? nodes.filter((node) => visibleNodeIds.has(node.id)) : nodes.filter((node) => node.visible !== false);
|
|
747
|
+
if (visibleNodes.length === 0) return;
|
|
748
|
+
const positions = [];
|
|
749
|
+
visibleNodes.forEach((node) => {
|
|
750
|
+
if (node.fx !== void 0 && node.fy !== void 0 && node.fx !== null && node.fy !== null) {
|
|
751
|
+
positions.push({ x: node.fx, y: node.fy });
|
|
752
|
+
} else if (node.x !== void 0 && node.y !== void 0 && node.x !== null && node.y !== null) {
|
|
753
|
+
positions.push({ x: node.x, y: node.y });
|
|
754
|
+
}
|
|
755
|
+
});
|
|
756
|
+
if (positions.length === 0) return;
|
|
757
|
+
const bounds = {
|
|
758
|
+
xMin: Math.min(...positions.map((p) => p.x)),
|
|
759
|
+
xMax: Math.max(...positions.map((p) => p.x)),
|
|
760
|
+
yMin: Math.min(...positions.map((p) => p.y)),
|
|
761
|
+
yMax: Math.max(...positions.map((p) => p.y))
|
|
762
|
+
};
|
|
763
|
+
const padding = 150;
|
|
764
|
+
bounds.xMin -= padding;
|
|
765
|
+
bounds.xMax += padding;
|
|
766
|
+
bounds.yMin -= padding;
|
|
767
|
+
bounds.yMax += padding;
|
|
768
|
+
const width = svgRef.current.clientWidth;
|
|
769
|
+
const height = svgRef.current.clientHeight;
|
|
770
|
+
const contentWidth = bounds.xMax - bounds.xMin;
|
|
771
|
+
const contentHeight = bounds.yMax - bounds.yMin;
|
|
772
|
+
const scaleX = width / contentWidth;
|
|
773
|
+
const scaleY = height / contentHeight;
|
|
774
|
+
let scale = Math.min(scaleX, scaleY);
|
|
775
|
+
scale = Math.min(Math.max(scale, 0.1), 2);
|
|
776
|
+
const centerX = (bounds.xMin + bounds.xMax) / 2;
|
|
777
|
+
const centerY = (bounds.yMin + bounds.yMax) / 2;
|
|
778
|
+
const translateX = width / 2 - centerX * scale;
|
|
779
|
+
const translateY = height / 2 - centerY * scale;
|
|
780
|
+
svg.transition().duration(750).call(zoom2.transform, d3.zoomIdentity.translate(translateX, translateY).scale(scale));
|
|
781
|
+
}, [nodes, visibleNodeIds]);
|
|
782
|
+
useEffect3(() => {
|
|
783
|
+
if (containerKey !== void 0 && containerKey !== prevContainerKeyRef.current) {
|
|
784
|
+
const timeoutId = setTimeout(() => {
|
|
785
|
+
zoomToFitAll();
|
|
786
|
+
}, 100);
|
|
787
|
+
prevContainerKeyRef.current = containerKey;
|
|
788
|
+
return () => clearTimeout(timeoutId);
|
|
789
|
+
}
|
|
790
|
+
}, [containerKey, zoomToFitAll]);
|
|
791
|
+
return { svgRef, zoomIn, zoomOut, zoomToNode, zoomToFitAll };
|
|
792
|
+
}
|
|
793
|
+
__name(useCustomD3Graph, "useCustomD3Graph");
|
|
794
|
+
|
|
795
|
+
export {
|
|
796
|
+
TableGeneratorRegistry,
|
|
797
|
+
tableGeneratorRegistry,
|
|
798
|
+
usePageUrlGenerator,
|
|
799
|
+
useUrlRewriter,
|
|
800
|
+
useDataListRetriever,
|
|
801
|
+
useDebounce,
|
|
802
|
+
registerTableGenerator,
|
|
803
|
+
useTableGenerator,
|
|
804
|
+
useCustomD3Graph
|
|
805
|
+
};
|
|
806
|
+
//# sourceMappingURL=chunk-WWWMJZEF.mjs.map
|