Skip to content

Commit

Permalink
#185, #186, #188, #190: Add and validate performance/submission on se…
Browse files Browse the repository at this point in the history
…rverside
  • Loading branch information
Espen Norderud committed Oct 9, 2023
1 parent dac26c3 commit 17206d0
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Author = {
}

export type NewPerformance = {
date: Date | null;
date?: Date | null;
dateAndTime: string | undefined;
location: string;
submission: {
Expand Down
1 change: 1 addition & 0 deletions src/components/conference/NewConference/submit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {IToastContextProps} from "../../toast/toast-context";

function getSubmitData(slug?: string): ISubmitData {
const descr = get(description);

const submitData: ISubmitData = {
title: get(name),
url: get(url),
Expand Down
124 changes: 90 additions & 34 deletions src/lib/server/sanityClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import sanityClient from '@sanity/client';
import type { SanityClient, SanityDocument, SanityImageAssetDocument } from '@sanity/client';
import type { Submission } from '../types/submission';
import type { Author } from '../types/author';
import type { ConferenceType } from '../types/conference';
// @ts-ignore
Expand All @@ -11,6 +10,7 @@ import { makeid } from '../../utils/conference-utils';
import type {IConference} from "../../model/conference";
import {featureIsToggledOn} from "../../featureFlagging/common";
import {findUsers} from "$lib/server/cvpartnerClient";
import type {IDescription} from "../../model/event";

const client: SanityClient = sanityClient({
projectId: public_env?.PUBLIC_SANITY_PROJECTID ?? 'mhv8s2ia',
Expand All @@ -22,6 +22,8 @@ const client: SanityClient = sanityClient({

export const SANITY_CONFERENCE_TYPE = 'conference';
export const SANITY_AUTHOR_TYPE = 'author';
export const SANITY_REFERENCE_TYPE = 'reference';
export const SANITY_SUBMISSION_TYPE = 'submission';


// If a slug already exists, recursively tries to add and increase an index.
Expand Down Expand Up @@ -53,7 +55,7 @@ async function generateSlug(string: string): Promise<string> {
return await ensureUniqueSlug(slug);
}

export async function createSubmission(submission: Submission, authors: Array<Author>) {
export async function createSubmission(submission: ISubmission, authors: Array<Author>) {
const authorReference = authors.map((a) => {
return {
_type: 'reference',
Expand Down Expand Up @@ -181,9 +183,10 @@ async function addAuthor(author: BaseAuthor): Promise<string> {
}

if (!foundAuthors || foundAuthors.length === 0) {
console.log("Submitted author data accepted: FOUND MATCHING USER IN CVPARTNER BUT NO MATCHING AUTHOR IN SANITY.\nCREATING AUTHOR:" + JSON.stringify(targetAuthor));

const insertedAuthor = await createAuthor(targetAuthor as Author);
return insertedAuthor._id;
const createdAuthor = await createAuthor(targetAuthor as Author);
return createdAuthor._id;

} else if (foundAuthors.length === 1) {
const foundAuthor = foundAuthors[0];
Expand All @@ -200,37 +203,99 @@ async function addAuthor(author: BaseAuthor): Promise<string> {
}
}

interface ISubmission {
title: string,
submissionType: string,
description: IDescription[],
duration: number,
authors: {
name: string,
email: string
}[]
}

async function addPerformances(performances?: {
dateAndTime: string,
location: string,
submission: {
title:string,
submissionType:string,
description:string,
duration:number,
authors:{
name:string,
email:string
}[]
function validateSubmission(submission?: ISubmission) {
if (!submission || !Object.keys(submission).length) {
throw Error("Missing submission data");
}
}[]){

performances?.forEach(async performance => {
const addedAuthorIds = await Promise.all(
(performance?.submission?.authors || []).map(addAuthor)
);
["title", "submissionType", "description"].forEach(key => {
// @ts-ignore
if (!(submission[key] && (submission[key] + "").trim())) {
throw Error("Missing submission " + key);
}
})
if (!(submission.duration > 0)) {
throw Error("Missing or invalid submission duration");
}
if (!submission.authors || !submission.authors.length) {
throw Error("Missing submission authors");
}
submission.authors.forEach(author => {
if (!author.name && !author.email) {
throw Error("Missing submission author name and email (one is needed)");
}
});
}

async function addSubmission(submission?: ISubmission) {
validateSubmission(submission);

const slug = await generateSlug(submission?.title as string);

const addedAuthorIds = await Promise.all(
(submission?.authors || []).map(addAuthor)
);

const submissionDoc = {
_type: SANITY_SUBMISSION_TYPE,
slug: { _type: 'slug', current: slug },
title: submission?.title,
submissionType: submission?.submissionType,
description: submission?.description,
duration: submission?.duration,
authors: addedAuthorIds.map(id => ({
_key: makeid(12),
_ref: id,
_type: SANITY_REFERENCE_TYPE
}))
};

const insertedConference: SanityDocument<any> = await client.create(submissionDoc);

return insertedConference._id;
}


async function addPerformance(performance?: {
dateAndTime: string,
location: string,
submission: ISubmission
}){


const submissionId = await addSubmission(performance?.submission);

const performanceDoc = {
dateAndTime: performance?.dateAndTime,
location: performance?.location,
submission: {
_ref: submissionId,
_type: SANITY_REFERENCE_TYPE
}
};
return performanceDoc;
}


export async function createConference(
conference: ConferenceType
): Promise<string> {
const slugCurrent = conference.slug ?? (await generateSlug(conference.title + getSlugYearFromDateString(conference.startDate)));
const imageAsset = conference.image ? await uploadImageFromDataUrl(conference.image) : undefined;

addPerformances(conference.performances);
const performanceDocs = await Promise.all(
(conference.performances || []).map(addPerformance)
)

let conferenceDoc = {
_type: SANITY_CONFERENCE_TYPE,
Expand All @@ -243,7 +308,7 @@ export async function createConference(
description: conference.description,
url: conference.url,
categoryTag: conference.categoryTag ?? [],
performances: conference.performances ?? [],
performances: performanceDocs ?? [],
image: imageAsset ? {
_type: 'image',
asset: {
Expand All @@ -254,18 +319,9 @@ export async function createConference(
};


/* const insertedConference: SanityDocument<any> = await client.create(conferenceDoc);
const insertedConference: SanityDocument<any> = await client.create(conferenceDoc);

return insertedConference.slug.current;
console.log(
'Created external conference:',
'\n _id:', insertedConference._id,
'\n title:', insertedConference.title,
'\n slug.current:', insertedConference.slug.current
); */

return "Nope."
}

async function uploadImageFromDataUrl(dataUrl: string): Promise<SanityImageAssetDocument | undefined> {
Expand Down
24 changes: 22 additions & 2 deletions src/lib/types/conference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@ export const Conference = z.object({
// _type: 'conference'
slug: z.string().optional(),
title: z.string().trim().min(1, {message: "Missing or invalid title"}),
description: z.string().trim().optional(),
description: z.array(z.object({
_key: z.string(),
_type: z.string(),
markDefs: z.array(z.any()),
children: z.array(z.object({
_key: z.string(),
_type: z.string(),
marks: z.array(z.any()),
text: z.string().trim()
}))
})),
startDate: z.string().trim().regex(yyyymmdd, {message: "Start date must be on the format YYYY-MM-DD"}).datetime( {message: "Missing or invalid start date"}),
endDate: z.string().trim().regex(yyyymmdd, {message: "End date must be on the format YYYY-MM-DD"}).datetime( {message: "Missing or invalid end date"}),
callForPapersDate: z.string().trim().regex(yyyymmdd, {message: "Call-for-papers date must be on the format YYYY-MM-DD"}).optional(),
Expand All @@ -26,7 +36,17 @@ export const Conference = z.object({
name: z.string().trim(),
email: z.string().trim()
})),
description: z.string().trim(),
description: z.array(z.object({
_key: z.string(),
_type: z.string(),
markDefs: z.array(z.any()),
children: z.array(z.object({
_key: z.string(),
_type: z.string(),
marks: z.array(z.any()),
text: z.string().trim()
})),
})),
duration: z.number(),
submissionType: z.nativeEnum(Submission),
title: z.string().trim()
Expand Down
2 changes: 1 addition & 1 deletion src/model/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface IPerformance {

export interface IDescription {
_type: string;
style: string;
style?: string;
_key: string;
markDefs: ImarkDefs[];
children: IChildren[];
Expand Down
5 changes: 3 additions & 2 deletions src/routes/konferanser/rediger/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import NewPerformanceModal
from "../../../components/conference/NewConference/Page/PerformanceModal/NewPerformanceModal.svelte";
import {makeid} from "../../../utils/conference-utils";
import {getMinimalPortableText} from "../../../utils/sanityclient-utils";
const toastContext: IToastContextProps = getContext('toastContext');
export let data;
Expand Down Expand Up @@ -54,8 +55,8 @@
dateAndTime: (new Date().getFullYear() + 1) + "-01-01T15:15:00.000Z",
location: "Rom 42",
submission: {
title: "Bidrag: " + Math.floor(Math.random()*10000),
description: "Bidragbeskrivelse: " + Math.random()*1000000,
title: "Test-bidrag: " + Math.floor(Math.random()*10000),
description: getMinimalPortableText("Bidragbeskrivelse: " + Math.random()*1000000),
authors: [{
name: data.user.name,
email: data.user.email
Expand Down

0 comments on commit 17206d0

Please sign in to comment.