mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-25 09:03:12 +03:00
More layout tweaks to new dashboard
refs: https://github.com/TryGhost/Team/issues/1462
This commit is contained in:
parent
7e499573e5
commit
f046e5e118
@ -22,37 +22,39 @@
|
||||
{{#if option.name}}{{option.name}}{{else}}<span class="red">Unknown option</span>{{/if}}
|
||||
</PowerSelect>
|
||||
</div>
|
||||
<div id="gh-dashboard5-anchor-globaldate">
|
||||
March 31, 2022
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{!-- {{#if this.hasPaidTiers}}
|
||||
{{!--
|
||||
{{#if this.hasPaidTiers}}
|
||||
<div class="gh-dashboard5-paid">
|
||||
<section class="gh-dashboard5-section">
|
||||
<div class="gh-dashboard5-growth">
|
||||
<article class="gh-dashboard5-box">
|
||||
<Dashboard::V5::ChartPaidMembers @days={{this.days}}/>
|
||||
</article>
|
||||
|
||||
<article class="gh-dashboard5-box">
|
||||
<Dashboard::V5::ChartPaidMix />
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{{/if}} --}}
|
||||
{{/if}}
|
||||
--}}
|
||||
|
||||
{{#if this.areNewslettersEnabled}}
|
||||
<section class="gh-dashboard5-split is-third">
|
||||
<section class="gh-dashboard5-section gh-dashboard5-engagement">
|
||||
<Dashboard::V5::ChartEngagement />
|
||||
</section>
|
||||
<section class="gh-dashboard5-split">
|
||||
<section class="gh-dashboard5-split">
|
||||
<section class="gh-dashboard5-section gh-dashboard5-engagement">
|
||||
<Dashboard::V5::ChartEngagement />
|
||||
</section>
|
||||
|
||||
<section class="gh-dashboard5-section gh-dashboard5-email">
|
||||
<article class="gh-dashboard5-box">
|
||||
<section class="gh-dashboard5-section gh-dashboard5-email">
|
||||
<Dashboard::V5::ChartEmail />
|
||||
</article>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="gh-dashboard5-section gh-dashboard5-rate">
|
||||
<Dashboard::V5::ChartOpenRate />
|
||||
</section>
|
||||
</section>
|
||||
{{else}}
|
||||
@ -63,33 +65,42 @@
|
||||
|
||||
{{else}}
|
||||
{{#if this.areNewslettersEnabled}}
|
||||
<section class="gh-dashboard5-section gh-dashboard5-email">
|
||||
<article class="gh-dashboard5-box">
|
||||
<Dashboard::V5::ChartEmail />
|
||||
</article>
|
||||
</section>
|
||||
<section class="gh-dashboard5-split">
|
||||
<section class="gh-dashboard5-split">
|
||||
<section class="gh-dashboard5-section gh-dashboard5-engagement">
|
||||
<Dashboard::V5::ChartEngagement />
|
||||
</section>
|
||||
|
||||
<section class="gh-dashboard5-section gh-dashboard5-email">
|
||||
<Dashboard::V5::ChartEmail />
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section class="gh-dashboard5-section gh-dashboard5-rate">
|
||||
<Dashboard::V5::ChartOpenRate />
|
||||
</section>
|
||||
</section>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
<section class="gh-dashboard5-split">
|
||||
<section class="gh-dashboard5-section gh-dashboard5-posts">
|
||||
<article class="gh-dashboard5-box">
|
||||
<Dashboard::V5::RecentPosts />
|
||||
</article>
|
||||
</section>
|
||||
<section class="gh-dashboard5-section gh-dashboard5-activity">
|
||||
<article class="gh-dashboard5-box">
|
||||
<Dashboard::V5::RecentActivity />
|
||||
</article>
|
||||
</section>
|
||||
|
||||
<section class="gh-dashboard5-section gh-dashboard5-resource">
|
||||
<Dashboard::V5::Resources::Help />
|
||||
</section>
|
||||
|
||||
{{!-- <section class="gh-dashboard-section gh-dashboard5-resource">
|
||||
<Dashboard::V5::ResourceGeneral />
|
||||
</section> --}}
|
||||
</section>
|
||||
|
||||
{{!-- <Dashboard::V5::Resources::WhatsNew />
|
||||
{{!--
|
||||
<Dashboard::V5::Resources::WhatsNew />
|
||||
<Dashboard::V5::Resources::LatestNewsletters />
|
||||
<Dashboard::V5::Resources::StaffPicks /> --}}
|
||||
<Dashboard::V5::Resources::StaffPicks />
|
||||
--}}
|
||||
{{/if}}
|
||||
<Dashboard::V5::PrototypeControlPanel />
|
||||
</section>
|
||||
|
@ -1,5 +1,38 @@
|
||||
<div class="gh-dashboard5-title">
|
||||
<h4>{{this.chartTitle}}</h4>
|
||||
<div class="gh-dashboard5-stats{{unless this.hasPaidTiers ' is-solo'}}" {{did-insert this.loadCharts}}>
|
||||
<button class="gh-dashboard5-stats-button {{if this.chartShowingTotal 'is-selected'}}" type="button" {{on "click" (fn this.changeChartDisplay "total")}}>
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label={{gh-pluralize this.totalMembers "Total member" without-count=true}}
|
||||
@value={{format-number this.totalMembers}}
|
||||
@trends={{this.hasTrends}}
|
||||
@percentage={{this.totalMembersTrend}}
|
||||
@large={{true}} />
|
||||
</button>
|
||||
{{#if this.hasPaidTiers}}
|
||||
<button class="gh-dashboard5-stats-button {{if this.chartShowingPaid 'is-selected'}}" type="button" {{on "click" (fn this.changeChartDisplay "paid")}}>
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label={{gh-pluralize this.paidMembers "Paid member" without-count=true}}
|
||||
@value={{format-number this.paidMembers}}
|
||||
@trends={{this.hasTrends}}
|
||||
@percentage={{this.paidMembersTrend}}
|
||||
@large={{true}} />
|
||||
</button>
|
||||
<button class="gh-dashboard5-stats-button {{if this.chartShowingBreakdown 'is-selected'}}" type="button" {{on "click" (fn this.changeChartDisplay "breakdown")}}>
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="Paid breakdown"
|
||||
@value={{format-number this.paidBreakdown}}
|
||||
@trends={{this.hasTrends}}
|
||||
@percentage={{this.paidBreakdownTrend}}
|
||||
@large={{true}} />
|
||||
</button>
|
||||
<button class="gh-dashboard5-stats-button {{if this.chartShowingMonthly 'is-selected'}}" type="button" {{on "click" (fn this.changeChartDisplay "monthly")}}>
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="MRR"
|
||||
@value="${{gh-price-amount this.currentMRR}}"
|
||||
@trends={{this.hasTrends}}
|
||||
@percentage={{this.mrrTrend}}
|
||||
@large={{true}} />
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="gh-dashboard5-chart">
|
||||
@ -13,48 +46,5 @@
|
||||
@options={{this.chartOptions}}
|
||||
@height={{this.chartHeight}} />
|
||||
</div>
|
||||
<div class="gh-dashboard5-chart-ticks">
|
||||
<span>Mar 1</span>
|
||||
<span>Mar 6</span>
|
||||
<span>Mar 12</span>
|
||||
<span>Mar 18</span>
|
||||
<span>Mar 24</span>
|
||||
<span>Mar 30</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="gh-dashboard5-stats" {{did-insert this.loadCharts}}>
|
||||
<button class="gh-dashboard5-stats-button {{if this.chartShowingTotal 'is-selected'}}" type="button" {{on "click" (fn this.changeChartDisplay "total")}}>
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label={{gh-pluralize this.totalMembers "Total member" without-count=true}}
|
||||
@value={{format-number this.totalMembers}}
|
||||
@trends={{this.hasTrends}}
|
||||
@percentage={{this.totalMembersTrend}}
|
||||
@large={{true}}
|
||||
@center={{true}}
|
||||
@reverse={{true}} />
|
||||
</button>
|
||||
{{#if this.hasPaidTiers}}
|
||||
<button class="gh-dashboard5-stats-button {{if this.chartShowingPaid 'is-selected'}}" type="button" {{on "click" (fn this.changeChartDisplay "paid")}}>
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label={{gh-pluralize this.paidMembers "Paid member" without-count=true}}
|
||||
@value={{format-number this.paidMembers}}
|
||||
@trends={{this.hasTrends}}
|
||||
@percentage={{this.paidMembersTrend}}
|
||||
@large={{true}}
|
||||
@center={{true}}
|
||||
@reverse={{true}} />
|
||||
</button>
|
||||
<button class="gh-dashboard5-stats-button {{if this.chartShowingMonthly 'is-selected'}}" type="button" {{on "click" (fn this.changeChartDisplay "monthly")}}>
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="MRR"
|
||||
@value="${{gh-price-amount this.currentMRR}}"
|
||||
@trends={{this.hasTrends}}
|
||||
@percentage={{this.mrrTrend}}
|
||||
@large={{true}}
|
||||
@center={{true}}
|
||||
@reverse={{true}} />
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -19,8 +19,7 @@ export default class ChartAnchor extends Component {
|
||||
@action
|
||||
changeChartDisplay(type) {
|
||||
this.chartDisplay = type;
|
||||
document.querySelector('#gh-dashboard5-bar').classList.remove('is-show');
|
||||
document.querySelector('#gh-dashboard5-anchor-tooltip').classList.remove('is-show');
|
||||
this.loadCharts();
|
||||
}
|
||||
|
||||
get chartShowingTotal() {
|
||||
@ -31,6 +30,10 @@ export default class ChartAnchor extends Component {
|
||||
return (this.chartDisplay === 'paid');
|
||||
}
|
||||
|
||||
get chartShowingBreakdown() {
|
||||
return (this.chartDisplay === 'breakdown');
|
||||
}
|
||||
|
||||
get chartShowingMonthly() {
|
||||
return (this.chartDisplay === 'monthly');
|
||||
}
|
||||
@ -40,6 +43,8 @@ export default class ChartAnchor extends Component {
|
||||
return this.dashboardStats.memberCountStats === null;
|
||||
} else if (this.chartDisplay === 'paid') {
|
||||
return this.dashboardStats.memberCountStats === null;
|
||||
} else if (this.chartDisplay === 'breakdown') {
|
||||
return this.dashboardStats.memberCountStats === null;
|
||||
} else if (this.chartDisplay === 'monthly') {
|
||||
return this.dashboardStats.mrrStats === null;
|
||||
}
|
||||
@ -54,6 +59,10 @@ export default class ChartAnchor extends Component {
|
||||
return this.dashboardStats.memberCounts?.paid ?? 0;
|
||||
}
|
||||
|
||||
get paidBreakdown() {
|
||||
return this.dashboardStats.memberCounts?.breakdown ?? 0;
|
||||
}
|
||||
|
||||
get freeMembers() {
|
||||
return this.dashboardStats.memberCounts?.free ?? 0;
|
||||
}
|
||||
@ -74,6 +83,10 @@ export default class ChartAnchor extends Component {
|
||||
return this.calculatePercentage(this.dashboardStats.memberCountsTrend.paid, this.dashboardStats.memberCounts.paid);
|
||||
}
|
||||
|
||||
get paidBreakdownTrend() {
|
||||
return '40%';
|
||||
}
|
||||
|
||||
get freeMembersTrend() {
|
||||
return this.calculatePercentage(this.dashboardStats.memberCountsTrend.free, this.dashboardStats.memberCounts.free);
|
||||
}
|
||||
@ -86,30 +99,45 @@ export default class ChartAnchor extends Component {
|
||||
return this.dashboardStats.siteStatus?.hasPaidTiers;
|
||||
}
|
||||
|
||||
get chartTitle() {
|
||||
if (this.chartDisplay === 'total') {
|
||||
return 'Total members';
|
||||
} else if (this.chartDisplay === 'paid') {
|
||||
return 'Paid members';
|
||||
} else if (this.chartDisplay === 'monthly') {
|
||||
return 'MRR';
|
||||
}
|
||||
}
|
||||
|
||||
get chartType() {
|
||||
if (this.chartDisplay === 'total') {
|
||||
return 'line';
|
||||
} else if (this.chartDisplay === 'paid') {
|
||||
if (this.chartDisplay === 'breakdown') {
|
||||
return 'bar';
|
||||
} else if (this.chartDisplay === 'monthly') {
|
||||
return 'line';
|
||||
}
|
||||
|
||||
return 'line';
|
||||
}
|
||||
|
||||
get chartData() {
|
||||
let stats = [];
|
||||
let labels = [];
|
||||
let data = [];
|
||||
let newData;
|
||||
let canceledData;
|
||||
|
||||
if (this.chartDisplay === 'breakdown') {
|
||||
stats = this.dashboardStats.filledMemberCountStats;
|
||||
labels = stats.map(stat => stat.date);
|
||||
newData = stats.map(stat => stat.paidSubscribed);
|
||||
canceledData = stats.map(stat => -stat.paidCanceled);
|
||||
|
||||
return {
|
||||
labels: labels,
|
||||
datasets: [
|
||||
{
|
||||
data: newData,
|
||||
fill: false,
|
||||
backgroundColor: '#BD96F6',
|
||||
cubicInterpolationMode: 'monotone',
|
||||
barThickness: 18
|
||||
},{
|
||||
data: canceledData,
|
||||
fill: false,
|
||||
backgroundColor: '#FB76B4',
|
||||
cubicInterpolationMode: 'monotone',
|
||||
barThickness: 18
|
||||
}]
|
||||
};
|
||||
}
|
||||
|
||||
if (this.chartDisplay === 'total') {
|
||||
stats = this.dashboardStats.filledMemberCountStats;
|
||||
@ -152,6 +180,102 @@ export default class ChartAnchor extends Component {
|
||||
}
|
||||
|
||||
get chartOptions() {
|
||||
if (this.chartDisplay === 'breakdown') {
|
||||
return {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
title: {
|
||||
display: false
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
hover: {
|
||||
onHover: function (e) {
|
||||
e.target.style.cursor = 'pointer';
|
||||
}
|
||||
},
|
||||
tooltips: {
|
||||
intersect: false,
|
||||
mode: 'index',
|
||||
displayColors: false,
|
||||
backgroundColor: '#15171A',
|
||||
xPadding: 7,
|
||||
yPadding: 7,
|
||||
cornerRadius: 5,
|
||||
caretSize: 7,
|
||||
caretPadding: 5,
|
||||
bodyFontSize: 12.5,
|
||||
titleFontSize: 12,
|
||||
titleFontStyle: 'normal',
|
||||
titleFontColor: 'rgba(255, 255, 255, 0.7)',
|
||||
titleMarginBottom: 3,
|
||||
callbacks: {
|
||||
title: (tooltipItems) => {
|
||||
return moment(tooltipItems[0].xLabel).format(DATE_FORMAT);
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
offset: true,
|
||||
gridLines: {
|
||||
drawTicks: false,
|
||||
display: true,
|
||||
drawBorder: false,
|
||||
color: 'rgba(255, 255, 255, 0.1)',
|
||||
lineWidth: 0,
|
||||
zeroLineColor: 'rgba(200, 204, 217, 0.75)',
|
||||
zeroLineWidth: 1
|
||||
},
|
||||
ticks: {
|
||||
display: true,
|
||||
maxTicksLimit: 5,
|
||||
fontColor: '#7C8B9A',
|
||||
padding: 8,
|
||||
precision: 0
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
offset: true,
|
||||
stacked: true,
|
||||
gridLines: {
|
||||
color: 'rgba(200, 204, 217, 0.75)',
|
||||
borderDash: [4,4],
|
||||
display: true,
|
||||
drawBorder: true,
|
||||
drawTicks: false,
|
||||
zeroLineWidth: 1,
|
||||
zeroLineColor: 'rgba(200, 204, 217, 0.75)',
|
||||
zeroLineBorderDash: [4,4]
|
||||
},
|
||||
ticks: {
|
||||
display: true,
|
||||
maxRotation: 0,
|
||||
minRotation: 0,
|
||||
padding: 8,
|
||||
autoSkip: true,
|
||||
maxTicksLimit: 7
|
||||
},
|
||||
type: 'time',
|
||||
time: {
|
||||
displayFormats: {
|
||||
millisecond: 'MMM DD',
|
||||
second: 'MMM DD',
|
||||
minute: 'MMM DD',
|
||||
hour: 'MMM DD',
|
||||
day: 'MMM DD',
|
||||
week: 'MMM DD',
|
||||
month: 'MMM DD',
|
||||
quarter: 'MMM DD',
|
||||
year: 'MMM DD'
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
@ -209,8 +333,11 @@ export default class ChartAnchor extends Component {
|
||||
yAxes: [{
|
||||
gridLines: {
|
||||
drawTicks: false,
|
||||
display: false,
|
||||
drawBorder: false
|
||||
display: true,
|
||||
drawBorder: false,
|
||||
color: 'transparent',
|
||||
zeroLineColor: 'rgba(200, 204, 217, 0.75)',
|
||||
zeroLineWidth: 1
|
||||
},
|
||||
ticks: {
|
||||
display: false,
|
||||
@ -218,26 +345,31 @@ export default class ChartAnchor extends Component {
|
||||
fontColor: '#7C8B9A',
|
||||
padding: 8,
|
||||
precision: 0,
|
||||
beginAtZero: false
|
||||
stepSize: 1
|
||||
},
|
||||
display: true
|
||||
}],
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
color: '#DDE1E5',
|
||||
color: 'rgba(200, 204, 217, 0.75)',
|
||||
borderDash: [4,4],
|
||||
display: true,
|
||||
drawBorder: true,
|
||||
drawTicks: false,
|
||||
zeroLineWidth: 1,
|
||||
zeroLineColor: '#DDE1E5',
|
||||
zeroLineColor: 'rgba(200, 204, 217, 0.75)',
|
||||
zeroLineBorderDash: [4,4]
|
||||
},
|
||||
ticks: {
|
||||
display: false,
|
||||
display: true,
|
||||
maxRotation: 0,
|
||||
minRotation: 0,
|
||||
beginAtZero: false
|
||||
padding: 14,
|
||||
autoSkip: true,
|
||||
maxTicksLimit: 8,
|
||||
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Droid Sans", "Helvetica Neue", sans-serif',
|
||||
fontSize: 11,
|
||||
fontColor: '#7c8b9a'
|
||||
},
|
||||
type: 'time',
|
||||
time: {
|
||||
@ -260,7 +392,7 @@ export default class ChartAnchor extends Component {
|
||||
}
|
||||
|
||||
get chartHeight() {
|
||||
return 275;
|
||||
return 300;
|
||||
}
|
||||
|
||||
calculatePercentage(from, to) {
|
||||
|
@ -1,48 +1,15 @@
|
||||
<div class="gh-dashboard5-title">
|
||||
<h4>Email</h4>
|
||||
</div>
|
||||
|
||||
<div {{did-insert this.loadCharts}} class="gh-dashboard5-insert">
|
||||
<div class="gh-dashboard5-insert-item">
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="Newsletter subscribers"
|
||||
@value={{format-number this.dataSubscribers.total}}
|
||||
@reverse={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="gh-dashboard5-insert-item">
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="Emails sent over last 30 days"
|
||||
@value={{format-number this.dataEmailsSent}}
|
||||
@reverse={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="gh-dashboard5-insert-item">
|
||||
<div class="gh-dashboard5-chart">
|
||||
{{#if this.loading}}
|
||||
<div class="gh-dashboard5-chart-loading" style={{html-safe (concat "height: " this.chartHeight "px;")}}/>
|
||||
{{else}}
|
||||
<div class="gh-dashboard5-chart-ticks">
|
||||
<span>100%</span>
|
||||
<span>75%</span>
|
||||
<span>50%</span>
|
||||
<span>25%</span>
|
||||
</div>
|
||||
<div class="gh-dashboard5-chart-container">
|
||||
<EmberChart
|
||||
@type={{this.chartType}}
|
||||
@data={{this.chartData}}
|
||||
@options={{this.chartOptions}}
|
||||
@height={{this.chartHeight}} />
|
||||
</div>
|
||||
{{/if}}
|
||||
<article class="gh-dashboard5-box">
|
||||
<div {{did-insert this.loadCharts}} class="gh-dashboard5-insert">
|
||||
<div class="gh-dashboard5-insert-item">
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="Newsletter subscribers"
|
||||
@value={{format-number this.dataSubscribers.total}} />
|
||||
</div>
|
||||
|
||||
<div class="gh-dashboard5-insert-item">
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="Emails sent over last 30 days"
|
||||
@value={{format-number this.dataEmailsSent}} />
|
||||
</div>
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="Open rate"
|
||||
@value="{{this.currentOpenRate}}%"
|
||||
@reverse={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
@ -1,22 +1,15 @@
|
||||
<article {{did-insert this.loadCharts}} class="gh-dashboard5-box">
|
||||
<div class="gh-dashboard5-title">
|
||||
<h4>Engagement</h4>
|
||||
</div>
|
||||
|
||||
<div class="gh-dashboard5-insert">
|
||||
<div class="gh-dashboard5-insert-item">
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="Engaged over 30 days"
|
||||
@value={{this.data30Days}}
|
||||
@reverse={true}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="gh-dashboard5-insert-item">
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="Engaged over 7 days"
|
||||
@value={{this.data7Days}}
|
||||
@reverse={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
27
ghost/admin/app/components/dashboard/v5/chart-open-rate.hbs
Normal file
27
ghost/admin/app/components/dashboard/v5/chart-open-rate.hbs
Normal file
@ -0,0 +1,27 @@
|
||||
<article class="gh-dashboard5-box">
|
||||
<div class="gh-dashboard5-insert">
|
||||
<Dashboard::v5::parts::ChartMetric
|
||||
@label="Open rate"
|
||||
@value="{{this.currentOpenRate}}%" />
|
||||
|
||||
<div class="gh-dashboard5-chart">
|
||||
{{#if this.loading}}
|
||||
<div class="gh-dashboard5-chart-loading" style={{html-safe (concat "height: " this.chartHeight "px;")}}/>
|
||||
{{else}}
|
||||
<div class="gh-dashboard5-chart-ticks">
|
||||
<span>100%</span>
|
||||
<span>75%</span>
|
||||
<span>50%</span>
|
||||
<span>25%</span>
|
||||
</div>
|
||||
<div class="gh-dashboard5-chart-container">
|
||||
<EmberChart
|
||||
@type={{this.chartType}}
|
||||
@data={{this.chartData}}
|
||||
@options={{this.chartOptions}}
|
||||
@height={{this.chartHeight}} />
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
137
ghost/admin/app/components/dashboard/v5/chart-open-rate.js
Normal file
137
ghost/admin/app/components/dashboard/v5/chart-open-rate.js
Normal file
@ -0,0 +1,137 @@
|
||||
import Component from '@glimmer/component';
|
||||
import {action} from '@ember/object';
|
||||
import {inject as service} from '@ember/service';
|
||||
|
||||
export default class ChartOpenRate extends Component {
|
||||
@service dashboardStats;
|
||||
|
||||
/**
|
||||
* Call this method when you need to fetch new data from the server.
|
||||
*/
|
||||
@action
|
||||
loadCharts() {
|
||||
// The dashboard stats service will take care or reusing and limiting API-requests between charts
|
||||
this.dashboardStats.loadNewsletterSubscribers();
|
||||
this.dashboardStats.loadEmailsSent();
|
||||
this.dashboardStats.loadEmailOpenRateStats();
|
||||
}
|
||||
|
||||
get dataSubscribers() {
|
||||
// @todo: show paid, free, total together
|
||||
return this.dashboardStats.newsletterSubscribers ?? {
|
||||
total: 0,
|
||||
free: 0,
|
||||
paid: 0
|
||||
};
|
||||
}
|
||||
|
||||
get currentOpenRate() {
|
||||
if (this.dashboardStats.emailOpenRateStats === null || this.dashboardStats.emailOpenRateStats.length === 0) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return this.dashboardStats.emailOpenRateStats[this.dashboardStats.emailOpenRateStats.length - 1].openRate;
|
||||
}
|
||||
|
||||
get dataEmailsSent() {
|
||||
return this.dashboardStats.emailsSent30d ?? 0;
|
||||
}
|
||||
|
||||
get loading() {
|
||||
return this.dashboardStats.emailOpenRateStats === null;
|
||||
}
|
||||
|
||||
get chartType() {
|
||||
return 'bar';
|
||||
}
|
||||
|
||||
get chartData() {
|
||||
const stats = this.dashboardStats.emailOpenRateStats;
|
||||
const labels = stats.map(stat => stat.subject);
|
||||
const data = stats.map(stat => stat.openRate);
|
||||
|
||||
return {
|
||||
labels,
|
||||
datasets: [{
|
||||
data,
|
||||
fill: false,
|
||||
backgroundColor: '#14B8FF',
|
||||
cubicInterpolationMode: 'monotone',
|
||||
barThickness: 18
|
||||
}]
|
||||
};
|
||||
}
|
||||
|
||||
get chartOptions() {
|
||||
return {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
title: {
|
||||
display: false
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
hover: {
|
||||
onHover: function (e) {
|
||||
e.target.style.cursor = 'pointer';
|
||||
}
|
||||
},
|
||||
tooltips: {
|
||||
intersect: false,
|
||||
mode: 'index',
|
||||
displayColors: false,
|
||||
backgroundColor: '#15171A',
|
||||
xPadding: 7,
|
||||
yPadding: 7,
|
||||
cornerRadius: 5,
|
||||
caretSize: 7,
|
||||
caretPadding: 5,
|
||||
bodyFontSize: 12.5,
|
||||
titleFontSize: 12,
|
||||
titleFontStyle: 'normal',
|
||||
titleFontColor: 'rgba(255, 255, 255, 0.7)',
|
||||
titleMarginBottom: 3
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
gridLines: {
|
||||
drawTicks: false,
|
||||
display: false,
|
||||
drawBorder: false
|
||||
},
|
||||
ticks: {
|
||||
display: false,
|
||||
maxTicksLimit: 5,
|
||||
fontColor: '#7C8B9A',
|
||||
padding: 8,
|
||||
precision: 0
|
||||
}
|
||||
}],
|
||||
xAxes: [{
|
||||
gridLines: {
|
||||
color: 'rgba(200, 204, 217, 0.75)',
|
||||
borderDash: [4,4],
|
||||
display: true,
|
||||
drawBorder: true,
|
||||
drawTicks: false,
|
||||
zeroLineWidth: 1,
|
||||
zeroLineColor: 'rgba(200, 204, 217, 0.75)',
|
||||
zeroLineBorderDash: [4,4]
|
||||
},
|
||||
ticks: {
|
||||
display: false,
|
||||
maxTicksLimit: 5,
|
||||
autoSkip: true,
|
||||
maxRotation: 0,
|
||||
minRotation: 0
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
get chartHeight() {
|
||||
return 125;
|
||||
}
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
<div class="gh-dashboard5-metric {{if @center "is-center"}} {{if @reverse "is-reverse"}}">
|
||||
<div class="gh-dashboard5-metric {{if @center "is-center"}} {{if @reverse "is-reverse"}} {{if @large "is-large"}}">
|
||||
<div class="gh-dashboard5-metric-data">
|
||||
{{#if @reverse}}
|
||||
{{#if @value}}
|
||||
<div class="gh-dashboard5-metric-value {{if @large "is-large"}}">
|
||||
<div class="gh-dashboard5-metric-value">
|
||||
{{@value}}
|
||||
</div>
|
||||
{{!-- {{#if @trends}}
|
||||
{{#if @trends}}
|
||||
<Dashboard::v5::parts::ChartPercentage @percentage={{@percentage}}/>
|
||||
{{/if}} --}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<h5 class="gh-dashboard5-metric-label">
|
||||
{{@label}}
|
||||
@ -17,12 +17,12 @@
|
||||
{{@label}}
|
||||
</h5>
|
||||
{{#if @value}}
|
||||
<div class="gh-dashboard5-metric-value {{if @large "is-large"}}">
|
||||
<div class="gh-dashboard5-metric-value">
|
||||
{{@value}}
|
||||
{{#if @trends}}
|
||||
<Dashboard::v5::parts::ChartPercentage @percentage={{@percentage}}/>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#if @trends}}
|
||||
<Dashboard::v5::parts::ChartPercentage @percentage={{@percentage}}/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="gh-dashboard5-list" data-test-dashboard-member-activity>
|
||||
<div class="gh-dashboard5-title">
|
||||
<h4>Recent activity</h4><h4>Recent posts</h4>
|
||||
<div class="gh-dashboard5-list-header">
|
||||
<div class="gh-dashboard5-list-title">Recent activity</div>
|
||||
</div>
|
||||
|
||||
<div class="gh-dashboard5-list-body">
|
||||
@ -23,16 +23,15 @@
|
||||
{{#let (parse-member-event event) as |parsedEvent|}}
|
||||
<div class="gh-dashboard5-list-item" data-test-dashboard-member-activity-item>
|
||||
<LinkTo class="member-details" @route="member" @model="{{parsedEvent.memberId}}">
|
||||
{{!-- {{svg-jar parsedEvent.icon}} --}}
|
||||
{{!-- {{parsedEvent.subject}} --}}
|
||||
John
|
||||
<GhMemberAvatar @member={{parsedEvent.member}} @containerClass="w8 h8 mr3 flex-shrink-0" />
|
||||
{{parsedEvent.subject}}
|
||||
<span>
|
||||
{{parsedEvent.action}}
|
||||
{{parsedEvent.object}}
|
||||
{{parsedEvent.info}}
|
||||
</span>
|
||||
</LinkTo>
|
||||
{{!-- <span class="gh-dashboard-activity-time">{{moment-from-now parsedEvent.timestamp}}</span> --}}
|
||||
<span class="gh-dashboard-activity-time">{{moment-from-now parsedEvent.timestamp}}</span>
|
||||
</div>
|
||||
{{/let}}
|
||||
{{/each}}
|
||||
|
@ -1,6 +1,8 @@
|
||||
<div class="gh-dashboard5-list" {{did-insert this.loadPosts}}>
|
||||
<div class="gh-dashboard5-title">
|
||||
<h4>Recent posts</h4>
|
||||
<div class="gh-dashboard5-list-header">
|
||||
<div class="gh-dashboard5-list-title">Recent posts</div>
|
||||
<div class="gh-dashboard5-list-title">Sends</div>
|
||||
<div class="gh-dashboard5-list-title">Opens</div>
|
||||
</div>
|
||||
|
||||
<div class="gh-dashboard5-list-body">
|
||||
@ -9,6 +11,8 @@
|
||||
<LinkTo class="gh-dashboard5-list-post permalink" @route="editor.edit" @models={{array post.displayName post.id}}>
|
||||
{{post.title}}
|
||||
</LinkTo>
|
||||
<span>231</span>
|
||||
<span>65%</span>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="gh-dashboard5-list-empty">
|
||||
|
@ -1098,3 +1098,9 @@ kbd {
|
||||
.gh-done {
|
||||
background: #15171A;
|
||||
}
|
||||
|
||||
|
||||
/* Dashboard v5 */
|
||||
.gh-dashboard5-anchor .gh-dashboard5-stats-button.is-selected {
|
||||
border-color: #394047;
|
||||
}
|
||||
|
@ -974,10 +974,12 @@ a.gh-dashboard-container {
|
||||
}
|
||||
|
||||
|
||||
/* Temporary section for prototype convenience */
|
||||
|
||||
/* ---------------------------------
|
||||
Dashboard v5 Prototype */
|
||||
|
||||
.prototype-panel {
|
||||
/* Keep it out of view */
|
||||
margin-top: 50vh;
|
||||
margin-top: 50vh; /* Keep it out of view */
|
||||
}
|
||||
|
||||
.prototype-states-buttons {
|
||||
@ -1037,6 +1039,10 @@ a.gh-dashboard-container {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------
|
||||
Dashboard v5 Misc */
|
||||
|
||||
.gh-dashboard5-number {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
@ -1129,7 +1135,6 @@ a.gh-dashboard-container {
|
||||
|
||||
.gh-dashboard5-overview > .gh-dashboard5-box {
|
||||
padding: 0;
|
||||
/* min-height: 346px; */
|
||||
}
|
||||
|
||||
.gh-dashboard5-overview .gh-dashboard5-insert {
|
||||
@ -1171,13 +1176,13 @@ a.gh-dashboard-container {
|
||||
|
||||
.gh-dashboard5-section .ember-power-select-selected-item {
|
||||
font-size: 1.2rem;
|
||||
text-transform: none;
|
||||
text-transform: uppercase;
|
||||
font-weight: 500;
|
||||
letter-spacing: .2px;
|
||||
font-size: 1.1rem;
|
||||
letter-spacing: .2px;
|
||||
color: var(--midgrey);
|
||||
letter-spacing: .3px;
|
||||
line-height: 1em;
|
||||
padding: 0;
|
||||
color: var(--midlightgrey);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.gh-dashboard5 .gh-list-header {
|
||||
@ -1314,8 +1319,13 @@ Dashboard v5 Layout */
|
||||
|
||||
.gh-dashboard5-split {
|
||||
display: grid;
|
||||
gap: 24px;
|
||||
gap: 32px;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split.is-four {
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split.is-solo {
|
||||
@ -1326,11 +1336,33 @@ Dashboard v5 Layout */
|
||||
grid-template-columns: 1fr 3fr;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split.is-three {
|
||||
grid-template-columns: 1fr 1fr 2fr;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split.is-fourth {
|
||||
grid-template-columns: 3fr 1fr;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split.is-fifth {
|
||||
grid-template-columns: 2fr 1fr;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split.is-triple {
|
||||
grid-template-columns: 2fr 1fr 1fr;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split .prototype-selection {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-section {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 24px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-container {
|
||||
@ -1348,8 +1380,10 @@ Dashboard v5 Layout */
|
||||
|
||||
.gh-dashboard5-title h4 {
|
||||
margin: 0 16px 0 0;
|
||||
font-weight: 700;
|
||||
color: var(--darkgrey);
|
||||
font-size: 1.65rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.4em;
|
||||
color: #15171a;
|
||||
}
|
||||
|
||||
.gh-dashboard5-title h4:nth-child(2) {
|
||||
@ -1370,8 +1404,6 @@ Dashboard v5 Layout */
|
||||
.gh-dashboard5-area {
|
||||
background: rgb(252,252,252);
|
||||
background: linear-gradient(180deg, rgba(252,252,252,1) 0%, rgba(249,250,254,1) 100%);
|
||||
/* background: rgb(255,249,226);
|
||||
background: linear-gradient(180deg, rgba(255,249,226,1) 0%, rgba(220,242,255,1) 100%); */
|
||||
background: #fafbfc;
|
||||
border: 1px solid rgb(235, 238, 240);
|
||||
padding: 24px;
|
||||
@ -1392,6 +1424,10 @@ Dashboard v5 Layout */
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-main-selection {
|
||||
margin-top: -24px;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------
|
||||
Dashboard v5 Chart */
|
||||
@ -1487,15 +1523,23 @@ Dashboard v5 Metric */
|
||||
align-items: center;
|
||||
font-size: 1.2rem;
|
||||
text-transform: uppercase;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
letter-spacing: .3px;
|
||||
line-height: 1em;
|
||||
margin: 2px 0 0;
|
||||
margin: 0 0 14px;
|
||||
padding: 0;
|
||||
color: var(--midgrey);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.gh-dashboard5-metric.is-large .gh-dashboard5-metric-label {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-metric.is-reverse .gh-dashboard5-metric-label {
|
||||
margin: 2px 0 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-metric.is-center .gh-dashboard5-metric-label {
|
||||
text-align: center;
|
||||
margin-top: 4px;
|
||||
@ -1504,10 +1548,8 @@ Dashboard v5 Metric */
|
||||
.gh-dashboard5-metric-value {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
font-size: 2.4rem;
|
||||
line-height: 4rem;
|
||||
font-weight: 700;
|
||||
color: var(--black);
|
||||
font-size: 2.8rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: -.1px;
|
||||
line-height: 1em;
|
||||
white-space: nowrap;
|
||||
@ -1515,15 +1557,20 @@ Dashboard v5 Metric */
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-metric-value.is-large {
|
||||
font-size: 3.2rem;
|
||||
margin-bottom: 6px;
|
||||
.gh-dashboard5-metric.is-large .gh-dashboard5-metric-value {
|
||||
font-size: 3.4rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-metric.is-center .gh-dashboard5-metric-value {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.gh-dashboard5-metric.is-reverse.is-large .gh-dashboard5-metric-value {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-metric-extra {
|
||||
text-transform: none;
|
||||
font-weight: 500;
|
||||
@ -1546,19 +1593,50 @@ Dashboard v5 List */
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-header {
|
||||
padding: 0 0 8px;
|
||||
display: grid;
|
||||
grid-template-columns: 65% 20% 15%;
|
||||
padding: 0 0 20px;
|
||||
border-bottom: 1px solid var(--whitegrey);
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-title {
|
||||
align-items: center;
|
||||
font-size: 1.2rem;
|
||||
text-transform: uppercase;
|
||||
font-weight: 500;
|
||||
letter-spacing: .3px;
|
||||
line-height: 1em;
|
||||
padding: 0;
|
||||
color: #7c8b9a;
|
||||
white-space: nowrap;
|
||||
padding: 0 24px 0 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 0 8px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-item {
|
||||
padding: 14px 0;
|
||||
border-bottom: 1px solid #efefef;
|
||||
display: grid;
|
||||
grid-template-columns: 65% 20% 15%;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid var(--whitegrey);
|
||||
}
|
||||
|
||||
.gh-dashboard5-activity .gh-dashboard5-list-item {
|
||||
grid-template-columns: 80% 20%;
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-item:nth-child(3) {
|
||||
border-bottom: 0 none;
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-item > span {
|
||||
padding: 0 24px 4px 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-item:last-child {
|
||||
@ -1566,13 +1644,19 @@ Dashboard v5 List */
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-item a {
|
||||
font-weight: 600;
|
||||
font-weight: 500;
|
||||
font-size: 1.5rem;
|
||||
color: var(--black);
|
||||
color: var(--darkgrey);
|
||||
display: inline-block;
|
||||
padding: 3px 64px 0 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-item > span {
|
||||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-item svg {
|
||||
@ -1581,9 +1665,10 @@ Dashboard v5 List */
|
||||
margin: 0 0.75rem 0 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-item a span {
|
||||
.gh-dashboard5-list-item > a > span {
|
||||
color: var(--midgrey);
|
||||
padding: 0 0 0 0.5rem
|
||||
padding: 0 0 0 0.5rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.gh-dashboard5-list-footer {
|
||||
@ -1601,6 +1686,9 @@ Dashboard v5 Section Anchor */
|
||||
|
||||
.gh-dashboard5-anchor .gh-dashboard5-box {
|
||||
align-items: stretch;
|
||||
padding-top: 8px;
|
||||
padding-bottom: 12px;
|
||||
height: 431px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-anchor.is-top .gh-dashboard5-box {
|
||||
@ -1611,12 +1699,8 @@ Dashboard v5 Section Anchor */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: calc(100% + 48px);
|
||||
padding: 4px;
|
||||
margin: 16px -24px -24px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid var(--whitegrey);
|
||||
border-width: 1px 0 0;
|
||||
background: #fafbfc;
|
||||
padding: 0 8px 8px;
|
||||
margin: 0 -24px 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-anchor .gh-dashboard5-title {
|
||||
@ -1633,17 +1717,25 @@ Dashboard v5 Section Anchor */
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
padding: 16px 16px 20px;
|
||||
margin: 2px;
|
||||
padding: 16px 16px 20px 12px;
|
||||
margin: 2px 4px 2px 2px;
|
||||
text-align: left;
|
||||
background: transparent;
|
||||
border-radius: 2px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-anchor .gh-dashboard5-stats-button.is-selected {
|
||||
color: #15171a;
|
||||
background: #fff!important;
|
||||
box-shadow: 0 2px 4px rgb(0 0 0 / 8%);
|
||||
color: var(--black);
|
||||
background: var(--white) !important;
|
||||
box-shadow: 0 0 12px rgb(0 0 0 / 3%);
|
||||
border: 1px solid var(--whitegrey);
|
||||
}
|
||||
|
||||
.gh-dashboard5-anchor .gh-dashboard5-stats.is-solo .gh-dashboard5-stats-button.is-selected {
|
||||
background: transparent;
|
||||
box-shadow: 0 none;
|
||||
border: 0 none;
|
||||
}
|
||||
|
||||
.gh-dashboard5-anchor .gh-dashboard5-stats-highlight {
|
||||
@ -1664,6 +1756,8 @@ Dashboard v5 Section Anchor */
|
||||
|
||||
.gh-dashboard5-anchor .gh-dashboard5-chart {
|
||||
flex-direction: column;
|
||||
margin-left: -16px;
|
||||
margin-right: -16px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-anchor .gh-dashboard5-chart-ticks {
|
||||
@ -1682,8 +1776,8 @@ Dashboard v5 Section Anchor */
|
||||
}
|
||||
|
||||
.gh-dashboard5-anchor .prototype-selection {
|
||||
top: 18px;
|
||||
right: 6px;
|
||||
top: 16px;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
|
||||
@ -1748,50 +1842,51 @@ Dashboard v5 Section Email */
|
||||
}
|
||||
|
||||
.gh-dashboard5-email .gh-dashboard5-insert {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
gap: 0;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.gh-dashboard5-email .gh-dashboard5-insert-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-email .gh-dashboard5-insert-item:nth-child(1) {
|
||||
/* --- Newsletter Subscribers */
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
padding: 4px 16px 16px 0;
|
||||
border: 1px solid var(--whitegrey);
|
||||
border-width: 0 1px 1px 0;
|
||||
/* --- Engaged Over 30 Days */
|
||||
padding: 4px 16px 0 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-email .gh-dashboard5-insert-item:nth-child(2) {
|
||||
/* --- Emails Sent */
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
/* --- Engaged Over 7 Days */
|
||||
padding: 4px 16px 0 16px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split .gh-dashboard5-email .gh-dashboard5-insert {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split .gh-dashboard5-email .gh-dashboard5-insert-item {
|
||||
border-radius: 0;
|
||||
border-width: 0 0 1px;
|
||||
padding: 8px 16px 16px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split .gh-dashboard5-email .gh-dashboard5-insert-item:nth-child(1) {
|
||||
/* --- Engaged Over 30 Days */
|
||||
padding: 4px 16px 16px 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split .gh-dashboard5-email .gh-dashboard5-insert-item:nth-child(2) {
|
||||
/* --- Engaged Over 7 Days */
|
||||
flex: 1;
|
||||
padding: 16px 16px 0 0;
|
||||
border-right: 1px solid var(--whitegrey);
|
||||
}
|
||||
|
||||
.gh-dashboard5-email .gh-dashboard5-insert-item:nth-child(3) {
|
||||
/* --- Open Rate */
|
||||
grid-column: 2;
|
||||
grid-row: 1 / span 2;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
padding: 4px 0 0 24px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-email .gh-dashboard5-chart {
|
||||
margin: 0 0 24px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-email .gh-dashboard5-chart-ticks {
|
||||
padding: 0 16px 0 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1803,7 +1898,7 @@ Dashboard v5 Section Engagement */
|
||||
}
|
||||
|
||||
.gh-dashboard5-engagement .prototype-selection {
|
||||
top: 18px;
|
||||
top: 16px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-engagement .gh-dashboard5-insert {
|
||||
@ -1823,7 +1918,6 @@ Dashboard v5 Section Engagement */
|
||||
.gh-dashboard5-engagement .gh-dashboard5-insert-item:nth-child(1) {
|
||||
/* --- Engaged Over 30 Days */
|
||||
padding: 4px 16px 0 0;
|
||||
border-right: 1px solid var(--whitegrey);
|
||||
}
|
||||
|
||||
.gh-dashboard5-engagement .gh-dashboard5-insert-item:nth-child(2) {
|
||||
@ -1841,13 +1935,12 @@ Dashboard v5 Section Engagement */
|
||||
padding: 8px 16px 16px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.gh-dashboard5-split .gh-dashboard5-engagement .gh-dashboard5-insert-item:nth-child(1) {
|
||||
/* --- Engaged Over 30 Days */
|
||||
padding: 4px 16px 16px 0;
|
||||
border-bottom: 1px solid var(--whitegrey);
|
||||
}
|
||||
|
||||
.gh-dashboard5-split .gh-dashboard5-engagement .gh-dashboard5-insert-item:nth-child(2) {
|
||||
@ -1861,25 +1954,102 @@ Dashboard v5 Section Engagement */
|
||||
Dashboard v5 Section Posts */
|
||||
|
||||
.gh-dashboard5-posts .gh-dashboard5-box {
|
||||
padding: 24px;
|
||||
padding: 28px 24px 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.gh-dashboard5-posts .gh-dashboard5-title {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-posts .gh-dashboard5-list-item {
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-posts .gh-dashboard5-list-item:nth-child(1) {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-posts .gh-dashboard5-list-item:nth-child(4),
|
||||
.gh-dashboard5-posts .gh-dashboard5-list-item:nth-child(5) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.gh-dashboard5-posts .gh-dashboard5-list-item a {
|
||||
width: 80%;
|
||||
height: 57px;
|
||||
overflow: hidden;
|
||||
color: var(--darkgrey);
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------
|
||||
Dashboard v5 Section Activity */
|
||||
|
||||
.gh-dashboard5-activity .gh-dashboard5-box {
|
||||
padding: 24px;
|
||||
padding: 28px 24px 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.gh-dashboard5-activity .gh-dashboard5-title {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.gh-dashboard5-activity .gh-dashboard5-list-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 10px 0;
|
||||
border-bottom: 0 none;
|
||||
}
|
||||
|
||||
.gh-dashboard5-activity .gh-dashboard5-list-item .member-details {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-activity .gh-dashboard5-list-item .member-avatar {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background: #70DEB1;
|
||||
border-radius: 24px;
|
||||
margin: 0 12px 0 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-activity .gh-dashboard5-list-item > span.gh-dashboard-activity-time {
|
||||
font-size: 1.2rem;
|
||||
color: var(--midlightgrey);
|
||||
text-align: right;
|
||||
padding-right: 0;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------
|
||||
Dashboard v5 Section Email Open Rate */
|
||||
|
||||
.gh-dashboard5-rate .gh-dashboard5-chart {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-rate .gh-dashboard5-chart-ticks {
|
||||
padding: 0 16px 0 0;
|
||||
}
|
||||
|
||||
.gh-dashboard5-rate .gh-dashboard5-metric-label {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------
|
||||
Dashboard v5 Section Resource */
|
||||
|
||||
@ -1946,4 +2116,4 @@ Dashboard v5 Section Resource */
|
||||
|
||||
.gh-dashboard5-area-dot.is-selected {
|
||||
background: var(--midgrey);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user