rj-grid 0.1.0 → 0.2.0
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 +17 -11
- package/dist/rj-grid.js +215 -14
- package/dist/types/index.d.ts +1 -1
- package/dist/types/src/RjGrid.vue.d.ts +9 -1
- package/dist/types/src/optionsSource.d.ts +42 -0
- package/dist/types/src/types.d.ts +29 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
自研**零第三方依赖**的企业级数据网格(Vue 3 + TypeScript),功能规格对标 AG Grid:虚拟滚动、冻结列、行/列拖拽、分组透视、树形、编辑与撤销、公式引擎、SSRM 服务端行模型、主题与 i18n、打印/CSV/Excel 导出、离线自然语言查询(NLQ)。gzip 约 93 KB(不含 vue / echarts)。
|
|
4
4
|
|
|
5
|
-
本仓库是该组件的**独立维护仓**:源码、单测、构建链、演示 playground
|
|
5
|
+
本仓库是该组件的**独立维护仓**:源码、单测、构建链、演示 playground、使用手册都在这里;产物已发布到**公共 npm(包名 `rj-grid`)**,宿主项目(如 join-cloud-vue3)按版本号安装,不参与组件开发。
|
|
6
6
|
|
|
7
7
|
## 仓库布局
|
|
8
8
|
|
|
@@ -33,18 +33,24 @@ pnpm size # 体积报告(可选)
|
|
|
33
33
|
pnpm dev # playground 演示页(默认 :5173,alias 走本地源码)
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
发布新版本:改完源码 → `npm version patch|minor|major`(自动 bump + commit + tag)→ `git push --follow-tags` → `npm publish`(`prepublishOnly` 会自动 `pnpm build && pnpm test`,杜绝发出旧 dist)。
|
|
37
37
|
|
|
38
|
-
## 宿主接入(
|
|
38
|
+
## 宿主接入(npm 版本号)
|
|
39
39
|
|
|
40
40
|
```jsonc
|
|
41
|
-
// 宿主 package.json
|
|
41
|
+
// 宿主 package.json —— 从公共 npm 按语义化版本安装
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"rj-grid": "
|
|
43
|
+
"rj-grid": "^0.1.0"
|
|
44
44
|
}
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
```powershell
|
|
48
|
+
pnpm add rj-grid # 或 npm i rj-grid
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
> 仍保留 git URL 方式(离线内网 / 需锁 commit 时):`"rj-grid": "git+https://gitee.com/rjding/rj-grid.git#v0.1.0"`。
|
|
52
|
+
|
|
53
|
+
从 npm 安装时目录名规范(`node_modules/rj-grid`),样式可**直接**引:`import 'rj-grid/style.css'`。仅当走 git URL 时才需下面的 CSS 垫片——pnpm 会把 git 依赖装进带 `#<commit>` 的目录名,vite 输出的资源 URL 含裸 `#`,浏览器把 `#` 之后当片段丢掉 → dev 下 404:
|
|
48
54
|
|
|
49
55
|
```css
|
|
50
56
|
/* 宿主 src/styles/rjgrid/index.css */
|
|
@@ -67,21 +73,21 @@ peer 依赖:`vue ^3.4.0` 必装;`echarts >=5.0.0` 可选(仅「集成图
|
|
|
67
73
|
## 升级与回滚
|
|
68
74
|
|
|
69
75
|
```powershell
|
|
70
|
-
pnpm update rj-grid #
|
|
71
|
-
pnpm
|
|
76
|
+
pnpm update rj-grid # 在 ^0.1.0 范围内升到最新
|
|
77
|
+
pnpm add rj-grid@latest # 跨范围拉最新
|
|
72
78
|
```
|
|
73
79
|
|
|
74
|
-
|
|
80
|
+
npm 安装的 lockfile 记录精确版本与 `integrity`,CI / 他人 `pnpm install --frozen-lockfile` 可复现。回滚只需把版本钉回旧号(如 `"rj-grid": "0.1.0"`)。本地联调可临时用 `"link:../rjGrid"`,调完换回版本号并重装。
|
|
75
81
|
|
|
76
82
|
## 为什么 dist 入库
|
|
77
83
|
|
|
78
|
-
|
|
84
|
+
发布走 `prepublishOnly`(`pnpm build && pnpm test`):`npm publish` 打的是**构建后磁盘上的 `dist/`**(按 `files` 字段 `["dist","README.md"]` 裁剪),所以公共 npm 消费方无需依赖仓库里的 dist。dist 仍入库只是为了兼容 **git URL 安装**那条路径(git 依赖不会在宿主机跑 `prepare` 重建);保留 dist 入库能同时喂饱两条路。
|
|
79
85
|
|
|
80
86
|
`build/rjDistCheck.mjs` 的五道守卫同时在把关:外部 import 只允许 `vue`/`echarts`;CSS 不引宿主资源;d.ts 不断链;dist 不得混入 `.vue/.ts/.scss` 源码;**不得带 sourcemap**——vite 的 `.map` 内嵌 `sourcesContent`(原始源码),一发包等于源码同步外流,因此 `vite.lib.config.ts` 里 `sourcemap: false` 是源码保护而非可选项。
|
|
81
87
|
|
|
82
88
|
## 私有仓注意
|
|
83
89
|
|
|
84
|
-
|
|
90
|
+
已发布到**公共 npm**,按版本号安装无需任何 git 凭据。仅当某宿主仍走 git URL 且仓库为 gitee 私有仓时,安装机才需具备克隆凭据(HTTPS 走 credential manager 里的 gitee 账号或部署密钥),CI 需预置,否则会卡在 git 认证。
|
|
85
91
|
|
|
86
92
|
## 文档
|
|
87
93
|
|
package/dist/rj-grid.js
CHANGED
|
@@ -4506,6 +4506,125 @@ function translate(messages, key, params) {
|
|
|
4506
4506
|
}
|
|
4507
4507
|
const RJ_LOCALE_KEY = Symbol("rj-locale");
|
|
4508
4508
|
const defaultTranslate = (key, params) => interpolate(zhCN[key] != null ? zhCN[key] : key, params);
|
|
4509
|
+
const RJ_OPTIONS_KEY = Symbol("rj-options");
|
|
4510
|
+
const defaultOptionsAccessor = {
|
|
4511
|
+
list: () => void 0,
|
|
4512
|
+
label: () => void 0
|
|
4513
|
+
};
|
|
4514
|
+
function pickValue(item, valueKey) {
|
|
4515
|
+
if (valueKey)
|
|
4516
|
+
return item[valueKey];
|
|
4517
|
+
if (item.value !== void 0)
|
|
4518
|
+
return item.value;
|
|
4519
|
+
if (item.id !== void 0)
|
|
4520
|
+
return item.id;
|
|
4521
|
+
if (item.code !== void 0)
|
|
4522
|
+
return item.code;
|
|
4523
|
+
if (item.key !== void 0)
|
|
4524
|
+
return item.key;
|
|
4525
|
+
return void 0;
|
|
4526
|
+
}
|
|
4527
|
+
function pickLabel(item, labelKey, value) {
|
|
4528
|
+
if (labelKey)
|
|
4529
|
+
return String(item[labelKey] ?? value);
|
|
4530
|
+
if (item.label !== void 0)
|
|
4531
|
+
return String(item.label);
|
|
4532
|
+
if (item.name !== void 0)
|
|
4533
|
+
return String(item.name);
|
|
4534
|
+
if (item.text !== void 0)
|
|
4535
|
+
return String(item.text);
|
|
4536
|
+
return String(value);
|
|
4537
|
+
}
|
|
4538
|
+
function normalizeOptions(raw, shape = {}) {
|
|
4539
|
+
const out = [];
|
|
4540
|
+
if (!Array.isArray(raw))
|
|
4541
|
+
return out;
|
|
4542
|
+
const ck = shape.childrenKey ?? "children";
|
|
4543
|
+
const walk = (arr) => {
|
|
4544
|
+
for (const it of arr) {
|
|
4545
|
+
if (it == null || typeof it !== "object") {
|
|
4546
|
+
if (it !== null && it !== void 0)
|
|
4547
|
+
out.push({ label: String(it), value: it });
|
|
4548
|
+
continue;
|
|
4549
|
+
}
|
|
4550
|
+
const item = it;
|
|
4551
|
+
if (shape.map) {
|
|
4552
|
+
out.push(shape.map(item));
|
|
4553
|
+
} else {
|
|
4554
|
+
const value = pickValue(item, shape.valueKey);
|
|
4555
|
+
const label = pickLabel(item, shape.labelKey, value);
|
|
4556
|
+
out.push({ label, value });
|
|
4557
|
+
}
|
|
4558
|
+
if (Array.isArray(item[ck]))
|
|
4559
|
+
walk(item[ck]);
|
|
4560
|
+
}
|
|
4561
|
+
};
|
|
4562
|
+
walk(raw);
|
|
4563
|
+
return out;
|
|
4564
|
+
}
|
|
4565
|
+
async function resolveOptions(source, dict, loaders) {
|
|
4566
|
+
var _a, _b, _c;
|
|
4567
|
+
try {
|
|
4568
|
+
if (dict)
|
|
4569
|
+
return normalizeOptions(await ((_a = loaders.dictLoader) == null ? void 0 : _a.call(loaders, dict)));
|
|
4570
|
+
if (!source)
|
|
4571
|
+
return [];
|
|
4572
|
+
if (Array.isArray(source))
|
|
4573
|
+
return normalizeOptions(source);
|
|
4574
|
+
if (typeof source === "function")
|
|
4575
|
+
return normalizeOptions(await source());
|
|
4576
|
+
const shape = source;
|
|
4577
|
+
if (source.items)
|
|
4578
|
+
return normalizeOptions(source.items, shape);
|
|
4579
|
+
if (source.dict)
|
|
4580
|
+
return normalizeOptions(await ((_b = loaders.dictLoader) == null ? void 0 : _b.call(loaders, source.dict)), shape);
|
|
4581
|
+
if (source.ref)
|
|
4582
|
+
return normalizeOptions(await ((_c = loaders.optionsLoader) == null ? void 0 : _c.call(loaders, source.ref)), shape);
|
|
4583
|
+
if (source.load)
|
|
4584
|
+
return normalizeOptions(await source.load(), shape);
|
|
4585
|
+
} catch {
|
|
4586
|
+
}
|
|
4587
|
+
return [];
|
|
4588
|
+
}
|
|
4589
|
+
let _fnSeq = 0;
|
|
4590
|
+
const fnKeys = /* @__PURE__ */ new WeakMap();
|
|
4591
|
+
function fnKey(fn, prefix) {
|
|
4592
|
+
let k = fnKeys.get(fn);
|
|
4593
|
+
if (!k) {
|
|
4594
|
+
k = `${prefix}:${++_fnSeq}`;
|
|
4595
|
+
fnKeys.set(fn, k);
|
|
4596
|
+
}
|
|
4597
|
+
return k;
|
|
4598
|
+
}
|
|
4599
|
+
function sourceCacheKey(col) {
|
|
4600
|
+
if (col.dict)
|
|
4601
|
+
return "dict:" + col.dict;
|
|
4602
|
+
const s = col.options;
|
|
4603
|
+
if (!s)
|
|
4604
|
+
return null;
|
|
4605
|
+
if (Array.isArray(s))
|
|
4606
|
+
return "static:" + colIdOf(col);
|
|
4607
|
+
if (typeof s === "function")
|
|
4608
|
+
return fnKey(s, "fn");
|
|
4609
|
+
if (s.dict)
|
|
4610
|
+
return "dict:" + s.dict;
|
|
4611
|
+
if (s.ref)
|
|
4612
|
+
return "ref:" + s.ref;
|
|
4613
|
+
if (s.load)
|
|
4614
|
+
return fnKey(s.load, "load");
|
|
4615
|
+
if (s.items)
|
|
4616
|
+
return "static:" + colIdOf(col);
|
|
4617
|
+
return null;
|
|
4618
|
+
}
|
|
4619
|
+
function collectOptionCols(cols, out = []) {
|
|
4620
|
+
for (const c of cols || []) {
|
|
4621
|
+
if (c.dict || c.options)
|
|
4622
|
+
out.push(c);
|
|
4623
|
+
if (c.children && c.children.length)
|
|
4624
|
+
collectOptionCols(c.children, out);
|
|
4625
|
+
}
|
|
4626
|
+
return out;
|
|
4627
|
+
}
|
|
4509
4628
|
const NUM_OPS = [
|
|
4510
4629
|
{ k: "greater than or equal to", op: "gte" },
|
|
4511
4630
|
{ k: "more than or equal to", op: "gte" },
|
|
@@ -6184,6 +6303,7 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
|
|
|
6184
6303
|
emits: ["commit", "cancel"],
|
|
6185
6304
|
setup(__props, { emit: __emit }) {
|
|
6186
6305
|
const t = inject(RJ_LOCALE_KEY, defaultTranslate);
|
|
6306
|
+
const optionsAccessor = inject(RJ_OPTIONS_KEY, defaultOptionsAccessor);
|
|
6187
6307
|
const props = __props;
|
|
6188
6308
|
const emit = __emit;
|
|
6189
6309
|
const cfg = computed(() => {
|
|
@@ -6225,9 +6345,16 @@ const _sfc_main$g = /* @__PURE__ */ defineComponent({
|
|
|
6225
6345
|
);
|
|
6226
6346
|
const options = computed(() => {
|
|
6227
6347
|
const o = cfg.value.options;
|
|
6228
|
-
if (
|
|
6229
|
-
|
|
6230
|
-
|
|
6348
|
+
if (typeof o === "function") {
|
|
6349
|
+
const r = o(props.row);
|
|
6350
|
+
if (Array.isArray(r) && r.length)
|
|
6351
|
+
return r;
|
|
6352
|
+
} else if (Array.isArray(o) && o.length) {
|
|
6353
|
+
return o;
|
|
6354
|
+
}
|
|
6355
|
+
if (isSelectLike.value)
|
|
6356
|
+
return optionsAccessor.list(props.column) || [];
|
|
6357
|
+
return Array.isArray(o) ? o : [];
|
|
6231
6358
|
});
|
|
6232
6359
|
const filteredOptions = computed(() => {
|
|
6233
6360
|
if (!isSelectLike.value)
|
|
@@ -6962,6 +7089,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
|
6962
7089
|
setup(__props, { emit: __emit }) {
|
|
6963
7090
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
6964
7091
|
const t = inject(RJ_LOCALE_KEY, defaultTranslate);
|
|
7092
|
+
const optionsAccessor = inject(RJ_OPTIONS_KEY, defaultOptionsAccessor);
|
|
6965
7093
|
const props = __props;
|
|
6966
7094
|
const emit = __emit;
|
|
6967
7095
|
const ops = computed(() => FILTER_OPS[props.filterType] || []);
|
|
@@ -6993,7 +7121,7 @@ const _sfc_main$c = /* @__PURE__ */ defineComponent({
|
|
|
6993
7121
|
});
|
|
6994
7122
|
const displayOf = (v) => {
|
|
6995
7123
|
var _a2;
|
|
6996
|
-
return ((_a2 = props.column.filterValueMap) == null ? void 0 : _a2[v]) ?? v;
|
|
7124
|
+
return optionsAccessor.label(props.column, v) ?? ((_a2 = props.column.filterValueMap) == null ? void 0 : _a2[v]) ?? v;
|
|
6997
7125
|
};
|
|
6998
7126
|
const allChecked = computed(
|
|
6999
7127
|
() => options.value.length > 0 && values.value.length >= options.value.length
|
|
@@ -9701,12 +9829,67 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
9701
9829
|
queryFields: { default: () => [] },
|
|
9702
9830
|
queryActions: { default: () => [] },
|
|
9703
9831
|
rowForm: { type: [Object, Boolean], default: true },
|
|
9832
|
+
dictLoader: {},
|
|
9833
|
+
optionsLoader: {},
|
|
9704
9834
|
builtinViews: { default: () => [] }
|
|
9705
9835
|
},
|
|
9706
9836
|
emits: ["selection-change", "cell-click", "cell-dblclick", "cell-value-changed", "cells-changed", "sort-change", "filter-change", "row-group-change", "pivot-change", "page-change", "view-change", "detail-open", "row-drag-end", "row-form-submit", "row-form-add", "ready"],
|
|
9707
9837
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
9708
9838
|
var _a;
|
|
9709
9839
|
const props = __props;
|
|
9840
|
+
const optCache = reactive(/* @__PURE__ */ new Map());
|
|
9841
|
+
async function resolveAllOptions() {
|
|
9842
|
+
const pending = /* @__PURE__ */ new Map();
|
|
9843
|
+
for (const col of collectOptionCols(props.columns)) {
|
|
9844
|
+
const key = sourceCacheKey(col);
|
|
9845
|
+
if (!key || optCache.has(key) || pending.has(key))
|
|
9846
|
+
continue;
|
|
9847
|
+
pending.set(key, col);
|
|
9848
|
+
}
|
|
9849
|
+
await Promise.all(
|
|
9850
|
+
[...pending.entries()].map(async ([key, col]) => {
|
|
9851
|
+
const list = await resolveOptions(col.options, col.dict, {
|
|
9852
|
+
dictLoader: props.dictLoader,
|
|
9853
|
+
optionsLoader: props.optionsLoader
|
|
9854
|
+
});
|
|
9855
|
+
optCache.set(key, list);
|
|
9856
|
+
})
|
|
9857
|
+
);
|
|
9858
|
+
}
|
|
9859
|
+
const colOptionsIndex = computed(() => {
|
|
9860
|
+
const m = /* @__PURE__ */ new Map();
|
|
9861
|
+
for (const col of collectOptionCols(props.columns)) {
|
|
9862
|
+
const key = sourceCacheKey(col);
|
|
9863
|
+
const list = key ? optCache.get(key) : void 0;
|
|
9864
|
+
if (!list || !list.length)
|
|
9865
|
+
continue;
|
|
9866
|
+
const labelMap = /* @__PURE__ */ new Map();
|
|
9867
|
+
for (const o of list)
|
|
9868
|
+
labelMap.set(String(o.value), String(o.label));
|
|
9869
|
+
m.set(colIdOf(col), { list, labelMap });
|
|
9870
|
+
}
|
|
9871
|
+
return m;
|
|
9872
|
+
});
|
|
9873
|
+
function colOptionList(col) {
|
|
9874
|
+
var _a2;
|
|
9875
|
+
return (_a2 = colOptionsIndex.value.get(colIdOf(col))) == null ? void 0 : _a2.list;
|
|
9876
|
+
}
|
|
9877
|
+
function colOptionLabel(col, value) {
|
|
9878
|
+
var _a2;
|
|
9879
|
+
if (value == null || value === "")
|
|
9880
|
+
return void 0;
|
|
9881
|
+
return (_a2 = colOptionsIndex.value.get(colIdOf(col))) == null ? void 0 : _a2.labelMap.get(String(value));
|
|
9882
|
+
}
|
|
9883
|
+
provide(RJ_OPTIONS_KEY, { list: colOptionList, label: colOptionLabel });
|
|
9884
|
+
onMounted(() => {
|
|
9885
|
+
void resolveAllOptions();
|
|
9886
|
+
});
|
|
9887
|
+
watch(
|
|
9888
|
+
() => props.columns,
|
|
9889
|
+
() => {
|
|
9890
|
+
void resolveAllOptions();
|
|
9891
|
+
}
|
|
9892
|
+
);
|
|
9710
9893
|
const emit = __emit;
|
|
9711
9894
|
const busListeners = /* @__PURE__ */ new Map();
|
|
9712
9895
|
function addEventListener(type, cb) {
|
|
@@ -10588,11 +10771,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
10588
10771
|
const type = rowModel.filterTypeOf(col);
|
|
10589
10772
|
let unique = [];
|
|
10590
10773
|
if (type === "select") {
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
|
|
10774
|
+
const optList = colOptionList(col);
|
|
10775
|
+
if (optList && optList.length) {
|
|
10776
|
+
unique = optList.map((o) => String(o.value));
|
|
10777
|
+
} else {
|
|
10778
|
+
unique = Array.from(
|
|
10779
|
+
new Set(
|
|
10780
|
+
rowModel.sourceRows().slice(0, 5e3).map((r) => cellRawValue(col, r)).filter((v) => v != null)
|
|
10781
|
+
)
|
|
10782
|
+
).map(String);
|
|
10783
|
+
}
|
|
10596
10784
|
}
|
|
10597
10785
|
const targetRect = el.target.getBoundingClientRect();
|
|
10598
10786
|
const rootRect = (_a2 = rootRef.value) == null ? void 0 : _a2.getBoundingClientRect();
|
|
@@ -11090,6 +11278,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
11090
11278
|
return formatByType(col, value, BOOL_LABELS.value);
|
|
11091
11279
|
return s;
|
|
11092
11280
|
}
|
|
11281
|
+
const lab = colOptionLabel(col, value);
|
|
11282
|
+
if (lab != null)
|
|
11283
|
+
return lab;
|
|
11093
11284
|
return formatByType(col, value, BOOL_LABELS.value);
|
|
11094
11285
|
}
|
|
11095
11286
|
function coveredByRowSpan(rows, i, leaf) {
|
|
@@ -12154,11 +12345,16 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12154
12345
|
const type = rowModel.filterTypeOf(col);
|
|
12155
12346
|
let unique = [];
|
|
12156
12347
|
if (type === "select") {
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
|
|
12161
|
-
|
|
12348
|
+
const optList = colOptionList(col);
|
|
12349
|
+
if (optList && optList.length) {
|
|
12350
|
+
unique = optList.map((o) => String(o.value));
|
|
12351
|
+
} else {
|
|
12352
|
+
unique = Array.from(
|
|
12353
|
+
new Set(
|
|
12354
|
+
rowModel.sourceRows().slice(0, 5e3).map((r) => cellRawValue(col, r)).filter((v) => v != null)
|
|
12355
|
+
)
|
|
12356
|
+
).map(String);
|
|
12357
|
+
}
|
|
12162
12358
|
}
|
|
12163
12359
|
const ss = rowModel.sortStates.value.find((x) => x.field === colId || x.field === col.field);
|
|
12164
12360
|
colMenu.value = {
|
|
@@ -12774,10 +12970,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
12774
12970
|
filterType = "select";
|
|
12775
12971
|
let options;
|
|
12776
12972
|
let strictOptions = false;
|
|
12973
|
+
const resolvedOpts = colOptionList(col);
|
|
12777
12974
|
if (Array.isArray(eo) && eo.length) {
|
|
12778
12975
|
filterType = "select";
|
|
12779
12976
|
options = eo.map((o) => String((o == null ? void 0 : o.label) ?? (o == null ? void 0 : o.value) ?? o));
|
|
12780
12977
|
strictOptions = true;
|
|
12978
|
+
} else if (resolvedOpts && resolvedOpts.length) {
|
|
12979
|
+
filterType = "select";
|
|
12980
|
+
options = resolvedOpts.map((o) => String(o.label ?? o.value));
|
|
12981
|
+
strictOptions = true;
|
|
12781
12982
|
} else if (filterType === "select") {
|
|
12782
12983
|
const set = /* @__PURE__ */ new Set();
|
|
12783
12984
|
for (const r of src) {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import RjGrid from './src/RjGrid.vue';
|
|
2
2
|
export { RjGrid };
|
|
3
|
-
export type { RjColumn, RjRowData, RjCellParams, RjGridApi, RjGridState, RjDataMode, RjLoadServerParams, RjLoadServerResult, RjFilterModel, RjFilterCondition, RjFilterType, RjSortState, RjSortDir, RjFixed, RjMenuItem, RjMenuContext, RjCellEventParams, RjSelectionEventParams, RjPinnedRow, RjFindMatch, RjEditorType, RjEditorConfig, RjEditorOption, RjImageConfig, RjSparklineConfig, RjColStateItem, RjColumnFilterState, RjExportScope, RjExportScopeResolved, RjServerExportParams, RjTransaction, RjExportParams, RjPrintOptions, RjPrintParams, RjAgg, RjAggFunc, RjAggCustom, RjQueryCondition, RjQueryFieldDef, RjQueryFieldKind, RjQueryOperator, RjQueryAction, RjQueryActionCtx, RjRowFormConfig, RjSavedView } from './src/types';
|
|
3
|
+
export type { RjColumn, RjRowData, RjCellParams, RjGridApi, RjGridState, RjDataMode, RjLoadServerParams, RjLoadServerResult, RjFilterModel, RjFilterCondition, RjFilterType, RjSortState, RjSortDir, RjFixed, RjMenuItem, RjMenuContext, RjCellEventParams, RjSelectionEventParams, RjPinnedRow, RjFindMatch, RjEditorType, RjEditorConfig, RjEditorOption, RjOptionSource, RjImageConfig, RjSparklineConfig, RjColStateItem, RjColumnFilterState, RjExportScope, RjExportScopeResolved, RjServerExportParams, RjTransaction, RjExportParams, RjPrintOptions, RjPrintParams, RjAgg, RjAggFunc, RjAggCustom, RjQueryCondition, RjQueryFieldDef, RjQueryFieldKind, RjQueryOperator, RjQueryAction, RjQueryActionCtx, RjRowFormConfig, RjSavedView } from './src/types';
|
|
4
4
|
export type { RjThemeParams } from './src/theme';
|
|
5
5
|
export type { RjIconName, RjIcons, RjIconsOverride } from './src/icons';
|
|
6
6
|
export { deriveQueryFields, queryOpsOfKind, defaultQueryOperator, matchQueryValue } from './src/query';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import './styles/rj-grid.scss';
|
|
2
|
-
import type { RjCellParams, RjColumn, RjDataMode, RjExportScopeResolved, RjFilterModel, RjGridState, RjLoadServerParams, RjMenuItem, RjPrintParams, RjRowData, RjServerExportParams, RjSortState, RjTransaction, RjQueryAction, RjQueryFieldDef, RjRowFormConfig, RjSavedView } from './types';
|
|
2
|
+
import type { RjCellParams, RjColumn, RjDataMode, RjEditorOption, RjExportScopeResolved, RjFilterModel, RjGridState, RjLoadServerParams, RjMenuItem, RjPrintParams, RjRowData, RjServerExportParams, RjSortState, RjTransaction, RjQueryAction, RjQueryFieldDef, RjRowFormConfig, RjSavedView } from './types';
|
|
3
3
|
import { type RjDisplayRow } from './useRowModel';
|
|
4
4
|
import { type RjThemeParams } from './theme';
|
|
5
5
|
import { type RjMessages } from './locale';
|
|
@@ -129,6 +129,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<im
|
|
|
129
129
|
queryActions?: RjQueryAction[] | undefined;
|
|
130
130
|
/** 内置行编辑/新增弹窗:false 关闭 openRowForm/openRowFormAdd 能力;对象可配 title/width/columns 与 addTitle/addColumns */
|
|
131
131
|
rowForm?: boolean | RjRowFormConfig | undefined;
|
|
132
|
+
/** 网格级字典加载器:列上 dict:'x'(或 options:{dict:'x'})时调用,返回 {label,value}[] 或原始数组(异步可) */
|
|
133
|
+
dictLoader?: ((key: string) => RjEditorOption[] | Promise<RjEditorOption[]>) | undefined;
|
|
134
|
+
/** 网格级命名源加载器:列上 options:{ref:'name'} 时调用,返回接口原始数组(异步可),字段归一交给列上的 labelKey/valueKey/map */
|
|
135
|
+
optionsLoader?: ((name: string) => unknown[] | Promise<unknown[]>) | undefined;
|
|
132
136
|
/** 内置视图(只读,恒排在自建视图前) */
|
|
133
137
|
builtinViews?: RjSavedView[] | undefined;
|
|
134
138
|
}>, {
|
|
@@ -332,6 +336,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<im
|
|
|
332
336
|
queryActions?: RjQueryAction[] | undefined;
|
|
333
337
|
/** 内置行编辑/新增弹窗:false 关闭 openRowForm/openRowFormAdd 能力;对象可配 title/width/columns 与 addTitle/addColumns */
|
|
334
338
|
rowForm?: boolean | RjRowFormConfig | undefined;
|
|
339
|
+
/** 网格级字典加载器:列上 dict:'x'(或 options:{dict:'x'})时调用,返回 {label,value}[] 或原始数组(异步可) */
|
|
340
|
+
dictLoader?: ((key: string) => RjEditorOption[] | Promise<RjEditorOption[]>) | undefined;
|
|
341
|
+
/** 网格级命名源加载器:列上 options:{ref:'name'} 时调用,返回接口原始数组(异步可),字段归一交给列上的 labelKey/valueKey/map */
|
|
342
|
+
optionsLoader?: ((name: string) => unknown[] | Promise<unknown[]>) | undefined;
|
|
335
343
|
/** 内置视图(只读,恒排在自建视图前) */
|
|
336
344
|
builtinViews?: RjSavedView[] | undefined;
|
|
337
345
|
}>, {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { InjectionKey } from 'vue';
|
|
2
|
+
import type { RjColumn, RjEditorOption, RjOptionSource } from './types';
|
|
3
|
+
/** 列字段归一选项(对象式源携带 map/labelKey/valueKey/childrenKey 时生效) */
|
|
4
|
+
interface RjOptionShape {
|
|
5
|
+
map?: (item: any) => RjEditorOption;
|
|
6
|
+
labelKey?: string;
|
|
7
|
+
valueKey?: string;
|
|
8
|
+
childrenKey?: string;
|
|
9
|
+
}
|
|
10
|
+
/** 网格注入给子组件(RjEditor / RjFilterMenu)的只读访问器 */
|
|
11
|
+
export interface RjOptionsAccessor {
|
|
12
|
+
/** 该列解析出的候选;未就绪或未声明时 undefined */
|
|
13
|
+
list: (col: RjColumn) => RjEditorOption[] | undefined;
|
|
14
|
+
/** 该列 value→label;未命中时 undefined */
|
|
15
|
+
label: (col: RjColumn, value: any) => string | undefined;
|
|
16
|
+
}
|
|
17
|
+
/** 注入键:网格根 provide 访问器,子组件 inject 消费(仿 RJ_LOCALE_KEY / RJ_ICONS_KEY) */
|
|
18
|
+
export declare const RJ_OPTIONS_KEY: InjectionKey<RjOptionsAccessor>;
|
|
19
|
+
/** 子组件默认访问器(单独使用、未 inject 到时回退,全部返回 undefined 不影响原行为) */
|
|
20
|
+
export declare const defaultOptionsAccessor: RjOptionsAccessor;
|
|
21
|
+
/**
|
|
22
|
+
* 把任意接口返回归一成 RjEditorOption[]:
|
|
23
|
+
* - map 命中优先(完全自定义);
|
|
24
|
+
* - 否则按 labelKey/valueKey(或默认字段)取;
|
|
25
|
+
* - childrenKey(默认 'children')命中数组即递归拍平(depth 缩进不写进 label,保持干净 value→label 表)。
|
|
26
|
+
*/
|
|
27
|
+
export declare function normalizeOptions(raw: unknown, shape?: RjOptionShape): RjEditorOption[];
|
|
28
|
+
/** 解析选项源所需的网格级加载器 */
|
|
29
|
+
export interface RjOptionLoaders {
|
|
30
|
+
dictLoader?: (key: string) => unknown | Promise<unknown>;
|
|
31
|
+
optionsLoader?: (name: string) => unknown | Promise<unknown>;
|
|
32
|
+
}
|
|
33
|
+
/** 解析一个列的选项源为候选数组(异步;失败静默回落空数组 → 显示原样回落原始值) */
|
|
34
|
+
export declare function resolveOptions(source: RjOptionSource | undefined, dict: string | undefined, loaders: RjOptionLoaders): Promise<RjEditorOption[]>;
|
|
35
|
+
/**
|
|
36
|
+
* 计算列选项源的缓存键:dict/ref 按 key 归并(两列同字典只加载一次),
|
|
37
|
+
* 静态数组 / 函数按列或函数身份。返回 null 表示该列无选项载体。
|
|
38
|
+
*/
|
|
39
|
+
export declare function sourceCacheKey(col: RjColumn): string | null;
|
|
40
|
+
/** 递归收集声明了 options/dict 的列(含多级表头子列) */
|
|
41
|
+
export declare function collectOptionCols(cols: RjColumn[], out?: RjColumn[]): RjColumn[];
|
|
42
|
+
export {};
|
|
@@ -109,6 +109,28 @@ export interface RjEditorOption {
|
|
|
109
109
|
label: string;
|
|
110
110
|
value: any;
|
|
111
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* 统一选项载体:一份数据源同时驱动 显示(value→label) / select 筛选候选 / select 编辑器 / NLQ 枚举。
|
|
114
|
+
* 数组=静态候选;函数=工厂(可同步/异步,网格级按列只解析一次);对象=按 load/ref/dict 取数,
|
|
115
|
+
* 再用 map 或 labelKey/valueKey 归一,childrenKey(默认 'children')命中即递归拍平树(label 不加缩进)。
|
|
116
|
+
*/
|
|
117
|
+
export type RjOptionSource = RjEditorOption[] | ((row?: RjRowData) => RjEditorOption[] | Promise<RjEditorOption[]>) | {
|
|
118
|
+
/** 静态候选(对象式) */
|
|
119
|
+
items?: RjEditorOption[];
|
|
120
|
+
/** 宿主直接给的接口函数(返回原始数组,交给 labelKey/valueKey/map 归一) */
|
|
121
|
+
load?: () => unknown[] | Promise<unknown[]>;
|
|
122
|
+
/** 命名源:交网格级 optionsLoader(name) 解析 */
|
|
123
|
+
ref?: string;
|
|
124
|
+
/** 字典 key:交网格级 dictLoader(key) 解析 */
|
|
125
|
+
dict?: string;
|
|
126
|
+
/** 自定义映射:接口单项 → {label,value} */
|
|
127
|
+
map?: (item: any) => RjEditorOption;
|
|
128
|
+
/** 字段映射(默认 label/name → label,value/id/code → value) */
|
|
129
|
+
labelKey?: string;
|
|
130
|
+
valueKey?: string;
|
|
131
|
+
/** 传入即递归拍平树(默认 'children') */
|
|
132
|
+
childrenKey?: string;
|
|
133
|
+
};
|
|
112
134
|
/** 编辑器配置 */
|
|
113
135
|
export interface RjEditorConfig {
|
|
114
136
|
type?: RjEditorType;
|
|
@@ -223,6 +245,13 @@ export interface RjColumn<T = RjRowData> {
|
|
|
223
245
|
headerComponent?: any;
|
|
224
246
|
editable?: boolean | ((row: T) => boolean);
|
|
225
247
|
editor?: RjEditorConfig | RjEditorType;
|
|
248
|
+
/**
|
|
249
|
+
* 统一选项载体:一处声明同时喂给 显示 / select 筛选 / select 编辑器 / NLQ(异步自动加载 + 按源缓存)。
|
|
250
|
+
* 向后兼容:显式 col.formatter / editor.options / filterValueMap 一律优先,本载体仅在其缺位时填充。
|
|
251
|
+
*/
|
|
252
|
+
options?: RjOptionSource;
|
|
253
|
+
/** options 的糖:等价 options:{dict},走网格级 dictLoader 按字典 key 取候选 */
|
|
254
|
+
dict?: string;
|
|
226
255
|
/** 编辑值新旧合并钩子 */
|
|
227
256
|
onCellValueChanged?: (params: {
|
|
228
257
|
newValue: any;
|