@startsimpli/ui 0.4.78 → 0.4.80
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/package.json +4 -3
- package/src/components/ActivityTimeline.tsx +302 -105
- package/src/components/activity/ActivityFeedPanel.tsx +208 -0
- package/src/components/activity/ActivityFilterBar.tsx +180 -0
- package/src/components/activity/__tests__/activity-feed.test.tsx +434 -0
- package/src/components/activity/activity-events.ts +179 -0
- package/src/components/activity/activity-feed-panel-default-class-names.ts +31 -0
- package/src/components/activity/activity-filter-bar-default-class-names.ts +34 -0
- package/src/components/activity/index.ts +51 -0
- package/src/components/activity/types.ts +94 -0
- package/src/components/index.ts +10 -2
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @startsimpli/ui/activity — the shared, filterable activity feed
|
|
3
|
+
* (startsim-768w.19.5).
|
|
4
|
+
*
|
|
5
|
+
* A primitive (the generalised `ActivityTimeline`, exported from the package
|
|
6
|
+
* root) plus the page-level composer `ActivityFeedPanel`, so an app that wants
|
|
7
|
+
* a "what happened here" surface holds theme classNames and a thin wrapper
|
|
8
|
+
* instead of its own timeline — rule #9.
|
|
9
|
+
*
|
|
10
|
+
* Nothing in here knows which event types exist. Visibility was decided by the
|
|
11
|
+
* endpoint; the feed renders what it receives, humanising an action it has
|
|
12
|
+
* never seen rather than dropping or mislabelling it.
|
|
13
|
+
*/
|
|
14
|
+
export { ActivityFeedPanel, type ActivityFeedPanelProps } from './ActivityFeedPanel';
|
|
15
|
+
export {
|
|
16
|
+
ACTIVITY_FEED_PANEL_DEFAULTS,
|
|
17
|
+
type ActivityFeedPanelClassNames,
|
|
18
|
+
} from './activity-feed-panel-default-class-names';
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
ActivityFilterBar,
|
|
22
|
+
activityFilterCount,
|
|
23
|
+
type ActivityFilterBarProps,
|
|
24
|
+
} from './ActivityFilterBar';
|
|
25
|
+
export {
|
|
26
|
+
ACTIVITY_FILTER_BAR_DEFAULTS,
|
|
27
|
+
type ActivityFilterBarClassNames,
|
|
28
|
+
} from './activity-filter-bar-default-class-names';
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
TONE_DOT,
|
|
32
|
+
SOURCE_NOTE,
|
|
33
|
+
actionOf,
|
|
34
|
+
humanizeAction,
|
|
35
|
+
activityLabel,
|
|
36
|
+
activityTone,
|
|
37
|
+
activityHead,
|
|
38
|
+
toActivityTimelineItems,
|
|
39
|
+
deriveActivityFilterOptions,
|
|
40
|
+
} from './activity-events';
|
|
41
|
+
|
|
42
|
+
export type {
|
|
43
|
+
ActivityClient,
|
|
44
|
+
ActivityEvent,
|
|
45
|
+
ActivityEventActor,
|
|
46
|
+
ActivityFilterOption,
|
|
47
|
+
ActivityFilterOptions,
|
|
48
|
+
ActivityFilterValue,
|
|
49
|
+
ActivityPage,
|
|
50
|
+
ActivityQuery,
|
|
51
|
+
} from './types';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @startsimpli/ui/activity — the shapes the shared activity feed renders.
|
|
3
|
+
*
|
|
4
|
+
* Structural on purpose: packages/ui imports no API client, so these mirror the
|
|
5
|
+
* event-stream row without depending on @startsimpli/api. `FoundryActivityEvent`
|
|
6
|
+
* is assignable to `ActivityEvent`, and so is any other append-only trail with
|
|
7
|
+
* an action + a timestamp.
|
|
8
|
+
*
|
|
9
|
+
* THE UI DECIDES NOTHING ABOUT VISIBILITY. The stream endpoint already filtered
|
|
10
|
+
* by the caller's resolved permission level, so every row that arrives here is
|
|
11
|
+
* renderable and there is no vocabulary of known types anywhere below.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export interface ActivityEventActor {
|
|
15
|
+
id?: string;
|
|
16
|
+
email?: string | null;
|
|
17
|
+
name?: string | null;
|
|
18
|
+
avatarUrl?: string | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** One row of an append-only event stream. Only `id` + `created_at` are
|
|
22
|
+
* required; everything else is per-type detail the renderer treats as
|
|
23
|
+
* optional so an unknown type still renders. */
|
|
24
|
+
export interface ActivityEvent {
|
|
25
|
+
id: string;
|
|
26
|
+
/** The raw event type as the server names it, e.g. `member_invited`. */
|
|
27
|
+
action?: string;
|
|
28
|
+
/** Alias of `action` for streams that name it `type`. */
|
|
29
|
+
type?: string;
|
|
30
|
+
target_type?: string;
|
|
31
|
+
target_id?: string;
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
actor?: ActivityEventActor | null;
|
|
34
|
+
actor_email?: string | null;
|
|
35
|
+
/** Lifecycle detail — present on state transitions, null on everything else. */
|
|
36
|
+
state?: string | null;
|
|
37
|
+
previous_state?: string | null;
|
|
38
|
+
source?: string;
|
|
39
|
+
reason?: string;
|
|
40
|
+
error?: string;
|
|
41
|
+
run_id?: string;
|
|
42
|
+
run_kind?: string;
|
|
43
|
+
created_at: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Narrowing the user asked for. Every field can only SUBTRACT from the rows
|
|
47
|
+
* the caller's level already permits — a filter is a preference, never an
|
|
48
|
+
* access decision. */
|
|
49
|
+
export interface ActivityFilterValue {
|
|
50
|
+
/** Actor user id or email. */
|
|
51
|
+
actor?: string;
|
|
52
|
+
/** One action, or several comma-separated. */
|
|
53
|
+
action?: string;
|
|
54
|
+
/** ISO-8601 lower bound on the timestamp (inclusive). */
|
|
55
|
+
since?: string;
|
|
56
|
+
/** ISO-8601 upper bound on the timestamp (inclusive). */
|
|
57
|
+
until?: string;
|
|
58
|
+
/** Free text. */
|
|
59
|
+
q?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface ActivityQuery extends ActivityFilterValue {
|
|
63
|
+
page?: number;
|
|
64
|
+
pageSize?: number;
|
|
65
|
+
// Index signature so this satisfies an API client's query-params type
|
|
66
|
+
// (mirrors `FoundryActivityParams`) — the injected client is the app's own.
|
|
67
|
+
[key: string]: unknown;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface ActivityPage {
|
|
71
|
+
count: number;
|
|
72
|
+
next?: string | null;
|
|
73
|
+
previous?: string | null;
|
|
74
|
+
results: ActivityEvent[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The one call the feed needs. The consuming app injects its authed client
|
|
79
|
+
* (`(p) => api.foundry.activity(slug, p)`), which is what keeps @startsimpli/api
|
|
80
|
+
* out of packages/ui and the app wrapper under ten lines.
|
|
81
|
+
*/
|
|
82
|
+
export interface ActivityClient {
|
|
83
|
+
list(params: ActivityQuery): Promise<ActivityPage>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface ActivityFilterOption {
|
|
87
|
+
value: string;
|
|
88
|
+
label: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface ActivityFilterOptions {
|
|
92
|
+
actors: ActivityFilterOption[];
|
|
93
|
+
actions: ActivityFilterOption[];
|
|
94
|
+
}
|
package/src/components/index.ts
CHANGED
|
@@ -154,8 +154,16 @@ export * from './pipeline'
|
|
|
154
154
|
export * from './calendar'
|
|
155
155
|
|
|
156
156
|
// Activity components (timeline, quick log, log dialog)
|
|
157
|
-
export { ActivityTimeline } from './ActivityTimeline'
|
|
158
|
-
export type {
|
|
157
|
+
export { ActivityTimeline, actorInitials, dayHeading } from './ActivityTimeline'
|
|
158
|
+
export type {
|
|
159
|
+
ActivityTimelineProps,
|
|
160
|
+
ActivityTimelineItem,
|
|
161
|
+
ActivityTimelineActor,
|
|
162
|
+
ActivityTone,
|
|
163
|
+
} from './ActivityTimeline'
|
|
164
|
+
// The shared, filterable activity feed: filter bar + page-level composer over
|
|
165
|
+
// any append-only event stream (startsim-768w.19.5).
|
|
166
|
+
export * from './activity'
|
|
159
167
|
export { QuickLogButtons } from './QuickLogButtons'
|
|
160
168
|
export type { QuickLogButtonsProps, QuickLogAction } from './QuickLogButtons'
|
|
161
169
|
export { LogActivityDialog } from './LogActivityDialog'
|