@weng-lab/genomebrowser-ui 0.1.11 → 0.2.0-beta.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.
Files changed (84) hide show
  1. package/.env.local +1 -0
  2. package/dist/TrackSelect/DataGrid/DefaultGroupingCell.d.ts +6 -0
  3. package/dist/TrackSelect/FolderList/Breadcrumb.d.ts +6 -0
  4. package/dist/TrackSelect/FolderList/FolderCard.d.ts +6 -0
  5. package/dist/TrackSelect/FolderList/FolderList.d.ts +6 -0
  6. package/dist/TrackSelect/{Data/humanBiosamples.json.d.ts → Folders/biosamples/data/human.json.d.ts} +1940 -1919
  7. package/dist/TrackSelect/{Data/mouseBiosamples.json.d.ts → Folders/biosamples/data/mouse.json.d.ts} +408 -357
  8. package/dist/TrackSelect/Folders/biosamples/human.d.ts +7 -0
  9. package/dist/TrackSelect/Folders/biosamples/mouse.d.ts +7 -0
  10. package/dist/TrackSelect/Folders/biosamples/shared/AssayToggle.d.ts +14 -0
  11. package/dist/TrackSelect/Folders/biosamples/shared/BiosampleGroupingCell.d.ts +6 -0
  12. package/dist/TrackSelect/Folders/biosamples/shared/BiosampleTreeItem.d.ts +7 -0
  13. package/dist/TrackSelect/Folders/biosamples/shared/columns.d.ts +14 -0
  14. package/dist/TrackSelect/Folders/biosamples/shared/constants.d.ts +19 -0
  15. package/dist/TrackSelect/Folders/biosamples/shared/createFolder.d.ts +24 -0
  16. package/dist/TrackSelect/Folders/biosamples/shared/treeBuilder.d.ts +25 -0
  17. package/dist/TrackSelect/Folders/biosamples/shared/types.d.ts +44 -0
  18. package/dist/TrackSelect/Folders/genes/data/human.json.d.ts +10 -0
  19. package/dist/TrackSelect/Folders/genes/data/mouse.json.d.ts +10 -0
  20. package/dist/TrackSelect/Folders/genes/human.d.ts +7 -0
  21. package/dist/TrackSelect/Folders/genes/mouse.d.ts +7 -0
  22. package/dist/TrackSelect/Folders/genes/shared/columns.d.ts +14 -0
  23. package/dist/TrackSelect/Folders/genes/shared/createFolder.d.ts +12 -0
  24. package/dist/TrackSelect/Folders/genes/shared/treeBuilder.d.ts +13 -0
  25. package/dist/TrackSelect/Folders/genes/shared/types.d.ts +26 -0
  26. package/dist/TrackSelect/Folders/index.d.ts +14 -0
  27. package/dist/TrackSelect/Folders/types.d.ts +76 -0
  28. package/dist/TrackSelect/TrackSelect.d.ts +12 -5
  29. package/dist/TrackSelect/TreeView/CustomTreeItem.d.ts +3 -0
  30. package/dist/TrackSelect/TreeView/TreeViewWrapper.d.ts +1 -1
  31. package/dist/TrackSelect/store.d.ts +1 -2
  32. package/dist/TrackSelect/types.d.ts +24 -62
  33. package/dist/genomebrowser-ui.es.js +1373 -2117
  34. package/dist/genomebrowser-ui.es.js.map +1 -1
  35. package/dist/lib.d.ts +2 -2
  36. package/package.json +3 -3
  37. package/src/TrackSelect/DataGrid/DataGridWrapper.tsx +36 -20
  38. package/src/TrackSelect/DataGrid/DefaultGroupingCell.tsx +64 -0
  39. package/src/TrackSelect/FolderList/Breadcrumb.tsx +38 -0
  40. package/src/TrackSelect/FolderList/FolderCard.tsx +51 -0
  41. package/src/TrackSelect/FolderList/FolderList.tsx +47 -0
  42. package/src/TrackSelect/Folders/NEW.md +929 -0
  43. package/src/TrackSelect/{Data → Folders/biosamples/data}/formatBiosamples.go +2 -2
  44. package/src/TrackSelect/{Data/humanBiosamples.json → Folders/biosamples/data/human.json} +1940 -1919
  45. package/src/TrackSelect/{Data/mouseBiosamples.json → Folders/biosamples/data/mouse.json} +408 -357
  46. package/src/TrackSelect/Folders/biosamples/human.ts +17 -0
  47. package/src/TrackSelect/Folders/biosamples/mouse.ts +17 -0
  48. package/src/TrackSelect/Folders/biosamples/shared/AssayToggle.tsx +65 -0
  49. package/src/TrackSelect/{DataGrid/GroupingCell.tsx → Folders/biosamples/shared/BiosampleGroupingCell.tsx} +7 -5
  50. package/src/TrackSelect/Folders/biosamples/shared/BiosampleTreeItem.tsx +15 -0
  51. package/src/TrackSelect/{DataGrid → Folders/biosamples/shared}/columns.tsx +31 -17
  52. package/src/TrackSelect/Folders/biosamples/shared/constants.tsx +116 -0
  53. package/src/TrackSelect/Folders/biosamples/shared/createFolder.ts +116 -0
  54. package/src/TrackSelect/Folders/biosamples/shared/treeBuilder.ts +227 -0
  55. package/src/TrackSelect/Folders/biosamples/shared/types.ts +48 -0
  56. package/src/TrackSelect/Folders/genes/data/human.json +7 -0
  57. package/src/TrackSelect/Folders/genes/data/mouse.json +7 -0
  58. package/src/TrackSelect/Folders/genes/human.ts +16 -0
  59. package/src/TrackSelect/Folders/genes/mouse.ts +16 -0
  60. package/src/TrackSelect/Folders/genes/shared/columns.tsx +42 -0
  61. package/src/TrackSelect/Folders/genes/shared/createFolder.ts +68 -0
  62. package/src/TrackSelect/Folders/genes/shared/treeBuilder.ts +45 -0
  63. package/src/TrackSelect/Folders/genes/shared/types.ts +29 -0
  64. package/src/TrackSelect/Folders/index.ts +27 -0
  65. package/src/TrackSelect/Folders/types.ts +95 -0
  66. package/src/TrackSelect/TrackSelect.tsx +409 -311
  67. package/src/TrackSelect/TreeView/CustomTreeItem.tsx +217 -0
  68. package/src/TrackSelect/TreeView/TreeViewWrapper.tsx +47 -42
  69. package/src/TrackSelect/store.ts +103 -46
  70. package/src/TrackSelect/types.ts +28 -74
  71. package/src/lib.ts +2 -2
  72. package/test/main.tsx +113 -169
  73. package/.claude/settings.local.json +0 -7
  74. package/dist/TrackSelect/DataGrid/CustomToolbar.d.ts +0 -12
  75. package/dist/TrackSelect/DataGrid/GroupingCell.d.ts +0 -2
  76. package/dist/TrackSelect/DataGrid/columns.d.ts +0 -4
  77. package/dist/TrackSelect/DataGrid/dataGridHelpers.d.ts +0 -49
  78. package/dist/TrackSelect/TreeView/treeViewHelpers.d.ts +0 -49
  79. package/dist/TrackSelect/consts.d.ts +0 -11
  80. package/src/TrackSelect/DataGrid/CustomToolbar.tsx +0 -152
  81. package/src/TrackSelect/DataGrid/dataGridHelpers.tsx +0 -155
  82. package/src/TrackSelect/TreeView/treeViewHelpers.tsx +0 -475
  83. package/src/TrackSelect/consts.ts +0 -92
  84. package/src/TrackSelect/issues.md +0 -404
