@checkstack/catalog-frontend 0.5.14 → 0.6.1

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 CHANGED
@@ -1,5 +1,38 @@
1
1
  # @checkstack/catalog-frontend
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [86bab6a]
8
+ - @checkstack/gitops-frontend@0.2.1
9
+
10
+ ## 0.6.0
11
+
12
+ ### Minor Changes
13
+
14
+ - 6c40b5b: Generalized provenance system and GitOps frontend plugin
15
+
16
+ **Breaking**: `EntityKindDefinition.reconcile()` now returns `{ entityId: string }` instead of `void`. Plugins must return the plugin-specific entity ID (e.g., catalog system UUID) so the engine can store it in provenance.
17
+
18
+ - Added `entityId` column to the provenance table (non-nullable)
19
+ - Reconciler engine passes `existingEntityId` to plugins for updates
20
+ - `getProvenance` now supports lookup by `entityId` in addition to `entityName`
21
+ - Added provider CRUD endpoints: `createProvider`, `updateProvider`, `deleteProvider`
22
+ - Created `gitops-frontend` plugin with provider management, secret management, and sync status dashboard
23
+ - Removed `gitops_entity_name` metadata markers from catalog entities
24
+ - Removed `findSystemByGitOpsName`, `deleteSystemByGitOpsName` (and Group equivalents) from EntityService
25
+ - Added provenance-based UI locking in catalog-frontend: edit/delete/drag disabled for GitOps-managed systems and groups
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies [6c40b5b]
30
+ - Updated dependencies [6c40b5b]
31
+ - Updated dependencies [4b0934d]
32
+ - @checkstack/gitops-frontend@0.2.0
33
+ - @checkstack/ui@1.3.6
34
+ - @checkstack/auth-frontend@0.5.25
35
+
3
36
  ## 0.5.14
4
37
 
5
38
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checkstack/catalog-frontend",
3
- "version": "0.5.14",
3
+ "version": "0.6.1",
4
4
  "type": "module",
5
5
  "main": "src/index.tsx",
