mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-07-03 16:31:32 +02:00
Update panel localization
This commit is contained in:
@@ -2,6 +2,8 @@ import * as React from 'react';
|
||||
import { SeoKeywordInfo } from './SeoKeywordInfo';
|
||||
import { VsTable, VsTableBody, VsTableHeader, VsTableHeaderCell } from './VscodeComponents';
|
||||
import { ErrorBoundary } from '@sentry/react';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
|
||||
export interface ISeoKeywordsProps {
|
||||
keywords: string[] | null;
|
||||
@@ -50,12 +52,16 @@ const SeoKeywords: React.FunctionComponent<ISeoKeywordsProps> = ({
|
||||
|
||||
return (
|
||||
<div className={`seo__status__keywords`}>
|
||||
<h4>Keywords</h4>
|
||||
<h4>{l10n.t(LocalizationKey.panelSeoKeywordsTitle)}</h4>
|
||||
|
||||
<VsTable bordered columns={['30%', 'auto']}>
|
||||
<VsTableHeader slot="header">
|
||||
<VsTableHeaderCell className={`table__cell`}>Keyword</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>Details</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>
|
||||
{l10n.t(LocalizationKey.panelSeoKeywordsHeaderKeyword)}
|
||||
</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>
|
||||
{l10n.t(LocalizationKey.panelSeoKeywordsHeaderDetails)}
|
||||
</VsTableHeaderCell>
|
||||
</VsTableHeader>
|
||||
<VsTableBody slot="body">
|
||||
{validateKeywords().map((keyword, index) => {
|
||||
@@ -70,7 +76,7 @@ const SeoKeywords: React.FunctionComponent<ISeoKeywordsProps> = ({
|
||||
|
||||
{data.wordCount && (
|
||||
<div className={`seo__status__note`}>
|
||||
* A keyword density of 1-1.5% is sufficient in most cases.
|
||||
{l10n.t(LocalizationKey.panelSeoKeywordsDensity)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -10,6 +10,8 @@ import { SeoFieldInfo } from './SeoFieldInfo';
|
||||
import { SeoKeywords } from './SeoKeywords';
|
||||
import { TagPicker } from './TagPicker';
|
||||
import { VsTable, VsTableBody, VsTableHeader, VsTableHeaderCell } from './VscodeComponents';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
|
||||
export interface ISeoStatusProps {
|
||||
seo: SEO;
|
||||
@@ -58,20 +60,26 @@ const SeoStatus: React.FunctionComponent<ISeoStatusProps> = ({
|
||||
return (
|
||||
<div>
|
||||
<div className={`seo__status__details`}>
|
||||
<h4>Recommendations</h4>
|
||||
<h4>{l10n.t(LocalizationKey.panelSeoStatusTitle)}</h4>
|
||||
|
||||
<VsTable ref={tableRef} bordered zebra>
|
||||
<VsTableHeader slot="header">
|
||||
<VsTableHeaderCell className={`table__cell`}>Property</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>Length</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>Valid</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>
|
||||
{l10n.t(LocalizationKey.panelSeoStatusHeaderProperty)}
|
||||
</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>
|
||||
{l10n.t(LocalizationKey.panelSeoStatusHeaderLength)}
|
||||
</VsTableHeaderCell>
|
||||
<VsTableHeaderCell className={`table__cell`}>
|
||||
{l10n.t(LocalizationKey.panelSeoStatusHeaderValid)}
|
||||
</VsTableHeaderCell>
|
||||
</VsTableHeader>
|
||||
<VsTableBody slot="body">
|
||||
{data[titleField] && seo.title > 0 && (
|
||||
<SeoFieldInfo
|
||||
title={titleField}
|
||||
value={data[titleField].length}
|
||||
recommendation={`${seo.title} chars`}
|
||||
recommendation={l10n.t(LocalizationKey.panelSeoStatusSeoFieldInfoCharacters, seo.title)}
|
||||
isValid={data[titleField].length <= seo.title}
|
||||
/>
|
||||
)}
|
||||
@@ -80,7 +88,7 @@ const SeoStatus: React.FunctionComponent<ISeoStatusProps> = ({
|
||||
<SeoFieldInfo
|
||||
title={`slug`}
|
||||
value={slug.length}
|
||||
recommendation={`${seo.slug} chars`}
|
||||
recommendation={l10n.t(LocalizationKey.panelSeoStatusSeoFieldInfoCharacters, seo.slug)}
|
||||
isValid={slug.length <= seo.slug}
|
||||
/>
|
||||
)}
|
||||
@@ -89,16 +97,16 @@ const SeoStatus: React.FunctionComponent<ISeoStatusProps> = ({
|
||||
<SeoFieldInfo
|
||||
title={descriptionField}
|
||||
value={data[descriptionField].length}
|
||||
recommendation={`${seo.description} chars`}
|
||||
recommendation={l10n.t(LocalizationKey.panelSeoStatusSeoFieldInfoCharacters, seo.description)}
|
||||
isValid={data[descriptionField].length <= seo.description}
|
||||
/>
|
||||
)}
|
||||
|
||||
{seo.content > 0 && data?.articleDetails?.wordCount > 0 && (
|
||||
<SeoFieldInfo
|
||||
title={`Article length`}
|
||||
title={l10n.t(LocalizationKey.panelSeoStatusSeoFieldInfoArticle)}
|
||||
value={data?.articleDetails?.wordCount}
|
||||
recommendation={`${seo.content} words`}
|
||||
recommendation={l10n.t(LocalizationKey.panelSeoStatusSeoFieldInfoWords, seo.content)}
|
||||
/>
|
||||
)}
|
||||
</VsTableBody>
|
||||
@@ -134,11 +142,11 @@ const SeoStatus: React.FunctionComponent<ISeoStatusProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<Collapsible id={`seo`} title="SEO Status" sendUpdate={pushUpdate}>
|
||||
<Collapsible id={`seo`} title={l10n.t(LocalizationKey.panelSeoStatusCollapsibleTitle)} sendUpdate={pushUpdate}>
|
||||
{!title && !data[descriptionField] ? (
|
||||
<div className={`seo__status__empty`}>
|
||||
<p>
|
||||
<b>Title</b> or <b>{descriptionField}</b> is needed.
|
||||
{l10n.t(LocalizationKey.panelSeoStatusRequired, "Title", descriptionField)}
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@@ -2,17 +2,19 @@ import { Messenger } from '@estruyf/vscode/dist/client';
|
||||
import * as React from 'react';
|
||||
import { CommandToCode } from '../CommandToCode';
|
||||
import { ActionButton } from './ActionButton';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
|
||||
export interface ISlugActionProps {}
|
||||
export interface ISlugActionProps { }
|
||||
|
||||
const SlugAction: React.FunctionComponent<
|
||||
ISlugActionProps
|
||||
> = ({}: React.PropsWithChildren<ISlugActionProps>) => {
|
||||
> = ({ }: React.PropsWithChildren<ISlugActionProps>) => {
|
||||
const optimize = () => {
|
||||
Messenger.send(CommandToCode.updateSlug);
|
||||
};
|
||||
|
||||
return <ActionButton onClick={optimize} title={`Optimize slug`} />;
|
||||
return <ActionButton onClick={optimize} title={l10n.t(LocalizationKey.panelSlugActionTitle)} />;
|
||||
};
|
||||
|
||||
SlugAction.displayName = 'SlugAction';
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import * as React from 'react';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
|
||||
export interface ISpinnerProps {}
|
||||
export interface ISpinnerProps { }
|
||||
|
||||
const Spinner: React.FunctionComponent<ISpinnerProps> = (
|
||||
props: React.PropsWithChildren<ISpinnerProps>
|
||||
_: React.PropsWithChildren<ISpinnerProps>
|
||||
) => {
|
||||
return <div className="spinner">Loading...</div>;
|
||||
return (
|
||||
<div className="spinner">
|
||||
{l10n.t(LocalizationKey.panelSpinnerLoading)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Spinner.displayName = 'Spinner';
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { SPONSOR_LINK } from '../../constants/Links';
|
||||
import { HeartIcon } from './Icons/HeartIcon';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
|
||||
export interface ISponsorMsgProps {
|
||||
isBacker: boolean | undefined;
|
||||
@@ -16,7 +18,7 @@ const SponsorMsg: React.FunctionComponent<ISponsorMsgProps> = ({
|
||||
return (
|
||||
<p className={`sponsor`}>
|
||||
<a href={SPONSOR_LINK} title="Support Front Matter">
|
||||
<span>Support</span> <HeartIcon className={`h-5 w-5 mr-2`} /> <span>FrontMatter</span>
|
||||
<span>{l10n.t(LocalizationKey.commonSupport)}</span> <HeartIcon className={`h-5 w-5 mr-2`} /> <span>FrontMatter</span>
|
||||
</a>
|
||||
</p>
|
||||
);
|
||||
|
||||
@@ -25,8 +25,18 @@ export const StartServerButton: React.FunctionComponent<IStartServerButtonProps>
|
||||
|
||||
return startCommand ? (
|
||||
<>
|
||||
<button onClick={() => startLocalServer(startCommand)}>{l10n.t(LocalizationKey.panelActionsStartServer)}</button>
|
||||
<button onClick={() => stopLocalServer()}>{l10n.t(LocalizationKey.panelActionsStopServer)}</button>
|
||||
<button
|
||||
title={l10n.t(LocalizationKey.panelStartServerbuttonStart)}
|
||||
type={`button`}
|
||||
onClick={() => startLocalServer(startCommand)}>
|
||||
{l10n.t(LocalizationKey.panelStartServerbuttonStart)}
|
||||
</button>
|
||||
<button
|
||||
title={l10n.t(LocalizationKey.panelStartServerbuttonStop)}
|
||||
type={`button`}
|
||||
onClick={() => stopLocalServer()}>
|
||||
{l10n.t(LocalizationKey.panelStartServerbuttonStop)}
|
||||
</button>
|
||||
</>
|
||||
) : null;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { PlusIcon, XIcon } from '@heroicons/react/outline';
|
||||
import * as React from 'react';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
|
||||
export interface ITagProps {
|
||||
className: string;
|
||||
@@ -13,7 +15,7 @@ export interface ITagProps {
|
||||
}
|
||||
|
||||
const Tag: React.FunctionComponent<ITagProps> = (props: React.PropsWithChildren<ITagProps>) => {
|
||||
const { value, className, title, onRemove, onCreate, disableConfigurable } = props;
|
||||
const { value, title, onRemove, onCreate, disableConfigurable } = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -21,7 +23,8 @@ const Tag: React.FunctionComponent<ITagProps> = (props: React.PropsWithChildren<
|
||||
{!disableConfigurable && onCreate && (
|
||||
<button
|
||||
className={`tag__create`}
|
||||
title={`Add ${value} to your settings`}
|
||||
title={l10n.t(LocalizationKey.panelTagAdd, value)}
|
||||
type={`button`}
|
||||
onClick={() => onCreate(value)}
|
||||
>
|
||||
<PlusIcon style={{ width: `1rem`, height: `1rem` }} />
|
||||
@@ -30,7 +33,11 @@ const Tag: React.FunctionComponent<ITagProps> = (props: React.PropsWithChildren<
|
||||
|
||||
<div className={`tag__value`}>{value}</div>
|
||||
|
||||
<button title={title} className={`tag__delete`} onClick={() => onRemove(value)}>
|
||||
<button
|
||||
title={title}
|
||||
className={`tag__delete`}
|
||||
type={`button`}
|
||||
onClick={() => onRemove(value)}>
|
||||
<XIcon style={{ width: `1rem`, height: `1rem` }} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,8 @@ import { FieldTitle } from './Fields/FieldTitle';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { PanelSettingsAtom } from '../state';
|
||||
import { SparklesIcon } from '@heroicons/react/outline';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../localization';
|
||||
|
||||
export interface ITagPickerProps {
|
||||
type: TagType;
|
||||
@@ -244,10 +246,10 @@ const TagPicker: React.FunctionComponent<ITagPickerProps> = ({
|
||||
|
||||
const inputPlaceholder = useMemo((): string => {
|
||||
if (checkIsDisabled()) {
|
||||
return `You have reached the limit of ${limit} ${label || type.toLowerCase()}`;
|
||||
return l10n.t(LocalizationKey.panelTagPickerInputPlaceholderDisabled, `${limit} ${label || type.toLowerCase()}`);
|
||||
}
|
||||
|
||||
return `Pick your ${label || type.toLowerCase()}`;
|
||||
return l10n.t(LocalizationKey.panelTagPickerInputPlaceholderEmpty, (label || type.toLowerCase()));
|
||||
}, [label, type, checkIsDisabled]);
|
||||
|
||||
const showRequiredState = useMemo(() => {
|
||||
@@ -266,7 +268,7 @@ const TagPicker: React.FunctionComponent<ITagPickerProps> = ({
|
||||
return (
|
||||
<button
|
||||
className='metadata_field__title__action'
|
||||
title={`Use Front Matter AI to suggest ${label?.toLowerCase() || type.toLowerCase()}`}
|
||||
title={l10n.t(LocalizationKey.panelTagPickerAiSuggest, (label?.toLowerCase() || type.toLowerCase()))}
|
||||
type='button'
|
||||
onClick={() => suggestTaxonomy(type)}
|
||||
disabled={loading}>
|
||||
@@ -324,7 +326,7 @@ const TagPicker: React.FunctionComponent<ITagPickerProps> = ({
|
||||
{
|
||||
loading && (
|
||||
<div className='metadata_field__loading'>
|
||||
Generating suggestions...
|
||||
{l10n.t(LocalizationKey.panelTagPickerAiGenerating)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -335,7 +337,7 @@ const TagPicker: React.FunctionComponent<ITagPickerProps> = ({
|
||||
{limit !== undefined && limit > 0 ? (
|
||||
<>
|
||||
{` `}
|
||||
<span style={{ fontWeight: 'lighter' }}>(Max.: {limit})</span>
|
||||
<span style={{ fontWeight: 'lighter' }}>({l10n.t(LocalizationKey.panelTagPickerLimit, limit)})</span>
|
||||
</>
|
||||
) : (
|
||||
``
|
||||
@@ -393,7 +395,7 @@ const TagPicker: React.FunctionComponent<ITagPickerProps> = ({
|
||||
{freeform && (
|
||||
<button
|
||||
className={`article__tags__input__button`}
|
||||
title={`Add the unknown tag`}
|
||||
title={l10n.t(LocalizationKey.panelTagPickerUnkown)}
|
||||
disabled={!inputValue || checkIsDisabled()}
|
||||
onClick={() => insertUnkownTag(closeMenu)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user