From 081fb7ce2e36e16cb272ee8be2b2033b4f6bd7a1 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Wed, 8 Jun 2022 18:37:13 +0200 Subject: [PATCH] Start of the taxonomy dashboard implementation --- src/commands/Dashboard.ts | 3 +- src/commands/Diagnostics.ts | 2 +- src/commands/Folders.ts | 3 +- src/constants/Extension.ts | 1 + src/constants/Features.ts | 3 + src/constants/TelemetryEvent.ts | 2 + src/dashboardWebView/DashboardCommand.ts | 3 + src/dashboardWebView/DashboardMessage.ts | 3 + .../components/{Dashboard.tsx => App.tsx} | 15 ++++- .../components/Header/Tabs.tsx | 11 +++- .../components/TaxonomyView/TaxonomyView.tsx | 44 +++++++++++++ .../components/TaxonomyView/index.ts | 1 + src/dashboardWebView/hooks/useMessages.tsx | 2 + src/dashboardWebView/index.tsx | 8 ++- src/dashboardWebView/models/NavigationType.ts | 1 + src/extension.ts | 5 ++ src/listeners/dashboard/TaxonomyListener.ts | 62 +++++++++++++++++++ src/listeners/dashboard/index.ts | 1 + 18 files changed, 162 insertions(+), 8 deletions(-) rename src/dashboardWebView/components/{Dashboard.tsx => App.tsx} (80%) create mode 100644 src/dashboardWebView/components/TaxonomyView/TaxonomyView.tsx create mode 100644 src/dashboardWebView/components/TaxonomyView/index.ts create mode 100644 src/listeners/dashboard/TaxonomyListener.ts diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts index 7c16b088..da1a57ed 100644 --- a/src/commands/Dashboard.ts +++ b/src/commands/Dashboard.ts @@ -7,7 +7,7 @@ import { Extension } from '../helpers/Extension'; import { WebviewHelper } from '@estruyf/vscode'; import { DashboardData } from '../models/DashboardData'; import { MediaLibrary } from '../helpers/MediaLibrary'; -import { DashboardListener, MediaListener, SettingsListener, TelemetryListener, DataListener, PagesListener, ExtensionListener, SnippetListener } from '../listeners/dashboard'; +import { DashboardListener, MediaListener, SettingsListener, TelemetryListener, DataListener, PagesListener, ExtensionListener, SnippetListener, TaxonomyListener } from '../listeners/dashboard'; import { MediaListener as PanelMediaListener } from '../listeners/panel' import { ModeListener } from '../listeners/general'; @@ -145,6 +145,7 @@ export class Dashboard { TelemetryListener.process(msg); SnippetListener.process(msg); ModeListener.process(msg); + TaxonomyListener.process(msg); }); } diff --git a/src/commands/Diagnostics.ts b/src/commands/Diagnostics.ts index 69093109..23974cfb 100644 --- a/src/commands/Diagnostics.ts +++ b/src/commands/Diagnostics.ts @@ -52,7 +52,7 @@ ${folderData.join("\n")} let projectStart = folder.path.split(projectName).pop(); projectStart = projectStart || ""; projectStart = projectStart?.replace(/\\/g, '/'); - projectStart = projectStart?.startsWith('/') ? projectStart.substr(1) : projectStart; + projectStart = projectStart?.startsWith('/') ? projectStart.substring(1) : projectStart; const mdFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.md')); const mdxFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.mdx')); diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index b9ecfcc4..d391468e 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -231,7 +231,7 @@ export class Folders { if (projectStart) { projectStart = projectStart.replace(/\\/g, '/'); - projectStart = projectStart.startsWith('/') ? projectStart.substr(1) : projectStart; + projectStart = projectStart.startsWith('/') ? projectStart.substring(1) : projectStart; let files: Uri[] = []; @@ -259,6 +259,7 @@ export class Folders { }); } catch (error) { // Skip the file + console.log((error as Error).message) } } diff --git a/src/constants/Extension.ts b/src/constants/Extension.ts index 385b8641..e3cffae4 100644 --- a/src/constants/Extension.ts +++ b/src/constants/Extension.ts @@ -32,6 +32,7 @@ export const COMMAND_NAME = { dashboardMedia: getCommandName("dashboard.media"), dashboardSnippets: getCommandName("dashboard.snippets"), dashboardData: getCommandName("dashboard.data"), + dashboardTaxonomy: getCommandName("dashboard.taxonomy"), dashboardClose: getCommandName("dashboard.close"), promote: getCommandName("promoteSettings"), createFolder: getCommandName("createFolder"), diff --git a/src/constants/Features.ts b/src/constants/Features.ts index e4aa8629..662aa88e 100644 --- a/src/constants/Features.ts +++ b/src/constants/Features.ts @@ -17,6 +17,9 @@ export const FEATURE_FLAG = { }, data: { view: "dashboard.data.view", + }, + taxonomy: { + view: "dashboard.taxonomy.view" } } }; \ No newline at end of file diff --git a/src/constants/TelemetryEvent.ts b/src/constants/TelemetryEvent.ts index 0c6c43cd..4b6bb928 100644 --- a/src/constants/TelemetryEvent.ts +++ b/src/constants/TelemetryEvent.ts @@ -10,6 +10,7 @@ export const TelemetryEvent = { openMediaDashboard: 'openMediaDashboard', openDataDashboard: 'openDataDashboard', openSnippetsDashboard: 'openSnippetsDashboard', + openTaxonomyDashboard: 'openTaxonomyDashboard', closeDashboard: 'closeDashboard', // Other actions @@ -41,4 +42,5 @@ export const TelemetryEvent = { webviewDataView: 'webviewDataView', webviewContentsView: 'webviewContentsView', webviewSnippetsView: 'webviewSnippetsView', + webviewTaxonomyDashboard: 'webviewTaxonomyDashboard', }; \ No newline at end of file diff --git a/src/dashboardWebView/DashboardCommand.ts b/src/dashboardWebView/DashboardCommand.ts index ae738955..2cff6a6f 100644 --- a/src/dashboardWebView/DashboardCommand.ts +++ b/src/dashboardWebView/DashboardCommand.ts @@ -8,4 +8,7 @@ export enum DashboardCommand { mediaUpdate = "mediaUpdate", dataFileEntries = "dataFileEntries", searchReady = "searchReady", + + // Taxonomy dashboard + setTaxonomyData = "setTaxonomyData", } \ No newline at end of file diff --git a/src/dashboardWebView/DashboardMessage.ts b/src/dashboardWebView/DashboardMessage.ts index e9a77851..ccb64e9b 100644 --- a/src/dashboardWebView/DashboardMessage.ts +++ b/src/dashboardWebView/DashboardMessage.ts @@ -41,6 +41,9 @@ export enum DashboardMessage { addSnippet = 'addSnippet', updateSnippet = 'updateSnippet', + // Taxonomy dashboard + getTaxonomyData = 'getTaxonomyData', + // Other getTheme = 'getTheme', updateSetting = 'updateSetting', diff --git a/src/dashboardWebView/components/Dashboard.tsx b/src/dashboardWebView/components/App.tsx similarity index 80% rename from src/dashboardWebView/components/Dashboard.tsx rename to src/dashboardWebView/components/App.tsx index f9cec4e2..e22ebc95 100644 --- a/src/dashboardWebView/components/Dashboard.tsx +++ b/src/dashboardWebView/components/App.tsx @@ -13,12 +13,13 @@ import { Snippets } from './SnippetsView/Snippets'; import { FeatureFlag } from '../../components/features/FeatureFlag'; import { FEATURE_FLAG } from '../../constants'; import { Messenger } from '@estruyf/vscode/dist/client'; +import { TaxonomyView } from './TaxonomyView'; -export interface IDashboardProps { +export interface IAppProps { showWelcome: boolean; } -export const Dashboard: React.FunctionComponent = ({showWelcome}: React.PropsWithChildren) => { +export const App: React.FunctionComponent = ({showWelcome}: React.PropsWithChildren) => { const { loading, pages, settings } = useMessages(); const view = useRecoilValue(DashboardViewSelector); const mode = useRecoilValue(ModeAtom); @@ -64,6 +65,16 @@ export const Dashboard: React.FunctionComponent = ({showWelcome ); } + if (view === NavigationType.Taxonomy) { + return ( + +
+ +
+
+ ); + } + return (
diff --git a/src/dashboardWebView/components/Header/Tabs.tsx b/src/dashboardWebView/components/Header/Tabs.tsx index 0352d167..4b2af0c9 100644 --- a/src/dashboardWebView/components/Header/Tabs.tsx +++ b/src/dashboardWebView/components/Header/Tabs.tsx @@ -1,4 +1,4 @@ -import { DatabaseIcon, PhotographIcon, ScissorsIcon } from '@heroicons/react/outline'; +import { DatabaseIcon, PhotographIcon, ScissorsIcon, TagIcon } from '@heroicons/react/outline'; import * as React from 'react'; import { useRecoilValue } from 'recoil'; import { FeatureFlag } from '../../../components/features/FeatureFlag'; @@ -49,6 +49,15 @@ export const Tabs: React.FunctionComponent = ({ onNavigate }: React. + +
  • + + Taxonomy + +
  • +
    ); }; \ No newline at end of file diff --git a/src/dashboardWebView/components/TaxonomyView/TaxonomyView.tsx b/src/dashboardWebView/components/TaxonomyView/TaxonomyView.tsx new file mode 100644 index 00000000..f238a8ce --- /dev/null +++ b/src/dashboardWebView/components/TaxonomyView/TaxonomyView.tsx @@ -0,0 +1,44 @@ +import { EventData } from '@estruyf/vscode'; +import { Messenger } from '@estruyf/vscode/dist/client'; +import * as React from 'react'; +import { useEffect } from 'react'; +import { TelemetryEvent } from '../../../constants'; +import { DashboardCommand } from '../../DashboardCommand'; +import { DashboardMessage } from '../../DashboardMessage'; +import { Page } from '../../models'; +import { PageLayout } from '../Layout/PageLayout'; + +export interface ITaxonomyViewProps { + pages: Page[]; +} + +export const TaxonomyView: React.FunctionComponent = ({ pages }: React.PropsWithChildren) => { + + const messageListener = (message: MessageEvent>) => { + const { command, data } = message.data; + + if (command === DashboardCommand.setTaxonomyData) { + console.log('TaxonomyView: setTaxonomyData', data); + } + }; + + useEffect(() => { + Messenger.send(DashboardMessage.sendTelemetry, { + event: TelemetryEvent.webviewTaxonomyDashboard + }); + + Messenger.send(DashboardMessage.getTaxonomyData); + + Messenger.listen(messageListener); + + return () => { + Messenger.unlisten(messageListener); + } + }, []); + + return ( + + {pages.length} + + ); +}; \ No newline at end of file diff --git a/src/dashboardWebView/components/TaxonomyView/index.ts b/src/dashboardWebView/components/TaxonomyView/index.ts new file mode 100644 index 00000000..08a45da6 --- /dev/null +++ b/src/dashboardWebView/components/TaxonomyView/index.ts @@ -0,0 +1 @@ +export * from './TaxonomyView'; diff --git a/src/dashboardWebView/hooks/useMessages.tsx b/src/dashboardWebView/hooks/useMessages.tsx index 32fd1543..7d7c83c5 100644 --- a/src/dashboardWebView/hooks/useMessages.tsx +++ b/src/dashboardWebView/hooks/useMessages.tsx @@ -33,6 +33,8 @@ export default function useMessages() { setView(NavigationType.Contents); } else if (message.data?.type === NavigationType.Data) { setView(NavigationType.Data); + } else if (message.data?.type === NavigationType.Taxonomy) { + setView(NavigationType.Taxonomy); } else if (message.data?.type === NavigationType.Snippets) { setView(NavigationType.Snippets); } diff --git a/src/dashboardWebView/index.tsx b/src/dashboardWebView/index.tsx index 89803e6d..6424e325 100644 --- a/src/dashboardWebView/index.tsx +++ b/src/dashboardWebView/index.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { render } from "react-dom"; import { RecoilRoot } from "recoil"; -import { Dashboard } from "./components/Dashboard"; +import { App } from "./components/App"; import * as Sentry from "@sentry/react"; import { Integrations } from "@sentry/tracing"; import { SENTRY_LINK } from "../constants"; @@ -37,7 +37,11 @@ if (elm) { if (type === "preview") { render(, elm); } else { - render(, elm); + render(( + + + + ), elm); } } diff --git a/src/dashboardWebView/models/NavigationType.ts b/src/dashboardWebView/models/NavigationType.ts index 2fd1da24..79679b0a 100644 --- a/src/dashboardWebView/models/NavigationType.ts +++ b/src/dashboardWebView/models/NavigationType.ts @@ -3,4 +3,5 @@ export enum NavigationType { Media = "media", Data = "data", Snippets = "snippets", + Taxonomy = "taxonomy", } \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 1e935643..381533fd 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -79,6 +79,11 @@ export async function activate(context: vscode.ExtensionContext) { Telemetry.send(TelemetryEvent.openDataDashboard); Dashboard.open({ type: NavigationType.Data }); })); + + subscriptions.push(vscode.commands.registerCommand(COMMAND_NAME.dashboardTaxonomy, (data?: DashboardData) => { + Telemetry.send(TelemetryEvent.openTaxonomyDashboard); + Dashboard.open({ type: NavigationType.Taxonomy }); + })); subscriptions.push(vscode.commands.registerCommand(COMMAND_NAME.dashboardClose, (data?: DashboardData) => { Telemetry.send(TelemetryEvent.closeDashboard); diff --git a/src/listeners/dashboard/TaxonomyListener.ts b/src/listeners/dashboard/TaxonomyListener.ts new file mode 100644 index 00000000..5e502d63 --- /dev/null +++ b/src/listeners/dashboard/TaxonomyListener.ts @@ -0,0 +1,62 @@ +import { join } from "path"; +import { Uri, workspace } from "vscode"; +import { Folders } from "../../commands/Folders"; +import { DEFAULT_FILE_TYPES, SETTING_CONTENT_SUPPORTED_FILETYPES, SETTING_TAXONOMY_CATEGORIES, SETTING_TAXONOMY_CUSTOM, SETTING_TAXONOMY_TAGS } from "../../constants"; +import { DashboardCommand } from "../../dashboardWebView/DashboardCommand"; +import { DashboardMessage } from "../../dashboardWebView/DashboardMessage"; +import { Settings } from "../../helpers"; +import { CustomTaxonomy } from "../../models"; +import { BaseListener } from "./BaseListener"; + + +export class TaxonomyListener extends BaseListener { + + /** + * Process the messages for the dashboard views + * @param msg + */ + public static process(msg: { command: DashboardMessage, data: any }) { + super.process(msg); + + switch(msg.command) { + case DashboardMessage.getTaxonomyData: + this.getData(); + break; + } + } + + private static async getData() { + // Retrieve the tags, categories and custom taxonomy + const taxonomyData = { + tags: Settings.get(SETTING_TAXONOMY_TAGS) || [], + categories: Settings.get(SETTING_TAXONOMY_CATEGORIES) || [], + customTaxonomy: Settings.get(SETTING_TAXONOMY_CUSTOM) || [] + }; + + const supportedFiles = Settings.get(SETTING_CONTENT_SUPPORTED_FILETYPES) || DEFAULT_FILE_TYPES; + const fileExtensions = supportedFiles.map(fileType => `${fileType.startsWith('.') ? '' : '.'}${fileType}`); + + const folders = Folders.get(); + const projectName = Folders.getProjectFolderName(); + + let files: Uri[] = []; + + for (const folder of folders) { + let projectStart = folder.path.split(projectName).pop(); + projectStart = projectStart || ""; + projectStart = projectStart?.replace(/\\/g, '/'); + projectStart = projectStart?.startsWith('/') ? projectStart.substring(1) : projectStart; + + for (const fileExtension of fileExtensions) { + const crntFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', `*${fileExtension}`)); + if (crntFiles && crntFiles.length > 0) { + files = [...files, ...crntFiles]; + } + } + } + + console.log(files) + + this.sendMsg(DashboardCommand.setTaxonomyData, taxonomyData); + } +} \ No newline at end of file diff --git a/src/listeners/dashboard/index.ts b/src/listeners/dashboard/index.ts index dcef562a..a26e99d8 100644 --- a/src/listeners/dashboard/index.ts +++ b/src/listeners/dashboard/index.ts @@ -7,3 +7,4 @@ export * from './PagesListener'; export * from './SettingsListener'; export * from './SnippetListener'; export * from './TelemetryListener'; +export * from './TaxonomyListener';