Skip to content

Commit

Permalink
Enhance SEO components with keyword management and styling updates #705
Browse files Browse the repository at this point in the history
  • Loading branch information
estruyf committed Nov 22, 2024
1 parent 8cecf8d commit fca8d26
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 37 deletions.
27 changes: 26 additions & 1 deletion src/panelWebView/components/SeoKeywordInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import * as React from 'react';
import { ValidInfo } from './ValidInfo';
import { VSCodeTableCell, VSCodeTableRow } from './VSCode/VSCodeTable';
import { Tag } from './Tag';
import { LocalizationKey, localize } from '../../localization';
import { Messenger } from '@estruyf/vscode/dist/client';
import { CommandToCode } from '../CommandToCode';

export interface ISeoKeywordInfoProps {
keywords: string[];
keyword: string;
title: string;
description: string;
Expand All @@ -14,6 +19,7 @@ export interface ISeoKeywordInfoProps {

const SeoKeywordInfo: React.FunctionComponent<ISeoKeywordInfoProps> = ({
keyword,
keywords,
title,
description,
slug,
Expand Down Expand Up @@ -64,13 +70,32 @@ const SeoKeywordInfo: React.FunctionComponent<ISeoKeywordInfoProps> = ({
return <ValidInfo isValid={exists.length > 0} />;
};

const onRemove = React.useCallback((tag: string) => {
const newSelection = keywords.filter((s) => s !== tag);
Messenger.send(CommandToCode.updateKeywords, {
values: newSelection,
parents: undefined
});
}, [keywords]);

if (!keyword || typeof keyword !== 'string') {
return null;
}

return (
<VSCodeTableRow>
<VSCodeTableCell>{keyword}</VSCodeTableCell>
<VSCodeTableCell>
<div className='flex h-full items-center'>
<Tag
value={keyword}
className={`!mx-0 !my-1 !px-2 !py-1`}
onRemove={onRemove}
onCreate={() => void 0}
title={localize(LocalizationKey.panelTagsTagWarning, keyword)}
disableConfigurable={true}
/>
</div>
</VSCodeTableCell>
<VSCodeTableCell className={`text-center`}>
<ValidInfo
isValid={!!title && title.toLowerCase().includes(keyword.toLowerCase())}
Expand Down
10 changes: 7 additions & 3 deletions src/panelWebView/components/SeoKeywords.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ const SeoKeywords: React.FunctionComponent<ISeoKeywordsProps> = ({
return [];
};

const validKeywords = React.useMemo(() => {
return validateKeywords();
}, [keywords]);

// Workaround for lit components not updating render
React.useEffect(() => {
setIsReady(false);
Expand All @@ -54,7 +58,7 @@ const SeoKeywords: React.FunctionComponent<ISeoKeywordsProps> = ({
}

return (
<section className={`seo__keywords mb-8`}>
<section className={`seo__keywords__table`}>
<h4 className='!text-left'>{localize(LocalizationKey.panelSeoKeywordsTitle)}</h4>

<VSCodeTable>
Expand Down Expand Up @@ -159,10 +163,10 @@ const SeoKeywords: React.FunctionComponent<ISeoKeywordsProps> = ({
</VSCodeTableHeader>

<VSCodeTableBody>
{validateKeywords().map((keyword, index) => {
{validKeywords.map((keyword, index) => {
return (
<ErrorBoundary key={keyword} fallback={<div />}>
<SeoKeywordInfo key={index} keyword={keyword} {...data} />
<SeoKeywordInfo key={index} keywords={validKeywords} keyword={keyword} {...data} />
</ErrorBoundary>
);
})}
Expand Down
46 changes: 24 additions & 22 deletions src/panelWebView/components/SeoStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const SeoStatus: React.FunctionComponent<ISeoStatusProps> = ({
const descriptionFieldName = contentType?.fields.find(f => f.name === descriptionField)?.title || descriptionField;

return (
<div className='space-y-8'>
<div className='seo space-y-8'>
<section className={`seo__insights`}>
<h4 className='!text-left'>{localize(LocalizationKey.panelSeoStatusTitle)}</h4>

Expand Down Expand Up @@ -85,28 +85,30 @@ const SeoStatus: React.FunctionComponent<ISeoStatusProps> = ({
</VSCodeTable>
</section>

<SeoKeywords
keywords={metadata?.keywords}
title={metadata[titleField]}
description={metadata[descriptionField]}
slug={metadata.slug}
headings={metadata?.articleDetails?.headingsText}
wordCount={metadata?.articleDetails?.wordCount}
content={metadata?.articleDetails?.content}
/>

<FieldBoundary fieldName={`Keywords`}>
<TagPicker
type={TagType.keywords}
icon={<Icon name="symbol-keyword" className='mr-2' />}
crntSelected={(metadata.keywords as string[]) || []}
options={[]}
freeform={true}
focussed={focusElm === TagType.keywords}
unsetFocus={unsetFocus}
disableConfigurable
<section className={`seo__keywords`}>
<SeoKeywords
keywords={metadata?.keywords}
title={metadata[titleField]}
description={metadata[descriptionField]}
slug={metadata.slug}
headings={metadata?.articleDetails?.headingsText}
wordCount={metadata?.articleDetails?.wordCount}
content={metadata?.articleDetails?.content}
/>
</FieldBoundary>

<FieldBoundary fieldName={`Keywords`}>
<TagPicker
type={TagType.keywords}
icon={<Icon name="symbol-keyword" className='mr-2' />}
crntSelected={(metadata.keywords as string[]) || []}
options={[]}
freeform={true}
focussed={focusElm === TagType.keywords}
unsetFocus={unsetFocus}
disableConfigurable
/>
</FieldBoundary>
</section>
</div>
);
}, [contentType, metadata, seo, focusElm, unsetFocus]);
Expand Down
11 changes: 4 additions & 7 deletions src/panelWebView/components/Tag.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { PlusIcon, XMarkIcon } from '@heroicons/react/24/outline';
import * as React from 'react';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../localization';
import { LocalizationKey, localize } from '../../localization';

export interface ITagProps {
className: string;
Expand All @@ -14,16 +13,14 @@ export interface ITagProps {
onRemove: (tags: string) => void;
}

const Tag: React.FunctionComponent<ITagProps> = (props: React.PropsWithChildren<ITagProps>) => {
const { value, title, onRemove, onCreate, disableConfigurable } = props;

const Tag: React.FunctionComponent<ITagProps> = ({ value, title, onRemove, onCreate, disableConfigurable, className }: React.PropsWithChildren<ITagProps>) => {
return (
<>
<div className={`tag`}>
<div className={`tag ${className || ""}`}>
{!disableConfigurable && onCreate && (
<button
className={`tag__create`}
title={l10n.t(LocalizationKey.panelTagAdd, value)}
title={localize(LocalizationKey.panelTagAdd, value)}
type={`button`}
onClick={() => onCreate(value)}
>
Expand Down
7 changes: 3 additions & 4 deletions src/panelWebView/components/Tags.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import { Tag } from './Tag';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../localization';
import { LocalizationKey, localize } from '../../localization';

export interface ITagsProps {
values: string[];
Expand Down Expand Up @@ -34,7 +33,7 @@ const Tags: React.FunctionComponent<ITagsProps> = (props: React.PropsWithChildre
value={t}
className={`article__tags__items__pill_exists`}
onRemove={onRemove}
title={l10n.t(LocalizationKey.commonRemoveValue, t)}
title={localize(LocalizationKey.commonRemoveValue, t)}
/>
))}
{unknownTags.map((t, idx) => (
Expand All @@ -44,7 +43,7 @@ const Tags: React.FunctionComponent<ITagsProps> = (props: React.PropsWithChildre
className={`article__tags__items__pill_notexists`}
onRemove={onRemove}
onCreate={onCreate}
title={l10n.t(LocalizationKey.panelTagsTagWarning, t)}
title={localize(LocalizationKey.panelTagsTagWarning, t)}
disableConfigurable={disableConfigurable}
/>
))}
Expand Down
12 changes: 12 additions & 0 deletions src/panelWebView/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1180,3 +1180,15 @@ vscode-divider {
}
}
}

/* SEO */
.seo {
.article__tags label,
.article__tags__items {
display: none;
}

.article__tags {
margin-bottom: 0;
}
}

0 comments on commit fca8d26

Please sign in to comment.