Skip to content

Commit

Permalink
Merge pull request #603 from gitroomhq/feat/repeated-post
Browse files Browse the repository at this point in the history
Add a repeated post
  • Loading branch information
nevo-david authored Feb 11, 2025
2 parents d51e560 + 83c7f75 commit ed93eab
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 24 deletions.
6 changes: 6 additions & 0 deletions apps/frontend/src/components/launches/add.edit.model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import { LoadingComponent } from '@gitroom/frontend/components/layout/loading';
import { DropFiles } from '@gitroom/frontend/components/layout/drop.files';
import { SelectCustomer } from '@gitroom/frontend/components/launches/select.customer';
import { TagsComponent } from './tags.component';
import { RepeatComponent } from '@gitroom/frontend/components/launches/repeat.component';

function countCharacters(text: string, type: string): number {
if (type !== 'x') {
Expand Down Expand Up @@ -140,6 +141,8 @@ export const AddEditModal: FC<{
// are we in edit mode?
const existingData = useExistingData();

const [inter, setInter] = useState(existingData?.posts?.[0]?.intervalInDays);

const [tags, setTags] = useState<any[]>(
// @ts-ignore
existingData?.posts?.[0]?.tags?.map((p: any) => ({
Expand Down Expand Up @@ -394,6 +397,7 @@ export const AddEditModal: FC<{
body: JSON.stringify({
...(postFor ? { order: postFor.id } : {}),
type,
inter,
tags,
shortLink,
date: dateState.utc().format('YYYY-MM-DDTHH:mm:ss'),
Expand All @@ -418,6 +422,7 @@ export const AddEditModal: FC<{
modal.closeAll();
},
[
inter,
postFor,
dateState,
value,
Expand Down Expand Up @@ -566,6 +571,7 @@ export const AddEditModal: FC<{
setSelectedIntegrations([]);
}}
/>
<RepeatComponent repeat={inter} onChange={setInter} />
<DatePicker onChange={setDateState} date={dateState} />
{!selectedIntegrations.length && (
<svg
Expand Down
7 changes: 6 additions & 1 deletion apps/frontend/src/components/launches/calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -420,8 +420,13 @@ export const CalendarColumn: FC<{
);

const editPost = useCallback(
(post: Post & { integration: Integration }, isDuplicate?: boolean) =>
(loadPost: Post & { integration: Integration }, isDuplicate?: boolean) =>
async () => {
const post = {
...loadPost,
// @ts-ignore
publishDate: loadPost.actualDate || loadPost.publishDate,
};
if (user?.orgId === post.submittedForOrganizationId) {
return previewPublication(post);
}
Expand Down
35 changes: 35 additions & 0 deletions apps/frontend/src/components/launches/repeat.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { FC } from 'react';
import { Select } from '@gitroom/react/form/select';

const list = [
{ value: 1, label: 'Every Day' },
{ value: 2, label: 'Every Two Days' },
{ value: 3, label: 'Every Three Days' },
{ value: 4, label: 'Every Four Days' },
{ value: 5, label: 'Every Five Days' },
{ value: 6, label: 'Every Six Days' },
{ value: 7, label: 'Every Week' },
{ value: 14, label: 'Every Two Weeks' },
{ value: 30, label: 'Every Month' },
];

export const RepeatComponent: FC<{ repeat: number|null, onChange: (newVal: number) => void }> = (props) => {
const { repeat } = props;
return (
<Select
disableForm={true}
label=""
hideErrors={true}
name="repeat"
value={repeat ? repeat : undefined}
onChange={(e) => props.onChange(Number(e.target.value))}
>
<option>Repeat Post Every...</option>
{list.map((item) => (
<option key={item.value} value={item.value}>
{item.label}
</option>
))}
</Select>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import { GetPostsDto } from '@gitroom/nestjs-libraries/dtos/posts/get.posts.dto'
import dayjs from 'dayjs';
import isoWeek from 'dayjs/plugin/isoWeek';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import utc from 'dayjs/plugin/utc';
import { v4 as uuidv4 } from 'uuid';
import { CreateTagDto } from '@gitroom/nestjs-libraries/dtos/posts/create.tag.dto';

dayjs.extend(isoWeek);
dayjs.extend(weekOfYear);
dayjs.extend(isSameOrAfter);
dayjs.extend(utc);

@Injectable()
export class PostsRepository {
Expand Down Expand Up @@ -80,7 +84,7 @@ export class PostsRepository {
});
}

getPosts(orgId: string, query: GetPostsDto) {
async getPosts(orgId: string, query: GetPostsDto) {
const dateYear = dayjs().year(query.year);
const date =
query.display === 'day'
Expand Down Expand Up @@ -108,20 +112,35 @@ export class PostsRepository {
.add(2, 'hours')
.toDate();

return this._post.model.post.findMany({
const list = await this._post.model.post.findMany({
where: {
OR: [
AND: [
{
organizationId: orgId,
OR: [
{
organizationId: orgId,
},
{
submittedForOrganizationId: orgId,
},
],
},
{
submittedForOrganizationId: orgId,
OR: [
{
publishDate: {
gte: startDate,
lte: endDate,
},
},
{
intervalInDays: {
not: null,
},
},
],
},
],
publishDate: {
gte: startDate,
lte: endDate,
},
deletedAt: null,
parentPostId: null,
...(query.customer
Expand All @@ -140,6 +159,7 @@ export class PostsRepository {
submittedForOrganizationId: true,
submittedForOrderId: true,
state: true,
intervalInDays: true,
tags: {
select: {
tag: true,
Expand All @@ -155,6 +175,28 @@ export class PostsRepository {
},
},
});

return list.reduce((all, post) => {
if (!post.intervalInDays) {
return [...all, post];
}

const addMorePosts = [];
let startingDate = dayjs.utc(post.publishDate);
while (dayjs.utc(endDate).isSameOrAfter(startingDate)) {
if (dayjs(startingDate).isSameOrAfter(dayjs.utc(post.publishDate))) {
addMorePosts.push({
...post,
publishDate: startingDate.toDate(),
actualDate: post.publishDate,
});
}

startingDate = startingDate.add(post.intervalInDays, 'days');
}

return [...all, ...addMorePosts];
}, [] as any[]);
}

async deletePost(orgId: string, group: string) {
Expand Down Expand Up @@ -272,7 +314,8 @@ export class PostsRepository {
orgId: string,
date: string,
body: PostBody,
tags: { value: string; label: string }[]
tags: { value: string; label: string }[],
inter?: number,
) {
const posts: Post[] = [];
const uuid = uuidv4();
Expand Down Expand Up @@ -303,6 +346,7 @@ export class PostsRepository {
: {}),
content: value.content,
group: uuid,
intervalInDays: inter ? +inter : null,
approvedSubmitForOrder: APPROVED_SUBMIT_FOR_ORDER.NO,
state: state === 'draft' ? ('DRAFT' as const) : ('QUEUE' as const),
image: JSON.stringify(value.image),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class PostsService {
];
}

getPosts(orgId: string, query: GetPostsDto) {
async getPosts(orgId: string, query: GetPostsDto) {
return this._postRepository.getPosts(orgId, query);
}

Expand Down Expand Up @@ -205,6 +205,18 @@ export class PostsService {
return;
}

if (firstPost?.intervalInDays) {
this._workerServiceProducer.emit('post', {
id,
options: {
delay: firstPost.intervalInDays * 86400000,
},
payload: {
id: id,
},
});
}

if (firstPost.submittedForOrderId) {
this._workerServiceProducer.emit('submit', {
payload: {
Expand Down Expand Up @@ -597,7 +609,8 @@ export class PostsService {
? dayjs().format('YYYY-MM-DDTHH:mm:00')
: body.date,
post,
body.tags
body.tags,
body.inter,
);

if (!posts?.length) {
Expand Down Expand Up @@ -633,6 +646,10 @@ export class PostsService {
},
payload: {
id: posts[0].id,
delay:
body.type === 'now'
? 0
: dayjs(posts[0].publishDate).diff(dayjs(), 'millisecond'),
},
});
}
Expand Down Expand Up @@ -666,6 +683,7 @@ export class PostsService {
},
payload: {
id: id,
delay: dayjs(date).diff(dayjs(), 'millisecond'),
},
});
}
Expand Down
2 changes: 2 additions & 0 deletions libraries/nestjs-libraries/src/database/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ model Post {
approvedSubmitForOrder APPROVED_SUBMIT_FOR_ORDER @default(NO)
lastMessageId String?
lastMessage Messages? @relation(fields: [lastMessageId], references: [id])
intervalInDays Int?
payoutProblems PayoutProblems[]
comments Comments[]
tags TagsPosts[]
Expand All @@ -389,6 +390,7 @@ model Post {
@@index([organizationId])
@@index([parentPostId])
@@index([submittedForOrderId])
@@index([intervalInDays])
@@index([approvedSubmitForOrder])
@@index([lastMessageId])
@@index([createdAt])
Expand Down
16 changes: 5 additions & 11 deletions libraries/nestjs-libraries/src/dtos/posts/create.post.dto.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import {
ArrayMinSize,
IsArray,
IsBoolean,
IsDateString,
IsDefined,
IsIn,
IsOptional,
IsString,
MinLength,
ValidateIf,
ValidateNested,
ArrayMinSize, IsArray, IsBoolean, IsDateString, IsDefined, IsIn, IsNumber, IsOptional, IsString, MinLength, ValidateIf, ValidateNested
} from 'class-validator';
import { Type } from 'class-transformer';
import { DevToSettingsDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/dev.to.settings.dto';
Expand Down Expand Up @@ -113,6 +103,10 @@ export class CreatePostDto {
@IsBoolean()
shortLink: boolean;

@IsOptional()
@IsNumber()
inter?: number;

@IsDefined()
@IsDateString()
date: string;
Expand Down

0 comments on commit ed93eab

Please sign in to comment.