LCOV - code coverage report
Current view: top level - pkg/playground - react-patterns.tsx Coverage Total Hit
Test: cockpit Lines: 47.1 % 136 64
Test Date: 2026-07-17 14:32:59

            Line data    Source code
       1              : /*
       2              :  * Copyright (C) 2025 Red Hat, Inc.
       3              :  * SPDX-License-Identifier: LGPL-2.1-or-later
       4              :  */
       5              : 
       6            5 : import cockpit from "cockpit";
       7            5 : import React from "react";
       8            5 : import { createRoot, Container } from 'react-dom/client';
       9              : 
      10              : import '../lib/patternfly/patternfly-6-cockpit.scss';
      11              : 
      12              : import { Page, PageSection } from "@patternfly/react-core/dist/esm/components/Page/index.js";
      13              : import { Button } from "@patternfly/react-core/dist/esm/components/Button/index.js";
      14              : import { show_modal_dialog } from "cockpit-components-dialog.jsx";
      15              : 
      16              : import { PatternDialogBody } from "./react-demo-dialog";
      17              : import { FileAcDemo, FileAcDemoPreselected } from "./react-demo-file-autocomplete";
      18              : import { TypeaheadDemo } from "./react-demo-typeahead";
      19              : import { MultiTypeaheadDemo } from "./react-demo-multi-typeahead";
      20              : import { CardsDemo } from "./react-demo-cards";
      21              : import { UploadDemo } from "./react-demo-file-upload";
      22              : 
      23              : import 'cockpit-dark-theme'; // once per page
      24              : import 'page.scss';
      25              : 
      26              : /* -----------------------------------------------------------------------------
      27              :   Modal Dialog
      28              :   -----------------------------------------------------------------------------
      29              :  */
      30              : 
      31            5 : let lastAction: string = "";
      32              : 
      33            0 : const onDialogStandardClicked = function(mode: string, progress_cb: (text: string, cancel?: () => void) => void) {
      34            0 :     lastAction = mode;
      35              : 
      36            0 :     return new Promise<void>((resolve, reject) => {
      37            0 :         progress_cb("Starting something long");
      38            0 :         if (mode == 'steps') {
      39            0 :             let interval: number = 0;
      40            0 :             const cancel = function() {
      41            0 :                 window.clearTimeout(interval);
      42            0 :                 progress_cb("Canceling");
      43            0 :                 window.setTimeout(function() {
      44            0 :                     reject(new Error("Action canceled"));
      45            0 :                 }, 1000);
      46            0 :             };
      47            0 :             let count = 0;
      48            0 :             interval = window.setInterval(function() {
      49            0 :                 count += 1;
      50            0 :                 progress_cb("Step " + count, cancel);
      51            0 :             }, 500);
      52            0 :             window.setTimeout(function() {
      53            0 :                 window.clearTimeout(interval);
      54            0 :                 resolve();
      55            0 :             }, 5000);
      56            0 :         } else if (mode == 'reject') {
      57            0 :             reject(new Error("Some error occurred"));
      58            0 :         } else {
      59            0 :             resolve();
      60            0 :         }
      61            0 :     });
      62            0 : };
      63              : 
      64            0 : const onDialogDone = function(success: boolean) {
      65            0 :     const result = success ? "successful" : "Canceled";
      66            0 :     const action = success ? lastAction : "no action";
      67            0 :     document.getElementById("demo-dialog-result")!.textContent = "Dialog closed: " + result + "(" + action + ")";
      68            0 : };
      69              : 
      70            0 : const onStandardDemoClicked = (staticError: React.ReactNode) => {
      71            0 :     const dialogProps = {
      72            0 :         title: "This shouldn't be seen",
      73            0 :         body: React.createElement(PatternDialogBody, { clickNested: onStandardDemoClicked }),
      74            0 :         static_error: staticError,
      75            0 :     };
      76              :     // also test modifying properties in subsequent render calls
      77            0 :     const footerProps = {
      78            0 :         actions: [
      79            0 :             {
      80            0 :                 clicked: onDialogStandardClicked.bind(null, 'standard action'),
      81            0 :                 caption: "OK",
      82            0 :                 style: 'primary',
      83            0 :             },
      84            0 :             {
      85            0 :                 clicked: onDialogStandardClicked.bind(null, 'dangerous action'),
      86            0 :                 caption: "Danger",
      87            0 :                 style: 'danger',
      88            0 :             },
      89            0 :             {
      90            0 :                 clicked: onDialogStandardClicked.bind(null, 'steps'),
      91            0 :                 caption: "Wait",
      92            0 :             },
      93            0 :         ],
      94            0 :         dialog_done: onDialogDone,
      95            0 :     };
      96            0 :     const dialogObj = show_modal_dialog(dialogProps, footerProps);
      97              :     // if this failed, exit (trying to create a nested dialog)
      98            0 :     if (!dialogObj)
      99            0 :         return;
     100            0 :     footerProps.actions.push(
     101            0 :         {
     102            0 :             clicked: onDialogStandardClicked.bind(null, 'reject'),
     103            0 :             caption: "Error",
     104            0 :             style: 'primary',
     105            0 :         });
     106            0 :     dialogObj.setFooterProps(footerProps);
     107            0 :     dialogProps.title = "Example React Dialog";
     108            0 :     dialogObj.setProps(dialogProps);
     109            0 : };
     110              : 
     111            5 : const ReactPatterns = () => {
     112            5 :     const narrow = { maxWidth: 600 };
     113              : 
     114            5 :     return (
     115            5 :         <Page isContentFilled className="no-masthead-sidebar">
     116            5 :             <PageSection>
     117            5 :                 <h3>Select file</h3>
     118            5 :                 <div id="demo-file-ac" style={narrow}>
     119            5 :                     <FileAcDemo />
     120            5 :                 </div>
     121            5 :                 <div id="demo-file-ac-preselected" style={narrow}>
     122            5 :                     <FileAcDemoPreselected />
     123            5 :                 </div>
     124            5 :             </PageSection>
     125              : 
     126            5 :             <PageSection id="demo-typeahead">
     127            5 :                 <h3>Typeahead</h3>
     128            5 :                 <div style={narrow}>
     129            5 :                     <TypeaheadDemo />
     130            5 :                 </div>
     131            5 :             </PageSection>
     132              : 
     133            5 :             <PageSection id="demo-multi-typeahead">
     134            5 :                 <h3>Multi Typeahead</h3>
     135            5 :                 <div style={narrow}>
     136            5 :                     <MultiTypeaheadDemo />
     137            5 :                 </div>
     138            5 :             </PageSection>
     139              : 
     140            5 :             <PageSection>
     141            5 :                 <h3>Dialogs</h3>
     142            5 :                 <Button
     143            5 :                     id="demo-show-dialog"
     144            5 :                     onClick={onStandardDemoClicked.bind(null, null)}
     145            5 :                 >
     146              :                     Show Dialog
     147            5 :                 </Button>
     148            5 :                 <Button
     149            5 :                     id="demo-show-error-dialog"
     150            5 :                     onClick={onStandardDemoClicked.bind(null, 'Some static error')}
     151            5 :                 >
     152              :                     Show Error-Dialog
     153            5 :                 </Button>
     154            5 :                 <div id="demo-dialog-result" />
     155            5 :             </PageSection>
     156              : 
     157            5 :             <PageSection>
     158            5 :                 <h3>Cards</h3>
     159            5 :                 <CardsDemo />
     160            5 :             </PageSection>
     161              : 
     162            5 :             <PageSection id="demo-upload">
     163            5 :                 <h3>Upload</h3>
     164            5 :                 <div style={narrow}>
     165            5 :                     <UploadDemo />
     166            5 :                 </div>
     167            5 :             </PageSection>
     168            5 :         </Page>
     169              :     );
     170            5 : };
     171              : 
     172            5 : function init_app(rootElement: Container) {
     173            5 :     const root = createRoot(rootElement);
     174            5 :     root.render(<ReactPatterns />);
     175            5 : }
     176              : 
     177            5 : document.addEventListener("DOMContentLoaded", function() {
     178            5 :     cockpit.transport.wait(function() {
     179            5 :         init_app(document.getElementById('app')!);
     180            5 :     });
     181            5 : });
        

Generated by: LCOV version 2.0-1