Skip to content

Commit 918cc5b

Browse files
committed
shell: Show some pages in fullscreen
1 parent 253d25b commit 918cc5b

File tree

9 files changed

+171
-23
lines changed

9 files changed

+171
-23
lines changed

files.js

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const info = {
2626
"playground/notifications-receiver.js",
2727
"playground/journal.jsx",
2828
"playground/remote.tsx",
29+
"playground/fullscreen.tsx",
2930

3031
"selinux/selinux.js",
3132
"shell/shell.jsx",
@@ -115,6 +116,7 @@ const info = {
115116
"playground/notifications-receiver.html",
116117
"playground/journal.html",
117118
"playground/remote.html",
119+
"playground/fullscreen.html",
118120

119121
"selinux/index.html",
120122

pkg/playground/fullscreen.html

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Cockpit playground</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<link href="fullscreen.css" type="text/css" rel="stylesheet" />
8+
<script src="../base1/cockpit.js"></script>
9+
<script src="fullscreen.js"></script>
10+
</head>
11+
<body class="pf-v5-m-tabular-nums">
12+
<div id="app" />
13+
</body>
14+
</html>

pkg/playground/fullscreen.tsx

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* This file is part of Cockpit.
3+
*
4+
* Copyright (C) 2016 Red Hat, Inc.
5+
*
6+
* Cockpit is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU Lesser General Public License as published by
8+
* the Free Software Foundation; either version 2.1 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Cockpit is distributed in the hope that it will be useful, but
12+
* WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with Cockpit; If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
import cockpit from "cockpit";
21+
import React from "react";
22+
import { createRoot, Container } from 'react-dom/client';
23+
import { usePageLocation } from "hooks";
24+
25+
import '../lib/patternfly/patternfly-5-cockpit.scss';
26+
27+
import { Page, PageSection, Bullseye, Button } from '@patternfly/react-core';
28+
29+
import 'cockpit-dark-theme'; // once per page
30+
31+
const FullscreenDemo = () => {
32+
const { path } = usePageLocation();
33+
34+
function go_fullscreen() {
35+
cockpit.location.go("/fullscreen");
36+
}
37+
38+
function go_halfscreen() {
39+
cockpit.location.go("/");
40+
}
41+
42+
return (
43+
<Page>
44+
<PageSection>
45+
<Bullseye>
46+
{ (path[0] != "fullscreen")
47+
? <Button onClick={go_fullscreen}>Go fullscreen</Button>
48+
: <Button onClick={go_halfscreen}>Go back</Button>
49+
}
50+
</Bullseye>
51+
</PageSection>
52+
</Page>
53+
);
54+
};
55+
56+
function init_app(rootElement: Container) {
57+
const root = createRoot(rootElement);
58+
root.render(<FullscreenDemo />);
59+
}
60+
61+
document.addEventListener("DOMContentLoaded", function() {
62+
cockpit.transport.wait(function() {
63+
init_app(document.getElementById('app')!);
64+
});
65+
});

pkg/playground/manifest.json

+6
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,14 @@
4444
},
4545
"remote": {
4646
"label": "Remote channel"
47+
},
48+
"fullscreen": {
49+
"label": "Fullscreen Shell"
4750
}
4851
},
52+
"fullscreen": {
53+
"fullscreen": [ "/fullscreen" ]
54+
},
4955
"preload": [ "preloaded" ],
5056
"content-security-policy": "img-src 'self' data:"
5157
}

pkg/shell/manifests.ts

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export interface Manifest {
5454
tools?: ManifestSection;
5555

5656
preload?: string[];
57+
fullscreen?: string[] | Record<string, string[]>;
5758
parent?: ManifestParentSection;
5859
".checksum"?: string;
5960
}

pkg/shell/shell.scss

+4
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ $desktop: $phone + 1px;
220220
grid-area: main;
221221
}
222222

223+
&.ct-fullscreen .area-ct-content {
224+
grid-area: switcher / switcher / main / main;
225+
}
226+
223227
.header {
224228
grid-area: header;
225229
}

pkg/shell/shell.tsx

+28-23
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ const Shell = () => {
7878

7979
config,
8080

81+
current_fullscreen,
8182
current_machine,
8283
current_manifest_item,
8384
} = state;
@@ -112,7 +113,7 @@ const Shell = () => {
112113
}
113114

