diff --git a/package.json b/package.json index a75d89fa..25496260 100644 --- a/package.json +++ b/package.json @@ -351,7 +351,7 @@ }, "file": { "type": "string", - "description": "Path to the file to load. Only JSON files are supported." + "description": "Path to the file to load. Only JSON or YAML files are supported." }, "fileType": { "type": "string", @@ -378,8 +378,59 @@ "required": [ "id", "title", - "file", - "labelField" + "file" + ], + "anyOf": [ + { + "required": [ + "schema" + ] + }, + { + "required": [ + "type" + ] + } + ] + }, + "scope": "Data" + }, + "frontMatter.data.folders": { + "type": "array", + "default": [], + "markdownDescription": "Specify the data files you want to use for your website. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.data.files)", + "items": { + "type": "object", + "default": {}, + "properties": { + "id": { + "type": "string", + "description": "Your unique ID you want to use for your data folder." + }, + "labelField": { + "type": "string", + "description": "The field you want to use as label for your data entries." + }, + "path": { + "type": "string", + "description": "Path to the folder to load files." + }, + "schema": { + "type": "object", + "default": {}, + "description": "The JSON schema for your data which will be used to render the data form.", + "additionalProperties": true + }, + "type": { + "type": "string", + "default": "content", + "description": "If you are using data types, you can specify your type ID." + } + }, + "additionalProperties": false, + "required": [ + "id", + "path" ], "anyOf": [ { diff --git a/src/constants/settings.ts b/src/constants/settings.ts index 45c612e4..a17cbcb1 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -56,6 +56,7 @@ export const SETTINGS_DASHBOARD_OPENONSTART = "dashboard.openOnStart"; export const SETTINGS_DASHBOARD_MEDIA_SNIPPET = "dashboard.mediaSnippet"; export const SETTINGS_DATA_FILES = "data.files"; +export const SETTINGS_DATA_FOLDERS = "data.folders"; export const SETTINGS_DATA_TYPES = "data.types"; export const SETTINGS_FRAMEWORK_ID = "framework.id"; diff --git a/src/helpers/DashboardSettings.ts b/src/helpers/DashboardSettings.ts index ccd3a030..f6f14923 100644 --- a/src/helpers/DashboardSettings.ts +++ b/src/helpers/DashboardSettings.ts @@ -1,9 +1,12 @@ +import { basename, join } from "path"; +import { workspace } from "vscode"; import { Folders } from "../commands/Folders"; import { Template } from "../commands/Template"; -import { ExtensionState, SETTINGS_CONTENT_DRAFT_FIELD, SETTINGS_CONTENT_SORTING, SETTINGS_CONTENT_SORTING_DEFAULT, SETTINGS_CONTENT_STATIC_FOLDER, SETTINGS_DASHBOARD_MEDIA_SNIPPET, SETTINGS_DASHBOARD_OPENONSTART, SETTINGS_DATA_FILES, SETTINGS_DATA_TYPES, SETTINGS_FRAMEWORK_ID, SETTINGS_MEDIA_SORTING_DEFAULT, SETTING_CUSTOM_SCRIPTS, SETTING_TAXONOMY_CONTENT_TYPES } from "../constants"; +import { ExtensionState, SETTINGS_CONTENT_DRAFT_FIELD, SETTINGS_CONTENT_SORTING, SETTINGS_CONTENT_SORTING_DEFAULT, SETTINGS_CONTENT_STATIC_FOLDER, SETTINGS_DASHBOARD_MEDIA_SNIPPET, SETTINGS_DASHBOARD_OPENONSTART, SETTINGS_DATA_FILES, SETTINGS_DATA_FOLDERS, SETTINGS_DATA_TYPES, SETTINGS_FRAMEWORK_ID, SETTINGS_MEDIA_SORTING_DEFAULT, SETTING_CUSTOM_SCRIPTS, SETTING_TAXONOMY_CONTENT_TYPES } from "../constants"; import { DashboardViewType, SortingOption, Settings as ISettings } from "../dashboardWebView/models"; import { CustomScript, DraftField, ScriptType, SortingSetting, TaxonomyType } from "../models"; import { DataFile } from "../models/DataFile"; +import { DataFolder } from "../models/DataFolder"; import { DataType } from "../models/DataType"; import { Extension } from "./Extension"; import { FrameworkDetector } from "./FrameworkDetector"; @@ -47,8 +50,56 @@ export class DashboardSettings { selectedFolder: await ext.getState(ExtensionState.SelectedFolder, "workspace") } }, - dataFiles: Settings.get(SETTINGS_DATA_FILES), + dataFiles: await this.getDataFiles(), dataTypes: Settings.get(SETTINGS_DATA_TYPES) } as ISettings } + + /** + * Retrieve all the data files + * @returns + */ + private static async getDataFiles(): Promise { + const wsPath = Folders.getWorkspaceFolder()?.fsPath; + const files = Settings.get(SETTINGS_DATA_FILES); + const folders = Settings.get(SETTINGS_DATA_FOLDERS); + + let clonedFiles = Object.assign([], files); + if (folders) { + for (let folder of folders) { + if (!folder.path) { + continue; + } + + const folderPath = Folders.getAbsFilePath(folder.path); + if (!folderPath) { + continue; + } + + let dataFolderPath = join(folderPath.replace((wsPath || ''), '')); + if (dataFolderPath.startsWith('/')) { + dataFolderPath = dataFolderPath.substring(1); + } + + const dataJsonFiles = await workspace.findFiles(join(dataFolderPath, '*.json')); + const dataYmlFiles = await workspace.findFiles(join(dataFolderPath, '*.yml')); + const dataYamlFiles = await workspace.findFiles(join(dataFolderPath, '*.yaml')); + + const dataFiles = [...dataJsonFiles, ...dataYmlFiles, ...dataYamlFiles]; + for (let dataFile of dataFiles) { + clonedFiles.push({ + id: basename(dataFile.fsPath), + title: basename(dataFile.fsPath), + file: dataFile.fsPath, + fileType: dataFile.fsPath.endsWith('.json') ? 'json' : 'yaml', + labelField: folder.labelField, + schema: folder.schema, + type: folder.type + } as DataFile) + } + } + } + + return clonedFiles; + } } \ No newline at end of file diff --git a/src/models/DataFolder.ts b/src/models/DataFolder.ts new file mode 100644 index 00000000..20337ed2 --- /dev/null +++ b/src/models/DataFolder.ts @@ -0,0 +1,9 @@ + + +export interface DataFolder { + id: string; + path: string; + labelField: string; + schema?: any; + type?: string; +} \ No newline at end of file