forked from iarv/vscode-front-matter
#654 - Add the open on website action
This commit is contained in:
@@ -335,5 +335,6 @@
|
||||
"dashboard.steps.stepsToGetStarted.assetsFolder.other.description": "Wenn Sie einen anderen Ordner konfigurieren möchten, können Sie dies manuell in der frontmatter.json-Datei tun.",
|
||||
"dashboard.steps.stepsToGetStarted.template.name": "Verwende eine Konfigurationsvorlage",
|
||||
"dashboard.steps.stepsToGetStarted.template.description": "Wählen Sie eine Vorlage aus, um die Datei frontmatter.json mit den empfohlenen Einstellungen vorzufüllen.",
|
||||
"listeners.dashboard.settingsListener.triggerTemplate.notification": "Vorlagendateien kopiert."
|
||||
"listeners.dashboard.settingsListener.triggerTemplate.notification": "Vorlagendateien kopiert.",
|
||||
"common.openOnWebsite": "Auf der Website öffnen"
|
||||
}
|
||||
@@ -335,5 +335,6 @@
|
||||
"panel.viewPanel.mediaInsert": "Continuer dans le tableau de bord des médias pour sélectionner l'image que vous voulez insérer.",
|
||||
"dashboard.steps.stepsToGetStarted.template.name": "Utiliser un modèle de configuration",
|
||||
"dashboard.steps.stepsToGetStarted.template.description": "Sélectionnez un modèle pour préremplir le fichier frontmatter.json avec les paramètres recommandés.",
|
||||
"listeners.dashboard.settingsListener.triggerTemplate.notification": "Fichiers de modèle copiés."
|
||||
"listeners.dashboard.settingsListener.triggerTemplate.notification": "Fichiers de modèle copiés.",
|
||||
"common.openOnWebsite": "Ouvrir sur le site web"
|
||||
}
|
||||
@@ -335,5 +335,6 @@
|
||||
"panel.viewPanel.mediaInsert": "Continuare nella dashboard multimediale per selezionare l'immagine che si desidera inserire.",
|
||||
"dashboard.steps.stepsToGetStarted.template.name": "Usa un modello di configurazione",
|
||||
"dashboard.steps.stepsToGetStarted.template.description": "Seleziona un modello per riempire in anticipo il file frontmatter.json con le impostazioni consigliate.",
|
||||
"listeners.dashboard.settingsListener.triggerTemplate.notification": "File del modello copiati."
|
||||
"listeners.dashboard.settingsListener.triggerTemplate.notification": "File del modello copiati.",
|
||||
"common.openOnWebsite": "Apri sul sito web"
|
||||
}
|
||||
@@ -335,5 +335,6 @@
|
||||
"dashboard.steps.stepsToGetStarted.assetsFolder.other.description": "別のフォルダを設定する場合は、frontmatter.jsonファイルで手動で行うことができます。",
|
||||
"dashboard.steps.stepsToGetStarted.template.name": "設定テンプレートを使用する",
|
||||
"dashboard.steps.stepsToGetStarted.template.description": "おすすめの設定でfrontmatter.jsonファイルを事前に埋めるテンプレートを選択します。",
|
||||
"listeners.dashboard.settingsListener.triggerTemplate.notification": "テンプレートファイルがコピーされました。"
|
||||
"listeners.dashboard.settingsListener.triggerTemplate.notification": "テンプレートファイルがコピーされました。",
|
||||
"common.openOnWebsite": "ウェブサイトで開く"
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
"common.support": "Support",
|
||||
"common.remove.value": "Remove {0}",
|
||||
"common.error.message": "Sorry, something went wrong.",
|
||||
"common.openOnWebsite": "Open on website",
|
||||
|
||||
"developer.title": "Developer mode",
|
||||
"developer.reload.title": "Reload the dashboard",
|
||||
|
||||
@@ -1753,6 +1753,10 @@
|
||||
"default": "yyyy-MM-dd",
|
||||
"markdownDescription": "%setting.frontMatter.templates.prefix.markdownDescription%",
|
||||
"scope": "Templates"
|
||||
},
|
||||
"frontMatter.website.host": {
|
||||
"type": "string",
|
||||
"markdownDescription": "%setting.frontMatter.website.host.markdownDescription%"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -240,5 +240,6 @@
|
||||
"setting.frontMatter.taxonomy.dateField.deprecationMessage": "Diese Einstellung ist veraltet und wird in der nächsten Hauptversion entfernt. Bitte verwenden Sie stattdessen die neuen `isPublishDate`-Einstellungen in den Datumsfeldern Ihrer Content-Typen.",
|
||||
"setting.frontMatter.taxonomy.modifiedField.deprecationMessage": "Diese Einstellung ist veraltet und wird in der nächsten Hauptversion entfernt. Bitte verwenden Sie stattdessen die neuen `isModifiedDate`-Einstellungen in den Datumsfeldern Ihrer Content-Typen.",
|
||||
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.customType.description": "🚧: Specify the name of the custom field type to use.",
|
||||
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.clearEmpty.description": "🚧: Specify if the empty values should be cleared."
|
||||
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.clearEmpty.description": "🚧: Specify if the empty values should be cleared.",
|
||||
"setting.frontMatter.website.host.markdownDescription": "🚧: Specify the host URL of your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.website.url)"
|
||||
}
|
||||
@@ -241,5 +241,6 @@
|
||||
"setting.frontMatter.taxonomy.modifiedField.deprecationMessage": "🚧: This setting is deprecated and will be removed in the next major version. Please use the new `isModifiedDate` settings instead in your content types date fields.",
|
||||
"setting.frontMatter.global.disabledNotifications.markdownDescription": "🚧: This is an array with the notifications types that can be disabled for Front Matter CMS. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.disablednotifications)",
|
||||
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.customType.description": "🚧: Specify the name of the custom field type to use.",
|
||||
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.clearEmpty.description": "🚧: Specify if the empty values should be cleared."
|
||||
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.clearEmpty.description": "🚧: Specify if the empty values should be cleared.",
|
||||
"setting.frontMatter.website.host.markdownDescription": "🚧: Specify the host URL of your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.website.url)"
|
||||
}
|
||||
@@ -240,5 +240,6 @@
|
||||
"setting.frontMatter.taxonomy.dateField.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please use the new `isPublishDate` settings instead in your content types date fields.",
|
||||
"setting.frontMatter.taxonomy.modifiedField.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please use the new `isModifiedDate` settings instead in your content types date fields.",
|
||||
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.customType.description": "Specify the name of the custom field type to use.",
|
||||
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.clearEmpty.description": "Specify if the empty values should be cleared."
|
||||
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.clearEmpty.description": "Specify if the empty values should be cleared.",
|
||||
"setting.frontMatter.website.host.markdownDescription": "Specify the host URL of your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.website.url)"
|
||||
}
|
||||
@@ -221,7 +221,7 @@ export class Preview {
|
||||
* @param filePath
|
||||
* @returns
|
||||
*/
|
||||
private static async getContentSlug(
|
||||
public static async getContentSlug(
|
||||
article: ParsedFrontMatter | null,
|
||||
filePath?: string
|
||||
): Promise<string | undefined> {
|
||||
|
||||
@@ -8,6 +8,7 @@ export const GeneralCommands = {
|
||||
toVSCode: {
|
||||
openLink: 'openLink',
|
||||
gitSync: 'gitSync',
|
||||
getLocalization: 'getLocalization'
|
||||
getLocalization: 'getLocalization',
|
||||
openOnWebsite: 'openOnWebsite'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -103,6 +103,8 @@ export const SETTING_GIT_SUBMODULE_FOLDER = 'git.submodule.folder';
|
||||
|
||||
export const SETTING_SNIPPETS_WRAPPER = 'snippets.wrapper.enabled';
|
||||
|
||||
export const SETTING_WEBSITE_URL = 'website.host';
|
||||
|
||||
/**
|
||||
* Sponsors only settings
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Messenger } from '@estruyf/vscode/dist/client';
|
||||
import { Menu } from '@headlessui/react';
|
||||
import { EyeIcon, TerminalIcon, TrashIcon } from '@heroicons/react/outline';
|
||||
import { EyeIcon, GlobeIcon, TerminalIcon, TrashIcon } from '@heroicons/react/outline';
|
||||
import * as React from 'react';
|
||||
import { CustomScript, ScriptType } from '../../../models';
|
||||
import { DashboardMessage } from '../../DashboardMessage';
|
||||
@@ -11,6 +11,9 @@ import { useState } from 'react';
|
||||
import useThemeColors from '../../hooks/useThemeColors';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../../localization';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { SettingsSelector } from '../../state';
|
||||
import { GeneralCommands } from '../../../constants';
|
||||
|
||||
export interface IContentActionsProps {
|
||||
title: string;
|
||||
@@ -29,6 +32,7 @@ export const ContentActions: React.FunctionComponent<IContentActionsProps> = ({
|
||||
}: React.PropsWithChildren<IContentActionsProps>) => {
|
||||
const [showDeletionAlert, setShowDeletionAlert] = React.useState(false);
|
||||
const { getColors } = useThemeColors();
|
||||
const settings = useRecoilValue(SettingsSelector);
|
||||
|
||||
const [referenceElement, setReferenceElement] = useState<any>(null);
|
||||
const [popperElement, setPopperElement] = useState<any>(null);
|
||||
@@ -54,6 +58,16 @@ export const ContentActions: React.FunctionComponent<IContentActionsProps> = ({
|
||||
setShowDeletionAlert(false);
|
||||
};
|
||||
|
||||
const openOnWebsite = React.useCallback((e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.stopPropagation();
|
||||
if (settings?.websiteUrl && path) {
|
||||
Messenger.send(GeneralCommands.toVSCode.openOnWebsite, {
|
||||
websiteUrl: settings.websiteUrl,
|
||||
filePath: path
|
||||
});
|
||||
}
|
||||
}, [settings?.websiteUrl, path]);
|
||||
|
||||
const runCustomScript = React.useCallback(
|
||||
(e: React.MouseEvent<HTMLButtonElement>, script: CustomScript) => {
|
||||
e.stopPropagation();
|
||||
@@ -101,11 +115,19 @@ export const ContentActions: React.FunctionComponent<IContentActionsProps> = ({
|
||||
<Menu as="div" className={`relative flex text-left`}>
|
||||
{!listView && (
|
||||
<div className="hidden group-hover/card:flex">
|
||||
<QuickAction title={`View content`} onClick={onView}>
|
||||
<QuickAction title={l10n.t(LocalizationKey.dashboardContentsContentActionsMenuItemView)} onClick={onView}>
|
||||
<EyeIcon className={`w-4 h-4`} aria-hidden="true" />
|
||||
</QuickAction>
|
||||
|
||||
<QuickAction title={`Delete content`} onClick={onDelete}>
|
||||
{
|
||||
settings?.websiteUrl && (
|
||||
<QuickAction title={l10n.t(LocalizationKey.commonOpenOnWebsite)} onClick={openOnWebsite}>
|
||||
<GlobeIcon className={`w-4 h-4`} aria-hidden="true" />
|
||||
</QuickAction>
|
||||
)
|
||||
}
|
||||
|
||||
<QuickAction title={l10n.t(LocalizationKey.commonDelete)} onClick={onDelete}>
|
||||
<TrashIcon className={`w-4 h-4`} aria-hidden="true" />
|
||||
</QuickAction>
|
||||
</div>
|
||||
@@ -136,6 +158,20 @@ export const ContentActions: React.FunctionComponent<IContentActionsProps> = ({
|
||||
onClick={(_, e) => onView(e)}
|
||||
/>
|
||||
|
||||
{
|
||||
settings?.websiteUrl && (
|
||||
<MenuItem
|
||||
title={
|
||||
<div className="flex items-center">
|
||||
<GlobeIcon className="mr-2 h-5 w-5 flex-shrink-0" aria-hidden={true} />{' '}
|
||||
<span>{l10n.t(LocalizationKey.commonOpenOnWebsite)}</span>
|
||||
</div>
|
||||
}
|
||||
onClick={(_, e) => openOnWebsite(e)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
{customScriptActions}
|
||||
|
||||
<MenuItem
|
||||
|
||||
@@ -33,6 +33,7 @@ export interface Settings {
|
||||
contentTypes: ContentType[];
|
||||
contentFolders: ContentFolder[];
|
||||
crntFramework: string;
|
||||
websiteUrl: string;
|
||||
framework: Framework | null | undefined;
|
||||
draftField: DraftField | null | undefined;
|
||||
customSorting: SortingSetting[] | undefined;
|
||||
|
||||
@@ -29,7 +29,8 @@ import {
|
||||
SETTING_DASHBOARD_CONTENT_CARD_DATE,
|
||||
SETTING_DASHBOARD_CONTENT_CARD_TITLE,
|
||||
SETTING_DASHBOARD_CONTENT_CARD_STATE,
|
||||
SETTING_DASHBOARD_CONTENT_CARD_DESCRIPTION
|
||||
SETTING_DASHBOARD_CONTENT_CARD_DESCRIPTION,
|
||||
SETTING_WEBSITE_URL
|
||||
} from '../constants';
|
||||
import {
|
||||
DashboardViewType,
|
||||
@@ -131,7 +132,8 @@ export class DashboardSettings {
|
||||
dataTypes: Settings.get<DataType[]>(SETTING_DATA_TYPES),
|
||||
snippets: Settings.get<Snippets>(SETTING_CONTENT_SNIPPETS),
|
||||
snippetsWrapper: Settings.get<boolean>(SETTING_SNIPPETS_WRAPPER),
|
||||
isBacker: await ext.getState<boolean | undefined>(CONTEXT.backer, 'global')
|
||||
isBacker: await ext.getState<boolean | undefined>(CONTEXT.backer, 'global'),
|
||||
websiteUrl: Settings.get<string>(SETTING_WEBSITE_URL)
|
||||
} as ISettings;
|
||||
|
||||
return settings;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SETTING_SPONSORS_AI_ENABLED } from './../constants/settings';
|
||||
import { SETTING_SPONSORS_AI_ENABLED, SETTING_WEBSITE_URL } from './../constants/settings';
|
||||
import { workspace } from 'vscode';
|
||||
import { Extension, Settings, TaxonomyHelper } from '.';
|
||||
import { Dashboard } from '../commands/Dashboard';
|
||||
@@ -96,7 +96,8 @@ export class PanelSettings {
|
||||
},
|
||||
dataTypes: Settings.get<DataType[]>(SETTING_DATA_TYPES),
|
||||
fieldGroups: Settings.get<FieldGroup[]>(SETTING_TAXONOMY_FIELD_GROUPS),
|
||||
contentFolders: Folders.get()
|
||||
contentFolders: Folders.get(),
|
||||
websiteUrl: Settings.get<string>(SETTING_WEBSITE_URL) || ''
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { GeneralCommands } from './../../constants/GeneralCommands';
|
||||
import { Dashboard } from '../../commands/Dashboard';
|
||||
import { PanelProvider } from '../../panelWebView/PanelProvider';
|
||||
import { Extension } from '../../helpers';
|
||||
import { ArticleHelper, Extension } from '../../helpers';
|
||||
import { Logger } from '../../helpers/Logger';
|
||||
import { commands, Uri } from 'vscode';
|
||||
import { commands, Uri, window } from 'vscode';
|
||||
import { PostMessageData } from '../../models';
|
||||
import { Preview } from '../../commands';
|
||||
import { urlJoin } from 'url-join-ts';
|
||||
|
||||
export abstract class BaseListener {
|
||||
public static process(msg: PostMessageData) {
|
||||
@@ -14,6 +16,9 @@ export abstract class BaseListener {
|
||||
commands.executeCommand('vscode.open', Uri.parse(msg.payload));
|
||||
}
|
||||
break;
|
||||
case GeneralCommands.toVSCode.openOnWebsite:
|
||||
this.openOnWebsite(msg.payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,4 +37,38 @@ export abstract class BaseListener {
|
||||
|
||||
Dashboard.postWebviewMessage({ command: command as any, payload });
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the page on the website
|
||||
* @param param0
|
||||
* @returns
|
||||
*/
|
||||
private static async openOnWebsite({
|
||||
websiteUrl,
|
||||
filePath
|
||||
}: {
|
||||
websiteUrl: string;
|
||||
filePath?: string;
|
||||
}) {
|
||||
if (websiteUrl) {
|
||||
const article = filePath
|
||||
? await ArticleHelper.getFrontMatterByPath(filePath)
|
||||
: ArticleHelper.getCurrent();
|
||||
if (article) {
|
||||
if (!filePath) {
|
||||
const editor = window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
filePath = editor.document.uri.fsPath;
|
||||
}
|
||||
|
||||
const slug = await Preview.getContentSlug(article, filePath);
|
||||
|
||||
const fullUrl = urlJoin(websiteUrl, slug);
|
||||
commands.executeCommand('vscode.open', fullUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,10 @@ export enum LocalizationKey {
|
||||
* Sorry, something went wrong.
|
||||
*/
|
||||
commonErrorMessage = 'common.error.message',
|
||||
/**
|
||||
* Open on website
|
||||
*/
|
||||
commonOpenOnWebsite = 'common.openOnWebsite',
|
||||
/**
|
||||
* Developer mode
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,7 @@ export interface PanelSettings {
|
||||
commaSeparatedFields: string[];
|
||||
aiEnabled: boolean;
|
||||
contentFolders: ContentFolder[];
|
||||
websiteUrl: string;
|
||||
}
|
||||
|
||||
export interface FieldGroup {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { SlugAction } from './SlugAction';
|
||||
import { StartServerButton } from './StartServerButton';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
import { OpenOnWebsiteAction } from './Actions/OpenOnWebsiteAction';
|
||||
|
||||
export interface IActionsProps {
|
||||
metadata: any;
|
||||
@@ -28,6 +29,8 @@ const Actions: React.FunctionComponent<IActionsProps> = ({
|
||||
|
||||
{settings?.preview?.host && <Preview slug={metadata.slug} />}
|
||||
|
||||
<OpenOnWebsiteAction baseUrl={settings.websiteUrl} slug={metadata.slug} />
|
||||
|
||||
<StartServerButton settings={settings} />
|
||||
|
||||
{settings && settings.scripts && settings.scripts.length > 0 && (
|
||||
|
||||
33
src/panelWebView/components/Actions/OpenOnWebsiteAction.tsx
Normal file
33
src/panelWebView/components/Actions/OpenOnWebsiteAction.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { messageHandler } from '@estruyf/vscode/dist/client';
|
||||
import * as React from 'react';
|
||||
import { ActionButton } from '../ActionButton';
|
||||
import * as l10n from "@vscode/l10n"
|
||||
import { LocalizationKey } from '../../../localization';
|
||||
import { GeneralCommands } from '../../../constants';
|
||||
|
||||
export interface IOpenOnWebsiteActionProps {
|
||||
baseUrl: string;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
export const OpenOnWebsiteAction: React.FunctionComponent<IOpenOnWebsiteActionProps> = ({
|
||||
baseUrl,
|
||||
slug
|
||||
}: React.PropsWithChildren<IOpenOnWebsiteActionProps>) => {
|
||||
|
||||
const open = () => {
|
||||
messageHandler.send(GeneralCommands.toVSCode.openOnWebsite, {
|
||||
websiteUrl: baseUrl,
|
||||
});
|
||||
};
|
||||
|
||||
if (!baseUrl || !slug) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<ActionButton
|
||||
title={l10n.t(LocalizationKey.commonOpenOnWebsite)}
|
||||
onClick={open} />
|
||||
);
|
||||
};
|
||||
1
src/panelWebView/components/Actions/index.ts
Normal file
1
src/panelWebView/components/Actions/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './OpenOnWebsiteAction';
|
||||
Reference in New Issue
Block a user