@module-federation/devtools 0.0.0-next-20250926024003 → 0.0.0-perf-devtools-20260106124142

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.
Files changed (92) hide show
  1. package/dist/es/App.js +328 -22
  2. package/dist/es/App.module.js +1 -1
  3. package/dist/es/App_module.css +291 -5
  4. package/dist/es/component/DependencyGraph/index.js +205 -0
  5. package/dist/es/component/DependencyGraph/index.module.js +5 -0
  6. package/dist/es/component/DependencyGraph/index_module.css +97 -0
  7. package/dist/es/component/{GraphItem → DependencyGraphItem}/index.js +15 -6
  8. package/dist/es/component/DependencyGraphItem/index.module.js +5 -0
  9. package/dist/es/component/DependencyGraphItem/index_module.css +95 -0
  10. package/dist/es/component/Form/index.js +191 -109
  11. package/dist/es/component/Form/index.module.js +1 -1
  12. package/dist/es/component/Form/index_module.css +179 -25
  13. package/dist/es/component/Layout/index.js +288 -51
  14. package/dist/es/component/Layout/index.module.js +1 -1
  15. package/dist/es/component/Layout/index_module.css +52 -32
  16. package/dist/es/component/ModuleInfo/index.js +289 -0
  17. package/dist/es/component/ModuleInfo/index.module.js +5 -0
  18. package/dist/es/component/ModuleInfo/index_module.css +183 -0
  19. package/dist/es/component/SharedDepsExplorer/FocusResultDisplay.js +39 -0
  20. package/dist/es/component/SharedDepsExplorer/index.js +505 -0
  21. package/dist/es/component/SharedDepsExplorer/share-utils.js +206 -0
  22. package/dist/es/index.css +15 -0
  23. package/dist/es/template/constant.js +5 -19
  24. package/dist/es/utils/chrome/fast-refresh.js +80 -7
  25. package/dist/es/utils/chrome/index.js +91 -38
  26. package/dist/es/utils/chrome/messages.js +6 -0
  27. package/dist/es/utils/chrome/post-message-listener.js +2 -1
  28. package/dist/es/utils/chrome/post-message-start.js +10 -2
  29. package/dist/es/utils/chrome/storage.js +6 -1
  30. package/dist/es/utils/sdk/graph.js +25 -4
  31. package/dist/es/utils/sdk/index.js +9 -0
  32. package/dist/es/worker/index.js +168 -1
  33. package/dist/lib/App.js +318 -17
  34. package/dist/lib/App.module.js +1 -1
  35. package/dist/lib/App_module.css +291 -5
  36. package/dist/lib/component/DependencyGraph/index.js +227 -0
  37. package/dist/lib/component/{GraphItem → DependencyGraph}/index.module.js +1 -1
  38. package/dist/lib/component/DependencyGraph/index_module.css +97 -0
  39. package/dist/lib/component/{GraphItem → DependencyGraphItem}/index.js +18 -9
  40. package/dist/lib/component/{Graph → DependencyGraphItem}/index.module.js +1 -1
  41. package/dist/lib/component/DependencyGraphItem/index_module.css +95 -0
  42. package/dist/lib/component/Form/index.js +188 -107
  43. package/dist/lib/component/Form/index.module.js +1 -1
  44. package/dist/lib/component/Form/index_module.css +179 -25
  45. package/dist/lib/component/Layout/index.js +280 -48
  46. package/dist/lib/component/Layout/index.module.js +1 -1
  47. package/dist/lib/component/Layout/index_module.css +52 -32
  48. package/dist/lib/component/ModuleInfo/index.js +319 -0
  49. package/dist/lib/component/ModuleInfo/index.module.js +25 -0
  50. package/dist/lib/component/ModuleInfo/index_module.css +183 -0
  51. package/dist/lib/component/SharedDepsExplorer/FocusResultDisplay.js +59 -0
  52. package/dist/lib/component/SharedDepsExplorer/index.js +512 -0
  53. package/dist/lib/component/SharedDepsExplorer/share-utils.js +237 -0
  54. package/dist/lib/index.css +15 -0
  55. package/dist/lib/template/constant.js +7 -17
  56. package/dist/lib/utils/chrome/fast-refresh.js +77 -8
  57. package/dist/lib/utils/chrome/index.js +94 -38
  58. package/dist/lib/utils/chrome/messages.js +31 -0
  59. package/dist/lib/utils/chrome/post-message-listener.js +2 -1
  60. package/dist/lib/utils/chrome/post-message-start.js +10 -2
  61. package/dist/lib/utils/chrome/storage.js +5 -0
  62. package/dist/lib/utils/sdk/graph.js +25 -4
  63. package/dist/lib/utils/sdk/index.js +10 -0
  64. package/dist/lib/worker/index.js +156 -1
  65. package/dist/types/src/App.d.ts +0 -1
  66. package/dist/types/src/component/{Graph → DependencyGraph}/index.d.ts +0 -1
  67. package/dist/types/src/component/{GraphItem → DependencyGraphItem}/index.d.ts +0 -1
  68. package/dist/types/src/component/Form/index.d.ts +2 -0
  69. package/dist/types/src/component/Layout/index.d.ts +0 -1
  70. package/dist/types/src/component/ModuleInfo/index.d.ts +8 -0
  71. package/dist/types/src/component/SharedDepsExplorer/FocusResultDisplay.d.ts +15 -0
  72. package/dist/types/src/component/SharedDepsExplorer/index.d.ts +6 -0
  73. package/dist/types/src/component/SharedDepsExplorer/share-utils.d.ts +44 -0
  74. package/dist/types/src/index.d.ts +2 -1
  75. package/dist/types/src/init.d.ts +0 -1
  76. package/dist/types/src/template/constant.d.ts +3 -5
  77. package/dist/types/src/utils/chrome/index.d.ts +5 -3
  78. package/dist/types/src/utils/chrome/messages.d.ts +2 -0
  79. package/dist/types/src/utils/chrome/storage.d.ts +5 -4
  80. package/dist/types/src/utils/sdk/graph.d.ts +2 -1
  81. package/dist/types/src/utils/sdk/index.d.ts +1 -0
  82. package/dist/types/src/utils/types/common.d.ts +4 -0
  83. package/dist/types/src/worker/index.d.ts +1 -0
  84. package/package.json +18 -14
  85. package/dist/es/component/Graph/index.js +0 -127
  86. package/dist/es/component/Graph/index.module.js +0 -5
  87. package/dist/es/component/Graph/index_module.css +0 -12
  88. package/dist/es/component/GraphItem/index.module.js +0 -5
  89. package/dist/es/component/GraphItem/index_module.css +0 -61
  90. package/dist/lib/component/Graph/index.js +0 -149
  91. package/dist/lib/component/Graph/index_module.css +0 -12
  92. package/dist/lib/component/GraphItem/index_module.css +0 -61
