Skip to content

Commit afc9847

Browse files
authored
website: Fix issue where OpenAPI docs template generates semi-synthet… (#14674)
* website: Fix issue where OpenAPI docs template generates semi-synthetic title. * website: Clarify linter behavior. Tidy components.
1 parent 620c95d commit afc9847

File tree

1 file changed

+53
-26
lines changed

1 file changed

+53
-26
lines changed

website/src/theme/DocItem/Content/index.tsx

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,41 @@ class MarkdownLintError extends Error {
2626
}
2727
}
2828

29+
function useBadgeLinterEffect() {
30+
const { frontMatter, metadata } = useDoc();
31+
const { hide_title } = frontMatter;
32+
const { id } = metadata;
33+
34+
useEffect(() => {
35+
if (hide_title) {
36+
console.debug(`Skipping badge linting for ${id} because \`hide_title\` is set`);
37+
return;
38+
}
39+
40+
const invalidBadges = document.querySelectorAll(`.theme-doc-markdown > header + .badge,
41+
.theme-doc-markdown .markdown > .badge
42+
`);
43+
44+
const badgeCount = invalidBadges.length;
45+
46+
if (!badgeCount) return;
47+
48+
const badgeContent = Array.from(invalidBadges, (badge) => `"${badge.textContent}"`);
49+
50+
const message = `${id}: ${badgeCount} Badge(s) defined in Markdown content instead of the frontmatter:\n ${badgeContent.join("\n")}`;
51+
52+
console.error(message);
53+
54+
console.error(`Found ${badgeCount} invalid badges on ${id}`, invalidBadges);
55+
56+
throw new MarkdownLintError(message);
57+
}, [hide_title, id]);
58+
}
59+
2960
const DocItemContent: React.FC<Props> = ({ children }) => {
3061
const syntheticTitle = useSyntheticTitle();
3162
const { frontMatter, metadata, contentTitle } = useDoc();
63+
const { id } = metadata;
3264
const {
3365
// ---
3466
support_level,
@@ -37,6 +69,8 @@ const DocItemContent: React.FC<Props> = ({ children }) => {
3769
authentik_preview,
3870
} = frontMatter;
3971

72+
useBadgeLinterEffect();
73+
4074
const badges: JSX.Element[] = [];
4175

4276
if (authentik_version) {
@@ -57,46 +91,23 @@ const DocItemContent: React.FC<Props> = ({ children }) => {
5791

5892
if (badges.length && !syntheticTitle) {
5993
throw new MarkdownLintError(
60-
`${metadata.id}: ${badges.length} Badge(s) found with a missing synthetic title. Remove the page heading and set it via the frontmatter.`,
94+
`${id}: ${badges.length} Badge(s) found with a missing synthetic title. Remove the page heading and set it via the frontmatter.`,
6195
);
6296
}
6397

6498
if (frontMatter.title && contentTitle && frontMatter.title === contentTitle) {
6599
throw new MarkdownLintError(
66-
`${metadata.id}: Synthetic title "${frontMatter.title}" and content title "${contentTitle}" are the same. Remove the first heading and let the frontmatter set the title.`,
100+
`${id}: Synthetic title "${frontMatter.title}" and content title "${contentTitle}" are the same. Remove the first heading and let the frontmatter set the title.`,
67101
);
68102
}
69103

70-
useEffect(() => {
71-
const invalidBadges = document.querySelectorAll(`.theme-doc-markdown > header + .badge,
72-
.theme-doc-markdown .markdown > .badge
73-
`);
74-
75-
if (!invalidBadges.length) return;
76-
77-
console.error(
78-
`Found ${invalidBadges.length} invalid badges on ${metadata.id}`,
79-
invalidBadges,
80-
);
81-
82-
throw new MarkdownLintError(
83-
`${metadata.id}: ${invalidBadges.length} Badge(s) defined in markdown content instead of the frontmatter.`,
84-
);
85-
}, [metadata.id]);
86-
87104
return (
88105
<div className={clsx(ThemeClassNames.docs.docMarkdown, "markdown")}>
89106
{syntheticTitle ? (
90107
<header>
91108
<Heading as="h1">{syntheticTitle}</Heading>
92109

93-
{badges.length ? (
94-
<p className="badge-group">
95-
{badges.map((badge, index) => (
96-
<React.Fragment key={index}>{badge}</React.Fragment>
97-
))}
98-
</p>
99-
) : null}
110+
<BadgeGroup badges={badges} />
100111
</header>
101112
) : null}
102113

@@ -105,4 +116,20 @@ const DocItemContent: React.FC<Props> = ({ children }) => {
105116
);
106117
};
107118

119+
interface BadgesProps {
120+
badges: JSX.Element[];
121+
}
122+
123+
const BadgeGroup: React.FC<BadgesProps> = ({ badges }) => {
124+
if (!badges.length) return null;
125+
126+
return (
127+
<p className="badge-group">
128+
{badges.map((badge, index) => (
129+
<React.Fragment key={index}>{badge}</React.Fragment>
130+
))}
131+
</p>
132+
);
133+
};
134+
108135
export default DocItemContent;

0 commit comments

Comments
 (0)