fix(categories): filter null/empty segments before saving class name#902
fix(categories): filter null/empty segments before saving class name#902fanxing11 wants to merge 2 commits into
Conversation
When editing a category with the Parent field set to "None" and the name untouched, [].concat(this.editing.name) could produce [null] because this.editing.name is initialized from cat.subname which may be null/undefined for freshly-created or corrupted classes. Any such null value gets written into settings.json under classes[].name and later serialized into the categorize() query, where the query interpreter treats it as a variable reference and raises QueryInterpretException: Tried to reference variable 'null' which is not defined breaking every chart that uses categorize(). Guard handleSubmit() so that: - parent is coerced to [] if it is not an array - null/undefined/empty-string segments are dropped from the final name - if nothing remains (no parent, no name), save is aborted silently Fixes ActivityWatch/activitywatch#1355
Greptile SummaryThis PR tightens category-name saving in the Category Editor. The main changes are:
Confidence Score: 4/5The changed save path is mostly safe, but invalid empty child names can collapse into their parent.
src/components/CategoryEditModal.vue Important Files Changed
Reviews (1): Last reviewed commit: "fix(categories): filter null/empty segme..." | Re-trigger Greptile |
| const nameSegments = parent | ||
| .concat(this.editing.name) | ||
| .filter(s => s !== null && s !== undefined && s !== ''); | ||
| if (nameSegments.length === 0) { |
There was a problem hiding this comment.
When an existing child category has an empty subname, this filter removes only the leaf while keeping the parent path. Saving a color or rule change for ['Work', ''] then writes the class as ['Work'], which can duplicate or overwrite the parent category instead of rejecting the invalid name.
| const nameSegments = parent | |
| .concat(this.editing.name) | |
| .filter(s => s !== null && s !== undefined && s !== ''); | |
| if (nameSegments.length === 0) { | |
| const nameSegments = parent.concat(this.editing.name); | |
| if (nameSegments.some(s => s === null || s === undefined || s === '')) { | |
| // Nothing valid to save (invalid parent/name segment) — abort silently. | |
| return; | |
| } | |
| if (nameSegments.length === 0) { |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #902 +/- ##
=======================================
Coverage 38.63% 38.63%
=======================================
Files 42 42
Lines 2226 2226
Branches 443 443
=======================================
Hits 860 860
Misses 1288 1288
Partials 78 78 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…parent Address greptile review on ActivityWatch#902: the previous version filtered null/undef/'' from the concatenated (parent + name) array as a whole. If the user cleared the Name field on a child category, the leaf would be dropped and the resulting name would equal the parent's name, effectively overwriting the child into a duplicate of its parent. Split the check: - filter null/undef/'' out of the parent segments - abort the save entirely if the leaf (editing.name) itself is invalid, so an empty name never silently collapses a child into its parent.
|
Good catch @greptile-apps — the collapse-into-parent edge case was real. Force-pushed e6ce490 which splits the check: parent segments still get null/undef/'' filtered, but the leaf name is validated on its own and the save is aborted if it's blank. That way an empty Name field can never silently rewrite a child into a duplicate of its parent. npm test still 121/121, lint 0 errors. |
|
The fix looks solid. The split between parent filtering and leaf validation is exactly right:
The One minor nit — the abort on invalid leaf name is silent right now (just handleOk(event) {
event.preventDefault();
this.handleSubmit(); // returns early if name invalid
this.$emit('ok'); // fires regardless
},Consider a small warning, e.g. setting a ...paired with a Otherwise the logic is correct and 121/121 tests passing gives confidence. LGTM from a correctness standpoint. Tip: You can customize Greptile's behavior for this repo with |
跟进 ActivityWatch/activitywatch#1355 — 现在还没人在做。
问题
Category Editor 保存分类时,如果 parent 选 "None" 且 name 字段没被 touch,
[].concat(this.editing.name)会产生[null]。原因是this.editing.name初始化自cat.subname,对新建/已损坏的 class 可能是 null/undefined。一旦
null被写进classes[].name,后续会被序列化进categorize()query,query 解释器把它当变量名去查:所有用
categorize()的 chart 全部挂掉。修复
handleSubmit()里加三道保护:不动 store 和 query 层,改动最小。
测试
npm test— 25/25 test suites 全过(121 tests)。npm run lint— 0 errors(3 个 pre-existing warnings 与本 PR 无关)。备注
issue 里提到后端
aw_query.q2_categorize也可以做防御性 filter,那个应该单独一个 PR 到 aw-server-python(算 defense in depth)。这里先修根源,阻止前端再写坏数据。user #s13mjl 已在 issue 里给出手动 workaround(改 settings.json 删 null),那部分对已有损坏数据仍然需要。