From 7a702f09a052cbcc4ba331e71db8bb8789689a85 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Mon, 20 Sep 2021 11:23:34 +0200 Subject: [PATCH] Documenation updates and preparations for 4.0.0 release --- .vscode/settings.json | 5 ++ CHANGELOG.md | 4 +- docs/content/changelog/CHANGELOG.md | 3 +- docs/content/docs/commands.md | 6 +++ docs/content/docs/settings.md | 15 ++++-- src/commands/Settings.ts | 10 ++-- src/constants/Extension.ts | 1 + src/explorerView/ExplorerView.ts | 6 +-- src/extension.ts | 10 ++-- src/helpers/Extension.ts | 5 ++ src/helpers/SettingsHelper.ts | 46 ++++++++++++++----- .../components/Fields/ChoiceField.tsx | 4 +- 12 files changed, 86 insertions(+), 29 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8d17a741..e48f7ecb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -49,6 +49,11 @@ "name": "date", "type": "datetime" }, + { + "title": "Last modified date", + "name": "lastmod", + "type": "datetime" + }, { "title": "Article preview", "name": "preview", diff --git a/CHANGELOG.md b/CHANGELOG.md index ad4d3d53..ac9280ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,16 @@ # Change Log -## [3.2.0] - (upcoming release) +## [4.0.0] - (upcoming release) - [#101](https://github.com/estruyf/vscode-front-matter/issues/101): Date picker available on the metadata section - [#102](https://github.com/estruyf/vscode-front-matter/issues/102): Support comma separated arrays in front matter - [#103](https://github.com/estruyf/vscode-front-matter/issues/103): Added title and description field to the metadata section - [#104](https://github.com/estruyf/vscode-front-matter/issues/104): Allow to set images in front matter from the metadata panel section - [#105](https://github.com/estruyf/vscode-front-matter/issues/105): Content Type support with backwards compatibility +- [#106](https://github.com/estruyf/vscode-front-matter/issues/106): Introduction of team level settings for Front Matter - [#107](https://github.com/estruyf/vscode-front-matter/issues/107): Number field support added in content type fields - [#108](https://github.com/estruyf/vscode-front-matter/issues/108): Choice field support added in content type fields +- [#109](https://github.com/estruyf/vscode-front-matter/issues/109): JSON Config script added to automate the JSON schema ## [3.1.0] - 2021-09-10 diff --git a/docs/content/changelog/CHANGELOG.md b/docs/content/changelog/CHANGELOG.md index 2c0385b3..ad4d3d53 100644 --- a/docs/content/changelog/CHANGELOG.md +++ b/docs/content/changelog/CHANGELOG.md @@ -7,7 +7,8 @@ - [#103](https://github.com/estruyf/vscode-front-matter/issues/103): Added title and description field to the metadata section - [#104](https://github.com/estruyf/vscode-front-matter/issues/104): Allow to set images in front matter from the metadata panel section - [#105](https://github.com/estruyf/vscode-front-matter/issues/105): Content Type support with backwards compatibility -- [#107](https://github.com/estruyf/vscode-front-matter/issues/107): Number field support added in content types fields +- [#107](https://github.com/estruyf/vscode-front-matter/issues/107): Number field support added in content type fields +- [#108](https://github.com/estruyf/vscode-front-matter/issues/108): Choice field support added in content type fields ## [3.1.0] - 2021-09-10 diff --git a/docs/content/docs/commands.md b/docs/content/docs/commands.md index f353996d..2ccbbeff 100644 --- a/docs/content/docs/commands.md +++ b/docs/content/docs/commands.md @@ -123,6 +123,12 @@ Open the site preview of your article in VS Code. ID: `frontMatter.preview` +## Promote settings from local to team level + +This command allows you to promote all local settings from within your `.vscode/settings.json` file to be promoted to the projects team configuration `frontmatter.json` file. + +ID: `frontMatter.promoteSettings` + ## Removed commands ### Set current date diff --git a/docs/content/docs/settings.md b/docs/content/docs/settings.md index a3923e6e..94ff8a63 100644 --- a/docs/content/docs/settings.md +++ b/docs/content/docs/settings.md @@ -11,11 +11,20 @@ weight: 7 ## Overview -Most of the actions are configurable to your needs. In this part of the documentation all settings are explained. +Most of Front Matter is configurable to your needs. In this part of the documentation all settings are explained. -## Where is the data stored? +## Team settings and local settings -The extension stores all settings in the VS Code user settings file located in your project under `.vscode/settings.json`. + +Since version 4 of Front Matter, Team settings got introduced. Teams settings allow you to have all settings on the project/solution level. You will be able to override them on user/local level (`.vscode/settings.json`). + +The purpose of team settings is to share the global configuration of your CMS configuration. This way, your whole team can use the same tags/categories but apply their changes locally. + +As you do not typically share your `.vscode/settings.json` configuration, we went for a `frontmatter.json` file on the root of your project/solution. The settings you provide in this JSON file are the same as you can configure on a local level. This allows you to easily copy, move settings from team to local level and vice versa. + +## Migrate local settings to team settings + +To allow you to easily migrate already defined settings, you can run the `Promote settings from local to team level` command. ## Available settings diff --git a/src/commands/Settings.ts b/src/commands/Settings.ts index e6e51e62..4fbd5043 100644 --- a/src/commands/Settings.ts +++ b/src/commands/Settings.ts @@ -23,7 +23,7 @@ export class Settings { if (newOption) { const configSetting = type === TaxonomyType.Tag ? SETTING_TAXONOMY_TAGS : SETTING_TAXONOMY_CATEGORIES; - let options = SettingsHelper.get(configSetting) as string[]; + let options = SettingsHelper.get(configSetting, true) as string[]; if (!options) { options = []; } @@ -125,22 +125,22 @@ export class Settings { } // Retrieve the currently known tags, and add the new ones - let crntTags: string[] = SettingsHelper.get(SETTING_TAXONOMY_TAGS) as string[]; + let crntTags: string[] = SettingsHelper.get(SETTING_TAXONOMY_TAGS, true) as string[]; if (!crntTags) { crntTags = []; } crntTags = [...crntTags, ...tags]; // Update the tags and filter out the duplicates crntTags = [...new Set(crntTags)]; crntTags = crntTags.sort().filter(t => !!t); - await SettingsHelper.update(SETTING_TAXONOMY_TAGS, crntTags); + await SettingsHelper.update(SETTING_TAXONOMY_TAGS, crntTags, true); // Retrieve the currently known tags, and add the new ones - let crntCategories: string[] = SettingsHelper.get(SETTING_TAXONOMY_CATEGORIES) as string[]; + let crntCategories: string[] = SettingsHelper.get(SETTING_TAXONOMY_CATEGORIES, true) as string[]; if (!crntCategories) { crntCategories = []; } crntCategories = [...crntCategories, ...categories]; // Update the categories and filter out the duplicates crntCategories = [...new Set(crntCategories)]; crntCategories = crntCategories.sort().filter(c => !!c); - await SettingsHelper.update(SETTING_TAXONOMY_CATEGORIES, crntCategories); + await SettingsHelper.update(SETTING_TAXONOMY_CATEGORIES, crntCategories, true); // Done Notifications.info(`Export completed. Tags: ${crntTags.length} - Categories: ${crntCategories.length}.`); diff --git a/src/constants/Extension.ts b/src/constants/Extension.ts index e5b5d0ef..0b84b17b 100644 --- a/src/constants/Extension.ts +++ b/src/constants/Extension.ts @@ -29,4 +29,5 @@ export const COMMAND_NAME = { collapseSections: getCommandName("collapseSections"), preview: getCommandName("preview"), dashboard: getCommandName("dashboard"), + promote: getCommandName("promoteSettings"), }; \ No newline at end of file diff --git a/src/explorerView/ExplorerView.ts b/src/explorerView/ExplorerView.ts index 596bf3fb..30ecfa11 100644 --- a/src/explorerView/ExplorerView.ts +++ b/src/explorerView/ExplorerView.ts @@ -397,8 +397,8 @@ export class ExplorerView implements WebviewViewProvider, Disposable { date: { format: Settings.get(SETTING_DATE_FORMAT) }, - tags: Settings.get(SETTING_TAXONOMY_TAGS) || [], - categories: Settings.get(SETTING_TAXONOMY_CATEGORIES) || [], + tags: Settings.get(SETTING_TAXONOMY_TAGS, true) || [], + categories: Settings.get(SETTING_TAXONOMY_CATEGORIES, true) || [], freeform: Settings.get(SETTING_PANEL_FREEFORM), scripts: Settings.get(SETTING_CUSTOM_SCRIPTS), isInitialized: await Template.isInitialized(), @@ -462,7 +462,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable { */ private async addTags(tagType: TagType, value: string) { if (value) { - let options = tagType === TagType.tags ? Settings.get(SETTING_TAXONOMY_TAGS) : Settings.get(SETTING_TAXONOMY_CATEGORIES); + let options = tagType === TagType.tags ? Settings.get(SETTING_TAXONOMY_TAGS, true) : Settings.get(SETTING_TAXONOMY_CATEGORIES, true); if (!options) { options = []; diff --git a/src/extension.ts b/src/extension.ts index 8986dbdc..4056c53b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -24,14 +24,15 @@ const mdSelector: vscode.DocumentSelector = { language: 'markdown', scheme: 'fil export async function activate(context: vscode.ExtensionContext) { const { subscriptions, extensionUri, extensionPath } = context; - SettingsHelper.init(); const extension = Extension.getInstance(context); if (!extension.checkIfExtensionCanRun()) { return undefined; } - - extension.migrateSettings() + + SettingsHelper.init(); + extension.migrateSettings(); + collection = vscode.languages.createDiagnosticCollection('frontMatter'); @@ -116,6 +117,9 @@ export async function activate(context: vscode.ExtensionContext) { } }); + // Settings promotion command + subscriptions.push(vscode.commands.registerCommand(COMMAND_NAME.promote, () => { console.log('promote'); SettingsHelper.promote(); })); + // Collapse all sections in the webview const collapseAll = vscode.commands.registerCommand(COMMAND_NAME.collapseSections, () => { ExplorerView.getInstance()?.collapseAll(); diff --git a/src/helpers/Extension.ts b/src/helpers/Extension.ts index ffb9cfab..3c800f11 100644 --- a/src/helpers/Extension.ts +++ b/src/helpers/Extension.ts @@ -152,4 +152,9 @@ export class Extension { return true; } + + public get packageJson() { + const frontMatter = extensions.getExtension(this.isBetaVersion() ? EXTENSION_BETA_ID : EXTENSION_ID)!; + return frontMatter.packageJSON; + } } \ No newline at end of file diff --git a/src/helpers/SettingsHelper.ts b/src/helpers/SettingsHelper.ts index bca95304..cda6a009 100644 --- a/src/helpers/SettingsHelper.ts +++ b/src/helpers/SettingsHelper.ts @@ -11,10 +11,7 @@ export class Settings { private static config: vscode.WorkspaceConfiguration; private static globalFile = "frontmatter.json"; private static globalConfig: any; - private static initialConfig = { - "$schema": `https://${Extension.getInstance().isBetaVersion() ? `beta.` : ``}frontmatter.codes/frontmatter.schema.json` - }; - + public static init() { const fmConfig = Settings.projectConfigPath; if (fmConfig && existsSync(fmConfig)) { @@ -67,7 +64,7 @@ export class Settings { /** * Retrieve a setting from global and local config */ - public static get(name: string): T | undefined{ + public static get(name: string, merging: boolean = false): T | undefined{ const configInpection = Settings.config.inspect(name); let setting = undefined; @@ -79,7 +76,11 @@ export class Settings { // Local overrides global if (configInpection && typeof configInpection.workspaceValue !== "undefined") { - setting = configInpection.workspaceValue; + if (merging && setting && typeof setting === "object") { + setting = Object.assign([], setting, configInpection.workspaceValue); + } else { + setting = configInpection.workspaceValue; + } } if (setting === undefined) { @@ -119,10 +120,15 @@ export class Settings { */ public static createTeamSettings() { const wsFolder = Folders.getWorkspaceFolder(); + + const initialConfig = { + "$schema": `https://${Extension.getInstance().isBetaVersion() ? `beta.` : ``}frontmatter.codes/frontmatter.schema.json` + }; + if (wsFolder) { const configPath = join(wsFolder.fsPath, Settings.globalFile); if (!existsSync(configPath)) { - writeFileSync(configPath, JSON.stringify(Settings.initialConfig, null, 2), 'utf8'); + writeFileSync(configPath, JSON.stringify(initialConfig, null, 2), 'utf8'); } } } @@ -133,10 +139,9 @@ export class Settings { * @param type */ public static getTaxonomy(type: TaxonomyType): string[] { - const config = vscode.workspace.getConfiguration(CONFIG_KEY); // Add all the known options to the selection list const configSetting = type === TaxonomyType.Tag ? SETTING_TAXONOMY_TAGS : SETTING_TAXONOMY_CATEGORIES; - const crntOptions = config.get(configSetting) as string[]; + const crntOptions = Settings.get(configSetting, true) as string[]; if (crntOptions && crntOptions.length > 0) { return crntOptions; } @@ -151,13 +156,32 @@ export class Settings { * @param options */ public static async updateTaxonomy(type: TaxonomyType, options: string[]) { - const config = vscode.workspace.getConfiguration(CONFIG_KEY); const configSetting = type === TaxonomyType.Tag ? SETTING_TAXONOMY_TAGS : SETTING_TAXONOMY_CATEGORIES; options = [...new Set(options)]; options = options.sort().filter(o => !!o); - await config.update(configSetting, options); + await Settings.update(configSetting, options, true); } + /** + * Promote settings from local to team level + */ + public static async promote() { + const pkg = Extension.getInstance().packageJson; + if (pkg?.contributes?.configuration?.properties) { + const settingNames = Object.keys(pkg.contributes.configuration.properties); + + for (const name of settingNames) { + const setting = Settings.config.inspect(name.replace(`frontMatter.`, '')); + + if (setting && typeof setting.workspaceValue !== "undefined") { + await Settings.update(name, setting.workspaceValue, true); + await Settings.update(name.replace(`frontMatter.`, ''), undefined); + } + } + } + } + + /** * Check if its the project config * @param filePath diff --git a/src/panelWebView/components/Fields/ChoiceField.tsx b/src/panelWebView/components/Fields/ChoiceField.tsx index d25bf011..85bd3a6e 100644 --- a/src/panelWebView/components/Fields/ChoiceField.tsx +++ b/src/panelWebView/components/Fields/ChoiceField.tsx @@ -17,7 +17,7 @@ export const ChoiceField: React.FunctionComponent = ({label, onChange(txtValue); }; - const containsSelected = selected && choices.indexOf(selected) !== -1; + const containsSelected = crntSelected && choices.indexOf(crntSelected) !== -1; return (
@@ -34,7 +34,7 @@ export const ChoiceField: React.FunctionComponent = ({label, onChange={(e) => onValueChange(e.currentTarget.value)}> { !containsSelected && } {choices.map((choice, index) => ( - + ))}