Ghost/ghost/admin/app/components/dashboard/charts/recents.hbs
Simon Backx e986b78458
Added member attributions to activity feed (#15283)
refs https://github.com/TryGhost/Team/issues/1833
refs https://github.com/TryGhost/Team/issues/1834

We've added the attribution property to subscription and signup events when the
flag is enabled. The attributions resource is fetched by creating multiple relations
on the model, rather than polymorphic as we ran into issues with that as they can't
be nullable/optional.

The parse-member-event structure has been updated to make it easier to work with,
specifically `getObject` is only used when the event is clickable, and there is now a 
join property which makes it easier to join the action and the object.
2022-08-24 10:11:25 -04:00

143 lines
9.2 KiB
Handlebars

<section class="gh-dashboard-section gh-dashboard-recents" {{did-insert this.loadPosts}}>
<article class="gh-dashboard-box">
<div class="gh-dashboard-tabs">
<button type="button" class="gh-dashboard-tab {{if this.postsTabSelected 'is-selected'}}" {{on "click" this.changeTabToPosts}}>
<Dashboard::Parts::Metric
@label="Recent posts" />
</button>
{{#if this.areMembersEnabled}}
<button type="button" class="gh-dashboard-tab {{if this.activityTabSelected 'is-selected'}}" {{on "click" this.changeTabToActivity}}>
<Dashboard::Parts::Metric
@label="Member activity" />
</button>
{{/if}}
</div>
{{#if this.postsTabSelected}}
<div class="gh-dashboard-recents-posts gh-dashboard-list {{unless this.areNewslettersEnabled 'is-single'}}">
<div class="gh-dashboard-list-header">
<div class="gh-dashboard-list-title">Title</div>
{{#if this.areNewslettersEnabled}}
<div class="gh-dashboard-list-title">Sends</div>
<div class="gh-dashboard-list-title">Open rate</div>
{{else}}
<div class="gh-dashboard-list-title">Published</div>
{{/if}}
</div>
<div class="gh-dashboard-list-body">
{{#each this.posts as |post|}}
<LinkTo class="gh-dashboard-list-item permalink" @route="editor.edit" @models={{array post.displayName post.id}}>
<div class="gh-dashboard-list-item-sub">
<span class="gh-dashboard-list-text">{{post.title}}</span>
</div>
{{#if this.areNewslettersEnabled}}
<div class="gh-dashboard-list-item-sub">
<span class="gh-dashboard-metric-minivalue {{unless post.email "na"}}">
{{#if post.email}}
{{format-number post.email.emailCount}}
{{else}}
&mdash;
{{/if}}
</span>
</div>
<div class="gh-dashboard-list-item-sub">
<span class="gh-dashboard-rate-bar">
{{#if post.email}}
<span class="gh-dashboard-metric-minivalue">{{post.email.openRate}}%</span>
<span class="gh-dashboard-rate-amount"><span style={{html-safe (concat "width: " post.email.openRate "%;")}}/></span>
{{else}}
<span class="gh-dashboard-metric-minivalue na">&mdash;</span>
{{/if}}
</span>
</div>
{{else}}
<div class="gh-dashboard-list-item-sub">
<span class="gh-dashboard-list-subtext">{{moment-format (moment-site-tz post.publishedAtUTC) "DD MMM YYYY HH:mm"}}</span>
</div>
{{/if}}
</LinkTo>
{{else}}
<div class="gh-dashboard-list-empty">
<p>No published posts yet.</p>
</div>
{{/each}}
</div>
<div class="gh-dashboard-list-footer">
<LinkTo @route="posts" @query={{reset-query-params "posts"}}>See all posts &rarr;</LinkTo>
</div>
</div>
{{else}}
<div class="gh-dashboard-recents-activity gh-dashboard-list {{if (feature "memberAttribution") 'feature-memberAttribution'}}" data-test-dashboard-member-activity>
<div class="gh-dashboard-list-header">
<div class="gh-dashboard-list-title">Member</div>
<div class="gh-dashboard-list-title">Event</div>
{{#if (feature "memberAttribution")}}<div class="gh-dashboard-list-title">Attribution</div>{{/if}}
<div class="gh-dashboard-list-title">Time</div>
</div>
<div class="gh-dashboard-list-body">
{{#let (members-event-fetcher filter=(members-event-filter excludeEmailEvents=true) pageSize=5) as |eventsFetcher|}}
{{#if eventsFetcher.isError}}
<div class="gh-dashboard-list-error">
<p>There was an error loading events</p>
{{#if eventsFetcher.errorMessage}}
<code>{{eventsFetcher.errorMessage}}</code>
{{/if}}
</div>
{{/if}}
{{#if eventsFetcher.isLoading}}
<div class="gh-dashboard-list-loading">
<div class="gh-loading-spinner"></div>
</div>
{{else}}
{{#if eventsFetcher.data}}
{{#each eventsFetcher.data as |event|}}
{{#let (parse-member-event event eventsFetcher.hasMultipleNewsletters) as |parsedEvent|}}
<div class="gh-dashboard-list-item member-details">
<div class="gh-dashboard-list-item-sub">
<GhMemberAvatar @member={{parsedEvent.member}} @containerClass="w8 h8 mr3 flex-shrink-0" />
<LinkTo class="gh-dashboard-list-text" @route="member" @model="{{parsedEvent.memberId}}" data-test-dashboard-member-activity-item>{{parsedEvent.subject}}</LinkTo>
</div>
<div class="gh-dashboard-list-item-sub">
{{svg-jar parsedEvent.icon}}
<span class="gh-dashboard-list-subtext">
{{capitalize-first-letter parsedEvent.action}}
{{#if parsedEvent.url}}
{{parsedEvent.join}}
<a class="ghost-members-activity-object-link {{if (feature "memberAttribution") 'hidden'}}" href="{{parsedEvent.url}}" target="_blank" rel="noopener noreferrer">{{parsedEvent.object}}</a>
{{/if}}
{{#if parsedEvent.info}}
<span class="highlight">{{parsedEvent.info}}</span>
{{/if}}
</span>
</div>
{{#if (feature "memberAttribution")}}
<div class="gh-dashboard-list-item-sub">
{{#if parsedEvent.url}}
<a class="ghost-members-activity-object-link" href="{{parsedEvent.url}}" target="_blank" rel="noopener noreferrer">{{parsedEvent.object}}</a>
{{else}}
<span class="gh-list-nodata">&mdash;</span>
{{/if}}
</div>
{{/if}}
<div class="gh-dashboard-list-item-sub gh-dashboard-list-item-date">
<span class="gh-dashboard-list-subtext">{{moment-from-now parsedEvent.timestamp}}</span>
</div>
</div>
{{/let}}
{{/each}}
{{else}}
<div class="gh-dashboard-list-empty" data-test-no-member-activities>
<p>No activity yet.</p>
</div>
{{/if}}
{{/if}}
{{/let}}
</div>
<div class="gh-dashboard-list-footer">
<LinkTo @route="members-activity" @query={{reset-query-params "members-activity"}}>See all activity &rarr;</LinkTo>
</div>
</div>
{{/if}}
</article>
</section>