mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-24 11:22:19 +03:00
parent
4cc615a5d3
commit
642c7f39cd
@ -27,7 +27,7 @@ const Newsletters: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
||||
updateRoute('newsletters/new');
|
||||
};
|
||||
const [selectedTab, setSelectedTab] = useState('active-newsletters');
|
||||
const {data: {newsletters: apiNewsletters, meta, isEnd} = {}, fetchNextPage} = useBrowseNewsletters();
|
||||
const {data: {newsletters: apiNewsletters, meta, isEnd} = {}, isLoading, fetchNextPage} = useBrowseNewsletters();
|
||||
const {mutateAsync: editNewsletter} = useEditNewsletter();
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
@ -138,12 +138,12 @@ const Newsletters: React.FC<{ keywords: string[] }> = ({keywords}) => {
|
||||
{
|
||||
id: 'active-newsletters',
|
||||
title: 'Active',
|
||||
contents: (<NewslettersList newsletters={sortedActiveNewsletters} isSortable onSort={onSort} />)
|
||||
contents: (<NewslettersList isLoading={isLoading} newsletters={sortedActiveNewsletters} isSortable onSort={onSort} />)
|
||||
},
|
||||
{
|
||||
id: 'archived-newsletters',
|
||||
title: 'Archived',
|
||||
contents: (<NewslettersList newsletters={archivedNewsletters} />)
|
||||
contents: (<NewslettersList isLoading={isLoading} newsletters={archivedNewsletters} />)
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -3,6 +3,7 @@ import React, {useEffect} from 'react';
|
||||
import {Form, LimitModal, Modal, TextArea, TextField, Toggle, showToast} from '@tryghost/admin-x-design-system';
|
||||
import {HostLimitError, useLimiter} from '../../../../hooks/useLimiter';
|
||||
import {RoutingModalProps, useRouting} from '@tryghost/admin-x-framework/routing';
|
||||
import {numberWithCommas} from '../../../../utils/helpers';
|
||||
import {toast} from 'react-hot-toast';
|
||||
import {useAddNewsletter} from '@tryghost/admin-x-framework/api/newsletters';
|
||||
import {useBrowseMembers} from '@tryghost/admin-x-framework/api/members';
|
||||
@ -18,7 +19,7 @@ const AddNewsletterModal: React.FC<RoutingModalProps> = () => {
|
||||
});
|
||||
|
||||
const {mutateAsync: addNewsletter} = useAddNewsletter();
|
||||
const {formState, updateForm, handleSave, errors, clearError} = useForm({
|
||||
const {formState, updateForm, saveState, handleSave, errors, clearError} = useForm({
|
||||
initialState: {
|
||||
name: '',
|
||||
description: '',
|
||||
@ -62,12 +63,16 @@ const AddNewsletterModal: React.FC<RoutingModalProps> = () => {
|
||||
});
|
||||
}, [limiter, modal, updateRoute]);
|
||||
|
||||
const subscriberCount = members?.meta?.pagination.total;
|
||||
|
||||
return <Modal
|
||||
afterClose={() => {
|
||||
updateRoute('newsletters');
|
||||
}}
|
||||
backDropClick={false}
|
||||
okColor='black'
|
||||
okLabel='Create'
|
||||
okLoading={saveState === 'saving'}
|
||||
size='sm'
|
||||
testId='add-newsletter-modal'
|
||||
title='Create newsletter'
|
||||
@ -106,7 +111,7 @@ const AddNewsletterModal: React.FC<RoutingModalProps> = () => {
|
||||
checked={formState.optInExistingSubscribers}
|
||||
direction='rtl'
|
||||
hint={formState.optInExistingSubscribers ?
|
||||
`This newsletter will be available to all members. Your ${members?.meta?.pagination.total} existing subscriber${members?.meta?.pagination.total === 1 ? '' : 's'} will also be opted-in to receive it.` :
|
||||
`This newsletter will be available to all members. Your ${subscriberCount === undefined ? '' : numberWithCommas(subscriberCount)} existing subscriber${members?.meta?.pagination.total === 1 ? '' : 's'} will also be opted-in to receive it.` :
|
||||
'The newsletter will be available to all new members. Existing members won’t be subscribed, but may visit their account area to opt-in to future emails.'
|
||||
}
|
||||
label='Opt-in existing subscribers'
|
||||
|
@ -6,6 +6,7 @@ import {useRouting} from '@tryghost/admin-x-framework/routing';
|
||||
|
||||
interface NewslettersListProps {
|
||||
newsletters: Newsletter[];
|
||||
isLoading: boolean;
|
||||
isSortable?: boolean;
|
||||
onSort?: (activeId: string, overId?: string) => void;
|
||||
}
|
||||
@ -78,8 +79,10 @@ const NewsletterItem: React.FC<{newsletter: Newsletter}> = ({newsletter}) => {
|
||||
);
|
||||
};
|
||||
|
||||
const NewslettersList: React.FC<NewslettersListProps> = ({newsletters, isSortable, onSort}) => {
|
||||
if (newsletters.length && isSortable) {
|
||||
const NewslettersList: React.FC<NewslettersListProps> = ({newsletters, isLoading, isSortable, onSort}) => {
|
||||
if (isLoading) {
|
||||
return <Table isLoading />;
|
||||
} else if (newsletters.length && isSortable) {
|
||||
return <SortableList
|
||||
container={props => <NewsletterItemContainer {...props} />}
|
||||
items={newsletters}
|
||||
|
@ -159,8 +159,7 @@ class NewslettersService {
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Load relations correctly
|
||||
newsletter = await this.NewsletterModel.findOne({id: newsletter.id}, {...options, require: true});
|
||||
let optedInMemberCount = undefined;
|
||||
|
||||
// subscribe existing members if opt_in_existing=true
|
||||
if (options.opt_in_existing) {
|
||||
@ -169,8 +168,7 @@ class NewslettersService {
|
||||
// subscribe members that have an existing subscription to an active newsletter
|
||||
const memberIds = await this.MemberModel.fetchAllSubscribed(_.pick(options, 'transacting'));
|
||||
|
||||
newsletter.meta = newsletter.meta || {};
|
||||
newsletter.meta.opted_in_member_count = memberIds.length;
|
||||
optedInMemberCount = memberIds.length;
|
||||
|
||||
if (memberIds.length) {
|
||||
debug(`Found ${memberIds.length} members to subscribe`);
|
||||
@ -179,6 +177,14 @@ class NewslettersService {
|
||||
}
|
||||
}
|
||||
|
||||
// Load relations correctly
|
||||
newsletter = await this.NewsletterModel.findOne({id: newsletter.id}, {...options, require: true});
|
||||
|
||||
if (optedInMemberCount !== undefined) {
|
||||
newsletter.meta = newsletter.meta || {};
|
||||
newsletter.meta.opted_in_member_count = optedInMemberCount;
|
||||
}
|
||||
|
||||
// send any verification emails and respond with the appropriate meta added
|
||||
return this.respondWithEmailVerification(newsletter, emailsToVerify);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user