mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Wired up Analytics export download trigger (#17782)
refs https://github.com/TryGhost/Product/issues/3349 - added a download handler for the analytics download button. - wired up the download api endpoint <!-- Leave the line below if you'd like GitHub Copilot to generate a summary from your commit --> <!-- copilot:summary --> ### <samp>🤖 Generated by Copilot at 46054be</samp> This pull request adds a feature to export post analytics as a csv file from the membership analytics dashboard. It implements a new query hook, a download function, and a response handler in the `apps/admin-x-settings` app, and adds a test case for the feature.
This commit is contained in:
parent
49493abf75
commit
e61b62e6be
4 changed files with 47 additions and 1 deletions
|
@ -16,3 +16,9 @@ export const useBrowsePosts = createQuery<PostsResponseType>({
|
||||||
dataType,
|
dataType,
|
||||||
path: '/posts/'
|
path: '/posts/'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// This endpoints returns a csv file
|
||||||
|
export const usePostsExports = createQuery<string>({
|
||||||
|
dataType,
|
||||||
|
path: '/posts/export/'
|
||||||
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@ import SettingGroupContent from '../../../admin-x-ds/settings/SettingGroupConten
|
||||||
import Toggle from '../../../admin-x-ds/global/form/Toggle';
|
import Toggle from '../../../admin-x-ds/global/form/Toggle';
|
||||||
import useSettingGroup from '../../../hooks/useSettingGroup';
|
import useSettingGroup from '../../../hooks/useSettingGroup';
|
||||||
import {getSettingValues} from '../../../api/settings';
|
import {getSettingValues} from '../../../api/settings';
|
||||||
|
import {usePostsExports} from '../../../api/posts';
|
||||||
|
|
||||||
const Analytics: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
const Analytics: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
||||||
const {
|
const {
|
||||||
|
@ -26,6 +27,27 @@ const Analytics: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
||||||
handleEditingChange(true);
|
handleEditingChange(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const {data: postsData} = usePostsExports({
|
||||||
|
searchParams: {
|
||||||
|
limit: '1000'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const exportPosts = async () => {
|
||||||
|
// it should download posts as csv
|
||||||
|
if (postsData) {
|
||||||
|
const blob = new Blob([postsData], {type: 'text/csv'});
|
||||||
|
const url = window.URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.setAttribute('hidden', '');
|
||||||
|
a.setAttribute('href', url);
|
||||||
|
a.setAttribute('download', 'posts.csv');
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const inputs = (
|
const inputs = (
|
||||||
<SettingGroupContent columns={2}>
|
<SettingGroupContent columns={2}>
|
||||||
<Toggle
|
<Toggle
|
||||||
|
@ -83,7 +105,7 @@ const Analytics: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
||||||
>
|
>
|
||||||
{inputs}
|
{inputs}
|
||||||
<div className='mt-1'>
|
<div className='mt-1'>
|
||||||
<Button color='green' label='Export analytics' link={true} />
|
<Button color='green' label='Export analytics' link={true} onClick={exportPosts} />
|
||||||
</div>
|
</div>
|
||||||
</SettingGroup>
|
</SettingGroup>
|
||||||
);
|
);
|
||||||
|
|
|
@ -72,6 +72,8 @@ export const useFetchApi = () => {
|
||||||
throw new ApiError(response, data);
|
throw new ApiError(response, data);
|
||||||
} else if (response.status === 204) {
|
} else if (response.status === 204) {
|
||||||
return;
|
return;
|
||||||
|
} else if (response.headers.get('content-type')?.includes('text/csv')) {
|
||||||
|
return await response.text();
|
||||||
} else {
|
} else {
|
||||||
return await response.json();
|
return await response.json();
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,4 +38,20 @@ test.describe('Analytics settings', async () => {
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Supports downloading analytics csv export', async ({page}) => {
|
||||||
|
const {lastApiRequests} = await mockApi({page, requests: {
|
||||||
|
...globalDataRequests,
|
||||||
|
postsExport: {method: 'GET', path: '/posts/export/?limit=1000', response: 'csv data'}
|
||||||
|
}});
|
||||||
|
|
||||||
|
await page.goto('/');
|
||||||
|
|
||||||
|
const section = page.getByTestId('analytics');
|
||||||
|
|
||||||
|
await section.getByRole('button', {name: 'Export analytics'}).click();
|
||||||
|
|
||||||
|
const hasDownloadUrl = lastApiRequests.postsExport?.url?.includes('/posts/export/?limit=1000');
|
||||||
|
expect(hasDownloadUrl).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue