mirror of
https://github.com/barthuijgen/factorio-sites.git
synced 2025-01-09 14:45:40 +02:00
Added user for blueprint_page and user filter query for main page (#4)
* Added user for blueprint_page and user filter query for main page * Added sql error catch, comments related fixes * Comments related fixes #2
This commit is contained in:
parent
21aaf8519d
commit
843b7e715f
@ -0,0 +1,2 @@
|
|||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "blueprint_page" ADD FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
@ -60,6 +60,7 @@ model blueprint_page {
|
|||||||
blueprint_book blueprint_book? @relation(fields: [blueprint_book_id], references: [id])
|
blueprint_book blueprint_book? @relation(fields: [blueprint_book_id], references: [id])
|
||||||
blueprint blueprint? @relation(fields: [blueprint_id], references: [id])
|
blueprint blueprint? @relation(fields: [blueprint_id], references: [id])
|
||||||
user_favorites user_favorites[]
|
user_favorites user_favorites[]
|
||||||
|
user user? @relation(fields: [user_id], references: [id])
|
||||||
}
|
}
|
||||||
|
|
||||||
model session {
|
model session {
|
||||||
@ -92,6 +93,7 @@ model user {
|
|||||||
updated_at DateTime @updatedAt
|
updated_at DateTime @updatedAt
|
||||||
session session[]
|
session session[]
|
||||||
user_favorites user_favorites[]
|
user_favorites user_favorites[]
|
||||||
|
blueprint_pages blueprint_page[]
|
||||||
}
|
}
|
||||||
|
|
||||||
model user_favorites {
|
model user_favorites {
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { NextPage } from "next";
|
import { NextPage } from "next";
|
||||||
|
import Link from "next/link";
|
||||||
import BBCode from "bbcode-to-react";
|
import BBCode from "bbcode-to-react";
|
||||||
import { Button, Grid, Image } from "@chakra-ui/react";
|
import { Button, Grid, Image } from "@chakra-ui/react";
|
||||||
import {
|
import {
|
||||||
getBlueprintBookById,
|
getBlueprintBookById,
|
||||||
getBlueprintById,
|
getBlueprintById,
|
||||||
getBlueprintPageById,
|
getBlueprintPageWithUserById,
|
||||||
isBlueprintPageUserFavorite,
|
isBlueprintPageUserFavorite,
|
||||||
} from "@factorio-sites/database";
|
} from "@factorio-sites/database";
|
||||||
import {
|
import {
|
||||||
@ -92,7 +93,7 @@ export const Index: NextPage<IndexProps> = ({
|
|||||||
.then((res) => res.text())
|
.then((res) => res.text())
|
||||||
.then((string) => {
|
.then((string) => {
|
||||||
const data = parseBlueprintStringClient(string);
|
const data = parseBlueprintStringClient(string);
|
||||||
console.log("data", data);
|
// console.log("data", data);
|
||||||
if (data && blueprint_book) {
|
if (data && blueprint_book) {
|
||||||
setBookChildTreeData(
|
setBookChildTreeData(
|
||||||
mergeBlueprintDataAndChildTree(data, {
|
mergeBlueprintDataAndChildTree(data, {
|
||||||
@ -185,7 +186,15 @@ export const Index: NextPage<IndexProps> = ({
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>User</td>
|
<td>User</td>
|
||||||
<td>-</td>
|
<td>
|
||||||
|
{blueprint_page.user ? (
|
||||||
|
<Link href={`/?user=${blueprint_page.user?.id}`}>
|
||||||
|
<a>{blueprint_page.user?.username}</a>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
"-"
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Tags</td>
|
<td>Tags</td>
|
||||||
@ -362,8 +371,8 @@ export const getServerSideProps = pageHandler(async (context, { session }) => {
|
|||||||
|
|
||||||
if (!blueprintId) return throwError("Blueprint ID not found");
|
if (!blueprintId) return throwError("Blueprint ID not found");
|
||||||
|
|
||||||
const blueprint_page = await getBlueprintPageById(blueprintId);
|
const blueprint_page = await getBlueprintPageWithUserById(blueprintId);
|
||||||
tl("getBlueprintPageById");
|
tl("getBlueprintPageWithUserById");
|
||||||
|
|
||||||
if (!blueprint_page) return throwError("Blueprint page not found");
|
if (!blueprint_page) return throwError("Blueprint page not found");
|
||||||
|
|
||||||
|
@ -156,6 +156,7 @@ export async function getServerSideProps({ query }: NextPageContext) {
|
|||||||
const entities = query.entities ? String(query.entities).split(",") : undefined;
|
const entities = query.entities ? String(query.entities).split(",") : undefined;
|
||||||
const items = query.items ? String(query.items).split(",") : undefined;
|
const items = query.items ? String(query.items).split(",") : undefined;
|
||||||
const recipes = query.recipes ? String(query.recipes).split(",") : undefined;
|
const recipes = query.recipes ? String(query.recipes).split(",") : undefined;
|
||||||
|
const user = query.user ? String(query.user) : undefined;
|
||||||
|
|
||||||
const { count, rows } = await searchBlueprintPages({
|
const { count, rows } = await searchBlueprintPages({
|
||||||
page,
|
page,
|
||||||
@ -166,6 +167,7 @@ export async function getServerSideProps({ query }: NextPageContext) {
|
|||||||
entities,
|
entities,
|
||||||
items,
|
items,
|
||||||
recipes,
|
recipes,
|
||||||
|
user,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import { blueprint_page } from "@prisma/client";
|
import { blueprint_page, user } from "@prisma/client";
|
||||||
import { join, raw, sqltag } from "@prisma/client/runtime";
|
import { join, raw, sqltag } from "@prisma/client/runtime";
|
||||||
import { getBlueprintImageRequestTopic } from "../gcp-pubsub";
|
import { getBlueprintImageRequestTopic } from "../gcp-pubsub";
|
||||||
import { prisma } from "../postgres/database";
|
import { prisma } from "../postgres/database";
|
||||||
import { BlueprintPage, ChildTree } from "@factorio-sites/types";
|
import { BlueprintPage, ChildTree } from "@factorio-sites/types";
|
||||||
import { getBlueprintBookById } from "./blueprint_book";
|
// import { getBlueprintBookById } from "./blueprint_book";
|
||||||
import {
|
import {
|
||||||
getAllBlueprintsFromChildTree,
|
getAllBlueprintsFromChildTree,
|
||||||
getFirstBlueprintFromChildTree,
|
getFirstBlueprintFromChildTree,
|
||||||
} from "@factorio-sites/node-utils";
|
} from "@factorio-sites/node-utils";
|
||||||
|
|
||||||
const mapBlueprintPageEntityToObject = (entity: blueprint_page): BlueprintPage => ({
|
const mapBlueprintPageEntityToObject = (
|
||||||
|
entity: blueprint_page,
|
||||||
|
user?: { id: string; username: string }
|
||||||
|
): BlueprintPage => ({
|
||||||
id: entity.id,
|
id: entity.id,
|
||||||
blueprint_id: entity.blueprint_id ?? null,
|
blueprint_id: entity.blueprint_id ?? null,
|
||||||
blueprint_book_id: entity.blueprint_book_id ?? null,
|
blueprint_book_id: entity.blueprint_book_id ?? null,
|
||||||
@ -21,6 +24,7 @@ const mapBlueprintPageEntityToObject = (entity: blueprint_page): BlueprintPage =
|
|||||||
updated_at: entity.updated_at && entity.updated_at.getTime() / 1000,
|
updated_at: entity.updated_at && entity.updated_at.getTime() / 1000,
|
||||||
factorioprints_id: entity.factorioprints_id ?? null,
|
factorioprints_id: entity.factorioprints_id ?? null,
|
||||||
favorite_count: (entity as any).favorite_count || null,
|
favorite_count: (entity as any).favorite_count || null,
|
||||||
|
user: user || null,
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function getBlueprintPageById(id: string): Promise<BlueprintPage | null> {
|
export async function getBlueprintPageById(id: string): Promise<BlueprintPage | null> {
|
||||||
@ -33,6 +37,13 @@ export async function getBlueprintPageByUserId(user_id: string): Promise<Bluepri
|
|||||||
return results ? results.map((result) => mapBlueprintPageEntityToObject(result)) : null;
|
return results ? results.map((result) => mapBlueprintPageEntityToObject(result)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getBlueprintPageWithUserById(
|
||||||
|
id: string
|
||||||
|
): Promise<(BlueprintPage & { user: { id: string; username: string } | null }) | null> {
|
||||||
|
const result = await prisma.blueprint_page.findUnique({ where: { id }, include: { user: true } });
|
||||||
|
return result ? mapBlueprintPageEntityToObject(result, result.user) : null;
|
||||||
|
}
|
||||||
|
|
||||||
export async function getBlueprintPageByFactorioprintsId(
|
export async function getBlueprintPageByFactorioprintsId(
|
||||||
id: string
|
id: string
|
||||||
): Promise<BlueprintPage | null> {
|
): Promise<BlueprintPage | null> {
|
||||||
@ -49,6 +60,7 @@ export async function searchBlueprintPages({
|
|||||||
entities,
|
entities,
|
||||||
items,
|
items,
|
||||||
recipes,
|
recipes,
|
||||||
|
user,
|
||||||
}: {
|
}: {
|
||||||
page: number;
|
page: number;
|
||||||
perPage: number;
|
perPage: number;
|
||||||
@ -58,6 +70,7 @@ export async function searchBlueprintPages({
|
|||||||
entities?: string[];
|
entities?: string[];
|
||||||
items?: string[];
|
items?: string[];
|
||||||
recipes?: string[];
|
recipes?: string[];
|
||||||
|
user?: string;
|
||||||
}): Promise<{ count: number; rows: BlueprintPage[] }> {
|
}): Promise<{ count: number; rows: BlueprintPage[] }> {
|
||||||
const orderMap: Record<string, string> = {
|
const orderMap: Record<string, string> = {
|
||||||
date: "blueprint_page.updated_at",
|
date: "blueprint_page.updated_at",
|
||||||
@ -80,39 +93,50 @@ export async function searchBlueprintPages({
|
|||||||
const tagsFragment = tags
|
const tagsFragment = tags
|
||||||
? sqltag`AND blueprint_page.tags @> array[${join(tags)}::varchar]`
|
? sqltag`AND blueprint_page.tags @> array[${join(tags)}::varchar]`
|
||||||
: sqltag``;
|
: sqltag``;
|
||||||
|
const userFragment = user ? sqltag`AND blueprint_page.user_id = ${user}` : sqltag``;
|
||||||
|
|
||||||
const result = (
|
try {
|
||||||
await prisma.$queryRaw<(blueprint_page & { favorite_count: number })[]>`
|
const result = (
|
||||||
SELECT DISTINCT blueprint_page.*, (SELECT COUNT(*) FROM user_favorites where user_favorites.blueprint_page_id = blueprint_page.id) AS favorite_count
|
await prisma.$queryRaw<(blueprint_page & { favorite_count: number })[]>`
|
||||||
FROM public.blueprint_page
|
SELECT DISTINCT blueprint_page.*, (SELECT COUNT(*) FROM user_favorites where user_favorites.blueprint_page_id = blueprint_page.id) AS favorite_count
|
||||||
${blueprintDataSearch}
|
FROM public.blueprint_page
|
||||||
WHERE blueprint_page.title ILIKE ${query ? `%${query}%` : "%"}
|
${blueprintDataSearch}
|
||||||
${entitiesFragment}
|
WHERE blueprint_page.title ILIKE ${query ? `%${query}%` : "%"}
|
||||||
${itemsFragment}
|
${entitiesFragment}
|
||||||
${recipesFragment}
|
${itemsFragment}
|
||||||
${tagsFragment}
|
${recipesFragment}
|
||||||
ORDER BY ${raw(orderMap[order] || orderMap.date)} DESC
|
${tagsFragment}
|
||||||
LIMIT ${perPage} OFFSET ${(page - 1) * perPage}`
|
${userFragment}
|
||||||
).map((blueprintPage) => ({
|
ORDER BY ${raw(orderMap[order] || orderMap.date)} DESC
|
||||||
...blueprintPage,
|
LIMIT ${perPage} OFFSET ${(page - 1) * perPage}`
|
||||||
created_at: new Date(blueprintPage.created_at),
|
).map((blueprintPage) => ({
|
||||||
updated_at: new Date(blueprintPage.updated_at),
|
...blueprintPage,
|
||||||
}));
|
created_at: new Date(blueprintPage.created_at),
|
||||||
|
updated_at: new Date(blueprintPage.updated_at),
|
||||||
|
}));
|
||||||
|
|
||||||
const countResult = await prisma.$queryRaw<{ count: number }[]>`
|
const countResult = await prisma.$queryRaw<{ count: number }[]>`
|
||||||
SELECT COUNT(DISTINCT blueprint_page.id)
|
SELECT COUNT(DISTINCT blueprint_page.id)
|
||||||
FROM public.blueprint_page
|
FROM public.blueprint_page
|
||||||
${blueprintDataSearch}
|
${blueprintDataSearch}
|
||||||
WHERE blueprint_page.title ILIKE ${query ? `%${query}%` : "%"}
|
WHERE blueprint_page.title ILIKE ${query ? `%${query}%` : "%"}
|
||||||
${entitiesFragment}
|
${entitiesFragment}
|
||||||
${itemsFragment}
|
${itemsFragment}
|
||||||
${recipesFragment}
|
${recipesFragment}
|
||||||
${tagsFragment}`;
|
${tagsFragment}
|
||||||
|
${userFragment}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
count: countResult[0].count,
|
count: countResult[0].count,
|
||||||
rows: result.map(mapBlueprintPageEntityToObject),
|
rows: result.map(mapBlueprintPageEntityToObject),
|
||||||
};
|
};
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return {
|
||||||
|
count: 0,
|
||||||
|
rows: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createBlueprintPage(
|
export async function createBlueprintPage(
|
||||||
@ -120,7 +144,7 @@ export async function createBlueprintPage(
|
|||||||
targetId: string,
|
targetId: string,
|
||||||
data: {
|
data: {
|
||||||
title: string;
|
title: string;
|
||||||
user_id: string | null;
|
user_id?: string;
|
||||||
description_markdown: string;
|
description_markdown: string;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
image_hash: string;
|
image_hash: string;
|
||||||
@ -132,7 +156,7 @@ export async function createBlueprintPage(
|
|||||||
) {
|
) {
|
||||||
const page = await prisma.blueprint_page.create({
|
const page = await prisma.blueprint_page.create({
|
||||||
data: {
|
data: {
|
||||||
user_id: data.user_id,
|
user_id: data.user_id || null,
|
||||||
title: data.title,
|
title: data.title,
|
||||||
description_markdown: data.description_markdown,
|
description_markdown: data.description_markdown,
|
||||||
factorioprints_id: data.factorioprints_id,
|
factorioprints_id: data.factorioprints_id,
|
||||||
@ -170,7 +194,7 @@ export async function editBlueprintPage(
|
|||||||
targetId: string,
|
targetId: string,
|
||||||
extraInfo: {
|
extraInfo: {
|
||||||
title: string;
|
title: string;
|
||||||
user_id: string | null;
|
user_id?: string;
|
||||||
description_markdown: string;
|
description_markdown: string;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
created_at?: number;
|
created_at?: number;
|
||||||
@ -181,7 +205,7 @@ export async function editBlueprintPage(
|
|||||||
const page = await prisma.blueprint_page.update({
|
const page = await prisma.blueprint_page.update({
|
||||||
where: { id: blueprintPageId },
|
where: { id: blueprintPageId },
|
||||||
data: {
|
data: {
|
||||||
user_id: extraInfo.user_id,
|
user_id: extraInfo.user_id || null,
|
||||||
title: extraInfo.title,
|
title: extraInfo.title,
|
||||||
description_markdown: extraInfo.description_markdown,
|
description_markdown: extraInfo.description_markdown,
|
||||||
factorioprints_id: extraInfo.factorioprints_id,
|
factorioprints_id: extraInfo.factorioprints_id,
|
||||||
|
@ -10,6 +10,7 @@ interface BlueprintDataFromFactorioprints {
|
|||||||
created_at?: number;
|
created_at?: number;
|
||||||
tags: string[];
|
tags: string[];
|
||||||
factorioprints_id: string;
|
factorioprints_id: string;
|
||||||
|
user_id: string;
|
||||||
}
|
}
|
||||||
export async function saveBlueprintFromFactorioprints(
|
export async function saveBlueprintFromFactorioprints(
|
||||||
factorioprintData: BlueprintDataFromFactorioprints,
|
factorioprintData: BlueprintDataFromFactorioprints,
|
||||||
@ -28,7 +29,7 @@ export async function saveBlueprintFromFactorioprints(
|
|||||||
};
|
};
|
||||||
|
|
||||||
const extraInfoPage = {
|
const extraInfoPage = {
|
||||||
user_id: null,
|
user_id: factorioprintData.user_id,
|
||||||
title: factorioprintData.title,
|
title: factorioprintData.title,
|
||||||
description_markdown: factorioprintData.description_markdown,
|
description_markdown: factorioprintData.description_markdown,
|
||||||
created_at: factorioprintData.created_at,
|
created_at: factorioprintData.created_at,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { Signal } from "./blueprint-string";
|
import { Signal } from "./blueprint-string";
|
||||||
|
|
||||||
export interface ChildTreeBlueprint {
|
export interface ChildTreeBlueprint {
|
||||||
type: "blueprint";
|
type: "blueprint";
|
||||||
id: string;
|
id: string;
|
||||||
@ -54,6 +53,7 @@ export interface BlueprintPage {
|
|||||||
updated_at: number;
|
updated_at: number;
|
||||||
factorioprints_id: string | null;
|
factorioprints_id: string | null;
|
||||||
favorite_count?: number;
|
favorite_count?: number;
|
||||||
|
user: { id: string; username: string } | null;
|
||||||
// BlueprintPageEntry->BlueprintEntry 1:m
|
// BlueprintPageEntry->BlueprintEntry 1:m
|
||||||
// BlueprintPageEntry->BlueprintBook 1:m
|
// BlueprintPageEntry->BlueprintBook 1:m
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user