@archiva/archiva-nextjs 0.3.0 → 0.3.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/dist/react/client.d.mts +5 -1
- package/dist/react/client.d.ts +5 -1
- package/dist/react/client.js +219 -19
- package/dist/react/client.mjs +219 -19
- package/package.json +1 -1
package/dist/react/client.d.mts
CHANGED
|
@@ -22,8 +22,12 @@ type TimelineItem = {
|
|
|
22
22
|
};
|
|
23
23
|
type TimelineProps = {
|
|
24
24
|
entityId?: string;
|
|
25
|
+
tenantId?: string;
|
|
25
26
|
actorId?: string;
|
|
26
27
|
entityType?: string;
|
|
28
|
+
actionKey?: string;
|
|
29
|
+
actionDescription?: string;
|
|
30
|
+
actorType?: 'user' | 'service' | 'system' | ('user' | 'service' | 'system')[];
|
|
27
31
|
initialLimit?: number;
|
|
28
32
|
className?: string;
|
|
29
33
|
emptyMessage?: string;
|
|
@@ -34,7 +38,7 @@ type TimelineProps = {
|
|
|
34
38
|
className?: string;
|
|
35
39
|
}> | undefined;
|
|
36
40
|
};
|
|
37
|
-
declare function Timeline({ entityId, actorId, entityType, initialLimit, className, emptyMessage, showSearch, showFilters, showSystemAndServices, getActorAvatar, }: TimelineProps): react_jsx_runtime.JSX.Element;
|
|
41
|
+
declare function Timeline({ entityId, tenantId, actorId, entityType, actionKey, actionDescription, actorType, initialLimit, className, emptyMessage, showSearch, showFilters, showSystemAndServices, getActorAvatar, }: TimelineProps): react_jsx_runtime.JSX.Element;
|
|
38
42
|
|
|
39
43
|
type ArchivaContextValue = {
|
|
40
44
|
apiBaseUrl: string;
|
package/dist/react/client.d.ts
CHANGED
|
@@ -22,8 +22,12 @@ type TimelineItem = {
|
|
|
22
22
|
};
|
|
23
23
|
type TimelineProps = {
|
|
24
24
|
entityId?: string;
|
|
25
|
+
tenantId?: string;
|
|
25
26
|
actorId?: string;
|
|
26
27
|
entityType?: string;
|
|
28
|
+
actionKey?: string;
|
|
29
|
+
actionDescription?: string;
|
|
30
|
+
actorType?: 'user' | 'service' | 'system' | ('user' | 'service' | 'system')[];
|
|
27
31
|
initialLimit?: number;
|
|
28
32
|
className?: string;
|
|
29
33
|
emptyMessage?: string;
|
|
@@ -34,7 +38,7 @@ type TimelineProps = {
|
|
|
34
38
|
className?: string;
|
|
35
39
|
}> | undefined;
|
|
36
40
|
};
|
|
37
|
-
declare function Timeline({ entityId, actorId, entityType, initialLimit, className, emptyMessage, showSearch, showFilters, showSystemAndServices, getActorAvatar, }: TimelineProps): react_jsx_runtime.JSX.Element;
|
|
41
|
+
declare function Timeline({ entityId, tenantId, actorId, entityType, actionKey, actionDescription, actorType, initialLimit, className, emptyMessage, showSearch, showFilters, showSystemAndServices, getActorAvatar, }: TimelineProps): react_jsx_runtime.JSX.Element;
|
|
38
42
|
|
|
39
43
|
type ArchivaContextValue = {
|
|
40
44
|
apiBaseUrl: string;
|
package/dist/react/client.js
CHANGED
|
@@ -205,7 +205,7 @@ var CloudCogIcon = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime2.js
|
|
|
205
205
|
function eventToTimelineItem(event, getActorAvatar) {
|
|
206
206
|
const actionValue = event.actionKey || event.action || "";
|
|
207
207
|
const action = actionValue.charAt(0).toUpperCase() + actionValue.slice(1);
|
|
208
|
-
const description =
|
|
208
|
+
const description = event.actionDescription || "";
|
|
209
209
|
const actorId = event.actorId || "unknown";
|
|
210
210
|
const userName = actorId.includes(":") ? actorId.split(":")[1] || actorId : actorId;
|
|
211
211
|
const userHandle = userName;
|
|
@@ -252,7 +252,8 @@ function eventToTimelineItem(event, getActorAvatar) {
|
|
|
252
252
|
// Matches ActivityLog.tsx line 361
|
|
253
253
|
statusIndicator: false,
|
|
254
254
|
// Can be set to true for recent items - matches ActivityLog.tsx line 362
|
|
255
|
-
data: event
|
|
255
|
+
data: event,
|
|
256
|
+
badge: action
|
|
256
257
|
};
|
|
257
258
|
}
|
|
258
259
|
async function fetchEventsWithRetry(apiBaseUrl, getToken, forceRefreshToken, params) {
|
|
@@ -260,12 +261,18 @@ async function fetchEventsWithRetry(apiBaseUrl, getToken, forceRefreshToken, par
|
|
|
260
261
|
if (params.entityId) {
|
|
261
262
|
url.searchParams.set("entityId", params.entityId);
|
|
262
263
|
}
|
|
264
|
+
if (params.tenantId) {
|
|
265
|
+
url.searchParams.set("tenantId", params.tenantId);
|
|
266
|
+
}
|
|
263
267
|
if (params.actorId) {
|
|
264
268
|
url.searchParams.set("actorId", params.actorId);
|
|
265
269
|
}
|
|
266
270
|
if (params.entityType) {
|
|
267
271
|
url.searchParams.set("entityType", params.entityType);
|
|
268
272
|
}
|
|
273
|
+
if (params.actionKey) {
|
|
274
|
+
url.searchParams.set("actionKey", params.actionKey);
|
|
275
|
+
}
|
|
269
276
|
if (params.actorType) {
|
|
270
277
|
const actorTypeValue = Array.isArray(params.actorType) ? params.actorType.join(",") : params.actorType;
|
|
271
278
|
url.searchParams.set("actorType", actorTypeValue);
|
|
@@ -276,6 +283,9 @@ async function fetchEventsWithRetry(apiBaseUrl, getToken, forceRefreshToken, par
|
|
|
276
283
|
if (params.cursor) {
|
|
277
284
|
url.searchParams.set("cursor", params.cursor);
|
|
278
285
|
}
|
|
286
|
+
if (params.q) {
|
|
287
|
+
url.searchParams.set("q", params.q);
|
|
288
|
+
}
|
|
279
289
|
const makeRequest = async (token2) => {
|
|
280
290
|
return fetch(url.toString(), {
|
|
281
291
|
headers: {
|
|
@@ -408,8 +418,15 @@ function SimpleAvatar({
|
|
|
408
418
|
}
|
|
409
419
|
);
|
|
410
420
|
}
|
|
411
|
-
function applyClientSideFilters(events, searchQuery, showSystemAndServices) {
|
|
421
|
+
function applyClientSideFilters(events, searchQuery, showSystemAndServices, actionDescription) {
|
|
412
422
|
let filtered = events;
|
|
423
|
+
if (actionDescription) {
|
|
424
|
+
filtered = filtered.filter((event) => {
|
|
425
|
+
const eventActionDescription = (event.actionDescription || "").toLowerCase();
|
|
426
|
+
const filterActionDescription = actionDescription.toLowerCase();
|
|
427
|
+
return eventActionDescription.includes(filterActionDescription);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
413
430
|
if (!showSystemAndServices) {
|
|
414
431
|
filtered = filtered.filter((event) => {
|
|
415
432
|
if (event.actorType) {
|
|
@@ -428,13 +445,18 @@ function applyClientSideFilters(events, searchQuery, showSystemAndServices) {
|
|
|
428
445
|
const query = searchQuery.toLowerCase();
|
|
429
446
|
return filtered.filter((event) => {
|
|
430
447
|
const actionValue = (event.actionKey || event.action || "").toLowerCase();
|
|
431
|
-
|
|
448
|
+
const actionDescValue = (event.actionDescription || "").toLowerCase();
|
|
449
|
+
return actionValue.includes(query) || actionDescValue.includes(query) || event.entityType.toLowerCase().includes(query) || event.entityId.toLowerCase().includes(query) || event.actorId && event.actorId.toLowerCase().includes(query) || event.source && event.source.toLowerCase().includes(query) || event.actorDisplay && event.actorDisplay.toLowerCase().includes(query);
|
|
432
450
|
});
|
|
433
451
|
}
|
|
434
452
|
function Timeline({
|
|
435
453
|
entityId,
|
|
454
|
+
tenantId,
|
|
436
455
|
actorId,
|
|
437
456
|
entityType,
|
|
457
|
+
actionKey,
|
|
458
|
+
actionDescription,
|
|
459
|
+
actorType,
|
|
438
460
|
initialLimit = 100,
|
|
439
461
|
className,
|
|
440
462
|
emptyMessage = "No events yet.",
|
|
@@ -451,25 +473,64 @@ function Timeline({
|
|
|
451
473
|
const [error, setError] = React2.useState(null);
|
|
452
474
|
const [hasMore, setHasMore] = React2.useState(false);
|
|
453
475
|
const [searchQuery, setSearchQuery] = React2.useState("");
|
|
476
|
+
const baseFilters = React2.useMemo(() => {
|
|
477
|
+
const filters = {};
|
|
478
|
+
if (entityId) filters.entityId = entityId;
|
|
479
|
+
if (tenantId) filters.tenantId = tenantId;
|
|
480
|
+
if (actorId) filters.actorId = actorId;
|
|
481
|
+
if (entityType) filters.entityType = entityType;
|
|
482
|
+
if (actionKey) filters.actionKey = actionKey;
|
|
483
|
+
if (actorType) filters.actorType = actorType;
|
|
484
|
+
if (!showSystemAndServices && !actorType) {
|
|
485
|
+
filters.actorType = "user";
|
|
486
|
+
}
|
|
487
|
+
return filters;
|
|
488
|
+
}, [entityId, tenantId, actorId, entityType, actionKey, actorType, showSystemAndServices]);
|
|
489
|
+
const [uiFilters, setUiFilters] = React2.useState({});
|
|
490
|
+
const mergedFilters = React2.useMemo(() => {
|
|
491
|
+
const merged = {
|
|
492
|
+
...baseFilters,
|
|
493
|
+
limit: initialLimit
|
|
494
|
+
};
|
|
495
|
+
if (!baseFilters.tenantId && uiFilters.tenantId) {
|
|
496
|
+
merged.tenantId = uiFilters.tenantId;
|
|
497
|
+
}
|
|
498
|
+
if (!baseFilters.actionKey && uiFilters.actionKey) {
|
|
499
|
+
merged.actionKey = uiFilters.actionKey;
|
|
500
|
+
}
|
|
501
|
+
if (!baseFilters.entityId && uiFilters.entityId) {
|
|
502
|
+
merged.entityId = uiFilters.entityId;
|
|
503
|
+
}
|
|
504
|
+
if (!baseFilters.entityType && uiFilters.entityType) {
|
|
505
|
+
merged.entityType = uiFilters.entityType;
|
|
506
|
+
}
|
|
507
|
+
if (!baseFilters.actorId && uiFilters.actorId) {
|
|
508
|
+
merged.actorId = uiFilters.actorId;
|
|
509
|
+
}
|
|
510
|
+
if (!baseFilters.actorType && uiFilters.actorType) {
|
|
511
|
+
merged.actorType = uiFilters.actorType;
|
|
512
|
+
}
|
|
513
|
+
return merged;
|
|
514
|
+
}, [baseFilters, uiFilters, initialLimit]);
|
|
515
|
+
const lockedFilters = React2.useMemo(() => ({
|
|
516
|
+
tenantId: !!tenantId,
|
|
517
|
+
actionKey: !!actionKey,
|
|
518
|
+
entityId: !!entityId,
|
|
519
|
+
entityType: !!entityType,
|
|
520
|
+
actorId: !!actorId,
|
|
521
|
+
actorType: !!actorType
|
|
522
|
+
}), [tenantId, actionKey, entityId, entityType, actorId, actorType]);
|
|
454
523
|
const queryParamsRef = React2.useRef({});
|
|
455
524
|
const queryParamsKeyRef = React2.useRef("");
|
|
456
525
|
const queryParams = React2.useMemo(() => {
|
|
457
|
-
const
|
|
458
|
-
entityId,
|
|
459
|
-
actorId,
|
|
460
|
-
entityType,
|
|
461
|
-
// Filter by actorType on API side
|
|
462
|
-
actorType: showSystemAndServices ? void 0 : "user",
|
|
463
|
-
limit: initialLimit
|
|
464
|
-
};
|
|
465
|
-
const key = JSON.stringify(params);
|
|
526
|
+
const key = JSON.stringify(mergedFilters);
|
|
466
527
|
if (key !== queryParamsKeyRef.current) {
|
|
467
528
|
queryParamsKeyRef.current = key;
|
|
468
|
-
queryParamsRef.current =
|
|
469
|
-
return
|
|
529
|
+
queryParamsRef.current = mergedFilters;
|
|
530
|
+
return mergedFilters;
|
|
470
531
|
}
|
|
471
532
|
return queryParamsRef.current;
|
|
472
|
-
}, [
|
|
533
|
+
}, [mergedFilters]);
|
|
473
534
|
const allEventsRef = React2.useRef([]);
|
|
474
535
|
React2.useEffect(() => {
|
|
475
536
|
allEventsRef.current = allEvents;
|
|
@@ -516,12 +577,13 @@ function Timeline({
|
|
|
516
577
|
},
|
|
517
578
|
[queryParams, apiBaseUrl, getToken, forceRefreshToken, cursor]
|
|
518
579
|
);
|
|
580
|
+
const filterKey = React2.useMemo(() => JSON.stringify(mergedFilters), [mergedFilters]);
|
|
519
581
|
React2.useEffect(() => {
|
|
520
582
|
setCursor(void 0);
|
|
521
583
|
setAllEvents([]);
|
|
522
584
|
setPreviousEvents([]);
|
|
523
585
|
void load({ reset: true });
|
|
524
|
-
}, [
|
|
586
|
+
}, [filterKey]);
|
|
525
587
|
const eventsToFilter = React2.useMemo(() => {
|
|
526
588
|
if (loading && allEvents.length === 0 && previousEvents.length > 0) {
|
|
527
589
|
return previousEvents;
|
|
@@ -529,8 +591,8 @@ function Timeline({
|
|
|
529
591
|
return allEvents;
|
|
530
592
|
}, [allEvents, loading, previousEvents]);
|
|
531
593
|
const filteredEvents = React2.useMemo(() => {
|
|
532
|
-
return applyClientSideFilters(eventsToFilter, searchQuery, showSystemAndServices);
|
|
533
|
-
}, [eventsToFilter, searchQuery, showSystemAndServices]);
|
|
594
|
+
return applyClientSideFilters(eventsToFilter, searchQuery, showSystemAndServices, actionDescription);
|
|
595
|
+
}, [eventsToFilter, searchQuery, showSystemAndServices, actionDescription]);
|
|
534
596
|
const timelineItems = React2.useMemo(() => {
|
|
535
597
|
return filteredEvents.slice(0, 10).map(
|
|
536
598
|
(event) => eventToTimelineItem(event, getActorAvatar)
|
|
@@ -555,6 +617,144 @@ function Timeline({
|
|
|
555
617
|
placeholder: "Search actions, entities, IDs, actors, sources..."
|
|
556
618
|
}
|
|
557
619
|
) }),
|
|
620
|
+
showFilters && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: "1rem", padding: "1rem", backgroundColor: "#f9fafb", borderRadius: "0.375rem", display: "flex", flexWrap: "wrap", gap: "0.75rem" }, children: [
|
|
621
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
622
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: [
|
|
623
|
+
"Tenant ID ",
|
|
624
|
+
lockedFilters.tenantId && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "#9ca3af" }, children: "(Locked)" })
|
|
625
|
+
] }),
|
|
626
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
627
|
+
"input",
|
|
628
|
+
{
|
|
629
|
+
type: "text",
|
|
630
|
+
placeholder: "All tenants",
|
|
631
|
+
value: lockedFilters.tenantId ? tenantId ?? "" : uiFilters.tenantId ?? "",
|
|
632
|
+
onChange: (e) => {
|
|
633
|
+
if (!lockedFilters.tenantId) {
|
|
634
|
+
setUiFilters((prev) => ({ ...prev, tenantId: e.target.value || void 0 }));
|
|
635
|
+
}
|
|
636
|
+
},
|
|
637
|
+
disabled: lockedFilters.tenantId,
|
|
638
|
+
style: {
|
|
639
|
+
padding: "0.375rem 0.5rem",
|
|
640
|
+
border: "1px solid #d1d5db",
|
|
641
|
+
borderRadius: "0.375rem",
|
|
642
|
+
fontSize: "0.875rem",
|
|
643
|
+
backgroundColor: lockedFilters.tenantId ? "#f3f4f6" : "white",
|
|
644
|
+
cursor: lockedFilters.tenantId ? "not-allowed" : "text"
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
)
|
|
648
|
+
] }),
|
|
649
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
650
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: [
|
|
651
|
+
"Action Key ",
|
|
652
|
+
lockedFilters.actionKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "#9ca3af" }, children: "(Locked)" })
|
|
653
|
+
] }),
|
|
654
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
655
|
+
"input",
|
|
656
|
+
{
|
|
657
|
+
type: "text",
|
|
658
|
+
placeholder: "All actions",
|
|
659
|
+
value: lockedFilters.actionKey ? actionKey ?? "" : uiFilters.actionKey ?? "",
|
|
660
|
+
onChange: (e) => {
|
|
661
|
+
if (!lockedFilters.actionKey) {
|
|
662
|
+
setUiFilters((prev) => ({ ...prev, actionKey: e.target.value || void 0 }));
|
|
663
|
+
}
|
|
664
|
+
},
|
|
665
|
+
disabled: lockedFilters.actionKey,
|
|
666
|
+
style: {
|
|
667
|
+
padding: "0.375rem 0.5rem",
|
|
668
|
+
border: "1px solid #d1d5db",
|
|
669
|
+
borderRadius: "0.375rem",
|
|
670
|
+
fontSize: "0.875rem",
|
|
671
|
+
backgroundColor: lockedFilters.actionKey ? "#f3f4f6" : "white",
|
|
672
|
+
cursor: lockedFilters.actionKey ? "not-allowed" : "text"
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
)
|
|
676
|
+
] }),
|
|
677
|
+
!lockedFilters.entityId && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
678
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: "Entity ID" }),
|
|
679
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
680
|
+
"input",
|
|
681
|
+
{
|
|
682
|
+
type: "text",
|
|
683
|
+
placeholder: "All entities",
|
|
684
|
+
value: uiFilters.entityId ?? "",
|
|
685
|
+
onChange: (e) => {
|
|
686
|
+
setUiFilters((prev) => ({ ...prev, entityId: e.target.value || void 0 }));
|
|
687
|
+
},
|
|
688
|
+
style: {
|
|
689
|
+
padding: "0.375rem 0.5rem",
|
|
690
|
+
border: "1px solid #d1d5db",
|
|
691
|
+
borderRadius: "0.375rem",
|
|
692
|
+
fontSize: "0.875rem"
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
)
|
|
696
|
+
] }),
|
|
697
|
+
!lockedFilters.entityType && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
698
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: "Entity Type" }),
|
|
699
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
700
|
+
"input",
|
|
701
|
+
{
|
|
702
|
+
type: "text",
|
|
703
|
+
placeholder: "All types",
|
|
704
|
+
value: uiFilters.entityType ?? "",
|
|
705
|
+
onChange: (e) => {
|
|
706
|
+
setUiFilters((prev) => ({ ...prev, entityType: e.target.value || void 0 }));
|
|
707
|
+
},
|
|
708
|
+
style: {
|
|
709
|
+
padding: "0.375rem 0.5rem",
|
|
710
|
+
border: "1px solid #d1d5db",
|
|
711
|
+
borderRadius: "0.375rem",
|
|
712
|
+
fontSize: "0.875rem"
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
)
|
|
716
|
+
] }),
|
|
717
|
+
!lockedFilters.actorId && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
718
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: "Actor ID" }),
|
|
719
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
720
|
+
"input",
|
|
721
|
+
{
|
|
722
|
+
type: "text",
|
|
723
|
+
placeholder: "All actors",
|
|
724
|
+
value: uiFilters.actorId ?? "",
|
|
725
|
+
onChange: (e) => {
|
|
726
|
+
setUiFilters((prev) => ({ ...prev, actorId: e.target.value || void 0 }));
|
|
727
|
+
},
|
|
728
|
+
style: {
|
|
729
|
+
padding: "0.375rem 0.5rem",
|
|
730
|
+
border: "1px solid #d1d5db",
|
|
731
|
+
borderRadius: "0.375rem",
|
|
732
|
+
fontSize: "0.875rem"
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
)
|
|
736
|
+
] }),
|
|
737
|
+
(Object.keys(uiFilters).length > 0 || searchQuery) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", alignItems: "flex-end" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
738
|
+
"button",
|
|
739
|
+
{
|
|
740
|
+
type: "button",
|
|
741
|
+
onClick: () => {
|
|
742
|
+
setUiFilters({});
|
|
743
|
+
setSearchQuery("");
|
|
744
|
+
},
|
|
745
|
+
style: {
|
|
746
|
+
padding: "0.375rem 0.75rem",
|
|
747
|
+
backgroundColor: "#ef4444",
|
|
748
|
+
color: "white",
|
|
749
|
+
border: "none",
|
|
750
|
+
borderRadius: "0.375rem",
|
|
751
|
+
fontSize: "0.875rem",
|
|
752
|
+
cursor: "pointer"
|
|
753
|
+
},
|
|
754
|
+
children: "Clear"
|
|
755
|
+
}
|
|
756
|
+
) })
|
|
757
|
+
] }),
|
|
558
758
|
(searchQuery || filteredEvents.length !== eventsToFilter.length) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: "0.5rem", fontSize: "0.875rem", color: "#6b7280" }, children: [
|
|
559
759
|
"Showing ",
|
|
560
760
|
filteredEvents.length,
|
package/dist/react/client.mjs
CHANGED
|
@@ -78,7 +78,7 @@ var CloudCogIcon = ({ className }) => /* @__PURE__ */ jsxs(
|
|
|
78
78
|
function eventToTimelineItem(event, getActorAvatar) {
|
|
79
79
|
const actionValue = event.actionKey || event.action || "";
|
|
80
80
|
const action = actionValue.charAt(0).toUpperCase() + actionValue.slice(1);
|
|
81
|
-
const description =
|
|
81
|
+
const description = event.actionDescription || "";
|
|
82
82
|
const actorId = event.actorId || "unknown";
|
|
83
83
|
const userName = actorId.includes(":") ? actorId.split(":")[1] || actorId : actorId;
|
|
84
84
|
const userHandle = userName;
|
|
@@ -125,7 +125,8 @@ function eventToTimelineItem(event, getActorAvatar) {
|
|
|
125
125
|
// Matches ActivityLog.tsx line 361
|
|
126
126
|
statusIndicator: false,
|
|
127
127
|
// Can be set to true for recent items - matches ActivityLog.tsx line 362
|
|
128
|
-
data: event
|
|
128
|
+
data: event,
|
|
129
|
+
badge: action
|
|
129
130
|
};
|
|
130
131
|
}
|
|
131
132
|
async function fetchEventsWithRetry(apiBaseUrl, getToken, forceRefreshToken, params) {
|
|
@@ -133,12 +134,18 @@ async function fetchEventsWithRetry(apiBaseUrl, getToken, forceRefreshToken, par
|
|
|
133
134
|
if (params.entityId) {
|
|
134
135
|
url.searchParams.set("entityId", params.entityId);
|
|
135
136
|
}
|
|
137
|
+
if (params.tenantId) {
|
|
138
|
+
url.searchParams.set("tenantId", params.tenantId);
|
|
139
|
+
}
|
|
136
140
|
if (params.actorId) {
|
|
137
141
|
url.searchParams.set("actorId", params.actorId);
|
|
138
142
|
}
|
|
139
143
|
if (params.entityType) {
|
|
140
144
|
url.searchParams.set("entityType", params.entityType);
|
|
141
145
|
}
|
|
146
|
+
if (params.actionKey) {
|
|
147
|
+
url.searchParams.set("actionKey", params.actionKey);
|
|
148
|
+
}
|
|
142
149
|
if (params.actorType) {
|
|
143
150
|
const actorTypeValue = Array.isArray(params.actorType) ? params.actorType.join(",") : params.actorType;
|
|
144
151
|
url.searchParams.set("actorType", actorTypeValue);
|
|
@@ -149,6 +156,9 @@ async function fetchEventsWithRetry(apiBaseUrl, getToken, forceRefreshToken, par
|
|
|
149
156
|
if (params.cursor) {
|
|
150
157
|
url.searchParams.set("cursor", params.cursor);
|
|
151
158
|
}
|
|
159
|
+
if (params.q) {
|
|
160
|
+
url.searchParams.set("q", params.q);
|
|
161
|
+
}
|
|
152
162
|
const makeRequest = async (token2) => {
|
|
153
163
|
return fetch(url.toString(), {
|
|
154
164
|
headers: {
|
|
@@ -281,8 +291,15 @@ function SimpleAvatar({
|
|
|
281
291
|
}
|
|
282
292
|
);
|
|
283
293
|
}
|
|
284
|
-
function applyClientSideFilters(events, searchQuery, showSystemAndServices) {
|
|
294
|
+
function applyClientSideFilters(events, searchQuery, showSystemAndServices, actionDescription) {
|
|
285
295
|
let filtered = events;
|
|
296
|
+
if (actionDescription) {
|
|
297
|
+
filtered = filtered.filter((event) => {
|
|
298
|
+
const eventActionDescription = (event.actionDescription || "").toLowerCase();
|
|
299
|
+
const filterActionDescription = actionDescription.toLowerCase();
|
|
300
|
+
return eventActionDescription.includes(filterActionDescription);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
286
303
|
if (!showSystemAndServices) {
|
|
287
304
|
filtered = filtered.filter((event) => {
|
|
288
305
|
if (event.actorType) {
|
|
@@ -301,13 +318,18 @@ function applyClientSideFilters(events, searchQuery, showSystemAndServices) {
|
|
|
301
318
|
const query = searchQuery.toLowerCase();
|
|
302
319
|
return filtered.filter((event) => {
|
|
303
320
|
const actionValue = (event.actionKey || event.action || "").toLowerCase();
|
|
304
|
-
|
|
321
|
+
const actionDescValue = (event.actionDescription || "").toLowerCase();
|
|
322
|
+
return actionValue.includes(query) || actionDescValue.includes(query) || event.entityType.toLowerCase().includes(query) || event.entityId.toLowerCase().includes(query) || event.actorId && event.actorId.toLowerCase().includes(query) || event.source && event.source.toLowerCase().includes(query) || event.actorDisplay && event.actorDisplay.toLowerCase().includes(query);
|
|
305
323
|
});
|
|
306
324
|
}
|
|
307
325
|
function Timeline({
|
|
308
326
|
entityId,
|
|
327
|
+
tenantId,
|
|
309
328
|
actorId,
|
|
310
329
|
entityType,
|
|
330
|
+
actionKey,
|
|
331
|
+
actionDescription,
|
|
332
|
+
actorType,
|
|
311
333
|
initialLimit = 100,
|
|
312
334
|
className,
|
|
313
335
|
emptyMessage = "No events yet.",
|
|
@@ -324,25 +346,64 @@ function Timeline({
|
|
|
324
346
|
const [error, setError] = React.useState(null);
|
|
325
347
|
const [hasMore, setHasMore] = React.useState(false);
|
|
326
348
|
const [searchQuery, setSearchQuery] = React.useState("");
|
|
349
|
+
const baseFilters = React.useMemo(() => {
|
|
350
|
+
const filters = {};
|
|
351
|
+
if (entityId) filters.entityId = entityId;
|
|
352
|
+
if (tenantId) filters.tenantId = tenantId;
|
|
353
|
+
if (actorId) filters.actorId = actorId;
|
|
354
|
+
if (entityType) filters.entityType = entityType;
|
|
355
|
+
if (actionKey) filters.actionKey = actionKey;
|
|
356
|
+
if (actorType) filters.actorType = actorType;
|
|
357
|
+
if (!showSystemAndServices && !actorType) {
|
|
358
|
+
filters.actorType = "user";
|
|
359
|
+
}
|
|
360
|
+
return filters;
|
|
361
|
+
}, [entityId, tenantId, actorId, entityType, actionKey, actorType, showSystemAndServices]);
|
|
362
|
+
const [uiFilters, setUiFilters] = React.useState({});
|
|
363
|
+
const mergedFilters = React.useMemo(() => {
|
|
364
|
+
const merged = {
|
|
365
|
+
...baseFilters,
|
|
366
|
+
limit: initialLimit
|
|
367
|
+
};
|
|
368
|
+
if (!baseFilters.tenantId && uiFilters.tenantId) {
|
|
369
|
+
merged.tenantId = uiFilters.tenantId;
|
|
370
|
+
}
|
|
371
|
+
if (!baseFilters.actionKey && uiFilters.actionKey) {
|
|
372
|
+
merged.actionKey = uiFilters.actionKey;
|
|
373
|
+
}
|
|
374
|
+
if (!baseFilters.entityId && uiFilters.entityId) {
|
|
375
|
+
merged.entityId = uiFilters.entityId;
|
|
376
|
+
}
|
|
377
|
+
if (!baseFilters.entityType && uiFilters.entityType) {
|
|
378
|
+
merged.entityType = uiFilters.entityType;
|
|
379
|
+
}
|
|
380
|
+
if (!baseFilters.actorId && uiFilters.actorId) {
|
|
381
|
+
merged.actorId = uiFilters.actorId;
|
|
382
|
+
}
|
|
383
|
+
if (!baseFilters.actorType && uiFilters.actorType) {
|
|
384
|
+
merged.actorType = uiFilters.actorType;
|
|
385
|
+
}
|
|
386
|
+
return merged;
|
|
387
|
+
}, [baseFilters, uiFilters, initialLimit]);
|
|
388
|
+
const lockedFilters = React.useMemo(() => ({
|
|
389
|
+
tenantId: !!tenantId,
|
|
390
|
+
actionKey: !!actionKey,
|
|
391
|
+
entityId: !!entityId,
|
|
392
|
+
entityType: !!entityType,
|
|
393
|
+
actorId: !!actorId,
|
|
394
|
+
actorType: !!actorType
|
|
395
|
+
}), [tenantId, actionKey, entityId, entityType, actorId, actorType]);
|
|
327
396
|
const queryParamsRef = React.useRef({});
|
|
328
397
|
const queryParamsKeyRef = React.useRef("");
|
|
329
398
|
const queryParams = React.useMemo(() => {
|
|
330
|
-
const
|
|
331
|
-
entityId,
|
|
332
|
-
actorId,
|
|
333
|
-
entityType,
|
|
334
|
-
// Filter by actorType on API side
|
|
335
|
-
actorType: showSystemAndServices ? void 0 : "user",
|
|
336
|
-
limit: initialLimit
|
|
337
|
-
};
|
|
338
|
-
const key = JSON.stringify(params);
|
|
399
|
+
const key = JSON.stringify(mergedFilters);
|
|
339
400
|
if (key !== queryParamsKeyRef.current) {
|
|
340
401
|
queryParamsKeyRef.current = key;
|
|
341
|
-
queryParamsRef.current =
|
|
342
|
-
return
|
|
402
|
+
queryParamsRef.current = mergedFilters;
|
|
403
|
+
return mergedFilters;
|
|
343
404
|
}
|
|
344
405
|
return queryParamsRef.current;
|
|
345
|
-
}, [
|
|
406
|
+
}, [mergedFilters]);
|
|
346
407
|
const allEventsRef = React.useRef([]);
|
|
347
408
|
React.useEffect(() => {
|
|
348
409
|
allEventsRef.current = allEvents;
|
|
@@ -389,12 +450,13 @@ function Timeline({
|
|
|
389
450
|
},
|
|
390
451
|
[queryParams, apiBaseUrl, getToken, forceRefreshToken, cursor]
|
|
391
452
|
);
|
|
453
|
+
const filterKey = React.useMemo(() => JSON.stringify(mergedFilters), [mergedFilters]);
|
|
392
454
|
React.useEffect(() => {
|
|
393
455
|
setCursor(void 0);
|
|
394
456
|
setAllEvents([]);
|
|
395
457
|
setPreviousEvents([]);
|
|
396
458
|
void load({ reset: true });
|
|
397
|
-
}, [
|
|
459
|
+
}, [filterKey]);
|
|
398
460
|
const eventsToFilter = React.useMemo(() => {
|
|
399
461
|
if (loading && allEvents.length === 0 && previousEvents.length > 0) {
|
|
400
462
|
return previousEvents;
|
|
@@ -402,8 +464,8 @@ function Timeline({
|
|
|
402
464
|
return allEvents;
|
|
403
465
|
}, [allEvents, loading, previousEvents]);
|
|
404
466
|
const filteredEvents = React.useMemo(() => {
|
|
405
|
-
return applyClientSideFilters(eventsToFilter, searchQuery, showSystemAndServices);
|
|
406
|
-
}, [eventsToFilter, searchQuery, showSystemAndServices]);
|
|
467
|
+
return applyClientSideFilters(eventsToFilter, searchQuery, showSystemAndServices, actionDescription);
|
|
468
|
+
}, [eventsToFilter, searchQuery, showSystemAndServices, actionDescription]);
|
|
407
469
|
const timelineItems = React.useMemo(() => {
|
|
408
470
|
return filteredEvents.slice(0, 10).map(
|
|
409
471
|
(event) => eventToTimelineItem(event, getActorAvatar)
|
|
@@ -428,6 +490,144 @@ function Timeline({
|
|
|
428
490
|
placeholder: "Search actions, entities, IDs, actors, sources..."
|
|
429
491
|
}
|
|
430
492
|
) }),
|
|
493
|
+
showFilters && /* @__PURE__ */ jsxs("div", { style: { marginBottom: "1rem", padding: "1rem", backgroundColor: "#f9fafb", borderRadius: "0.375rem", display: "flex", flexWrap: "wrap", gap: "0.75rem" }, children: [
|
|
494
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
495
|
+
/* @__PURE__ */ jsxs("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: [
|
|
496
|
+
"Tenant ID ",
|
|
497
|
+
lockedFilters.tenantId && /* @__PURE__ */ jsx("span", { style: { color: "#9ca3af" }, children: "(Locked)" })
|
|
498
|
+
] }),
|
|
499
|
+
/* @__PURE__ */ jsx(
|
|
500
|
+
"input",
|
|
501
|
+
{
|
|
502
|
+
type: "text",
|
|
503
|
+
placeholder: "All tenants",
|
|
504
|
+
value: lockedFilters.tenantId ? tenantId ?? "" : uiFilters.tenantId ?? "",
|
|
505
|
+
onChange: (e) => {
|
|
506
|
+
if (!lockedFilters.tenantId) {
|
|
507
|
+
setUiFilters((prev) => ({ ...prev, tenantId: e.target.value || void 0 }));
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
disabled: lockedFilters.tenantId,
|
|
511
|
+
style: {
|
|
512
|
+
padding: "0.375rem 0.5rem",
|
|
513
|
+
border: "1px solid #d1d5db",
|
|
514
|
+
borderRadius: "0.375rem",
|
|
515
|
+
fontSize: "0.875rem",
|
|
516
|
+
backgroundColor: lockedFilters.tenantId ? "#f3f4f6" : "white",
|
|
517
|
+
cursor: lockedFilters.tenantId ? "not-allowed" : "text"
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
)
|
|
521
|
+
] }),
|
|
522
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
523
|
+
/* @__PURE__ */ jsxs("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: [
|
|
524
|
+
"Action Key ",
|
|
525
|
+
lockedFilters.actionKey && /* @__PURE__ */ jsx("span", { style: { color: "#9ca3af" }, children: "(Locked)" })
|
|
526
|
+
] }),
|
|
527
|
+
/* @__PURE__ */ jsx(
|
|
528
|
+
"input",
|
|
529
|
+
{
|
|
530
|
+
type: "text",
|
|
531
|
+
placeholder: "All actions",
|
|
532
|
+
value: lockedFilters.actionKey ? actionKey ?? "" : uiFilters.actionKey ?? "",
|
|
533
|
+
onChange: (e) => {
|
|
534
|
+
if (!lockedFilters.actionKey) {
|
|
535
|
+
setUiFilters((prev) => ({ ...prev, actionKey: e.target.value || void 0 }));
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
disabled: lockedFilters.actionKey,
|
|
539
|
+
style: {
|
|
540
|
+
padding: "0.375rem 0.5rem",
|
|
541
|
+
border: "1px solid #d1d5db",
|
|
542
|
+
borderRadius: "0.375rem",
|
|
543
|
+
fontSize: "0.875rem",
|
|
544
|
+
backgroundColor: lockedFilters.actionKey ? "#f3f4f6" : "white",
|
|
545
|
+
cursor: lockedFilters.actionKey ? "not-allowed" : "text"
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
)
|
|
549
|
+
] }),
|
|
550
|
+
!lockedFilters.entityId && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
551
|
+
/* @__PURE__ */ jsx("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: "Entity ID" }),
|
|
552
|
+
/* @__PURE__ */ jsx(
|
|
553
|
+
"input",
|
|
554
|
+
{
|
|
555
|
+
type: "text",
|
|
556
|
+
placeholder: "All entities",
|
|
557
|
+
value: uiFilters.entityId ?? "",
|
|
558
|
+
onChange: (e) => {
|
|
559
|
+
setUiFilters((prev) => ({ ...prev, entityId: e.target.value || void 0 }));
|
|
560
|
+
},
|
|
561
|
+
style: {
|
|
562
|
+
padding: "0.375rem 0.5rem",
|
|
563
|
+
border: "1px solid #d1d5db",
|
|
564
|
+
borderRadius: "0.375rem",
|
|
565
|
+
fontSize: "0.875rem"
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
)
|
|
569
|
+
] }),
|
|
570
|
+
!lockedFilters.entityType && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
571
|
+
/* @__PURE__ */ jsx("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: "Entity Type" }),
|
|
572
|
+
/* @__PURE__ */ jsx(
|
|
573
|
+
"input",
|
|
574
|
+
{
|
|
575
|
+
type: "text",
|
|
576
|
+
placeholder: "All types",
|
|
577
|
+
value: uiFilters.entityType ?? "",
|
|
578
|
+
onChange: (e) => {
|
|
579
|
+
setUiFilters((prev) => ({ ...prev, entityType: e.target.value || void 0 }));
|
|
580
|
+
},
|
|
581
|
+
style: {
|
|
582
|
+
padding: "0.375rem 0.5rem",
|
|
583
|
+
border: "1px solid #d1d5db",
|
|
584
|
+
borderRadius: "0.375rem",
|
|
585
|
+
fontSize: "0.875rem"
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
)
|
|
589
|
+
] }),
|
|
590
|
+
!lockedFilters.actorId && /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [
|
|
591
|
+
/* @__PURE__ */ jsx("label", { style: { fontSize: "0.75rem", fontWeight: 500, color: "#6b7280" }, children: "Actor ID" }),
|
|
592
|
+
/* @__PURE__ */ jsx(
|
|
593
|
+
"input",
|
|
594
|
+
{
|
|
595
|
+
type: "text",
|
|
596
|
+
placeholder: "All actors",
|
|
597
|
+
value: uiFilters.actorId ?? "",
|
|
598
|
+
onChange: (e) => {
|
|
599
|
+
setUiFilters((prev) => ({ ...prev, actorId: e.target.value || void 0 }));
|
|
600
|
+
},
|
|
601
|
+
style: {
|
|
602
|
+
padding: "0.375rem 0.5rem",
|
|
603
|
+
border: "1px solid #d1d5db",
|
|
604
|
+
borderRadius: "0.375rem",
|
|
605
|
+
fontSize: "0.875rem"
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
)
|
|
609
|
+
] }),
|
|
610
|
+
(Object.keys(uiFilters).length > 0 || searchQuery) && /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "flex-end" }, children: /* @__PURE__ */ jsx(
|
|
611
|
+
"button",
|
|
612
|
+
{
|
|
613
|
+
type: "button",
|
|
614
|
+
onClick: () => {
|
|
615
|
+
setUiFilters({});
|
|
616
|
+
setSearchQuery("");
|
|
617
|
+
},
|
|
618
|
+
style: {
|
|
619
|
+
padding: "0.375rem 0.75rem",
|
|
620
|
+
backgroundColor: "#ef4444",
|
|
621
|
+
color: "white",
|
|
622
|
+
border: "none",
|
|
623
|
+
borderRadius: "0.375rem",
|
|
624
|
+
fontSize: "0.875rem",
|
|
625
|
+
cursor: "pointer"
|
|
626
|
+
},
|
|
627
|
+
children: "Clear"
|
|
628
|
+
}
|
|
629
|
+
) })
|
|
630
|
+
] }),
|
|
431
631
|
(searchQuery || filteredEvents.length !== eventsToFilter.length) && /* @__PURE__ */ jsxs("div", { style: { marginBottom: "0.5rem", fontSize: "0.875rem", color: "#6b7280" }, children: [
|
|
432
632
|
"Showing ",
|
|
433
633
|
filteredEvents.length,
|