diff --git a/src/packages/plan/gql.ts b/src/packages/plan/gql.ts index 16c79f5..1f49ac0 100644 --- a/src/packages/plan/gql.ts +++ b/src/packages/plan/gql.ts @@ -39,11 +39,7 @@ export default { `, CREATE_TAGS: `#graphql mutation CreateTags($tags: [tags_insert_input!]!) { - insert_tags(objects: $tags, on_conflict: { - constraint: tags_name_key, - update_columns: [] - }) { - affected_rows + insert_tags(objects: $tags) { returning { color created_at diff --git a/src/packages/plan/plan.ts b/src/packages/plan/plan.ts index d61f71c..5e31dd2 100644 --- a/src/packages/plan/plan.ts +++ b/src/packages/plan/plan.ts @@ -123,22 +123,57 @@ export async function importPlan(req: Request, res: Response) { // insert all the imported activities into the plan logger.info(`POST /importPlan: Importing activities: ${name}`); + const tagsResponse = await fetch(GQL_API_URL, { + body: JSON.stringify({ + query: gql.GET_TAGS, + }), + headers, + method: 'POST', + }); + + const tagsResponseJSON = (await tagsResponse.json()) as { + data: { + tags: Tag[]; + }; + }; + + let tagsMap: Record = {}; + if (tagsResponseJSON != null && tagsResponseJSON.data != null) { + const { + data: { tags }, + } = tagsResponseJSON; + tagsMap = tags.reduce((prevTagsMap: Record, tag) => { + return { + ...prevTagsMap, + [tag.name]: tag, + }; + }, {}); + } + + // derive a map of uniquely named tags from the list of activities that doesn't already exist in the database const activityTags = activities.reduce( (prevActivitiesTagsMap: Record>, { tags }) => { - const tagsMap = - tags?.reduce((prevTagsMap: Record>, { tag }) => { - return { - ...prevTagsMap, - [tag.name]: { - color: tag.color, - name: tag.name, - }, - }; - }, {}) ?? {}; + const currentTagsMap = + tags?.reduce( + (prevTagsMap: Record>, { tag: { name: tagName, color } }) => { + // If the tag doesn't exist already, add it + if (tagsMap[tagName] === undefined) { + return { + ...prevTagsMap, + [tagName]: { + color, + name: tagName, + }, + }; + } + return prevTagsMap; + }, + {}, + ) ?? {}; return { ...prevActivitiesTagsMap, - ...tagsMap, + ...currentTagsMap, }; }, {}, @@ -160,35 +195,18 @@ export async function importPlan(req: Request, res: Response) { }; if (data && data.insert_tags && data.insert_tags.returning.length) { + // track the newly created tags for cleanup if an error occurs during plan import createdTags = data.insert_tags.returning; } - const tagsResponse = await fetch(GQL_API_URL, { - body: JSON.stringify({ - query: gql.GET_TAGS, + // add the newly created tags to the `tagsMap` + tagsMap = createdTags.reduce( + (prevTagsMap: Record, tag) => ({ + ...prevTagsMap, + [tag.name]: tag, }), - headers, - method: 'POST', - }); - - const tagsResponseJSON = (await tagsResponse.json()) as { - data: { - tags: Tag[]; - }; - }; - - let tagsMap: Record = {}; - if (tagsResponseJSON != null && tagsResponseJSON.data != null) { - const { - data: { tags }, - } = tagsResponseJSON; - tagsMap = tags.reduce((prevTagsMap: Record, tag) => { - return { - ...prevTagsMap, - [tag.name]: tag, - }; - }, {}); - } + tagsMap, + ); const activityRemap: Record = {}; const activityDirectivesInsertInput = activities.map(