6
6
  "checkstack": {
@@ -13,12 +13,13 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "@checkstack/auth-common": "0.6.1",
16
- "@checkstack/auth-frontend": "0.5.18",
16
+ "@checkstack/auth-frontend": "0.5.25",
17
17
  "@checkstack/catalog-common": "1.3.1",
18
18
  "@checkstack/common": "0.6.5",
19
19
  "@checkstack/frontend-api": "0.3.9",
20
+ "@checkstack/gitops-frontend": "0.2.0",
20
21
  "@checkstack/notification-common": "0.2.8",
21
- "@checkstack/ui": "1.2.1",
22
+ "@checkstack/ui": "1.3.6",
22
23
  "@dnd-kit/core": "^6.3.1",
23
24
  "@dnd-kit/utilities": "^3.2.2",
24
25
  "lucide-react": "^0.344.0",
@@ -1,9 +1,10 @@
1
1
  import { useState } from "react";
2
2
  import { useDraggable } from "@dnd-kit/core";
3
- import { GripVertical, Edit, Trash2, FolderPlus } from "lucide-react";
3
+ import { GripVertical, Edit, Trash2, FolderPlus, GitBranch } from "lucide-react";
4
4
  import { Button } from "@checkstack/ui";
5
5
  import { ExtensionSlot } from "@checkstack/frontend-api";
6
6
  import { CatalogSystemActionsSlot } from "@checkstack/catalog-common";
7
+ import { useProvenanceLock } from "@checkstack/gitops-frontend";
7
8
  import type { Group, System } from "../api";
8
9
 
9
10
  interface DraggableSystemProps {
@@ -38,8 +39,14 @@ export const DraggableSystem = ({
38
39
  }: DraggableSystemProps) => {
39
40
  const [isPickerOpen, setIsPickerOpen] = useState(false);
40
41
 
42
+ const { isLocked } = useProvenanceLock({
43
+ kind: "System",
44
+ entityId: system.id,
45
+ });
46
+
41
47
  const { attributes, listeners, setNodeRef } = useDraggable({
42
48
  id: system.id,
49
+ disabled: isLocked,
43
50
  });
44
51
 
45
52
  const availableGroups = groups.filter((g) => !assignedGroupIds.includes(g.id));
@@ -55,10 +62,18 @@ export const DraggableSystem = ({
55
62
  <div
56
63
  {...listeners}
57
64
  {...attributes}
58
- className="flex-shrink-0 mt-0.5 cursor-grab active:cursor-grabbing text-muted-foreground/40 hover:text-muted-foreground touch-none"
59
- aria-label={`Drag ${system.name}`}
65
+ className={`flex-shrink-0 mt-0.5 text-muted-foreground/40 touch-none ${
66
+ isLocked
67
+ ? "cursor-not-allowed opacity-30"
68
+ : "cursor-grab active:cursor-grabbing hover:text-muted-foreground"
69
+ }`}
70
+ aria-label={isLocked ? `${system.name} is managed by GitOps` : `Drag ${system.name}`}
60
71
  >
61
- <GripVertical className="w-4 h-4" />
72
+ {isLocked ? (
73
+ <GitBranch className="w-4 h-4 text-primary" />
74
+ ) : (
75
+ <GripVertical className="w-4 h-4" />
76
+ )}
62
77
  </div>
63
78
 
64
79
  {/* Name + description — gets all remaining width, never truncated */}
@@ -142,6 +157,8 @@ export const DraggableSystem = ({
142
157
  size="sm"
143
158
  className="h-7 w-7 p-0"
144
159
  onClick={() => onEdit(system)}
160
+ disabled={isLocked}
161
+ title={isLocked ? "Managed by GitOps" : undefined}
145
162
  aria-label={`Edit ${system.name}`}
146
163
  >
147
164
  <Edit className="w-3.5 h-3.5" />
@@ -152,6 +169,8 @@ export const DraggableSystem = ({
152
169
  size="sm"
153
170
  className="text-destructive hover:text-destructive/90 hover:bg-destructive/10 h-7 w-7 p-0"
154
171
  onClick={() => onDelete(system.id)}
172
+ disabled={isLocked}
173
+ title={isLocked ? "Managed by GitOps" : undefined}
155
174
  aria-label={`Delete ${system.name}`}
156
175
  >
157
176
  <Trash2 className="w-3.5 h-3.5" />
@@ -1,6 +1,7 @@
1
1
  import { useDroppable } from "@dnd-kit/core";
2
2
  import { EditableText, Button } from "@checkstack/ui";
3
- import { Trash2 } from "lucide-react";
3
+ import { Trash2, GitBranch } from "lucide-react";
4
+ import { useProvenanceLock } from "@checkstack/gitops-frontend";
4
5
  import type { Group, System } from "../api";
5
6
 
6
7
  interface DroppableGroupProps {
@@ -35,6 +36,11 @@ export const DroppableGroup = ({
35
36
  }: DroppableGroupProps) => {
36
37
  const { setNodeRef } = useDroppable({ id: group.id });
37
38
 
39
+ const { isLocked } = useProvenanceLock({
40
+ kind: "Group",
41
+ entityId: group.id,
42
+ });
43
+
38
44
  const groupSystems = (group.systemIds ?? [])
39
45
  .map((sysId) => systems.find((s) => s.id === sysId))
40
46
  .filter((sys): sys is System => !!sys);
@@ -56,18 +62,28 @@ export const DroppableGroup = ({
56
62
  >
57
63
  {/* Group header */}
58
64
  <div className="flex items-center justify-between">
59
- <div className="flex-1">
60
- <EditableText
61
- value={group.name}
62
- onSave={(newName) => onUpdateGroupName(group.id, newName)}
63
- className="font-medium text-foreground"
64
- />
65
- <p className="text-xs text-muted-foreground font-mono">{group.id}</p>
65
+ <div className="flex items-center gap-2 flex-1">
66
+ {isLocked && (
67
+ <span title="Managed by GitOps">
68
+ <GitBranch className="w-4 h-4 text-primary shrink-0" />
69
+ </span>
70
+ )}
71
+ <div className="flex-1">
72
+ <EditableText
73
+ value={group.name}
74
+ onSave={(newName) => onUpdateGroupName(group.id, newName)}
75
+ className="font-medium text-foreground"
76
+ disabled={isLocked}
77
+ />
78
+ <p className="text-xs text-muted-foreground font-mono">{group.id}</p>
79
+ </div>
66
80
  </div>
67
81
  <Button
68
82
  variant="ghost"
69
83
  className="text-destructive hover:text-destructive/90 hover:bg-destructive/10 h-8 w-8 p-0"
70
84
  onClick={() => onDeleteGroup(group.id)}
85
+ disabled={isLocked}
86
+ title={isLocked ? "Managed by GitOps" : undefined}
71
87
  aria-label={`Delete group ${group.name}`}
72
88
  >
73
89
  <Trash2 className="w-4 h-4" />