diff --git a/.eslintrc.json b/.eslintrc.json index d499b3eb..08c37301 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,12 +4,11 @@ "browser": true, "es6": true }, - "extends": ["eslint:recommended", "standard", "standard-jsx", "standard-react"], + "extends": ["eslint:recommended", "standard"], "parserOptions": { "ecmaVersion": "2022", "sourceType": "module" }, - "plugins": ["react", "react-hooks"], "rules": { "indent": ["error", 4, { @@ -22,12 +21,8 @@ "no-var": "error", "lines-between-class-members": ["error", "always", { "exceptAfterSingleLine": true }], "prefer-promise-reject-errors": ["error", { "allowEmptyReject": true }], - "react/jsx-indent": ["error", 4], "semi": ["error", "always", { "omitLastInOneLineBlock": true }], - "react-hooks/rules-of-hooks": "error", - "react-hooks/exhaustive-deps": "error", - "camelcase": "off", "comma-dangle": "off", "curly": "off", @@ -35,10 +30,6 @@ "key-spacing": "off", "no-console": "off", "quotes": "off", - "react/jsx-curly-spacing": "off", - "react/jsx-indent-props": "off", - "react/jsx-no-useless-fragment": "error", - "react/prop-types": "off", "space-before-function-paren": "off", "standard/no-callback-literal": "off" }, diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0526b5fc..dd9e50bb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -30,10 +30,6 @@ updates: - "types*" ignore: - # https://github.com/cockpit-project/cockpit/issues/21151 - - dependency-name: "sass" - versions: [">=1.80.0", "2.x"] - # needs to be done in Cockpit first - dependency-name: "@patternfly/*" update-types: ["version-update:semver-major"] diff --git a/package.json b/package.json index 3b97fab7..d412d6e0 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,6 @@ "stylelint:fix": "stylelint --fix src/*{.css,scss}" }, "devDependencies": { - "@types/react": "18.3.12", - "@types/react-dom": "18.3.1", "@typescript-eslint/eslint-plugin": "8.15.0", "argparse": "2.0.1", "esbuild": "0.24.0", @@ -30,18 +28,14 @@ "eslint": "8.57.1", "eslint-config-standard": "17.1.0", "eslint-config-standard-jsx": "11.0.0", - "eslint-config-standard-react": "13.0.0", "eslint-plugin-import": "2.31.0", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "6.6.0", - "eslint-plugin-react": "7.37.2", - "eslint-plugin-react-hooks": "4.6.2", "gettext-parser": "8.0.0", "glob": "11.0.0", "htmlparser": "1.7.7", "jed": "1.1.1", "qunit": "2.22.0", - "sass": "1.79.6", "stylelint": "16.10.0", "stylelint-config-recommended-scss": "14.0.0", "stylelint-config-standard": "36.0.1", @@ -50,11 +44,7 @@ "typescript": "5.6.3" }, "dependencies": { - "@patternfly/patternfly": "5.4.2", - "@patternfly/react-core": "5.4.8", - "@patternfly/react-icons": "5.4.2", - "@patternfly/react-styles": "5.4.1", - "react": "18.3.1", - "react-dom": "18.3.1" + "@patternfly/elements": "4.0.2", + "lit": "3.2.1" } } diff --git a/packaging/cockpit-starter-kit.spec.in b/packaging/cockpit-starter-kit.spec.in index 14cd470c..e9a650f0 100644 --- a/packaging/cockpit-starter-kit.spec.in +++ b/packaging/cockpit-starter-kit.spec.in @@ -57,7 +57,7 @@ appstream-util validate-relax --nonet %{buildroot}/%{_datadir}/metainfo/* %files %doc README.md -%license LICENSE dist/index.js.LEGAL.txt dist/index.css.LEGAL.txt +%license LICENSE dist/index.js.LEGAL.txt %{_datadir}/cockpit/* %{_datadir}/metainfo/* diff --git a/src/app.scss b/src/app.scss deleted file mode 100644 index 6d2c5d8b..00000000 --- a/src/app.scss +++ /dev/null @@ -1,5 +0,0 @@ -@use "page.scss"; - -p { - font-weight: bold; -} diff --git a/src/app.tsx b/src/ct-application.ts similarity index 50% rename from src/app.tsx rename to src/ct-application.ts index 0d3b12fd..a06e7d62 100644 --- a/src/app.tsx +++ b/src/ct-application.ts @@ -1,7 +1,7 @@ /* * This file is part of Cockpit. * - * Copyright (C) 2017 Red Hat, Inc. + * Copyright (C) 2024 Red Hat, Inc. * * Cockpit is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by @@ -17,32 +17,36 @@ * along with Cockpit; If not, see . */ -import React, { useEffect, useState } from 'react'; -import { Alert } from "@patternfly/react-core/dist/esm/components/Alert/index.js"; -import { Card, CardBody, CardTitle } from "@patternfly/react-core/dist/esm/components/Card/index.js"; +import { css, html, LitElement } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; + +import '@patternfly/elements/pf-card/pf-card.js'; import cockpit from 'cockpit'; const _ = cockpit.gettext; -export const Application = () => { - const [hostname, setHostname] = useState(_("Unknown")); +@customElement('ct-application') +export class Application extends LitElement { + @state() private accessor hostname = _("Unknown"); + + static readonly styles = css` + .running-on { + color: green; + } + `; - useEffect(() => { + connectedCallback() { + super.connectedCallback(); const hostname = cockpit.file('/etc/hostname'); - hostname.watch(content => setHostname(content?.trim() ?? "")); - return hostname.close; - }, []); - - return ( - - Starter Kit - - - - - ); -}; + hostname.watch(content => { this.hostname = content?.trim() ?? "" }); + } + + render() { + return html` + +

Starter Kit

+

${cockpit.format(_("Running on $0"), this.hostname)}

+
`; + } +} diff --git a/src/index.html b/src/index.html index 2b06bb4f..f034309f 100644 --- a/src/index.html +++ b/src/index.html @@ -29,6 +29,6 @@ -
+ diff --git a/src/index.tsx b/src/index.ts similarity index 64% rename from src/index.tsx rename to src/index.ts index 51254c0a..a85da714 100644 --- a/src/index.tsx +++ b/src/index.ts @@ -1,7 +1,7 @@ /* * This file is part of Cockpit. * - * Copyright (C) 2017 Red Hat, Inc. + * Copyright (C) 2024 Red Hat, Inc. * * Cockpit is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by @@ -17,16 +17,6 @@ * along with Cockpit; If not, see . */ -import React from 'react'; -import { createRoot } from 'react-dom/client'; +// import "cockpit-dark-theme"; // doesn't work for PFE -import "cockpit-dark-theme"; - -import { Application } from './app.jsx'; - -import "patternfly/patternfly-5-cockpit.scss"; -import './app.scss'; - -document.addEventListener("DOMContentLoaded", () => { - createRoot(document.getElementById("app")!).render(); -}); +import './ct-application.ts'; diff --git a/test/browser/run-test.sh b/test/browser/run-test.sh index 586583d9..9a33db99 100644 --- a/test/browser/run-test.sh +++ b/test/browser/run-test.sh @@ -7,6 +7,19 @@ git init rm -f bots # common local case: existing bots symlink make bots test/common +# support running from clean git tree +if [ -e .git ]; then + # move package.json temporarily otherwise npm might try to install the dependencies from it + rm -f package-lock.json # otherwise the command below installs *everything*, argh + mv package.json .package.json + # only install a subset to save time/space + npm install query-selector-shadow-dom + mv .package.json package.json +else + # upstream tarballs ship test dependencies; print version for debugging + grep '"version"' node_modules/query-selector-shadow-dom/package.json +fi + # disable detection of affected tests; testing takes too long as there is no parallelization mv .git dot-git diff --git a/test/check-application b/test/check-application index 3e85d0f9..cc362e12 100755 --- a/test/check-application +++ b/test/check-application @@ -18,16 +18,16 @@ class TestApplication(testlib.MachineCase): self.login_and_go("/starter-kit") # verify expected heading - b.wait_text(".pf-v5-c-card__title", "Starter Kit") + b.wait_text("pf-card [slot='header']", "Starter Kit") # verify expected host name hostname = m.execute("cat /etc/hostname").strip() - b.wait_in_text(".pf-v5-c-alert__title", "Running on " + hostname) + b.wait_in_text("pf-card .running-on", "Running on " + hostname) # change current hostname self.write_file("/etc/hostname", "new-" + hostname) # verify new hostname name - b.wait_in_text(".pf-v5-c-alert__title", "Running on new-" + hostname) + b.wait_in_text("pf-card .running-on", "Running on new-" + hostname) # change language to German b.switch_to_top() @@ -46,7 +46,7 @@ class TestApplication(testlib.MachineCase): b.go("/starter-kit") b.enter_page("/starter-kit") # page label (from js) should be translated - b.wait_in_text(".pf-v5-c-alert__title", "Läuft auf") + b.wait_in_text("pf-card .running-on", "Läuft auf") if __name__ == '__main__': diff --git a/tsconfig.json b/tsconfig.json index c4b1669d..e0e3c019 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,6 @@ "allowJs": true, "checkJs": true, "exactOptionalPropertyTypes": true, - "jsx": "react", "lib": [ "dom", "es2020"