@yuneta/gobj-ui 7.23.169 → 7.23.170
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/dist/gobj-ui.cjs.js +394 -386
- package/dist/gobj-ui.es.js +394 -386
- package/package.json +2 -2
- package/src/c_yui_treedb_topic_with_form.js +5 -39
- package/src/treedb_write_plan.js +47 -1
- package/src/treedb_write_plan.test.js +53 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuneta/gobj-ui",
|
|
3
|
-
"version": "7.23.
|
|
3
|
+
"version": "7.23.170",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/gobj-ui.cjs.js",
|
|
6
6
|
"module": "dist/gobj-ui.es.js",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@rollup/plugin-terser": "^1.0.0",
|
|
32
32
|
"@vitest/coverage-v8": "^4.1.10",
|
|
33
|
-
"@yuneta/gobj-js": "^7.
|
|
33
|
+
"@yuneta/gobj-js": "^7.21.0",
|
|
34
34
|
"vite": "^8.2.1",
|
|
35
35
|
"vitest": "^4.1.10"
|
|
36
36
|
},
|
|
@@ -96,7 +96,9 @@ import {t} from "i18next";
|
|
|
96
96
|
|
|
97
97
|
import {yui_toolbar_icon} from "./yui_toolbar.js";
|
|
98
98
|
|
|
99
|
-
import {
|
|
99
|
+
import {
|
|
100
|
+
plan_treedb_writes, READONLY_FORM_TOOLBAR, col_goes_back_to_treedb
|
|
101
|
+
} from "./treedb_write_plan.js";
|
|
100
102
|
import {
|
|
101
103
|
yui_file_read, yui_files_manifest, yui_file_id_label, yui_file_size_label
|
|
102
104
|
} from "./yui_file_field.js";
|
|
@@ -3262,42 +3264,6 @@ function get_schema_col(gobj, id)
|
|
|
3262
3264
|
return null;
|
|
3263
3265
|
}
|
|
3264
3266
|
|
|
3265
|
-
/************************************************************
|
|
3266
|
-
* Does column `col` travel back to treedb on a write?
|
|
3267
|
-
*
|
|
3268
|
-
* The form SHOWS every field and sends back only what the topic
|
|
3269
|
-
* accepts: the writable cols, the fkeys (a link is edited by
|
|
3270
|
-
* linking) and the pkey, which is not written but is what
|
|
3271
|
-
* ADDRESSES the record.
|
|
3272
|
-
*
|
|
3273
|
-
* It matters because `treedb_update_node()` does not check
|
|
3274
|
-
* `writable` -- it writes any col it is handed -- so a read-only
|
|
3275
|
-
* field travelling back is written with whatever the form made of
|
|
3276
|
-
* it, and the fields that describe a record are exactly the ones
|
|
3277
|
-
* that do not survive a round trip through a widget: a `time` is an
|
|
3278
|
-
* integer rendered as a `datetime-local`, with no seconds, so every
|
|
3279
|
-
* save moved it back up to 59 s. Nothing looked wrong until the
|
|
3280
|
-
* stored timestamp had moved.
|
|
3281
|
-
*
|
|
3282
|
-
* `is_file` and not the type: a `file` column IS an fkey (it is
|
|
3283
|
-
* flagged ['fkey','file']) but answers `type: "file"`, and the write
|
|
3284
|
-
* goes out with `autolink`, which rebuilds the links from what the
|
|
3285
|
-
* record carries. Dropped, a read-only `file` column -- the one only
|
|
3286
|
-
* a load fills -- was UNLINKED by every save of any other field.
|
|
3287
|
-
************************************************************/
|
|
3288
|
-
function col_goes_back_to_treedb(gobj, col)
|
|
3289
|
-
{
|
|
3290
|
-
let desc = gobj_read_attr(gobj, "desc");
|
|
3291
|
-
let pkey = desc.pkey || "id";
|
|
3292
|
-
const field_desc = treedb_get_field_desc(col);
|
|
3293
|
-
|
|
3294
|
-
if(field_desc.is_writable || field_desc.type === "fkey" ||
|
|
3295
|
-
field_desc.is_file || col.id === pkey) {
|
|
3296
|
-
return true;
|
|
3297
|
-
}
|
|
3298
|
-
return false;
|
|
3299
|
-
}
|
|
3300
|
-
|
|
3301
3267
|
/************************************************************
|
|
3302
3268
|
* The record the FORM hands over, without the columns that do
|
|
3303
3269
|
* not go back to treedb (see col_goes_back_to_treedb()). The
|
|
@@ -3309,7 +3275,7 @@ function strip_read_only_cols(gobj, record)
|
|
|
3309
3275
|
let row = {};
|
|
3310
3276
|
for(let field_name of Object.keys(record || {})) {
|
|
3311
3277
|
let col = get_schema_col(gobj, field_name);
|
|
3312
|
-
if(col && !col_goes_back_to_treedb(gobj, col)) {
|
|
3278
|
+
if(col && !col_goes_back_to_treedb(gobj_read_attr(gobj, "desc"), col)) {
|
|
3313
3279
|
continue;
|
|
3314
3280
|
}
|
|
3315
3281
|
row[field_name] = record[field_name];
|
|
@@ -3336,7 +3302,7 @@ function transform__form_record_2_treedb_record(gobj, kw, operation)
|
|
|
3336
3302
|
continue;
|
|
3337
3303
|
}
|
|
3338
3304
|
|
|
3339
|
-
if(!col_goes_back_to_treedb(gobj, col)) {
|
|
3305
|
+
if(!col_goes_back_to_treedb(gobj_read_attr(gobj, "desc"), col)) {
|
|
3340
3306
|
continue;
|
|
3341
3307
|
}
|
|
3342
3308
|
|
package/src/treedb_write_plan.js
CHANGED
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
* All Rights Reserved.
|
|
20
20
|
***********************************************************************/
|
|
21
21
|
|
|
22
|
+
import {treedb_get_field_desc} from "@yuneta/gobj-js";
|
|
23
|
+
import {topic_pkey2s} from "./schema_model.js";
|
|
24
|
+
|
|
22
25
|
/* What a read-only form keeps: reading a record includes taking it with
|
|
23
26
|
* you, so `copy` stays and the write half goes. */
|
|
24
27
|
const READONLY_FORM_TOOLBAR = ["copy"];
|
|
@@ -70,4 +73,47 @@ function plan_treedb_writes(flags)
|
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
|
|
73
|
-
|
|
76
|
+
/************************************************************
|
|
77
|
+
* Does column `col` travel back to treedb on a write?
|
|
78
|
+
*
|
|
79
|
+
* The form SHOWS every field and sends back only what the topic
|
|
80
|
+
* accepts: the writable cols, the fkeys (a link is edited by
|
|
81
|
+
* linking) and the pkey, which is not written but is what
|
|
82
|
+
* ADDRESSES the record.
|
|
83
|
+
*
|
|
84
|
+
* It matters because `treedb_update_node()` does not check
|
|
85
|
+
* `writable` -- it writes any col it is handed -- so a read-only
|
|
86
|
+
* field travelling back is written with whatever the form made of
|
|
87
|
+
* it, and the fields that describe a record are exactly the ones
|
|
88
|
+
* that do not survive a round trip through a widget: a `time` is an
|
|
89
|
+
* integer rendered as a `datetime-local`, with no seconds, so every
|
|
90
|
+
* save moved it back up to 59 s. Nothing looked wrong until the
|
|
91
|
+
* stored timestamp had moved.
|
|
92
|
+
*
|
|
93
|
+
* `is_file` and not the type: a `file` column IS an fkey (it is
|
|
94
|
+
* flagged ['fkey','file']) but answers `type: "file"`, and the write
|
|
95
|
+
* goes out with `autolink`, which rebuilds the links from what the
|
|
96
|
+
* record carries. Dropped, a read-only `file` column -- the one only
|
|
97
|
+
* a load fills -- was UNLINKED by every save of any other field.
|
|
98
|
+
*
|
|
99
|
+
* The pkey2s go back for the same reason as the pkey: a secondary key
|
|
100
|
+
* names the INSTANCE the update is for (`yunos.yuno_release` in the
|
|
101
|
+
* agent), and it is `persistent, required`, not `writable`. Dropped,
|
|
102
|
+
* the update reached the backend with no pkey2 and C_NODE resolved it
|
|
103
|
+
* to the PRIMARY instance -- right by chance while the table lists
|
|
104
|
+
* primaries, wrong from a form opened on a row of `instances`.
|
|
105
|
+
************************************************************/
|
|
106
|
+
function col_goes_back_to_treedb(desc, col)
|
|
107
|
+
{
|
|
108
|
+
let d = desc || {};
|
|
109
|
+
let pkey = d.pkey || "id";
|
|
110
|
+
const field_desc = treedb_get_field_desc(col);
|
|
111
|
+
|
|
112
|
+
if(field_desc.is_writable || field_desc.type === "fkey" ||
|
|
113
|
+
field_desc.is_file || col.id === pkey) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return topic_pkey2s(d).includes(col.id);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export {plan_treedb_writes, READONLY_FORM_TOOLBAR, col_goes_back_to_treedb};
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
* affordance back by accident.
|
|
9
9
|
***********************************************************************/
|
|
10
10
|
import { describe, test, expect } from "vitest";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
plan_treedb_writes, READONLY_FORM_TOOLBAR, col_goes_back_to_treedb
|
|
13
|
+
} from "./treedb_write_plan.js";
|
|
12
14
|
|
|
13
15
|
const WRITES = ["edition_mode", "new_button", "delete_button", "paste_button", "in_row_icons"];
|
|
14
16
|
|
|
@@ -81,3 +83,53 @@ describe("readonly beats every with_*", () => {
|
|
|
81
83
|
expect(plan_treedb_writes({readonly: "yes"}).new_button).toBe(false);
|
|
82
84
|
});
|
|
83
85
|
});
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
/***********************************************************************
|
|
89
|
+
* Which columns of a form go back in the write. The shape is the
|
|
90
|
+
* agent's `yunos`: a pkey, a secondary key that is required but not
|
|
91
|
+
* writable, and the read-only columns that never survive a widget.
|
|
92
|
+
***********************************************************************/
|
|
93
|
+
const YUNOS_DESC = {
|
|
94
|
+
pkey: "id",
|
|
95
|
+
pkey2s: ["yuno_release"],
|
|
96
|
+
};
|
|
97
|
+
const COL = {
|
|
98
|
+
id: {id: "id", type: "string", flag: ["persistent", "required", "rowid"]},
|
|
99
|
+
yuno_release: {id: "yuno_release", type: "string", flag: ["persistent", "required"]},
|
|
100
|
+
yuno_name: {id: "yuno_name", type: "string", flag: ["persistent", "writable"]},
|
|
101
|
+
date: {id: "date", type: "integer", flag: ["persistent", "time"]},
|
|
102
|
+
realm_id: {id: "realm_id", type: "string", flag: ["persistent", "fkey"]},
|
|
103
|
+
photo: {id: "photo", type: "string", flag: ["persistent", "fkey", "file"]},
|
|
104
|
+
yunos: {id: "yunos", type: "object", flag: ["hook"], hook: {yunos: "realm_id"}},
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
describe("what goes back to treedb from a form", () => {
|
|
108
|
+
test("a writable column, an fkey and a file column go back", () => {
|
|
109
|
+
expect(col_goes_back_to_treedb(YUNOS_DESC, COL.yuno_name)).toBe(true);
|
|
110
|
+
expect(col_goes_back_to_treedb(YUNOS_DESC, COL.realm_id)).toBe(true);
|
|
111
|
+
expect(col_goes_back_to_treedb(YUNOS_DESC, COL.photo)).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("a read-only time and a hook stay: they do not survive the widget", () => {
|
|
115
|
+
expect(col_goes_back_to_treedb(YUNOS_DESC, COL.date)).toBe(false);
|
|
116
|
+
expect(col_goes_back_to_treedb(YUNOS_DESC, COL.yunos)).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test("the pkey goes back although it is not writable: it addresses the record", () => {
|
|
120
|
+
expect(col_goes_back_to_treedb(YUNOS_DESC, COL.id)).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("a pkey2 goes back although it is not writable: it names the INSTANCE", () => {
|
|
124
|
+
expect(col_goes_back_to_treedb(YUNOS_DESC, COL.yuno_release)).toBe(true);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("a pkey2s declared as a bare string (the C literal) counts the same", () => {
|
|
128
|
+
expect(col_goes_back_to_treedb({pkey: "id", pkey2s: "yuno_release"}, COL.yuno_release)).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test("without pkey2s in the desc the same column stays read-only", () => {
|
|
132
|
+
expect(col_goes_back_to_treedb({pkey: "id"}, COL.yuno_release)).toBe(false);
|
|
133
|
+
expect(col_goes_back_to_treedb(null, COL.yuno_release)).toBe(false);
|
|
134
|
+
});
|
|
135
|
+
});
|