♻️ Style optimisation + minor refactor

- use consistent css units
- replace hard-coded color values with variables
- update disk quota chart render (to allow for variable colors)
- small style update to the notifications widget
This commit is contained in:
Marcell Fülöp 2022-06-20 17:42:45 +00:00
parent 7d8d3078b2
commit 278a6fc7b7
6 changed files with 99 additions and 91 deletions

View File

@ -1,9 +1,9 @@
<template> <template>
<div class="nextcloud-widget nextcloud-status-wrapper"> <div class="nextcloud-widget nextcloud-status-wrapper">
<div v-if="notifications.length" class="sep"> <div v-if="notifications.length">
<!-- group actions: delete all --> <!-- group actions: delete all -->
<p v-if="canDeleteNotification('delete-all')"> <p v-if="canDeleteNotification('delete-all')" class="group-action">
<span class="action group-action" @click="deleteNotifications">{{ tt('delete-all') }}</span> <span class="action secondary" @click="deleteNotifications">{{ tt('delete-all') }}</span>
</p> </p>
<hr/> <hr/>
<!-- notifications list --> <!-- notifications list -->
@ -147,26 +147,25 @@ export default {
div p small i { div p small i {
position: relative; position: relative;
top: .25rem; top: .25em;
} }
small.date { small.date {
background: var(--widget-text-color); background: var(--widget-text-color);
color: var(--widget-accent-color); color: var(--widget-accent-color);
border-radius: 4px; border-radius: .25em;
padding: .15rem .3rem; padding: .15em .3em;
margin: .25rem .25rem .25rem 0; margin: .25em .25em .25em 0;
display: inline-block; display: inline-block;
font-weight: bold; font-weight: bold;
opacity: .66;
} }
span.group-action { p.group-action {
float: right; margin-top: 0;
} }
span.action, span a.action { span.action, span a.action {
cursor: pointer; cursor: pointer;
margin: .1rem 0 .1rem .5rem; margin: .1em .5em .1em 0;
padding: .15rem; padding: .15em;
border-radius: 4px; border-radius: .25em;
white-space: nowrap; white-space: nowrap;
} }
span.action:hover, span a.action:hover { span.action:hover, span a.action:hover {
@ -197,13 +196,13 @@ export default {
width: 16px; width: 16px;
height: 16px; height: 16px;
position: relative; position: relative;
top: 1rem; top: 1em;
opacity: .75; opacity: .75;
} }
} }
} }
div hr { div hr {
margin-top: 0.3rem; margin-top: .3em;
margin-bottom: 0; margin-bottom: 0;
} }
} }

View File

@ -18,7 +18,7 @@
<i class="fal fa-browser"></i> <i class="fal fa-browser"></i>
<em v-html="formatNumber(apps.num_installed)"></em> <em v-html="formatNumber(apps.num_installed)"></em>
<strong>{{ tt('applications') }}</strong> <strong>{{ tt('applications') }}</strong>
<span v-if="apps.num_updates_available" data-nc-updates class="success"> <span v-if="apps.num_updates_available" class="success has-updates">
<i class="fal fa-download"></i><em>{{ apps.num_updates_available }}</em> <i class="fal fa-download"></i><em>{{ apps.num_updates_available }}</em>
<strong> <strong>
{{ tt('updates-available', {{ tt('updates-available',
@ -191,10 +191,8 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
@import '@/styles/widgets/nextcloud-shared.scss'; @import '@/styles/widgets/nextcloud-shared.scss';
.nextcloud-stats-wrapper { .nextcloud-stats-wrapper {
div.server-info { div.server-info .nc-updates {
[data-nc-updates] { margin-left: .5em;
margin-left: 0.5rem;
}
} }
} }
</style> </style>

View File

@ -144,10 +144,10 @@ export default {
}, },
getMemoryGaugeColor(memPercent) { getMemoryGaugeColor(memPercent) {
if (memPercent < 50) return this.getColorRgba('widget-text-color', 0.6); if (memPercent < 50) return this.getColorRgba('widget-text-color', 0.6);
if (memPercent < 60) return '#f6f000'; if (memPercent < 60) return this.getColorRgba('warning', 0.75);
if (memPercent < 80) return '#fca016'; if (memPercent < 80) return this.getColorRgba('error', 0.9);
if (memPercent < 100) return '#f80363'; if (memPercent < 100) return this.getColorRgba('danger');
return '#272f4d'; return this.getColorRgba('background');
}, },
getMemoryGaugeLabel() { getMemoryGaugeLabel() {
const sys = this.server.nextcloud.system; const sys = this.server.nextcloud.system;
@ -201,14 +201,15 @@ export default {
max-width: 44%; max-width: 44%;
small { small {
font-size: 12px; font-size: 12px;
color: #999999; color: #666666;
display: inline-block; display: inline-block;
width: 100%; width: 100%;
text-align: center; text-align: center;
margin: .69rem 0 1rem 0; margin: .9em 0 1.4em 0;
opacity: 1;
} }
small:last-child { small:last-child {
margin-top: 16px; margin-top: 2em;
font-size: 10px; font-size: 10px;
} }
} }
@ -219,8 +220,8 @@ export default {
color: var(--widget-text-color); color: var(--widget-text-color);
text-align: center; text-align: center;
position: absolute; position: absolute;
font-size: 1.3rem; font-size: 1.3em;
margin: 0.5rem 0; margin: .5em 0;
width: 100%; width: 100%;
bottom: 0; bottom: 0;
} }

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-if="user.id" class="nextcloud-widget nextcloud-info-wrapper"> <div v-if="didLoadData" class="nextcloud-widget nextcloud-info-wrapper">
<!-- logo, branding, user info --> <!-- logo, branding, user info -->
<div> <div>
<div class="logo"> <div class="logo">
@ -13,7 +13,7 @@
<p class="version" v-if="version.string"> <p class="version" v-if="version.string">
<small>Nextcloud {{ tt('version') }} {{ version.string }}</small> <small>Nextcloud {{ tt('version') }} {{ version.string }}</small>
</p> </p>
<p class="username">{{ user.displayName }} <em v-if="user.id">({{ user.id }})</em></p> <p class="username">{{ user.displayName }} <em>({{ user.id }})</em></p>
<p class="login" v-tooltip="lastLoginTooltip()"> <p class="login" v-tooltip="lastLoginTooltip()">
<span>{{ tt('last-login') }}</span>&nbsp; <span>{{ tt('last-login') }}</span>&nbsp;
<small>{{ getTimeAgo(user.lastLogin) }}</small> <small>{{ getTimeAgo(user.lastLogin) }}</small>
@ -30,8 +30,8 @@
<strong v-else>{{ tt('disk-space') }}</strong> <strong v-else>{{ tt('disk-space') }}</strong>
<em v-html="formatPercent(user.quota.relative)"></em> <em v-html="formatPercent(user.quota.relative)"></em>
<small>{{ tt('of') }}</small><strong v-html="convertBytes(user.quota.total)"></strong> <small>{{ tt('of') }}</small><strong v-html="convertBytes(user.quota.total)"></strong>
<span v-if="quotaChartData"> <span v-if="quotaChart.dataLoaded">
<PercentageChart :values="quotaChartData" :showLegend="false" /> <PercentageChart :values="quotaChart.data" :showLegend="false" />
</span> </span>
</p> </p>
<hr/> <hr/>
@ -68,9 +68,20 @@ export default {
quota: null, quota: null,
}, },
}, },
quotaChartData: null, quotaChart: {
dataLoaded: false,
data: [
{ label: null, size: null, color: null },
{ label: null, size: null, color: null },
],
},
}; };
}, },
computed: {
didLoadData() {
return !!this.user.id;
},
},
methods: { methods: {
allowedStatuscodes() { allowedStatuscodes() {
return [100, 200]; return [100, 200];
@ -92,18 +103,20 @@ export default {
this.user.quota = user.quota; this.user.quota = user.quota;
this.user.displayName = user.displayname; this.user.displayName = user.displayname;
this.user.lastLogin = user.lastLogin; this.user.lastLogin = user.lastLogin;
},
getQuotaChartColorUsed(percent) {
if (percent < 0.75) return this.getValueFromCss('widget-text-color');
if (percent < 0.85) return this.getValueFromCss('warning');
if (percent < 0.95) return this.getValueFromCss('error');
return this.getValueFromCss('danger');
},
updateQuotaChart() {
const used = parseFloat(this.user.quota.used / this.user.quota.total); const used = parseFloat(this.user.quota.used / this.user.quota.total);
const free = parseFloat(this.user.quota.free / this.user.quota.total); const free = parseFloat(this.user.quota.free / this.user.quota.total);
this.quotaChartData = [ const d = this.quotaChart.data;
{ label: this.tt('used'), size: used, color: this.getQuotaChartColor(used) }, d[0] = { label: this.tt('used'), size: used, color: this.getQuotaChartColorUsed(used) };
{ label: this.tt('available'), size: free, color: '#20e253' }, d[1] = { label: this.tt('available'), size: free, color: this.getValueFromCss('success') };
]; this.quotaChart.dataLoaded = true;
},
getQuotaChartColor(percent) {
if (percent < 0.75) return '#272f4d';
if (percent < 0.85) return '#fce216';
if (percent < 0.95) return '#ff9000';
return '#f80363';
}, },
/* Tooltip generators */ /* Tooltip generators */
quotaTooltip() { quotaTooltip() {
@ -126,6 +139,9 @@ export default {
created() { created() {
this.overrideUpdateInterval = 120; this.overrideUpdateInterval = 120;
}, },
updated() {
this.updateQuotaChart();
},
}; };
</script> </script>
@ -139,20 +155,20 @@ export default {
border-top: none; border-top: none;
} }
div.percentage-chart-wrapper { div.percentage-chart-wrapper {
margin: 0 0.75rem; margin: 0 .75em;
width: 5em; width: 5em;
position: relative; position: relative;
top: 0.2rem; top: .2em;
float: right; float: right;
} }
div.logo { div.logo {
width: 40%; width: 40%;
text-align: center; text-align: center;
img { img {
width: 8rem; width: 8em;
} }
p { p {
font-size: 90%; font-size: .9em;
opacity: .85; opacity: .85;
} }
} }
@ -166,23 +182,23 @@ export default {
} }
p.brand { p.brand {
margin: 0; margin: 0;
font-size: 135%; font-size: 1.35em;
font-weight: 800; font-weight: 800;
letter-spacing: 3px; letter-spacing: 3px;
} }
p.version small { p.version small {
font-size: 75%; font-size: .75em;
} }
p.username { p.username {
font-size: 110%; font-size: 1.1em;
em { em {
font-size: 90%; font-size: .9em;
} }
} }
p.login { p.login {
span { span {
font-size: 90%; font-size: .9em;
margin-right: .25rem; margin-right: .25em;
} }
} }
} }

View File

@ -19,7 +19,7 @@
<!-- user status: status --> <!-- user status: status -->
<div> <div>
<p> <p>
<small :class="'status ' + getStatusClass(status.status)"> <small :class="`status ${status.status}`">
<i v-if="status.status === 'online' || status.status === 'dnd'" <i v-if="status.status === 'online' || status.status === 'dnd'"
class="fas fa-circle" v-tooltip="tt(status.status)"></i> class="fas fa-circle" v-tooltip="tt(status.status)"></i>
<i v-else class="far fa-circle" v-tooltip="tt(status.status)"></i> <i v-else class="far fa-circle" v-tooltip="tt(status.status)"></i>
@ -131,14 +131,6 @@ export default {
this.newStatuses[status.userId] = status; this.newStatuses[status.userId] = status;
} }
}, },
getStatusClass(status) {
switch (status) {
case 'online': return 'success';
case 'away': return 'warning';
case 'dnd': return 'danger';
case 'offline': default: return 'disabled';
}
},
/* Tooltip generators */ /* Tooltip generators */
clearAtTooltip(clearAtTime) { clearAtTooltip(clearAtTime) {
const content = clearAtTime ? `${this.tt('until')}` const content = clearAtTime ? `${this.tt('until')}`
@ -165,6 +157,18 @@ export default {
margin: 0; margin: 0;
} }
} }
.online {
color: var(--success);
}
.offline {
color: var(--medium-grey);
}
.away {
color: var(--error);
}
.dnd {
color: var(--danger);
}
div.user > div { div.user > div {
display: table; display: table;
width: 100%; width: 100%;
@ -177,7 +181,7 @@ export default {
} }
> div:nth-child(2) { > div:nth-child(2) {
p small i { p small i {
color: #aaaaaa; color: var(--medium-grey);
top: 0; top: 0;
opacity: .5; opacity: .5;
margin: 0; margin: 0;
@ -189,8 +193,11 @@ export default {
} }
} }
div.user hr { div.user hr {
margin-top: 0.3rem; margin-top: .3em;
margin-bottom: 0.3rem; margin-bottom: .3em;
}
div.user hr:last-child {
margin-bottom: 0;
} }
} }
</style> </style>

View File

@ -1,7 +1,7 @@
.nextcloud-widget { .nextcloud-widget {
p { p {
color: var(--widget-text-color); color: var(--widget-text-color);
margin: 0.5rem 0; margin: .5em 0;
} }
a { a {
@ -9,21 +9,21 @@
} }
p i { p i {
font-size: 110%; font-size: 1.1em;
min-width: 22px; min-width: 22px;
text-align: center; text-align: center;
} }
p em { p em {
font-size: 110%; font-size: 1.1em;
margin: 0 4px; margin: 0 .24em;
font-weight: 800; font-weight: 800;
} }
strong { strong {
font-weight: 800; font-weight: 800;
font-size: 105%; font-size: 1.05em;
margin-left: .25rem; margin-left: .25em;
} }
small { small {
@ -34,16 +34,19 @@
color: var(--widget-text-color); color: var(--widget-text-color);
border: none; border: none;
border-top: 1px solid; border-top: 1px solid;
margin-top: 0.8rem; margin-top: .8em;
margin-bottom: 0.8rem; margin-bottom: .8em;
opacity: .25; opacity: .25;
clear: both; clear: both;
} }
hr:last-child {
margin-bottom: 0;
}
div.sep { div.sep {
border-top: 1px dashed var(--widget-text-color); border-top: 1px dashed var(--widget-text-color);
width: 100%; width: 100%;
padding: .4rem 0; padding: .4em 0 0 0;
margin: .85em 0 0 0; margin: .85em 0 0 0;
> div:not(:first-child) { > div:not(:first-child) {
width: 100%; width: 100%;
@ -51,22 +54,6 @@
} }
} }
.success {
color: var(--success);
}
.warning {
color: #ff9000;
}
.danger {
color: var(--danger);
}
.disabled {
color: #818181;
}
::v-deep span.decimals { ::v-deep span.decimals {
font-size: 85%; font-size: 85%;
} }