mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Added conversions count and separate analytics page (#15637)
fixes https://github.com/TryGhost/Team/issues/2084 - When audience feedback is enabled, we use a single 'conversions' count instead of having separate ones for signups and paid conversions. - The analytics component is separated so we can change it without breaking the existing page.
This commit is contained in:
parent
b6d2d97af2
commit
22fe1c01de
8 changed files with 403 additions and 49 deletions
|
@ -76,19 +76,10 @@
|
|||
{{#if this.post.showAttributionAnalytics }}
|
||||
<div class="gh-post-analytics-item">
|
||||
<LinkTo @route="members" @query={{hash filterParam=(concat "signup:[" this.post.id "]") }}>
|
||||
<h3>{{format-number this.post.count.signups}}</h3>
|
||||
<p>{{gh-pluralize this.post.count.signups "signup" without-count=true}}</p>
|
||||
<h3>{{format-number this.post.count.conversions}}</h3>
|
||||
<p>{{gh-pluralize this.post.count.conversions "conversions" without-count=true}}</p>
|
||||
</LinkTo>
|
||||
</div>
|
||||
|
||||
{{#if this.post.showPaidAttributionAnalytics }}
|
||||
<div class="gh-post-analytics-item">
|
||||
<LinkTo @route="members" @query={{hash filterParam=(concat "conversion:[" this.post.id "]") }}>
|
||||
<h3>{{format-number this.post.count.paid_conversions}}</h3>
|
||||
<p><span class="hide-when-small">Paid </span>{{gh-pluralize this.post.count.paid_conversions "conversion" without-count=true}}</p>
|
||||
</LinkTo>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if this.post.showAudienceFeedback }}
|
||||
|
|
157
ghost/admin/app/components/posts/old-analytics.hbs
Normal file
157
ghost/admin/app/components/posts/old-analytics.hbs
Normal file
|
@ -0,0 +1,157 @@
|
|||
<section class="gh-canvas" {{did-insert this.loadData}}>
|
||||
|
||||
<GhCanvasHeader class="gh-canvas-header gh-post-analytics-header">
|
||||
<div class="flex flex-column flex-grow-1">
|
||||
<div class="gh-canvas-breadcrumb">
|
||||
<LinkTo @route="posts">
|
||||
Posts
|
||||
</LinkTo>
|
||||
{{svg-jar "arrow-right-small"}}Analytics
|
||||
</div>
|
||||
<h2 class="gh-canvas-title gh-post-title">
|
||||
{{this.post.title}}
|
||||
</h2>
|
||||
<div class="gh-post-analytics-meta">
|
||||
<div class="gh-post-analytics-meta-text">
|
||||
{{#if this.post.hasBeenEmailed }}
|
||||
{{#if this.post.emailOnly}}
|
||||
Sent
|
||||
{{else}}
|
||||
Published and sent
|
||||
{{/if}}
|
||||
{{else}}
|
||||
Published
|
||||
{{#if @post.didEmailFail}}
|
||||
but failed to send
|
||||
{{else}}
|
||||
on your site
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#let (moment-site-tz this.post.publishedAtUTC) as |publishedAt|}}
|
||||
on
|
||||
{{moment-format publishedAt "D MMM YYYY"}}
|
||||
at
|
||||
{{moment-format publishedAt "HH:mm"}}
|
||||
{{/let}}
|
||||
</div>
|
||||
<LinkTo @route="editor.edit" @models={{array this.post.displayName this.post.id}} class="gh-post-list-cta edit" title="">
|
||||
{{svg-jar "pen" title=""}}<span>Edit post</span>
|
||||
</LinkTo>
|
||||
</div>
|
||||
</div>
|
||||
</GhCanvasHeader>
|
||||
|
||||
<h4 class="gh-main-section-header small bn">
|
||||
Engagement
|
||||
</h4>
|
||||
<div class="gh-post-analytics-box">
|
||||
{{#if this.post.hasBeenEmailed}}
|
||||
<div class="gh-post-analytics-item">
|
||||
<LinkTo @route="members" @query={{hash filterParam=(concat "emails.post_id:[" this.post.id "]") }}>
|
||||
<h3>{{format-number this.post.email.emailCount}}</h3>
|
||||
<p>Sent</p>
|
||||
</LinkTo>
|
||||
</div>
|
||||
|
||||
{{#if this.post.showEmailOpenAnalytics }}
|
||||
<div class="gh-post-analytics-item">
|
||||
<LinkTo @route="members" @query={{hash filterParam=(concat "opened_emails.post_id:[" this.post.id "]") }}>
|
||||
<h3>{{format-number this.post.email.openedCount}}</h3>
|
||||
<p>Opened — <strong>{{this.post.email.openRate}}%</strong></p>
|
||||
</LinkTo>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.post.showEmailClickAnalytics }}
|
||||
<div class="gh-post-analytics-item">
|
||||
<LinkTo @route="members" @query={{hash filterParam=(concat "clicked_links.post_id:[" this.post.id "]") }}>
|
||||
<h3>{{format-number this.post.count.clicks}}</h3>
|
||||
<p>Clicked — <strong>{{this.post.clickRate}}%</strong></p>
|
||||
</LinkTo>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if this.post.showAttributionAnalytics }}
|
||||
<div class="gh-post-analytics-item">
|
||||
<LinkTo @route="members" @query={{hash filterParam=(concat "signup:[" this.post.id "]") }}>
|
||||
<h3>{{format-number this.post.count.signups}}</h3>
|
||||
<p>{{gh-pluralize this.post.count.signups "signup" without-count=true}}</p>
|
||||
</LinkTo>
|
||||
</div>
|
||||
|
||||
{{#if this.post.showPaidAttributionAnalytics }}
|
||||
<div class="gh-post-analytics-item">
|
||||
<LinkTo @route="members" @query={{hash filterParam=(concat "conversion:[" this.post.id "]") }}>
|
||||
<h3>{{format-number this.post.count.paid_conversions}}</h3>
|
||||
<p><span class="hide-when-small">Paid </span>{{gh-pluralize this.post.count.paid_conversions "conversion" without-count=true}}</p>
|
||||
</LinkTo>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if this.isLoaded }}
|
||||
{{#if this.showLinks }}
|
||||
{{#if (is-empty this.links) }}
|
||||
{{!-- Empty state --}}
|
||||
{{else}}
|
||||
<Posts::LinksTable @links={{this.links}} @updateLink={{this.updateLink}} />
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showSources }}
|
||||
{{#if (is-empty this.sources) }}
|
||||
{{!-- Empty state --}}
|
||||
{{else}}
|
||||
<h4 class="gh-main-section-header small bn">
|
||||
Growth from this post
|
||||
</h4>
|
||||
<div class="gh-post-analytics-box column">
|
||||
<div class="gh-attribution-box">
|
||||
<div class="gh-attribution-table-column">
|
||||
<MemberAttribution::SourceAttributionTable
|
||||
@sources={{this.sources}}
|
||||
@sortColumn={{this.sortColumn}}
|
||||
@setSortColumn={{this.setSortColumn}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
<h4 class="gh-main-section-header small bn">
|
||||
Get started with analytics
|
||||
</h4>
|
||||
<div class="gh-post-analytics-box resources">
|
||||
<a href="https://ghost.org/help/post-analytics/" target="_blank" class="gh-post-analytics-resource" rel="noopener noreferrer">
|
||||
<div class="thumbnail" style="background-image: url(assets/img/marketing/analytics-1.jpg);"></div>
|
||||
<div class="flex flex-column justify-between">
|
||||
<div>
|
||||
<h3>Understanding analytics in Ghost</h3>
|
||||
<p>Find out how to review the performance of your content and get the most out of post analytics in Ghost.</p>
|
||||
</div>
|
||||
<div class="gh-btn gh-btn-link">Read more →</div>
|
||||
</div>
|
||||
</a>
|
||||
<a href="https://ghost.org/resources/content-distribution/" target="_blank" class="gh-post-analytics-resource" rel="noopener noreferrer">
|
||||
<div class="thumbnail" style="background-image: url(assets/img/marketing/analytics-2.jpg);"></div>
|
||||
<div class="flex flex-column justify-between">
|
||||
<div>
|
||||
<h3>How to get your content seen online</h3>
|
||||
<p>Use these content distribution tactics to get more people to discover your work and increase engagement.</p>
|
||||
</div>
|
||||
<div class="gh-btn gh-btn-link">Read more →</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="gh-post-analytics-loading">
|
||||
<div class="gh-loading-spinner-outer">
|
||||
<div class="gh-loading-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
196
ghost/admin/app/components/posts/old-analytics.js
Normal file
196
ghost/admin/app/components/posts/old-analytics.js
Normal file
|
@ -0,0 +1,196 @@
|
|||
import Component from '@glimmer/component';
|
||||
import {action} from '@ember/object';
|
||||
import {inject as service} from '@ember/service';
|
||||
import {task} from 'ember-concurrency';
|
||||
import {tracked} from '@glimmer/tracking';
|
||||
|
||||
/**
|
||||
* @typedef {import('../../services/dashboard-stats').SourceAttributionCount} SourceAttributionCount
|
||||
*/
|
||||
|
||||
const DISPLAY_OPTIONS = [{
|
||||
name: 'Free signups',
|
||||
value: 'signups'
|
||||
}, {
|
||||
name: 'Paid conversions',
|
||||
value: 'paid'
|
||||
}];
|
||||
|
||||
export default class Analytics extends Component {
|
||||
@service ajax;
|
||||
@service ghostPaths;
|
||||
@service settings;
|
||||
@service membersUtils;
|
||||
@service utils;
|
||||
@service feature;
|
||||
|
||||
@tracked sources = null;
|
||||
@tracked links = null;
|
||||
@tracked sortColumn = 'signups';
|
||||
displayOptions = DISPLAY_OPTIONS;
|
||||
|
||||
get post() {
|
||||
return this.args.post;
|
||||
}
|
||||
|
||||
get allowedDisplayOptions() {
|
||||
if (!this.hasPaidConversionData) {
|
||||
return this.displayOptions.filter(d => d.value === 'signups');
|
||||
}
|
||||
|
||||
if (!this.hasFreeSignups) {
|
||||
return this.displayOptions.filter(d => d.value === 'paid');
|
||||
}
|
||||
|
||||
return this.displayOptions;
|
||||
}
|
||||
|
||||
get isDropdownDisabled() {
|
||||
if (!this.hasPaidConversionData || !this.hasFreeSignups) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
get selectedDisplayOption() {
|
||||
if (!this.hasPaidConversionData) {
|
||||
return this.displayOptions.find(d => d.value === 'signups');
|
||||
}
|
||||
|
||||
if (!this.hasFreeSignups) {
|
||||
return this.displayOptions.find(d => d.value === 'paid');
|
||||
}
|
||||
|
||||
return this.displayOptions.find(d => d.value === this.sortColumn) ?? this.displayOptions[0];
|
||||
}
|
||||
|
||||
get selectedSortColumn() {
|
||||
if (!this.hasPaidConversionData) {
|
||||
return 'signups';
|
||||
}
|
||||
|
||||
if (!this.hasFreeSignups) {
|
||||
return 'paid';
|
||||
}
|
||||
return this.sortColumn;
|
||||
}
|
||||
|
||||
get hasPaidConversionData() {
|
||||
return this.sources.some(sourceData => sourceData.paidConversions > 0);
|
||||
}
|
||||
|
||||
get hasFreeSignups() {
|
||||
return this.sources.some(sourceData => sourceData.signups > 0);
|
||||
}
|
||||
|
||||
@action
|
||||
onDisplayChange(selected) {
|
||||
this.sortColumn = selected.value;
|
||||
}
|
||||
|
||||
@action
|
||||
setSortColumn(column) {
|
||||
this.sortColumn = column;
|
||||
}
|
||||
|
||||
@action
|
||||
updateLink(linkId, linkTo) {
|
||||
this.links = this.links?.map((link) => {
|
||||
if (link.link.link_id === linkId) {
|
||||
return {
|
||||
...link,
|
||||
link: {
|
||||
...link.link,
|
||||
to: this.utils.cleanTrackedUrl(linkTo, false),
|
||||
title: this.utils.cleanTrackedUrl(linkTo, true)
|
||||
}
|
||||
};
|
||||
}
|
||||
return link;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
loadData() {
|
||||
if (this.showSources) {
|
||||
this.fetchReferrersStats();
|
||||
} else {
|
||||
this.sources = [];
|
||||
}
|
||||
|
||||
if (this.showLinks) {
|
||||
this.fetchLinks();
|
||||
} else {
|
||||
this.links = [];
|
||||
}
|
||||
}
|
||||
|
||||
async fetchReferrersStats() {
|
||||
if (this._fetchReferrersStats.isRunning) {
|
||||
return this._fetchReferrersStats.last;
|
||||
}
|
||||
return this._fetchReferrersStats.perform();
|
||||
}
|
||||
|
||||
async fetchLinks() {
|
||||
if (this._fetchLinks.isRunning) {
|
||||
return this._fetchLinks.last;
|
||||
}
|
||||
return this._fetchLinks.perform();
|
||||
}
|
||||
|
||||
@task
|
||||
*_fetchReferrersStats() {
|
||||
let statsUrl = this.ghostPaths.url.api(`stats/referrers/posts/${this.post.id}`);
|
||||
let result = yield this.ajax.request(statsUrl);
|
||||
this.sources = result.stats.map((stat) => {
|
||||
return {
|
||||
source: stat.source ?? 'Direct',
|
||||
signups: stat.signups,
|
||||
paidConversions: stat.paid_conversions
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@task
|
||||
*_fetchLinks() {
|
||||
const filter = `post_id:${this.post.id}`;
|
||||
let statsUrl = this.ghostPaths.url.api(`links/`) + `?filter=${encodeURIComponent(filter)}`;
|
||||
let result = yield this.ajax.request(statsUrl);
|
||||
const links = result.links.map((link) => {
|
||||
return {
|
||||
...link,
|
||||
link: {
|
||||
...link.link,
|
||||
to: this.utils.cleanTrackedUrl(link.link.to, false),
|
||||
title: this.utils.cleanTrackedUrl(link.link.to, true)
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Remove duplicates by title ad merge
|
||||
const linksByTitle = links.reduce((acc, link) => {
|
||||
if (!acc[link.link.title]) {
|
||||
acc[link.link.title] = link;
|
||||
} else {
|
||||
acc[link.link.title].clicks += link.clicks;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
this.links = Object.values(linksByTitle);
|
||||
}
|
||||
|
||||
get showLinks() {
|
||||
return this.post.showEmailClickAnalytics;
|
||||
}
|
||||
|
||||
get showSources() {
|
||||
return this.feature.get('sourceAttribution') && this.post.showAttributionAnalytics;
|
||||
}
|
||||
|
||||
get isLoaded() {
|
||||
return this.links !== null && this.souces !== null;
|
||||
}
|
||||
}
|
|
@ -1 +1,5 @@
|
|||
<Posts::Analytics @post={{this.post}} />
|
||||
{{#if (feature 'audienceFeedback') }}
|
||||
<Posts::Analytics @post={{this.post}} />
|
||||
{{else}}
|
||||
<Posts::OldAnalytics @post={{this.post}} />
|
||||
{{/if}}
|
||||
|
|
|
@ -26,7 +26,7 @@ function defaultRelations(frame) {
|
|||
}
|
||||
|
||||
if (labs.isSet('audienceFeedback')) {
|
||||
frame.options.withRelated = ['tags', 'authors', 'authors.roles', 'email', 'tiers', 'newsletter', 'count.signups', 'count.paid_conversions', 'count.clicks', 'count.sentiment', 'count.positive_feedback'];
|
||||
frame.options.withRelated = ['tags', 'authors', 'authors.roles', 'email', 'tiers', 'newsletter', 'count.conversions', 'count.clicks', 'count.sentiment', 'count.positive_feedback'];
|
||||
} else {
|
||||
frame.options.withRelated = ['tags', 'authors', 'authors.roles', 'email', 'tiers', 'newsletter', 'count.signups', 'count.paid_conversions', 'count.clicks'];
|
||||
}
|
||||
|
|
|
@ -1346,6 +1346,26 @@ Post = ghostBookshelf.Model.extend({
|
|||
.as('count__paid_conversions');
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Combination of sigups and paid conversions, but unique per member
|
||||
*/
|
||||
conversions(modelOrCollection) {
|
||||
modelOrCollection.query('columns', 'posts.*', (qb) => {
|
||||
qb.count('*')
|
||||
.from('k')
|
||||
.with('k', (q) => {
|
||||
q.select('member_id')
|
||||
.from('members_subscription_created_events')
|
||||
.whereRaw('posts.id = members_subscription_created_events.attribution_id')
|
||||
.union(function () {
|
||||
this.select('member_id')
|
||||
.from('members_created_events')
|
||||
.whereRaw('posts.id = members_created_events.attribution_id');
|
||||
});
|
||||
})
|
||||
.as('count__conversions');
|
||||
});
|
||||
},
|
||||
clicks(modelOrCollection) {
|
||||
modelOrCollection.query('columns', 'posts.*', (qb) => {
|
||||
qb.countDistinct('members_click_events.member_id')
|
||||
|
|
|
@ -21,10 +21,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -71,10 +70,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -123,7 +121,7 @@ exports[`Posts API Can browse 2: [headers] 1`] = `
|
|||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "10226",
|
||||
"content-length": "10192",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
|
@ -152,10 +150,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -206,10 +203,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -280,7 +276,7 @@ exports[`Posts API Can browse with formats 2: [headers] 1`] = `
|
|||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "13092",
|
||||
"content-length": "13058",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
|
@ -299,10 +295,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -352,7 +347,7 @@ exports[`Posts API Create Can create a post with lexical 2: [headers] 1`] = `
|
|||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "3909",
|
||||
"content-length": "3892",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/posts\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
|
@ -372,10 +367,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -425,7 +419,7 @@ exports[`Posts API Create Can create a post with mobiledoc 2: [headers] 1`] = `
|
|||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "3725",
|
||||
"content-length": "3708",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/posts\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
|
@ -546,10 +540,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -599,7 +592,7 @@ exports[`Posts API Update Can update a post with lexical 2: [headers] 1`] = `
|
|||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "3860",
|
||||
"content-length": "3843",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/posts\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
|
@ -619,10 +612,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -672,7 +664,7 @@ exports[`Posts API Update Can update a post with lexical 4: [headers] 1`] = `
|
|||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "3857",
|
||||
"content-length": "3840",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
|
@ -692,10 +684,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -745,7 +736,7 @@ exports[`Posts API Update Can update a post with mobiledoc 2: [headers] 1`] = `
|
|||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "3670",
|
||||
"content-length": "3653",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/posts\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
|
@ -765,10 +756,9 @@ Object {
|
|||
"comment_id": Any<String>,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -818,7 +808,7 @@ exports[`Posts API Update Can update a post with mobiledoc 4: [headers] 1`] = `
|
|||
Object {
|
||||
"access-control-allow-origin": "http://127.0.0.1:2369",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "3667",
|
||||
"content-length": "3650",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Version, Origin, Accept-Encoding",
|
||||
|
|
|
@ -283,10 +283,9 @@ Object {
|
|||
"comment_id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -521,10 +520,9 @@ Object {
|
|||
"comment_id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -737,10 +735,9 @@ Object {
|
|||
"comment_id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
@ -1019,10 +1016,9 @@ Object {
|
|||
"comment_id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"count": Object {
|
||||
"clicks": 0,
|
||||
"paid_conversions": 0,
|
||||
"conversions": 0,
|
||||
"positive_feedback": 0,
|
||||
"sentiment": 0,
|
||||
"signups": 0,
|
||||
},
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"custom_excerpt": null,
|
||||
|
|
Loading…
Add table
Reference in a new issue