@object-ui/core 13.1.0 → 14.0.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/CHANGELOG.md +28 -0
- package/dist/actions/ActionRunner.d.ts +8 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/utils/export-filename.d.ts +36 -0
- package/dist/utils/export-filename.js +50 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @object-ui/core
|
|
2
2
|
|
|
3
|
+
## 14.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 443360a: Action params support a `visible` CEL predicate — the param dialog omits a param
|
|
8
|
+
when it evaluates false, against the same scope as action `visible` (features /
|
|
9
|
+
user / app / data). Fixes the create-user form offering a **Phone Number** field
|
|
10
|
+
the default backend rejects ("Phone numbers require the phoneNumber auth plugin"):
|
|
11
|
+
paired with the framework gating that param on `features.phoneNumber`, the form
|
|
12
|
+
now follows the plugin — no phone field unless the opt-in phoneNumber auth plugin
|
|
13
|
+
is loaded. `filterVisibleParams` is exported + unit-tested (feature-off hides,
|
|
14
|
+
feature-on shows, malformed predicate fails open).
|
|
15
|
+
- 05e56ca: 导出/导入模板的下载文件名与内容本地化。
|
|
16
|
+
|
|
17
|
+
**导出文件名**:CSV/Excel/JSON 导出下载不再是 `<对象名>.<扩展名>`(如 `contracts.csv`),改为「对象显示名-视图名-时间戳.扩展名」(如 `任务-In Progress-20260714-153045.xlsx`);`exportOptions.fileNamePrefix` 配置仍优先(且作为完整前缀,不再追加视图名)。视图名与对象名重复时自动省略;`@object-ui/core` 新增 `buildExportFileName(ext, { prefix, label, objectName, viewLabel }, now?)` 与 `sanitizeFileNameBase(raw)`,ObjectGrid 与 ListView 的所有导出路径(服务端流式与前端兜底)统一走它。app-shell/plugin-view 的 ObjectView 现将当前视图的显示标签写进传给 ListView 的 schema(`label`),使导出文件名能区分同一对象的不同保存视图。
|
|
18
|
+
|
|
19
|
+
**导入模板**:「下载模板」修复两处英文漏出——示例行的 select/多选取值改为优先取选项**显示标签**(如 `准备中`)而非 ASCII slug(`prepare`,服务端导入两者都接受);模板文件名本地化为 `{{object}}-导入模板.csv`(新增 i18n key `grid.import.templateFileName`,英文回退 `{{object}}-import-template.csv`)。
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [86c69c3]
|
|
22
|
+
- Updated dependencies [6a74160]
|
|
23
|
+
- @object-ui/types@14.0.0
|
|
24
|
+
|
|
25
|
+
## 13.2.0
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- @object-ui/types@13.2.0
|
|
30
|
+
|
|
3
31
|
## 13.1.0
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
|
@@ -250,6 +250,14 @@ export interface ActionParamDef {
|
|
|
250
250
|
helpText?: string;
|
|
251
251
|
placeholder?: string;
|
|
252
252
|
validation?: string;
|
|
253
|
+
/**
|
|
254
|
+
* Visibility predicate (CEL) evaluated against the same scope as action
|
|
255
|
+
* `visible` (`current_user` / `app` / `data` / `features`). When it evaluates
|
|
256
|
+
* false the param dialog omits this param — used to hide a param the backend
|
|
257
|
+
* only accepts under an opt-in capability (e.g. `create_user.phoneNumber`
|
|
258
|
+
* gated on `features.phoneNumber`). Absent = always visible.
|
|
259
|
+
*/
|
|
260
|
+
visible?: string;
|
|
253
261
|
/** Object name the lookup picker queries (`reference_to` on the field). */
|
|
254
262
|
referenceTo?: string;
|
|
255
263
|
/** Field on the referenced record used as the human label (default `name`). */
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Download filename builder for data exports (csv / xlsx / json).
|
|
3
|
+
*
|
|
4
|
+
* Exports used to download as `<objectApiName>.<ext>` (e.g. `contracts.csv`),
|
|
5
|
+
* which reads poorly for end users and silently collides in the Downloads
|
|
6
|
+
* folder. This builds `<base>-<YYYYMMDD>-<HHMMSS>.<ext>` where the base falls
|
|
7
|
+
* back through: explicit configured prefix (`exportOptions.fileNamePrefix`) →
|
|
8
|
+
* translated object label (e.g. 合同) → object API name → 'export'.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Sanitize a candidate base name for cross-platform filesystem safety while
|
|
12
|
+
* keeping non-ASCII letters (e.g. Chinese object labels) intact. Returns an
|
|
13
|
+
* empty string when nothing usable survives, so callers can fall through.
|
|
14
|
+
*/
|
|
15
|
+
export declare function sanitizeFileNameBase(raw: string | undefined | null): string;
|
|
16
|
+
export interface ExportFileNameParts {
|
|
17
|
+
/** Explicit prefix from view config (`exportOptions.fileNamePrefix`) — wins when set. */
|
|
18
|
+
prefix?: string;
|
|
19
|
+
/** Human-readable (translated) object label — the preferred base. */
|
|
20
|
+
label?: string;
|
|
21
|
+
/** Object API name — fallback when no label is available. */
|
|
22
|
+
objectName?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Active list-view label (e.g. `In Progress`), appended after the object
|
|
25
|
+
* base so exports from different saved views don't read identically.
|
|
26
|
+
* Skipped when it duplicates the base, and not appended to an explicit
|
|
27
|
+
* `prefix` (configured prefixes are authoritative as-is).
|
|
28
|
+
*/
|
|
29
|
+
viewLabel?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build `<base>-<YYYYMMDD>-<HHMMSS>.<ext>` in the user's local time, e.g.
|
|
33
|
+
* `合同-进行中-20260714-153045.xlsx`. The timestamp keeps repeated exports of
|
|
34
|
+
* the same object distinct and sortable.
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildExportFileName(ext: string, parts?: ExportFileNameParts, now?: Date): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Download filename builder for data exports (csv / xlsx / json).
|
|
3
|
+
*
|
|
4
|
+
* Exports used to download as `<objectApiName>.<ext>` (e.g. `contracts.csv`),
|
|
5
|
+
* which reads poorly for end users and silently collides in the Downloads
|
|
6
|
+
* folder. This builds `<base>-<YYYYMMDD>-<HHMMSS>.<ext>` where the base falls
|
|
7
|
+
* back through: explicit configured prefix (`exportOptions.fileNamePrefix`) →
|
|
8
|
+
* translated object label (e.g. 合同) → object API name → 'export'.
|
|
9
|
+
*/
|
|
10
|
+
/** Windows-reserved + control characters that cannot appear in a filename. */
|
|
11
|
+
const ILLEGAL_FILENAME_CHARS = /[\\\/:*?"<>|\u0000-\u001f]+/g;
|
|
12
|
+
/** Longest base we emit — keeps the full name comfortably under OS limits. */
|
|
13
|
+
const MAX_BASE_LENGTH = 80;
|
|
14
|
+
/**
|
|
15
|
+
* Sanitize a candidate base name for cross-platform filesystem safety while
|
|
16
|
+
* keeping non-ASCII letters (e.g. Chinese object labels) intact. Returns an
|
|
17
|
+
* empty string when nothing usable survives, so callers can fall through.
|
|
18
|
+
*/
|
|
19
|
+
export function sanitizeFileNameBase(raw) {
|
|
20
|
+
if (!raw)
|
|
21
|
+
return '';
|
|
22
|
+
return String(raw)
|
|
23
|
+
.replace(ILLEGAL_FILENAME_CHARS, '_')
|
|
24
|
+
.replace(/\s+/g, ' ')
|
|
25
|
+
.replace(/_{2,}/g, '_')
|
|
26
|
+
// Leading/trailing dots, underscores and spaces are dropped: Windows
|
|
27
|
+
// strips trailing dots/spaces, and a leading dot hides the file on unix.
|
|
28
|
+
.replace(/^[\s._-]+|[\s._-]+$/g, '')
|
|
29
|
+
.slice(0, MAX_BASE_LENGTH);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build `<base>-<YYYYMMDD>-<HHMMSS>.<ext>` in the user's local time, e.g.
|
|
33
|
+
* `合同-进行中-20260714-153045.xlsx`. The timestamp keeps repeated exports of
|
|
34
|
+
* the same object distinct and sortable.
|
|
35
|
+
*/
|
|
36
|
+
export function buildExportFileName(ext, parts = {}, now = new Date()) {
|
|
37
|
+
const prefix = sanitizeFileNameBase(parts.prefix);
|
|
38
|
+
let base = prefix ||
|
|
39
|
+
sanitizeFileNameBase(parts.label) ||
|
|
40
|
+
sanitizeFileNameBase(parts.objectName) ||
|
|
41
|
+
'export';
|
|
42
|
+
const view = sanitizeFileNameBase(parts.viewLabel);
|
|
43
|
+
if (!prefix && view && view.toLowerCase() !== base.toLowerCase()) {
|
|
44
|
+
base = `${base}-${view}`.slice(0, MAX_BASE_LENGTH);
|
|
45
|
+
}
|
|
46
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
47
|
+
const stamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}` +
|
|
48
|
+
`-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
|
|
49
|
+
return `${base}-${stamp}.${ext}`;
|
|
50
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@objectstack/formula": "^
|
|
29
|
-
"@objectstack/spec": "^
|
|
28
|
+
"@objectstack/formula": "^14.6.0",
|
|
29
|
+
"@objectstack/spec": "^14.6.0",
|
|
30
30
|
"lodash": "^4.18.1",
|
|
31
31
|
"zod": "^4.4.3",
|
|
32
|
-
"@object-ui/types": "
|
|
32
|
+
"@object-ui/types": "14.0.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"typescript": "^6.0.3",
|