Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cockpit-d-installer for openSUSE:Factory checked in at 2023-03-08 14:54:01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cockpit-d-installer (Old) and /work/SRC/openSUSE:Factory/.cockpit-d-installer.new.31432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cockpit-d-installer" Wed Mar 8 14:54:01 2023 rev:4 rq:1070152 version:0 Changes: -------- --- /work/SRC/openSUSE:Factory/cockpit-d-installer/cockpit-d-installer.changes 2023-02-16 16:56:54.982955907 +0100 +++ /work/SRC/openSUSE:Factory/.cockpit-d-installer.new.31432/cockpit-d-installer.changes 2023-03-08 14:54:02.395155457 +0100 @@ -1,0 +2,18 @@ +Tue Feb 21 00:50:48 UTC 2023 - David Diaz <dgonza...@suse.com> + +- Set icons as aria-hidden (gh#yast/d-installer#437). + +------------------------------------------------------------------- +Mon Feb 20 22:52:48 UTC 2023 - David Diaz <dgonza...@suse.com> + +- Sidebar improvements (gh#yast/d-installer#436) + * Use proper control for open and close actions + * Improve styling and labels + * Add missing aria attributes + +------------------------------------------------------------------- +Thu Feb 16 12:56:24 UTC 2023 - Ladislav Slezák <lsle...@suse.com> + +- Integrate cockpit terminal application (gh#yast/d-installer#426) + +------------------------------------------------------------------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ d-installer.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/README.md new/d-installer/README.md --- old/d-installer/README.md 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/README.md 2023-03-01 09:03:42.000000000 +0100 @@ -17,14 +17,22 @@ Bear in mind that if something goes wrong while building the application (e.g., the linter fails), the link will not be created. -While working on the code, you might want to run the [webpack-dev-server](https://github.com/webpack/webpack-dev-server) to get the [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/) enabled. +While working on the code, you might want to run the [webpack-dev-server](https://github.com/webpack/webpack-dev-server) +to get the [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/) enabled. ``` npm run server ``` -Or simply run the Webpack watcher for refreshing the build every time you save a change **BUT** reloading -the code in your browser by yourself. +Unfortunately, it does not work remotely yet because it needs to connect to +'localhost'. You might workaround it by just using the browser from the VM +through SSH (e.g., "ssh -X yourmachine firefox" -or chromium-). + +Thus, if live reloading does not work for you, using the Webpack watcher for +refreshing the build every time a file is changed still being an option through +the command below. But please, do not forget that you have to reload the code +in your browser manually. + ``` npm run watch diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/__mocks__/svg.js new/d-installer/__mocks__/svg.js --- old/d-installer/__mocks__/svg.js 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/__mocks__/svg.js 2023-03-01 09:03:42.000000000 +0100 @@ -1,8 +1,8 @@ import React from 'react'; -export default () => ( +export default ({...props}) => ( // Simple SVG square based on a wikimedia example https://commons.wikimedia.org/wiki/SVG_examples - <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="48" height="48"> + <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="48" height="48" {...props}> <rect x="0" y="0" width="48" height="48" /> </svg> ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/package/cockpit-d-installer.changes new/d-installer/package/cockpit-d-installer.changes --- old/d-installer/package/cockpit-d-installer.changes 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/package/cockpit-d-installer.changes 2023-03-01 09:03:42.000000000 +0100 @@ -1,4 +1,22 @@ ------------------------------------------------------------------- +Tue Feb 21 00:50:48 UTC 2023 - David Diaz <dgonza...@suse.com> + +- Set icons as aria-hidden (gh#yast/d-installer#437). + +------------------------------------------------------------------- +Mon Feb 20 22:52:48 UTC 2023 - David Diaz <dgonza...@suse.com> + +- Sidebar improvements (gh#yast/d-installer#436) + * Use proper control for open and close actions + * Improve styling and labels + * Add missing aria attributes + +------------------------------------------------------------------- +Thu Feb 16 12:56:24 UTC 2023 - Ladislav Slezák <lsle...@suse.com> + +- Integrate cockpit terminal application (gh#yast/d-installer#426) + +------------------------------------------------------------------- Wed Feb 15 16:35:54 UTC 2023 - Imobach Gonzalez Sosa <igonzalezs...@suse.com> - Version 0.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/assets/styles/blocks.scss new/d-installer/src/assets/styles/blocks.scss --- old/d-installer/src/assets/styles/blocks.scss 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/src/assets/styles/blocks.scss 2023-03-01 09:03:42.000000000 +0100 @@ -64,6 +64,10 @@ box-shadow: 0 0 20px 10px var(--color-primary-darkest); } +.sidebar header { + --focus-color: var(--color-primary-darkest); +} + .sidebar footer { border-top: 1px solid var(--color-gray); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/assets/styles/layout.scss new/d-installer/src/assets/styles/layout.scss --- old/d-installer/src/assets/styles/layout.scss 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/src/assets/styles/layout.scss 2023-03-01 09:03:42.000000000 +0100 @@ -28,12 +28,13 @@ } .wrapper > header { - --color-button-plain-link: white; - --color-button-plain-link-hover: #fcfcfc; - grid-area: header; background: var(--color-background-primary); color: var(--color-text-secondary); + + svg { + color: white; + } } .wrapper > main { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/assets/styles/utilities.scss new/d-installer/src/assets/styles/utilities.scss --- old/d-installer/src/assets/styles/utilities.scss 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/src/assets/styles/utilities.scss 2023-03-01 09:03:42.000000000 +0100 @@ -99,6 +99,11 @@ box-shadow: 0 -3px 10px 0 var(--color-gray-darker); } +.plain-control { + background: none; + border: none; +} + .tallest { /** block-size fallbacks **/ height: 95dvh; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/components/core/ShowTerminalButton.jsx new/d-installer/src/components/core/ShowTerminalButton.jsx --- old/d-installer/src/components/core/ShowTerminalButton.jsx 1970-01-01 01:00:00.000000000 +0100 +++ new/d-installer/src/components/core/ShowTerminalButton.jsx 2023-03-01 09:03:42.000000000 +0100 @@ -0,0 +1,64 @@ +/* + * Copyright (c) [2023] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +import React, { useState } from "react"; +import { Button } from "@patternfly/react-core"; + +import { Terminal } from "~/components/core"; +import { Icon } from "~/components/layout"; + +/** + * Button for displaying the terminal application + * + * @component + * + * @param {function} onClickCallback callback triggered after clicking the button + */ +const ShowTerminalButton = ({ onClickCallback }) => { + const [isTermDisplayed, setIsTermDisplayed] = useState(false); + + const onClick = () => { + if (onClickCallback) onClickCallback(); + setIsTermDisplayed(true); + }; + + const onClose = () => { + setIsTermDisplayed(false); + }; + + return ( + <> + <Button + variant="link" + onClick={onClick} + isDisabled={isTermDisplayed} + icon={<Icon name="terminal" size="24" />} + > + Terminal + </Button> + + { isTermDisplayed && + <Terminal onCloseCallback={onClose} /> } + </> + ); +}; + +export default ShowTerminalButton; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/components/core/ShowTerminalButton.test.jsx new/d-installer/src/components/core/ShowTerminalButton.test.jsx --- old/d-installer/src/components/core/ShowTerminalButton.test.jsx 1970-01-01 01:00:00.000000000 +0100 +++ new/d-installer/src/components/core/ShowTerminalButton.test.jsx 2023-03-01 09:03:42.000000000 +0100 @@ -0,0 +1,41 @@ +/* + * Copyright (c) [2023] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +import React from "react"; +import { screen } from "@testing-library/react"; +import { plainRender, mockComponent } from "~/test-utils"; +import { ShowTerminalButton } from "~/components/core"; + +jest.mock("~/components/core/Terminal", () => mockComponent("Terminal Mock")); + +describe("ShowTerminalButton", () => { + it("renders a button that displays <Terminal> after clicking", async () => { + const { user } = plainRender(<ShowTerminalButton />); + const button = screen.getByRole("button", "Terminal"); + + // no terminal displayed just after the render + expect(screen.queryByText(/Terminal Mock/)).not.toBeInTheDocument(); + + await user.click(button); + // it is displayed after clicking the button + screen.getByText(/Terminal Mock/); + }); +}); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/components/core/Sidebar.jsx new/d-installer/src/components/core/Sidebar.jsx --- old/d-installer/src/components/core/Sidebar.jsx 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/src/components/core/Sidebar.jsx 2023-03-01 09:03:42.000000000 +0100 @@ -19,9 +19,9 @@ * find current contact information at www.suse.com. */ -import React, { useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { Icon, PageActions } from "~/components/layout"; -import { About, ChangeProductButton, LogsButton, ShowLogButton } from "~/components/core"; +import { About, ChangeProductButton, LogsButton, ShowLogButton, ShowTerminalButton } from "~/components/core"; import { TargetIpsPopup } from "~/components/network"; /** @@ -29,34 +29,46 @@ */ export default function Sidebar() { const [isOpen, setIsOpen] = useState(false); + const closeButtonRef = useRef(null); - const open = (e) => { - // Avoid the link navigating to the initial route - e.preventDefault(); - - setIsOpen(true); - }; + const open = () => setIsOpen(true); const close = () => setIsOpen(false); + useEffect(() => { + if (isOpen) closeButtonRef.current.focus(); + }, [isOpen]); + return ( <> <PageActions> - <a href="#" onClick={open} aria-label="Open D-Installer options"> + <button + onClick={open} + className="plain-control" + aria-label="Show navigation and other options" + aria-controls="navigation-and-options" + aria-expanded={isOpen} + > <Icon name="menu" onClick={open} /> - </a> + </button> </PageActions> <nav - aria-label="D-Installer options" - data-state={isOpen ? "visible" : "hidden"} + id="navigation-and-options" className="wrapper sidebar" + aria-label="Navigation and other options" + data-state={isOpen ? "visible" : "hidden"} > <header className="split justify-between"> <h1>Options</h1> - <a href="#" onClick={close} aria-label="Close D-Installer options"> + <button + onClick={close} + ref={closeButtonRef} + className="plain-control" + aria-label="Hide navigation and other options" + > <Icon name="menu_open" data-variant="flip-X" onClick={close} /> - </a> + </button> </header> <div className="flex-stack"> @@ -65,6 +77,7 @@ <TargetIpsPopup onClickCallback={close} /> <LogsButton /> <ShowLogButton onClickCallback={close} /> + <ShowTerminalButton onClickCallback={close} /> </div> <footer className="split" data-state="reversed"> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/components/core/Sidebar.test.jsx new/d-installer/src/components/core/Sidebar.test.jsx --- old/d-installer/src/components/core/Sidebar.test.jsx 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/src/components/core/Sidebar.test.jsx 2023-03-01 09:03:42.000000000 +0100 @@ -20,7 +20,7 @@ */ import React from "react"; -import { screen, within, createEvent, fireEvent } from "@testing-library/react"; +import { screen, within } from "@testing-library/react"; import { plainRender, mockComponent, mockLayout } from "~/test-utils"; import { Sidebar } from "~/components/core"; @@ -39,7 +39,7 @@ it("renders a link for displaying the sidebar", async () => { const { user } = plainRender(<Sidebar />); - const link = await screen.findByLabelText(/Open/i); + const link = await screen.findByLabelText(/Show/i); const nav = await screen.findByRole("navigation", { name: /options/i }); expect(nav).toHaveAttribute("data-state", "hidden"); @@ -47,23 +47,11 @@ expect(nav).toHaveAttribute("data-state", "visible"); }); -// Test that opening the sidebar does not navigate to the initial route -// This is achive by preventing the default link click behavior -// Read https://testing-library.com/docs/dom-testing-library/api-events#fireevent and -// https://developer.mozilla.org/en-US/docs/Web/API/Event/defaultPrevented -it("prevents the default event when the user click on the open link", async () => { - plainRender(<Sidebar />); - const link = await screen.findByLabelText(/Open/i); - const clickEvent = createEvent.click(link); - fireEvent(link, clickEvent); - expect(clickEvent.defaultPrevented).toBe(true); -}); - it("renders a link for hidding the sidebar", async () => { const { user } = plainRender(<Sidebar />); - const openLink = await screen.findByLabelText(/Open/i); - const closeLink = await screen.findByLabelText(/Close/i); + const openLink = await screen.findByLabelText(/Show/i); + const closeLink = await screen.findByLabelText(/Hide/i); const nav = await screen.findByRole("navigation", { name: /options/i }); @@ -73,6 +61,17 @@ expect(nav).toHaveAttribute("data-state", "hidden"); }); +it("moves the focus to the close action after opening it", async () => { + const { user } = plainRender(<Sidebar />); + + const openLink = await screen.findByLabelText(/Show/i); + const closeLink = await screen.findByLabelText(/Hide/i); + + expect(closeLink).not.toHaveFocus(); + await user.click(openLink); + expect(closeLink).toHaveFocus(); +}); + describe("Sidebar content", () => { it("contains the component for changing the selected product", async () => { plainRender(<Sidebar />); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/components/core/Terminal.jsx new/d-installer/src/components/core/Terminal.jsx --- old/d-installer/src/components/core/Terminal.jsx 1970-01-01 01:00:00.000000000 +0100 +++ new/d-installer/src/components/core/Terminal.jsx 2023-03-01 09:03:42.000000000 +0100 @@ -0,0 +1,52 @@ +/* + * Copyright (c) [2023] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +import React, { useState } from "react"; +import { Popup } from "~/components/core"; + +export default function Terminal({ onCloseCallback }) { + // the popup is visible + const [isOpen, setIsOpen] = useState(true); + + const close = () => { + setIsOpen(false); + if (onCloseCallback) onCloseCallback(); + }; + + // embed the cockpit terminal into an iframe, see + // https://cockpit-project.org/guide/latest/embedding.html#embedding-components + // https://cockpit-project.org/guide/latest/api-terminal-html.html + return ( + <Popup + isOpen={isOpen} + variant="large" + className="tallest" + aria-label="terminal popup" + > + + <iframe className="vertically-centered" src="/cockpit/@localhost/system/terminal.html" /> + + <Popup.Actions> + <Popup.Confirm onClick={close} autoFocus>Close</Popup.Confirm> + </Popup.Actions> + </Popup> + ); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/components/core/Terminal.test.jsx new/d-installer/src/components/core/Terminal.test.jsx --- old/d-installer/src/components/core/Terminal.test.jsx 1970-01-01 01:00:00.000000000 +0100 +++ new/d-installer/src/components/core/Terminal.test.jsx 2023-03-01 09:03:42.000000000 +0100 @@ -0,0 +1,57 @@ +/* + * Copyright (c) [2023] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +import React from "react"; + +import { screen, waitFor, within } from "@testing-library/react"; +import { plainRender } from "~/test-utils"; +import { Terminal } from "~/components/core"; + +describe("Terminal", () => { + it("displays the cockpit terminal in an iframe", async () => { + plainRender(<Terminal />); + const dialog = await screen.findByRole("dialog"); + const iframe = dialog.querySelector("iframe"); + expect(iframe.src).toMatch(/cockpit\/@localhost\/system\/terminal.html/); + }); + + it("closes the popup after clicking the close button", async () => { + const { user } = plainRender(<Terminal />); + const dialog = await screen.findByRole("dialog"); + const closeButton = within(dialog).getByRole("button", { name: /Close/i }); + + await user.click(closeButton); + await waitFor(() => { + expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); + }); + }); + + it("triggers the onCloseCallback after clicking the close button", async () => { + const callback = jest.fn(); + const { user } = plainRender(<Terminal onCloseCallback={callback} />); + const dialog = await screen.findByRole("dialog"); + const closeButton = within(dialog).getByRole("button", { name: /Close/i }); + + await user.click(closeButton); + + expect(callback).toHaveBeenCalled(); + }); +}); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/components/core/index.js new/d-installer/src/components/core/index.js --- old/d-installer/src/components/core/index.js 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/src/components/core/index.js 2023-03-01 09:03:42.000000000 +0100 @@ -40,3 +40,5 @@ export { default as ProgressText } from "./ProgressText"; export { default as ChangeProductButton } from "./ChangeProductButton"; export { default as ValidationErrors } from "./ValidationErrors"; +export { default as Terminal } from "./Terminal"; +export { default as ShowTerminalButton } from "./ShowTerminalButton"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/components/layout/Icon.jsx new/d-installer/src/components/layout/Icon.jsx --- old/d-installer/src/components/layout/Icon.jsx 2023-02-15 17:42:25.000000000 +0100 +++ new/d-installer/src/components/layout/Icon.jsx 2023-03-01 09:03:42.000000000 +0100 @@ -23,37 +23,39 @@ // NOTE: "@icons" is an alias to use a shorter path to real icons location. // Check the tsconfig.json file to see its value. -import Inventory from "@icons/inventory_2.svg?component"; -import Translate from "@icons/translate.svg?component"; -import SettingsEthernet from "@icons/settings_ethernet.svg?component"; -import EditSquare from "@icons/edit_square.svg?component"; -import Edit from "@icons/edit.svg?component"; +import Apps from "@icons/apps.svg?component"; +import CheckCircle from "@icons/check_circle.svg?component"; +import Delete from "@icons/delete.svg?component"; +import Description from "@icons/description.svg?component"; import Download from "@icons/download.svg?component"; +import Downloading from "@icons/downloading.svg?component"; +import Edit from "@icons/edit.svg?component"; +import EditSquare from "@icons/edit_square.svg?component"; +import Error from "@icons/error.svg?component"; import HardDrive from "@icons/hard_drive.svg?component"; import Help from "@icons/help.svg?component"; +import HomeStorage from "@icons/home_storage.svg?component"; +import Info from "@icons/info.svg?component"; +import Inventory from "@icons/inventory_2.svg?component"; +import Lan from "@icons/lan.svg?component"; +import Lock from "@icons/lock.svg?component"; import ManageAccounts from "@icons/manage_accounts.svg?component"; import Menu from "@icons/menu.svg?component"; import MenuOpen from "@icons/menu_open.svg?component"; -import HomeStorage from "@icons/home_storage.svg?component"; -import Problem from "@icons/problem.svg?component"; -import Error from "@icons/error.svg?component"; -import CheckCircle from "@icons/check_circle.svg?component"; -import TaskAlt from "@icons/task_alt.svg?component"; -import Downloading from "@icons/downloading.svg?component"; import MoreVert from "@icons/more_vert.svg?component"; -import Wifi from "@icons/wifi.svg?component"; -import Lan from "@icons/lan.svg?component"; -import Lock from "@icons/lock.svg?component"; -import SignalCellularAlt from "@icons/signal_cellular_alt.svg?component"; -import SettingsFill from "@icons/settings-fill.svg?component"; +import Problem from "@icons/problem.svg?component"; +import Refresh from "@icons/refresh.svg?component"; import SettingsApplications from "@icons/settings_applications.svg?component"; -import Info from "@icons/info.svg?component"; -import Delete from "@icons/delete.svg?component"; +import SettingsEthernet from "@icons/settings_ethernet.svg?component"; +import SettingsFill from "@icons/settings-fill.svg?component"; +import SignalCellularAlt from "@icons/signal_cellular_alt.svg?component"; +import TaskAlt from "@icons/task_alt.svg?component"; +import Terminal from "@icons/terminal.svg?component"; +import Translate from "@icons/translate.svg?component"; import Warning from "@icons/warning.svg?component"; -import Apps from "@icons/apps.svg?component"; +import Wifi from "@icons/wifi.svg?component"; + import Loading from "./three-dots-loader-icon.svg?component"; -import Description from "@icons/description.svg?component"; -import Refresh from "@icons/refresh.svg?component"; const icons = { apps: Apps, @@ -78,15 +80,16 @@ menu_open: MenuOpen, more_vert: MoreVert, problem: Problem, + refresh: Refresh, settings: SettingsFill, settings_applications: SettingsApplications, settings_ethernet: SettingsEthernet, signal_cellular_alt: SignalCellularAlt, task_alt: TaskAlt, + terminal: Terminal, translate: Translate, warning: Warning, - wifi: Wifi, - refresh: Refresh + wifi: Wifi }; /** @@ -105,14 +108,16 @@ * * @param {object} props - component props * @param {string} props.name - desired icon + * @param {string} [props.className=""] - CSS classes * @param {string|number} [props.size=32] - the icon width and height * @param {object} [props.otherProps] other props sent to SVG icon * */ -export default function Icon({ name, size = 32, ...otherProps }) { +export default function Icon({ name, className = "", size = 32, ...otherProps }) { const IconComponent = icons[name]; + const cssClassName = `${className} icon-size-${size}`.trim(); return (IconComponent) - ? <IconComponent className={`icon-size-${size}`} {...otherProps} /> - : <em>`icon ${name} not found!`</em>; + ? <IconComponent className={cssClassName} aria-hidden="true" {...otherProps} /> + : <em>icon {name} not found!</em>; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/d-installer/src/components/layout/Icon.test.jsx new/d-installer/src/components/layout/Icon.test.jsx --- old/d-installer/src/components/layout/Icon.test.jsx 1970-01-01 01:00:00.000000000 +0100 +++ new/d-installer/src/components/layout/Icon.test.jsx 2023-03-01 09:03:42.000000000 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) [2023] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +import React from "react"; +import { screen } from "@testing-library/react"; +import { plainRender } from "~/test-utils"; +import { Icon } from "~/components/layout"; + +describe("when given a known name", () => { + it("renders an aria-hidden SVG element", async () => { + const { container } = plainRender(<Icon name="wifi" />); + const svgElement = container.querySelector('svg'); + expect(svgElement).toHaveAttribute("aria-hidden", "true"); + }); +}); + +describe("when given an unknown name", () => { + it("renders an informative text", async () => { + plainRender(<Icon name="apsens" />); + await screen.findByText("icon apsens not found!", { name: /options/i }); + }); +}); ++++++ d-installer.obsinfo ++++++ --- /var/tmp/diff_new_pack.z4Kcix/_old 2023-03-08 14:54:07.583183708 +0100 +++ /var/tmp/diff_new_pack.z4Kcix/_new 2023-03-08 14:54:07.607183838 +0100 @@ -1,5 +1,5 @@ name: d-installer -version: 0.7.763a7e4 -mtime: 1676479345 -commit: 763a7e4d1e1540960b84e3b08674cdb7364f4b7d +version: 0.7.40780d13 +mtime: 1677657822 +commit: 40780d13fede321540d52a46f041d9300014943d ++++++ node_modules.obscpio ++++++ /work/SRC/openSUSE:Factory/cockpit-d-installer/node_modules.obscpio /work/SRC/openSUSE:Factory/.cockpit-d-installer.new.31432/node_modules.obscpio differ: char 49, line 1