Improved handling of null values when entering tags frontmatter

This commit is contained in:
PrinOrange
2024-01-06 20:20:05 +08:00
parent fb308f7b11
commit eac42b69a7
8 changed files with 61 additions and 15 deletions

View File

@@ -2,6 +2,7 @@
"cSpell.words": [ "cSpell.words": [
"alipay", "alipay",
"frontmatter", "frontmatter",
"Frontmatters",
"giscus", "giscus",
"github", "github",
"micromessenger", "micromessenger",

View File

@@ -4,7 +4,7 @@ import { TPostListItem, TTagSubPostSet } from "@/types/post-list";
import fs from "fs"; import fs from "fs";
import { serialize } from "next-mdx-remote/serialize"; import { serialize } from "next-mdx-remote/serialize";
import path from "path"; import path from "path";
import { capitalizeFirstLetter, nullifyEmptyString } from "./utils"; import { isEmptyString, nullifyEmptyArray, nullifyEmptyString } from "./utils";
async function getFrontmatters(filepath: string): Promise<TFrontmatter> { async function getFrontmatters(filepath: string): Promise<TFrontmatter> {
const source = fs.readFileSync(filepath, "utf-8"); const source = fs.readFileSync(filepath, "utf-8");
@@ -45,7 +45,10 @@ const sortOutPostLists = async (): Promise<{
for (let i = 0; i < postFilePaths.length; i++) { for (let i = 0; i < postFilePaths.length; i++) {
const frontmatter = await getFrontmatters(postFilePaths[i]); const frontmatter = await getFrontmatters(postFilePaths[i]);
const postId = path.parse(postFilePaths[i]).name; const postId = path.parse(postFilePaths[i]).name;
const normalizedTags = frontmatter.tags?.map((tagname) => tagname.toUpperCase());
const normalizedTags = frontmatter.tags
?.filter((tagname) => !isEmptyString(tagname))
.map((tagname) => tagname.toUpperCase());
const postListItem: TPostListItem = { const postListItem: TPostListItem = {
id: postId, id: postId,
@@ -53,7 +56,7 @@ const sortOutPostLists = async (): Promise<{
title: frontmatter.title, title: frontmatter.title,
subtitle: nullifyEmptyString(frontmatter.subtitle), subtitle: nullifyEmptyString(frontmatter.subtitle),
coverURL: nullifyEmptyString(frontmatter.coverURL), coverURL: nullifyEmptyString(frontmatter.coverURL),
tags: normalizedTags ?? [], tags: nullifyEmptyArray(normalizedTags),
summary: nullifyEmptyString(frontmatter.summary), summary: nullifyEmptyString(frontmatter.summary),
time: frontmatter.time, time: frontmatter.time,
pin: frontmatter.pin ?? false, pin: frontmatter.pin ?? false,

View File

@@ -1,3 +1,4 @@
import { NonEmptyArray } from "@/types/utils.type";
import { clsx, type ClassValue } from "clsx"; import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
@@ -33,13 +34,10 @@ export function paginateArray<T = any>(array: T[], pageSize: number, pageNumber:
* @returns return `null` if the input belongs to "", undefined and null. * @returns return `null` if the input belongs to "", undefined and null.
*/ */
export function nullifyEmptyString(value: string | null | undefined): string | null { export function nullifyEmptyString(value: string | null | undefined): string | null {
if (value == null) { if (isEmptyString(value)) {
return null; return null;
} }
if (value.trim() === "") { return value!;
return null;
}
return value;
} }
/** /**
@@ -48,7 +46,7 @@ export function nullifyEmptyString(value: string | null | undefined): string | n
* @returns return `true` if the input belongs to "", undefined and null. * @returns return `true` if the input belongs to "", undefined and null.
*/ */
export function isEmptyString(value: string | null | undefined): boolean { export function isEmptyString(value: string | null | undefined): boolean {
if (value == null) { if (value === null || value === undefined) {
return true; return true;
} }
if (value.trim() === "") { if (value.trim() === "") {
@@ -57,6 +55,42 @@ export function isEmptyString(value: string | null | undefined): boolean {
return false; return false;
} }
/**
* Removes empty values from an array.
* @param value - The array to remove empty values from.
* @returns The array without empty values.
* @template T - The type of the array elements.
*/
export function removeEmptyValuesFromArray<T = any>(value: any[]): T[] {
return value.filter((item) => item != null);
}
/**
* Checks if an array is empty.
* @param value - The array to check.
* @returns True if the array is empty, false otherwise.
*/
export function isEmptyArray(value: any[] | null | undefined): boolean {
if (value === null || value === undefined) {
return true;
}
return removeEmptyValuesFromArray(value).length !== 0;
}
/**
* Nullifies an empty array.
*
* @template T - The type of the array elements.
* @param value - The array value to be nullified if empty.
* @returns The nullified array if it is empty, otherwise returns the original array.
*/
export function nullifyEmptyArray<T>(value: T[] | null | undefined): NonEmptyArray<T> | null {
if (isEmptyArray(value)) {
return null;
}
return value as NonEmptyArray<T>;
}
/** /**
* Capitalizes the first letter of each word in a string. * Capitalizes the first letter of each word in a string.
* *

View File

@@ -38,7 +38,7 @@ export default function PostsPage(props: PostsPageProps) {
} }
}; };
const handleChangePageNumber = (event: ChangeEvent<HTMLInputElement>) => { const handleInputPageNumber = (event: ChangeEvent<HTMLInputElement>) => {
setPageNumber(event.target.value); setPageNumber(event.target.value);
}; };
@@ -78,7 +78,7 @@ export default function PostsPage(props: PostsPageProps) {
<div className="my-auto font-bold flex justify-center"> <div className="my-auto font-bold flex justify-center">
<Input <Input
onKeyDown={handleEnterKeyJump} onKeyDown={handleEnterKeyJump}
onChange={handleChangePageNumber} onChange={handleInputPageNumber}
className="my-auto mx-2 w-11 h-6" className="my-auto mx-2 w-11 h-6"
value={pageNumber} value={pageNumber}
/> />

View File

@@ -7,6 +7,7 @@ import { Footer } from "@/components/utils/Footer";
import { NavBar } from "@/components/utils/NavBar"; import { NavBar } from "@/components/utils/NavBar";
import { SEO } from "@/components/utils/SEO"; import { SEO } from "@/components/utils/SEO";
import { Config } from "@/data/config"; import { Config } from "@/data/config";
import { isEmptyString } from "@/lib/utils";
import { fontFangZhengXiaoBiaoSongCN, fontSourceSerifScreenCN } from "@/styles/font"; import { fontFangZhengXiaoBiaoSongCN, fontSourceSerifScreenCN } from "@/styles/font";
import { TSearchResultItem } from "@/types/search-result"; import { TSearchResultItem } from "@/types/search-result";
import axios from "axios"; import axios from "axios";
@@ -30,7 +31,7 @@ export default function SearchPage() {
onSuccess: (data) => { onSuccess: (data) => {
setSearchResult(data); setSearchResult(data);
if (data.length === 0) { if (data.length === 0) {
toast({ title: "Empty Result", description: "Change the keyword please." }); toast({ title: "Empty Result", description: "No results were found for this keyword. Try another keyword." });
} }
}, },
onError: () => { onError: () => {
@@ -47,6 +48,10 @@ export default function SearchPage() {
}; };
const handleMakeSearch = () => { const handleMakeSearch = () => {
if (isEmptyString(searchText)) {
toast({ title: "Enter a Keyword", description: "Please enter one keyword at least." });
return;
}
querySearch.refetch(); querySearch.refetch();
}; };

View File

@@ -35,7 +35,7 @@ export default function TagsContentPage(props: TagsContentPageProps) {
} }
}; };
const handleChangePageNumber = (event: ChangeEvent<HTMLInputElement>) => { const handleInputPageNumber = (event: ChangeEvent<HTMLInputElement>) => {
setPageNumber(event.target.value); setPageNumber(event.target.value);
}; };
@@ -70,7 +70,7 @@ export default function TagsContentPage(props: TagsContentPageProps) {
<div className="my-auto font-bold flex justify-center"> <div className="my-auto font-bold flex justify-center">
<Input <Input
onKeyDown={handleEnterKeyJump} onKeyDown={handleEnterKeyJump}
onChange={handleChangePageNumber} onChange={handleInputPageNumber}
className="my-auto mx-2 w-11 h-6" className="my-auto mx-2 w-11 h-6"
value={pageNumber} value={pageNumber}
/> />

View File

@@ -1,7 +1,9 @@
import { NonEmptyArray } from "./utils.type";
export type TFrontmatter = { export type TFrontmatter = {
title: string; title: string;
time: string; time: string;
tags: string[] | null; tags: NonEmptyArray<string> | null;
subtitle: string | null; subtitle: string | null;
summary: string | null; summary: string | null;
coverURL: string | null; coverURL: string | null;

1
types/utils.type.ts Normal file
View File

@@ -0,0 +1 @@
export type NonEmptyArray<T> = [T, ...T[]];