mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-03-28 17:42:40 +01:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
301814bcdd |
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@@ -10,9 +10,7 @@
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}", "--disable-extension=eliostruyf.vscode-front-matter"
|
||||
],
|
||||
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
|
||||
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
|
||||
"preLaunchTask": "npm: build:ext"
|
||||
},
|
||||
@@ -21,9 +19,7 @@
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}", "--disable-extension=eliostruyf.vscode-front-matter"
|
||||
],
|
||||
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
|
||||
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
|
||||
}
|
||||
]
|
||||
|
||||
10
.vscode/settings.json
vendored
10
.vscode/settings.json
vendored
@@ -1,15 +1,5 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"commitHelper.messages": [
|
||||
{
|
||||
"type": "👨💻 apps",
|
||||
"values": ["#search", "#profile"]
|
||||
},
|
||||
{
|
||||
"type": "⚙️ tasks",
|
||||
"values": ["#build", "#deploy", "#skip"]
|
||||
}
|
||||
],
|
||||
"workbench.colorCustomizations": {
|
||||
"titleBar.activeBackground": "#15c2cb",
|
||||
"titleBar.inactiveBackground": "#44ffd299",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Change Log
|
||||
|
||||
## [10.2.0] - 2024-06-12 - [Release notes](https://beta.frontmatter.codes/updates/v10.2.0)
|
||||
## [10.2.0] - 2024-xx-xx
|
||||
|
||||
### ✨ New features
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
### 🎨 Enhancements
|
||||
|
||||
- [#441](https://github.com/estruyf/vscode-front-matter/issues/441): Show input descriptions for snippet and data forms
|
||||
- [#442](https://github.com/estruyf/vscode-front-matter/issues/442): Hide sidebar on data view when data file is selected + show dropdown of data files
|
||||
- [#442](https://github.com/estruyf/vscode-front-matter/issues/442): Hide sidebar on data view when data file is selecte + show dropdown of data files
|
||||
- [#788](https://github.com/estruyf/vscode-front-matter/issues/788): Show a warning on setting update when it exists in an extended configuration
|
||||
- [#798](https://github.com/estruyf/vscode-front-matter/issues/798): Changed dialog to slide-over for the snippet forms
|
||||
- [#799](https://github.com/estruyf/vscode-front-matter/issues/799): Added `frontMatter.logging` setting to define the logging output. Options are `info`, `warn`, `error`, and `verbose`. The default is `info`.
|
||||
- [#799](https://github.com/estruyf/vscode-front-matter/issues/799): Added `frontMatter.logging` setting to define the logging output. Options are `info`, `warn`, `error`, and `verbose`. Default is `info`.
|
||||
- [#800](https://github.com/estruyf/vscode-front-matter/issues/800): Add colors for the Front Matter CMS output
|
||||
- [#808](https://github.com/estruyf/vscode-front-matter/issues/808): Add support to generate field groups and `block` fields in content type generation
|
||||
- [#810](https://github.com/estruyf/vscode-front-matter/issues/810): Update the tab title based on the view
|
||||
- [#811](https://github.com/estruyf/vscode-front-matter/issues/811): Added `panel.gitActions` view mode option to hide the Git actions in the panel
|
||||
- [#812](https://github.com/estruyf/vscode-front-matter/issues/812): Added the `{{locale}}` placeholder, which can be used in the `previewPath` property
|
||||
- [#812](https://github.com/estruyf/vscode-front-matter/issues/812): Added the `{{locale}}` placeholder which can be used in the `previewPath` property
|
||||
|
||||
### ⚡️ Optimizations
|
||||
|
||||
|
||||
17
assets/icons/frontmatter-short-teal.svg
Normal file
17
assets/icons/frontmatter-short-teal.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1250 1250" style="enable-background:new 0 0 1250 1250;" xml:space="preserve">
|
||||
<path fill="#02aeb7" d="M316,1082.3H119.4V151.2h347.5v218.9H316v135.7h140.5v210.5H316V1082.3z"/>
|
||||
<path fill="#02aeb7" d="M602.2,151.2H704l77.7,379.9c9.5,47.4,18.1,95,26,142.6s15,97.6,21.4,149.8c0.7-6.8,1.3-12.1,1.7-16
|
||||
c0.2-2.7,0.6-5.5,1.1-8.2l16.6-106.7l14.9-101.3l13.2-66.9l69.2-373.3h102.9l81.2,931.1h-113.6l-19.9-316c-0.8-16.1-1.4-29.9-2-41.6
|
||||
c-0.6-11.7-0.9-21.3-0.9-29L988.3,571l-2.8-114.6c0-0.8,0-2.5-0.3-5.1s-0.5-6.1-0.9-10.6l-2.8,18.7c-3,22.1-5.8,41.4-8.3,57.9
|
||||
s-4.7,30.3-6.6,41.6l-15.1,84.9l-5.7,32l-74.3,406.4h-80.1l-69.7-351c-9.5-46.2-17.9-93.1-25.4-140.8s-14.2-97.6-20.3-149.9
|
||||
l-34.3,641.6H529.6L602.2,151.2z"/>
|
||||
<rect x="119.4" y="0.1" fill="#02aeb7" width="184" height="64.7"/>
|
||||
<rect x="395.7" y="0.1" fill="#02aeb7" width="184" height="64.7"/>
|
||||
<rect x="675.3" y="0.1" fill="#02aeb7" width="184" height="64.7"/>
|
||||
<rect x="119.4" y="1184.7" fill="#02aeb7" width="184" height="64.7"/>
|
||||
<rect x="395.7" y="1184.7" fill="#02aeb7" width="184" height="64.7"/>
|
||||
<rect x="675.3" y="1184.7" fill="#02aeb7" width="184" height="64.7"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
10
package-lock.json
generated
10
package-lock.json
generated
@@ -33,7 +33,7 @@
|
||||
"@types/react": "17.0.0",
|
||||
"@types/react-datepicker": "^4.8.0",
|
||||
"@types/react-dom": "17.0.0",
|
||||
"@types/vscode": "^1.73.0",
|
||||
"@types/vscode": "^1.90.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||
"@typescript-eslint/parser": "^5.50.0",
|
||||
"@vscode-elements/elements": "^1.2.0",
|
||||
@@ -110,7 +110,7 @@
|
||||
"yawn-yaml": "^1.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.73.0"
|
||||
"vscode": "^1.90.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
@@ -2084,9 +2084,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/vscode": {
|
||||
"version": "1.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.86.0.tgz",
|
||||
"integrity": "sha512-DnIXf2ftWv+9LWOB5OJeIeaLigLHF7fdXF6atfc7X5g2w/wVZBgk0amP7b+ub5xAuW1q7qP5YcFvOcit/DtyCQ==",
|
||||
"version": "1.90.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.90.0.tgz",
|
||||
"integrity": "sha512-oT+ZJL7qHS9Z8bs0+WKf/kQ27qWYR3trsXpq46YDjFqBsMLG4ygGGjPaJ2tyrH0wJzjOEmDyg9PDJBBhWg9pkQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/vscode-webview": {
|
||||
|
||||
24
package.json
24
package.json
@@ -26,10 +26,13 @@
|
||||
},
|
||||
"qna": "https://github.com/estruyf/vscode-front-matter/discussions",
|
||||
"engines": {
|
||||
"vscode": "^1.73.0"
|
||||
"vscode": "^1.90.0"
|
||||
},
|
||||
"l10n": "./l10n",
|
||||
"categories": [
|
||||
"AI",
|
||||
"Chat",
|
||||
"Visualization",
|
||||
"Other"
|
||||
],
|
||||
"keywords": [
|
||||
@@ -69,6 +72,21 @@
|
||||
"**/.frontmatter/config/*.json": "jsonc"
|
||||
}
|
||||
},
|
||||
"chatParticipants": [{
|
||||
"id": "frontMatter.chat",
|
||||
"name": "fm",
|
||||
"fullName": "Front Matter",
|
||||
"description": "Front Matter CMS chat",
|
||||
"isSticky": true,
|
||||
"commands": [{
|
||||
"name": "docs",
|
||||
"description": "Ask a question about Front Matter CMS and we will try to help you out."
|
||||
}, {
|
||||
"name": "create",
|
||||
"description": "Create a new Front Matter CMS project.",
|
||||
"isSticky": true
|
||||
}]
|
||||
}],
|
||||
"keybindings": [{
|
||||
"command": "frontMatter.dashboard",
|
||||
"key": "alt+d"
|
||||
@@ -1176,7 +1194,7 @@
|
||||
"scope": "Site preview"
|
||||
},
|
||||
"frontMatter.preview.trailingSlash": {
|
||||
"type": "boolean",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"markdownDescription": "%setting.frontMatter.preview.trailingSlash.markdownDescription%",
|
||||
"scope": "Site preview"
|
||||
@@ -2768,7 +2786,7 @@
|
||||
"@types/react": "17.0.0",
|
||||
"@types/react-datepicker": "^4.8.0",
|
||||
"@types/react-dom": "17.0.0",
|
||||
"@types/vscode": "^1.73.0",
|
||||
"@types/vscode": "^1.90.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.50.0",
|
||||
"@typescript-eslint/parser": "^5.50.0",
|
||||
"@vscode-elements/elements": "^1.2.0",
|
||||
|
||||
@@ -27,7 +27,6 @@ import { CustomPlaceholder, Field } from '../models';
|
||||
import { format } from 'date-fns';
|
||||
import {
|
||||
ArticleHelper,
|
||||
Logger,
|
||||
Settings,
|
||||
SlugHelper,
|
||||
processArticlePlaceholdersFromData,
|
||||
@@ -134,7 +133,6 @@ export class Article {
|
||||
private static async setLastModifiedDateInner(
|
||||
document: TextDocument
|
||||
): Promise<ParsedFrontMatter | undefined> {
|
||||
Logger.verbose(`Article:setLastModifiedDateInner:Start`);
|
||||
const article = ArticleHelper.getFrontMatterFromDocument(document);
|
||||
|
||||
// Only set the date, if there is already front matter set
|
||||
@@ -144,16 +142,9 @@ export class Article {
|
||||
|
||||
const cloneArticle = Object.assign({}, article);
|
||||
const dateField = await ArticleHelper.getModifiedDateField(article);
|
||||
Logger.verbose(`Article:setLastModifiedDateInner:DateField - ${JSON.stringify(dateField)}`);
|
||||
|
||||
try {
|
||||
const fieldName = dateField?.name || DefaultFields.LastModified;
|
||||
const fieldValue = Article.formatDate(new Date(), dateField?.dateFormat);
|
||||
cloneArticle.data[fieldName] = fieldValue;
|
||||
Logger.verbose(
|
||||
`Article:setLastModifiedDateInner:DateField name - ${fieldName} - value - ${fieldValue}`
|
||||
);
|
||||
Logger.verbose(`Article:setLastModifiedDateInner:End`);
|
||||
cloneArticle.data[fieldName] = Article.formatDate(new Date(), dateField?.dateFormat);
|
||||
return cloneArticle;
|
||||
} catch (e: unknown) {
|
||||
Notifications.error(
|
||||
@@ -380,16 +371,11 @@ export class Article {
|
||||
public static formatDate(dateValue: Date, fieldDateFormat?: string): string {
|
||||
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
|
||||
|
||||
Logger.verbose(`Article:formatDate:Start`);
|
||||
|
||||
if (fieldDateFormat) {
|
||||
Logger.verbose(`Article:formatDate:FieldDateFormat - ${fieldDateFormat}`);
|
||||
return format(dateValue, DateHelper.formatUpdate(fieldDateFormat) as string);
|
||||
} else if (dateFormat && typeof dateFormat === 'string') {
|
||||
Logger.verbose(`Article:formatDate:DateFormat - ${dateFormat}`);
|
||||
return format(dateValue, DateHelper.formatUpdate(dateFormat) as string);
|
||||
} else {
|
||||
Logger.verbose(`Article:formatDate:toISOString - ${dateValue}`);
|
||||
return typeof dateValue.toISOString === 'function'
|
||||
? dateValue.toISOString()
|
||||
: dateValue?.toString();
|
||||
|
||||
@@ -1,14 +1,99 @@
|
||||
import { Telemetry } from './../helpers/Telemetry';
|
||||
import { TelemetryEvent, PreviewCommands, GeneralCommands } from './../constants';
|
||||
import { TelemetryEvent, PreviewCommands, GeneralCommands, WEBSITE_LINKS, COMMAND_NAME } from './../constants';
|
||||
import { join } from 'path';
|
||||
import { commands, Uri, ViewColumn, window } from 'vscode';
|
||||
import {
|
||||
CancellationToken,
|
||||
chat,
|
||||
ChatContext,
|
||||
ChatRequest,
|
||||
ChatResponseStream,
|
||||
commands,
|
||||
LanguageModelChatMessage,
|
||||
lm,
|
||||
Uri,
|
||||
ViewColumn,
|
||||
window
|
||||
} from 'vscode';
|
||||
import { Extension } from '../helpers';
|
||||
import { WebviewHelper } from '@estruyf/vscode';
|
||||
import { getLocalizationFile } from '../utils/getLocalizationFile';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../localization';
|
||||
import { Folders } from '.';
|
||||
|
||||
export class Chatbot {
|
||||
private static company: string;
|
||||
private static chatId: number;
|
||||
|
||||
public static async register() {
|
||||
const fmChat = chat.createChatParticipant('frontMatter.chat', this.handler);
|
||||
fmChat.iconPath = Uri.joinPath(
|
||||
Extension.getInstance().extensionPath,
|
||||
'/assets/icons/frontmatter-short-teal.svg'
|
||||
);
|
||||
}
|
||||
|
||||
private static async handler(
|
||||
request: ChatRequest,
|
||||
context: ChatContext,
|
||||
stream: ChatResponseStream,
|
||||
token: CancellationToken
|
||||
) {
|
||||
const { command, prompt } = request;
|
||||
|
||||
if (command === 'docs' && prompt) {
|
||||
if (!this.chatId || !this.company) {
|
||||
stream.progress('Initializing the Front Matter AI...');
|
||||
|
||||
await this.initChat();
|
||||
}
|
||||
|
||||
if (!this.company || !this.chatId) {
|
||||
this.showAiError(stream);
|
||||
return;
|
||||
}
|
||||
|
||||
stream.progress('Fetching information from the docs...');
|
||||
|
||||
const data: {
|
||||
answer: string;
|
||||
answerId: number;
|
||||
sources: string[];
|
||||
} = await this.retrieveDocs(prompt);
|
||||
|
||||
if (!data.answer) {
|
||||
this.showAiError(stream);
|
||||
return;
|
||||
}
|
||||
|
||||
stream.markdown(data.answer);
|
||||
} else if (command === 'create') {
|
||||
stream.progress(`Checking your configuration...`);
|
||||
|
||||
const messages = [LanguageModelChatMessage.User(`You are a kind and helpful assistant named Front Matter AI. You aim to provide support in managing Front Matter CMS and its content. If you don't know the answer to a question, you will guide the user to the documentation (https://frontmatter.codes/docs). You can use the "https://frontmatter.codes/docs" link as a reference. When returning code you will surround it in a MD code block, not HTML.`)];
|
||||
|
||||
messages.push(LanguageModelChatMessage.User(request.prompt));
|
||||
|
||||
const [model] = await lm.selectChatModels({ vendor: 'copilot', family: 'gpt-4' });
|
||||
|
||||
try {
|
||||
const chatResponse = await model.sendRequest(messages, {}, token);
|
||||
for await (const fragment of chatResponse.text) {
|
||||
stream.markdown(fragment);
|
||||
}
|
||||
stream.button({
|
||||
command: COMMAND_NAME.createByContentType,
|
||||
title: 'Create new content',
|
||||
});
|
||||
} catch (err) {
|
||||
this.showAiError(stream);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
stream.markdown('Sorry, I do not understand that command. Check out the [Front Matter CMS](https://frontmatter.codes/docs) documentation for more information.')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the Chatbot in the editor
|
||||
*/
|
||||
@@ -119,4 +204,50 @@ export class Chatbot {
|
||||
|
||||
Telemetry.send(TelemetryEvent.openChatbot);
|
||||
}
|
||||
|
||||
private static async initChat() {
|
||||
const response = await fetch(`${WEBSITE_LINKS.root}/api/ai-init`);
|
||||
|
||||
if (!response.ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!data.company || !data.chatId) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.company = data.company;
|
||||
this.chatId = data.chatId;
|
||||
}
|
||||
|
||||
private static async retrieveDocs(prompt: string) {
|
||||
if (!this.company || !this.chatId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await fetch(`${WEBSITE_LINKS.root}/api/ai-chat`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'accept': '*',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
company: this.company,
|
||||
chatId: this.chatId,
|
||||
question: prompt,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
private static showAiError(stream: ChatResponseStream) {
|
||||
stream.markdown(`Sorry, I am not able to connect to the Front Matter AI service. Please try again later or check out the [Front Matter CMS](https://frontmatter.codes/docs) documentation.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +250,9 @@ export class Preview {
|
||||
// Check if there is a pathname defined on content folder level
|
||||
const folders = await Folders.get();
|
||||
if (folders.length > 0) {
|
||||
for (const folder of folders) {
|
||||
const foldersWithPath = folders.filter((folder) => folder.previewPath);
|
||||
|
||||
for (const folder of foldersWithPath) {
|
||||
const folderPath = parseWinPath(folder.path);
|
||||
if (filePath.startsWith(folderPath)) {
|
||||
if (!selectedFolder || selectedFolder.path.length < folderPath.length) {
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { FEATURE_FLAG } from './Features';
|
||||
|
||||
export const DEFAULT_PANEL_FEATURE_FLAGS = Object.values(FEATURE_FLAG.panel).filter(
|
||||
(v) => v !== FEATURE_FLAG.panel.globalSettings
|
||||
);
|
||||
|
||||
export const DEFAULT_DASHBOARD_FEATURE_FLAGS = [
|
||||
FEATURE_FLAG.dashboard.data.view,
|
||||
FEATURE_FLAG.dashboard.taxonomy.view,
|
||||
FEATURE_FLAG.dashboard.snippets.view,
|
||||
FEATURE_FLAG.dashboard.snippets.manage
|
||||
];
|
||||
@@ -9,7 +9,6 @@ import { Tab } from './Tab';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../../localization';
|
||||
import { PageIcon } from '../../../panelWebView/components/Icons';
|
||||
import { DEFAULT_DASHBOARD_FEATURE_FLAGS } from '../../../constants/DefaultFeatureFlags';
|
||||
|
||||
export interface ITabsProps {
|
||||
onNavigate: (navigationType: NavigationType) => void;
|
||||
@@ -20,6 +19,12 @@ export const Tabs: React.FunctionComponent<ITabsProps> = ({
|
||||
}: React.PropsWithChildren<ITabsProps>) => {
|
||||
const mode = useRecoilValue(ModeAtom);
|
||||
|
||||
const allDashboardVIews = [
|
||||
FEATURE_FLAG.dashboard.snippets.view,
|
||||
FEATURE_FLAG.dashboard.data.view,
|
||||
FEATURE_FLAG.dashboard.taxonomy.view
|
||||
];
|
||||
|
||||
return (
|
||||
<ul
|
||||
className="flex items-center justify-start h-full space-x-4"
|
||||
@@ -38,7 +43,7 @@ export const Tabs: React.FunctionComponent<ITabsProps> = ({
|
||||
<span>{l10n.t(LocalizationKey.dashboardHeaderTabsMedia)}</span>
|
||||
</Tab>
|
||||
</li>
|
||||
<FeatureFlag features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS} flag={FEATURE_FLAG.dashboard.snippets.view}>
|
||||
<FeatureFlag features={mode?.features || [...allDashboardVIews]} flag={FEATURE_FLAG.dashboard.snippets.view}>
|
||||
<li role="presentation">
|
||||
<Tab navigationType={NavigationType.Snippets} onNavigate={onNavigate}>
|
||||
<ScissorsIcon className={`h-4 w-auto mr-2`} />
|
||||
@@ -46,7 +51,7 @@ export const Tabs: React.FunctionComponent<ITabsProps> = ({
|
||||
</Tab>
|
||||
</li>
|
||||
</FeatureFlag>
|
||||
<FeatureFlag features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS} flag={FEATURE_FLAG.dashboard.data.view}>
|
||||
<FeatureFlag features={mode?.features || [...allDashboardVIews]} flag={FEATURE_FLAG.dashboard.data.view}>
|
||||
<li role="presentation">
|
||||
<Tab navigationType={NavigationType.Data} onNavigate={onNavigate}>
|
||||
<CircleStackIcon className={`h-4 w-auto mr-2`} />
|
||||
@@ -54,7 +59,7 @@ export const Tabs: React.FunctionComponent<ITabsProps> = ({
|
||||
</Tab>
|
||||
</li>
|
||||
</FeatureFlag>
|
||||
<FeatureFlag features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS} flag={FEATURE_FLAG.dashboard.taxonomy.view}>
|
||||
<FeatureFlag features={mode?.features || [...allDashboardVIews]} flag={FEATURE_FLAG.dashboard.taxonomy.view}>
|
||||
<li role="presentation">
|
||||
<Tab navigationType={NavigationType.Taxonomy} onNavigate={onNavigate}>
|
||||
<TagIcon className={`h-4 w-auto mr-2`} />
|
||||
|
||||
@@ -19,7 +19,6 @@ import { LocalizationKey } from '../../../localization';
|
||||
import { FooterActions } from './FooterActions';
|
||||
import { ItemMenu } from './ItemMenu';
|
||||
import { SlideOver } from '../Modals/SlideOver';
|
||||
import { DEFAULT_DASHBOARD_FEATURE_FLAGS } from '../../../constants/DefaultFeatureFlags';
|
||||
|
||||
export interface IItemProps {
|
||||
snippetKey: string;
|
||||
@@ -164,7 +163,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({
|
||||
</h2>
|
||||
|
||||
<FeatureFlag
|
||||
features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS}
|
||||
features={mode?.features || []}
|
||||
flag={FEATURE_FLAG.dashboard.snippets.manage}
|
||||
alternative={
|
||||
<ItemMenu
|
||||
@@ -191,7 +190,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({
|
||||
</div>
|
||||
|
||||
<FeatureFlag
|
||||
features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS}
|
||||
features={mode?.features || []}
|
||||
flag={FEATURE_FLAG.dashboard.snippets.manage}
|
||||
alternative={
|
||||
<FooterActions
|
||||
|
||||
@@ -18,7 +18,6 @@ import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../../localization';
|
||||
import { List } from '../Media/List';
|
||||
import { SlideOver } from '../Modals/SlideOver';
|
||||
import { DEFAULT_DASHBOARD_FEATURE_FLAGS } from '../../../constants/DefaultFeatureFlags';
|
||||
|
||||
export interface ISnippetsProps { }
|
||||
|
||||
@@ -97,9 +96,7 @@ export const Snippets: React.FunctionComponent<ISnippetsProps> = (
|
||||
return (
|
||||
<PageLayout
|
||||
header={
|
||||
<FeatureFlag
|
||||
features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS}
|
||||
flag={FEATURE_FLAG.dashboard.snippets.manage}>
|
||||
<FeatureFlag features={mode?.features || []} flag={FEATURE_FLAG.dashboard.snippets.manage}>
|
||||
<div
|
||||
className={`py-3 px-4 flex items-center justify-between border-b border-[var(--frontmatter-border)]`}
|
||||
aria-label={l10n.t(LocalizationKey.dashboardSnippetsViewSnippetsAriaLabel)}
|
||||
|
||||
@@ -241,6 +241,9 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
// Cache commands
|
||||
Cache.registerCommands();
|
||||
|
||||
// GitHub Copilot integration
|
||||
Chatbot.register();
|
||||
|
||||
// Subscribe all commands
|
||||
subscriptions.push(insertTags, PanelView, insertCategories, collapseAll, fmStatusBarItem);
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ export class PagesListener extends BaseListener {
|
||||
// Optimize the list of recently changed files
|
||||
DataListener.getFoldersAndFiles(doc.uri);
|
||||
// Trigger the metadata update
|
||||
this.watcherExec(doc.uri, 'save');
|
||||
this.watcherExec(doc.uri);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -103,9 +103,9 @@ export class PagesListener extends BaseListener {
|
||||
false,
|
||||
false
|
||||
);
|
||||
watcher.onDidCreate(async (uri: Uri) => this.watcherExec(uri, 'create'));
|
||||
watcher.onDidChange(async (uri: Uri) => this.watcherExec(uri, 'change'));
|
||||
watcher.onDidDelete(async (uri: Uri) => this.watcherExec(uri, 'delete'));
|
||||
watcher.onDidCreate(async (uri: Uri) => this.watcherExec(uri));
|
||||
watcher.onDidChange(async (uri: Uri) => this.watcherExec(uri));
|
||||
watcher.onDidDelete(async (uri: Uri) => this.watcherExec(uri));
|
||||
this.watchers[folderUri.fsPath] = watcher;
|
||||
}
|
||||
}
|
||||
@@ -162,10 +162,10 @@ export class PagesListener extends BaseListener {
|
||||
* Watcher for processing page updates
|
||||
* @param file
|
||||
*/
|
||||
private static async watcherExec(file: Uri, type?: 'create' | 'change' | 'delete' | 'save') {
|
||||
private static async watcherExec(file: Uri) {
|
||||
const progressFile = async (file: Uri) => {
|
||||
const ext = Extension.getInstance();
|
||||
Logger.info(`File watcher execution for (${type}): ${file.fsPath}`);
|
||||
Logger.info(`File watcher execution for: ${file.fsPath}`);
|
||||
|
||||
const pageIdx = this.lastPages.findIndex((p) => p.fmFilePath === file.fsPath);
|
||||
if (pageIdx !== -1) {
|
||||
|
||||
@@ -17,7 +17,6 @@ import { usePrevious } from './hooks/usePrevious';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../localization';
|
||||
import { InitializeAction } from './components/InitializeAction';
|
||||
import { DEFAULT_PANEL_FEATURE_FLAGS } from '../constants/DefaultFeatureFlags';
|
||||
|
||||
export interface IViewPanelProps { }
|
||||
|
||||
@@ -38,6 +37,10 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (
|
||||
const prevMediaSelection = usePrevious(mediaSelecting);
|
||||
const [scrollY, setScrollY] = useState(0);
|
||||
|
||||
const allPanelValues = useMemo(() => {
|
||||
return Object.values(FEATURE_FLAG.panel).filter(v => v !== FEATURE_FLAG.panel.globalSettings)
|
||||
}, [FEATURE_FLAG.panel]);
|
||||
|
||||
const scollListener = useCallback((e: Event) => {
|
||||
if (!mediaSelecting) {
|
||||
setScrollY(window.scrollY);
|
||||
@@ -45,7 +48,7 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (
|
||||
}, [mediaSelecting]);
|
||||
|
||||
const isSomethingShown = useMemo(() => {
|
||||
const panelModeValues = (mode?.features || DEFAULT_PANEL_FEATURE_FLAGS).filter(v => v.startsWith('panel.'));
|
||||
const panelModeValues = (mode?.features || [...allPanelValues]).filter(v => v.startsWith('panel.'));
|
||||
|
||||
if (panelModeValues.length === 0) {
|
||||
return false;
|
||||
@@ -122,19 +125,19 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (
|
||||
<InitializeAction settings={settings} />
|
||||
|
||||
<div className={`ext_actions`}>
|
||||
<FeatureFlag features={mode?.features || DEFAULT_PANEL_FEATURE_FLAGS} flag={FEATURE_FLAG.panel.gitActions}>
|
||||
<FeatureFlag features={mode?.features || [...allPanelValues]} flag={FEATURE_FLAG.panel.gitActions}>
|
||||
<GitAction settings={settings} />
|
||||
</FeatureFlag>
|
||||
|
||||
{!loading && (<CustomView metadata={metadata} />)}
|
||||
|
||||
<FeatureFlag features={mode?.features || DEFAULT_PANEL_FEATURE_FLAGS} flag={FEATURE_FLAG.panel.globalSettings}>
|
||||
<FeatureFlag features={mode?.features || [...allPanelValues]} flag={FEATURE_FLAG.panel.globalSettings}>
|
||||
<GlobalSettings settings={settings} isBase={!metadata} />
|
||||
</FeatureFlag>
|
||||
|
||||
{
|
||||
!loading && metadata && settings && settings.seo && (
|
||||
<FeatureFlag features={mode?.features || DEFAULT_PANEL_FEATURE_FLAGS} flag={FEATURE_FLAG.panel.seo}>
|
||||
<FeatureFlag features={mode?.features || [...allPanelValues]} flag={FEATURE_FLAG.panel.seo}>
|
||||
<SeoStatus
|
||||
seo={settings.seo}
|
||||
data={metadata}
|
||||
@@ -146,7 +149,7 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (
|
||||
}
|
||||
|
||||
{!loading && settings && (
|
||||
<FeatureFlag features={mode?.features || DEFAULT_PANEL_FEATURE_FLAGS} flag={FEATURE_FLAG.panel.actions}>
|
||||
<FeatureFlag features={mode?.features || [...allPanelValues]} flag={FEATURE_FLAG.panel.actions}>
|
||||
<Actions
|
||||
metadata={metadata}
|
||||
settings={settings}
|
||||
@@ -156,23 +159,23 @@ export const ViewPanel: React.FunctionComponent<IViewPanelProps> = (
|
||||
|
||||
{
|
||||
!loading && metadata && (
|
||||
<FeatureFlag features={mode?.features || DEFAULT_PANEL_FEATURE_FLAGS} flag={FEATURE_FLAG.panel.metadata}>
|
||||
<FeatureFlag features={mode?.features || [...allPanelValues]} flag={FEATURE_FLAG.panel.metadata}>
|
||||
<Metadata
|
||||
settings={settings}
|
||||
metadata={metadata}
|
||||
focusElm={focusElm}
|
||||
unsetFocus={unsetFocus}
|
||||
features={mode?.features || DEFAULT_PANEL_FEATURE_FLAGS}
|
||||
features={mode?.features || [...allPanelValues]}
|
||||
/>
|
||||
</FeatureFlag>
|
||||
)
|
||||
}
|
||||
|
||||
<FeatureFlag features={mode?.features || DEFAULT_PANEL_FEATURE_FLAGS} flag={FEATURE_FLAG.panel.recentlyModified}>
|
||||
<FeatureFlag features={mode?.features || [...allPanelValues]} flag={FEATURE_FLAG.panel.recentlyModified}>
|
||||
<FolderAndFiles data={folderAndFiles} isBase={!metadata} />
|
||||
</FeatureFlag>
|
||||
|
||||
<FeatureFlag features={mode?.features || DEFAULT_PANEL_FEATURE_FLAGS} flag={FEATURE_FLAG.panel.otherActions}>
|
||||
<FeatureFlag features={mode?.features || [...allPanelValues]} flag={FEATURE_FLAG.panel.otherActions}>
|
||||
<OtherActions settings={settings} isFile={!!metadata} isBase={!metadata} />
|
||||
</FeatureFlag>
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import { FEATURE_FLAG, GeneralCommands } from '../../constants';
|
||||
import { Messenger } from '@estruyf/vscode/dist/client';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
import { DEFAULT_PANEL_FEATURE_FLAGS } from '../../constants/DefaultFeatureFlags';
|
||||
|
||||
export interface IMetadata {
|
||||
[prop: string]: string[] | string | null | IMetadata;
|
||||
@@ -96,7 +95,7 @@ const Metadata: React.FunctionComponent<IMetadataProps> = ({
|
||||
id={`tags`}
|
||||
title={`${l10n.t(LocalizationKey.panelMetadataTitle)}${contentType?.name ? ` (${contentType?.name})` : ""}`}
|
||||
className={`inherit z-20`}>
|
||||
<FeatureFlag features={features || DEFAULT_PANEL_FEATURE_FLAGS} flag={FEATURE_FLAG.panel.contentType}>
|
||||
<FeatureFlag features={features || []} flag={FEATURE_FLAG.panel.contentType}>
|
||||
<ContentTypeValidator fields={contentType?.fields || []} metadata={metadata} />
|
||||
</FeatureFlag>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user