@burdenoff/microfe-vibecontrols 2026.725.1 → 2026.727.2
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/components/audit/AuditLogTable.js +147 -191
- package/dist/components/audit/AuditLogTable.js.map +1 -1
- package/dist/components/audit/index.js +0 -1
- package/dist/constants/permissions.js +0 -1
- package/dist/constants/permissions.js.map +1 -1
- package/dist/generated/wspace-operations.js +1460 -1488
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/index.js +11 -11
- package/dist/pages/VibeAuditPage.js +116 -236
- package/dist/pages/VibeAuditPage.js.map +1 -1
- package/package.json +1 -1
- package/dist/components/audit/AuditDeleteDialog.js +0 -76
- package/dist/components/audit/AuditDeleteDialog.js.map +0 -1
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { StatusBadge as e } from "../shared/StatusBadge.js";
|
|
2
|
-
import { SelectionCheckbox as t } from "../shared/SelectionCheckbox.js";
|
|
3
2
|
import "../shared/index.js";
|
|
4
|
-
import { useI18n as
|
|
5
|
-
import { ChevronRight as
|
|
6
|
-
import { jsx as
|
|
3
|
+
import { useI18n as t } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
4
|
+
import { ChevronRight as n, Terminal as r } from "lucide-react";
|
|
5
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
7
6
|
//#region src/components/audit/AuditLogTable.tsx
|
|
8
|
-
var
|
|
7
|
+
var o = {
|
|
9
8
|
SUCCESS: "success",
|
|
10
9
|
FAILURE: "error",
|
|
11
10
|
DENIED: "warning",
|
|
12
11
|
ERROR: "error"
|
|
13
|
-
},
|
|
12
|
+
}, s = {
|
|
14
13
|
CREATE: "bg-status-success-bg-subtle text-status-success-text",
|
|
15
14
|
UPDATE: "bg-status-info-bg-subtle text-status-info-text",
|
|
16
15
|
DELETE: "bg-status-error-bg-subtle text-status-error-text",
|
|
@@ -21,7 +20,7 @@ var c = {
|
|
|
21
20
|
ARCHIVE: "bg-bg-sunken text-text-secondary",
|
|
22
21
|
RESTORE: "bg-status-info-bg-subtle text-status-info-text"
|
|
23
22
|
};
|
|
24
|
-
function
|
|
23
|
+
function c(e) {
|
|
25
24
|
return new Date(e).toLocaleString("en-US", {
|
|
26
25
|
month: "short",
|
|
27
26
|
day: "numeric",
|
|
@@ -30,235 +29,192 @@ function u(e) {
|
|
|
30
29
|
second: "2-digit"
|
|
31
30
|
});
|
|
32
31
|
}
|
|
33
|
-
function
|
|
32
|
+
function l(e) {
|
|
34
33
|
return e.replace(/_/g, " ").toLowerCase().replace(/\b\w/g, (e) => e.toUpperCase());
|
|
35
34
|
}
|
|
36
|
-
function
|
|
37
|
-
let { t:
|
|
38
|
-
let n =
|
|
35
|
+
function u({ items: u, total: d, hasMore: f, page: p, pageSize: m, onPageChange: h, onSelectLog: g, selectedLogId: _ }) {
|
|
36
|
+
let { t: v } = t(), y = Math.max(1, Math.ceil(d / m)), b = (e, t) => {
|
|
37
|
+
let n = v(e);
|
|
39
38
|
return n === e ? t : n;
|
|
40
39
|
};
|
|
41
|
-
return /* @__PURE__ */
|
|
42
|
-
/* @__PURE__ */
|
|
40
|
+
return /* @__PURE__ */ a("div", { children: [
|
|
41
|
+
/* @__PURE__ */ i("div", {
|
|
43
42
|
className: "space-y-3 md:hidden",
|
|
44
|
-
children:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
/* @__PURE__ */
|
|
50
|
-
className: "
|
|
51
|
-
children: [
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
className: "mt-1"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
size: "sm"
|
|
89
|
-
})]
|
|
90
|
-
}),
|
|
91
|
-
/* @__PURE__ */ s("div", {
|
|
92
|
-
className: "mt-4 flex items-center justify-end gap-2",
|
|
93
|
-
children: [/* @__PURE__ */ s("button", {
|
|
94
|
-
type: "button",
|
|
95
|
-
onClick: () => v(n.id),
|
|
96
|
-
className: "inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-sm text-text-primary transition-colors hover:bg-bg-surface",
|
|
97
|
-
children: ["View details", /* @__PURE__ */ o(r, { size: 14 })]
|
|
98
|
-
}), /* @__PURE__ */ o("button", {
|
|
99
|
-
type: "button",
|
|
100
|
-
onClick: () => y(n.id),
|
|
101
|
-
className: "rounded p-1 text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text",
|
|
102
|
-
title: O("audit.deleteAuditLog", "Delete audit log"),
|
|
103
|
-
children: /* @__PURE__ */ o(a, { size: 14 })
|
|
104
|
-
})]
|
|
43
|
+
children: u.map((t) => /* @__PURE__ */ a("article", {
|
|
44
|
+
className: `rounded-lg border border-border-default p-4 transition-colors ${_ === t.id ? "bg-bg-sunken" : "bg-bg-surface"}`,
|
|
45
|
+
children: [
|
|
46
|
+
/* @__PURE__ */ a("div", {
|
|
47
|
+
className: "flex items-start justify-between gap-3",
|
|
48
|
+
children: [/* @__PURE__ */ a("div", {
|
|
49
|
+
className: "min-w-0",
|
|
50
|
+
children: [
|
|
51
|
+
/* @__PURE__ */ i("p", {
|
|
52
|
+
className: "text-xs text-text-secondary",
|
|
53
|
+
children: c(t.createdAt)
|
|
54
|
+
}),
|
|
55
|
+
/* @__PURE__ */ i("p", {
|
|
56
|
+
className: "mt-1 truncate font-medium text-text-primary",
|
|
57
|
+
children: t.resourceName || t.description || "-"
|
|
58
|
+
}),
|
|
59
|
+
/* @__PURE__ */ i("p", {
|
|
60
|
+
className: "mt-1 text-xs text-text-secondary",
|
|
61
|
+
children: l(t.resourceType)
|
|
62
|
+
})
|
|
63
|
+
]
|
|
64
|
+
}), /* @__PURE__ */ a("span", {
|
|
65
|
+
className: `inline-flex shrink-0 items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${s[t.action] || "bg-bg-surface text-text-secondary"}`,
|
|
66
|
+
children: [t.command ? /* @__PURE__ */ i(r, { size: 12 }) : null, t.action]
|
|
67
|
+
})]
|
|
68
|
+
}),
|
|
69
|
+
/* @__PURE__ */ a("div", {
|
|
70
|
+
className: "mt-3 flex items-center justify-between gap-3",
|
|
71
|
+
children: [/* @__PURE__ */ a("p", {
|
|
72
|
+
className: "min-w-0 truncate text-xs capitalize text-text-secondary",
|
|
73
|
+
children: [(t.actorType || "unknown").toLowerCase().replace(/_/g, " "), t.resourceName ? ` · ${t.resourceName}` : ""]
|
|
74
|
+
}), /* @__PURE__ */ i(e, {
|
|
75
|
+
status: t.status,
|
|
76
|
+
variant: o[t.status],
|
|
77
|
+
size: "sm"
|
|
78
|
+
})]
|
|
79
|
+
}),
|
|
80
|
+
/* @__PURE__ */ i("div", {
|
|
81
|
+
className: "mt-4 flex items-center justify-end gap-2",
|
|
82
|
+
children: /* @__PURE__ */ a("button", {
|
|
83
|
+
type: "button",
|
|
84
|
+
onClick: () => g(t.id),
|
|
85
|
+
className: "inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-sm text-text-primary transition-colors hover:bg-bg-surface",
|
|
86
|
+
children: ["View details", /* @__PURE__ */ i(n, { size: 14 })]
|
|
105
87
|
})
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
})
|
|
88
|
+
})
|
|
89
|
+
]
|
|
90
|
+
}, t.id))
|
|
109
91
|
}),
|
|
110
|
-
/* @__PURE__ */
|
|
92
|
+
/* @__PURE__ */ i("div", {
|
|
111
93
|
className: "hidden overflow-x-auto rounded-card border border-border-subtle bg-bg-surface shadow-elevation-1 md:block",
|
|
112
|
-
children: /* @__PURE__ */
|
|
94
|
+
children: /* @__PURE__ */ a("table", {
|
|
113
95
|
className: "w-full min-w-[860px] text-sm",
|
|
114
|
-
children: [/* @__PURE__ */
|
|
96
|
+
children: [/* @__PURE__ */ i("thead", { children: /* @__PURE__ */ a("tr", {
|
|
115
97
|
className: "border-b border-border-subtle bg-bg-sunken",
|
|
116
98
|
children: [
|
|
117
|
-
/* @__PURE__ */
|
|
118
|
-
className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
119
|
-
children: /* @__PURE__ */ o(t, {
|
|
120
|
-
checked: S,
|
|
121
|
-
indeterminate: C,
|
|
122
|
-
onChange: T,
|
|
123
|
-
ariaLabel: "Select all visible audit logs"
|
|
124
|
-
})
|
|
125
|
-
}),
|
|
126
|
-
/* @__PURE__ */ o("th", {
|
|
99
|
+
/* @__PURE__ */ i("th", {
|
|
127
100
|
className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
128
|
-
children:
|
|
101
|
+
children: b("audit.time", "Time")
|
|
129
102
|
}),
|
|
130
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ i("th", {
|
|
131
104
|
className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
132
|
-
children:
|
|
105
|
+
children: b("audit.action", "Action")
|
|
133
106
|
}),
|
|
134
|
-
/* @__PURE__ */
|
|
107
|
+
/* @__PURE__ */ i("th", {
|
|
135
108
|
className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
136
|
-
children:
|
|
109
|
+
children: b("audit.resource", "Resource")
|
|
137
110
|
}),
|
|
138
|
-
/* @__PURE__ */
|
|
111
|
+
/* @__PURE__ */ i("th", {
|
|
139
112
|
className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
140
|
-
children:
|
|
113
|
+
children: b("audit.name", "Name")
|
|
141
114
|
}),
|
|
142
|
-
/* @__PURE__ */
|
|
115
|
+
/* @__PURE__ */ i("th", {
|
|
143
116
|
className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
144
|
-
children:
|
|
117
|
+
children: b("audit.actor", "Actor")
|
|
145
118
|
}),
|
|
146
|
-
/* @__PURE__ */
|
|
119
|
+
/* @__PURE__ */ i("th", {
|
|
147
120
|
className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
148
|
-
children:
|
|
121
|
+
children: b("audit.status", "Status")
|
|
149
122
|
}),
|
|
150
|
-
/* @__PURE__ */
|
|
123
|
+
/* @__PURE__ */ i("th", {
|
|
151
124
|
className: "px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-text-muted",
|
|
152
|
-
children:
|
|
125
|
+
children: b("audit.actions", "Actions")
|
|
153
126
|
})
|
|
154
127
|
]
|
|
155
|
-
}) }), /* @__PURE__ */
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
})
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
/* @__PURE__ */
|
|
194
|
-
className: "
|
|
195
|
-
children: /* @__PURE__ */
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
/* @__PURE__ */ o("td", {
|
|
202
|
-
className: "px-4 py-3 text-right",
|
|
203
|
-
children: /* @__PURE__ */ s("div", {
|
|
204
|
-
className: "flex items-center justify-end gap-1",
|
|
205
|
-
children: [/* @__PURE__ */ o("button", {
|
|
206
|
-
type: "button",
|
|
207
|
-
onClick: () => v(n.id),
|
|
208
|
-
className: "rounded p-1 text-text-secondary transition-colors hover:bg-bg-surface hover:text-text-primary",
|
|
209
|
-
title: O("audit.viewAuditLog", "View details"),
|
|
210
|
-
children: /* @__PURE__ */ o(r, { size: 14 })
|
|
211
|
-
}), /* @__PURE__ */ o("button", {
|
|
212
|
-
type: "button",
|
|
213
|
-
onClick: () => y(n.id),
|
|
214
|
-
className: "rounded p-1 text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text",
|
|
215
|
-
title: O("audit.deleteAuditLog", "Delete audit log"),
|
|
216
|
-
children: /* @__PURE__ */ o(a, { size: 14 })
|
|
217
|
-
})]
|
|
128
|
+
}) }), /* @__PURE__ */ i("tbody", { children: u.map((t) => /* @__PURE__ */ a("tr", {
|
|
129
|
+
className: `border-b border-border-subtle transition-colors hover:bg-bg-sunken ${_ === t.id ? "bg-bg-sunken" : ""}`,
|
|
130
|
+
children: [
|
|
131
|
+
/* @__PURE__ */ i("td", {
|
|
132
|
+
className: "whitespace-nowrap px-4 py-3 text-xs text-text-secondary",
|
|
133
|
+
children: c(t.createdAt)
|
|
134
|
+
}),
|
|
135
|
+
/* @__PURE__ */ i("td", {
|
|
136
|
+
className: "px-4 py-3",
|
|
137
|
+
children: /* @__PURE__ */ a("span", {
|
|
138
|
+
className: `inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${s[t.action] || "bg-bg-surface text-text-secondary"}`,
|
|
139
|
+
children: [t.command ? /* @__PURE__ */ i(r, { size: 12 }) : null, t.action]
|
|
140
|
+
})
|
|
141
|
+
}),
|
|
142
|
+
/* @__PURE__ */ i("td", {
|
|
143
|
+
className: "px-4 py-3 text-xs text-text-secondary",
|
|
144
|
+
children: l(t.resourceType)
|
|
145
|
+
}),
|
|
146
|
+
/* @__PURE__ */ i("td", {
|
|
147
|
+
className: "max-w-[220px] truncate px-4 py-3",
|
|
148
|
+
title: t.resourceName || t.description || "",
|
|
149
|
+
children: t.resourceName || t.description || "-"
|
|
150
|
+
}),
|
|
151
|
+
/* @__PURE__ */ i("td", {
|
|
152
|
+
className: "max-w-[140px] truncate px-4 py-3 text-xs capitalize text-text-secondary",
|
|
153
|
+
title: t.actorId,
|
|
154
|
+
children: (t.actorType || "unknown").toLowerCase().replace(/_/g, " ")
|
|
155
|
+
}),
|
|
156
|
+
/* @__PURE__ */ i("td", {
|
|
157
|
+
className: "px-4 py-3",
|
|
158
|
+
children: /* @__PURE__ */ i(e, {
|
|
159
|
+
status: t.status,
|
|
160
|
+
variant: o[t.status],
|
|
161
|
+
size: "sm"
|
|
162
|
+
})
|
|
163
|
+
}),
|
|
164
|
+
/* @__PURE__ */ i("td", {
|
|
165
|
+
className: "px-4 py-3 text-right",
|
|
166
|
+
children: /* @__PURE__ */ i("div", {
|
|
167
|
+
className: "flex items-center justify-end gap-1",
|
|
168
|
+
children: /* @__PURE__ */ i("button", {
|
|
169
|
+
type: "button",
|
|
170
|
+
onClick: () => g(t.id),
|
|
171
|
+
className: "rounded p-1 text-text-secondary transition-colors hover:bg-bg-surface hover:text-text-primary",
|
|
172
|
+
title: b("audit.viewAuditLog", "View details"),
|
|
173
|
+
children: /* @__PURE__ */ i(n, { size: 14 })
|
|
218
174
|
})
|
|
219
175
|
})
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}) })]
|
|
176
|
+
})
|
|
177
|
+
]
|
|
178
|
+
}, t.id)) })]
|
|
223
179
|
})
|
|
224
180
|
}),
|
|
225
|
-
/* @__PURE__ */
|
|
181
|
+
/* @__PURE__ */ a("div", {
|
|
226
182
|
className: "mt-4 flex flex-col gap-3 text-sm text-text-secondary sm:flex-row sm:items-center sm:justify-between",
|
|
227
|
-
children: [/* @__PURE__ */
|
|
228
|
-
|
|
183
|
+
children: [/* @__PURE__ */ a("span", { children: [
|
|
184
|
+
b("audit.showing", "Showing"),
|
|
229
185
|
" ",
|
|
230
|
-
|
|
186
|
+
p * m + 1,
|
|
231
187
|
"-",
|
|
232
|
-
Math.min((
|
|
188
|
+
Math.min((p + 1) * m, d),
|
|
233
189
|
" ",
|
|
234
|
-
|
|
190
|
+
b("audit.of", "of"),
|
|
235
191
|
" ",
|
|
236
|
-
|
|
237
|
-
] }), /* @__PURE__ */
|
|
192
|
+
d
|
|
193
|
+
] }), /* @__PURE__ */ a("div", {
|
|
238
194
|
className: "flex flex-wrap items-center gap-2",
|
|
239
195
|
children: [
|
|
240
|
-
/* @__PURE__ */
|
|
196
|
+
/* @__PURE__ */ i("button", {
|
|
241
197
|
type: "button",
|
|
242
|
-
disabled:
|
|
243
|
-
onClick: () =>
|
|
198
|
+
disabled: p === 0,
|
|
199
|
+
onClick: () => h(p - 1),
|
|
244
200
|
className: "rounded border border-border-default px-3 py-1 transition-colors hover:bg-bg-surface disabled:opacity-50",
|
|
245
|
-
children:
|
|
201
|
+
children: b("audit.previous", "Previous")
|
|
246
202
|
}),
|
|
247
|
-
/* @__PURE__ */
|
|
248
|
-
|
|
203
|
+
/* @__PURE__ */ a("span", { children: [
|
|
204
|
+
b("audit.page", "Page"),
|
|
249
205
|
" ",
|
|
250
|
-
|
|
206
|
+
p + 1,
|
|
251
207
|
" ",
|
|
252
|
-
|
|
208
|
+
b("audit.of", "of"),
|
|
253
209
|
" ",
|
|
254
|
-
|
|
210
|
+
y
|
|
255
211
|
] }),
|
|
256
|
-
/* @__PURE__ */
|
|
212
|
+
/* @__PURE__ */ i("button", {
|
|
257
213
|
type: "button",
|
|
258
|
-
disabled: !
|
|
259
|
-
onClick: () =>
|
|
214
|
+
disabled: !f,
|
|
215
|
+
onClick: () => h(p + 1),
|
|
260
216
|
className: "rounded border border-border-default px-3 py-1 transition-colors hover:bg-bg-surface disabled:opacity-50",
|
|
261
|
-
children:
|
|
217
|
+
children: b("audit.next", "Next")
|
|
262
218
|
})
|
|
263
219
|
]
|
|
264
220
|
})]
|
|
@@ -266,6 +222,6 @@ function f({ items: f, total: p, hasMore: m, page: h, pageSize: g, onPageChange:
|
|
|
266
222
|
] });
|
|
267
223
|
}
|
|
268
224
|
//#endregion
|
|
269
|
-
export {
|
|
225
|
+
export { u as AuditLogTable };
|
|
270
226
|
|
|
271
227
|
//# sourceMappingURL=AuditLogTable.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditLogTable.js","names":[],"sources":["../../../src/components/audit/AuditLogTable.tsx"],"sourcesContent":["import { ChevronRight, Terminal, Trash2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { StatusBadge } from '@/components/shared';\nimport { SelectionCheckbox } from '@/components/shared/SelectionCheckbox';\nimport type { VibeAuditLogFieldsFragment } from '@/generated/wspace-operations';\n\ninterface AuditLogTableProps {\n items: VibeAuditLogFieldsFragment[];\n total: number;\n hasMore: boolean;\n page: number;\n pageSize: number;\n onPageChange: (page: number) => void;\n onSelectLog: (id: string) => void;\n onDeleteLog: (id: string) => void;\n selectedLogId: string | null;\n selectedLogIds: Set<string>;\n allVisibleSelected: boolean;\n partiallySelected: boolean;\n onToggleLogSelection: (id: string, checked: boolean) => void;\n onToggleAllVisible: (checked: boolean) => void;\n}\n\nconst statusVariantMap: Record<string, 'success' | 'error' | 'warning' | 'info'> = {\n SUCCESS: 'success',\n FAILURE: 'error',\n DENIED: 'warning',\n ERROR: 'error',\n};\n\nconst actionColors: Record<string, string> = {\n CREATE: 'bg-status-success-bg-subtle text-status-success-text',\n UPDATE: 'bg-status-info-bg-subtle text-status-info-text',\n DELETE: 'bg-status-error-bg-subtle text-status-error-text',\n EXECUTE: 'bg-[var(--color-accent-soft)] text-text-primary',\n EXPORT: 'bg-status-warning-bg-subtle text-status-warning-text',\n SHARE: 'bg-status-success-bg-subtle text-status-success-text',\n REVOKE: 'bg-status-warning-bg-subtle text-status-warning-text',\n ARCHIVE: 'bg-bg-sunken text-text-secondary',\n RESTORE: 'bg-status-info-bg-subtle text-status-info-text',\n};\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\nfunction formatResourceType(type: string): string {\n return type\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (character) => character.toUpperCase());\n}\n\nexport function AuditLogTable({\n items,\n total,\n hasMore,\n page,\n pageSize,\n onPageChange,\n onSelectLog,\n onDeleteLog,\n selectedLogId,\n selectedLogIds,\n allVisibleSelected,\n partiallySelected,\n onToggleLogSelection,\n onToggleAllVisible,\n}: AuditLogTableProps) {\n const { t } = useI18n();\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n\n const tr = (key: string, fallback: string) => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n return (\n <div>\n <div className=\"space-y-3 md:hidden\">\n {items.map((item) => {\n const isSelected = selectedLogIds.has(item.id);\n return (\n <article\n key={item.id}\n className={`rounded-lg border border-border-default p-4 transition-colors ${\n selectedLogId === item.id ? 'bg-bg-sunken' : 'bg-bg-surface'\n }`}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3\">\n <SelectionCheckbox\n checked={isSelected}\n onChange={(checked) => onToggleLogSelection(item.id, checked)}\n ariaLabel={`Select audit log ${item.id}`}\n className=\"mt-1\"\n />\n <div className=\"min-w-0\">\n <p className=\"text-xs text-text-secondary\">{formatDate(item.createdAt)}</p>\n <p className=\"mt-1 truncate font-medium text-text-primary\">\n {item.resourceName || item.description || '-'}\n </p>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {formatResourceType(item.resourceType)}\n </p>\n </div>\n </div>\n <span\n className={`inline-flex shrink-0 items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${\n actionColors[item.action] || 'bg-bg-surface text-text-secondary'\n }`}\n >\n {item.command ? <Terminal size={12} /> : null}\n {item.action}\n </span>\n </div>\n <div className=\"mt-3 flex items-center justify-between gap-3\">\n <p className=\"min-w-0 truncate text-xs capitalize text-text-secondary\">\n {(item.actorType || 'unknown').toLowerCase().replace(/_/g, ' ')}\n {item.resourceName ? ` · ${item.resourceName}` : ''}\n </p>\n <StatusBadge\n status={item.status}\n variant={statusVariantMap[item.status]}\n size=\"sm\"\n />\n </div>\n <div className=\"mt-4 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => onSelectLog(item.id)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-sm text-text-primary transition-colors hover:bg-bg-surface\"\n >\n View details\n <ChevronRight size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => onDeleteLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text\"\n title={tr('audit.deleteAuditLog', 'Delete audit log')}\n >\n <Trash2 size={14} />\n </button>\n </div>\n </article>\n );\n })}\n </div>\n\n <div className=\"hidden overflow-x-auto rounded-card border border-border-subtle bg-bg-surface shadow-elevation-1 md:block\">\n <table className=\"w-full min-w-[860px] text-sm\">\n <thead>\n <tr className=\"border-b border-border-subtle bg-bg-sunken\">\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n <SelectionCheckbox\n checked={allVisibleSelected}\n indeterminate={partiallySelected}\n onChange={onToggleAllVisible}\n ariaLabel=\"Select all visible audit logs\"\n />\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.time', 'Time')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.action', 'Action')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.resource', 'Resource')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.name', 'Name')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.actor', 'Actor')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.status', 'Status')}\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody>\n {items.map((item) => {\n const isSelected = selectedLogIds.has(item.id);\n return (\n <tr\n key={item.id}\n className={`border-b border-border-subtle transition-colors hover:bg-bg-sunken ${\n selectedLogId === item.id ? 'bg-bg-sunken' : ''\n }`}\n >\n <td className=\"px-4 py-3 align-top\">\n <SelectionCheckbox\n checked={isSelected}\n onChange={(checked) => onToggleLogSelection(item.id, checked)}\n ariaLabel={`Select audit log ${item.id}`}\n />\n </td>\n <td className=\"whitespace-nowrap px-4 py-3 text-xs text-text-secondary\">\n {formatDate(item.createdAt)}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${\n actionColors[item.action] || 'bg-bg-surface text-text-secondary'\n }`}\n >\n {item.command ? <Terminal size={12} /> : null}\n {item.action}\n </span>\n </td>\n <td className=\"px-4 py-3 text-xs text-text-secondary\">\n {formatResourceType(item.resourceType)}\n </td>\n <td\n className=\"max-w-[220px] truncate px-4 py-3\"\n title={item.resourceName || item.description || ''}\n >\n {item.resourceName || item.description || '-'}\n </td>\n <td\n className=\"max-w-[140px] truncate px-4 py-3 text-xs capitalize text-text-secondary\"\n title={item.actorId}\n >\n {(item.actorType || 'unknown').toLowerCase().replace(/_/g, ' ')}\n </td>\n <td className=\"px-4 py-3\">\n <StatusBadge\n status={item.status}\n variant={statusVariantMap[item.status]}\n size=\"sm\"\n />\n </td>\n <td className=\"px-4 py-3 text-right\">\n <div className=\"flex items-center justify-end gap-1\">\n <button\n type=\"button\"\n onClick={() => onSelectLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-bg-surface hover:text-text-primary\"\n title={tr('audit.viewAuditLog', 'View details')}\n >\n <ChevronRight size={14} />\n </button>\n <button\n type=\"button\"\n onClick={() => onDeleteLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text\"\n title={tr('audit.deleteAuditLog', 'Delete audit log')}\n >\n <Trash2 size={14} />\n </button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n <div className=\"mt-4 flex flex-col gap-3 text-sm text-text-secondary sm:flex-row sm:items-center sm:justify-between\">\n <span>\n {tr('audit.showing', 'Showing')} {page * pageSize + 1}-\n {Math.min((page + 1) * pageSize, total)} {tr('audit.of', 'of')} {total}\n </span>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n disabled={page === 0}\n onClick={() => onPageChange(page - 1)}\n className=\"rounded border border-border-default px-3 py-1 transition-colors hover:bg-bg-surface disabled:opacity-50\"\n >\n {tr('audit.previous', 'Previous')}\n </button>\n <span>\n {tr('audit.page', 'Page')} {page + 1} {tr('audit.of', 'of')} {totalPages}\n </span>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => onPageChange(page + 1)}\n className=\"rounded border border-border-default px-3 py-1 transition-colors hover:bg-bg-surface disabled:opacity-50\"\n >\n {tr('audit.next', 'Next')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAuBA,IAAM,IAA6E;CACjF,SAAS;CACT,SAAS;CACT,QAAQ;CACR,OAAO;CACR,EAEK,IAAuC;CAC3C,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,SAAS;CACT,SAAS;CACV;AAED,SAAS,EAAW,GAA4B;AAE9C,QADa,IAAI,KAAK,EAAW,CACrB,eAAe,SAAS;EAClC,OAAO;EACP,KAAK;EACL,MAAM;EACN,QAAQ;EACR,QAAQ;EACT,CAAC;;AAGJ,SAAS,EAAmB,GAAsB;AAChD,QAAO,EACJ,QAAQ,MAAM,IAAI,CAClB,aAAa,CACb,QAAQ,UAAU,MAAc,EAAU,aAAa,CAAC;;AAG7D,SAAgB,EAAc,EAC5B,UACA,UACA,YACA,SACA,aACA,iBACA,gBACA,gBACA,kBACA,mBACA,uBACA,sBACA,yBACA,yBACqB;CACrB,IAAM,EAAE,SAAM,GAAS,EACjB,IAAa,KAAK,IAAI,GAAG,KAAK,KAAK,IAAQ,EAAS,CAAC,EAErD,KAAM,GAAa,MAAqB;EAC5C,IAAM,IAAQ,EAAE,EAAI;AACpB,SAAO,MAAU,IAAM,IAAW;;AAGpC,QACE,kBAAC,OAAD,EAAA,UAAA;EACE,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAM,KAAK,MAAS;IACnB,IAAM,IAAa,EAAe,IAAI,EAAK,GAAG;AAC9C,WACE,kBAAC,WAAD;KAEE,WAAW,iEACT,MAAkB,EAAK,KAAK,iBAAiB;eAHjD;MAME,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SACE,SAAS;SACT,WAAW,MAAY,EAAqB,EAAK,IAAI,EAAQ;SAC7D,WAAW,oBAAoB,EAAK;SACpC,WAAU;SACV,CAAA,EACF,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,KAAD;WAAG,WAAU;qBAA+B,EAAW,EAAK,UAAU;WAAK,CAAA;UAC3E,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAK,gBAAgB,EAAK,eAAe;WACxC,CAAA;UACJ,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAmB,EAAK,aAAa;WACpC,CAAA;UACA;WACF;WACN,kBAAC,QAAD;QACE,WAAW,mFACT,EAAa,EAAK,WAAW;kBAFjC,CAKG,EAAK,UAAU,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA,GAAG,MACxC,EAAK,OACD;UACH;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAb,EACI,EAAK,aAAa,WAAW,aAAa,CAAC,QAAQ,MAAM,IAAI,EAC9D,EAAK,eAAe,MAAM,EAAK,iBAAiB,GAC/C;WACJ,kBAAC,GAAD;QACE,QAAQ,EAAK;QACb,SAAS,EAAiB,EAAK;QAC/B,MAAK;QACL,CAAA,CACE;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAY,EAAK,GAAG;QACnC,WAAU;kBAHZ,CAIC,gBAEC,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA,CACnB;WACT,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAY,EAAK,GAAG;QACnC,WAAU;QACV,OAAO,EAAG,wBAAwB,mBAAmB;kBAErD,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;QACb,CAAA,CACL;;MACE;OA7DH,EAAK,GA6DF;KAEZ;GACE,CAAA;EAEN,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,SAAD;IAAO,WAAU;cAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;KAAI,WAAU;eAAd;MACE,kBAAC,MAAD;OAAI,WAAU;iBACZ,kBAAC,GAAD;QACE,SAAS;QACT,eAAe;QACf,UAAU;QACV,WAAU;QACV,CAAA;OACC,CAAA;MACL,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,cAAc,OAAO;OACtB,CAAA;MACL,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,gBAAgB,SAAS;OAC1B,CAAA;MACL,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,kBAAkB,WAAW;OAC9B,CAAA;MACL,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,cAAc,OAAO;OACtB,CAAA;MACL,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,eAAe,QAAQ;OACxB,CAAA;MACL,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,gBAAgB,SAAS;OAC1B,CAAA;MACL,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,iBAAiB,UAAU;OAC5B,CAAA;MACF;QACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAM,KAAK,MAAS;KACnB,IAAM,IAAa,EAAe,IAAI,EAAK,GAAG;AAC9C,YACE,kBAAC,MAAD;MAEE,WAAW,sEACT,MAAkB,EAAK,KAAK,iBAAiB;gBAHjD;OAME,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,GAAD;SACE,SAAS;SACT,WAAW,MAAY,EAAqB,EAAK,IAAI,EAAQ;SAC7D,WAAW,oBAAoB,EAAK;SACpC,CAAA;QACC,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAW,EAAK,UAAU;QACxB,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,QAAD;SACE,WAAW,0EACT,EAAa,EAAK,WAAW;mBAFjC,CAKG,EAAK,UAAU,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA,GAAG,MACxC,EAAK,OACD;;QACJ,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAmB,EAAK,aAAa;QACnC,CAAA;OACL,kBAAC,MAAD;QACE,WAAU;QACV,OAAO,EAAK,gBAAgB,EAAK,eAAe;kBAE/C,EAAK,gBAAgB,EAAK,eAAe;QACvC,CAAA;OACL,kBAAC,MAAD;QACE,WAAU;QACV,OAAO,EAAK;mBAEV,EAAK,aAAa,WAAW,aAAa,CAAC,QAAQ,MAAM,IAAI;QAC5D,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,GAAD;SACE,QAAQ,EAAK;SACb,SAAS,EAAiB,EAAK;SAC/B,MAAK;SACL,CAAA;QACC,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,UAAD;UACE,MAAK;UACL,eAAe,EAAY,EAAK,GAAG;UACnC,WAAU;UACV,OAAO,EAAG,sBAAsB,eAAe;oBAE/C,kBAAC,GAAD,EAAc,MAAM,IAAM,CAAA;UACnB,CAAA,EACT,kBAAC,UAAD;UACE,MAAK;UACL,eAAe,EAAY,EAAK,GAAG;UACnC,WAAU;UACV,OAAO,EAAG,wBAAwB,mBAAmB;oBAErD,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;UACb,CAAA,CACL;;QACH,CAAA;OACF;QAnEE,EAAK,GAmEP;MAEP,EACI,CAAA,CACF;;GACJ,CAAA;EAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,QAAD,EAAA,UAAA;IACG,EAAG,iBAAiB,UAAU;IAAC;IAAE,IAAO,IAAW;IAAE;IACrD,KAAK,KAAK,IAAO,KAAK,GAAU,EAAM;IAAC;IAAE,EAAG,YAAY,KAAK;IAAC;IAAE;IAC5D,EAAA,CAAA,EACP,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,MAAS;MACnB,eAAe,EAAa,IAAO,EAAE;MACrC,WAAU;gBAET,EAAG,kBAAkB,WAAW;MAC1B,CAAA;KACT,kBAAC,QAAD,EAAA,UAAA;MACG,EAAG,cAAc,OAAO;MAAC;MAAE,IAAO;MAAE;MAAE,EAAG,YAAY,KAAK;MAAC;MAAE;MACzD,EAAA,CAAA;KACP,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,CAAC;MACX,eAAe,EAAa,IAAO,EAAE;MACrC,WAAU;gBAET,EAAG,cAAc,OAAO;MAClB,CAAA;KACL;MACF;;EACF,EAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"AuditLogTable.js","names":[],"sources":["../../../src/components/audit/AuditLogTable.tsx"],"sourcesContent":["import { ChevronRight, Terminal } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { StatusBadge } from '@/components/shared';\nimport type { VibeAuditLogFieldsFragment } from '@/generated/wspace-operations';\n\ninterface AuditLogTableProps {\n items: VibeAuditLogFieldsFragment[];\n total: number;\n hasMore: boolean;\n page: number;\n pageSize: number;\n onPageChange: (page: number) => void;\n onSelectLog: (id: string) => void;\n selectedLogId: string | null;\n}\n\nconst statusVariantMap: Record<string, 'success' | 'error' | 'warning' | 'info'> = {\n SUCCESS: 'success',\n FAILURE: 'error',\n DENIED: 'warning',\n ERROR: 'error',\n};\n\nconst actionColors: Record<string, string> = {\n CREATE: 'bg-status-success-bg-subtle text-status-success-text',\n UPDATE: 'bg-status-info-bg-subtle text-status-info-text',\n DELETE: 'bg-status-error-bg-subtle text-status-error-text',\n EXECUTE: 'bg-[var(--color-accent-soft)] text-text-primary',\n EXPORT: 'bg-status-warning-bg-subtle text-status-warning-text',\n SHARE: 'bg-status-success-bg-subtle text-status-success-text',\n REVOKE: 'bg-status-warning-bg-subtle text-status-warning-text',\n ARCHIVE: 'bg-bg-sunken text-text-secondary',\n RESTORE: 'bg-status-info-bg-subtle text-status-info-text',\n};\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleString('en-US', {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n}\n\nfunction formatResourceType(type: string): string {\n return type\n .replace(/_/g, ' ')\n .toLowerCase()\n .replace(/\\b\\w/g, (character) => character.toUpperCase());\n}\n\nexport function AuditLogTable({\n items,\n total,\n hasMore,\n page,\n pageSize,\n onPageChange,\n onSelectLog,\n selectedLogId,\n}: AuditLogTableProps) {\n const { t } = useI18n();\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n\n const tr = (key: string, fallback: string) => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n return (\n <div>\n <div className=\"space-y-3 md:hidden\">\n {items.map((item) => {\n return (\n <article\n key={item.id}\n className={`rounded-lg border border-border-default p-4 transition-colors ${\n selectedLogId === item.id ? 'bg-bg-sunken' : 'bg-bg-surface'\n }`}\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <p className=\"text-xs text-text-secondary\">{formatDate(item.createdAt)}</p>\n <p className=\"mt-1 truncate font-medium text-text-primary\">\n {item.resourceName || item.description || '-'}\n </p>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {formatResourceType(item.resourceType)}\n </p>\n </div>\n <span\n className={`inline-flex shrink-0 items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${\n actionColors[item.action] || 'bg-bg-surface text-text-secondary'\n }`}\n >\n {item.command ? <Terminal size={12} /> : null}\n {item.action}\n </span>\n </div>\n <div className=\"mt-3 flex items-center justify-between gap-3\">\n <p className=\"min-w-0 truncate text-xs capitalize text-text-secondary\">\n {(item.actorType || 'unknown').toLowerCase().replace(/_/g, ' ')}\n {item.resourceName ? ` · ${item.resourceName}` : ''}\n </p>\n <StatusBadge\n status={item.status}\n variant={statusVariantMap[item.status]}\n size=\"sm\"\n />\n </div>\n <div className=\"mt-4 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n onClick={() => onSelectLog(item.id)}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-default px-3 py-1.5 text-sm text-text-primary transition-colors hover:bg-bg-surface\"\n >\n View details\n <ChevronRight size={14} />\n </button>\n </div>\n </article>\n );\n })}\n </div>\n\n <div className=\"hidden overflow-x-auto rounded-card border border-border-subtle bg-bg-surface shadow-elevation-1 md:block\">\n <table className=\"w-full min-w-[860px] text-sm\">\n <thead>\n <tr className=\"border-b border-border-subtle bg-bg-sunken\">\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.time', 'Time')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.action', 'Action')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.resource', 'Resource')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.name', 'Name')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.actor', 'Actor')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.status', 'Status')}\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-text-muted\">\n {tr('audit.actions', 'Actions')}\n </th>\n </tr>\n </thead>\n <tbody>\n {items.map((item) => {\n return (\n <tr\n key={item.id}\n className={`border-b border-border-subtle transition-colors hover:bg-bg-sunken ${\n selectedLogId === item.id ? 'bg-bg-sunken' : ''\n }`}\n >\n <td className=\"whitespace-nowrap px-4 py-3 text-xs text-text-secondary\">\n {formatDate(item.createdAt)}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex items-center gap-1 rounded px-2 py-0.5 text-xs font-medium ${\n actionColors[item.action] || 'bg-bg-surface text-text-secondary'\n }`}\n >\n {item.command ? <Terminal size={12} /> : null}\n {item.action}\n </span>\n </td>\n <td className=\"px-4 py-3 text-xs text-text-secondary\">\n {formatResourceType(item.resourceType)}\n </td>\n <td\n className=\"max-w-[220px] truncate px-4 py-3\"\n title={item.resourceName || item.description || ''}\n >\n {item.resourceName || item.description || '-'}\n </td>\n <td\n className=\"max-w-[140px] truncate px-4 py-3 text-xs capitalize text-text-secondary\"\n title={item.actorId}\n >\n {(item.actorType || 'unknown').toLowerCase().replace(/_/g, ' ')}\n </td>\n <td className=\"px-4 py-3\">\n <StatusBadge\n status={item.status}\n variant={statusVariantMap[item.status]}\n size=\"sm\"\n />\n </td>\n <td className=\"px-4 py-3 text-right\">\n <div className=\"flex items-center justify-end gap-1\">\n <button\n type=\"button\"\n onClick={() => onSelectLog(item.id)}\n className=\"rounded p-1 text-text-secondary transition-colors hover:bg-bg-surface hover:text-text-primary\"\n title={tr('audit.viewAuditLog', 'View details')}\n >\n <ChevronRight size={14} />\n </button>\n </div>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n\n <div className=\"mt-4 flex flex-col gap-3 text-sm text-text-secondary sm:flex-row sm:items-center sm:justify-between\">\n <span>\n {tr('audit.showing', 'Showing')} {page * pageSize + 1}-\n {Math.min((page + 1) * pageSize, total)} {tr('audit.of', 'of')} {total}\n </span>\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n disabled={page === 0}\n onClick={() => onPageChange(page - 1)}\n className=\"rounded border border-border-default px-3 py-1 transition-colors hover:bg-bg-surface disabled:opacity-50\"\n >\n {tr('audit.previous', 'Previous')}\n </button>\n <span>\n {tr('audit.page', 'Page')} {page + 1} {tr('audit.of', 'of')} {totalPages}\n </span>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => onPageChange(page + 1)}\n className=\"rounded border border-border-default px-3 py-1 transition-colors hover:bg-bg-surface disabled:opacity-50\"\n >\n {tr('audit.next', 'Next')}\n </button>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -101,7 +101,6 @@ var e = {
|
|
|
101
101
|
INSTRUCTION_FILE_SHARE: "instruction-file:share",
|
|
102
102
|
AUDIT_LIST: "audit:list",
|
|
103
103
|
AUDIT_READ: "audit:read",
|
|
104
|
-
AUDIT_DELETE: "audit:delete",
|
|
105
104
|
AUDIT_EXPORT: "audit:export",
|
|
106
105
|
TARGET_LIST: "target:list",
|
|
107
106
|
TARGET_READ: "target:read",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.js","names":[],"sources":["../../src/constants/permissions.ts"],"sourcesContent":["/**\n * VibeControls Permission Constants\n *\n * All permission strings for VibeControls resources.\n * Use with fe-libs usePermissions hook: hasPermission(VIBE_PERMISSIONS.VIBE_CREATE)\n *\n * IMPORTANT — only strings present in the wspace-rbac-svc seed\n * (`prisma/seed-unified-rbac.ts` ACTION_DEFINITIONS) are ever returned by\n * `myPermissions`/`hasPermission`. Gating on a string the seed does NOT\n * define makes `hasPermission` return false for EVERYONE → a full lockout.\n *\n * Read/CRUD for catalog, component, template, ai-context, ai-prompt,\n * instruction-file and docs_site were seeded in the BOFF-2034 follow-up, so\n * their pages now gate on their own resource (no more `vibe:list` proxy).\n * The new resourceTypes added in that pass (scorecard, aitoolevent,\n * docs_page, docs_revision, docs_build_image) only reach ALREADY-EXISTING\n * workspaces after their cloned roles are re-synced — do NOT hard-gate a\n * page on those until the backfill has run, or pre-existing workspaces lock\n * out.\n *\n * Resource types:\n * - vibe: list, read, create, update, delete, scan, manage\n * - agent: list, read, create, update, delete, admin, mutate, invoke\n * - session: list, read, create, update, delete, execute\n * - note: list, read, create, update, delete\n * - webhook: list, read, create, update, delete\n * - action: list, read, create, update, delete, execute\n * - calendar-agent-task: list, read, create, update, delete, execute\n * - configuration: list, read, create, update, delete\n * - docs_site: list, read, create, update, delete, execute\n * - docs_page: list, read, create, update, delete\n * - target: list, read, create, update, delete\n * - tunnel: list, read, create, delete\n * - analytics: list, read\n * - log: list, read\n */\n\nexport const VIBE_PERMISSIONS = {\n // Vibe resources\n VIBE_LIST: 'vibe:list',\n VIBE_READ: 'vibe:read',\n VIBE_CREATE: 'vibe:create',\n VIBE_UPDATE: 'vibe:update',\n VIBE_DELETE: 'vibe:delete',\n VIBE_SCAN: 'vibe:scan',\n VIBE_MANAGE: 'vibe:manage',\n\n // Agent resources\n AGENT_LIST: 'agent:list',\n AGENT_READ: 'agent:read',\n AGENT_CREATE: 'agent:create',\n AGENT_UPDATE: 'agent:update',\n AGENT_DELETE: 'agent:delete',\n // Elevated agent control-plane actions (gateway enforces these on\n // remote-exec / credential / code-server control mutations).\n AGENT_ADMIN: 'agent:admin', // set/rotate API key, nuke, dry-run\n AGENT_MUTATE: 'agent:mutate', // code-server start/stop, plugin install\n AGENT_INVOKE: 'agent:invoke', // execute scheduled prompt, mint agent capabilities\n\n // Agent message bookmark resources\n AGENT_MESSAGE_BOOKMARK_READ: 'agent-message-bookmark:read',\n AGENT_MESSAGE_BOOKMARK_CREATE: 'agent-message-bookmark:create',\n AGENT_MESSAGE_BOOKMARK_UPDATE: 'agent-message-bookmark:update',\n AGENT_MESSAGE_BOOKMARK_DELETE: 'agent-message-bookmark:delete',\n\n // Integration connection resources\n INTEGRATION_CONNECTION_READ: 'integration-connection:read',\n\n // Session resources\n SESSION_LIST: 'session:list',\n SESSION_READ: 'session:read',\n SESSION_CREATE: 'session:create',\n SESSION_UPDATE: 'session:update',\n SESSION_DELETE: 'session:delete',\n SESSION_EXECUTE: 'session:execute',\n SESSION_SHARE: 'session:share',\n\n // Note resources\n NOTE_LIST: 'note:list',\n NOTE_READ: 'note:read',\n NOTE_CREATE: 'note:create',\n NOTE_UPDATE: 'note:update',\n NOTE_DELETE: 'note:delete',\n\n // Webhook resources\n WEBHOOK_LIST: 'webhook:list',\n WEBHOOK_READ: 'webhook:read',\n WEBHOOK_CREATE: 'webhook:create',\n WEBHOOK_UPDATE: 'webhook:update',\n WEBHOOK_DELETE: 'webhook:delete',\n // `testWebhook` / `triggerWebhook` enforce `webhook:execute` (seeded).\n WEBHOOK_EXECUTE: 'webhook:execute',\n\n // VibeDeck resources\n VIBEDECK_LIST: 'vibedeck:list',\n VIBEDECK_READ: 'vibedeck:read',\n VIBEDECK_CREATE: 'vibedeck:create',\n VIBEDECK_UPDATE: 'vibedeck:update',\n VIBEDECK_DELETE: 'vibedeck:delete',\n VIBEDECK_EXECUTE: 'vibedeck:execute',\n VIBEDECK_SHARE: 'vibedeck:share',\n\n // VibeDeck button resources — sub-resource of vibedeck. The svc enforces\n // `vibedeck-button:*` on the button CRUD/execute mutations in vibedeck.gql\n // (seeded in BOFF-2659, defaults mirror vibedeck). Since it is a newer\n // resourceType, gate with the fail-open \"registered\" guard (fall back to the\n // parent `vibedeck:*` grant when the button perms aren't in the actor's set)\n // so pre-backfill workspaces don't lock out.\n VIBEDECK_BUTTON_LIST: 'vibedeck-button:list',\n VIBEDECK_BUTTON_READ: 'vibedeck-button:read',\n VIBEDECK_BUTTON_CREATE: 'vibedeck-button:create',\n VIBEDECK_BUTTON_UPDATE: 'vibedeck-button:update',\n VIBEDECK_BUTTON_DELETE: 'vibedeck-button:delete',\n VIBEDECK_BUTTON_EXECUTE: 'vibedeck-button:execute',\n\n // Calendar Agent Task resources\n CALENDAR_AGENT_TASK_LIST: 'calendar-agent-task:list',\n CALENDAR_AGENT_TASK_READ: 'calendar-agent-task:read',\n CALENDAR_AGENT_TASK_CREATE: 'calendar-agent-task:create',\n CALENDAR_AGENT_TASK_UPDATE: 'calendar-agent-task:update',\n CALENDAR_AGENT_TASK_DELETE: 'calendar-agent-task:delete',\n CALENDAR_AGENT_TASK_EXECUTE: 'calendar-agent-task:execute',\n\n // Schedule resources (wspace-scheduler-svc — the unified-source\n // ScheduledJobs surfaced on the Calendar agenda live here).\n // `scheduledJob`/`scheduledJobs` enforce `schedule:read`;\n // `executeJobNow` enforces `schedule:execute`. Distinct from\n // `calendar-agent-task:*` so RBAC denials don't cross-bleed\n // between the two services.\n SCHEDULE_LIST: 'schedule:list',\n SCHEDULE_READ: 'schedule:read',\n SCHEDULE_EXECUTE: 'schedule:execute',\n\n // Configuration resources\n CONFIG_LIST: 'configuration:list',\n CONFIG_READ: 'configuration:read',\n CONFIG_CREATE: 'configuration:create',\n CONFIG_UPDATE: 'configuration:update',\n CONFIG_DELETE: 'configuration:delete',\n\n // Docs Site resources\n DOCS_SITE_LIST: 'docs_site:list',\n DOCS_SITE_READ: 'docs_site:read',\n DOCS_SITE_CREATE: 'docs_site:create',\n DOCS_SITE_UPDATE: 'docs_site:update',\n DOCS_SITE_DELETE: 'docs_site:delete',\n DOCS_COMPILE: 'docs_site:execute',\n\n // Docs Page resources\n DOCS_PAGE_LIST: 'docs_page:list',\n DOCS_PAGE_READ: 'docs_page:read',\n DOCS_PAGE_CREATE: 'docs_page:create',\n DOCS_PAGE_UPDATE: 'docs_page:update',\n DOCS_PAGE_DELETE: 'docs_page:delete',\n // Docs Site generic-sharing surface (backend `shareDocs`, @rbac resource `docs_site`)\n DOCS_SITE_SHARE: 'docs_site:share',\n\n // Action resources\n ACTION_LIST: 'action:list',\n ACTION_READ: 'action:read',\n ACTION_CREATE: 'action:create',\n ACTION_UPDATE: 'action:update',\n ACTION_DELETE: 'action:delete',\n ACTION_EXECUTE: 'action:execute',\n ACTION_SHARE: 'action:share',\n\n // AI Prompt resources (read/CRUD seeded in BOFF-2034 follow-up)\n AIPROMPT_READ: 'ai-prompt:read',\n AIPROMPT_CREATE: 'ai-prompt:create',\n AIPROMPT_UPDATE: 'ai-prompt:update',\n AIPROMPT_DELETE: 'ai-prompt:delete',\n AIPROMPT_SHARE: 'ai-prompt:share',\n\n // AI Context resources (read/CRUD seeded in BOFF-2034 follow-up)\n AICONTEXT_READ: 'ai-context:read',\n AICONTEXT_CREATE: 'ai-context:create',\n AICONTEXT_UPDATE: 'ai-context:update',\n AICONTEXT_DELETE: 'ai-context:delete',\n AICONTEXT_SHARE: 'ai-context:share',\n\n // Agent Instruction File resources (read/CRUD seeded in BOFF-2034 follow-up)\n INSTRUCTION_FILE_READ: 'instruction-file:read',\n INSTRUCTION_FILE_CREATE: 'instruction-file:create',\n INSTRUCTION_FILE_UPDATE: 'instruction-file:update',\n INSTRUCTION_FILE_DELETE: 'instruction-file:delete',\n INSTRUCTION_FILE_SHARE: 'instruction-file:share',\n\n // Audit resources\n AUDIT_LIST: 'audit:list',\n AUDIT_READ: 'audit:read',\n AUDIT_DELETE: 'audit:delete',\n AUDIT_EXPORT: 'audit:export',\n\n // Target resources — guards wired in BOFF-2034 (Remaining Pages Audit)\n TARGET_LIST: 'target:list',\n TARGET_READ: 'target:read',\n TARGET_CREATE: 'target:create',\n TARGET_UPDATE: 'target:update',\n TARGET_DELETE: 'target:delete',\n // Target generic-sharing surface (backend `shareTarget`, @rbac resource `target`)\n TARGET_SHARE: 'target:share',\n\n // Catalog resources (read/CRUD seeded in BOFF-2034 follow-up)\n CATALOG_READ: 'catalog:read',\n CATALOG_CREATE: 'catalog:create',\n CATALOG_UPDATE: 'catalog:update',\n CATALOG_DELETE: 'catalog:delete',\n CATALOG_SHARE: 'catalog:share',\n\n // Component resources (read/CRUD seeded in BOFF-2034 follow-up)\n COMPONENT_READ: 'component:read',\n COMPONENT_CREATE: 'component:create',\n COMPONENT_UPDATE: 'component:update',\n COMPONENT_DELETE: 'component:delete',\n COMPONENT_SHARE: 'component:share',\n\n // Template resources (read/CRUD seeded in BOFF-2034 follow-up)\n TEMPLATE_READ: 'template:read',\n TEMPLATE_CREATE: 'template:create',\n TEMPLATE_UPDATE: 'template:update',\n TEMPLATE_DELETE: 'template:delete',\n TEMPLATE_SHARE: 'template:share',\n\n // Scorecard resources. NOTE: `scorecard` is a NEW resourceType — pre-existing\n // workspaces only grant these after their cloned roles are re-synced, so do\n // not hard-gate a page on scorecard:* until that backfill has run.\n SCORECARD_READ: 'scorecard:read',\n SCORECARD_CREATE: 'scorecard:create',\n SCORECARD_UPDATE: 'scorecard:update',\n SCORECARD_DELETE: 'scorecard:delete',\n SCORECARD_SHARE: 'scorecard:share',\n\n // Tunnel resources. The svc enforces `tunnel:read` on list/detail queries\n // (there is no seeded `tunnel:list`), `tunnel:execute` on start/stop/session\n // control, and `tunnel:update` on edits.\n TUNNEL_READ: 'tunnel:read',\n TUNNEL_CREATE: 'tunnel:create',\n TUNNEL_UPDATE: 'tunnel:update',\n TUNNEL_DELETE: 'tunnel:delete',\n TUNNEL_EXECUTE: 'tunnel:execute',\n TUNNEL_SHARE: 'tunnel:share',\n\n // Analytics resources\n ANALYTICS_LIST: 'analytics:list',\n ANALYTICS_READ: 'analytics:read',\n\n // Log resources\n LOG_LIST: 'log:list',\n LOG_READ: 'log:read',\n} as const;\n\nexport type VibePermission = (typeof VIBE_PERMISSIONS)[keyof typeof VIBE_PERMISSIONS];\n"],"mappings":";AAqCA,IAAa,IAAmB;CAE9B,WAAW;CACX,WAAW;CACX,aAAa;CACb,aAAa;CACb,aAAa;CACb,WAAW;CACX,aAAa;CAGb,YAAY;CACZ,YAAY;CACZ,cAAc;CACd,cAAc;CACd,cAAc;CAGd,aAAa;CACb,cAAc;CACd,cAAc;CAGd,6BAA6B;CAC7B,+BAA+B;CAC/B,+BAA+B;CAC/B,+BAA+B;CAG/B,6BAA6B;CAG7B,cAAc;CACd,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAChB,iBAAiB;CACjB,eAAe;CAGf,WAAW;CACX,WAAW;CACX,aAAa;CACb,aAAa;CACb,aAAa;CAGb,cAAc;CACd,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAEhB,iBAAiB;CAGjB,eAAe;CACf,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,kBAAkB;CAClB,gBAAgB;CAQhB,sBAAsB;CACtB,sBAAsB;CACtB,wBAAwB;CACxB,wBAAwB;CACxB,wBAAwB;CACxB,yBAAyB;CAGzB,0BAA0B;CAC1B,0BAA0B;CAC1B,4BAA4B;CAC5B,4BAA4B;CAC5B,4BAA4B;CAC5B,6BAA6B;CAQ7B,eAAe;CACf,eAAe;CACf,kBAAkB;CAGlB,aAAa;CACb,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CAGf,gBAAgB;CAChB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,cAAc;CAGd,gBAAgB;CAChB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAElB,iBAAiB;CAGjB,aAAa;CACb,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CACf,gBAAgB;CAChB,cAAc;CAGd,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,gBAAgB;CAGhB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CAGjB,uBAAuB;CACvB,yBAAyB;CACzB,yBAAyB;CACzB,yBAAyB;CACzB,wBAAwB;CAGxB,YAAY;CACZ,YAAY;CACZ,cAAc;CACd,cAAc;CAGd,aAAa;CACb,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CAEf,cAAc;CAGd,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAChB,eAAe;CAGf,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CAGjB,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,gBAAgB;CAKhB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CAKjB,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CACf,gBAAgB;CAChB,cAAc;CAGd,gBAAgB;CAChB,gBAAgB;CAGhB,UAAU;CACV,UAAU;CACX"}
|
|
1
|
+
{"version":3,"file":"permissions.js","names":[],"sources":["../../src/constants/permissions.ts"],"sourcesContent":["/**\n * VibeControls Permission Constants\n *\n * All permission strings for VibeControls resources.\n * Use with fe-libs usePermissions hook: hasPermission(VIBE_PERMISSIONS.VIBE_CREATE)\n *\n * IMPORTANT — only strings present in the wspace-rbac-svc seed\n * (`prisma/seed-unified-rbac.ts` ACTION_DEFINITIONS) are ever returned by\n * `myPermissions`/`hasPermission`. Gating on a string the seed does NOT\n * define makes `hasPermission` return false for EVERYONE → a full lockout.\n *\n * Read/CRUD for catalog, component, template, ai-context, ai-prompt,\n * instruction-file and docs_site were seeded in the BOFF-2034 follow-up, so\n * their pages now gate on their own resource (no more `vibe:list` proxy).\n * The new resourceTypes added in that pass (scorecard, aitoolevent,\n * docs_page, docs_revision, docs_build_image) only reach ALREADY-EXISTING\n * workspaces after their cloned roles are re-synced — do NOT hard-gate a\n * page on those until the backfill has run, or pre-existing workspaces lock\n * out.\n *\n * Resource types:\n * - vibe: list, read, create, update, delete, scan, manage\n * - agent: list, read, create, update, delete, admin, mutate, invoke\n * - session: list, read, create, update, delete, execute\n * - note: list, read, create, update, delete\n * - webhook: list, read, create, update, delete\n * - action: list, read, create, update, delete, execute\n * - calendar-agent-task: list, read, create, update, delete, execute\n * - configuration: list, read, create, update, delete\n * - docs_site: list, read, create, update, delete, execute\n * - docs_page: list, read, create, update, delete\n * - target: list, read, create, update, delete\n * - tunnel: list, read, create, delete\n * - analytics: list, read\n * - log: list, read\n */\n\nexport const VIBE_PERMISSIONS = {\n // Vibe resources\n VIBE_LIST: 'vibe:list',\n VIBE_READ: 'vibe:read',\n VIBE_CREATE: 'vibe:create',\n VIBE_UPDATE: 'vibe:update',\n VIBE_DELETE: 'vibe:delete',\n VIBE_SCAN: 'vibe:scan',\n VIBE_MANAGE: 'vibe:manage',\n\n // Agent resources\n AGENT_LIST: 'agent:list',\n AGENT_READ: 'agent:read',\n AGENT_CREATE: 'agent:create',\n AGENT_UPDATE: 'agent:update',\n AGENT_DELETE: 'agent:delete',\n // Elevated agent control-plane actions (gateway enforces these on\n // remote-exec / credential / code-server control mutations).\n AGENT_ADMIN: 'agent:admin', // set/rotate API key, nuke, dry-run\n AGENT_MUTATE: 'agent:mutate', // code-server start/stop, plugin install\n AGENT_INVOKE: 'agent:invoke', // execute scheduled prompt, mint agent capabilities\n\n // Agent message bookmark resources\n AGENT_MESSAGE_BOOKMARK_READ: 'agent-message-bookmark:read',\n AGENT_MESSAGE_BOOKMARK_CREATE: 'agent-message-bookmark:create',\n AGENT_MESSAGE_BOOKMARK_UPDATE: 'agent-message-bookmark:update',\n AGENT_MESSAGE_BOOKMARK_DELETE: 'agent-message-bookmark:delete',\n\n // Integration connection resources\n INTEGRATION_CONNECTION_READ: 'integration-connection:read',\n\n // Session resources\n SESSION_LIST: 'session:list',\n SESSION_READ: 'session:read',\n SESSION_CREATE: 'session:create',\n SESSION_UPDATE: 'session:update',\n SESSION_DELETE: 'session:delete',\n SESSION_EXECUTE: 'session:execute',\n SESSION_SHARE: 'session:share',\n\n // Note resources\n NOTE_LIST: 'note:list',\n NOTE_READ: 'note:read',\n NOTE_CREATE: 'note:create',\n NOTE_UPDATE: 'note:update',\n NOTE_DELETE: 'note:delete',\n\n // Webhook resources\n WEBHOOK_LIST: 'webhook:list',\n WEBHOOK_READ: 'webhook:read',\n WEBHOOK_CREATE: 'webhook:create',\n WEBHOOK_UPDATE: 'webhook:update',\n WEBHOOK_DELETE: 'webhook:delete',\n // `testWebhook` / `triggerWebhook` enforce `webhook:execute` (seeded).\n WEBHOOK_EXECUTE: 'webhook:execute',\n\n // VibeDeck resources\n VIBEDECK_LIST: 'vibedeck:list',\n VIBEDECK_READ: 'vibedeck:read',\n VIBEDECK_CREATE: 'vibedeck:create',\n VIBEDECK_UPDATE: 'vibedeck:update',\n VIBEDECK_DELETE: 'vibedeck:delete',\n VIBEDECK_EXECUTE: 'vibedeck:execute',\n VIBEDECK_SHARE: 'vibedeck:share',\n\n // VibeDeck button resources — sub-resource of vibedeck. The svc enforces\n // `vibedeck-button:*` on the button CRUD/execute mutations in vibedeck.gql\n // (seeded in BOFF-2659, defaults mirror vibedeck). Since it is a newer\n // resourceType, gate with the fail-open \"registered\" guard (fall back to the\n // parent `vibedeck:*` grant when the button perms aren't in the actor's set)\n // so pre-backfill workspaces don't lock out.\n VIBEDECK_BUTTON_LIST: 'vibedeck-button:list',\n VIBEDECK_BUTTON_READ: 'vibedeck-button:read',\n VIBEDECK_BUTTON_CREATE: 'vibedeck-button:create',\n VIBEDECK_BUTTON_UPDATE: 'vibedeck-button:update',\n VIBEDECK_BUTTON_DELETE: 'vibedeck-button:delete',\n VIBEDECK_BUTTON_EXECUTE: 'vibedeck-button:execute',\n\n // Calendar Agent Task resources\n CALENDAR_AGENT_TASK_LIST: 'calendar-agent-task:list',\n CALENDAR_AGENT_TASK_READ: 'calendar-agent-task:read',\n CALENDAR_AGENT_TASK_CREATE: 'calendar-agent-task:create',\n CALENDAR_AGENT_TASK_UPDATE: 'calendar-agent-task:update',\n CALENDAR_AGENT_TASK_DELETE: 'calendar-agent-task:delete',\n CALENDAR_AGENT_TASK_EXECUTE: 'calendar-agent-task:execute',\n\n // Schedule resources (wspace-scheduler-svc — the unified-source\n // ScheduledJobs surfaced on the Calendar agenda live here).\n // `scheduledJob`/`scheduledJobs` enforce `schedule:read`;\n // `executeJobNow` enforces `schedule:execute`. Distinct from\n // `calendar-agent-task:*` so RBAC denials don't cross-bleed\n // between the two services.\n SCHEDULE_LIST: 'schedule:list',\n SCHEDULE_READ: 'schedule:read',\n SCHEDULE_EXECUTE: 'schedule:execute',\n\n // Configuration resources\n CONFIG_LIST: 'configuration:list',\n CONFIG_READ: 'configuration:read',\n CONFIG_CREATE: 'configuration:create',\n CONFIG_UPDATE: 'configuration:update',\n CONFIG_DELETE: 'configuration:delete',\n\n // Docs Site resources\n DOCS_SITE_LIST: 'docs_site:list',\n DOCS_SITE_READ: 'docs_site:read',\n DOCS_SITE_CREATE: 'docs_site:create',\n DOCS_SITE_UPDATE: 'docs_site:update',\n DOCS_SITE_DELETE: 'docs_site:delete',\n DOCS_COMPILE: 'docs_site:execute',\n\n // Docs Page resources\n DOCS_PAGE_LIST: 'docs_page:list',\n DOCS_PAGE_READ: 'docs_page:read',\n DOCS_PAGE_CREATE: 'docs_page:create',\n DOCS_PAGE_UPDATE: 'docs_page:update',\n DOCS_PAGE_DELETE: 'docs_page:delete',\n // Docs Site generic-sharing surface (backend `shareDocs`, @rbac resource `docs_site`)\n DOCS_SITE_SHARE: 'docs_site:share',\n\n // Action resources\n ACTION_LIST: 'action:list',\n ACTION_READ: 'action:read',\n ACTION_CREATE: 'action:create',\n ACTION_UPDATE: 'action:update',\n ACTION_DELETE: 'action:delete',\n ACTION_EXECUTE: 'action:execute',\n ACTION_SHARE: 'action:share',\n\n // AI Prompt resources (read/CRUD seeded in BOFF-2034 follow-up)\n AIPROMPT_READ: 'ai-prompt:read',\n AIPROMPT_CREATE: 'ai-prompt:create',\n AIPROMPT_UPDATE: 'ai-prompt:update',\n AIPROMPT_DELETE: 'ai-prompt:delete',\n AIPROMPT_SHARE: 'ai-prompt:share',\n\n // AI Context resources (read/CRUD seeded in BOFF-2034 follow-up)\n AICONTEXT_READ: 'ai-context:read',\n AICONTEXT_CREATE: 'ai-context:create',\n AICONTEXT_UPDATE: 'ai-context:update',\n AICONTEXT_DELETE: 'ai-context:delete',\n AICONTEXT_SHARE: 'ai-context:share',\n\n // Agent Instruction File resources (read/CRUD seeded in BOFF-2034 follow-up)\n INSTRUCTION_FILE_READ: 'instruction-file:read',\n INSTRUCTION_FILE_CREATE: 'instruction-file:create',\n INSTRUCTION_FILE_UPDATE: 'instruction-file:update',\n INSTRUCTION_FILE_DELETE: 'instruction-file:delete',\n INSTRUCTION_FILE_SHARE: 'instruction-file:share',\n\n // Audit resources\n // BOFF-5164: AUDIT_DELETE removed — VibeAuditLog is write-once/append-only\n // for its mandatory 7-year retention window; no delete capability exists.\n AUDIT_LIST: 'audit:list',\n AUDIT_READ: 'audit:read',\n AUDIT_EXPORT: 'audit:export',\n\n // Target resources — guards wired in BOFF-2034 (Remaining Pages Audit)\n TARGET_LIST: 'target:list',\n TARGET_READ: 'target:read',\n TARGET_CREATE: 'target:create',\n TARGET_UPDATE: 'target:update',\n TARGET_DELETE: 'target:delete',\n // Target generic-sharing surface (backend `shareTarget`, @rbac resource `target`)\n TARGET_SHARE: 'target:share',\n\n // Catalog resources (read/CRUD seeded in BOFF-2034 follow-up)\n CATALOG_READ: 'catalog:read',\n CATALOG_CREATE: 'catalog:create',\n CATALOG_UPDATE: 'catalog:update',\n CATALOG_DELETE: 'catalog:delete',\n CATALOG_SHARE: 'catalog:share',\n\n // Component resources (read/CRUD seeded in BOFF-2034 follow-up)\n COMPONENT_READ: 'component:read',\n COMPONENT_CREATE: 'component:create',\n COMPONENT_UPDATE: 'component:update',\n COMPONENT_DELETE: 'component:delete',\n COMPONENT_SHARE: 'component:share',\n\n // Template resources (read/CRUD seeded in BOFF-2034 follow-up)\n TEMPLATE_READ: 'template:read',\n TEMPLATE_CREATE: 'template:create',\n TEMPLATE_UPDATE: 'template:update',\n TEMPLATE_DELETE: 'template:delete',\n TEMPLATE_SHARE: 'template:share',\n\n // Scorecard resources. NOTE: `scorecard` is a NEW resourceType — pre-existing\n // workspaces only grant these after their cloned roles are re-synced, so do\n // not hard-gate a page on scorecard:* until that backfill has run.\n SCORECARD_READ: 'scorecard:read',\n SCORECARD_CREATE: 'scorecard:create',\n SCORECARD_UPDATE: 'scorecard:update',\n SCORECARD_DELETE: 'scorecard:delete',\n SCORECARD_SHARE: 'scorecard:share',\n\n // Tunnel resources. The svc enforces `tunnel:read` on list/detail queries\n // (there is no seeded `tunnel:list`), `tunnel:execute` on start/stop/session\n // control, and `tunnel:update` on edits.\n TUNNEL_READ: 'tunnel:read',\n TUNNEL_CREATE: 'tunnel:create',\n TUNNEL_UPDATE: 'tunnel:update',\n TUNNEL_DELETE: 'tunnel:delete',\n TUNNEL_EXECUTE: 'tunnel:execute',\n TUNNEL_SHARE: 'tunnel:share',\n\n // Analytics resources\n ANALYTICS_LIST: 'analytics:list',\n ANALYTICS_READ: 'analytics:read',\n\n // Log resources\n LOG_LIST: 'log:list',\n LOG_READ: 'log:read',\n} as const;\n\nexport type VibePermission = (typeof VIBE_PERMISSIONS)[keyof typeof VIBE_PERMISSIONS];\n"],"mappings":";AAqCA,IAAa,IAAmB;CAE9B,WAAW;CACX,WAAW;CACX,aAAa;CACb,aAAa;CACb,aAAa;CACb,WAAW;CACX,aAAa;CAGb,YAAY;CACZ,YAAY;CACZ,cAAc;CACd,cAAc;CACd,cAAc;CAGd,aAAa;CACb,cAAc;CACd,cAAc;CAGd,6BAA6B;CAC7B,+BAA+B;CAC/B,+BAA+B;CAC/B,+BAA+B;CAG/B,6BAA6B;CAG7B,cAAc;CACd,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAChB,iBAAiB;CACjB,eAAe;CAGf,WAAW;CACX,WAAW;CACX,aAAa;CACb,aAAa;CACb,aAAa;CAGb,cAAc;CACd,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAEhB,iBAAiB;CAGjB,eAAe;CACf,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,kBAAkB;CAClB,gBAAgB;CAQhB,sBAAsB;CACtB,sBAAsB;CACtB,wBAAwB;CACxB,wBAAwB;CACxB,wBAAwB;CACxB,yBAAyB;CAGzB,0BAA0B;CAC1B,0BAA0B;CAC1B,4BAA4B;CAC5B,4BAA4B;CAC5B,4BAA4B;CAC5B,6BAA6B;CAQ7B,eAAe;CACf,eAAe;CACf,kBAAkB;CAGlB,aAAa;CACb,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CAGf,gBAAgB;CAChB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,cAAc;CAGd,gBAAgB;CAChB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAElB,iBAAiB;CAGjB,aAAa;CACb,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CACf,gBAAgB;CAChB,cAAc;CAGd,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,gBAAgB;CAGhB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CAGjB,uBAAuB;CACvB,yBAAyB;CACzB,yBAAyB;CACzB,yBAAyB;CACzB,wBAAwB;CAKxB,YAAY;CACZ,YAAY;CACZ,cAAc;CAGd,aAAa;CACb,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CAEf,cAAc;CAGd,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAChB,eAAe;CAGf,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CAGjB,eAAe;CACf,iBAAiB;CACjB,iBAAiB;CACjB,iBAAiB;CACjB,gBAAgB;CAKhB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CAKjB,aAAa;CACb,eAAe;CACf,eAAe;CACf,eAAe;CACf,gBAAgB;CAChB,cAAc;CAGd,gBAAgB;CAChB,gBAAgB;CAGhB,UAAU;CACV,UAAU;CACX"}
|