package/dist/es/App.js CHANGED
@@ -1,14 +1,102 @@
1
- import { Fragment, jsx } from "react/jsx-runtime";
2
- import { useState, useEffect } from "react";
3
- import { Layout, Empty } from "@arco-design/web-react";
1
+ var __async = (__this, __arguments, generator) => {
2
+ return new Promise((resolve, reject) => {
3
+ var fulfilled = (value) => {
4
+ try {
5
+ step(generator.next(value));
6
+ } catch (e) {
7
+ reject(e);
8
+ }
9
+ };
10
+ var rejected = (value) => {
11
+ try {
12
+ step(generator.throw(value));
13
+ } catch (e) {
14
+ reject(e);
15
+ }
16
+ };
17
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
18
+ step((generator = generator.apply(__this, __arguments)).next());
19
+ });
20
+ };
21
+ import { jsx, jsxs } from "react/jsx-runtime";
22
+ import { useState, useEffect, useMemo, useCallback, useRef } from "react";
23
+ import { Empty, Tag, Button, Tooltip } from "@arco-design/web-react";
4
24
  import "./init";
5
25
  import ProxyLayout from "./component/Layout";
6
- import { getGlobalModuleInfo } from "./utils";
26
+ import Dependency from "./component/DependencyGraph";
27
+ import ModuleInfo from "./component/ModuleInfo";
28
+ import SharedDepsExplorer from "./component/SharedDepsExplorer";
29
+ import {
30
+ getGlobalModuleInfo,
31
+ refreshModuleInfo,
32
+ separateType,
33
+ syncActiveTab
34
+ } from "./utils";
35
+ import { MESSAGE_ACTIVE_TAB_CHANGED } from "./utils/chrome/messages";
7
36
  import "@arco-design/web-react/dist/css/arco.css";
8
37
  import styles from "./App.module";
