Add weight to individual docs articles

This commit is contained in:
thiloho
2024-08-29 12:05:02 +02:00
parent 816df44bd3
commit e5b55baaef
6 changed files with 204 additions and 32 deletions

View File

@@ -0,0 +1,54 @@
-- migrate:up
ALTER TABLE internal.article
ADD COLUMN article_weight INTEGER CHECK (article_weight IS NULL
OR article_weight >= 0);
CREATE OR REPLACE VIEW api.article WITH ( security_invoker = ON
) AS
SELECT
id,
website_id,
user_id,
title,
meta_description,
meta_author,
cover_image,
publication_date,
main_content,
created_at,
last_modified_at,
last_modified_by,
title_description_search,
category,
article_weight -- New column
FROM
internal.article;
GRANT SELECT, INSERT, UPDATE, DELETE ON api.article TO authenticated_user;
-- migrate:down
DROP VIEW api.article;
CREATE VIEW api.article WITH ( security_invoker = ON
) AS
SELECT
id,
website_id,
user_id,
title,
meta_description,
meta_author,
cover_image,
publication_date,
main_content,
created_at,
last_modified_at,
last_modified_by,
title_description_search,
category
FROM
internal.article;
ALTER TABLE internal.article
DROP COLUMN article_weight;

View File

@@ -0,0 +1,140 @@
-- migrate:up
CREATE OR REPLACE VIEW api.website_overview WITH ( security_invoker = ON
) AS
SELECT
w.id,
w.user_id,
w.content_type,
w.title,
s.accent_color_light_theme,
s.accent_color_dark_theme,
s.favicon_image,
h.logo_type,
h.logo_text,
h.logo_image,
ho.main_content,
f.additional_text,
(
SELECT
JSON_AGG(
JSON_BUILD_OBJECT(
'id', a.id, 'title', a.title, 'meta_description', a.meta_description, 'meta_author', a.meta_author, 'cover_image', a.cover_image, 'publication_date', a.publication_date, 'main_content', a.main_content, 'created_at', a.created_at, 'last_modified_at', a.last_modified_at
)
)
FROM
internal.article a
WHERE
a.website_id = w.id
) AS articles,
CASE WHEN w.content_type = 'Docs' THEN
(
SELECT
JSON_OBJECT_AGG(
COALESCE(
category_name, 'Uncategorized'
), articles
)
FROM (
SELECT
dc.category_name,
dc.category_weight AS category_weight,
JSON_AGG(
JSON_BUILD_OBJECT(
'id', a.id, 'title', a.title, 'meta_description', a.meta_description, 'meta_author', a.meta_author, 'cover_image', a.cover_image, 'publication_date', a.publication_date, 'main_content', a.main_content, 'created_at', a.created_at, 'last_modified_at', a.last_modified_at
)
) AS articles
FROM
internal.article a
LEFT JOIN internal.docs_category dc ON a.category = dc.id
WHERE
a.website_id = w.id
GROUP BY
dc.id,
dc.category_name,
dc.category_weight
ORDER BY
category_weight DESC NULLS LAST
) AS categorized_articles)
ELSE
NULL
END AS categorized_articles
FROM
internal.website w
JOIN internal.settings s ON w.id = s.website_id
JOIN internal.header h ON w.id = h.website_id
JOIN internal.home ho ON w.id = ho.website_id
JOIN internal.footer f ON w.id = f.website_id;
GRANT SELECT ON api.website_overview TO authenticated_user;
-- migrate:down
DROP VIEW api.website_overview;
CREATE VIEW api.website_overview WITH ( security_invoker = ON
) AS
SELECT
w.id,
w.user_id,
w.content_type,
w.title,
s.accent_color_light_theme,
s.accent_color_dark_theme,
s.favicon_image,
h.logo_type,
h.logo_text,
h.logo_image,
ho.main_content,
f.additional_text,
(
SELECT
JSON_AGG(
JSON_BUILD_OBJECT(
'id', a.id, 'title', a.title, 'meta_description', a.meta_description, 'meta_author', a.meta_author, 'cover_image', a.cover_image, 'publication_date', a.publication_date, 'main_content', a.main_content, 'created_at', a.created_at, 'last_modified_at', a.last_modified_at
)
)
FROM
internal.article a
WHERE
a.website_id = w.id
) AS articles,
CASE WHEN w.content_type = 'Docs' THEN
(
SELECT
JSON_OBJECT_AGG(
COALESCE(
category_name, 'Uncategorized'
), articles
)
FROM (
SELECT
dc.category_name,
dc.category_weight AS category_weight,
JSON_AGG(
JSON_BUILD_OBJECT(
'id', a.id, 'title', a.title, 'meta_description', a.meta_description, 'meta_author', a.meta_author, 'cover_image', a.cover_image, 'publication_date', a.publication_date, 'main_content', a.main_content, 'created_at', a.created_at, 'last_modified_at', a.last_modified_at
)
) AS articles
FROM
internal.article a
LEFT JOIN internal.docs_category dc ON a.category = dc.id
WHERE
a.website_id = w.id
GROUP BY
dc.id,
dc.category_name,
dc.category_weight
ORDER BY
category_weight DESC
) AS categorized_articles)
ELSE
NULL
END AS categorized_articles
FROM
internal.website w
JOIN internal.settings s ON w.id = s.website_id
JOIN internal.header h ON w.id = h.website_id
JOIN internal.home ho ON w.id = ho.website_id
JOIN internal.footer f ON w.id = f.website_id;
GRANT SELECT ON api.website_overview TO authenticated_user;