@@ -1,404 +0,0 @@
1
- # TrackSelect Code Review Issues
2
-
3
- ## Critical Issues
4
-
5
- ### ~~1. Bug: Hardcoded `rowById` Import Breaks Multi-Assembly Support~~ ✅ FIXED
6
-
7
- **File:** `TreeViewWrapper.tsx:3,28-42`
8
-
9
- ~~**Problem:** The `rowById` from `consts.ts` is always built with `"GRCh38"` (human assembly). When the store is created with `mm10` assembly, the TreeViewWrapper will fail to find rows because it's looking in the wrong map.~~
10
-
11
- **Resolution:** Removed hardcoded import, now gets `rowById` from the store.
12
-
13
- ---
14
-
15
- ### 2. Bug: Memory Leak from Missing Timeout Cleanup
16
-
17
- **File:** `TrackSelect.tsx:117,170-173`
18
-
19
- **Problem:** No cleanup on unmount. If component unmounts while timeout is pending, it will try to update state on an unmounted component.
20
-
21
- **Fix - Add useEffect after line 118:**
22
- ```typescript
23
- useEffect(() => {
24
- return () => {
25
- if (searchTimeoutRef.current) {
26
- clearTimeout(searchTimeoutRef.current);
27
- }
28
- };
29
- }, []);
30
- ```
31
-
32
- ---
33
-
34
- ### 3. Bug: Unsafe Type Assertion with `as any`
35
-
36
- **File:** `TrackSelect.tsx:254-256`
37
-
38
- ```typescript
39
- const allIds: Set<string> =
40
- (newSelection && (newSelection as any).ids) ?? new Set<string>();
41
- ```
42
-
43
- **Problem:** Using `as any` bypasses TypeScript safety.
44
-
45
- **Fix:**
46
- ```typescript
47
- let allIds: Set<string>;
48
- if (
49
- newSelection &&
50
- typeof newSelection === 'object' &&
51
- 'ids' in newSelection &&
52
- newSelection.ids instanceof Set
53
- ) {
54
- allIds = newSelection.ids as Set<string>;
55
- } else {
56
- allIds = new Set<string>();
57
- }
58
- ```
59
-
60
- ---
61
-
62
- ### 4. Bug: Inconsistent Map Keys in `buildSortedAssayTreeView`
63
-
64
- **File:** `TreeView/treeViewHelpers.tsx:134,145`
65
-
66
- ```typescript
67
- // Line 134 (get):
68
- let expNode = sampleAssayMap.get(row.displayname + row.id);
69
- // Line 145 (set):
70
- sampleAssayMap.set(row.displayname + row.assay, expNode);
71
- ```
72
-
73
- **Problem:** Different keys used for get vs set - lookup will always return `undefined`.
74
-
75
- **Fix Line 134:**
76
- ```typescript
77
- let expNode = sampleAssayMap.get(row.displayname + row.assay);
78
- ```
79
-
80
- ---
81
-
82
- ## Code Duplication Issues
83
-
84
- ### 5. Duplicate Assay Formatting Functions
85
-
86
- **Files:**
87
- - `DataGrid/dataGridHelpers.tsx:17-38` - `formatAssayType`
88
- - `TreeView/treeViewHelpers.tsx:43-64` - `formatAssayName`
89
-
90
- Nearly identical switch statements.
91
-
92
- **Fix - Create shared utility in `consts.ts`:**
93
- ```typescript
94
- export const ASSAY_DISPLAY_MAP: Record<string, string> = {
95
- dnase: "DNase",
96
- atac: "ATAC",
97
- h3k4me3: "H3K4me3",
98
- h3k27ac: "H3K27ac",
99
- ctcf: "CTCF",
100
- chromhmm: "ChromHMM",
101
- ccre: "cCRE",
102
- rnaseq: "RNA-seq",
103
- };
104
-
105
- export function formatAssayType(assay: string): string {
106
- return ASSAY_DISPLAY_MAP[assay.toLowerCase()] ?? assay;
107
- }
108
- ```
109
-
110
- ---
111
-
112
- ### 6. Duplicate Root Tree Item Object (6 occurrences)
113
-
114
- **File:** `TrackSelect.tsx` - Lines 83, 95, 108, 134, 145, 222
115
-
116
- Same object literal repeated 6 times:
117
- ```typescript
118
- {
119
- id: "1",
120
- isAssayItem: false,
121
- label: "Biosamples",
122
- icon: "folder",
123
- children: [],
124
- allRowInfo: [],
125
- }
126
- ```
127
-
128
- **Fix - Add to `consts.ts`:**
129
- ```typescript
130
- export const createRootTreeItem = (): TreeViewBaseItem<ExtendedTreeItemProps> => ({
131
- id: "1",
132
- isAssayItem: false,
133
- label: "Biosamples",
134
- icon: "folder",
135
- children: [],
136
- allRowInfo: [],
137
- });
138
- ```
139
-
140
- ---
141
-
142
- ### 7. Duplicate Column renderCell Logic
143
-
144
- **File:** `DataGrid/columns.tsx:19-92`
145
-
146
- Similar renderCell implementations across multiple column definitions.
147
-
148
- **Fix - Create helper functions:**
149
- ```typescript
150
- const renderGroupCell = (params: GridRenderCellParams<RowInfo>) => {
151
- if (params.rowNode.type !== "group" || params.value === undefined) {
152
- return null;
153
- }
154
- return <div><b>{params.value}</b></div>;
155
- };
156
- ```
157
-
158
- ---
159
-
160
- ### 8. Duplicate Tree Building Logic
161
-
162
- **File:** `TreeView/treeViewHelpers.tsx:73-243`
163
-
164
- `buildSortedAssayTreeView` and `buildTreeView` share common patterns.
165
-
166
- **Fix - Extract shared logic:**
167
- ```typescript
168
- function getSelectedRows(
169
- selectedIds: string[],
170
- rowById: Map<string, RowInfo>
171
- ): RowInfo[] {
172
- return selectedIds.reduce<RowInfo[]>((acc, id) => {
173
- const row = rowById.get(id);
174
- if (row) acc.push(row);
175
- return acc;
176
- }, []);
177
- }
178
- ```
179
-
180
- ---
181
-
182
- ## Unused Code
183
-
184
- ### 9. Unused `CustomToolbar` Component
185
-
186
- **File:** `DataGrid/CustomToolbar.tsx`
187
-
188
- Entire file defines a component that is never imported or used.
189
-
190
- **Recommendation:** Delete the file or integrate into `DataGridWrapper.tsx`.
191
-
192
- ---
193
-
194
- ### 10. Unused Exports in consts.ts
195
-
196
- **File:** `consts.ts:102-108`
197
-
198
- ```typescript
199
- export const isTrackId = (id: string): boolean => rowById.has(id);
200
- export const getActiveTracks = (selectedIds: Set<string>): Set<string> =>
201
- new Set(Array.from(selectedIds).filter(isTrackId));
202
- ```
203
-
204
- Never used anywhere.
205
-
206
- **Recommendation:** Remove or document intended usage.
207
-
208
- ---
209
-
210
- ## Type Safety Issues
211
-
212
- ### 11. Using `any` Type in getNestedValue
213
-
214
- **File:** `DataGrid/dataGridHelpers.tsx:65-67`
215
-
216
- ```typescript
217
- function getNestedValue(obj: any, path: string): any {
218
- return path.split(".").reduce((acc, key) => acc && acc[key], obj);
219
- }
220
- ```
221
-
222
- **Fix:** Remove function and access properties directly:
223
- ```typescript
224
- const data = tracksData.tracks;
225
- ```
226
-
227
- ---
228
-
229
- ### 12. Non-Null Assertion Without Safety Check
230
-
231
- **File:** `TreeView/TreeViewWrapper.tsx:87`
232
-
233
- ```typescript
234
- ({items[0].allRowInfo!.length} search results)
235
- ```
236
-
237
- **Fix:**
238
- ```typescript
239
- ({items[0]?.allRowInfo?.length ?? 0} search results)
240
- ```
241
-
242
- ---
243
-
244
- ### 13. Implicit Any in FuseOptionKey
245
-
246
- **File:** `types.ts:14`
247
-
248
- ```typescript
249
- keyWeightMap: FuseOptionKey<any>[];
250
- ```
251
-
252
- **Fix:**
253
- ```typescript
254
- keyWeightMap: FuseOptionKey<TrackInfo | RowInfo>[];
255
- ```
256
-
257
- ---
258
-
259
- ## Performance Issues
260
-
261
- ### 14. Redundant useEffect Dependency
262
-
263
- **File:** `DataGrid/DataGridWrapper.tsx:48-50`
264
-
265
- **Fix - Memoize baseVisibility:**
266
- ```typescript
267
- const baseVisibility = useMemo<GridColumnVisibilityModel>(() =>
268
- sortedAssay
269
- ? { assay: false, ontology: false, displayname: false, id: false }
270
- : { ontology: false, displayname: false, assay: false, id: false },
271
- [sortedAssay]
272
- );
273
- ```
274
-
275
- ---
276
-
277
- ### 15. Eager Module Initialization
278
-
279
- **File:** `consts.ts:95-97`
280
-
281
- ```typescript
282
- const humanData = buildRowsForAssembly("GRCh38");
283
- export const rows = humanData.rows;
284
- export const rowById = humanData.rowById;
285
- ```
286
-
287
- Runs at module load time even if never used.
288
-
289
- **Fix - Lazy initialization:**
290
- ```typescript
291
- let _humanData: ReturnType<typeof buildRowsForAssembly> | null = null;
292
-
293
- function getHumanData() {
294
- if (!_humanData) {
295
- _humanData = buildRowsForAssembly("GRCh38");
296
- }
297
- return _humanData;
298
- }
299
- ```
300
-
301
- ---
302
-
303
- ## Code Quality Issues
304
-
305
- ### 16. Magic Number for maxTracks
306
-
307
- **File:** `store.ts:19`
308
-
309
- ```typescript
310
- maxTracks: 30,
311
- ```
312
-
313
- **Fix:**
314
- ```typescript
315
- const DEFAULT_MAX_TRACKS = 30;
316
- maxTracks: DEFAULT_MAX_TRACKS,
317
- ```
318
-
319
- ---
320
-
321
- ### 17. Redundant Null Check
322
-
323
- **File:** `TreeView/treeViewHelpers.tsx:191-194`
324
-
325
- The `reduce` already filters out falsy values, so the check in `forEach` is redundant.
326
-
327
- ---
328
-
329
- ### 18. Redundant has() + get()
330
-
331
- **File:** `store.ts:36-43`
332
-
333
- ```typescript
334
- if (storeRowById.has(id)) {
335
- const row = storeRowById.get(id);
336
- if (row) { // Redundant after has()
337
- ```
338
-
339
- **Fix:**
340
- ```typescript
341
- const row = storeRowById.get(id);
342
- if (row) {
343
- map.set(id, row);
344
- }
345
- ```
346
-
347
- ---
348
-
349
- ### 19. Commented-Out Code
350
-
351
- **File:** `store.ts:9-10`
352
-
353
- ```typescript
354
- // const isAutoGeneratedId = (id: string) => id.startsWith("auto-generated-row-");
355
- ```
356
-
357
- **Recommendation:** Remove or use.
358
-
359
- ---
360
-
361
- ### 20. Typo in Comment
362
-
363
- **File:** `types.ts:22`
364
-
365
- ```typescript
366
- * Types for the JSON-formatted tracks fomr modifiedHumanTracks.json
367
- ```
368
-
369
- Should be "from".
370
-
371
- ---
372
-
373
- ### 21. Missing Return Type Annotations
374
-
375
- **File:** `TreeView/treeViewHelpers.tsx:288`
376
-
377
- ```typescript
378
- export function AssayIcon(type: string) {
379
- ```
380
-
381
- **Fix:**
382
- ```typescript
383
- export function AssayIcon(type: string): JSX.Element {
384
- ```
385
-
386
- ---
387
-
388
- ### 22. Hardcoded Color Values
389
-
390
- **File:** `TreeView/treeViewHelpers.tsx:289-298`
391
-
392
- **Recommendation:** Move to `consts.ts` as `ASSAY_COLORS` for reusability.
393
-
394
- ---
395
-
396
- ## Summary
397
-
398
- | Severity | Count | Fixed |
399
- |----------|-------|-------|
400
- | Critical | 4 | 1 |
401
- | High | 4 | 0 |
402
- | Medium | 5 | 0 |
403
- | Low | 9 | 0 |
404
- | **Total** | **22** | **1** |