@datum-cloud/activity-ui 0.7.0 → 0.7.1-dev.80aff08
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/ActivityFeed.d.ts +11 -1
- package/dist/components/ActivityFeed.d.ts.map +1 -1
- package/dist/index.esm.js +20 -12
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +20 -12
- package/dist/index.js.map +1 -1
- package/dist/lib/activity-filters.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -47,6 +47,16 @@ export interface ActivityFeedProps {
|
|
|
47
47
|
loadMoreThreshold?: number;
|
|
48
48
|
/** Handler called when user wants to create a policy (for empty state) */
|
|
49
49
|
onCreatePolicy?: () => void;
|
|
50
|
+
/**
|
|
51
|
+
* Whether to probe ActivityPolicies to decide between the "No Policies"
|
|
52
|
+
* and "No activities found" empty states (default: false).
|
|
53
|
+
*
|
|
54
|
+
* ActivityPolicy is a Platform-scope resource. Tenant-scoped clients
|
|
55
|
+
* (Project, Organization, User) cannot list it and always receive a 403,
|
|
56
|
+
* so leave this off in tenant UIs. Enable it only in platform-operator
|
|
57
|
+
* UIs that have access to the Platform scope.
|
|
58
|
+
*/
|
|
59
|
+
checkPolicies?: boolean;
|
|
50
60
|
/** Enable real-time streaming (default: false) */
|
|
51
61
|
enableStreaming?: boolean;
|
|
52
62
|
/** Callback invoked when the effective time range is resolved */
|
|
@@ -67,5 +77,5 @@ export interface ActivityFeedProps {
|
|
|
67
77
|
* ActivityFeed displays a chronological list of activities with filtering and pagination.
|
|
68
78
|
* Supports optional real-time streaming of new activities.
|
|
69
79
|
*/
|
|
70
|
-
export declare function ActivityFeed({ client, initialFilters, initialTimeRange, pageSize, onResourceClick, resourceLinkResolver, tenantLinkResolver, tenantRenderer, onActivityClick, compact, variant, resourceUid, showFilters, hiddenFilters, className, infiniteScroll, loadMoreThreshold, onCreatePolicy, enableStreaming, onEffectiveTimeRangeChange, errorFormatter, maxHeight, onFiltersChange: onFiltersChangeProp, }: ActivityFeedProps): import("react/jsx-runtime").JSX.Element;
|
|
80
|
+
export declare function ActivityFeed({ client, initialFilters, initialTimeRange, pageSize, onResourceClick, resourceLinkResolver, tenantLinkResolver, tenantRenderer, onActivityClick, compact, variant, resourceUid, showFilters, hiddenFilters, className, infiniteScroll, loadMoreThreshold, onCreatePolicy, checkPolicies, enableStreaming, onEffectiveTimeRangeChange, errorFormatter, maxHeight, onFiltersChange: onFiltersChangeProp, }: ActivityFeedProps): import("react/jsx-runtime").JSX.Element;
|
|
71
81
|
//# sourceMappingURL=ActivityFeed.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActivityFeed.d.ts","sourceRoot":"","sources":["../../src/components/ActivityFeed.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,0BAA0B,EAC1B,cAAc,EACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,mBAAmB,IAAI,WAAW,EAClC,SAAS,EACV,MAAM,0BAA0B,CAAC;AAYlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAoBlD,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,8BAA8B;IAC9B,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;IAClD,yDAAyD;IACzD,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,uDAAuD;IACvD,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,wEAAwE;IACxE,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iDAAiD;IACjD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC/C,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;IACzC,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4FAA4F;IAC5F,aAAa,CAAC,EAAE,KAAK,CACjB,eAAe,GACf,YAAY,GACZ,WAAW,GACX,oBAAoB,GACpB,cAAc,GACd,cAAc,CACjB,CAAC;IACF,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,kDAAkD;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iEAAiE;IACjE,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;IACxD,4DAA4D;IAC5D,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;CACxE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,cAA0C,EAC1C,gBAAsC,EACtC,QAAa,EACb,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,OAAe,EACf,OAAgB,EAChB,WAAW,EACX,WAAkB,EAClB,aAAkB,EAClB,SAAc,EACd,cAAqB,EACrB,iBAAuB,EACvB,cAAc,EACd,eAAuB,EACvB,0BAA0B,EAC1B,cAAc,EACd,SAAS,EACT,eAAe,EAAE,mBAAmB,GACrC,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"ActivityFeed.d.ts","sourceRoot":"","sources":["../../src/components/ActivityFeed.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,0BAA0B,EAC1B,cAAc,EACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,mBAAmB,IAAI,WAAW,EAClC,SAAS,EACV,MAAM,0BAA0B,CAAC;AAYlC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAoBlD,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,8BAA8B;IAC9B,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,yBAAyB;IACzB,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,IAAI,CAAC;IAClD,yDAAyD;IACzD,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,uDAAuD;IACvD,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,wEAAwE;IACxE,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iDAAiD;IACjD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC/C,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,CAAC;IACzC,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8BAA8B;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4FAA4F;IAC5F,aAAa,CAAC,EAAE,KAAK,CACjB,eAAe,GACf,YAAY,GACZ,WAAW,GACX,oBAAoB,GACpB,cAAc,GACd,cAAc,CACjB,CAAC;IACF,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kEAAkE;IAClE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iEAAiE;IACjE,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;IACxD,4DAA4D;IAC5D,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;CACxE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,cAA0C,EAC1C,gBAAsC,EACtC,QAAa,EACb,eAAe,EACf,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,OAAe,EACf,OAAgB,EAChB,WAAW,EACX,WAAkB,EAClB,aAAkB,EAClB,SAAc,EACd,cAAqB,EACrB,iBAAuB,EACvB,cAAc,EACd,aAAqB,EACrB,eAAuB,EACvB,0BAA0B,EAC1B,cAAc,EACd,SAAS,EACT,eAAe,EAAE,mBAAmB,GACrC,EAAE,iBAAiB,2CAihBnB"}
|
package/dist/index.esm.js
CHANGED
|
@@ -10562,7 +10562,7 @@ function getActorInitials(name) {
|
|
|
10562
10562
|
* Get Tailwind classes for actor avatar based on actor type
|
|
10563
10563
|
*/
|
|
10564
10564
|
function getActorAvatarClasses(actorType, compact) {
|
|
10565
|
-
const baseClasses = cn("rounded-full flex items-center justify-center shrink-0 font-semibold", compact ? "w-5 h-5 text-
|
|
10565
|
+
const baseClasses = cn("rounded-full flex items-center justify-center shrink-0 font-semibold", compact ? "w-5 h-5 text-2xs" : "w-6 h-6 text-2xs");
|
|
10566
10566
|
switch (actorType) {
|
|
10567
10567
|
case "user":
|
|
10568
10568
|
return cn(baseClasses, "bg-primary text-primary-foreground");
|
|
@@ -11297,7 +11297,7 @@ function groupActivitiesByDay(activities) {
|
|
|
11297
11297
|
* ActivityFeed displays a chronological list of activities with filtering and pagination.
|
|
11298
11298
|
* Supports optional real-time streaming of new activities.
|
|
11299
11299
|
*/
|
|
11300
|
-
function ActivityFeed({ client, initialFilters = { changeSource: "human" }, initialTimeRange = { start: "now-7d" }, pageSize = 30, onResourceClick, resourceLinkResolver, tenantLinkResolver, tenantRenderer, onActivityClick, compact = false, variant = "feed", resourceUid, showFilters = true, hiddenFilters = [], className = "", infiniteScroll = true, loadMoreThreshold = 200, onCreatePolicy, enableStreaming = false, onEffectiveTimeRangeChange, errorFormatter, maxHeight, onFiltersChange: onFiltersChangeProp, }) {
|
|
11300
|
+
function ActivityFeed({ client, initialFilters = { changeSource: "human" }, initialTimeRange = { start: "now-7d" }, pageSize = 30, onResourceClick, resourceLinkResolver, tenantLinkResolver, tenantRenderer, onActivityClick, compact = false, variant = "feed", resourceUid, showFilters = true, hiddenFilters = [], className = "", infiniteScroll = true, loadMoreThreshold = 200, onCreatePolicy, checkPolicies = false, enableStreaming = false, onEffectiveTimeRangeChange, errorFormatter, maxHeight, onFiltersChange: onFiltersChangeProp, }) {
|
|
11301
11301
|
// Merge resourceUid into initial filters if provided
|
|
11302
11302
|
const mergedInitialFilters = {
|
|
11303
11303
|
...initialFilters,
|
|
@@ -11316,12 +11316,19 @@ function ActivityFeed({ client, initialFilters = { changeSource: "human" }, init
|
|
|
11316
11316
|
const loadMoreTriggerRef = useRef(null);
|
|
11317
11317
|
// Store the latest loadMore function in a ref to avoid observer re-subscription
|
|
11318
11318
|
const loadMoreRef = useRef(loadMore);
|
|
11319
|
-
// Track whether policies exist in the system
|
|
11319
|
+
// Track whether policies exist in the system. Null means unknown: neither
|
|
11320
|
+
// empty state is shown, so tenants never see the policy prompt.
|
|
11320
11321
|
const [hasPolicies, setHasPolicies] = useState(null);
|
|
11321
|
-
const [policiesLoading, setPoliciesLoading] = useState(
|
|
11322
|
-
// Check for policies on mount
|
|
11322
|
+
const [policiesLoading, setPoliciesLoading] = useState(checkPolicies);
|
|
11323
|
+
// Check for policies on mount, but only when the host opts in. Tenant
|
|
11324
|
+
// clients cannot list the Platform-scope ActivityPolicy resource.
|
|
11323
11325
|
useEffect(() => {
|
|
11324
|
-
|
|
11326
|
+
if (!checkPolicies) {
|
|
11327
|
+
setHasPolicies(null);
|
|
11328
|
+
setPoliciesLoading(false);
|
|
11329
|
+
return;
|
|
11330
|
+
}
|
|
11331
|
+
const probePolicies = async () => {
|
|
11325
11332
|
try {
|
|
11326
11333
|
const policyList = await client.listPolicies();
|
|
11327
11334
|
setHasPolicies((policyList.items?.length ?? 0) > 0);
|
|
@@ -11334,8 +11341,8 @@ function ActivityFeed({ client, initialFilters = { changeSource: "human" }, init
|
|
|
11334
11341
|
setPoliciesLoading(false);
|
|
11335
11342
|
}
|
|
11336
11343
|
};
|
|
11337
|
-
|
|
11338
|
-
}, [client]);
|
|
11344
|
+
probePolicies();
|
|
11345
|
+
}, [client, checkPolicies]);
|
|
11339
11346
|
// Auto-execute on mount
|
|
11340
11347
|
useEffect(() => {
|
|
11341
11348
|
refresh();
|
|
@@ -15369,7 +15376,9 @@ function serializeActivityFilters(filters, timeRange, streamingEnabled = true) {
|
|
|
15369
15376
|
if (!streamingEnabled) {
|
|
15370
15377
|
params.set('streaming', 'false');
|
|
15371
15378
|
}
|
|
15372
|
-
|
|
15379
|
+
// Written even when it matches a default: the default differs between
|
|
15380
|
+
// pages, so an omitted value can't be read back as the one chosen.
|
|
15381
|
+
if (filters.changeSource) {
|
|
15373
15382
|
params.set('changeSource', filters.changeSource);
|
|
15374
15383
|
}
|
|
15375
15384
|
if (filters.actorNames && filters.actorNames.length > 0) {
|
|
@@ -15433,12 +15442,11 @@ function serializeEventFilters(filters, timeRange, streamingEnabled = true) {
|
|
|
15433
15442
|
function parseActivityFilters(searchParams) {
|
|
15434
15443
|
const filters = {};
|
|
15435
15444
|
const changeSource = searchParams.get('changeSource');
|
|
15445
|
+
// Left unset when absent so the caller's default applies. Filling in
|
|
15446
|
+
// 'human' here overrode pages that default to 'all'.
|
|
15436
15447
|
if (changeSource === 'human' || changeSource === 'system' || changeSource === 'all') {
|
|
15437
15448
|
filters.changeSource = changeSource;
|
|
15438
15449
|
}
|
|
15439
|
-
else {
|
|
15440
|
-
filters.changeSource = 'human';
|
|
15441
|
-
}
|
|
15442
15450
|
const actorNames = searchParams.get('actorNames');
|
|
15443
15451
|
if (actorNames) {
|
|
15444
15452
|
filters.actorNames = actorNames.split(',').filter(Boolean);
|