View File

@@ -3,16 +3,14 @@ import { API_BASE_PREFIX } from "$lib/server/utils";
export const load: PageServerLoad = async ({ params, fetch, cookies, url, parent, locals }) => { export const load: PageServerLoad = async ({ params, fetch, cookies, url, parent, locals }) => {
const searchQuery = url.searchParams.get("article_search_query"); const searchQuery = url.searchParams.get("article_search_query");
const sortBy = url.searchParams.get("article_sort");
const filterBy = url.searchParams.get("article_filter"); const filterBy = url.searchParams.get("article_filter");
const { website, home } = await parent(); const { website, home } = await parent();
let baseFetchUrl = `${API_BASE_PREFIX}/article?website_id=eq.${params.websiteId}&select=id,title`; let baseFetchUrl = `${API_BASE_PREFIX}/article?website_id=eq.${params.websiteId}&select=id,title`;
let docsSortString = "";
if (website.content_type === "Docs") { if (website.content_type === "Docs") {
baseFetchUrl += ",docs_category(category_name,category_weight)"; baseFetchUrl +=
docsSortString = "docs_category(category_weight).desc,"; ",docs_category(category_name,category_weight)&order=docs_category(category_weight).desc.nullslast,article_weight.desc.nullslast";
} }
const parameters = new URLSearchParams(); const parameters = new URLSearchParams();
@@ -21,22 +19,6 @@ export const load: PageServerLoad = async ({ params, fetch, cookies, url, parent
parameters.append("title_description_search", `wfts(english).${searchQuery}`); parameters.append("title_description_search", `wfts(english).${searchQuery}`);
} }
switch (sortBy) {
case null:
case "creation-time":
parameters.append("order", `${docsSortString}created_at.desc`);
break;
case "last-modified":
parameters.append("order", `${docsSortString}last_modified_at.desc`);
break;
case "title-a-to-z":
parameters.append("order", `${docsSortString}title.asc`);
break;
case "title-z-to-a":
parameters.append("order", `${docsSortString}title.desc`);
break;
}
switch (filterBy) { switch (filterBy) {
case "creations": case "creations":
parameters.append("user_id", `eq.${locals.user.id}`); parameters.append("user_id", `eq.${locals.user.id}`);

View File

@@ -53,7 +53,7 @@
</h2> </h2>
<details> <details>
<summary>Search & Sort & Filter</summary> <summary>Search & Filter</summary>
<form method="GET"> <form method="GET">
<label> <label>
Search: Search:
@@ -63,16 +63,6 @@
value={$page.url.searchParams.get("article_search_query")} value={$page.url.searchParams.get("article_search_query")}
/> />
</label> </label>
<label>
Sort:
<select name="article_sort">
{#each sortOptions as { value, text }}
<option {value} selected={value === $page.url.searchParams.get("article_sort")}
>{text}</option
>
{/each}
</select>
</label>
<label> <label>
Filter: Filter:
<select name="article_filter"> <select name="article_filter">

View File

@@ -66,7 +66,8 @@ export const actions: Actions = {
cover_image: uploadedImage.file_id, cover_image: uploadedImage.file_id,
publication_date: data.get("publication-date"), publication_date: data.get("publication-date"),
main_content: data.get("main-content"), main_content: data.get("main-content"),
category: data.get("category") category: data.get("category"),
article_weight: data.get("article-weight") ? data.get("article-weight") : null
}) })
}); });

View File

@@ -52,6 +52,11 @@
}} }}
> >
{#if data.website.content_type === "Docs"} {#if data.website.content_type === "Docs"}
<label>
Weight:
<input type="number" name="article-weight" value={data.article.article_weight} min="0" />
</label>
<label> <label>
Category: Category:
<select name="category"> <select name="category">