diff options
| author | Zephyrrus <[email protected]> | 2021-01-07 23:55:37 +0200 |
|---|---|---|
| committer | Zephyrrus <[email protected]> | 2021-01-07 23:55:37 +0200 |
| commit | 925080f6a08a1f1515143db1bd6aef8109f5fb67 (patch) | |
| tree | 298476e0f2aea59422bcc46fb1e1ce8bb4f19c18 | |
| parent | chore: revert nuxt update, it breaks SSR in development mode, not worth it. (diff) | |
| download | host.fuwn.me-925080f6a08a1f1515143db1bd6aef8109f5fb67.tar.xz host.fuwn.me-925080f6a08a1f1515143db1bd6aef8109f5fb67.zip | |
chore: refactor stats generator to use an enum for types
fix: saved data not being converted to JSON automatically when using SQLite (and possibly MSSQL)
feat: display when a stat was generated in the section's header
fix: not being able to click through the footer (sorry IE11 users, you still won't be able to click through it)
fix: add is-mobile to columns so they don't stack on top of each other
feat: add text next to the NSFW toggle and make it look like the elements around it (begone round iOS edges)
| -rw-r--r-- | src/api/routes/service/statsGET.js | 24 | ||||
| -rw-r--r-- | src/api/utils/StatsGenerator.js | 34 | ||||
| -rw-r--r-- | src/api/utils/Util.js | 13 | ||||
| -rw-r--r-- | src/site/components/album/AlbumDetails.vue | 8 | ||||
| -rw-r--r-- | src/site/components/footer/Footer.vue | 6 | ||||
| -rw-r--r-- | src/site/components/sidebar/Sidebar.vue | 2 | ||||
| -rw-r--r-- | src/site/components/statistics/byte.vue | 2 | ||||
| -rw-r--r-- | src/site/components/statistics/byteUsage.vue | 2 | ||||
| -rw-r--r-- | src/site/components/statistics/detailed.vue | 17 | ||||
| -rw-r--r-- | src/site/components/statistics/generic.vue | 2 | ||||
| -rw-r--r-- | src/site/components/statistics/time.vue | 2 | ||||
| -rw-r--r-- | src/site/pages/dashboard/admin/statistics.vue | 7 | ||||
| -rw-r--r-- | src/site/pages/dashboard/albums/index.vue | 2 |
13 files changed, 93 insertions, 28 deletions
diff --git a/src/api/routes/service/statsGET.js b/src/api/routes/service/statsGET.js index d6fa69e..2241ca8 100644 --- a/src/api/routes/service/statsGET.js +++ b/src/api/routes/service/statsGET.js @@ -1,5 +1,6 @@ const Route = require('../../structures/Route'); const StatsGenerator = require('../../utils/StatsGenerator'); +const moment = require('moment'); // Thank you Bobby for the stats code https://github.com/BobbyWibowo/lolisafe/blob/safe.fiery.me/controllers/utilsController.js class filesGET extends Route { @@ -9,12 +10,23 @@ class filesGET extends Route { async run(req, res, db) { const cachedStats = await db('statistics') - .select('type', 'data', 'batchId') + .select('type', 'data', 'batchId', 'createdAt') .where('batchId', '=', db('statistics').max('batchId')); - let stats = cachedStats.reduce((acc, { type, data }) => { + let stats = cachedStats.reduce((acc, { type, data, createdAt }) => { try { - acc[type] = JSON.parse(data); + // pg returns json, sqlite retuns a string... + if (typeof data === 'string' || data instanceof String) { + acc[type] = JSON.parse(data); + } else { + acc[type] = data; + } + + acc[type].meta = { + cached: true, + generatedOn: moment(createdAt).format('MMMM Do YYYY, h:mm:ss a z'), // pg returns this as a date, sqlite3 returns an unix timestamp :< + type: StatsGenerator.Type.HIDDEN + }; } catch (e) { console.error(e); } @@ -24,10 +36,12 @@ class filesGET extends Route { stats = { ...stats, ...(await StatsGenerator.getMissingStats(db, Object.keys(stats))) }; - return res.json(StatsGenerator.keyOrder.reduce((acc, k) => { + const ordered = StatsGenerator.keyOrder.reduce((acc, k) => { acc[k] = stats[k]; return acc; - }, {})); + }, {}); + + return res.json({ statistics: ordered }); } } diff --git a/src/api/utils/StatsGenerator.js b/src/api/utils/StatsGenerator.js index 2e48f32..ce73cd2 100644 --- a/src/api/utils/StatsGenerator.js +++ b/src/api/utils/StatsGenerator.js @@ -1,6 +1,22 @@ const si = require('systeminformation'); class StatsGenerator { + // symbols would be better because they're unique, but harder to serialize them + static Type = Object.freeze({ + // should contain key value: number + TIME: 'time', + // should contain key value: number + BYTE: 'byte', + // should contain key value: { used: number, total: number } + BYTE_USAGE: 'byteUsage', + // should contain key data: Array<{ key: string, value: number | string }> + // and optionally a count/total + DETAILED: 'detailed', + // hidden type should be skipped during iteration, can contain anything + // these should be treated on a case by case basis on the frontend + HIDDEN: 'hidden' + }); + static statGenerators = { system: StatsGenerator.getSystemInfo, fileSystems: StatsGenerator.getFileSystemsInfo, @@ -30,20 +46,20 @@ class StatsGenerator { used: mem.active, total: mem.total }, - type: 'byteUsage' + type: StatsGenerator.Type.BYTE_USAGE }, 'Memory Usage': { value: process.memoryUsage().rss, - type: 'byte' + type: StatsGenerator.Type.BYTE }, 'System Uptime': { value: time.uptime, - type: 'time' + type: StatsGenerator.Type.TIME }, 'Node.js': `${process.versions.node}`, 'Service Uptime': { value: Math.floor(nodeUptime), - type: 'time' + type: StatsGenerator.Type.TIME } }; } @@ -58,7 +74,7 @@ class StatsGenerator { total: fs.size, used: fs.used }, - type: 'byteUsage' + type: StatsGenerator.Type.BYTE_USAGE }; } @@ -73,11 +89,11 @@ class StatsGenerator { 'Others': { data: {}, count: 0, - type: 'detailed' + type: StatsGenerator.Type.DETAILED }, 'Size in DB': { value: 0, - type: 'byte' + type: StatsGenerator.Type.BYTE } }; @@ -88,7 +104,7 @@ class StatsGenerator { 'Total': uploads.length, 'Size in DB': { value: uploads.reduce((acc, upload) => acc + parseInt(upload.size, 10), 0), - type: 'byte' + type: StatsGenerator.Type.BYTE } }; }; @@ -127,7 +143,7 @@ class StatsGenerator { Others: { data, count, - type: 'detailed' + type: StatsGenerator.Type.DETAILED } }; }; diff --git a/src/api/utils/Util.js b/src/api/utils/Util.js index 658ac61..6feedd4 100644 --- a/src/api/utils/Util.js +++ b/src/api/utils/Util.js @@ -311,11 +311,18 @@ class Util { return extname + multi; } - static async saveStatsToDb() { + // TODO: Allow choosing what to save to db and what stats we care about in general + // TODO: if a stat is not saved to db but selected to be shows on the dashboard, it will be generated during the request + static async saveStatsToDb(force) { + // If there were no changes since the instance started, don't generate new stats + // OR // if we alredy saved a stats to the db, and there were no new changes to the db since then // skip generating and saving new stats. - // XXX: Should we save non-db related statistics to the database anyway? (like performance, disk usage) - if (statsLastSavedTime && statsLastSavedTime > db.userParams.lastMutationTime) { + if (!force && + (!db.userParams.lastMutationTime || + (statsLastSavedTime && statsLastSavedTime > db.userParams.lastMutationTime) + ) + ) { return; } diff --git a/src/site/components/album/AlbumDetails.vue b/src/site/components/album/AlbumDetails.vue index 81819b2..da472b0 100644 --- a/src/site/components/album/AlbumDetails.vue +++ b/src/site/components/album/AlbumDetails.vue @@ -101,7 +101,13 @@ <div class="level-item"> <b-switch :value="nsfw" - @input="toggleNsfw()" /> + :rounded="false" + type="is-warning" + class="has-text-light" + left-label + @input="toggleNsfw()"> + NSFW + </b-switch> </div> <div class="level-item"> <button diff --git a/src/site/components/footer/Footer.vue b/src/site/components/footer/Footer.vue index 96774e7..0c77603 100644 --- a/src/site/components/footer/Footer.vue +++ b/src/site/components/footer/Footer.vue @@ -72,6 +72,9 @@ export default { <style lang="scss" scoped> @import '~/assets/styles/_colors.scss'; footer { + pointer-events: none; + touch-action: none; + @media screen and (min-width: 1025px) { position: fixed; bottom: 0; @@ -84,6 +87,9 @@ export default { .container { .column { + pointer-events: auto; + touch-action: auto; + text-align: center; @media screen and (min-width: 1025px) { margin-right: 2rem; diff --git a/src/site/components/sidebar/Sidebar.vue b/src/site/components/sidebar/Sidebar.vue index 98c3c81..a021226 100644 --- a/src/site/components/sidebar/Sidebar.vue +++ b/src/site/components/sidebar/Sidebar.vue @@ -29,7 +29,7 @@ </template> <b-menu-item icon="account" label="Users" tag="nuxt-link" to="/dashboard/admin/users" exact /> <b-menu-item icon="cog-outline" label="Settings" tag="nuxt-link" to="/dashboard/admin/settings" exact /> - <!--<b-menu-item icon="chart-line" label="Statistics" tag="nuxt-link" to="/dashboard/admin/statistics" exact />--> + <b-menu-item icon="chart-line" label="Statistics" tag="nuxt-link" to="/dashboard/admin/statistics" exact /> </b-menu-item> <b-menu-item class="item" diff --git a/src/site/components/statistics/byte.vue b/src/site/components/statistics/byte.vue index 05852cd..16f4427 100644 --- a/src/site/components/statistics/byte.vue +++ b/src/site/components/statistics/byte.vue @@ -1,6 +1,6 @@ <template> <div> - <div class="columns"> + <div class="columns is-mobile"> <div class="column is-2"> {{ title }} </div> diff --git a/src/site/components/statistics/byteUsage.vue b/src/site/components/statistics/byteUsage.vue index 740feff..9062e5e 100644 --- a/src/site/components/statistics/byteUsage.vue +++ b/src/site/components/statistics/byteUsage.vue @@ -1,6 +1,6 @@ <template> <div> - <div class="columns"> + <div class="columns is-mobile"> <div class="column is-2"> {{ title }} </div> diff --git a/src/site/components/statistics/detailed.vue b/src/site/components/statistics/detailed.vue index 8a0722e..0d93e9a 100644 --- a/src/site/components/statistics/detailed.vue +++ b/src/site/components/statistics/detailed.vue @@ -1,11 +1,11 @@ <template> <div> - <div class="columns"> + <div class="columns is-mobile"> <div class="column is-2"> {{ title }} </div> <div class="column"> - <b-table :data="data || []" :mobile-cards="true"> + <b-table v-if="data.length" :data="data || []" :mobile-cards="true" narrowed class="details"> <b-table-column v-slot="props" field="type" label="Type"> {{ props.row.key }} </b-table-column> @@ -13,6 +13,9 @@ {{ props.row.value }} </b-table-column> </b-table> + <template v-else> + - + </template> </div> </div> </div> @@ -31,3 +34,13 @@ export default { } }; </script> +<style lang="scss" scoped> + .details ::v-deep .table-wrapper { + box-shadow: none; + + .table { + border-radius: unset; + background: #2A2E3C; + } + } +</style> diff --git a/src/site/components/statistics/generic.vue b/src/site/components/statistics/generic.vue index 704be7a..aa0f7e9 100644 --- a/src/site/components/statistics/generic.vue +++ b/src/site/components/statistics/generic.vue @@ -1,6 +1,6 @@ <template> <div> - <div class="columns"> + <div class="columns is-mobile"> <div class="column is-2"> {{ title }} </div> diff --git a/src/site/components/statistics/time.vue b/src/site/components/statistics/time.vue index ff1bb8d..54174da 100644 --- a/src/site/components/statistics/time.vue +++ b/src/site/components/statistics/time.vue @@ -1,6 +1,6 @@ <template> <div> - <div class="columns"> + <div class="columns is-mobile"> <div class="column is-2"> {{ title }} </div> diff --git a/src/site/pages/dashboard/admin/statistics.vue b/src/site/pages/dashboard/admin/statistics.vue index 4d601cf..ecee102 100644 --- a/src/site/pages/dashboard/admin/statistics.vue +++ b/src/site/pages/dashboard/admin/statistics.vue @@ -14,8 +14,11 @@ <div :key="category" class="stats-container"> <h2 class="title"> - {{ category }} + {{ category }} <span v-if="stats[category].meta" class="is-size-7 is-pulled-right is-family-monospace has-text-grey-light"> + generated on {{ stats[category].meta.generatedOn }} + </span> </h2> + <template v-for="item in Object.keys(stats[category])"> <!-- If it's plain text or a number, just print it --> <template v-if="typeof stats[category][item] === 'string' || typeof stats[category][item] === 'number'"> @@ -25,7 +28,7 @@ </template> <!-- If it's an object then we need to do some magic --> - <template v-else-if="typeof stats[category][item] === 'object'"> + <template v-else-if="typeof stats[category][item] === 'object' && stats[category][item].type !== 'hidden'"> <byteUsage v-if="stats[category][item].type === 'byteUsage'" :key="item" :title="item" diff --git a/src/site/pages/dashboard/albums/index.vue b/src/site/pages/dashboard/albums/index.vue index e3ccc08..2ebfb3f 100644 --- a/src/site/pages/dashboard/albums/index.vue +++ b/src/site/pages/dashboard/albums/index.vue @@ -105,7 +105,7 @@ export default { div.search-container { padding: 1rem 2rem; - background-color: $base-2; + // background-color: $base-2; } div.column > h2.subtitle { padding-top: 1px; } |