@patternfly/quickstarts 6.3.0-prerelease.5 → 6.3.0-prerelease.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ConsoleShared/src/components/markdown-extensions/accordion-extension.d.ts +1 -1
- package/dist/ConsoleShared/src/components/markdown-extensions/admonition-extension.d.ts +1 -1
- package/dist/index.es.js +226 -133
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +226 -133
- package/dist/index.js.map +1 -1
- package/dist/quickstarts-base.css +4 -4
- package/dist/quickstarts-full.es.js +274 -181
- package/dist/quickstarts-full.es.js.map +1 -1
- package/dist/quickstarts.css +4 -4
- package/dist/quickstarts.min.css +1 -1
- package/package.json +2 -2
- package/src/ConsoleInternal/components/markdown-view.tsx +92 -4
- package/src/ConsoleShared/src/components/markdown-extensions/__tests__/accordion-extension.spec.tsx +105 -0
- package/src/ConsoleShared/src/components/markdown-extensions/__tests__/admonition-extension.spec.tsx +121 -0
- package/src/ConsoleShared/src/components/markdown-extensions/accordion-extension.tsx +20 -13
- package/src/ConsoleShared/src/components/markdown-extensions/accordion-render-extension.tsx +19 -5
- package/src/ConsoleShared/src/components/markdown-extensions/admonition-extension.tsx +17 -6
- package/src/QuickStartDrawerContent.tsx +3 -1
- package/src/catalog/Toolbar/QuickStartCatalogFilterItems.tsx +1 -4
- package/src/controller/QuickStartIntroduction.tsx +1 -1
package/dist/index.js
CHANGED
|
@@ -1191,6 +1191,155 @@ const useMultilineCopyClipboardShowdownExtension = () => {
|
|
|
1191
1191
|
}), [getResource]);
|
|
1192
1192
|
};
|
|
1193
1193
|
|
|
1194
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1195
|
+
const DOMPurify$2 = require('dompurify');
|
|
1196
|
+
var AdmonitionType;
|
|
1197
|
+
(function (AdmonitionType) {
|
|
1198
|
+
AdmonitionType["TIP"] = "TIP";
|
|
1199
|
+
AdmonitionType["NOTE"] = "NOTE";
|
|
1200
|
+
AdmonitionType["IMPORTANT"] = "IMPORTANT";
|
|
1201
|
+
AdmonitionType["WARNING"] = "WARNING";
|
|
1202
|
+
AdmonitionType["CAUTION"] = "CAUTION";
|
|
1203
|
+
})(AdmonitionType || (AdmonitionType = {}));
|
|
1204
|
+
const admonitionToAlertVariantMap = {
|
|
1205
|
+
[AdmonitionType.NOTE]: { variant: 'info' },
|
|
1206
|
+
[AdmonitionType.TIP]: { variant: 'custom', customIcon: jsxRuntime.jsx(LightbulbIcon__default["default"], {}) },
|
|
1207
|
+
[AdmonitionType.IMPORTANT]: { variant: 'danger' },
|
|
1208
|
+
[AdmonitionType.CAUTION]: { variant: 'warning', customIcon: jsxRuntime.jsx(FireIcon__default["default"], {}) },
|
|
1209
|
+
[AdmonitionType.WARNING]: { variant: 'warning' },
|
|
1210
|
+
};
|
|
1211
|
+
const useAdmonitionShowdownExtension = () =>
|
|
1212
|
+
// const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
|
|
1213
|
+
react.useMemo(() => ({
|
|
1214
|
+
type: 'lang',
|
|
1215
|
+
regex: /\[(.+)]{{(admonition) ([\w-]+)}}/g,
|
|
1216
|
+
replace: (text, content, admonitionLabel, admonitionType) => {
|
|
1217
|
+
if (!content || !admonitionLabel || !admonitionType) {
|
|
1218
|
+
return text;
|
|
1219
|
+
}
|
|
1220
|
+
if (admonitionLabel !== 'admonition') {
|
|
1221
|
+
return text;
|
|
1222
|
+
}
|
|
1223
|
+
admonitionType = admonitionType.toUpperCase();
|
|
1224
|
+
// Process markdown content directly using marked
|
|
1225
|
+
const processedContent = marked.marked.parseInline(content);
|
|
1226
|
+
const sanitizedContent = DOMPurify$2.sanitize(processedContent);
|
|
1227
|
+
// Handle unknown admonition types by defaulting to NOTE
|
|
1228
|
+
const admonitionConfig = admonitionToAlertVariantMap[admonitionType] || admonitionToAlertVariantMap.NOTE;
|
|
1229
|
+
const { variant, customIcon } = admonitionConfig;
|
|
1230
|
+
const pfAlert = (jsxRuntime.jsx(reactCore.Alert, Object.assign({ variant: variant }, (customIcon && { customIcon }), { isInline: true, title: admonitionType, className: "pfext-markdown-admonition" }, { children: jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: sanitizedContent } }) })));
|
|
1231
|
+
return removeTemplateWhitespace(server.renderToStaticMarkup(pfAlert));
|
|
1232
|
+
},
|
|
1233
|
+
}), []);
|
|
1234
|
+
|
|
1235
|
+
const useCodeShowdownExtension = () => react.useMemo(() => ({
|
|
1236
|
+
type: 'output',
|
|
1237
|
+
regex: /<pre><code>(.*?)\n?<\/code><\/pre>/g,
|
|
1238
|
+
replace: (text, content) => {
|
|
1239
|
+
if (!content) {
|
|
1240
|
+
return text;
|
|
1241
|
+
}
|
|
1242
|
+
const pfCodeBlock = jsxRuntime.jsx(reactCore.CodeBlock, { children: content });
|
|
1243
|
+
return removeTemplateWhitespace(server.renderToStaticMarkup(pfCodeBlock));
|
|
1244
|
+
},
|
|
1245
|
+
}), []);
|
|
1246
|
+
|
|
1247
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1248
|
+
const DOMPurify$1 = require('dompurify');
|
|
1249
|
+
const useAccordionShowdownExtension = () => react.useMemo(() => ({
|
|
1250
|
+
type: 'lang',
|
|
1251
|
+
regex: /\[(.+)]{{(accordion) ("(.*?)")}}/g,
|
|
1252
|
+
replace: (_text, accordionContent, _command, _quotedHeading, accordionHeading) => {
|
|
1253
|
+
const accordionId = String(accordionHeading).replace(/\s/g, '-');
|
|
1254
|
+
// Process accordion content with markdown
|
|
1255
|
+
const processedContent = marked.marked.parseInline(accordionContent);
|
|
1256
|
+
const sanitizedContent = DOMPurify$1.sanitize(processedContent);
|
|
1257
|
+
return removeTemplateWhitespace(server.renderToStaticMarkup(jsxRuntime.jsx(reactCore.Accordion, { children: jsxRuntime.jsxs(reactCore.AccordionItem, { children: [jsxRuntime.jsx(reactCore.AccordionToggle, Object.assign({ id: `${ACCORDION_MARKDOWN_BUTTON_ID}-${accordionId}` }, { children: accordionHeading })), jsxRuntime.jsx(reactCore.AccordionContent, Object.assign({ id: `${ACCORDION_MARKDOWN_CONTENT_ID}-${accordionId}`, hidden: true }, { children: jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: sanitizedContent } }) }))] }) })));
|
|
1258
|
+
},
|
|
1259
|
+
}), []);
|
|
1260
|
+
|
|
1261
|
+
const AccordionShowdownHandler = ({ buttonElement, contentElement, }) => {
|
|
1262
|
+
const [expanded, setExpanded] = react.useState(false);
|
|
1263
|
+
const handleClick = () => {
|
|
1264
|
+
const newExpanded = !expanded;
|
|
1265
|
+
const expandedModifier = 'pf-m-expanded';
|
|
1266
|
+
// Find the accordion item element (parent of the button)
|
|
1267
|
+
const accordionItem = buttonElement.closest('.pf-v6-c-accordion__item');
|
|
1268
|
+
// Update button - both visual state and aria-expanded
|
|
1269
|
+
buttonElement.className = `pf-v6-c-accordion__toggle ${newExpanded ? expandedModifier : ''}`;
|
|
1270
|
+
buttonElement.setAttribute('aria-expanded', newExpanded.toString());
|
|
1271
|
+
// Update content - both visual state and hidden attribute
|
|
1272
|
+
contentElement.hidden = !newExpanded;
|
|
1273
|
+
contentElement.className = `pf-v6-c-accordion__expandable-content ${newExpanded ? expandedModifier : ''}`;
|
|
1274
|
+
// Update accordion item
|
|
1275
|
+
if (accordionItem) {
|
|
1276
|
+
accordionItem.className = `pf-v6-c-accordion__item ${newExpanded ? expandedModifier : ''}`;
|
|
1277
|
+
}
|
|
1278
|
+
setExpanded(newExpanded);
|
|
1279
|
+
};
|
|
1280
|
+
useEventListener(buttonElement, 'click', handleClick);
|
|
1281
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
1282
|
+
};
|
|
1283
|
+
const AccordionRenderExtension = ({ docContext }) => {
|
|
1284
|
+
const buttonElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_BUTTON_ID}]`);
|
|
1285
|
+
const contentElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_CONTENT_ID}]`);
|
|
1286
|
+
return buttonElements.length > 0 ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from(buttonElements).map((elm) => {
|
|
1287
|
+
const content = Array.from(contentElements).find((elm2) => {
|
|
1288
|
+
const elmId = elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1];
|
|
1289
|
+
const elm2Id = elm2.id.split(ACCORDION_MARKDOWN_CONTENT_ID)[1];
|
|
1290
|
+
return elmId === elm2Id;
|
|
1291
|
+
});
|
|
1292
|
+
return (jsxRuntime.jsx(AccordionShowdownHandler, { buttonElement: elm, contentElement: content }, elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1]));
|
|
1293
|
+
}) })) : null;
|
|
1294
|
+
};
|
|
1295
|
+
|
|
1296
|
+
const FallbackImg = ({ src, alt, className, fallback }) => {
|
|
1297
|
+
const [isSrcValid, setIsSrcValid] = react.useState(true);
|
|
1298
|
+
if (src && isSrcValid) {
|
|
1299
|
+
return jsxRuntime.jsx("img", { className: className, src: src, alt: alt, onError: () => setIsSrcValid(false) });
|
|
1300
|
+
}
|
|
1301
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1304
|
+
const DASH = '-';
|
|
1305
|
+
|
|
1306
|
+
const PopoverStatus = ({ hideHeader, children, isVisible = null, statusBody, title, onHide, onShow, }) => (jsxRuntime.jsx(reactCore.Popover, Object.assign({ position: reactCore.PopoverPosition.right, headerContent: hideHeader ? null : title, bodyContent: children, "aria-label": title, onHide: onHide, onShow: onShow, isVisible: isVisible }, { children: jsxRuntime.jsx(reactCore.Button, Object.assign({ variant: "link", isInline: true }, { children: statusBody })) })));
|
|
1307
|
+
|
|
1308
|
+
const StatusIconAndText = ({ icon, title, spin, iconOnly, noTooltip, className, }) => {
|
|
1309
|
+
if (!title) {
|
|
1310
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: DASH });
|
|
1311
|
+
}
|
|
1312
|
+
return (jsxRuntime.jsxs("span", Object.assign({ className: reactStyles.css('pfext-icon-and-text', className), title: iconOnly && !noTooltip ? title : undefined }, { children: [icon &&
|
|
1313
|
+
react.cloneElement(icon, {
|
|
1314
|
+
className: reactStyles.css(spin && 'fa-spin', icon.props.className, !iconOnly && 'pfext-icon-and-text__icon pfext-icon-flex-child'),
|
|
1315
|
+
}), !iconOnly && jsxRuntime.jsx(CamelCaseWrap, { value: title, dataTest: "status-text" })] })));
|
|
1316
|
+
};
|
|
1317
|
+
|
|
1318
|
+
const GenericStatus = (props) => {
|
|
1319
|
+
const { Icon, children, popoverTitle, title, noTooltip, iconOnly } = props, restProps = tslib.__rest(props, ["Icon", "children", "popoverTitle", "title", "noTooltip", "iconOnly"]);
|
|
1320
|
+
const renderIcon = iconOnly && !noTooltip ? jsxRuntime.jsx(Icon, { title: title }) : jsxRuntime.jsx(Icon, {});
|
|
1321
|
+
const statusBody = (jsxRuntime.jsx(StatusIconAndText, Object.assign({}, restProps, { noTooltip: noTooltip, title: title, iconOnly: iconOnly, icon: renderIcon })));
|
|
1322
|
+
return react.Children.toArray(children).length ? (jsxRuntime.jsx(PopoverStatus, Object.assign({ title: popoverTitle || title }, restProps, { statusBody: statusBody }, { children: children }))) : (statusBody);
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
const GreenCheckCircleIcon = ({ className, title, size }) => (jsxRuntime.jsx(reactCore.Icon, Object.assign({ size: size, status: "success" }, { children: jsxRuntime.jsx(CheckCircleIcon__default["default"], { "data-test": "success-icon", className: className, title: title }) })));
|
|
1326
|
+
|
|
1327
|
+
const SuccessStatus = (props) => (jsxRuntime.jsx(GenericStatus, Object.assign({}, props, { Icon: GreenCheckCircleIcon, title: props.title || 'Healthy' })));
|
|
1328
|
+
SuccessStatus.displayName = 'SuccessStatus';
|
|
1329
|
+
|
|
1330
|
+
const Status = ({ status, title, iconOnly, noTooltip, className }) => {
|
|
1331
|
+
const statusProps = { title: title || status, iconOnly, noTooltip, className };
|
|
1332
|
+
switch (status) {
|
|
1333
|
+
case 'In Progress':
|
|
1334
|
+
return jsxRuntime.jsx(StatusIconAndText, Object.assign({}, statusProps, { icon: jsxRuntime.jsx(SyncAltIcon__default["default"], {}) }));
|
|
1335
|
+
case 'Complete':
|
|
1336
|
+
return jsxRuntime.jsx(SuccessStatus, Object.assign({}, statusProps));
|
|
1337
|
+
default:
|
|
1338
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: status || DASH });
|
|
1339
|
+
}
|
|
1340
|
+
};
|
|
1341
|
+
const StatusIcon = ({ status }) => jsxRuntime.jsx(Status, { status: status, iconOnly: true });
|
|
1342
|
+
|
|
1194
1343
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1195
1344
|
const DOMPurify = require('dompurify');
|
|
1196
1345
|
const markdownConvert = (markdown, extensions) => tslib.__awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1202,7 +1351,7 @@ const markdownConvert = (markdown, extensions) => tslib.__awaiter(void 0, void 0
|
|
|
1202
1351
|
node.setAttribute('rel', 'noopener noreferrer');
|
|
1203
1352
|
return node;
|
|
1204
1353
|
}
|
|
1205
|
-
// add PF content classes
|
|
1354
|
+
// add PF content classes to standard elements (details blocks get handled separately)
|
|
1206
1355
|
if (node.nodeType === 1) {
|
|
1207
1356
|
const contentElements = [
|
|
1208
1357
|
'ul',
|
|
@@ -1253,13 +1402,82 @@ const markdownConvert = (markdown, extensions) => tslib.__awaiter(void 0, void 0
|
|
|
1253
1402
|
const reversedMarkdown = reverseString(markdown);
|
|
1254
1403
|
const reverseMarkdownWithSubstitutedCodeFences = reversedMarkdown.replace(/{{```((.|\n)*?)```/g, '{{@@@$1@@@');
|
|
1255
1404
|
const markdownWithSubstitutedCodeFences = reverseString(reverseMarkdownWithSubstitutedCodeFences);
|
|
1256
|
-
|
|
1405
|
+
// Fix malformed HTML entities early in the process
|
|
1406
|
+
let preprocessedMarkdown = markdownWithSubstitutedCodeFences;
|
|
1407
|
+
preprocessedMarkdown = preprocessedMarkdown
|
|
1408
|
+
.replace(/ ([^;])/g, ' $1')
|
|
1409
|
+
.replace(/&nbsp;/g, ' ');
|
|
1410
|
+
preprocessedMarkdown = preprocessedMarkdown.replace(/ (?![;])/g, ' ');
|
|
1411
|
+
// Process content in segments to ensure markdown parsing continues after HTML blocks
|
|
1412
|
+
const htmlBlockRegex = /(<(?:details|div|section|article)[^>]*>[\s\S]*?<\/(?:details|div|section|article)>)/g;
|
|
1413
|
+
let parsedMarkdown = '';
|
|
1414
|
+
// Check if there are any HTML blocks
|
|
1415
|
+
if (htmlBlockRegex.test(preprocessedMarkdown)) {
|
|
1416
|
+
// Reset regex for actual processing
|
|
1417
|
+
htmlBlockRegex.lastIndex = 0;
|
|
1418
|
+
let lastIndex = 0;
|
|
1419
|
+
let match;
|
|
1420
|
+
while ((match = htmlBlockRegex.exec(preprocessedMarkdown)) !== null) {
|
|
1421
|
+
// Process markdown before the HTML block
|
|
1422
|
+
const markdownBefore = preprocessedMarkdown.slice(lastIndex, match.index).trim();
|
|
1423
|
+
if (markdownBefore) {
|
|
1424
|
+
const parsed = yield marked.marked.parse(markdownBefore);
|
|
1425
|
+
parsedMarkdown += parsed;
|
|
1426
|
+
}
|
|
1427
|
+
// Process the HTML block: parse markdown content inside while preserving HTML structure
|
|
1428
|
+
let htmlBlock = match[1];
|
|
1429
|
+
// Find and process markdown content inside HTML tags
|
|
1430
|
+
const contentRegex = />(\s*[\s\S]*?)\s*</g;
|
|
1431
|
+
const contentMatches = [];
|
|
1432
|
+
let contentMatch;
|
|
1433
|
+
while ((contentMatch = contentRegex.exec(htmlBlock)) !== null) {
|
|
1434
|
+
const content = contentMatch[1];
|
|
1435
|
+
// Only process content that has markdown formatting but no extension syntax
|
|
1436
|
+
if (content.trim() &&
|
|
1437
|
+
!content.includes('{{') &&
|
|
1438
|
+
(content.includes('**') || content.includes('- ') || content.includes('\n'))) {
|
|
1439
|
+
// This looks like markdown content without extensions - parse it as block content
|
|
1440
|
+
const parsedContent = yield marked.marked.parse(content.trim());
|
|
1441
|
+
// Remove wrapping <p> tags if they exist since we're inside HTML already
|
|
1442
|
+
const cleanedContent = parsedContent.replace(/^<p[^>]*>([\s\S]*)<\/p>[\s]*$/g, '$1');
|
|
1443
|
+
contentMatches.push({
|
|
1444
|
+
original: contentMatch[0],
|
|
1445
|
+
replacement: `>${cleanedContent}<`,
|
|
1446
|
+
});
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
// Apply the content replacements
|
|
1450
|
+
contentMatches.forEach(({ original, replacement }) => {
|
|
1451
|
+
htmlBlock = htmlBlock.replace(original, replacement);
|
|
1452
|
+
});
|
|
1453
|
+
// Apply extensions (like admonitions) to the processed HTML block
|
|
1454
|
+
if (extensions) {
|
|
1455
|
+
extensions.forEach(({ regex, replace }) => {
|
|
1456
|
+
if (regex) {
|
|
1457
|
+
htmlBlock = htmlBlock.replace(regex, replace);
|
|
1458
|
+
}
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
parsedMarkdown += htmlBlock;
|
|
1462
|
+
lastIndex = htmlBlockRegex.lastIndex;
|
|
1463
|
+
}
|
|
1464
|
+
// Process any remaining markdown after the last HTML block
|
|
1465
|
+
const markdownAfter = preprocessedMarkdown.slice(lastIndex).trim();
|
|
1466
|
+
if (markdownAfter) {
|
|
1467
|
+
const parsed = yield marked.marked.parse(markdownAfter);
|
|
1468
|
+
parsedMarkdown += parsed;
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
else {
|
|
1472
|
+
// No HTML blocks found, process normally
|
|
1473
|
+
parsedMarkdown = yield marked.marked.parse(preprocessedMarkdown);
|
|
1474
|
+
}
|
|
1257
1475
|
// Swap the temporary tokens back to code fences before we run the extensions
|
|
1258
1476
|
let md = parsedMarkdown.replace(/@@@/g, '```');
|
|
1259
1477
|
if (extensions) {
|
|
1260
1478
|
// Convert code spans back to md format before we run the custom extension regexes
|
|
1261
1479
|
md = md.replace(/<code>(.*)<\/code>/g, '`$1`');
|
|
1262
|
-
extensions.forEach(({ regex, replace }) => {
|
|
1480
|
+
extensions.forEach(({ regex, replace }, _index) => {
|
|
1263
1481
|
if (regex) {
|
|
1264
1482
|
md = md.replace(regex, replace);
|
|
1265
1483
|
}
|
|
@@ -1324,7 +1542,7 @@ const RenderExtension = ({ renderExtension, selector, markup, docContext, }) =>
|
|
|
1324
1542
|
};
|
|
1325
1543
|
const InlineMarkdownView = ({ markup, isEmpty, renderExtension, className, }) => {
|
|
1326
1544
|
const id = react.useMemo(() => uniqueId('markdown'), []);
|
|
1327
|
-
return (jsxRuntime.jsxs("div", Object.assign({ className: reactStyles.css({ 'is-empty': isEmpty }, className), id: id }, { children: [jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: markup } }), renderExtension && (jsxRuntime.jsx(RenderExtension, { renderExtension: renderExtension, selector: `#${id}`, markup: markup }))] })));
|
|
1545
|
+
return (jsxRuntime.jsxs("div", Object.assign({ className: reactStyles.css({ 'is-empty': isEmpty }, className), id: id }, { children: [jsxRuntime.jsx("div", { style: { marginBlockEnd: 'var(--pf-t-global--spacer--md)' }, dangerouslySetInnerHTML: { __html: markup } }), renderExtension && (jsxRuntime.jsx(RenderExtension, { renderExtension: renderExtension, selector: `#${id}`, markup: markup }))] })));
|
|
1328
1546
|
};
|
|
1329
1547
|
const IFrameMarkdownView = ({ exactHeight, markup, isEmpty, renderExtension, className, }) => {
|
|
1330
1548
|
const [frame, setFrame] = react.useState();
|
|
@@ -1383,7 +1601,7 @@ const IFrameMarkdownView = ({ exactHeight, markup, isEmpty, renderExtension, cla
|
|
|
1383
1601
|
}
|
|
1384
1602
|
</style>
|
|
1385
1603
|
<body class="pf-m-redhat-font"><div style="overflow-y: auto;">${markup}</div></body>`;
|
|
1386
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("iframe", { sandbox: "allow-popups allow-popups-to-escape-sandbox allow-same-origin", srcDoc: contents, style: { border: '0px', display: 'block', width: '100%', height: '0' }, ref: (r) => {
|
|
1604
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("iframe", { title: "Markdown content preview", sandbox: "allow-popups allow-popups-to-escape-sandbox allow-same-origin", srcDoc: contents, style: { border: '0px', display: 'block', width: '100%', height: '0' }, ref: (r) => {
|
|
1387
1605
|
setFrame(r);
|
|
1388
1606
|
}, onLoad: () => onLoad(), className: className }), loaded && frame && renderExtension && (jsxRuntime.jsx(RenderExtension, { markup: markup, selector: '', renderExtension: renderExtension, docContext: frame.contentDocument }))] }));
|
|
1389
1607
|
};
|
|
@@ -1431,131 +1649,6 @@ const QuickStartMarkdownView = ({ content, exactHeight, className, }) => {
|
|
|
1431
1649
|
markdown.renderExtension(docContext, rootSelector)] })), className: className }));
|
|
1432
1650
|
};
|
|
1433
1651
|
|
|
1434
|
-
var AdmonitionType;
|
|
1435
|
-
(function (AdmonitionType) {
|
|
1436
|
-
AdmonitionType["TIP"] = "TIP";
|
|
1437
|
-
AdmonitionType["NOTE"] = "NOTE";
|
|
1438
|
-
AdmonitionType["IMPORTANT"] = "IMPORTANT";
|
|
1439
|
-
AdmonitionType["WARNING"] = "WARNING";
|
|
1440
|
-
AdmonitionType["CAUTION"] = "CAUTION";
|
|
1441
|
-
})(AdmonitionType || (AdmonitionType = {}));
|
|
1442
|
-
const admonitionToAlertVariantMap = {
|
|
1443
|
-
[AdmonitionType.NOTE]: { variant: 'info' },
|
|
1444
|
-
[AdmonitionType.TIP]: { variant: 'custom', customIcon: jsxRuntime.jsx(LightbulbIcon__default["default"], {}) },
|
|
1445
|
-
[AdmonitionType.IMPORTANT]: { variant: 'danger' },
|
|
1446
|
-
[AdmonitionType.CAUTION]: { variant: 'warning', customIcon: jsxRuntime.jsx(FireIcon__default["default"], {}) },
|
|
1447
|
-
[AdmonitionType.WARNING]: { variant: 'warning' },
|
|
1448
|
-
};
|
|
1449
|
-
const useAdmonitionShowdownExtension = () =>
|
|
1450
|
-
// const { getResource } = React.useContext<QuickStartContextValues>(QuickStartContext);
|
|
1451
|
-
react.useMemo(() => ({
|
|
1452
|
-
type: 'lang',
|
|
1453
|
-
regex: /\[(.+)]{{(admonition) ([\w-]+)}}/g,
|
|
1454
|
-
replace: (text, content, admonitionLabel, admonitionType, groupId) => {
|
|
1455
|
-
if (!content || !admonitionLabel || !admonitionType || !groupId) {
|
|
1456
|
-
return text;
|
|
1457
|
-
}
|
|
1458
|
-
admonitionType = admonitionType.toUpperCase();
|
|
1459
|
-
const { variant, customIcon } = admonitionToAlertVariantMap[admonitionType];
|
|
1460
|
-
const mdContent = jsxRuntime.jsx(QuickStartMarkdownView, { content: content });
|
|
1461
|
-
const pfAlert = (jsxRuntime.jsx(reactCore.Alert, Object.assign({ variant: variant }, (customIcon && { customIcon }), { isInline: true, title: admonitionType, className: "pfext-markdown-admonition" }, { children: mdContent })));
|
|
1462
|
-
return removeTemplateWhitespace(server.renderToStaticMarkup(pfAlert));
|
|
1463
|
-
},
|
|
1464
|
-
}), []);
|
|
1465
|
-
|
|
1466
|
-
const useCodeShowdownExtension = () => react.useMemo(() => ({
|
|
1467
|
-
type: 'output',
|
|
1468
|
-
regex: /<pre><code>(.*?)\n?<\/code><\/pre>/g,
|
|
1469
|
-
replace: (text, content) => {
|
|
1470
|
-
if (!content) {
|
|
1471
|
-
return text;
|
|
1472
|
-
}
|
|
1473
|
-
const pfCodeBlock = jsxRuntime.jsx(reactCore.CodeBlock, { children: content });
|
|
1474
|
-
return removeTemplateWhitespace(server.renderToStaticMarkup(pfCodeBlock));
|
|
1475
|
-
},
|
|
1476
|
-
}), []);
|
|
1477
|
-
|
|
1478
|
-
const useAccordionShowdownExtension = () => react.useMemo(() => ({
|
|
1479
|
-
type: 'lang',
|
|
1480
|
-
regex: /\[(.+)]{{(accordion) ("(.*?)")}}/g,
|
|
1481
|
-
replace: (_text, accordionContent, _command, accordionHeading) => {
|
|
1482
|
-
const accordionId = String(accordionHeading).replace(/\s/g, '-');
|
|
1483
|
-
return removeTemplateWhitespace(server.renderToStaticMarkup(jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsx(reactCore.Accordion, Object.assign({ asDefinitionList: true }, { children: jsxRuntime.jsxs(reactCore.AccordionItem, Object.assign({ isExpanded: false }, { children: [jsxRuntime.jsx(reactCore.AccordionToggle, Object.assign({ id: `${ACCORDION_MARKDOWN_BUTTON_ID}-${accordionId}` }, { children: accordionHeading })), jsxRuntime.jsx(reactCore.AccordionContent, Object.assign({ id: `${ACCORDION_MARKDOWN_CONTENT_ID}-${accordionId}` }, { children: accordionContent }))] })) })) })));
|
|
1484
|
-
},
|
|
1485
|
-
}), []);
|
|
1486
|
-
|
|
1487
|
-
const AccordionShowdownHandler = ({ buttonElement, contentElement, }) => {
|
|
1488
|
-
const [expanded, setExpanded] = react.useState(false);
|
|
1489
|
-
const handleClick = () => {
|
|
1490
|
-
const expandedModifier = 'pf-m-expanded';
|
|
1491
|
-
buttonElement.className = `pf-v6-c-accordion__toggle ${!expanded ? expandedModifier : ''}`;
|
|
1492
|
-
contentElement.hidden = expanded;
|
|
1493
|
-
contentElement.className = `pf-v6-c-accordion__expanded-content ${!expanded ? expandedModifier : ''}`;
|
|
1494
|
-
setExpanded(!expanded);
|
|
1495
|
-
};
|
|
1496
|
-
useEventListener(buttonElement, 'click', handleClick);
|
|
1497
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
1498
|
-
};
|
|
1499
|
-
const AccordionRenderExtension = ({ docContext }) => {
|
|
1500
|
-
const buttonElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_BUTTON_ID}]`);
|
|
1501
|
-
const contentElements = docContext.querySelectorAll(`[id ^= ${ACCORDION_MARKDOWN_CONTENT_ID}]`);
|
|
1502
|
-
return buttonElements.length > 0 ? (jsxRuntime.jsx(jsxRuntime.Fragment, { children: Array.from(buttonElements).map((elm) => {
|
|
1503
|
-
const content = Array.from(contentElements).find((elm2) => {
|
|
1504
|
-
const elmId = elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1];
|
|
1505
|
-
const elm2Id = elm2.id.split(ACCORDION_MARKDOWN_CONTENT_ID)[1];
|
|
1506
|
-
return elmId === elm2Id;
|
|
1507
|
-
});
|
|
1508
|
-
return (jsxRuntime.jsx(AccordionShowdownHandler, { buttonElement: elm, contentElement: content }, elm.id.split(ACCORDION_MARKDOWN_BUTTON_ID)[1]));
|
|
1509
|
-
}) })) : null;
|
|
1510
|
-
};
|
|
1511
|
-
|
|
1512
|
-
const FallbackImg = ({ src, alt, className, fallback }) => {
|
|
1513
|
-
const [isSrcValid, setIsSrcValid] = react.useState(true);
|
|
1514
|
-
if (src && isSrcValid) {
|
|
1515
|
-
return jsxRuntime.jsx("img", { className: className, src: src, alt: alt, onError: () => setIsSrcValid(false) });
|
|
1516
|
-
}
|
|
1517
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
|
|
1518
|
-
};
|
|
1519
|
-
|
|
1520
|
-
const DASH = '-';
|
|
1521
|
-
|
|
1522
|
-
const PopoverStatus = ({ hideHeader, children, isVisible = null, statusBody, title, onHide, onShow, }) => (jsxRuntime.jsx(reactCore.Popover, Object.assign({ position: reactCore.PopoverPosition.right, headerContent: hideHeader ? null : title, bodyContent: children, "aria-label": title, onHide: onHide, onShow: onShow, isVisible: isVisible }, { children: jsxRuntime.jsx(reactCore.Button, Object.assign({ variant: "link", isInline: true }, { children: statusBody })) })));
|
|
1523
|
-
|
|
1524
|
-
const StatusIconAndText = ({ icon, title, spin, iconOnly, noTooltip, className, }) => {
|
|
1525
|
-
if (!title) {
|
|
1526
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: DASH });
|
|
1527
|
-
}
|
|
1528
|
-
return (jsxRuntime.jsxs("span", Object.assign({ className: reactStyles.css('pfext-icon-and-text', className), title: iconOnly && !noTooltip ? title : undefined }, { children: [icon &&
|
|
1529
|
-
react.cloneElement(icon, {
|
|
1530
|
-
className: reactStyles.css(spin && 'fa-spin', icon.props.className, !iconOnly && 'pfext-icon-and-text__icon pfext-icon-flex-child'),
|
|
1531
|
-
}), !iconOnly && jsxRuntime.jsx(CamelCaseWrap, { value: title, dataTest: "status-text" })] })));
|
|
1532
|
-
};
|
|
1533
|
-
|
|
1534
|
-
const GenericStatus = (props) => {
|
|
1535
|
-
const { Icon, children, popoverTitle, title, noTooltip, iconOnly } = props, restProps = tslib.__rest(props, ["Icon", "children", "popoverTitle", "title", "noTooltip", "iconOnly"]);
|
|
1536
|
-
const renderIcon = iconOnly && !noTooltip ? jsxRuntime.jsx(Icon, { title: title }) : jsxRuntime.jsx(Icon, {});
|
|
1537
|
-
const statusBody = (jsxRuntime.jsx(StatusIconAndText, Object.assign({}, restProps, { noTooltip: noTooltip, title: title, iconOnly: iconOnly, icon: renderIcon })));
|
|
1538
|
-
return react.Children.toArray(children).length ? (jsxRuntime.jsx(PopoverStatus, Object.assign({ title: popoverTitle || title }, restProps, { statusBody: statusBody }, { children: children }))) : (statusBody);
|
|
1539
|
-
};
|
|
1540
|
-
|
|
1541
|
-
const GreenCheckCircleIcon = ({ className, title, size }) => (jsxRuntime.jsx(reactCore.Icon, Object.assign({ size: size, status: "success" }, { children: jsxRuntime.jsx(CheckCircleIcon__default["default"], { "data-test": "success-icon", className: className, title: title }) })));
|
|
1542
|
-
|
|
1543
|
-
const SuccessStatus = (props) => (jsxRuntime.jsx(GenericStatus, Object.assign({}, props, { Icon: GreenCheckCircleIcon, title: props.title || 'Healthy' })));
|
|
1544
|
-
SuccessStatus.displayName = 'SuccessStatus';
|
|
1545
|
-
|
|
1546
|
-
const Status = ({ status, title, iconOnly, noTooltip, className }) => {
|
|
1547
|
-
const statusProps = { title: title || status, iconOnly, noTooltip, className };
|
|
1548
|
-
switch (status) {
|
|
1549
|
-
case 'In Progress':
|
|
1550
|
-
return jsxRuntime.jsx(StatusIconAndText, Object.assign({}, statusProps, { icon: jsxRuntime.jsx(SyncAltIcon__default["default"], {}) }));
|
|
1551
|
-
case 'Complete':
|
|
1552
|
-
return jsxRuntime.jsx(SuccessStatus, Object.assign({}, statusProps));
|
|
1553
|
-
default:
|
|
1554
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, { children: status || DASH });
|
|
1555
|
-
}
|
|
1556
|
-
};
|
|
1557
|
-
const StatusIcon = ({ status }) => jsxRuntime.jsx(Status, { status: status, iconOnly: true });
|
|
1558
|
-
|
|
1559
1652
|
const QuickStartTileDescription = ({ description, prerequisites, }) => {
|
|
1560
1653
|
const { getResource } = react.useContext(QuickStartContext);
|
|
1561
1654
|
const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
|
|
@@ -1658,7 +1751,7 @@ const QuickStartCatalogFilterSelect = (_a) => {
|
|
|
1658
1751
|
};
|
|
1659
1752
|
const QuickStartCatalogFilterCount = ({ quickStartsCount }) => {
|
|
1660
1753
|
const { getResource } = react.useContext(QuickStartContext);
|
|
1661
|
-
return (jsxRuntime.jsx(reactCore.ToolbarItem, Object.assign({ align: { default: 'alignEnd' } }, { children: getResource('{{count, number}} item', quickStartsCount)
|
|
1754
|
+
return (jsxRuntime.jsx(reactCore.ToolbarItem, Object.assign({ align: { default: 'alignEnd' } }, { children: getResource('{{count, number}} item', quickStartsCount) })));
|
|
1662
1755
|
};
|
|
1663
1756
|
const QuickStartCatalogFilterSearchWrapper = ({ onSearchInputChange = () => { } }) => {
|
|
1664
1757
|
const { useQueryParams, filter, setFilter } = react.useContext(QuickStartContext);
|
|
@@ -1872,7 +1965,7 @@ const QuickStartIntroduction = ({ tasks, introduction, allTaskStatuses, prerequi
|
|
|
1872
1965
|
const prereqs = prerequisites === null || prerequisites === void 0 ? void 0 : prerequisites.filter((p) => p);
|
|
1873
1966
|
const [isPrereqsExpanded, setIsPrereqsExpanded] = react.useState(false);
|
|
1874
1967
|
const prereqList = (prereqs === null || prereqs === void 0 ? void 0 : prereqs.length) > 0 && (jsxRuntime.jsx(reactCore.ExpandableSection, Object.assign({ toggleText: getResource('View Prerequisites ({{totalPrereqs}})').replace('{{totalPrereqs}}', prereqs.length), onToggle: () => setIsPrereqsExpanded(!isPrereqsExpanded) }, { children: jsxRuntime.jsx(reactCore.List, { children: prereqs.map((pr) => (jsxRuntime.jsx(reactCore.ListItem, { children: jsxRuntime.jsx(QuickStartMarkdownView, { content: pr }) }, pr))) }) })));
|
|
1875
|
-
return (jsxRuntime.jsxs(reactCore.Stack, Object.assign({ hasGutter: true }, { children: [jsxRuntime.jsx(QuickStartMarkdownView, { content: introduction }), prereqList, jsxRuntime.jsxs("p", { children: [getResource('In this quick start, you will complete {{count, number}} task', tasks === null || tasks === void 0 ? void 0 : tasks.length).replace('{{count, number}}', (tasks === null || tasks === void 0 ? void 0 : tasks.length) || 0), ":"] }), jsxRuntime.jsx(QuickStartTaskHeaderList, { tasks: tasks, allTaskStatuses: allTaskStatuses, onTaskSelect: onTaskSelect })] })));
|
|
1968
|
+
return (jsxRuntime.jsxs(reactCore.Stack, Object.assign({ hasGutter: true }, { children: [jsxRuntime.jsx(QuickStartMarkdownView, { content: introduction }), prereqList, jsxRuntime.jsxs("p", { children: [getResource('In this quick start, you will complete {{count, number}} task', (tasks === null || tasks === void 0 ? void 0 : tasks.length) || 0).replace('{{count, number}}', (tasks === null || tasks === void 0 ? void 0 : tasks.length) || 0), ":"] }), jsxRuntime.jsx(QuickStartTaskHeaderList, { tasks: tasks, allTaskStatuses: allTaskStatuses, onTaskSelect: onTaskSelect })] })));
|
|
1876
1969
|
};
|
|
1877
1970
|
|
|
1878
1971
|
const getAlertVariant = (status) => {
|
|
@@ -2045,7 +2138,7 @@ const QuickStartPanelContent = (_a) => {
|
|
|
2045
2138
|
const QuickStartDrawerContent = (_a) => {
|
|
2046
2139
|
var { quickStarts = [], appendTo, fullWidth, handleDrawerClose } = _a, props = tslib.__rest(_a, ["quickStarts", "appendTo", "fullWidth", "handleDrawerClose"]);
|
|
2047
2140
|
const { activeQuickStartID, allQuickStarts = [], activeQuickStartState, } = react.useContext(QuickStartContext);
|
|
2048
|
-
const combinedQuickStarts = allQuickStarts.
|
|
2141
|
+
const combinedQuickStarts = [...allQuickStarts, ...quickStarts].filter((qs, idx, arr) => arr.findIndex((q) => q.metadata.name === qs.metadata.name) === idx);
|
|
2049
2142
|
const handleClose = () => {
|
|
2050
2143
|
handleDrawerClose && handleDrawerClose(activeQuickStartState === null || activeQuickStartState === void 0 ? void 0 : activeQuickStartState.status);
|
|
2051
2144
|
};
|