diff --git a/.travis.yml b/.travis.yml
index e5d53fc..2d4a7b1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,5 +4,4 @@ language: node_js
node_js:
- "8"
script:
- - npm install
- - npm run build
+ - make
diff --git a/Makefile b/Makefile
index ae129f5..8c04110 100644
--- a/Makefile
+++ b/Makefile
@@ -12,6 +12,7 @@ VM_IMAGE=$(CURDIR)/test/images/$(TEST_OS)
NODE_MODULES_TEST=package-lock.json
# one example file in dist/ from webpack to check if that already ran
WEBPACK_TEST=dist/index.html
+SASS=$(CURDIR)/node_modules/.bin/sass
all: $(WEBPACK_TEST)
@@ -65,7 +66,7 @@ dist/po.%.js: po/%.po $(NODE_MODULES_TEST)
%.spec: %.spec.in
sed -e 's/%{VERSION}/$(VERSION)/g' $< > $@
-$(WEBPACK_TEST): $(NODE_MODULES_TEST) $(shell find src/ -type f) package.json webpack.config.js $(patsubst %,dist/po.%.js,$(LINGUAS))
+$(WEBPACK_TEST): $(NODE_MODULES_TEST) $(shell find src/ -type f) package.json webpack.config.js dist/patternfly-4-cockpit.css $(patsubst %,dist/po.%.js,$(LINGUAS))
NODE_ENV=$(NODE_ENV) npm run build
watch:
@@ -75,9 +76,11 @@ clean:
rm -rf dist/
[ ! -e cockpit-$(PACKAGE_NAME).spec.in ] || rm -f cockpit-$(PACKAGE_NAME).spec
+# patternfly-4-cockpit.css needs to be shipped in the release tarball to avoid rebuilding the webpack, but we don't need to install it
install: $(WEBPACK_TEST)
mkdir -p $(DESTDIR)/usr/share/cockpit/$(PACKAGE_NAME)
cp -r dist/* $(DESTDIR)/usr/share/cockpit/$(PACKAGE_NAME)
+ rm $(DESTDIR)/usr/share/cockpit/$(PACKAGE_NAME)/patternfly-4-cockpit.css
mkdir -p $(DESTDIR)/usr/share/metainfo/
cp org.cockpit-project.$(PACKAGE_NAME).metainfo.xml $(DESTDIR)/usr/share/metainfo/
@@ -156,6 +159,10 @@ test/common:
git checkout --force FETCH_HEAD -- test/common
git reset test/common
+dist/patternfly-4-cockpit.css: src/lib/patternfly-4-cockpit.scss $(NODE_MODULES_TEST)
+ $(SASS) $< $@ --source-map --source-map-urls absolute --style compressed --load-path node_modules && \
+ sed -i -f src/lib/patternfly.sed $@
+
$(NODE_MODULES_TEST): package.json
# if it exists already, npm install won't update it; force that so that we always get up-to-date packages
rm -f package-lock.json
diff --git a/package.json b/package.json
index d9ab2b1..680c864 100644
--- a/package.json
+++ b/package.json
@@ -33,10 +33,12 @@
"eslint-plugin-react": "^7.14.3",
"eslint-plugin-react-hooks": "^2.1.2",
"eslint-plugin-standard": "^4.0.1",
- "mini-css-extract-plugin": "^0.9.0",
"htmlparser": "^1.7.7",
"jed": "^1.1.1",
+ "mini-css-extract-plugin": "^0.9.0",
+ "node-sass": "4.14.1",
"po2json": "^1.0.0-alpha",
+ "sass": "^1.26.5",
"sass-loader": "^7.0.3",
"sizzle": "^2.3.3",
"stdio": "^0.2.7",
@@ -44,8 +46,9 @@
"webpack-cli": "^3.1.0"
},
"dependencies": {
+ "@patternfly/patternfly": "^2.71.6",
+ "@patternfly/react-core": "^3.158.1",
"core-js": "3.6.5",
- "node-sass": "4.14.1",
"react": "16.13.1",
"react-dom": "16.13.1"
}
diff --git a/src/app.jsx b/src/app.jsx
index 1f671a9..9f17f50 100644
--- a/src/app.jsx
+++ b/src/app.jsx
@@ -19,6 +19,7 @@
import cockpit from 'cockpit';
import React from 'react';
+import { Alert, Card, CardHead, CardHeader, CardHeadMain, Title } from '@patternfly/react-core';
import './app.scss';
const _ = cockpit.gettext;
@@ -35,12 +36,19 @@ export class Application extends React.Component {
render() {
return (
-
-
Starter Kit
-
- { cockpit.format(_("Running on $0"), this.state.hostname) }
-
-
+
+
+
+ Starter Kit
+
+
+
+
+
+
);
}
}
diff --git a/src/index.html b/src/index.html
index 5182d9b..62a2bf0 100644
--- a/src/index.html
+++ b/src/index.html
@@ -22,7 +22,6 @@ along with this package; If not, see .
-
@@ -30,7 +29,7 @@ along with this package; If not, see .
-
+
diff --git a/src/index.js b/src/index.js
index 0a0e535..4981382 100644
--- a/src/index.js
+++ b/src/index.js
@@ -17,11 +17,21 @@
* along with Cockpit; If not, see .
*/
+import "../dist/patternfly-4-cockpit.css";
+
import "core-js/stable";
import React from 'react';
import ReactDOM from 'react-dom';
import { Application } from './app.jsx';
+/*
+ * PF4 overrides need to come after the JSX components imports because
+ * these are importing CSS stylesheets that we are overriding
+ * Having the overrides here will ensure that when mini-css-extract-plugin will extract the CSS
+ * out of the dist/index.js and since it will maintain the order of the imported CSS,
+ * the overrides will be correctly in the end of our stylesheet.
+ */
+import "./lib/patternfly-4-overrides.scss";
document.addEventListener("DOMContentLoaded", function () {
ReactDOM.render(React.createElement(Application, {}), document.getElementById('app'));
diff --git a/src/lib/_fonts.scss b/src/lib/_fonts.scss
new file mode 100644
index 0000000..b3cb18a
--- /dev/null
+++ b/src/lib/_fonts.scss
@@ -0,0 +1,36 @@
+/*
+ * Keep in sync with https://github.com/cockpit-project/cockpit/tree/master/src/base1/_fonts.scss
+ */
+
+@mixin printRedHatFont(
+$weightValue: 400,
+$weightName: "Regular",
+$familyName: "RedHatText",
+$style: "normal",
+$relative: true
+) {
+ $filePath: "../../static/fonts" + "/" + $familyName + "-" + $weightName;
+ @font-face {
+ font-family: $familyName;
+ src: url('#{$filePath}.woff2') format('woff2');
+ font-style: #{$style};
+ font-weight: $weightValue;
+ text-rendering: optimizeLegibility;
+ }
+}
+
+@include printRedHatFont(700, "Bold", $familyName: "RedHatDisplay");
+@include printRedHatFont(700, "BoldItalic", $style: "italic", $familyName: "RedHatDisplay");
+@include printRedHatFont(300, "Black", $familyName: "RedHatDisplay");
+@include printRedHatFont(300, "BlackItalic", $style: "italic", $familyName: "RedHatDisplay");
+@include printRedHatFont(300, "Italic", $style: "italic", $familyName: "RedHatDisplay");
+@include printRedHatFont(400, "Medium", $familyName: "RedHatDisplay");
+@include printRedHatFont(400, "MediumItalic", $style: "italic", $familyName: "RedHatDisplay");
+@include printRedHatFont(300, "Regular", $familyName: "RedHatDisplay");
+
+@include printRedHatFont(300, "Bold");
+@include printRedHatFont(300, "BoldItalic", $style: "italic");
+@include printRedHatFont(300, "Italic");
+@include printRedHatFont(700, "Medium");
+@include printRedHatFont(700, "MediumItalic", $style: "italic");
+@include printRedHatFont(400, "Regular");
diff --git a/src/lib/patternfly-4-cockpit.scss b/src/lib/patternfly-4-cockpit.scss
new file mode 100644
index 0000000..d4af1b8
--- /dev/null
+++ b/src/lib/patternfly-4-cockpit.scss
@@ -0,0 +1,14 @@
+/*
+ * Keep in sync with https://github.com/cockpit-project/cockpit/tree/master/src/base1/patternfly-4-cockpit.scss
+ */
+
+/* Set fake font and icon path variables - we are going to indentify these through
+ * patternfly.sed and remove the relevant font-face declarations
+ */
+$pf-global--font-path: 'patternfly-fonts-fake-path';
+$pf-global--fonticon-path: 'patternfly-icons-fake-path';
+$pf-global--disable-fontawesome: true !default; // Disable Font Awesome 5 Free
+@import '@patternfly/patternfly/patternfly-base.scss';
+
+/* Import our own fonts since the PF4 font-face rules are filtered out with patternfly.sed */
+@import "./fonts";
diff --git a/src/lib/patternfly-4-overrides.scss b/src/lib/patternfly-4-overrides.scss
new file mode 100644
index 0000000..a02cb95
--- /dev/null
+++ b/src/lib/patternfly-4-overrides.scss
@@ -0,0 +1,43 @@
+/*
+ * Keep in sync with https://github.com/cockpit-project/cockpit/tree/master/pkg/lib/patternfly-4-overrides.scss
+ */
+
+/*** PF4 overrides ***/
+
+/* WORKAROUND: Override word-break bug */
+/* See: https://github.com/patternfly/patternfly-next/issues/2325 */
+.pf-c-table td {
+ word-break: normal;
+ overflow-wrap: break-word;
+}
+
+/* WORKAROUND: Dropdown (PF4): Caret is not properly aligned bug */
+/* See: https://github.com/patternfly/patternfly/issues/2715 */
+/* Align the icons inside of all dropdown toggles. */
+/* Part 1 of 2 */
+.pf-c-dropdown__toggle-button {
+ display: flex;
+ align-items: center;
+}
+
+/* Make split button dropdowns the same height as their sibling. */
+/* Part 2 of 2 */
+.pf-m-split-button {
+ align-items: stretch;
+}
+
+/* WORKAROUND: Navigation problems with Tertiary Nav widget on mobile */
+/* See: https://github.com/patternfly/patternfly-design/issues/840 */
+/* Helper mod to wrap pf-c-nav__tertiary */
+.ct-m-nav__tertiary-wrap {
+ flex-wrap: wrap;
+
+ .pf-c-nav__scroll-button {
+ display: none;
+ }
+}
+
+/* Helper mod to center pf-c-nav__tertiary when it wraps */
+.ct-m-nav__tertiary-center {
+ justify-content: center;
+}
diff --git a/src/lib/patternfly.sed b/src/lib/patternfly.sed
new file mode 100644
index 0000000..89d878c
--- /dev/null
+++ b/src/lib/patternfly.sed
@@ -0,0 +1,3 @@
+# Keep the PF4 relevant rules in sync with https://github.com/cockpit-project/cockpit/blob/master/tools/patternfly.sed
+s/src:url[(]"patternfly-icons-fake-path\/pficon[^}]*/src:url('fonts\/patternfly.woff')format('woff');/
+s/@font-face[^}]*patternfly-fonts-fake-path[^}]*}//g
diff --git a/test/check-application b/test/check-application
index 2ad5d68..c4068b2 100755
--- a/test/check-application
+++ b/test/check-application
@@ -20,16 +20,16 @@ class TestApplication(testlib.MachineCase):
self.login_and_go("/starter-kit")
# verify expected heading
- b.wait_text(".container-fluid h2", "Starter Kit")
+ b.wait_text("h2.pf-c-title", "Starter Kit")
# verify expected host name
hostname = m.execute("hostname").strip()
- b.wait_text(".container-fluid p", "Running on " + hostname)
+ b.wait_in_text("h4.pf-c-alert__title", "Running on " + hostname)
# change current hostname
m.execute("echo new-%s > /etc/hostname" % hostname)
# verify new hostname name
- b.wait_text(".container-fluid p", "Running on new-" + hostname)
+ b.wait_in_text("h4.pf-c-alert__title", "Running on new-" + hostname)
# change language to German
b.switch_to_top()
@@ -48,7 +48,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(".container-fluid p", "Läuft auf")
+ b.wait_in_text("h4.pf-c-alert__title", "Läuft auf")
if __name__ == '__main__':
testlib.test_main()
diff --git a/webpack.config.js b/webpack.config.js
index 01973c4..3ecc95a 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -115,6 +115,9 @@ var babel_loader = {
module.exports = {
mode: production ? 'production' : 'development',
+ resolve: {
+ modules: [ nodedir ],
+ },
entry: info.entries,
externals: externals,
output: output,
@@ -133,19 +136,25 @@ module.exports = {
test: /\.(js|jsx)$/
},
{
- exclude: /node_modules/,
- test: /\.scss$/,
+ test: /\.s?css$/,
use: [
extract.loader,
{
loader: 'css-loader',
- options: { url: false }
+ options: {
+ sourceMap: true,
+ url: false
+ }
},
{
loader: 'sass-loader',
- }
+ options: {
+ sourceMap: true,
+ outputStyle: 'compressed',
+ },
+ },
]
- }
+ },
]
},
plugins: plugins