114115
return (
115-
<div id="main" className="page"
116+
<div id="main" className={"page" + (current_fullscreen ? " ct-fullscreen" : "")}
116117
style={
117118
{
118119
'--ct-color-host-accent': (current_machine.address == "localhost" ? undefined : current_machine.color)
@@ -122,28 +123,32 @@ const Shell = () => {
122123
<SkipLink focus_id="content">{_("Skip to content")}</SkipLink>
123124
<SkipLink focus_id="hosts-sel">{_("Skip main navigation")}</SkipLink>
124125

125-
<div id="sidebar-toggle" className="pf-v5-c-select pf-m-dark sidebar-toggle">
126-
<SidebarToggle />
127-
</div>
128-
129-
<div id="nav-system" className="area-ct-subnav nav-system-menu sidebar interact">
130-
<nav id="host-apps" className="host-apps">
131-
<PageNav state={state} />
132-
</nav>
133-
</div>
134-
135-
<nav id="hosts-sel" className="navbar navbar-default navbar-pf navbar-pf-vertical" tabIndex={-1}>
136-
{ config.host_switcher_enabled
137-
? <CockpitHosts state={state} host_modal_state={host_modal_state} selector="nav-hosts" />
138-
: <CockpitCurrentHost current_user={current_user} machine={current_machine} />
139-
}
140-
</nav>
141-
142-
<div id="nav-hosts" className="area-ct-subnav nav-hosts-menu sidebar" />
143-
144-
<div id="topnav" className="header">
145-
<TopNav state={state} />
146-
</div>
126+
{ !current_fullscreen &&
127+
<>
128+
<div id="sidebar-toggle" className="pf-v5-c-select pf-m-dark sidebar-toggle">
129+
<SidebarToggle />
130+
</div>
131+
132+
<div id="nav-system" className="area-ct-subnav nav-system-menu sidebar interact">
133+
<nav id="host-apps" className="host-apps">
134+
<PageNav state={state} />
135+
</nav>
136+
</div>
137+
138+
<nav id="hosts-sel" className="navbar navbar-default navbar-pf navbar-pf-vertical" tabIndex={-1}>
139+
{ config.host_switcher_enabled
140+
? <CockpitHosts state={state} host_modal_state={host_modal_state} selector="nav-hosts" />
141+
: <CockpitCurrentHost current_user={current_user} machine={current_machine} />
142+
}
143+
</nav>
144+
145+
<div id="nav-hosts" className="area-ct-subnav nav-hosts-menu sidebar" />
146+
147+
<div id="topnav" className="header">
148+
<TopNav state={state} />
149+
</div>
150+
</>
151+
}
147152

148153
<Frames hidden={!!failure} state={state} idle_state={idle_state} />
149154

pkg/shell/state.tsx

+18
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ export class ShellState extends EventEmitter<ShellStateEvents> {
585585
current_manifest: Manifest | null = null;
586586

587587
current_frame: ShellFrame | null = null;
588+
current_fullscreen: boolean | null = null;
588589

589590
update() {
590591
if (!this.ready || this.problem) {
@@ -642,6 +643,23 @@ export class ShellState extends EventEmitter<ShellStateEvents> {
642643
this.current_manifest_item = item;
643644
this.current_manifest = compiled.find_path_manifest(location.path);
644645

646+
this.current_fullscreen = false;
647+
if (this.current_manifest.fullscreen) {
648+
let fs = this.current_manifest.fullscreen;
649+
const path_prefix = location.path.split("/", 1)[0];
650+
if (Array.isArray(fs))
651+
fs = { "": fs };
652+
for (const path_suffix in fs) {
653+
if ((path_suffix == "" && path_prefix == location.path)
654+
|| (path_prefix + "/" + path_suffix == location.path)) {
655+
for (const hash_prefix of fs[path_suffix]) {
656+
if (this.current_location.hash.startsWith(hash_prefix))
657+
this.current_fullscreen = true;
658+
}
659+
}
660+
}
661+
}
662+
645663
let frame = null;
646664
if (location.path && (machine.state == "connected" || machine.state == "connecting"))
647665
frame = this.#ensure_frame(machine, location.path, location.hash, item.label);

test/verify/check-pages

+33
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,39 @@ OnCalendar=daily
10471047
b.wait_visible("#fsreplace1-create")
10481048
set_content_and_validate(path, "user data", custom_context)
10491049

1050+
def testFullscreen(self):
1051+
b = self.browser
1052+
m = self.machine
1053+
1054+
self.login_and_go("/playground/fullscreen")
1055+
1056+
def get_size(sel):
1057+
clip = b.call_js_func('ph_element_clip', sel)
1058+
return (clip["width"], clip["height"])
1059+
1060+
def wait_size(sel, size):
1061+
b.wait(lambda: get_size(sel) == size)
1062+
1063+
b.switch_to_top()
1064+
shell_size = get_size('body')
1065+
content_size = get_size('#content')
1066+
b.enter_page("/playground/fullscreen")
1067+
1068+
self.assertEqual(get_size("#app"), content_size)
1069+
1070+
b.click('#app button:contains("Go fullscreen")')
1071+
wait_size("#app", shell_size)
1072+
1073+
b.click('#app button:contains("Go back")')
1074+
wait_size("#app", content_size)
1075+
1076+
b.click('#app button:contains("Go fullscreen")')
1077+
wait_size("#app", shell_size)
1078+
1079+
b.eval_js("window.history.back()")
1080+
wait_size("#app", content_size)
1081+
1082+
10501083

10511084
if __name__ == '__main__':
10521085
testlib.test_main()

0 commit comments

Comments
 (0)