diff --git a/CHANGELOG.md b/CHANGELOG.md index 95bd4b41..8784bb38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,10 @@ ### 🎨 Enhancements +- [#558](https://github.com/estruyf/vscode-front-matter/issues/558): Moved the tags and categories to a `.frontmatter/database/taxonomyDb.json` file - [#566](https://github.com/estruyf/vscode-front-matter/issues/566): Keep the panel context on the live preview - [#568](https://github.com/estruyf/vscode-front-matter/issues/568): Update the preview URL if the slug changes -- [#558](https://github.com/estruyf/vscode-front-matter/issues/558): Moved the tags and categories to a `.frontmatter/database/taxonomyDb.json` file +- [#586](https://github.com/estruyf/vscode-front-matter/issues/586): Allow to specify the content card fields ### ⚡️ Optimizations diff --git a/package.json b/package.json index 4624be65..88679ee6 100644 --- a/package.json +++ b/package.json @@ -573,6 +573,26 @@ "markdownDescription": "Specify the name of the metadata field that will be used to show the tags on the content card. When empty or null, it will hide the tags from the card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.cardTags)", "scope": "Dashboard" }, + "frontMatter.dashboard.content.card.fields.state": { + "type": "boolean", + "default": true, + "markdownDescription": "Specify if you want to show the state/draft status on the content card view. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.state)" + }, + "frontMatter.dashboard.content.card.fields.date": { + "type": "boolean", + "default": true, + "markdownDescription": "Specify if you want to show the date on the content card view. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.date)" + }, + "frontMatter.dashboard.content.card.fields.description": { + "type": ["null", "string"], + "default": "", + "markdownDescription": "Specify the name of the metadata field that will be used to show the description on the content card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.description)" + }, + "frontMatter.dashboard.content.card.fields.title": { + "type": ["null", "string"], + "default": "", + "markdownDescription": "Specify the name of the metadata field that will be used to show the title on the content card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.title)" + }, "frontMatter.dashboard.mediaSnippet": { "type": "array", "default": [], diff --git a/src/constants/settings.ts b/src/constants/settings.ts index aed86f07..29b1efc2 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -76,6 +76,13 @@ export const SETTING_DASHBOARD_OPENONSTART = 'dashboard.openOnStart'; export const SETTING_DASHBOARD_CONTENT_TAGS = 'dashboard.content.cardTags'; export const SETTING_DASHBOARD_CONTENT_PAGINATION = 'dashboard.content.pagination'; +// Content cards +export const SETTING_DASHBOARD_CONTENT_CARD_STATE = 'dashboard.content.card.fields.state'; +export const SETTING_DASHBOARD_CONTENT_CARD_DATE = 'dashboard.content.card.fields.date'; +export const SETTING_DASHBOARD_CONTENT_CARD_TITLE = 'dashboard.content.card.fields.title'; +export const SETTING_DASHBOARD_CONTENT_CARD_DESCRIPTION = + 'dashboard.content.card.fields.description'; + export const SETTING_DATA_FILES = 'data.files'; export const SETTING_DATA_FOLDERS = 'data.folders'; export const SETTING_DATA_TYPES = 'data.types'; diff --git a/src/dashboardWebView/components/Contents/Item.tsx b/src/dashboardWebView/components/Contents/Item.tsx index 87772165..205291aa 100644 --- a/src/dashboardWebView/components/Contents/Item.tsx +++ b/src/dashboardWebView/components/Contents/Item.tsx @@ -11,7 +11,6 @@ import { useEffect, useMemo, useState } from 'react'; import useThemeColors from '../../hooks/useThemeColors'; import { Status } from './Status'; import * as React from 'react'; -import { messageHandler } from '@estruyf/vscode/dist/client'; export interface IItemProps extends Page { } @@ -28,25 +27,51 @@ export const Item: React.FunctionComponent = ({ const view = useRecoilValue(ViewSelector); const settings = useRecoilValue(SettingsSelector); const draftField = useMemo(() => settings?.draftField, [settings]); + const cardFields = useMemo(() => settings?.dashboardState?.contents?.cardFields, [settings?.dashboardState?.contents?.cardFields]); const [imageHtml, setImageHtml] = useState(undefined); const [footerHtml, setFooterHtml] = useState(undefined); const { getColors } = useThemeColors(); const escapedTitle = useMemo(() => { - if (title && typeof title !== 'string') { + console.log('escapedTitle', title, cardFields?.title, pageData); + let value = title; + + if (cardFields?.title) { + if (cardFields.title === "description") { + value = description; + } else if (cardFields?.title !== "title") { + value = pageData[cardFields?.title] || title; + } + } else if (cardFields?.title === null) { + return null; + } + + if (value && typeof value !== 'string') { return ''; } - return title; - }, [title]); + return value; + }, [title, description, cardFields?.title, pageData]); const escapedDescription = useMemo(() => { - if (description && typeof description !== 'string') { + let value = description; + + if (cardFields?.description) { + if (cardFields.description === "title") { + value = title; + } else if (cardFields?.description !== "description") { + value = pageData[cardFields?.description] || description; + } + } else if (cardFields?.description === null) { + return null; + } + + if (value && typeof value !== 'string') { return ''; } - return description; - }, [description]); + return value; + }, [description, title, cardFields?.description, pageData]); const openFile = () => { Messenger.send(DashboardMessage.openFile, fmFilePath); @@ -77,6 +102,10 @@ export const Item: React.FunctionComponent = ({ return []; }, [settings, pageData]); + const hasDraftOrDate = useMemo(() => { + return cardFields && (cardFields.state || cardFields.date); + }, [cardFields]); + useEffect(() => { if (window.fmExternal && window.fmExternal.getCardFooter) { window.fmExternal.getCardFooter(fmFilePath, { @@ -137,7 +166,7 @@ export const Item: React.FunctionComponent = ({ pageData[PREVIEW_IMAGE_FIELD] ? ( {escapedTitle} @@ -160,21 +189,27 @@ export const Item: React.FunctionComponent = ({
-
- {draftField && draftField.name && } +
+ { + cardFields?.state && draftField && draftField.name && + } - - - + { + cardFields?.date && + }
+ + (SETTING_CONTENT_SORTING_DEFAULT), tags: Settings.get(SETTING_DASHBOARD_CONTENT_TAGS), templatesEnabled: Settings.get(SETTING_TEMPLATES_ENABLED), - pagination: pagination !== undefined ? pagination : true + pagination: pagination !== undefined ? pagination : true, + cardFields: { + state: Settings.get(SETTING_DASHBOARD_CONTENT_CARD_STATE), + date: Settings.get(SETTING_DASHBOARD_CONTENT_CARD_DATE), + title: Settings.get(SETTING_DASHBOARD_CONTENT_CARD_TITLE), + description: Settings.get(SETTING_DASHBOARD_CONTENT_CARD_DESCRIPTION) + } }, media: { sorting: await ext.getState( diff --git a/src/listeners/dashboard/PagesListener.ts b/src/listeners/dashboard/PagesListener.ts index c26aafde..13a345ac 100644 --- a/src/listeners/dashboard/PagesListener.ts +++ b/src/listeners/dashboard/PagesListener.ts @@ -3,11 +3,16 @@ import { basename } from 'path'; import { commands, FileSystemWatcher, RelativePattern, TextDocument, Uri, workspace } from 'vscode'; import { Dashboard } from '../../commands/Dashboard'; import { Folders } from '../../commands/Folders'; -import { COMMAND_NAME, ExtensionState } from '../../constants'; +import { + COMMAND_NAME, + ExtensionState, + SETTING_DASHBOARD_CONTENT_CARD_DESCRIPTION, + SETTING_DASHBOARD_CONTENT_CARD_TITLE +} from '../../constants'; import { DashboardCommand } from '../../dashboardWebView/DashboardCommand'; import { DashboardMessage } from '../../dashboardWebView/DashboardMessage'; import { Page } from '../../dashboardWebView/models'; -import { ArticleHelper, Extension, Logger } from '../../helpers'; +import { ArticleHelper, Extension, Logger, Settings } from '../../helpers'; import { BaseListener } from './BaseListener'; import { DataListener } from '../panel'; import Fuse from 'fuse.js'; @@ -219,13 +224,24 @@ export class PagesListener extends BaseListener { * Search the pages */ private static async searchPages(data: { query: string }) { + const fieldKeys = [ + { name: 'title', weight: 1 }, + { name: 'fmBody', weight: 1 }, + { name: 'slug', weight: 0.5 }, + { name: 'description', weight: 0.5 } + ]; + + const cardTitle = Settings.get(SETTING_DASHBOARD_CONTENT_CARD_TITLE); + if (cardTitle) { + fieldKeys.push({ name: cardTitle as string, weight: 1 }); + } + const cardDescription = Settings.get(SETTING_DASHBOARD_CONTENT_CARD_DESCRIPTION); + if (cardTitle) { + fieldKeys.push({ name: cardDescription as string, weight: 0.5 }); + } + const fuseOptions: Fuse.IFuseOptions = { - keys: [ - { name: 'title', weight: 1 }, - { name: 'fmBody', weight: 1 }, - { name: 'slug', weight: 0.5 }, - { name: 'description', weight: 0.5 } - ], + keys: fieldKeys, includeScore: true, ignoreLocation: true, threshold: 0.1