9
- const { Content } = Layout;
38
+ const cloneModuleInfo = (info) => {
39
+ try {
40
+ return JSON.parse(JSON.stringify(info || {}));
41
+ } catch (error) {
42
+ console.warn("[MF Devtools] cloneModuleInfo failed", error);
43
+ return info || {};
44
+ }
45
+ };
46
+ const normalizeShareValue = (target, seen = /* @__PURE__ */ new WeakSet()) => {
47
+ if (typeof target === "function") {
48
+ const name = target.name ? `: ${target.name}` : "";
49
+ return `[Function${name}]`;
50
+ }
51
+ if (!target || typeof target !== "object") {
52
+ return target;
53
+ }
54
+ if (seen.has(target)) {
55
+ return "[Circular]";
56
+ }
57
+ seen.add(target);
58
+ if (target instanceof Map) {
59
+ const mapped = {};
60
+ target.forEach((value, key) => {
61
+ mapped[String(key)] = normalizeShareValue(value, seen);
62
+ });
63
+ return mapped;
64
+ }
65
+ if (target instanceof Set) {
66
+ const setItems = [];
67
+ target.forEach((value) => {
68
+ setItems.push(normalizeShareValue(value, seen));
69
+ });
70
+ return setItems;
71
+ }
72
+ if (Array.isArray(target)) {
73
+ return target.map((item) => normalizeShareValue(item, seen));
74
+ }
75
+ return Object.keys(target).reduce((memo, key) => {
76
+ memo[key] = normalizeShareValue(target[key], seen);
77
+ return memo;
78
+ }, {});
79
+ };
80
+ const buildShareSnapshot = (share) => {
81
+ const normalize = (value) => {
82
+ try {
83
+ return normalizeShareValue(value);
84
+ } catch (error) {
85
+ console.warn("[MF Devtools] normalize share snapshot failed", error);
86
+ return normalizeShareValue(value);
87
+ }
88
+ };
89
+ const scopes = normalize(share || {});
90
+ return scopes;
91
+ };
92
+ const NAV_ITEMS = [
93
+ { key: "moduleInfo", label: "Module info" },
94
+ { key: "proxy", label: "Proxy" },
95
+ { key: "dependency", label: "Dependency graph" },
96
+ { key: "share", label: "Shared" },
97
+ { key: "performance", label: "Performance" }
98
+ ];
10
99
  const App = (props) => {
11
- var _a;
12
100
  const {
13
101
  versionList,
14
102
  setVersionList,
@@ -18,23 +106,241 @@ const App = (props) => {
18
106
  customValueValidate,
19
107
  headerSlot
20
108
  } = props;
21
- const [module, setModule] = useState(((_a = window.__FEDERATION__) == null ? void 0 : _a.moduleInfo) || {});
22
- useEffect(() => {
23
- getGlobalModuleInfo(setModule);
109
+ const [moduleInfo, setModuleInfo] = useState(
110
+ () => {
111
+ var _a;
112
+ return cloneModuleInfo(((_a = window.__FEDERATION__) == null ? void 0 : _a.moduleInfo) || {});
113
+ }
114
+ );
115
+ const [shareInfo, setShareInfo] = useState(
116
+ () => {
117
+ var _a;
118
+ return buildShareSnapshot((_a = window.__FEDERATION__) == null ? void 0 : _a.__SHARE__);
119
+ }
120
+ );
121
+ const [inspectedTab, setInspectedTab] = useState(
122
+ window.targetTab
123
+ );
124
+ const [activePanel, setActivePanel] = useState("proxy");
125
+ const [selectedModuleId, setSelectedModuleId] = useState(null);
126
+ const [refreshing, setRefreshing] = useState(false);
127
+ const panelSyncReadyRef = useRef(false);
128
+ const applyModuleUpdate = useCallback((info) => {
129
+ var _a;
130
+ setModuleInfo(cloneModuleInfo(info));
131
+ const shareSnapshot = buildShareSnapshot(
132
+ (_a = window.__FEDERATION__) == null ? void 0 : _a.__SHARE__
133
+ );
134
+ setShareInfo(shareSnapshot);
135
+ panelSyncReadyRef.current = true;
24
136
  }, []);
25
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Layout, { className: styles.layout, children: /* @__PURE__ */ jsx(Content, { className: styles.content, children: Object.keys(module).length > 0 || process.env.NODE_ENV === "development" ? /* @__PURE__ */ jsx(
26
- ProxyLayout,
27
- {
28
- moduleInfo: module,
29
- versionList,
30
- setVersionList,
31
- getVersion,
32
- handleSnapshot,
33
- handleProxyAddress,
34
- customValueValidate,
35
- headerSlot
36
- }
37
- ) : /* @__PURE__ */ jsx(Empty, { description: "No ModuleInfo Detected" }) }) }) });
137
+ const { producer, consumers } = useMemo(
138
+ () => separateType(moduleInfo),
139
+ [moduleInfo]
140
+ );
141
+ const moduleKeys = useMemo(() => Object.keys(moduleInfo || {}), [moduleInfo]);
142
+ const moduleCount = moduleKeys.length;
143
+ const consumerCount = useMemo(
144
+ () => Object.keys(consumers || {}).length,
145
+ [consumers]
146
+ );
147
+ const hasModule = moduleCount > 0 || process.env.NODE_ENV === "development";
148
+ useEffect(() => {
149
+ if (!moduleKeys.length) {
150
+ setSelectedModuleId(null);
151
+ return;
152
+ }
153
+ if (!selectedModuleId || !moduleKeys.includes(selectedModuleId)) {
154
+ setSelectedModuleId(moduleKeys[0]);
155
+ }
156
+ }, [moduleKeys, selectedModuleId]);
157
+ useEffect(() => {
158
+ const bootstrap = () => __async(void 0, null, function* () {
159
+ const tab = yield syncActiveTab();
160
+ setInspectedTab(tab || void 0);
161
+ const detach = yield getGlobalModuleInfo(
162
+ (info) => applyModuleUpdate(info)
163
+ );
164
+ panelSyncReadyRef.current = true;
165
+ return detach;
166
+ });
167
+ const cleanupPromise = bootstrap();
168
+ return () => {
169
+ cleanupPromise.then((cleanup) => cleanup == null ? void 0 : cleanup());
170
+ };
171
+ }, [applyModuleUpdate]);
172
+ useEffect(() => {
173
+ const updateActiveTab = (tabId) => __async(void 0, null, function* () {
174
+ var _a, _b;
175
+ const tab = yield syncActiveTab(tabId);
176
+ setInspectedTab(tab || void 0);
177
+ if ((_a = window.__FEDERATION__) == null ? void 0 : _a.moduleInfo) {
178
+ applyModuleUpdate(cloneModuleInfo((_b = window.__FEDERATION__) == null ? void 0 : _b.moduleInfo));
179
+ }
180
+ yield refreshModuleInfo();
181
+ });
182
+ const onMessage = (message, _sender, _sendResponse) => {
183
+ if ((message == null ? void 0 : message.type) === MESSAGE_ACTIVE_TAB_CHANGED) {
184
+ updateActiveTab(message.tabId);
185
+ }
186
+ };
187
+ chrome.runtime.onMessage.addListener(onMessage);
188
+ const onActivated = (activeInfo) => {
189
+ updateActiveTab(activeInfo.tabId);
190
+ };
191
+ chrome.tabs.onActivated.addListener(onActivated);
192
+ return () => {
193
+ chrome.runtime.onMessage.removeListener(onMessage);
194
+ chrome.tabs.onActivated.removeListener(onActivated);
195
+ };
196
+ }, [applyModuleUpdate]);
197
+ const handleRefresh = () => __async(void 0, null, function* () {
198
+ var _a, _b;
199
+ if (refreshing) {
200
+ return;
201
+ }
202
+ setRefreshing(true);
203
+ try {
204
+ yield refreshModuleInfo();
205
+ if ((_a = window.__FEDERATION__) == null ? void 0 : _a.moduleInfo) {
206
+ applyModuleUpdate(cloneModuleInfo((_b = window.__FEDERATION__) == null ? void 0 : _b.moduleInfo));
207
+ }
208
+ } finally {
209
+ setRefreshing(false);
210
+ }
211
+ });
212
+ const resetModuleInfo = useCallback(() => {
213
+ var _a;
214
+ const origin = ((_a = window.__FEDERATION__) == null ? void 0 : _a.originModuleInfo) || {};
215
+ applyModuleUpdate(cloneModuleInfo(origin));
216
+ }, [applyModuleUpdate]);
217
+ useEffect(() => {
218
+ const shouldAutoSync = activePanel === "proxy" || activePanel === "dependency" || activePanel === "share";
219
+ if (!shouldAutoSync || !panelSyncReadyRef.current) {
220
+ return;
221
+ }
222
+ let cancelled = false;
223
+ const syncPanelData = () => __async(void 0, null, function* () {
224
+ var _a, _b;
225
+ yield refreshModuleInfo();
226
+ if (cancelled) {
227
+ return;
228
+ }
229
+ if ((_a = window.__FEDERATION__) == null ? void 0 : _a.moduleInfo) {
230
+ applyModuleUpdate(cloneModuleInfo((_b = window.__FEDERATION__) == null ? void 0 : _b.moduleInfo));
231
+ }
232
+ });
233
+ void syncPanelData();
234
+ return () => {
235
+ cancelled = true;
236
+ };
237
+ }, [activePanel, applyModuleUpdate]);
238
+ const renderContent = () => {
239
+ var _a;
240
+ switch (activePanel) {
241
+ case "moduleInfo":
242
+ return /* @__PURE__ */ jsx(
243
+ ModuleInfo,
244
+ {
245
+ moduleInfo,
246
+ selectedModuleId,
247
+ onSelectModule: (id) => setSelectedModuleId(id)
248
+ }
249
+ );
250
+ case "proxy":
251
+ return /* @__PURE__ */ jsx(
252
+ ProxyLayout,
253
+ {
254
+ moduleInfo,
255
+ versionList,
256
+ setVersionList,
257
+ getVersion,
258
+ handleSnapshot,
259
+ handleProxyAddress,
260
+ customValueValidate,
261
+ headerSlot,
262
+ onModuleInfoChange: applyModuleUpdate,
263
+ onModuleInfoReset: resetModuleInfo,
264
+ tabId: inspectedTab == null ? void 0 : inspectedTab.id
265
+ }
266
+ );
267
+ case "dependency":
268
+ return hasModule ? /* @__PURE__ */ jsx(Dependency, { snapshot: moduleInfo }) : /* @__PURE__ */ jsx("div", { className: styles.emptyState, children: /* @__PURE__ */ jsx(
269
+ Empty,
270
+ {
271
+ description: "No ModuleInfo Detected",
272
+ className: styles.empty
273
+ }
274
+ ) });
275
+ case "share":
276
+ return /* @__PURE__ */ jsx(
277
+ SharedDepsExplorer,
278
+ {
279
+ shareData: JSON.parse(
280
+ JSON.stringify((_a = window.__FEDERATION__) == null ? void 0 : _a.__SHARE__)
281
+ )
282
+ }
283
+ );
284
+ case "performance":
285
+ return /* @__PURE__ */ jsx("div", { className: styles.placeholder, children: "WIP..." });
286
+ default:
287
+ return null;
288
+ }
289
+ };
290
+ return /* @__PURE__ */ jsxs("div", { className: `${styles.shell} ${styles.overrideArco}`, children: [
291
+ /* @__PURE__ */ jsx("aside", { className: styles.sidebar, children: NAV_ITEMS.map((item) => /* @__PURE__ */ jsx(
292
+ "button",
293
+ {
294
+ type: "button",
295
+ className: `${styles.tabItem} ${activePanel === item.key ? styles.activeTab : ""}`,
296
+ onClick: () => setActivePanel(item.key),
297
+ children: item.label
298
+ },
299
+ item.key
300
+ )) }),
301
+ /* @__PURE__ */ jsxs("section", { className: styles.panel, children: [
302
+ /* @__PURE__ */ jsxs("header", { className: styles.header, children: [
303
+ /* @__PURE__ */ jsxs("div", { className: styles.headerTop, children: [
304
+ /* @__PURE__ */ jsxs("div", { className: styles.branding, children: [
305
+ /* @__PURE__ */ jsx("span", { className: styles.logo, children: "Module Federation" }),
306
+ /* @__PURE__ */ jsx("span", { className: styles.subtitle, children: "DevTools Companion" })
307
+ ] }),
308
+ /* @__PURE__ */ jsx(Tooltip, { content: "重新同步当前页面的 Federation 信息", children: /* @__PURE__ */ jsx(
309
+ Button,
310
+ {
311
+ size: "mini",
312
+ type: "primary",
313
+ loading: refreshing,
314
+ onClick: handleRefresh,
315
+ className: styles.refresh,
316
+ children: "Refresh"
317
+ }
318
+ ) })
319
+ ] }),
320
+ /* @__PURE__ */ jsxs("div", { className: styles.meta, children: [
321
+ /* @__PURE__ */ jsxs("div", { className: styles.scope, children: [
322
+ /* @__PURE__ */ jsx("span", { className: styles.scopeLabel, children: "Focus Tab" }),
323
+ /* @__PURE__ */ jsx(Tag, { className: "common-tag", children: (inspectedTab == null ? void 0 : inspectedTab.title) || "Waiting for target" })
324
+ ] }),
325
+ /* @__PURE__ */ jsxs("div", { className: styles.stats, children: [
326
+ /* @__PURE__ */ jsxs("div", { className: styles.statBlock, children: [
327
+ /* @__PURE__ */ jsx("span", { className: styles.statValue, children: moduleCount }),
328
+ /* @__PURE__ */ jsx("span", { className: styles.statLabel, children: "Modules" })
329
+ ] }),
330
+ /* @__PURE__ */ jsxs("div", { className: styles.statBlock, children: [
331
+ /* @__PURE__ */ jsx("span", { className: styles.statValue, children: producer.length }),
332
+ /* @__PURE__ */ jsx("span", { className: styles.statLabel, children: "Remotes" })
333
+ ] }),
334
+ /* @__PURE__ */ jsxs("div", { className: styles.statBlock, children: [
335
+ /* @__PURE__ */ jsx("span", { className: styles.statValue, children: consumerCount }),
336
+ /* @__PURE__ */ jsx("span", { className: styles.statLabel, children: "Consumers" })
337
+ ] })
338
+ ] })
339
+ ] })
340
+ ] }),
341
+ /* @__PURE__ */ jsx("div", { className: styles.body, children: /* @__PURE__ */ jsx("div", { className: styles.content, children: renderContent() }) })
342
+ ] })
343
+ ] });
38
344
  };
