-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(dashboard): Activity feed panel #7238
base: new-activity-feed-page
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for dashboard-v2-novu-staging ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
✅ Deploy Preview for dev-web-novu ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
TODO: Missing backend support for digest events widget | ||
{job.type === 'digest' && job.digest?.events && ( | ||
<ActivityDetailCard title="Digest Events" expandable={true} open> | ||
<div className="min-w-0 max-w-full font-mono"> | ||
{job.digest.events.map((event: DigestEvent, index: number) => ( | ||
<div key={index} className="group flex items-center gap-2 rounded-sm px-1 py-1.5 hover:bg-neutral-100"> | ||
<RiCheckboxCircleLine className="text-success h-4 w-4 shrink-0" /> | ||
<div className="flex items-center gap-2 truncate"> | ||
<span className="truncate text-xs text-neutral-500">{event.type}</span> | ||
<span className="text-xs text-neutral-400"> | ||
{`${format(new Date(job.updatedAt), 'HH:mm')} UTC`} | ||
</span> | ||
</div> | ||
</div> | ||
))} | ||
</div> | ||
</ActivityDetailCard> | ||
)} */} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much effort is to enrich the API accordingly?
initial={{ width: 0, opacity: 0 }} | ||
animate={{ width: '35%', opacity: 1 }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we should not animate the width but rather the position of the activity panel, as the animation creates an effect of "shrinked/stretched" content.
hasActiveFilters={false} | ||
onClearFilters={() => {}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please remove all unused props as they fail the build
import { JOB_STATUS_CONFIG } from './constants'; | ||
|
||
interface ActivityJobItemProps { | ||
job: IActivityJob; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't use I
to mark that's the interface
); | ||
} | ||
|
||
function LoadingSkeleton() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we have it as a separate component, then whenever we update the layout of the panel or change anything in there, we will need to "remember" to make the same adjustments for the skeleton. Ideally, we should reuse the same layout component or have skeletons embedded into the ActivityPanel.
return ( | ||
<div className="animate-pulse"> | ||
<div className="flex items-center gap-2 border-b border-t border-neutral-200 border-b-neutral-100 p-2"> | ||
<div className="h-3 w-3 rounded-full bg-neutral-200" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the Skeleton
primitive
> | ||
<div> | ||
<div className="flex items-center gap-2 border-b border-t border-neutral-200 border-b-neutral-100 p-2 px-3"> | ||
<Route className="h-3 w-3" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RiRouteFill
if (error || !activity) { | ||
return ( | ||
<motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.3 }}> | ||
<div className="flex h-96 items-center justify-center"> | ||
<div className="text-foreground-600 text-sm">Failed to load activity details</div> | ||
</div> | ||
</motion.div> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
export function ActivityDetailCard({ title, timestamp, expandable = false, open, children }: ActivityDetailCardProps) { | ||
const [internalOpen, setInternalOpen] = useState(false); | ||
const isExpanded = open ?? internalOpen; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have the accordion primitive that we can use for the nice animation. However, I don't know if it will require doing some updates.
<div className="flex items-center justify-between"> | ||
<span className="text-foreground-400 max-w-[300px] truncate pr-2 text-xs">{getStatusMessage(job)}</span> | ||
<Badge variant="soft" className="bg-foreground-50 shrink-0 px-2 py-0.5 text-[11px] leading-3"> | ||
{format(new Date(job.updatedAt), 'MMM d yyyy, HH:mm:ss')} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be useful to show here also the TimeDisplayHoverCard
export function ExecutionDetailItem({ detail }: ExecutionDetailItemProps) { | ||
const { icon: StatusIcon, colorClass } = getStatusConfig(detail.status); | ||
|
||
const formatContent = (raw: unknown): string => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move to the helper util file
What changed? Why was the change needed?
This PR utilized the existing API without any extra changes there.
Not in scope: Filters, Workflow Editor connectivity
Screenshots
https://www.loom.com/share/0923c3816bbc49fbae494c24266d5c98
Expand for optional sections
Related enterprise PR
Special notes for your reviewer