@epxing/dashboard 0.0.0-stage → 5.3.0-beta.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/API.md +79 -0
- package/README.md +40 -2
- package/dist/_virtual/_plugin-vue_export-helper.js +10 -0
- package/dist/_virtual/preload-helper.js +88 -0
- package/dist/assets/technology_bg-oWIS2awO.jpg +0 -0
- package/dist/src/Dashboard.js +332 -0
- package/dist/src/DashboardGrid.js +182 -0
- package/dist/src/DesignGrid.js +711 -0
- package/dist/src/DesignItem.js +63 -0
- package/dist/src/Div.js +408 -0
- package/dist/src/Header.js +385 -0
- package/dist/src/Preview.js +27 -0
- package/dist/src/Tabs.js +468 -0
- package/dist/src/Title.js +101 -0
- package/dist/src/Widget.js +266 -0
- package/dist/src/chart-request-scope.js +32 -0
- package/dist/src/design-target.js +57 -0
- package/dist/src/grid/compact.js +68 -0
- package/dist/src/grid/compat/GridItem.js +35 -0
- package/dist/src/grid/compat/GridLayout.js +76 -0
- package/dist/src/grid/designState.js +21 -0
- package/dist/src/grid/engines.js +25 -0
- package/dist/src/grid/geometry.js +44 -0
- package/dist/src/grid/gridstackParams.js +69 -0
- package/dist/src/grid/mixins.js +108 -0
- package/dist/src/grid/model.js +223 -0
- package/dist/src/grid/useViewportGate.js +55 -0
- package/dist/src/index.js +26 -0
- package/dist/src/layout-util.js +108 -0
- package/dist/src/mobile-design.js +50 -0
- package/dist/src/theme-style.js +133 -0
- package/dist/style.css +1009 -0
- package/package.json +85 -3
- package/src/Dashboard.vue +459 -0
- package/src/DashboardGrid.vue +189 -0
- package/src/DesignGrid.vue +851 -0
- package/src/DesignItem.vue +124 -0
- package/src/Div.vue +419 -0
- package/src/Header.vue +501 -0
- package/src/Preview.vue +30 -0
- package/src/Tabs.vue +484 -0
- package/src/Title.vue +107 -0
- package/src/Widget.vue +354 -0
- package/src/chart-request-scope.js +22 -0
- package/src/design-target.js +55 -0
- package/src/grid/compact.js +81 -0
- package/src/grid/compat/GridItem.vue +30 -0
- package/src/grid/compat/GridLayout.vue +76 -0
- package/src/grid/designState.js +17 -0
- package/src/grid/engines.js +22 -0
- package/src/grid/geometry.js +55 -0
- package/src/grid/gridstackParams.js +72 -0
- package/src/grid/mixins.js +114 -0
- package/src/grid/model.js +259 -0
- package/src/grid/useViewportGate.js +57 -0
- package/src/index.js +28 -0
- package/src/layout-util.js +157 -0
- package/src/mobile-design.js +50 -0
- package/src/theme-style.js +185 -0
- package/types/div.d.ts +1 -0
- package/types/index.d.ts +7 -0
- package/types/tabs.d.ts +1 -0
- package/types/title.d.ts +1 -0
- package/types/widget.d.ts +1 -0
package/API.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# @epxing/dashboard API
|
|
2
|
+
|
|
3
|
+
看板根容器、分组标签、标题、内容区和挂件组件。
|
|
4
|
+
|
|
5
|
+
本页对应包版本 `5.3.0-beta.1`。导出名、子路径和签名从当前源码、package.json 与类型声明生成。
|
|
6
|
+
|
|
7
|
+
## 安装与使用
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
pnpm add @epxing/dashboard
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
import DashboardPlugin, { Dashboard, DashboardWidget } from '@epxing/dashboard'
|
|
17
|
+
import '@epxing/dashboard/style.css'
|
|
18
|
+
|
|
19
|
+
// app 已初始化 core 和基础组件
|
|
20
|
+
app.use(DashboardPlugin)
|
|
21
|
+
app.component('ProductDashboard', Dashboard)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 接入约定
|
|
25
|
+
|
|
26
|
+
default 与具名 Dashboard 是同一根组件;其 install 会注册配套组件、预览和网格兼容组件。布局、请求与保存依赖平台运行环境。Tabs/Title/Div/Widget 稳定子路径均为 default 组件导出。
|
|
27
|
+
|
|
28
|
+
## 根入口完整导出
|
|
29
|
+
|
|
30
|
+
| 导出名 | 形态 | 用途 | 参数 / 配置 / 事件 |
|
|
31
|
+
| --- | --- | --- | --- |
|
|
32
|
+
| `default` | 默认导出 | Dashboard 组件,同时具有 install,可用作组件或 app.use 插件。 | [详细参考](../../docs/revision/dashboard/Dashboard.md) |
|
|
33
|
+
| `Dashboard` | Vue 组件 | 看板根容器,组织布局、挂件和看板运行状态。 | [详细参考](../../docs/revision/dashboard/Dashboard.md) |
|
|
34
|
+
| `DashboardTabs` | Vue 组件 | 看板标签页容器,按标签组织看板内容。 | [详细参考](../../docs/revision/dashboard/Tabs.md) |
|
|
35
|
+
| `DashboardTitle` | Vue 组件 | 看板标题组件,展示标题和相关样式。 | [详细参考](../../docs/revision/dashboard/Title.md) |
|
|
36
|
+
| `DashboardDiv` | Vue 组件 | 看板内容容器,承载嵌套内容和布局。 | [详细参考](../../docs/revision/dashboard/Div.md) |
|
|
37
|
+
| `DashboardWidget` | Vue 组件 | 看板挂件容器,负责挂件内容与布局交互。 | [详细参考](../../docs/revision/dashboard/Widget.md) |
|
|
38
|
+
|
|
39
|
+
## 函数、类与工具对象
|
|
40
|
+
|
|
41
|
+
签名中的 any 表示现有声明未进一步限定结构;源代码方法签名保留默认参数。异步结果与泛型以声明为准。
|
|
42
|
+
|
|
43
|
+
## 稳定子路径
|
|
44
|
+
|
|
45
|
+
下表按实际 package.json 的公开入口列出。default 使用默认导入,其他名称使用具名导入;类型接口用 import type。
|
|
46
|
+
|
|
47
|
+
| 导入路径 | 完整导出名 | 用途 / 详细说明 |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| `@epxing/dashboard/tabs` | `default` | 看板标签页容器,按标签组织看板内容。 [详细参考](../../docs/revision/dashboard/Tabs.md) |
|
|
50
|
+
| `@epxing/dashboard/title` | `default` | 看板标题组件,展示标题和相关样式。 [详细参考](../../docs/revision/dashboard/Title.md) |
|
|
51
|
+
| `@epxing/dashboard/div` | `default` | 看板内容容器,承载嵌套内容和布局。 [详细参考](../../docs/revision/dashboard/Div.md) |
|
|
52
|
+
| `@epxing/dashboard/widget` | `default` | 看板挂件容器,负责挂件内容与布局交互。 [详细参考](../../docs/revision/dashboard/Widget.md) |
|
|
53
|
+
| `@epxing/dashboard/style.css` | 样式副作用入口 | 在产品入口引入一次。 |
|
|
54
|
+
|
|
55
|
+
## 源码兼容与其他入口
|
|
56
|
+
|
|
57
|
+
/src 路径保留给已有产品和源码级扩展,可能包含平台内部实现;新产品优先采用上方根导出与稳定子路径。通配符表示按实际文件名匹配,不代表所有源码都属于根入口。
|
|
58
|
+
|
|
59
|
+
| 公开路径模式 | 实际目标 |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| `@epxing/dashboard/src` | `./dist/src/index.js` |
|
|
62
|
+
| `@epxing/dashboard/src/*.css` | `./src/*.css` |
|
|
63
|
+
| `@epxing/dashboard/src/*.scss` | `./src/*.scss` |
|
|
64
|
+
| `@epxing/dashboard/src/*.png` | `./src/*.png` |
|
|
65
|
+
| `@epxing/dashboard/src/*.svg` | `./src/*.svg` |
|
|
66
|
+
| `@epxing/dashboard/src/*.jpg` | `./src/*.jpg` |
|
|
67
|
+
| `@epxing/dashboard/src/*.gif` | `./src/*.gif` |
|
|
68
|
+
| `@epxing/dashboard/src/*.woff` | `./src/*.woff` |
|
|
69
|
+
| `@epxing/dashboard/src/*.woff2` | `./src/*.woff2` |
|
|
70
|
+
| `@epxing/dashboard/src/*.ttf` | `./src/*.ttf` |
|
|
71
|
+
| `@epxing/dashboard/src/*.js` | `./dist/src/*.js` |
|
|
72
|
+
| `@epxing/dashboard/src/*.jsx` | `./dist/src/*.js` |
|
|
73
|
+
| `@epxing/dashboard/src/*.vue` | `./dist/src/*.js` |
|
|
74
|
+
| `@epxing/dashboard/src/*` | `./dist/src/*.js` |
|
|
75
|
+
| `@epxing/dashboard/package.json` | `./package.json` |
|
|
76
|
+
|
|
77
|
+
## 文档维护
|
|
78
|
+
|
|
79
|
+
本页由 build/gen-package-api-docs.mjs 生成。修改公开入口并更新构建产物和类型声明后,在框架根运行 `pnpm docs:api`;`pnpm docs:api:check` 检查清单、类型、包内文档与站点镜像是否同步,同时验证页面编译和文档链接。用途和示例维护在 build/package-api-notes.mjs,组件和源码方法的详细参考位于 docs/revision。
|
package/README.md
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @epxing/dashboard
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[完整公开 API、导入方式与示例](./API.md)
|
|
4
|
+
|
|
5
|
+
数据看板包 - **可视化看板搭建,拖拽组件组成仪表盘大屏(按需加载)**。
|
|
6
|
+
|
|
7
|
+
## 范围
|
|
8
|
+
|
|
9
|
+
- `src/frame/packages/dashboard/`(Dashboard.vue / Widget.vue / Tabs.vue / Div.vue / Header.vue)
|
|
10
|
+
- `src/frame/packages/visual-config-page/Dashboard*.vue`
|
|
11
|
+
- `src/frame/packages/visual-config-page/DashboardDesign.vue`
|
|
12
|
+
- `src/frame/packages/visual-config-page/dashboard-theme-setting/`(Background / Border / Index)
|
|
13
|
+
|
|
14
|
+
## 依赖
|
|
15
|
+
|
|
16
|
+
- `@epxing/utils`
|
|
17
|
+
- `@epxing/theme`
|
|
18
|
+
- `@epxing/core`
|
|
19
|
+
- `@epxing/components`
|
|
20
|
+
- echarts / d3(本包独占重依赖)
|
|
21
|
+
|
|
22
|
+
## 加载策略
|
|
23
|
+
|
|
24
|
+
`apps/platform` 路由层 `() => import('@epxing/dashboard')` 懒加载。
|
|
25
|
+
|
|
26
|
+
## 状态
|
|
27
|
+
|
|
28
|
+
🟡 stub - 实际迁移在 T20。
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## 独立包公共入口(2026-10-22)
|
|
32
|
+
|
|
33
|
+
根入口及稳定子路径提供类型声明。先安装 core 与需要的 component,再按需安装本包。
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
import plugin from '@epxing/dashboard'
|
|
37
|
+
import '@epxing/dashboard/style.css'
|
|
38
|
+
app.use(plugin)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
工作区构建:`pnpm --filter @epxing/dashboard build`。pack/publish 的 prepack 会重建;版本由 Changesets 独立管理。旧 `/src/*` 入口保留。完整初始化、打包与远程共享流程见 docs/build-and-publish.md。
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const scriptRel = /* @__PURE__ */ (function detectScriptRel() {
|
|
2
|
+
const relList = typeof document !== "undefined" && document.createElement("link").relList;
|
|
3
|
+
return relList && relList.supports && relList.supports("modulepreload") ? "modulepreload" : "preload";
|
|
4
|
+
})();
|
|
5
|
+
const assetsURL = function(dep, importerUrl) {
|
|
6
|
+
return new URL(dep, importerUrl).href;
|
|
7
|
+
};
|
|
8
|
+
const seen = {};
|
|
9
|
+
const __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|
10
|
+
let promise = Promise.resolve();
|
|
11
|
+
if (deps && deps.length > 0) {
|
|
12
|
+
let allSettled2 = function(promises) {
|
|
13
|
+
return Promise.all(
|
|
14
|
+
promises.map(
|
|
15
|
+
(p) => Promise.resolve(p).then(
|
|
16
|
+
(value) => ({ status: "fulfilled", value }),
|
|
17
|
+
(reason) => ({ status: "rejected", reason })
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
const links = document.getElementsByTagName("link");
|
|
23
|
+
const cspNonceMeta = document.querySelector(
|
|
24
|
+
"meta[property=csp-nonce]"
|
|
25
|
+
);
|
|
26
|
+
const cspNonce = (cspNonceMeta == null ? void 0 : cspNonceMeta.nonce) || (cspNonceMeta == null ? void 0 : cspNonceMeta.getAttribute("nonce"));
|
|
27
|
+
promise = allSettled2(
|
|
28
|
+
deps.map((dep) => {
|
|
29
|
+
dep = assetsURL(dep, importerUrl);
|
|
30
|
+
if (dep in seen) return;
|
|
31
|
+
seen[dep] = true;
|
|
32
|
+
const isCss = dep.endsWith(".css");
|
|
33
|
+
const cssSelector = isCss ? '[rel="stylesheet"]' : "";
|
|
34
|
+
const isBaseRelative = !!importerUrl;
|
|
35
|
+
if (isBaseRelative) {
|
|
36
|
+
for (let i = links.length - 1; i >= 0; i--) {
|
|
37
|
+
const link2 = links[i];
|
|
38
|
+
if (link2.href === dep && (!isCss || link2.rel === "stylesheet")) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
} else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const link = document.createElement("link");
|
|
46
|
+
link.rel = isCss ? "stylesheet" : scriptRel;
|
|
47
|
+
if (!isCss) {
|
|
48
|
+
link.as = "script";
|
|
49
|
+
}
|
|
50
|
+
link.crossOrigin = "";
|
|
51
|
+
link.href = dep;
|
|
52
|
+
if (cspNonce) {
|
|
53
|
+
link.setAttribute("nonce", cspNonce);
|
|
54
|
+
}
|
|
55
|
+
document.head.appendChild(link);
|
|
56
|
+
if (isCss) {
|
|
57
|
+
return new Promise((res, rej) => {
|
|
58
|
+
link.addEventListener("load", res);
|
|
59
|
+
link.addEventListener(
|
|
60
|
+
"error",
|
|
61
|
+
() => rej(new Error(`Unable to preload CSS for ${dep}`))
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
function handlePreloadError(err) {
|
|
69
|
+
const e = new Event("vite:preloadError", {
|
|
70
|
+
cancelable: true
|
|
71
|
+
});
|
|
72
|
+
e.payload = err;
|
|
73
|
+
window.dispatchEvent(e);
|
|
74
|
+
if (!e.defaultPrevented) {
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return promise.then((res) => {
|
|
79
|
+
for (const item of res || []) {
|
|
80
|
+
if (item.status !== "rejected") continue;
|
|
81
|
+
handlePreloadError(item.reason);
|
|
82
|
+
}
|
|
83
|
+
return baseModule().catch(handlePreloadError);
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
export {
|
|
87
|
+
__vitePreload
|
|
88
|
+
};
|
|
Binary file
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import DashboardHeader from "./Header.js";
|
|
2
|
+
import DashboardGrid from "./DashboardGrid.js";
|
|
3
|
+
import chartRequestScope from "./chart-request-scope.js";
|
|
4
|
+
import component from "@epxing/core/src/mixins/component";
|
|
5
|
+
import { pageGridMixin } from "./grid/mixins.js";
|
|
6
|
+
import { buildThemeCss, buildThemeChartConfig } from "./theme-style.js";
|
|
7
|
+
import { stackMobileLayout } from "./layout-util.js";
|
|
8
|
+
import { indexDashboardItems, resolveMobileItem } from "./mobile-design.js";
|
|
9
|
+
import { isLegacyConfig } from "./grid/model.js";
|
|
10
|
+
import { mapState } from "vuex";
|
|
11
|
+
import { resolveComponent, openBlock, createElementBlock, normalizeStyle, normalizeClass, createVNode, createElementVNode, withCtx, mergeProps, createCommentVNode } from "vue";
|
|
12
|
+
/* empty css */
|
|
13
|
+
/* empty css */
|
|
14
|
+
import _export_sfc from "../_virtual/_plugin-vue_export-helper.js";
|
|
15
|
+
function refesh() {
|
|
16
|
+
this.resolveChartRequestBroker().invalidate();
|
|
17
|
+
this._epxWalkChildren((child) => {
|
|
18
|
+
if (child.$options.$componentType === "component" && child.$refesh) child.$refesh();
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const _sfc_main = {
|
|
22
|
+
name: "epx-dashboard",
|
|
23
|
+
mixins: [component, pageGridMixin, chartRequestScope],
|
|
24
|
+
components: {
|
|
25
|
+
[DashboardHeader.name]: DashboardHeader,
|
|
26
|
+
[DashboardGrid.name]: DashboardGrid
|
|
27
|
+
},
|
|
28
|
+
$componentType: "page",
|
|
29
|
+
// 组件类型: 页面
|
|
30
|
+
navConfigs: {
|
|
31
|
+
flag: false
|
|
32
|
+
},
|
|
33
|
+
style: {},
|
|
34
|
+
layout: "grid",
|
|
35
|
+
// 组件列表
|
|
36
|
+
items: [],
|
|
37
|
+
// 组件配置
|
|
38
|
+
itemConfigs: {},
|
|
39
|
+
props: {
|
|
40
|
+
inline: Boolean,
|
|
41
|
+
routeKey: [String, Number],
|
|
42
|
+
routes: {
|
|
43
|
+
type: Array,
|
|
44
|
+
default() {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
data() {
|
|
50
|
+
return {
|
|
51
|
+
headerTitle: null,
|
|
52
|
+
pageParams: {},
|
|
53
|
+
model: {},
|
|
54
|
+
// 组件全局data
|
|
55
|
+
pageEvents: {},
|
|
56
|
+
searchScopeParams: [],
|
|
57
|
+
themeMode: null,
|
|
58
|
+
themeStyles: {}
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
computed: {
|
|
62
|
+
...mapState({
|
|
63
|
+
showMenu: (state) => state.config.showMenu,
|
|
64
|
+
showAppNav: (state) => state.config.showAppNav
|
|
65
|
+
}),
|
|
66
|
+
pageTitle() {
|
|
67
|
+
return this.headerTitle || this.page && this.page.title || this.meta && this.meta.name;
|
|
68
|
+
},
|
|
69
|
+
components() {
|
|
70
|
+
const { items = [], mItems } = this.$component;
|
|
71
|
+
let list;
|
|
72
|
+
if (this.mobileDashboard) {
|
|
73
|
+
list = items.filter((item) => !item.mobileHidden);
|
|
74
|
+
} else if (this.$isMobile) {
|
|
75
|
+
if (mItems && mItems.length) {
|
|
76
|
+
const pcIndex = indexDashboardItems(items);
|
|
77
|
+
list = mItems.filter((c) => !c.mobileHidden && pcIndex.has(String(c.id))).map((c) => resolveMobileItem(c, pcIndex));
|
|
78
|
+
} else {
|
|
79
|
+
const { mobileAutoStack = true } = this.$configs;
|
|
80
|
+
list = mobileAutoStack ? stackMobileLayout(items, 48) : items;
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
list = items;
|
|
84
|
+
}
|
|
85
|
+
list.forEach((item) => {
|
|
86
|
+
if (item && item.i == null && item.id != null) item.i = item.id;
|
|
87
|
+
});
|
|
88
|
+
return list;
|
|
89
|
+
},
|
|
90
|
+
// 移动端组件样式:以 PC 组件 style 为基础,叠加 mItems 项里设置的移动端覆盖(空值/未设的键沿用 PC)
|
|
91
|
+
mobileComponentStyle() {
|
|
92
|
+
return (component2) => {
|
|
93
|
+
if (!this.$isMobile || this.mobileDashboard) return component2.style;
|
|
94
|
+
const pcItem = indexDashboardItems(this.$component.items || []).get(String(component2.id)) || {};
|
|
95
|
+
const override = {};
|
|
96
|
+
const cur = component2.style || {};
|
|
97
|
+
for (const k in cur) {
|
|
98
|
+
if (cur[k] !== void 0 && cur[k] !== null && cur[k] !== "") override[k] = cur[k];
|
|
99
|
+
}
|
|
100
|
+
return { ...pcItem.style || {}, ...override };
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
theme() {
|
|
104
|
+
const { theme } = this.$configs;
|
|
105
|
+
return theme;
|
|
106
|
+
},
|
|
107
|
+
colAttribute() {
|
|
108
|
+
return (component2 = {}) => {
|
|
109
|
+
const { xsspan = 24, ...other } = component2;
|
|
110
|
+
const colAttribute = {
|
|
111
|
+
...other,
|
|
112
|
+
xs: {
|
|
113
|
+
span: xsspan
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
delete colAttribute.id;
|
|
117
|
+
delete colAttribute.style;
|
|
118
|
+
delete colAttribute.title;
|
|
119
|
+
return colAttribute;
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
pageStyle() {
|
|
123
|
+
const { layout = "grid", direction = "row", justify = "flex-start", align = "top" } = this.$configs;
|
|
124
|
+
if (layout === "flex") {
|
|
125
|
+
return { display: "flex", "flex-direction": direction, "justify-content": justify, "align-items": align };
|
|
126
|
+
} else {
|
|
127
|
+
return {};
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
dashboardStyle() {
|
|
131
|
+
const { backgroundColor, backgroundImage } = this.$configs;
|
|
132
|
+
return {
|
|
133
|
+
...this.mobileDashboard ? { width: "100%", maxWidth: `${Number(this.$configs.mobileCanvasWidth) || 375}px`, margin: "0 auto", flex: "none" } : {},
|
|
134
|
+
backgroundColor,
|
|
135
|
+
backgroundImage: backgroundImage ? `url(${this.$util.getFileUrl(backgroundImage)})` : null
|
|
136
|
+
};
|
|
137
|
+
},
|
|
138
|
+
componentStyle() {
|
|
139
|
+
return (component2) => {
|
|
140
|
+
const { layout } = this.$configs;
|
|
141
|
+
const { flex } = component2;
|
|
142
|
+
const compoentStyle = {};
|
|
143
|
+
if (layout === "flex" && flex) {
|
|
144
|
+
compoentStyle.flex = 1;
|
|
145
|
+
}
|
|
146
|
+
return compoentStyle;
|
|
147
|
+
};
|
|
148
|
+
},
|
|
149
|
+
scopeParams() {
|
|
150
|
+
const { globalScopeParams: configScopeParams = [] } = this.$configs;
|
|
151
|
+
const { scopeParams: queryScopeParams = [] } = this.$query;
|
|
152
|
+
const _scopeParams = this.$_.cloneDeep([...configScopeParams, ...queryScopeParams, ...this.searchScopeParams]);
|
|
153
|
+
return this.$formatScope(_scopeParams);
|
|
154
|
+
},
|
|
155
|
+
themeChartConfig() {
|
|
156
|
+
return buildThemeChartConfig(this.themeStyles, this.mobileRendering);
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
watch: {
|
|
160
|
+
pageTitle: {
|
|
161
|
+
handler(v) {
|
|
162
|
+
this.$emit("change-route", this.routeKey, { title: v });
|
|
163
|
+
},
|
|
164
|
+
immediate: true
|
|
165
|
+
},
|
|
166
|
+
scopeParams: {
|
|
167
|
+
deep: true,
|
|
168
|
+
handler(v) {
|
|
169
|
+
if (!this.$_.isEqual(this.oldParams, v)) {
|
|
170
|
+
this.pageParams.scopeParams = v;
|
|
171
|
+
}
|
|
172
|
+
this.oldParams = v;
|
|
173
|
+
},
|
|
174
|
+
immediate: true
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
provide() {
|
|
178
|
+
const provideData = {
|
|
179
|
+
getMobileDashboard: () => this.mobileDashboard,
|
|
180
|
+
getThemeChartConfig: () => this.themeChartConfig,
|
|
181
|
+
// 容器内网格的门控策略 / 配置是否旧版都跟随页面(provide 只跑一次,用函数延迟读)
|
|
182
|
+
getDashboardLoadWay: () => this.loadWay,
|
|
183
|
+
getDashboardLegacy: () => isLegacyConfig(this.$configs)
|
|
184
|
+
};
|
|
185
|
+
if (this.isPage) {
|
|
186
|
+
provideData.upPage = this;
|
|
187
|
+
provideData.pageId = this.page ? this.page.pageId : "";
|
|
188
|
+
provideData.pageMetaId = this.isPage ? this.$metaId || (this.page ? this.page.metaId : "") : null;
|
|
189
|
+
}
|
|
190
|
+
return provideData;
|
|
191
|
+
},
|
|
192
|
+
methods: {
|
|
193
|
+
getTheme() {
|
|
194
|
+
if (!this.theme) return Promise.resolve({});
|
|
195
|
+
return this.$http.find({
|
|
196
|
+
entityId: "FM_CHART_THEME",
|
|
197
|
+
"scope.CODE": this.theme
|
|
198
|
+
}).then((data) => {
|
|
199
|
+
if (data && data.data.CONTENT) {
|
|
200
|
+
this.themeMode = data.data.STYLE;
|
|
201
|
+
return JSON.parse(data == null ? void 0 : data.data.CONTENT);
|
|
202
|
+
}
|
|
203
|
+
return {};
|
|
204
|
+
});
|
|
205
|
+
},
|
|
206
|
+
async setThemeStyle() {
|
|
207
|
+
const { themeStyles: configThemeStyles = {} } = this.$configs;
|
|
208
|
+
const activeThemeStyles = await this.getTheme();
|
|
209
|
+
const allThemeStyles = this.$_.assignWith(configThemeStyles, activeThemeStyles, (configThemeItem, themeItem) => {
|
|
210
|
+
return configThemeItem && themeItem && typeof configThemeItem === "object" && typeof themeItem === "object" ? { ...themeItem, ...configThemeItem } : configThemeItem || themeItem;
|
|
211
|
+
});
|
|
212
|
+
this.themeStyles = allThemeStyles;
|
|
213
|
+
const styles = buildThemeCss(allThemeStyles, `.epx-dashboard-${this.$component.id}`, (path) => this.$util.getFileUrl(path), { mobilePreview: this.mobileDashboard });
|
|
214
|
+
let styleElement = document.head.querySelector(`#dashboard-${this.$component.id}`);
|
|
215
|
+
if (!styleElement) {
|
|
216
|
+
styleElement = document.createElement("style");
|
|
217
|
+
styleElement.id = `dashboard-${this.$component.id}`;
|
|
218
|
+
styleElement.type = "text/css";
|
|
219
|
+
styleElement.textContent = styles;
|
|
220
|
+
document.head.appendChild(styleElement);
|
|
221
|
+
} else {
|
|
222
|
+
styleElement.textContent = styles;
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
removeThemeStyle() {
|
|
226
|
+
const styleElement = document.head.querySelector(`#dashboard-${this.$component.id}`);
|
|
227
|
+
styleElement == null ? void 0 : styleElement.remove();
|
|
228
|
+
},
|
|
229
|
+
// reloadPage 会经 RouterView 以新 key 重建整个页面实例,滚动位置无法在此恢复(旧实例的 $refs 已失效)
|
|
230
|
+
$refesh() {
|
|
231
|
+
refesh.apply(this);
|
|
232
|
+
if (this.upPage) this.upPage.$refesh();
|
|
233
|
+
this.reloadPage();
|
|
234
|
+
},
|
|
235
|
+
enableAutoReload() {
|
|
236
|
+
if (this.refreshInterval) {
|
|
237
|
+
clearInterval(this.refreshInterval);
|
|
238
|
+
}
|
|
239
|
+
this.refreshInterval = setInterval(() => {
|
|
240
|
+
refesh.apply(this);
|
|
241
|
+
}, (this.$configs.refreshInterval || 60) * 1e3);
|
|
242
|
+
},
|
|
243
|
+
openFullScreen() {
|
|
244
|
+
if (this.$refs.dashboard.requestFullscreen) {
|
|
245
|
+
this.$refs.dashboard.requestFullscreen();
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
search(v) {
|
|
249
|
+
this.searchScopeParams = v;
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
created() {
|
|
253
|
+
const grid = this.gridParams;
|
|
254
|
+
if (grid.rowHeight === "auto" || grid.padding === "auto") {
|
|
255
|
+
window.addEventListener("resize", this.updateBodyHeight);
|
|
256
|
+
}
|
|
257
|
+
if (this.$configs.autoRefresh) {
|
|
258
|
+
this.enableAutoReload();
|
|
259
|
+
}
|
|
260
|
+
this.setThemeStyle();
|
|
261
|
+
},
|
|
262
|
+
beforeUnmount() {
|
|
263
|
+
window.removeEventListener("resize", this.updateBodyHeight);
|
|
264
|
+
this.removeThemeStyle();
|
|
265
|
+
if (this.refreshInterval) {
|
|
266
|
+
clearInterval(this.refreshInterval);
|
|
267
|
+
this.refreshInterval = null;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
const _hoisted_1 = {
|
|
272
|
+
key: 0,
|
|
273
|
+
class: "epx-dashboard__component-container"
|
|
274
|
+
};
|
|
275
|
+
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
276
|
+
const _component_epx_dashboard_header = resolveComponent("epx-dashboard-header");
|
|
277
|
+
const _component_epx_component = resolveComponent("epx-component");
|
|
278
|
+
const _component_epx_dashboard_grid = resolveComponent("epx-dashboard-grid");
|
|
279
|
+
return openBlock(), createElementBlock("div", {
|
|
280
|
+
class: normalizeClass(["epx-dashboard", "epx-dashboard-" + this.$component.id, "epx-dashboard--" + $options.theme, { "epx-dashboard--hidden-scroll-bar": _ctx.$configs.scrollBarHidden, "is-mobile-preview": _ctx.mobileDashboard }]),
|
|
281
|
+
style: normalizeStyle(_ctx.$component.style),
|
|
282
|
+
ref: "container"
|
|
283
|
+
}, [
|
|
284
|
+
createVNode(_component_epx_dashboard_header, {
|
|
285
|
+
onFullscreen: $options.openFullScreen,
|
|
286
|
+
title: _ctx.$component.title,
|
|
287
|
+
scopeFlag: _ctx.$configs.scopeFlag,
|
|
288
|
+
globalSearchFields: _ctx.$configs.globalSearchFields,
|
|
289
|
+
searchDefaultFlag: _ctx.$configs.searchDefaultFlag,
|
|
290
|
+
onSearch: $options.search
|
|
291
|
+
}, null, 8, ["onFullscreen", "title", "scopeFlag", "globalSearchFields", "searchDefaultFlag", "onSearch"]),
|
|
292
|
+
createElementVNode("div", {
|
|
293
|
+
ref: "dashboard",
|
|
294
|
+
class: normalizeClass(["epx-dashboard__container", { "epx-dashboard__container--mobile": _ctx.mobileDashboard }]),
|
|
295
|
+
style: normalizeStyle($options.dashboardStyle)
|
|
296
|
+
}, [
|
|
297
|
+
createVNode(_component_epx_dashboard_grid, {
|
|
298
|
+
items: $options.components,
|
|
299
|
+
grid: _ctx.gridParams,
|
|
300
|
+
"load-way": _ctx.loadWay,
|
|
301
|
+
"body-height": _ctx.bodyHeight
|
|
302
|
+
}, {
|
|
303
|
+
item: withCtx(({ item: component2 }) => [
|
|
304
|
+
component2.contentType ? (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
305
|
+
createVNode(_component_epx_component, mergeProps(_ctx.isPage ? _ctx.$forwardAttrs(_ctx.$attrs) : {}, {
|
|
306
|
+
class: "epx-dashboard__component",
|
|
307
|
+
name: component2.contentType,
|
|
308
|
+
"is-dashboard": "",
|
|
309
|
+
"content-type": component2.contentType,
|
|
310
|
+
"comp-id": component2.id,
|
|
311
|
+
"comp-title": component2.title,
|
|
312
|
+
items: component2.items,
|
|
313
|
+
itemConfigs: _ctx.$component.itemConfigs,
|
|
314
|
+
"comp-style": $options.mobileComponentStyle(component2),
|
|
315
|
+
"comp-configs": component2.configs,
|
|
316
|
+
"comp-grid": _ctx.containerGrid(component2),
|
|
317
|
+
"chart-cache": _ctx.$configs.chartCache,
|
|
318
|
+
theme: $data.themeMode,
|
|
319
|
+
"mobile-appearance": _ctx.mobileRendering ? component2.mobileAppearance : void 0,
|
|
320
|
+
themeChartConfig: $options.themeChartConfig
|
|
321
|
+
}), null, 16, ["name", "content-type", "comp-id", "comp-title", "items", "itemConfigs", "comp-style", "comp-configs", "comp-grid", "chart-cache", "theme", "mobile-appearance", "themeChartConfig"])
|
|
322
|
+
])) : createCommentVNode("", true)
|
|
323
|
+
]),
|
|
324
|
+
_: 1
|
|
325
|
+
}, 8, ["items", "grid", "load-way", "body-height"])
|
|
326
|
+
], 6)
|
|
327
|
+
], 6);
|
|
328
|
+
}
|
|
329
|
+
const Dashboard = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-2bc41af0"]]);
|
|
330
|
+
export {
|
|
331
|
+
Dashboard as default
|
|
332
|
+
};
|