Move to PatternFly Elements and lit
PFE uses lit, so it makes sense to just use that for the main application as well. Web components are pretty much React built into the web platform, and lit adds some convenience around that. This is mostly a demo -- for real Cockpit pages, PF Elements is still missing too many components.
This commit is contained in:
parent
6506f469ac
commit
5aa20207b7
11 changed files with 51 additions and 73 deletions
|
|
@ -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"
|
||||
},
|
||||
|
|
|
|||
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
|
|
@ -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"]
|
||||
|
|
|
|||
14
package.json
14
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"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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/*
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
@use "page.scss";
|
||||
|
||||
p {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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");
|
||||
|
||||
useEffect(() => {
|
||||
static readonly styles = css`
|
||||
.running-on {
|
||||
color: green;
|
||||
}
|
||||
`;
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
const hostname = cockpit.file('/etc/hostname');
|
||||
hostname.watch(content => setHostname(content?.trim() ?? ""));
|
||||
return hostname.close;
|
||||
}, []);
|
||||
hostname.watch(content => { this.hostname = content?.trim() ?? "" });
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle>Starter Kit</CardTitle>
|
||||
<CardBody>
|
||||
<Alert
|
||||
variant="info"
|
||||
title={ cockpit.format(_("Running on $0"), hostname) }
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
render() {
|
||||
return html`
|
||||
<pf-card>
|
||||
<h1 slot="header">Starter Kit</h1>
|
||||
<p class="running-on">${cockpit.format(_("Running on $0"), this.hostname)}</p>
|
||||
</pf-card>`;
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,6 @@ along with this package; If not, see <http://www.gnu.org/licenses/>.
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<ct-application></ct-application>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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(<Application />);
|
||||
});
|
||||
import './ct-application.ts';
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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__':
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"jsx": "react",
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2020"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue