Compare commits

...

10 commits

Author SHA1 Message Date
Andrew Collington c67ad50bbc Added toggle switch 2023-10-30 00:55:32 +00:00
Andrew Collington da0a4bfb0f Small footer tweak 2023-10-29 23:52:54 +00:00
Andrew Collington 6cd2b091f2 Cleaned up header nav on small screens 2023-10-29 23:42:01 +00:00
Andrew Collington 6cfb28f3a4 Fixed sizing issues with svgs in footer 2023-10-29 23:18:08 +00:00
Andrew Collington 9d07819789 Fixed issue with tab positioning 2023-10-29 23:08:44 +00:00
Andrew Collington aad06c0b92 Revisited top navigation icons
* Used slightly different svg icons
* Changed animation for both
2023-10-29 22:53:42 +00:00
Andrew Collington 423a47b865 Updated compile-scss command for latest sass version 2023-10-29 22:51:16 +00:00
Andrew Collington 3300b107f8 Revamping the css and jsx
* Moved SVG icons into the JSX so that they're no longer background images
* Added "dark" colours - still need tweaking, but this is a start
* Updated rules to use CSS variables throughout rather than sass variable directly
2023-10-29 15:46:47 +00:00
Andrew Collington 8b6f6c6dfc Moved the opcache-gui class to the main body of the page 2023-10-29 15:43:58 +00:00
Andrew Collington fdf813dfba Updated all package dependencies 2023-10-29 15:43:17 +00:00
5 changed files with 503 additions and 267 deletions

View file

@ -166,17 +166,28 @@ function MainNavigation(props) {
{ {
props.allow.reset && props.allow.reset &&
<div label={props.txt("Reset cache")} tabId="resetCache" <div label={props.txt("Reset cache")} tabId="resetCache"
className={`nav-tab-link-reset${props.resetting ? ' is-resetting pulse' : ''}`} className={`nav-tab-link-reset${props.resetting ? ' is-resetting activated' : ''}`}
handler={props.resetHandler} handler={props.resetHandler}
tabIndex={5} tabIndex={5}
icon={(
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 489.645 489.645">
<path d="M460.656,132.911c-58.7-122.1-212.2-166.5-331.8-104.1c-9.4,5.2-13.5,16.6-8.3,27c5.2,9.4,16.6,13.5,27,8.3 c99.9-52,227.4-14.9,276.7,86.3c65.4,134.3-19,236.7-87.4,274.6c-93.1,51.7-211.2,17.4-267.6-70.7l69.3,14.5 c10.4,2.1,21.8-4.2,23.9-15.6c2.1-10.4-4.2-21.8-15.6-23.9l-122.8-25c-20.6-2-25,16.6-23.9,22.9l15.6,123.8 c1,10.4,9.4,17.7,19.8,17.7c12.8,0,20.8-12.5,19.8-23.9l-6-50.5c57.4,70.8,170.3,131.2,307.4,68.2 C414.856,432.511,548.256,314.811,460.656,132.911z"/>
</svg>
)}
></div> ></div>
} }
{ {
props.allow.realtime && props.allow.realtime &&
<div label={props.txt(`${props.realtime ? 'Disable' : 'Enable'} real-time update`)} tabId="toggleRealtime" <div label={props.txt(`${props.realtime ? 'Disable' : 'Enable'} real-time update`)} tabId="toggleRealtime"
className={`nav-tab-link-realtime${props.realtime ? ' live-update pulse' : ''}`} className={`nav-tab-link-realtime${props.realtime ? ' live-update activated' : ''}`}
handler={props.realtimeHandler} handler={props.realtimeHandler}
tabIndex={6} tabIndex={6}
icon={(
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" viewBox="0 0 489.698 489.698">
<path d="M468.999,227.774c-11.4,0-20.8,8.3-20.8,19.8c-1,74.9-44.2,142.6-110.3,178.9c-99.6,54.7-216,5.6-260.6-61l62.9,13.1 c10.4,2.1,21.8-4.2,23.9-15.6c2.1-10.4-4.2-21.8-15.6-23.9l-123.7-26c-7.2-1.7-26.1,3.5-23.9,22.9l15.6,124.8 c1,10.4,9.4,17.7,19.8,17.7c15.5,0,21.8-11.4,20.8-22.9l-7.3-60.9c101.1,121.3,229.4,104.4,306.8,69.3 c80.1-42.7,131.1-124.8,132.1-215.4C488.799,237.174,480.399,227.774,468.999,227.774z"/>
<path d="M20.599,261.874c11.4,0,20.8-8.3,20.8-19.8c1-74.9,44.2-142.6,110.3-178.9c99.6-54.7,216-5.6,260.6,61l-62.9-13.1 c-10.4-2.1-21.8,4.2-23.9,15.6c-2.1,10.4,4.2,21.8,15.6,23.9l123.8,26c7.2,1.7,26.1-3.5,23.9-22.9l-15.6-124.8 c-1-10.4-9.4-17.7-19.8-17.7c-15.5,0-21.8,11.4-20.8,22.9l7.2,60.9c-101.1-121.2-229.4-104.4-306.8-69.2 c-80.1,42.6-131.1,124.8-132.2,215.3C0.799,252.574,9.199,261.874,20.599,261.874z"/>
</svg>
)}
></div> ></div>
} }
</Tabs> </Tabs>
@ -190,6 +201,7 @@ class Tabs extends React.Component {
super(props); super(props);
this.state = { this.state = {
activeTab: this.props.children[0].props.label, activeTab: this.props.children[0].props.label,
colourMode: 0, // 0 = light, 1 = dark
}; };
} }
@ -197,10 +209,22 @@ class Tabs extends React.Component {
this.setState({ activeTab: tab }); this.setState({ activeTab: tab });
} }
onClickModeSwitch = (event) => {
event.stopPropagation()
console.log(event)
this.setState({ colourMode: event.target.checked ? 1 : 0 });
if (event.target.checked) {
document.body.classList.add('dark-mode');
} else {
document.body.classList.remove('dark-mode');
}
}
render() { render() {
const { const {
onClickTabItem, onClickTabItem,
state: { activeTab } onClickModeSwitch,
state: { activeTab, colourMode }
} = this; } = this;
const children = this.props.children.filter(Boolean); const children = this.props.children.filter(Boolean);
@ -209,7 +233,7 @@ class Tabs extends React.Component {
<> <>
<ul className="nav-tab-list"> <ul className="nav-tab-list">
{children.map((child) => { {children.map((child) => {
const { tabId, label, className, handler, tabIndex } = child.props; const { tabId, label, className, handler, tabIndex, icon } = child.props;
return ( return (
<Tab <Tab
activeTab={activeTab} activeTab={activeTab}
@ -219,9 +243,33 @@ class Tabs extends React.Component {
className={className} className={className}
tabIndex={tabIndex} tabIndex={tabIndex}
tabId={tabId} tabId={tabId}
icon={icon}
/> />
); );
})} })}
<Tab
activeTab={activeTab}
key={7}
label={(
<div className="mode-container" onClick={onClickModeSwitch}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" />
</svg>
<label className="switch mode-switch">
<input type="checkbox" name="dark_mode" id="dark_mode" value={colourMode} />
<label htmlFor="dark_mode" data-on="Dark" data-off="Light" className="mode-switch-inner"></label>
</label>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 009.002-5.998z" />
</svg>
</div>
)}
onClick={() => null}
className=""
tabIndex={7}
tabId="mode-switch"
/>
</ul> </ul>
<div className="tab-content"> <div className="tab-content">
{children.map((child) => ( {children.map((child) => (
@ -248,7 +296,7 @@ class Tab extends React.Component {
render() { render() {
const { const {
onClick, onClick,
props: { activeTab, label, tabIndex, tabId }, props: { activeTab, label, tabIndex, tabId, icon },
} = this; } = this;
let className = 'nav-tab'; let className = 'nav-tab';
@ -265,7 +313,7 @@ class Tab extends React.Component {
tabIndex={tabIndex} tabIndex={tabIndex}
role="tab" role="tab"
aria-controls={`${tabId}-content`} aria-controls={`${tabId}-content`}
>{label}</li> >{icon}{label}</li>
); );
} }
} }
@ -1188,12 +1236,16 @@ function Footer(props) {
<a className="github-link" href="https://github.com/amnuts/opcache-gui" <a className="github-link" href="https://github.com/amnuts/opcache-gui"
target="_blank" target="_blank"
title="opcache-gui (currently version {props.version}) on GitHub" title="opcache-gui (currently version {props.version}) on GitHub"
>https://github.com/amnuts/opcache-gui - version {props.version}</a> ><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" width="1.19em" height="1em" viewBox="0 0 1664 1408">
<path d="M640 960q0 40-12.5 82t-43 76t-72.5 34t-72.5-34t-43-76t-12.5-82t12.5-82t43-76t72.5-34t72.5 34t43 76t12.5 82zm640 0q0 40-12.5 82t-43 76t-72.5 34t-72.5-34t-43-76t-12.5-82t12.5-82t43-76t72.5-34t72.5 34t43 76t12.5 82zm160 0q0-120-69-204t-187-84q-41 0-195 21q-71 11-157 11t-157-11q-152-21-195-21q-118 0-187 84t-69 204q0 88 32 153.5t81 103t122 60t140 29.5t149 7h168q82 0 149-7t140-29.5t122-60t81-103t32-153.5zm224-176q0 207-61 331q-38 77-105.5 133t-141 86t-170 47.5t-171.5 22t-167 4.5q-78 0-142-3t-147.5-12.5t-152.5-30t-137-51.5t-121-81t-86-115Q0 992 0 784q0-237 136-396q-27-82-27-170q0-116 51-218q108 0 190 39.5T539 163q147-35 309-35q148 0 280 32q105-82 187-121t189-39q51 102 51 218q0 87-27 168q136 160 136 398z"/>
</svg> https://github.com/amnuts/opcache-gui, v{props.version}</a>
<a className="sponsor-link" href="https://github.com/sponsors/amnuts" <a className="sponsor-link" href="https://github.com/sponsors/amnuts"
target="_blank" target="_blank"
title="Sponsor this project and author on GitHub" title="Sponsor this project and author on GitHub"
>Sponsor this project</a> ><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path fill="crimson" d="M12 21.35l-1.45-1.32c-5.15-4.67-8.55-7.75-8.55-11.53 0-3.08 2.42-5.5 5.5-5.5 1.74 0 3.41.81 4.5 2.09 1.09-1.28 2.76-2.09 4.5-2.09 3.08 0 5.5 2.42 5.5 5.5 0 3.78-3.4 6.86-8.55 11.54l-1.45 1.31z"/>
</svg> Sponsor this project</a>
</footer> </footer>
); );
} }

View file

@ -1,41 +1,111 @@
$nav-header-color: #6CA6EF; $light-background: #FFF;
$nav-hover-color: #F4F4F4; $light-font-color: #000;
$nav-border-color: #CCC; $light-nav-header-color: #6CA6EF;
$nav-background-color: #FFF; $light-nav-hover-color: #F4F4F4;
$nav-icon-color: #626262; $light-nav-border-color: #CCC;
$nav-icon-active-color: #00ba00; $light-nav-background-color: #FFF;
$light-nav-icon-color: #626262;
$light-nav-icon-active-color: #00ba00;
$light-table-header-color: #6CA6EF;
$light-table-row-color: #EFFEFF;
$light-table-row-color-alternative: #E0ECEF;
$light-table-row-border-color: #FFF;
$light-table-header-font-color: #FFF;
$light-table-header-border-color: #FFF;
$light-widget-header-color: #CDCDCD;
$light-widget-background-color: #EDEDED;
$light-widget-graph-fill-color: #6CA6EF;
$light-widget-graph-background-color: #E5E7E7E7;
$light-pagination-active-color: #4d75af;
$light-pagination-active-font-color: #FFF;
$light-pagination-hover-color: #FF7400;
$light-pagination-hover-font-color: #FFF;
$light-footer-border-color: #CCC;
$table-header-color: #6CA6EF; $dark-background: #282A36;
$table-row-color: #EFFEFF; $dark-font-color: #EAEAEA;
$table-row-color-alternative: #E0ECEF; $dark-nav-header-color: #6272A4;
$table-row-border-color: #FFF; $dark-nav-hover-color: #282A36;
$table-header-font-color: #FFF; $dark-nav-border-color: #44475A;
$table-header-border-color: #FFF; $dark-nav-background-color: #282A36;
$dark-nav-icon-color: #BD93F9;
$widget-header-color: #CDCDCD; $dark-nav-icon-active-color: #50FA7B;
$widget-background-color: #EDEDED; $dark-table-header-color: #6272A4;
$widget-graph-fill-color: #6CA6EF; $dark-table-row-color: #282A36;
$widget-graph-background-color: #E5E7E7E7; $dark-table-row-color-alternative: #44475A;
$dark-table-row-border-color: #282A36;
$pagination-active-color: #4d75af; $dark-table-header-font-color: #BD93F9;
$pagination-active-font-color: #FFF; $dark-table-header-border-color: #BD93F9;
$pagination-hover-color: #FF7400; $dark-widget-header-color: #44475A;
$pagination-hover-font-color: #FFF; $dark-widget-background-color: #282A36;
$dark-widget-graph-fill-color: #6272A4;
$footer-border-color: #CCC; $dark-widget-graph-background-color: #44475A;
$dark-pagination-active-color: #FF79C6;
@function toRGB ($color) { $dark-pagination-active-font-color: #282A36;
@return "rgb(" + red($color) + ", " + green($color) + ", " + blue($color)+ ")"; $dark-pagination-hover-color: #FF6E6E;
} $dark-pagination-hover-font-color: #282A36;
$dark-footer-border-color: #44475A;
:root { :root {
--opcache-gui-graph-track-fill-color: #{$widget-graph-fill-color}; --opcache-gui-graph-track-fill-color: #{$light-widget-graph-fill-color};
--opcache-gui-graph-track-background-color: #{$widget-graph-background-color}; --opcache-gui-graph-track-background-color: #{$light-widget-graph-background-color};
} }
.opcache-gui { body.opcache-gui {
--page-background: #{$light-background};
--font-color: #{$light-font-color};
--nav-header-color: #{$light-nav-header-color};
--nav-hover-color: #{$light-nav-hover-color};
--nav-border-color: #{$light-nav-border-color};
--nav-background-color: #{$light-nav-background-color};
--nav-icon-color: #{$light-nav-icon-color};
--nav-icon-active-color: #{$light-nav-icon-active-color};
--table-header-color: #{$light-table-header-color};
--table-row-color: #{$light-table-row-color};
--table-row-color-alternative: #{$light-table-row-color-alternative};
--table-row-border-color: #{$light-table-row-border-color};
--table-header-font-color: #{$light-table-header-font-color};
--table-header-border-color: #{$light-table-header-border-color};
--widget-header-color: #{$light-widget-header-color};
--widget-background-color: #{$light-widget-background-color};
--widget-graph-fill-color: #{$light-widget-graph-fill-color};
--widget-graph-background-color: #{$light-widget-graph-background-color};
--pagination-active-color: #{$light-pagination-active-color};
--pagination-active-font-color: #{$light-pagination-active-font-color};
--pagination-hover-color: #{$light-pagination-hover-color};
--pagination-hover-font-color: #{$light-pagination-hover-font-color};
--footer-border-color: #{$light-footer-border-color};
&.dark-mode {
--page-background: #{$dark-background};
--font-color: #{$dark-font-color};
--nav-header-color: #{$dark-nav-header-color};
--nav-hover-color: #{$dark-nav-hover-color};
--nav-border-color: #{$dark-nav-border-color};
--nav-background-color: #{$dark-nav-background-color};
--nav-icon-color: #{$dark-nav-icon-color};
--nav-icon-active-color: #{$dark-nav-icon-active-color};
--table-header-color: #{$dark-table-header-color};
--table-row-color: #{$dark-table-row-color};
--table-row-color-alternative: #{$dark-table-row-color-alternative};
--table-row-border-color: #{$dark-table-row-border-color};
--table-header-font-color: #{$dark-table-header-font-color};
--table-header-border-color: #{$dark-table-header-border-color};
--widget-header-color: #{$dark-widget-header-color};
--widget-background-color: #{$dark-widget-background-color};
--widget-graph-fill-color: #{$dark-widget-graph-fill-color};
--widget-graph-background-color: #{$dark-widget-graph-background-color};
--pagination-active-color: #{$dark-pagination-active-color};
--pagination-active-font-color: #{$dark-pagination-active-font-color};
--pagination-hover-color: #{$dark-pagination-hover-color};
--pagination-hover-font-color: #{$dark-pagination-hover-font-color};
--footer-border-color: #{$dark-footer-border-color};
}
background-color: var(--page-background);
font-family: sans-serif; font-family: sans-serif;
font-size: 90%; font-size: 90%;
color: var(--font-color);
padding: 0; padding: 0;
margin: 0; margin: 0;
@ -65,29 +135,32 @@ $footer-border-color: #CCC;
list-style-type: none; list-style-type: none;
padding-left: 8px; padding-left: 8px;
margin: 0; margin: 0;
border-bottom: 1px solid $nav-border-color; border-bottom: 1px solid var(--nav-border-color);
display: flex;
align-items: end;
} }
.nav-tab { .nav-tab {
display: inline-block; display: inline-flex;
margin: 0 0 -1px 0; margin: 0 0 -1px 0;
padding: 15px 30px; padding: 15px 30px;
border: 1px solid transparent; border: 1px solid transparent;
border-bottom-color: $nav-border-color; border-bottom-color: var(--nav-border-color);
text-decoration: none; text-decoration: none;
background-color: $nav-background-color; background-color: var(--nav-background-color);
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
align-items: center;
&:hover { &:hover {
background-color: $nav-hover-color; background-color: var(--nav-hover-color);
text-decoration: underline; text-decoration: underline;
} }
&.active { &.active {
border: 1px solid $nav-border-color; border: 1px solid var(--nav-border-color);
border-bottom-color: $nav-background-color; border-bottom-color: var(--nav-background-color);
border-top: 3px solid $nav-header-color; border-top: 3px solid var(--nav-header-color);
} }
&.active:hover { &.active:hover {
@ -98,38 +171,61 @@ $footer-border-color: #CCC;
outline: 0; outline: 0;
text-decoration: underline; text-decoration: underline;
} }
}
.nav-tab-link-reset { &:last-child {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1.5em" height="1.5em" viewBox="0 0 24 24"><path d="M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" fill="#{toRGB($nav-icon-color)}"/></svg>'); flex: 1;
&.is-resetting { justify-content: end;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1.5em" height="1.5em" viewBox="0 0 24 24"><path d="M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z" fill="#{toRGB($nav-icon-active-color)}"/></svg>'); padding: 0 1rem 0 0;
} align-self: center;
} border: 0;
.nav-tab-link-realtime { &:hover {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1.5em" height="1.5em" viewBox="0 0 24 24"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8s8 3.58 8 8s-3.58 8-8 8z" fill="#{toRGB($nav-icon-color)}"/><path d="M12.5 7H11v6l5.25 3.15l.75-1.23l-4.5-2.67z" fill="#{toRGB($nav-icon-color)}"/></svg>'); background-color: initial;
&.live-update { text-decoration: initial;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1.5em" height="1.5em" viewBox="0 0 24 24"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8s8 3.58 8 8s-3.58 8-8 8z" fill="#{toRGB($nav-icon-active-color)}"/><path d="M12.5 7H11v6l5.25 3.15l.75-1.23l-4.5-2.67z" fill="#{toRGB($nav-icon-active-color)}"/></svg>'); }
} }
} }
.nav-tab-link-reset, .nav-tab-link-realtime { .nav-tab-link-reset, .nav-tab-link-realtime {
position: relative; > svg {
padding-left: 50px; overflow: visible;
&.pulse::before { width: 1.1rem;
content: ""; height: 1.1rem;
position: absolute; margin-right: 0.5em;
top: 12px;
left: 25px; > path {
width: 18px; fill: var(--nav-icon-color);
height: 18px; }
z-index: 10; }
opacity: 0;
background-color: transparent; &.activated {
border: 2px solid $nav-icon-active-color; > svg > path {
border-radius: 100%; fill: var(--nav-icon-active-color);
animation: pulse 2s linear infinite; transform-origin: 50% 50%;
display: inline-block;
}
}
}
.nav-tab-link-reset {
&.activated {
> svg > path {
animation: spin-all 2s linear infinite;
}
}
&.is-resetting {
> svg > path {
fill: var(--nav-icon-active-color);
}
}
}
.nav-tab-link-realtime {
&.activated {
> svg > path {
animation: spin-pause 2s ease-in infinite;
}
} }
} }
@ -165,18 +261,18 @@ $footer-border-color: #CCC;
margin: 0 auto; margin: 0 auto;
font-size: 3.2em; font-size: 3.2em;
font-weight: 100; font-weight: 100;
color: $widget-graph-fill-color; color: var(--widget-graph-fill-color);
user-select: none; user-select: none;
} }
} }
.widget-panel { .widget-panel {
background-color: $widget-background-color; background-color: var(--widget-background-color);
margin-bottom: 10px; margin-bottom: 10px;
} }
.widget-header { .widget-header {
background-color: $widget-header-color; background-color: var(--widget-header-color);
padding: 4px 6px; padding: 4px 6px;
margin: 0; margin: 0;
text-align: center; text-align: center;
@ -189,7 +285,7 @@ $footer-border-color: #CCC;
text-align: center; text-align: center;
span.large { span.large {
color: $widget-graph-fill-color; color: var(--widget-graph-fill-color);
font-size: 80pt; font-size: 80pt;
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -198,7 +294,7 @@ $footer-border-color: #CCC;
+ span { + span {
font-size: 20pt; font-size: 20pt;
margin: 0; margin: 0;
color: $widget-graph-fill-color; color: var(--widget-graph-fill-color);
} }
} }
} }
@ -222,19 +318,20 @@ $footer-border-color: #CCC;
tr { tr {
&:nth-child(odd) { &:nth-child(odd) {
background-color: $table-row-color; background-color: var(--table-row-color);
} }
&:nth-child(even) { &:nth-child(even) {
background-color: $table-row-color-alternative; background-color: var(--table-row-color-alternative);
} }
} }
th { th {
text-align: left; text-align: left;
padding: 6px; padding: 6px;
background-color: $table-header-color; background-color: var(--table-header-color);
color: $table-header-font-color; color: var(--table-header-font-color);
border-color: $table-header-border-color; border-color: var(--table-header-border-color);
font-weight: normal; font-weight: normal;
} }
@ -242,7 +339,7 @@ $footer-border-color: #CCC;
padding: 4px 6px; padding: 4px 6px;
line-height: 1.4em; line-height: 1.4em;
vertical-align: top; vertical-align: top;
border-color: $table-row-border-color; border-color: var(--table-row-border-color);
overflow: hidden; overflow: hidden;
overflow-wrap: break-word; overflow-wrap: break-word;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -284,43 +381,37 @@ $footer-border-color: #CCC;
display: block; display: block;
} }
.nav-tab-link-reset,
.nav-tab-link-realtime,
.github-link,
.sponsor-link {
background-repeat: no-repeat;
background-color: transparent;
}
.nav-tab-link-reset,
.nav-tab-link-realtime {
background-position: 24px 50%;
}
.main-footer { .main-footer {
border-top: 1px solid $footer-border-color; border-top: 1px solid var(--footer-border-color);
padding: 1em 2em; padding: 1em 2em;
display: flex;
align-items: center;
} }
.github-link, .github-link,
.sponsor-link { .sponsor-link {
background-position: 0 50%;
padding: 2em 0 2em 2.3em;
text-decoration: none; text-decoration: none;
opacity: 0.7; opacity: 0.7;
font-size: 80%; font-size: 80%;
display: flex;
align-items: center;
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
> svg {
height: 1rem;
width: 1rem;
margin-right: 0.25rem;
}
} }
.github-link { .github-link > svg > path {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1.19em" height="1em" viewBox="0 0 1664 1408"><path d="M640 960q0 40-12.5 82t-43 76t-72.5 34t-72.5-34t-43-76t-12.5-82t12.5-82t43-76t72.5-34t72.5 34t43 76t12.5 82zm640 0q0 40-12.5 82t-43 76t-72.5 34t-72.5-34t-43-76t-12.5-82t12.5-82t43-76t72.5-34t72.5 34t43 76t12.5 82zm160 0q0-120-69-204t-187-84q-41 0-195 21q-71 11-157 11t-157-11q-152-21-195-21q-118 0-187 84t-69 204q0 88 32 153.5t81 103t122 60t140 29.5t149 7h168q82 0 149-7t140-29.5t122-60t81-103t32-153.5zm224-176q0 207-61 331q-38 77-105.5 133t-141 86t-170 47.5t-171.5 22t-167 4.5q-78 0-142-3t-147.5-12.5t-152.5-30t-137-51.5t-121-81t-86-115Q0 992 0 784q0-237 136-396q-27-82-27-170q0-116 51-218q108 0 190 39.5T539 163q147-35 309-35q148 0 280 32q105-82 187-121t189-39q51 102 51 218q0 87-27 168q136 160 136 398z" fill="#{toRGB($nav-icon-color)}"/></svg>'); fill: var(--nav-icon-color);
} }
.sponsor-link { .sponsor-link {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path fill="crimson" d="M12 21.35l-1.45-1.32c-5.15-4.67-8.55-7.75-8.55-11.53 0-3.08 2.42-5.5 5.5-5.5 1.74 0 3.41.81 4.5 2.09 1.09-1.28 2.76-2.09 4.5-2.09 3.08 0 5.5 2.42 5.5 5.5 0 3.78-3.4 6.86-8.55 11.54l-1.45 1.31z"/></svg>');
margin-left: 2em; margin-left: 2em;
} }
@ -366,13 +457,107 @@ $footer-border-color: #CCC;
} }
&.active { &.active {
background-color: $pagination-active-color; background-color: var(--pagination-active-color);
color: $pagination-active-font-color; color: var(--pagination-active-font-color);
} }
&:hover:not(.active) { &:hover:not(.active) {
background-color: $pagination-hover-color; background-color: var(--pagination-hover-color);
color: $pagination-hover-font-color; color: var(--pagination-hover-font-color);
}
}
}
}
.mode-container {
display: flex;
align-items: center;
font-size: 80%;
svg {
width: 1rem;
height: 1rem;
margin: 0 2px;
}
label {
color: var(--font-color);
font-weight: 500;
}
.mode-switch {
display: inline-block;
margin: 0;
position: relative;
> label.mode-switch-inner {
margin: 0;
width: 140px;
height: 30px;
background: #E0E0E0;
border-radius: 26px;
overflow: hidden;
position: relative;
transition: all 0.3s ease;
display: block;
&:before {
content: attr(data-on);
position: absolute;
font-weight: 500;
top: 7px;
right: 20px;
}
&:after {
content: attr(data-off);
width: 70px;
height: 16px;
background: #fff;
border-radius: 26px;
position: absolute;
left: 2px;
top: 2px;
text-align: center;
transition: all 0.3s ease;
box-shadow: 0px 0px 6px -2px #111;
padding: 5px 0px;
}
}
> .alert {
display: none;
background: #FF9800;
border: none;
color: #fff;
}
input[type="checkbox"] {
cursor: pointer;
width: 50px;
height: 25px;
opacity: 0;
position: absolute;
top: 0;
z-index: 1;
margin: 0;
&:checked + label.mode-switch-inner {
background: #151515;
color: #fff;
&:after {
content: attr(data-on);
left: 68px;
background: #3c3c3c;
}
&:before {
content: attr(data-off);
right: auto;
left: 20px;
}
} }
} }
} }
@ -381,10 +566,27 @@ $footer-border-color: #CCC;
@media screen and (max-width: 750px) { @media screen and (max-width: 750px) {
.nav-tab-list { .nav-tab-list {
border-bottom: 0; border-bottom: 0;
display: flex;
flex-direction: column;
align-items: normal;
padding: 0;
} }
.nav-tab { .nav-tab {
display: block;
margin: 0; margin: 0;
border: 0;
border-top: 1px solid var(--nav-border-color);
border-left: 15px solid transparent;
padding: 15px 30px 15px 15px;
&:last-child {
border-bottom: 1px solid var(--nav-border-color);
}
&.active {
border: 0;
border-top: 1px solid var(--nav-border-color);
border-left: 15px solid var(--nav-header-color);
}
} }
.nav-tab-link { .nav-tab-link {
display: block; display: block;
@ -393,7 +595,7 @@ $footer-border-color: #CCC;
border: 0; border: 0;
} }
.nav-tab-link[data-for].active { .nav-tab-link[data-for].active {
border-bottom-color: $nav-border-color; border-bottom-color: var(--nav-border-color);
} }
.tab-content-overview-info { .tab-content-overview-info {
margin-right: auto; margin-right: auto;
@ -413,13 +615,20 @@ $footer-border-color: #CCC;
} }
} }
@keyframes pulse { @keyframes spin-pause {
0% { 0% {
transform: scale(1); transform: rotate(0deg);
opacity: 1;
} }
50%,100% { 50%, 100% {
transform: scale(2); transform: rotate(360deg);
opacity: 0; }
}
@keyframes spin-all {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
} }
} }

View file

@ -75,9 +75,9 @@ $opcache = (new Service($options))->handle();
</style> </style>
</head> </head>
<body style="padding: 0; margin: 0;"> <body style="padding: 0; margin: 0;" class="opcache-gui">
<div class="opcache-gui" id="interface" /> <div id="interface" />
<script type="text/javascript"> <script type="text/javascript">

255
index.php

File diff suppressed because one or more lines are too long

View file

@ -4,15 +4,16 @@
"version": "3.5.4", "version": "3.5.4",
"main": "index.js", "main": "index.js",
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.12.8", "@babel/cli": "^7.23.0",
"@babel/core": "^7.12.9", "@babel/core": "^7.23.2",
"@babel/preset-react": "^7.12.7", "@babel/plugin-proposal-class-properties": "^7.18.6",
"node-sass": ">=7.0.0" "@babel/preset-react": "^7.22.15",
"sass": "^1.69.5"
}, },
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"compile-jsx": "node_modules/.bin/babel --presets @babel/preset-react build/_frontend/interface.jsx --plugins @babel/plugin-proposal-class-properties -o build/interface.js", "compile-jsx": "node_modules/.bin/babel --presets @babel/preset-react build/_frontend/interface.jsx --plugins @babel/plugin-proposal-class-properties -o build/interface.js",
"compile-scss": "node_modules/.bin/node-sass -xi build/_frontend/interface.scss -o build/ --output-style=compressed" "compile-scss": "node_modules/.bin/sass --no-source-map --style=compressed -q build/_frontend/interface.scss build/interface.css"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -23,8 +24,5 @@
"bugs": { "bugs": {
"url": "https://github.com/amnuts/opcache-gui/issues" "url": "https://github.com/amnuts/opcache-gui/issues"
}, },
"homepage": "https://github.com/amnuts/opcache-gui#readme", "homepage": "https://github.com/amnuts/opcache-gui#readme"
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.12.1"
}
} }