diff --git a/CHANGELOG.md b/CHANGELOG.md index dcfc47b..a092034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ Template for next version ### Added +- add start and end page to form create call + ### Changed - notifications / hooks / pages and buttons encode and decode their ids @@ -29,6 +31,9 @@ Template for next version ### Fixed - missing encode / decode for form fields within submissions (https://github.com/ohmyform/ui/commit/30ff2c96bca20c1641d9cbb96c34cce934e1afea#r68602651) +- form field resolvers were missing +- node-gyp update to enable build on osx 12.3 +- creating of new fields ### Security diff --git a/src/dto/form/form.create.input.ts b/src/dto/form/form.create.input.ts index 1152b18..3e6b4a6 100644 --- a/src/dto/form/form.create.input.ts +++ b/src/dto/form/form.create.input.ts @@ -1,4 +1,5 @@ import { Field, InputType } from '@nestjs/graphql' +import { PageInput } from './page.input' @InputType('FormCreateInput') export class FormCreateInput { @@ -19,4 +20,10 @@ export class FormCreateInput { @Field({ nullable: true }) readonly layout: string + + @Field({ nullable: true }) + readonly startPage: PageInput + + @Field({ nullable: true }) + readonly endPage: PageInput } diff --git a/src/dto/form/page.input.ts b/src/dto/form/page.input.ts index 9f63984..2b4256a 100644 --- a/src/dto/form/page.input.ts +++ b/src/dto/form/page.input.ts @@ -18,6 +18,6 @@ export class PageInput { @Field({ nullable: true }) readonly buttonText?: string - @Field(() => [ButtonInput]) + @Field(() => [ButtonInput], { nullable: true }) readonly buttons: ButtonInput[] } diff --git a/src/resolver/form/form.resolver.ts b/src/resolver/form/form.resolver.ts index a3cadfa..76b2786 100644 --- a/src/resolver/form/form.resolver.ts +++ b/src/resolver/form/form.resolver.ts @@ -9,6 +9,7 @@ import { FormNotificationModel } from '../../dto/form/form.notification.model' import { PageModel } from '../../dto/form/page.model' import { UserModel } from '../../dto/user/user.model' import { FormEntity } from '../../entity/form.entity' +import { FormFieldEntity } from '../../entity/form.field.entity' import { PageEntity } from '../../entity/page.entity' import { UserEntity } from '../../entity/user.entity' import { FormService } from '../../service/form/form.service' @@ -37,10 +38,14 @@ export class FormResolver { return form.fields .sort((a,b) => a.idx - b.idx) - .map(field => new FormFieldModel( - this.idService.encode(field.id), - field, - )) + .map(field => { + cache.add(cache.getCacheKey(FormFieldEntity.name, field.id), field) + + return new FormFieldModel( + this.idService.encode(field.id), + field, + ) + }) } @ResolveField(() => [FormHookModel]) diff --git a/src/resolver/form/index.ts b/src/resolver/form/index.ts index 82c01b9..f841292 100644 --- a/src/resolver/form/index.ts +++ b/src/resolver/form/index.ts @@ -1,5 +1,6 @@ import { FormCreateMutation } from './form.create.mutation' import { FormDeleteMutation } from './form.delete.mutation' +import { FormFieldResolver } from './form.field.resolver' import { FormListQuery } from './form.list.query' import { FormQuery } from './form.query' import { FormResolver } from './form.resolver' @@ -11,6 +12,7 @@ import { PageResolver } from './page.resolver' export const formResolvers = [ FormCreateMutation, FormDeleteMutation, + FormFieldResolver, FormQuery, FormResolver, FormListQuery, diff --git a/src/service/form/form.create.service.ts b/src/service/form/form.create.service.ts index 47ad6fa..1c0bcdf 100644 --- a/src/service/form/form.create.service.ts +++ b/src/service/form/form.create.service.ts @@ -3,13 +3,16 @@ import { InjectRepository } from '@nestjs/typeorm' import { Repository } from 'typeorm' import { FormCreateInput } from '../../dto/form/form.create.input' import { FormEntity } from '../../entity/form.entity' +import { PageEntity } from '../../entity/page.entity' import { UserEntity } from '../../entity/user.entity' +import { FormPageCreateService } from './form.page.create.service' @Injectable() export class FormCreateService { constructor( @InjectRepository(FormEntity) - private readonly formRepository: Repository + private readonly formRepository: Repository, + private readonly formPageCreateService: FormPageCreateService, ) { } @@ -23,9 +26,14 @@ export class FormCreateService { form.language = input.language || 'en' form.design.layout = input.layout + + form.endPage = this.formPageCreateService.create(input.endPage) + form.startPage = this.formPageCreateService.create(input.startPage) + form.admin = admin return await this.formRepository.save(form) } + } diff --git a/src/service/form/form.page.create.service.ts b/src/service/form/form.page.create.service.ts new file mode 100644 index 0000000..2787151 --- /dev/null +++ b/src/service/form/form.page.create.service.ts @@ -0,0 +1,44 @@ +import { Injectable } from '@nestjs/common' +import { PageInput } from '../../dto/form/page.input' +import { PageButtonEntity } from '../../entity/page.button.entity' +import { PageEntity } from '../../entity/page.entity' +import { IdService } from '../id.service' + +@Injectable() +export class FormPageCreateService { + constructor( + private readonly idService: IdService, + ) { + } + + public create(input: PageInput): PageEntity { + const page = new PageEntity() + page.show = Boolean(input?.show) + page.buttons = [] + + if (!input) { + return page + } + + page.title = input.title + page.buttonText = input.buttonText + page.paragraph = input.paragraph + + if (input.buttons !== undefined) { + page.buttons = input.buttons.map(buttonInput => { + const button = new PageButtonEntity() + button.page = page + button.url = buttonInput.url + button.action = buttonInput.action + button.text = buttonInput.text + button.color = buttonInput.color + button.bgColor = buttonInput.bgColor + button.activeColor = buttonInput.activeColor + + return button + }) + } + + return page + } +} \ No newline at end of file diff --git a/src/service/form/form.page.update.service.ts b/src/service/form/form.page.update.service.ts new file mode 100644 index 0000000..28446fd --- /dev/null +++ b/src/service/form/form.page.update.service.ts @@ -0,0 +1,73 @@ +import { Injectable } from '@nestjs/common' +import { PageInput } from '../../dto/form/page.input' +import { PageButtonEntity } from '../../entity/page.button.entity' +import { PageEntity } from '../../entity/page.entity' +import { IdService } from '../id.service' + +@Injectable() +export class FormPageUpdateService { + constructor( + private readonly idService: IdService, + ) { + } + + public update(page: PageEntity, input: PageInput): PageEntity { + if (!page) { + page = new PageEntity() + page.show = false + } + + if (input.show !== undefined) { + page.show = input.show + } + + if (input.title !== undefined) { + page.title = input.title + } + + if (input.paragraph !== undefined) { + page.paragraph = input.paragraph + } + + if (input.buttonText !== undefined) { + page.buttonText = input.buttonText + } + + if (input.buttons !== undefined) { + page.buttons = input.buttons.map(buttonInput => { + const entity = this.findByIdInList( + page?.buttons, + buttonInput.id, + new PageButtonEntity() + ) + + entity.page = page + entity.url = buttonInput.url + entity.action = buttonInput.action + entity.text = buttonInput.text + entity.color = buttonInput.color + entity.bgColor = buttonInput.bgColor + entity.activeColor = buttonInput.activeColor + + return entity + }) + } + + return page + } + + + private findByIdInList(list: T[], id: string, fallback: T): T { + if (!list || /^NEW-/.test(id)) { + return fallback + } + + const found = list.find((value) => value.id === this.idService.decode(id)) + + if (found) { + return found + } + + return fallback + } +} \ No newline at end of file diff --git a/src/service/form/form.update.service.ts b/src/service/form/form.update.service.ts index 9e64ff2..dfeb64a 100644 --- a/src/service/form/form.update.service.ts +++ b/src/service/form/form.update.service.ts @@ -11,6 +11,7 @@ import { FormNotificationEntity } from '../../entity/form.notification.entity' import { PageButtonEntity } from '../../entity/page.button.entity' import { PageEntity } from '../../entity/page.entity' import { IdService } from '../id.service' +import { FormPageUpdateService } from './form.page.update.service' @Injectable() export class FormUpdateService { @@ -22,6 +23,7 @@ export class FormUpdateService { @InjectRepository(FormHookEntity) private readonly formHookRepository: Repository, private readonly idService: IdService, + private readonly pageService: FormPageUpdateService, ) { } @@ -261,87 +263,11 @@ export class FormUpdateService { */ if (input.startPage !== undefined) { - if (!form.startPage) { - form.startPage = new PageEntity() - form.startPage.show = false - } - - if (input.startPage.show !== undefined) { - form.startPage.show = input.startPage.show - } - - if (input.startPage.title !== undefined) { - form.startPage.title = input.startPage.title - } - - if (input.startPage.paragraph !== undefined) { - form.startPage.paragraph = input.startPage.paragraph - } - - if (input.startPage.buttonText !== undefined) { - form.startPage.buttonText = input.startPage.buttonText - } - - if (input.startPage.buttons !== undefined) { - form.startPage.buttons = input.startPage.buttons.map(buttonInput => { - const entity = this.findByIdInList( - form.startPage?.buttons, - buttonInput.id, - new PageButtonEntity() - ) - entity.page = form.startPage - entity.url = buttonInput.url - entity.action = buttonInput.action - entity.text = buttonInput.text - entity.color = buttonInput.color - entity.bgColor = buttonInput.bgColor - entity.activeColor = buttonInput.activeColor - - return entity - }) - } + form.startPage = this.pageService.update(form.startPage, input.startPage) } if (input.endPage !== undefined) { - if (!form.endPage) { - form.endPage = new PageEntity() - form.endPage.show = false - } - - if (input.endPage.show !== undefined) { - form.endPage.show = input.endPage.show - } - - if (input.endPage.title !== undefined) { - form.endPage.title = input.endPage.title - } - - if (input.endPage.paragraph !== undefined) { - form.endPage.paragraph = input.endPage.paragraph - } - - if (input.endPage.buttonText !== undefined) { - form.endPage.buttonText = input.endPage.buttonText - } - - if (input.endPage.buttons !== undefined) { - form.endPage.buttons = input.endPage.buttons.map(buttonInput => { - const entity = this.findByIdInList( - form.endPage?.buttons, - buttonInput.id, - new PageButtonEntity() - ) - entity.page = form.endPage - entity.url = buttonInput.url - entity.action = buttonInput.action - entity.text = buttonInput.text - entity.color = buttonInput.color - entity.bgColor = buttonInput.bgColor - entity.activeColor = buttonInput.activeColor - - return entity - }) - } + form.endPage = this.pageService.update(form.endPage, input.endPage) } await this.formRepository.save(form) @@ -350,7 +276,7 @@ export class FormUpdateService { } private findByIdInList(list: T[], id: string, fallback: T): T { - if (!list) { + if (!list || /^NEW-/.test(id)) { return fallback } diff --git a/src/service/form/index.ts b/src/service/form/index.ts index 2617cad..1add17e 100644 --- a/src/service/form/index.ts +++ b/src/service/form/index.ts @@ -1,6 +1,8 @@ import { FormCreateService } from './form.create.service' import { FormDeleteService } from './form.delete.service' import { FormFieldService } from './form.field.service' +import { FormPageCreateService } from './form.page.create.service' +import { FormPageUpdateService } from './form.page.update.service' import { FormService } from './form.service' import { FormStatisticService } from './form.statistic.service' import { FormUpdateService } from './form.update.service' @@ -9,6 +11,8 @@ export const formServices = [ FormCreateService, FormDeleteService, FormFieldService, + FormPageCreateService, + FormPageUpdateService, FormService, FormStatisticService, FormUpdateService,