@checkstack/dependency-frontend 0.2.1 → 0.2.3
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 +54 -0
- package/package.json +6 -6
- package/src/components/DependencyMapPage.tsx +44 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,59 @@
|
|
|
1
1
|
# @checkstack/dependency-frontend
|
|
2
2
|
|
|
3
|
+
## 0.2.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d1a2796: Enforce stricter code quality standards and eliminate AI slop anti-patterns.
|
|
8
|
+
|
|
9
|
+
**New utility**
|
|
10
|
+
|
|
11
|
+
- `extractErrorMessage(error, fallback?)` in `@checkstack/common` for consistent error extraction
|
|
12
|
+
|
|
13
|
+
**ESLint rules**
|
|
14
|
+
|
|
15
|
+
- `react-hooks/rules-of-hooks` and `exhaustive-deps` for hook correctness
|
|
16
|
+
- `no-console` in frontend packages — forces `toast` over silent `console.error`
|
|
17
|
+
- `no-restricted-syntax` banning `instanceof Error` — forces `extractErrorMessage`
|
|
18
|
+
- Custom `no-eslint-disable-any` rule preventing `@typescript-eslint/no-explicit-any` circumvention
|
|
19
|
+
|
|
20
|
+
**Refactoring**
|
|
21
|
+
|
|
22
|
+
- Replace 141 `instanceof Error` boilerplate patterns across the codebase
|
|
23
|
+
- Replace swallowed `console.error` with user-visible `toast.error()` feedback
|
|
24
|
+
- Remove 15 redundant `as` type casts in IntegrationsPage and ProviderConnectionsPage
|
|
25
|
+
- Consolidate 3 identical callback handlers into `handleDialogClose`
|
|
26
|
+
- Fix conditional React hook call in `FormField.tsx`
|
|
27
|
+
- Fix unstable useMemo deps in `Dashboard.tsx`
|
|
28
|
+
- Replace `useEffect`→`setState` with derived `useMemo` in `RegisterPage.tsx`
|
|
29
|
+
- Rewrite `keystore.test.ts` with typed `DrizzleMockChain` (eliminating 7 `any` suppressions)
|
|
30
|
+
- Delete obvious comments in `encryption.ts` and Teams `provider.ts`
|
|
31
|
+
|
|
32
|
+
- Updated dependencies [d1a2796]
|
|
33
|
+
- Updated dependencies [3c34b07]
|
|
34
|
+
- @checkstack/common@0.6.5
|
|
35
|
+
- @checkstack/ui@1.2.1
|
|
36
|
+
- @checkstack/dashboard-frontend@0.3.26
|
|
37
|
+
- @checkstack/frontend-api@0.3.9
|
|
38
|
+
- @checkstack/catalog-common@1.3.1
|
|
39
|
+
- @checkstack/healthcheck-common@0.10.1
|
|
40
|
+
- @checkstack/dependency-common@0.2.1
|
|
41
|
+
- @checkstack/signal-frontend@0.0.15
|
|
42
|
+
|
|
43
|
+
## 0.2.2
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- c0935d8: Fix dependency map node positions resetting when connecting two nodes. The graph-building effect was rebuilding all nodes from scratch on every data change, discarding unsaved drag positions. Node and edge construction are now split into separate effects with a clear position resolution priority: in-memory positions → saved positions → auto-layout fallback for new systems only.
|
|
48
|
+
- @checkstack/catalog-common@1.3.0
|
|
49
|
+
- @checkstack/common@0.6.4
|
|
50
|
+
- @checkstack/dashboard-frontend@0.3.25
|
|
51
|
+
- @checkstack/dependency-common@0.2.0
|
|
52
|
+
- @checkstack/frontend-api@0.3.8
|
|
53
|
+
- @checkstack/healthcheck-common@0.10.0
|
|
54
|
+
- @checkstack/signal-frontend@0.0.14
|
|
55
|
+
- @checkstack/ui@1.2.0
|
|
56
|
+
|
|
3
57
|
## 0.2.1
|
|
4
58
|
|
|
5
59
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/dependency-frontend",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "src/index.tsx",
|
|
6
6
|
"checkstack": {
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
"lint:code": "eslint . --max-warnings 0"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@checkstack/catalog-common": "1.
|
|
15
|
+
"@checkstack/catalog-common": "1.3.0",
|
|
16
16
|
"@checkstack/common": "0.6.4",
|
|
17
|
-
"@checkstack/dashboard-frontend": "0.3.
|
|
18
|
-
"@checkstack/dependency-common": "0.
|
|
17
|
+
"@checkstack/dashboard-frontend": "0.3.25",
|
|
18
|
+
"@checkstack/dependency-common": "0.2.0",
|
|
19
19
|
"@checkstack/frontend-api": "0.3.8",
|
|
20
|
-
"@checkstack/healthcheck-common": "0.
|
|
20
|
+
"@checkstack/healthcheck-common": "0.10.0",
|
|
21
21
|
"@checkstack/signal-frontend": "0.0.14",
|
|
22
22
|
"@checkstack/ui": "1.2.0",
|
|
23
23
|
"@xyflow/react": "^12.10.2",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"typescript": "^5.0.0",
|
|
30
30
|
"@types/react": "^18.2.0",
|
|
31
|
-
"@checkstack/tsconfig": "0.0.
|
|
31
|
+
"@checkstack/tsconfig": "0.0.5",
|
|
32
32
|
"@checkstack/scripts": "0.1.2"
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
type DependencyEdge,
|
|
47
47
|
type DependencyEdgeData,
|
|
48
48
|
} from "./canvas/DependencyEdge";
|
|
49
|
+
import { extractErrorMessage } from "@checkstack/common";
|
|
49
50
|
|
|
50
51
|
const nodeTypes = { system: SystemNodeComponent };
|
|
51
52
|
const edgeTypes = { dependency: DependencyEdgeComponent };
|
|
@@ -171,7 +172,7 @@ function DependencyMapContent() {
|
|
|
171
172
|
},
|
|
172
173
|
onError: (error) => {
|
|
173
174
|
const message =
|
|
174
|
-
error
|
|
175
|
+
extractErrorMessage(error, "Failed to create dependency");
|
|
175
176
|
|
|
176
177
|
// Check for cycle error and resolve names
|
|
177
178
|
if (message.includes("circular chain")) {
|
|
@@ -193,7 +194,7 @@ function DependencyMapContent() {
|
|
|
193
194
|
void refetchWarnings();
|
|
194
195
|
},
|
|
195
196
|
onError: (error) => {
|
|
196
|
-
toast.error(error
|
|
197
|
+
toast.error(extractErrorMessage(error, "Failed to update"));
|
|
197
198
|
},
|
|
198
199
|
});
|
|
199
200
|
|
|
@@ -206,7 +207,7 @@ function DependencyMapContent() {
|
|
|
206
207
|
void refetchWarnings();
|
|
207
208
|
},
|
|
208
209
|
onError: (error) => {
|
|
209
|
-
toast.error(error
|
|
210
|
+
toast.error(extractErrorMessage(error, "Failed to delete"));
|
|
210
211
|
},
|
|
211
212
|
});
|
|
212
213
|
|
|
@@ -227,21 +228,44 @@ function DependencyMapContent() {
|
|
|
227
228
|
[createDependency],
|
|
228
229
|
);
|
|
229
230
|
|
|
230
|
-
//
|
|
231
|
+
// Track node positions for saving and for preserving in-memory positions
|
|
232
|
+
const nodesRef = useRef(nodes);
|
|
233
|
+
nodesRef.current = nodes;
|
|
234
|
+
|
|
235
|
+
// Build nodes from systems, positions, warnings, and health data.
|
|
236
|
+
// Position resolution priority:
|
|
237
|
+
// 1. Current in-memory position (user may have dragged but not saved yet)
|
|
238
|
+
// 2. Saved position from the backend
|
|
239
|
+
// 3. Auto-layout fallback for brand-new systems with no position at all
|
|
240
|
+
|
|
231
241
|
useEffect(() => {
|
|
232
|
-
if (!systemsData?.systems
|
|
242
|
+
if (!systemsData?.systems) return;
|
|
233
243
|
|
|
234
244
|
const savedPositions = posData?.positions ?? [];
|
|
235
|
-
const positions = autoLayout(
|
|
236
|
-
systemsData.systems.map((s) => s.id),
|
|
237
|
-
savedPositions,
|
|
238
|
-
);
|
|
239
|
-
|
|
240
245
|
const warnings = warningsData?.warnings ?? {};
|
|
241
246
|
const healthStatuses = healthData?.statuses ?? {};
|
|
242
247
|
|
|
248
|
+
// Lookup maps for position resolution
|
|
249
|
+
const savedPositionMap = new Map(
|
|
250
|
+
savedPositions.map((p) => [p.systemId, { x: p.x, y: p.y }]),
|
|
251
|
+
);
|
|
252
|
+
const currentPositionMap = new Map<string, { x: number; y: number }>();
|
|
253
|
+
for (const node of nodesRef.current) {
|
|
254
|
+
currentPositionMap.set(node.id, node.position);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Auto-layout only for systems that have no saved and no in-memory position
|
|
258
|
+
const unpositioned = systemsData.systems
|
|
259
|
+
.map((s) => s.id)
|
|
260
|
+
.filter((id) => !savedPositionMap.has(id) && !currentPositionMap.has(id));
|
|
261
|
+
const fallbackPositions = autoLayout(unpositioned, []);
|
|
262
|
+
|
|
243
263
|
const newNodes: SystemNode[] = systemsData.systems.map((system) => {
|
|
244
|
-
const pos =
|
|
264
|
+
const pos =
|
|
265
|
+
currentPositionMap.get(system.id) ??
|
|
266
|
+
savedPositionMap.get(system.id) ??
|
|
267
|
+
fallbackPositions.get(system.id) ?? { x: 0, y: 0 };
|
|
268
|
+
|
|
245
269
|
const warning = warnings[system.id];
|
|
246
270
|
|
|
247
271
|
// Map real health status to node status
|
|
@@ -270,6 +294,13 @@ function DependencyMapContent() {
|
|
|
270
294
|
};
|
|
271
295
|
});
|
|
272
296
|
|
|
297
|
+
setNodes(newNodes);
|
|
298
|
+
}, [systemsData, posData, warningsData, healthData, setNodes]);
|
|
299
|
+
|
|
300
|
+
// Build edges separately — only depends on dependency data
|
|
301
|
+
useEffect(() => {
|
|
302
|
+
if (!depsData?.dependencies) return;
|
|
303
|
+
|
|
273
304
|
const newEdges: DependencyEdge[] = depsData.dependencies.map(
|
|
274
305
|
(dep: Dependency) => {
|
|
275
306
|
const edgeData: DependencyEdgeData = {
|
|
@@ -294,13 +325,10 @@ function DependencyMapContent() {
|
|
|
294
325
|
},
|
|
295
326
|
);
|
|
296
327
|
|
|
297
|
-
setNodes(newNodes);
|
|
298
328
|
setEdges(newEdges);
|
|
299
|
-
}, [
|
|
329
|
+
}, [depsData, setEdges]);
|
|
300
330
|
|
|
301
331
|
// Track node position changes for saving
|
|
302
|
-
const nodesRef = useRef(nodes);
|
|
303
|
-
nodesRef.current = nodes;
|
|
304
332
|
|
|
305
333
|
const handleNodesChange = useCallback(
|
|
306
334
|
(changes: NodeChange<SystemNode>[]) => {
|
|
@@ -323,6 +351,7 @@ function DependencyMapContent() {
|
|
|
323
351
|
}, 2000);
|
|
324
352
|
}
|
|
325
353
|
},
|
|
354
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- handleSave reads from nodesRef (always current); including it would cause infinite re-render loops via setHasUnsaved
|
|
326
355
|
[onNodesChange],
|
|
327
356
|
);
|
|
328
357
|
|