Skip to content

Commit

Permalink
Move to PatternFly Elements and lit
Browse files Browse the repository at this point in the history
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.

Install query-selector-shadow-dom to enable testlib's shiny new support
for traversing selectors through shadow DOMs from
cockpit-project/cockpit#21233
  • Loading branch information
martinpitt committed Nov 8, 2024
1 parent 880094d commit 7ecaca0
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 65 deletions.
11 changes: 1 addition & 10 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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,
{
Expand All @@ -22,23 +21,15 @@
"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",
"jsx-quotes": "off",
"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"
},
Expand Down
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ devel-uninstall:
print-version:
@echo "$(VERSION)"

# required for running integration tests
TEST_NPMS = \
node_modules/query-selector-shadow-dom \
$(NULL)


dist: $(TARFILE)
@ls -1 $(TARFILE)

Expand All @@ -125,8 +131,8 @@ $(TARFILE): export NODE_ENV=production
$(TARFILE): $(DIST_TEST) $(SPEC)
if type appstream-util >/dev/null 2>&1; then appstream-util validate-relax --nonet *.metainfo.xml; fi
tar --xz $(TAR_ARGS) -cf $(TARFILE) --transform 's,^,$(RPM_NAME)/,' \
--exclude packaging/$(SPEC).in --exclude node_modules \
$$(git ls-files) $(COCKPIT_REPO_FILES) $(NODE_MODULES_TEST) $(SPEC) dist/
--exclude packaging/$(SPEC).in \
$$(git ls-files) $(COCKPIT_REPO_FILES) $(NODE_MODULES_TEST) $(SPEC) $(TEST_NPMS) dist/

$(NODE_CACHE): $(NODE_MODULES_TEST)
tar --xz $(TAR_ARGS) -cf $@ node_modules
Expand Down
14 changes: 3 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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.13.0",
"argparse": "2.0.1",
"esbuild": "0.24.0",
Expand All @@ -30,16 +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",
"query-selector-shadow-dom": "1.0.1",
"qunit": "2.22.0",
"sass": "1.80.3",
"stylelint": "16.10.0",
Expand All @@ -50,11 +46,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"
}
}
7 changes: 4 additions & 3 deletions src/app.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@use "page.scss";
// requires PF5, needs counterpart for PFE
// @use "page.scss";

p {
font-weight: bold;
.running-on {
color: green;
}
42 changes: 20 additions & 22 deletions src/app.tsx
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -17,32 +17,30 @@
* 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 { 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(() => {
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>`;
}
}
2 changes: 1 addition & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@
</head>

<body>
<div id="app"></div>
<ct-application />
</body>
</html>
15 changes: 4 additions & 11 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -17,16 +17,9 @@
* 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 './app.jsx';

import { Application } from './app.jsx';

import "patternfly/patternfly-5-cockpit.scss";
// import "patternfly/patternfly-5-cockpit.scss"; // does not apply to PFE
import './app.scss';

document.addEventListener("DOMContentLoaded", () => {
createRoot(document.getElementById("app")!).render(<Application />);
});
8 changes: 4 additions & 4 deletions test/check-application
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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__':
Expand Down
1 change: 0 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"allowJs": true,
"checkJs": true,
"exactOptionalPropertyTypes": true,
"jsx": "react",
"lib": [
"dom",
"es2020"
Expand Down

0 comments on commit 7ecaca0

Please sign in to comment.