39
345
  var App_default = App;
40
346
  export {
@@ -1,5 +1,5 @@
1
1
  import "./App_module.css";
2
- var App_module_default = { "layout": "layout_ae2ee", "content": "content_ae2ee" };
2
+ var App_module_default = { "shell": "shell_ae2ee", "sidebar": "sidebar_ae2ee", "tabItem": "tabItem_ae2ee", "activeTab": "activeTab_ae2ee", "panel": "panel_ae2ee", "header": "header_ae2ee", "headerTop": "headerTop_ae2ee", "branding": "branding_ae2ee", "refresh": "refresh_ae2ee", "logo": "logo_ae2ee", "subtitle": "subtitle_ae2ee", "meta": "meta_ae2ee", "scope": "scope_ae2ee", "scopeLabel": "scopeLabel_ae2ee", "stats": "stats_ae2ee", "statBlock": "statBlock_ae2ee", "statValue": "statValue_ae2ee", "statLabel": "statLabel_ae2ee", "body": "body_ae2ee", "content": "content_ae2ee", "emptyState": "emptyState_ae2ee", "empty": "empty_ae2ee", "placeholder": "placeholder_ae2ee", "overrideArco": "overrideArco_ae2ee" };
3
3
  export {
4
4
  App_module_default as default
5
5
  };
@@ -3,17 +3,303 @@
3
3
  }
4
4
  .arco-form-layout-horizontal {
5
5
  flex: 1 1;
6
- margin: 0 1vw 0 0;
6
+ margin: 0;
7
7
  }
8
8
  .arco-form-item-wrapper {
9
9
  width: 100%;
10
10
  flex: 1 1;
11
11
  }
12
+ .arco-empty {
13
+ color: #4b5563;
14
+ }
15
+ .arco-select, .arco-input {
16
+ background: transparent;
17
+ }
18
+ .arco-tag-color-arcoblue {
19
+ background: rgba(34, 197, 94, 0.18);
20
+ border: 1px solid rgba(34, 197, 94, 0.35);
21
+ color: #4b5563;
22
+ }
12
23
 
13
- .layout_ae2ee {
24
+ .shell_ae2ee {
14
25
  width: 100%;
15
- height: 100vh;
26
+ min-height: 100vh;
27
+ display: flex;
28
+ align-items: stretch;
29
+ justify-content: center;
30
+ gap: clamp(18px, 3vw, 36px);
31
+ padding: 28px clamp(16px, 4vw, 48px);
32
+ box-sizing: border-box;
33
+ background: radial-gradient(circle at 10% 20%, rgba(229, 231, 235, 0.8) 0%, rgba(243, 244, 246, 0.9) 55%), linear-gradient(135deg, #ffffff 0%, #f9fafb 40%, #f3f4f6 100%);
34
+ }
35
+
36
+ .sidebar_ae2ee {
37
+ width: clamp(160px, 18vw, 220px);
38
+ min-width: 150px;
39
+ display: flex;
40
+ flex-direction: column;
41
+ gap: 12px;
42
+ padding: clamp(18px, 2.5vw, 24px) clamp(14px, 2vw, 18px);
43
+ border-radius: 22px;
44
+ border: 1px solid rgba(148, 163, 184, 0.18);
45
+ background: rgba(255, 255, 255, 0.95);
46
+ box-shadow: 0 18px 48px rgba(0, 0, 0, 0.08), 0 1px 0 rgba(0, 0, 0, 0.05) inset;
47
+ box-sizing: border-box;
48
+ }
49
+
50
+ .tabItem_ae2ee {
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: flex-start;
54
+ border: 1px solid transparent;
55
+ border-radius: 12px;
56
+ padding: 10px 12px;
57
+ background: rgba(249, 250, 251, 0.8);
58
+ color: rgba(55, 65, 81, 0.9);
59
+ font-size: 13px;
60
+ letter-spacing: 0.04em;
61
+ text-transform: uppercase;
62
+ cursor: pointer;
63
+ transition: all 0.15s ease;
64
+ white-space: nowrap;
65
+ }
66
+
67
+ .tabItem_ae2ee:hover {
68
+ border-color: rgba(37, 49, 48, 0.45);
69
+ color: #1e293b;
70
+ }
71
+
72
+ .activeTab_ae2ee {
73
+ border-color: rgba(99, 102, 241, 0.65);
74
+ background: linear-gradient(135deg, rgba(59, 130, 246, 0.15), rgba(37, 99, 235, 0.1));
75
+ color: #1e293b;
76
+ box-shadow: 0 12px 28px rgba(30, 64, 175, 0.25);
77
+ }
78
+
79
+ .panel_ae2ee {
80
+ flex: 1 1;
81
+ min-width: 0;
82
+ width: 100%;
83
+ max-width: 1120px;
84
+ min-height: calc(100vh - 56px);
85
+ background: rgba(255, 255, 255, 0.98);
86
+ border: 1px solid rgba(0, 0, 0, 0.08);
87
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.06), 0 2px 0 rgba(0, 0, 0, 0.04) inset;
88
+ border-radius: 22px;
89
+ padding: clamp(20px, 3vw, 32px);
90
+ display: flex;
91
+ flex-direction: column;
92
+ gap: 28px;
93
+ box-sizing: border-box;
94
+ color: #1f2937;
95
+ }
96
+
97
+ .header_ae2ee {
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 18px;
101
+ }
102
+
103
+ .headerTop_ae2ee {
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: space-between;
107
+ gap: 14px;
108
+ }
109
+
110
+ .branding_ae2ee {
111
+ display: flex;
112
+ flex-direction: column;
113
+ gap: 4px;
114
+ }
115
+
116
+ .refresh_ae2ee .arco-btn-primary {
117
+ background: linear-gradient(135deg, rgba(34, 197, 94, 0.8), rgba(22, 163, 74, 0.7));
118
+ border-color: rgba(34, 197, 94, 0.65);
119
+ }
120
+ .refresh_ae2ee .arco-btn-primary:hover {
121
+ background: linear-gradient(135deg, rgba(34, 197, 94, 0.95), rgba(22, 163, 74, 0.85));
122
+ }
123
+
124
+ .logo_ae2ee {
125
+ font-size: 20px;
126
+ font-weight: 600;
127
+ letter-spacing: 0.02em;
128
+ color: #1e293b;
129
+ }
130
+
131
+ .subtitle_ae2ee {
132
+ font-size: 12px;
133
+ font-weight: 500;
134
+ color: rgba(75, 85, 99, 0.8);
135
+ text-transform: uppercase;
136
+ letter-spacing: 0.12em;
137
+ }
138
+
139
+ .meta_ae2ee {
140
+ display: flex;
141
+ align-items: stretch;
142
+ justify-content: space-between;
143
+ gap: 18px;
144
+ flex-wrap: wrap;
145
+ }
146
+
147
+ .scope_ae2ee {
148
+ display: flex;
149
+ flex-direction: column;
150
+ gap: 8px;
151
+ flex: 1 1 160px;
152
+ }
153
+
154
+ .scopeLabel_ae2ee {
155
+ font-size: 12px;
156
+ color: rgba(75, 85, 99, 0.85);
157
+ text-transform: uppercase;
158
+ letter-spacing: 0.08em;
16
159
  }
17
- .layout_ae2ee .content_ae2ee {
18
- margin: 0 0.5vw 0 2vw;
160
+
161
+ .stats_ae2ee {
162
+ display: flex;
163
+ align-items: center;
164
+ gap: 14px;
165
+ flex-wrap: wrap;
166
+ }
167
+
168
+ .statBlock_ae2ee {
169
+ display: flex;
170
+ flex-direction: column;
171
+ gap: 2px;
172
+ min-width: 80px;
173
+ padding: 12px 14px;
174
+ border-radius: 14px;
175
+ background: linear-gradient(140deg, rgba(243, 244, 246, 0.8) 0%, rgba(229, 231, 235, 0.6) 100%);
176
+ border: 1px solid rgba(203, 213, 225, 0.4);
177
+ box-shadow: 0 10px 24px rgba(0, 0, 0, 0.08);
178
+ }
179
+
180
+ .statValue_ae2ee {
181
+ font-size: 22px;
182
+ font-weight: 600;
183
+ color: #1e293b;
184
+ line-height: 1.1;
185
+ }
186
+
187
+ .statLabel_ae2ee {
188
+ font-size: 11px;
189
+ color: rgba(75, 85, 99, 0.88);
190
+ letter-spacing: 0.04em;
191
+ text-transform: uppercase;
192
+ }
193
+
194
+ .body_ae2ee {
195
+ flex: 1 1;
196
+ display: flex;
197
+ flex-direction: column;
198
+ min-height: 0;
199
+ overflow: hidden;
200
+ }
201
+
202
+ .content_ae2ee {
203
+ flex: 1 1;
204
+ display: flex;
205
+ flex-direction: column;
206
+ min-height: 0;
207
+ overflow: auto;
208
+ gap: 16px;
209
+ }
210
+
211
+ @media (max-width: 980px) {
212
+ .shell_ae2ee {
213
+ flex-direction: column;
214
+ align-items: stretch;
215
+ }
216
+ .sidebar_ae2ee {
217
+ width: 100%;
218
+ flex-direction: row;
219
+ align-items: center;
220
+ justify-content: flex-start;
221
+ overflow-x: auto;
222
+ padding: 16px 12px;
223
+ gap: 10px;
224
+ }
225
+ .tabItem_ae2ee {
226
+ flex: 1 0 auto;
227
+ justify-content: center;
228
+ padding: 10px 14px;
229
+ }
230
+ .panel_ae2ee {
231
+ max-width: none;
232
+ min-height: auto;
233
+ }
234
+ }
235
+ @media (max-width: 640px) {
236
+ .panel_ae2ee {
237
+ padding: 20px;
238
+ }
239
+ .meta_ae2ee {
240
+ gap: 12px;
241
+ }
242
+ .stats_ae2ee {
243
+ width: 100%;
244
+ justify-content: space-between;
245
+ }
246
+ }
247
+ .emptyState_ae2ee {
248
+ flex: 1 1;
249
+ display: flex;
250
+ align-items: center;
251
+ justify-content: center;
252
+ border-radius: 18px;
253
+ border: 1px dashed rgba(203, 213, 225, 0.4);
254
+ background: rgba(255, 255, 255, 0.8);
255
+ padding: 32px;
256
+ }
257
+
258
+ .empty_ae2ee .arco-empty-image > svg path {
259
+ fill: rgba(75, 85, 99, 0.5);
260
+ }
261
+
262
+ .placeholder_ae2ee {
263
+ flex: 1 1;
264
+ display: flex;
265
+ align-items: center;
266
+ justify-content: center;
267
+ border-radius: 18px;
268
+ border: 1px dashed rgba(203, 213, 225, 0.4);
269
+ background: rgba(255, 255, 255, 0.8);
270
+ color: rgba(75, 85, 99, 0.75);
271
+ font-size: 14px;
272
+ letter-spacing: 0.08em;
273
+ text-transform: uppercase;
274
+ }
275
+
276
+ .overrideArco_ae2ee .arco-input-inner-wrapper,
277
+ .overrideArco_ae2ee .arco-select-view {
278
+ background-color: #fff !important;
279
+ border-color: rgba(228, 228, 231, 0.5) !important;
280
+ }
281
+ .overrideArco_ae2ee .arco-input-inner-wrapper:hover,
282
+ .overrideArco_ae2ee .arco-select-view:hover {
283
+ background-color: #fff !important;
284
+ border-color: rgba(228, 228, 231, 0.5) !important;
285
+ }
286
+ .overrideArco_ae2ee .arco-input-inner-wrapper:focus-within,
287
+ .overrideArco_ae2ee .arco-select-view-focus {
288
+ background-color: #fff !important;
289
+ border-color: rgba(228, 228, 231, 0.5) !important;
290
+ }
291
+ .overrideArco_ae2ee .arco-collapse-item .arco-collapse-item-icon-hover {
292
+ top: 25% !important;
293
+ }
294
+ .overrideArco_ae2ee .arco-tabs-content {
295
+ padding-top: 0px !important;
296
+ }
297
+
298
+ .arco-table-th {
299
+ background-color: rgb(250 250 250/var(--tw-bg-opacity)) !important;
300
+ border-bottom-color: rgb(228 228 231/var(--tw-border-opacity)) !important;
301
+ }
302
+
303
+ .arco-table-td {
304
+ border-bottom-color: rgba(228, 228, 231, 0.5) !important;
19
305
  }