From bc7224766134a271ad379f8d2f6fb460a2b08dda Mon Sep 17 00:00:00 2001 From: pusztaienike Date: Tue, 1 Jun 2021 17:26:54 +0200 Subject: [PATCH 1/5] add usage widget to stats --- apps/sensenet/package.json | 2 + .../settings/stats-usage-widget.tsx | 135 ++++++++++++++++++ .../src/components/settings/stats.tsx | 2 + apps/sensenet/src/localization/default.ts | 2 + apps/sensenet/src/localization/hungarian.ts | 2 + yarn.lock | 10 ++ 6 files changed, 153 insertions(+) create mode 100644 apps/sensenet/src/components/settings/stats-usage-widget.tsx diff --git a/apps/sensenet/package.json b/apps/sensenet/package.json index 178f992f0..33ff8d5de 100644 --- a/apps/sensenet/package.json +++ b/apps/sensenet/package.json @@ -99,10 +99,12 @@ "clsx": "^1.1.1", "date-fns": "^2.21.3", "filesize": "^6.3.0", + "frappe-charts": "^1.6.1", "react": "^16.13.0", "react-autosuggest": "^10.1.0", "react-day-picker": "^7.4.10", "react-dom": "^16.13.0", + "react-frappe-charts": "^4.0.0", "react-markdown": "^6.0.2", "react-monaco-editor": "0.43.0", "react-responsive": "^8.2.0", diff --git a/apps/sensenet/src/components/settings/stats-usage-widget.tsx b/apps/sensenet/src/components/settings/stats-usage-widget.tsx new file mode 100644 index 000000000..3f68d913f --- /dev/null +++ b/apps/sensenet/src/components/settings/stats-usage-widget.tsx @@ -0,0 +1,135 @@ +import { formatSize } from '@sensenet/controls-react' +import { createStyles, ListItemText, makeStyles, MenuItem, Paper, Select } from '@material-ui/core' +import React, { useState } from 'react' +import ReactFrappeChart from 'react-frappe-charts' +import { widgetStyles } from '../../globalStyles' +import { useLocalization } from '../../hooks' +import { useDateUtils } from '../../hooks/use-date-utils' + +const exampleStatsUsageData = { + ApiCalls: 3, + UsageOfThisRepository: 250085376, //byte + UsageData: [ + { + PeriodStartDate: '2021-01-01T00:00:00Z', + PeriodEndDate: '2021-02-01T00:00:00Z', + UsageValues: [ + 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, 233, 233, 232, 234, 43, 23, 32, 65, 1, 0, 1, 22, 91, 24, 25, 6, 3, + 80, 2, 2, 3, + ], + }, + { + PeriodStartDate: '2021-02-01T00:00:00Z', + PeriodEndDate: '2021-03-01T00:00:00Z', + UsageValues: [ + 234, 43, 23, 32, 65, 1, 0, 1, 22, 91, 24, 25, 6, 3, 80, 2, 2, 3, 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, + 233, 233, + ], + }, + { + PeriodStartDate: '2021-03-01T00:00:00Z', + PeriodEndDate: '2021-04-01T00:00:00Z', + UsageValues: [ + 234, 143, 123, 132, 165, 111, 110, 11, 122, 91, 24, 25, 6, 3, 80, 2, 2, 3, 215, 220, 230, 215, 258, 112, 17, 37, + 12, 23, 233, 233, + ], + }, + { + PeriodStartDate: '2021-04-01T00:00:00Z', + PeriodEndDate: '2021-05-01T00:00:00Z', + UsageValues: [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 91, 24, 25, 6, 3, 80, 2, 2, 3, 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, 233, + 233, + ], + }, + { + // ez egy tört hónap + PeriodStartDate: '2021-05-01T00:00:00Z', + PeriodEndDate: '2021-05-13T00:00:00Z', + UsageValues: [200, 201, 202, 203, 204, 205, 206, 207, 208, 291, 324, 325, 306], + }, + ], +} + +const useWidgetStyles = makeStyles(widgetStyles) + +const useStyles = makeStyles(() => { + return createStyles({ + rowContainer: { + padding: '16px 0', + }, + usageContainer: { + display: 'flex', + flexFlow: 'row', + }, + leftContent: { + width: '60%', + backgroundColor: '#252525', + }, + rightContent: { + width: '40%', + paddingLeft: '40px', + }, + }) +}) +export const UsageWidget: React.FunctionComponent = () => { + const classes = useStyles() + const widgetClasses = useWidgetStyles() + const localization = useLocalization().settings + const dateUtils = useDateUtils() + const [currentData, setCurrentData] = useState( + exampleStatsUsageData.UsageData[exampleStatsUsageData.UsageData.length - 1], + ) + + return ( +
+ +
+ {localization.usage} +
+
+
+ +
+
+ +
{localization.usageOfThisRepo}
+
{formatSize(exampleStatsUsageData.UsageOfThisRepository)}
+
{localization.apiCalls}
+
{exampleStatsUsageData.ApiCalls}
+
+
+
+
+ ) +} diff --git a/apps/sensenet/src/components/settings/stats.tsx b/apps/sensenet/src/components/settings/stats.tsx index 54ac553d6..c13e96f58 100644 --- a/apps/sensenet/src/components/settings/stats.tsx +++ b/apps/sensenet/src/components/settings/stats.tsx @@ -9,6 +9,7 @@ import { FullScreenLoader } from '../full-screen-loader' import { ComponentsWidget } from './stats-components-widget' import { InstalledPackagesWidget } from './stats-installed-packages-widget' import { StorageWidget } from './stats-storage-widget' +import { UsageWidget } from './stats-usage-widget' export const Stats: React.FunctionComponent = () => { const globalClasses = useGlobalStyles() @@ -53,6 +54,7 @@ export const Stats: React.FunctionComponent = () => { + diff --git a/apps/sensenet/src/localization/default.ts b/apps/sensenet/src/localization/default.ts index 97c9a7867..e4768405b 100644 --- a/apps/sensenet/src/localization/default.ts +++ b/apps/sensenet/src/localization/default.ts @@ -462,6 +462,8 @@ const values = { installedPackagesInfo: 'These packages are mainly the building bricks of sensenet components. There are tool-like packages that are not part of the component structure, they were made to run multiple times, for example delete or index content.', notAvailable: 'Not available', + usageOfThisRepo: 'Usage of this repository', + apiCalls: 'API calls', }, customActions: { executeCustomActionDialog: { diff --git a/apps/sensenet/src/localization/hungarian.ts b/apps/sensenet/src/localization/hungarian.ts index dc3ebfdd7..ea8f54692 100644 --- a/apps/sensenet/src/localization/hungarian.ts +++ b/apps/sensenet/src/localization/hungarian.ts @@ -200,6 +200,8 @@ const values: DeepPartial = { installedPackagesInfo: 'Csomagok, melyekből a sensenet komponensek felépülnek. Léteznek olyan csomagok is, melyek nem felelősek a komponensekért, többszöri futtatásra lettek létrehozva - ilyenek a tool-típusú csomagok. Ezek például kontent törlésre vagy indexelésre használatosak.', notAvailable: 'Nem elérhető', + usageOfThisRepo: 'A tárhely státusza', + apiCalls: 'API hívások', }, forms: { referencePicker: 'Referencia választó', diff --git a/yarn.lock b/yarn.lock index 32e4a0620..72b882854 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12068,6 +12068,11 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" +frappe-charts@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/frappe-charts/-/frappe-charts-1.6.1.tgz#2162cec05f4524b10cf232df8787a3ac20218384" + integrity sha512-Fteae/oqv4XdxP4ALoqTmUBBvXt8ECtghziqabp1ZA4yLqY8a3haafNqluwUCxnBOvrV+EdpvhZu0H+VEebX1Q== + fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -21318,6 +21323,11 @@ react-focus-lock@^2.1.0: use-callback-ref "^1.2.1" use-sidecar "^1.0.1" +react-frappe-charts@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/react-frappe-charts/-/react-frappe-charts-4.0.0.tgz#5a9958641ac0e74ce4c44a23788a5e879ac716a7" + integrity sha512-QmYY1ExlPidE8DK3jtjGWakP0YptHOlFMoYF4/Qxsbrw5hYMCwocPoco4b3e2qk6mI0trdpzILzpjmFWutO/MA== + react-helmet-async@^1.0.2, react-helmet-async@^1.0.7: version "1.0.9" resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.0.9.tgz#5b9ed2059de6b4aab47f769532f9fbcbce16c5ca" From 947f2ad5670eb1987b54feea3618639d6ef3e2d9 Mon Sep 17 00:00:00 2001 From: pusztaienike Date: Wed, 2 Jun 2021 08:55:06 +0200 Subject: [PATCH 2/5] make changes --- .../components/settings/stats-usage-widget.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/sensenet/src/components/settings/stats-usage-widget.tsx b/apps/sensenet/src/components/settings/stats-usage-widget.tsx index 3f68d913f..c7166ed1c 100644 --- a/apps/sensenet/src/components/settings/stats-usage-widget.tsx +++ b/apps/sensenet/src/components/settings/stats-usage-widget.tsx @@ -7,8 +7,6 @@ import { useLocalization } from '../../hooks' import { useDateUtils } from '../../hooks/use-date-utils' const exampleStatsUsageData = { - ApiCalls: 3, - UsageOfThisRepository: 250085376, //byte UsageData: [ { PeriodStartDate: '2021-01-01T00:00:00Z', @@ -17,6 +15,8 @@ const exampleStatsUsageData = { 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, 233, 233, 232, 234, 43, 23, 32, 65, 1, 0, 1, 22, 91, 24, 25, 6, 3, 80, 2, 2, 3, ], + ApiCalls: 2, + UsagePerMonth: 230085376, //byte }, { PeriodStartDate: '2021-02-01T00:00:00Z', @@ -25,6 +25,8 @@ const exampleStatsUsageData = { 234, 43, 23, 32, 65, 1, 0, 1, 22, 91, 24, 25, 6, 3, 80, 2, 2, 3, 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, 233, 233, ], + ApiCalls: 6, + UsagePerMonth: 220085376, //byte }, { PeriodStartDate: '2021-03-01T00:00:00Z', @@ -33,6 +35,8 @@ const exampleStatsUsageData = { 234, 143, 123, 132, 165, 111, 110, 11, 122, 91, 24, 25, 6, 3, 80, 2, 2, 3, 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, 233, 233, ], + ApiCalls: 5, + UsagePerMonth: 50232435, //byte }, { PeriodStartDate: '2021-04-01T00:00:00Z', @@ -41,12 +45,16 @@ const exampleStatsUsageData = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 91, 24, 25, 6, 3, 80, 2, 2, 3, 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, 233, 233, ], + ApiCalls: 1, + UsagePerMonth: 12344544, //byte }, { // ez egy tört hónap PeriodStartDate: '2021-05-01T00:00:00Z', PeriodEndDate: '2021-05-13T00:00:00Z', UsageValues: [200, 201, 202, 203, 204, 205, 206, 207, 208, 291, 324, 325, 306], + ApiCalls: 3, + UsagePerMonth: 250085376, //byte }, ], } @@ -124,9 +132,9 @@ export const UsageWidget: React.FunctionComponent = () => { })}
{localization.usageOfThisRepo}
-
{formatSize(exampleStatsUsageData.UsageOfThisRepository)}
+
{formatSize(currentData.UsagePerMonth)}
{localization.apiCalls}
-
{exampleStatsUsageData.ApiCalls}
+
{currentData.ApiCalls}
From 13cf1861b5d8abb5af76fbe7f52213b8c7db2ce6 Mon Sep 17 00:00:00 2001 From: pusztaienike Date: Mon, 14 Jun 2021 16:15:02 +0200 Subject: [PATCH 3/5] fix types --- .../settings/stats-usage-widget.tsx | 184 +++++++++++------- .../src/components/settings/stats.tsx | 23 ++- apps/sensenet/src/localization/default.ts | 5 +- apps/sensenet/src/localization/hungarian.ts | 5 +- 4 files changed, 143 insertions(+), 74 deletions(-) diff --git a/apps/sensenet/src/components/settings/stats-usage-widget.tsx b/apps/sensenet/src/components/settings/stats-usage-widget.tsx index c7166ed1c..3a2d25a00 100644 --- a/apps/sensenet/src/components/settings/stats-usage-widget.tsx +++ b/apps/sensenet/src/components/settings/stats-usage-widget.tsx @@ -1,62 +1,90 @@ import { formatSize } from '@sensenet/controls-react' import { createStyles, ListItemText, makeStyles, MenuItem, Paper, Select } from '@material-ui/core' -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import ReactFrappeChart from 'react-frappe-charts' import { widgetStyles } from '../../globalStyles' import { useLocalization } from '../../hooks' import { useDateUtils } from '../../hooks/use-date-utils' -const exampleStatsUsageData = { - UsageData: [ - { - PeriodStartDate: '2021-01-01T00:00:00Z', - PeriodEndDate: '2021-02-01T00:00:00Z', - UsageValues: [ - 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, 233, 233, 232, 234, 43, 23, 32, 65, 1, 0, 1, 22, 91, 24, 25, 6, 3, - 80, 2, 2, 3, - ], - ApiCalls: 2, - UsagePerMonth: 230085376, //byte - }, - { - PeriodStartDate: '2021-02-01T00:00:00Z', - PeriodEndDate: '2021-03-01T00:00:00Z', - UsageValues: [ - 234, 43, 23, 32, 65, 1, 0, 1, 22, 91, 24, 25, 6, 3, 80, 2, 2, 3, 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, - 233, 233, - ], - ApiCalls: 6, - UsagePerMonth: 220085376, //byte - }, - { - PeriodStartDate: '2021-03-01T00:00:00Z', - PeriodEndDate: '2021-04-01T00:00:00Z', - UsageValues: [ - 234, 143, 123, 132, 165, 111, 110, 11, 122, 91, 24, 25, 6, 3, 80, 2, 2, 3, 215, 220, 230, 215, 258, 112, 17, 37, - 12, 23, 233, 233, - ], - ApiCalls: 5, - UsagePerMonth: 50232435, //byte - }, - { - PeriodStartDate: '2021-04-01T00:00:00Z', - PeriodEndDate: '2021-05-01T00:00:00Z', - UsageValues: [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 91, 24, 25, 6, 3, 80, 2, 2, 3, 215, 220, 230, 215, 258, 112, 17, 37, 12, 23, 233, - 233, - ], - ApiCalls: 1, - UsagePerMonth: 12344544, //byte - }, - { - // ez egy tört hónap - PeriodStartDate: '2021-05-01T00:00:00Z', - PeriodEndDate: '2021-05-13T00:00:00Z', - UsageValues: [200, 201, 202, 203, 204, 205, 206, 207, 208, 291, 324, 325, 306], - ApiCalls: 3, - UsagePerMonth: 250085376, //byte - }, - ], +export type PeriodData = { + PeriodStartDate: string + PeriodEndDate: string +} + +const getUsageData1 = () => { + return { + DataType: 'SampleApiCall', + Start: '2021-06-01T00:00:00Z', + End: '2021-07-01T00:00:00', + TimeWindow: 'Month', + Resolution: 'Day', + CallCount: [ + 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, + 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, + ], + RequestLengths: [ + 360000, 360001, 360002, 360003, 360004, 360005, 360006, 360007, 360008, 360009, 360010, 360011, 360012, 360013, + 360014, 360015, 360016, 360017, 360018, 360019, 360020, 360021, 360022, 360023, 360024, 360025, 360026, 360027, + 360028, 360029, 360030, + ], + ResponseLengths: [ + 340000, 340001, 340002, 340003, 340004, 340005, 340006, 340007, 340008, 340009, 340010, 340011, 340012, 340013, + 340014, 340015, 340016, 340017, 340018, 340019, 340020, 340021, 340022, 340023, 340024, 340025, 340026, 340027, + 340028, 340029, 340030, + ], + Status100: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + Status200: [ + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + ], + Status300: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + Status400: [ + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 360, 360, + ], + Status500: [ + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 360, 360, + ], + } +} + +const getUsageData2 = () => { + return { + DataType: 'SampleApiCall', + Start: '2021-05-01T00:00:00Z', + End: '2021-06-01T00:00:00', + TimeWindow: 'Month', + Resolution: 'Day', + CallCount: [ + 2600, 2601, 1602, 2602, 2604, 2605, 2606, 2607, 2608, 2609, 1610, 2611, 2612, 2612, 2614, 2615, 2616, 2617, 2618, + 2619, 2620, 2621, 2622, 2622, 2624, 2625, 2626, 2627, 2628, 1629, 2620, 2620, + ], + RequestLengths: [ + 160000, 160001, 160002, 160001, 160004, 160005, 160006, 160007, 160008, 160009, 160010, 160011, 160012, 160011, + 160014, 160015, 160016, 160017, 160018, 160019, 160020, 160021, 160022, 160021, 160024, 160025, 160026, 160027, + 160028, 160029, 160010, 160010, + ], + ResponseLengths: [ + 240000, 240001, 240001, 240002, 240004, 240005, 240006, 240007, 240008, 240009, 240010, 240011, 240011, 240012, + 240014, 240015, 240016, 240017, 240018, 240019, 240010, 240011, 240011, 240012, 240014, 240015, 240016, 240017, + 240018, 240019, 240020, 240020, + ], + Status100: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + Status200: [ + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + ], + Status300: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + Status400: [ + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 360, 360, 360, + ], + Status500: [ + 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 360, 360, 360, 360, 360, 360, 360, + ], + } } const useWidgetStyles = makeStyles(widgetStyles) @@ -80,20 +108,37 @@ const useStyles = makeStyles(() => { }, }) }) -export const UsageWidget: React.FunctionComponent = () => { + +export interface UsageWidgetProps { + periodData: PeriodData[] +} + +export const UsageWidget: React.FunctionComponent = (props) => { const classes = useStyles() const widgetClasses = useWidgetStyles() const localization = useLocalization().settings const dateUtils = useDateUtils() - const [currentData, setCurrentData] = useState( - exampleStatsUsageData.UsageData[exampleStatsUsageData.UsageData.length - 1], - ) + const [currentPeriod, setCurrentPeriod] = useState(props.periodData[props.periodData.length - 1]) + const [currentData, setCurrentData] = useState(getUsageData1()) + + const dataTraffic = currentData.RequestLengths.map((request, index) => request + currentData.ResponseLengths[index]) + + useEffect(() => { + if ( + currentPeriod.PeriodStartDate === '2021-01-01T00:00:00Z' || + currentPeriod.PeriodStartDate === '2021-03-01T00:00:00Z' + ) { + setCurrentData(getUsageData1()) + } else { + setCurrentData(getUsageData2()) + } + }, [currentPeriod]) return (
- {localization.usage} + {localization.traffic}
@@ -105,24 +150,25 @@ export const UsageWidget: React.FunctionComponent = () => { lineOptions={{ hideDots: 1 }} barOptions={{ spaceRatio: 10 }} data={{ - labels: Array(currentData.UsageValues.length).fill(''), - datasets: [{ values: currentData.UsageValues }], + labels: Array(dataTraffic.length) + .fill('') + .map((_item, index) => (index % 5 ? '' : index.toString())), + datasets: [{ values: dataTraffic }], }} />
-
{localization.usageOfThisRepo}
-
{formatSize(currentData.UsagePerMonth)}
+
{localization.dataTraffic}
+
{formatSize(dataTraffic.reduce((a, b) => a + b, 0))}
{localization.apiCalls}
-
{currentData.ApiCalls}
+
{currentData.CallCount.reduce((a, b) => a + b, 0)}
diff --git a/apps/sensenet/src/components/settings/stats.tsx b/apps/sensenet/src/components/settings/stats.tsx index c13e96f58..9b3c85b2a 100644 --- a/apps/sensenet/src/components/settings/stats.tsx +++ b/apps/sensenet/src/components/settings/stats.tsx @@ -11,6 +11,27 @@ import { InstalledPackagesWidget } from './stats-installed-packages-widget' import { StorageWidget } from './stats-storage-widget' import { UsageWidget } from './stats-usage-widget' +const getPeriods = () => { + return [ + { + PeriodStartDate: '2021-01-01T00:00:00Z', + PeriodEndDate: '2021-02-01T00:00:00Z', + }, + { + PeriodStartDate: '2021-02-01T00:00:00Z', + PeriodEndDate: '2021-03-01T00:00:00Z', + }, + { + PeriodStartDate: '2021-03-01T00:00:00Z', + PeriodEndDate: '2021-04-01T00:00:00Z', + }, + { + PeriodStartDate: '2021-04-01T00:00:00Z', + PeriodEndDate: '2021-05-01T00:00:00Z', + }, + ] +} + export const Stats: React.FunctionComponent = () => { const globalClasses = useGlobalStyles() const localization = useLocalization() @@ -54,7 +75,7 @@ export const Stats: React.FunctionComponent = () => {
- + diff --git a/apps/sensenet/src/localization/default.ts b/apps/sensenet/src/localization/default.ts index 767d84bfc..45ce1384a 100644 --- a/apps/sensenet/src/localization/default.ts +++ b/apps/sensenet/src/localization/default.ts @@ -462,8 +462,9 @@ const values = { installedPackagesInfo: 'These packages are mainly the building bricks of sensenet components. There are tool-like packages that are not part of the component structure, they were made to run multiple times, for example delete or index content.', notAvailable: 'Not available', - usageOfThisRepo: 'Usage of this repository', - apiCalls: 'API calls', + traffic: 'Traffic', + dataTraffic: 'Data traffic (request and response)', + apiCalls: 'Number of requests (API calls)', }, customActions: { executeCustomActionDialog: { diff --git a/apps/sensenet/src/localization/hungarian.ts b/apps/sensenet/src/localization/hungarian.ts index ea8f54692..8d6f97be5 100644 --- a/apps/sensenet/src/localization/hungarian.ts +++ b/apps/sensenet/src/localization/hungarian.ts @@ -200,8 +200,9 @@ const values: DeepPartial = { installedPackagesInfo: 'Csomagok, melyekből a sensenet komponensek felépülnek. Léteznek olyan csomagok is, melyek nem felelősek a komponensekért, többszöri futtatásra lettek létrehozva - ilyenek a tool-típusú csomagok. Ezek például kontent törlésre vagy indexelésre használatosak.', notAvailable: 'Nem elérhető', - usageOfThisRepo: 'A tárhely státusza', - apiCalls: 'API hívások', + traffic: 'Adatforgalom', + dataTraffic: 'Adatforgalom (kérések és válaszok)', + apiCalls: 'Kérések száma (API hívások)', }, forms: { referencePicker: 'Referencia választó', From 661e18d841c32ea850b99460fd5393b8cfa61ac6 Mon Sep 17 00:00:00 2001 From: pusztaie Date: Thu, 17 Jun 2021 10:54:29 +0200 Subject: [PATCH 4/5] fix the logic of period dropdown --- .../settings/stats-usage-widget.tsx | 41 ++++++------ .../src/components/settings/stats.tsx | 63 +++++++++++++------ apps/sensenet/src/hooks/use-date-utils.ts | 4 +- 3 files changed, 65 insertions(+), 43 deletions(-) diff --git a/apps/sensenet/src/components/settings/stats-usage-widget.tsx b/apps/sensenet/src/components/settings/stats-usage-widget.tsx index 3a2d25a00..cbe1f78f8 100644 --- a/apps/sensenet/src/components/settings/stats-usage-widget.tsx +++ b/apps/sensenet/src/components/settings/stats-usage-widget.tsx @@ -1,5 +1,6 @@ import { formatSize } from '@sensenet/controls-react' import { createStyles, ListItemText, makeStyles, MenuItem, Paper, Select } from '@material-ui/core' +import { isSameDay } from 'date-fns' import React, { useEffect, useState } from 'react' import ReactFrappeChart from 'react-frappe-charts' import { widgetStyles } from '../../globalStyles' @@ -7,8 +8,8 @@ import { useLocalization } from '../../hooks' import { useDateUtils } from '../../hooks/use-date-utils' export type PeriodData = { - PeriodStartDate: string - PeriodEndDate: string + PeriodStartDate: Date + PeriodEndDate: Date } const getUsageData1 = () => { @@ -23,14 +24,14 @@ const getUsageData1 = () => { 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, ], RequestLengths: [ - 360000, 360001, 360002, 360003, 360004, 360005, 360006, 360007, 360008, 360009, 360010, 360011, 360012, 360013, - 360014, 360015, 360016, 360017, 360018, 360019, 360020, 360021, 360022, 360023, 360024, 360025, 360026, 360027, - 360028, 360029, 360030, + 310000, 360001, 360002, 360003, 300004, 360005, 360006, 360007, 310008, 360009, 360010, 360011, 360012, 360013, + 310014, 360015, 360016, 360017, 300018, 360019, 360020, 360021, 310022, 360023, 360024, 360025, 360026, 360027, + 310028, 360029, 360030, ], ResponseLengths: [ - 340000, 340001, 340002, 340003, 340004, 340005, 340006, 340007, 340008, 340009, 340010, 340011, 340012, 340013, - 340014, 340015, 340016, 340017, 340018, 340019, 340020, 340021, 340022, 340023, 340024, 340025, 340026, 340027, - 340028, 340029, 340030, + 340000, 300001, 340002, 340003, 310004, 340005, 340006, 340007, 340008, 340009, 340010, 340011, 340012, 340013, + 340014, 300015, 340016, 340017, 310018, 340019, 340020, 340021, 340022, 340023, 340024, 340025, 340026, 340027, + 340028, 300029, 340030, ], Status100: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], Status200: [ @@ -61,14 +62,14 @@ const getUsageData2 = () => { 2619, 2620, 2621, 2622, 2622, 2624, 2625, 2626, 2627, 2628, 1629, 2620, 2620, ], RequestLengths: [ - 160000, 160001, 160002, 160001, 160004, 160005, 160006, 160007, 160008, 160009, 160010, 160011, 160012, 160011, - 160014, 160015, 160016, 160017, 160018, 160019, 160020, 160021, 160022, 160021, 160024, 160025, 160026, 160027, - 160028, 160029, 160010, 160010, + 150000, 160001, 140002, 160001, 130004, 160005, 160006, 110007, 160008, 160009, 160010, 160011, 160012, 160011, + 150014, 160015, 140016, 160017, 130018, 160019, 160020, 110021, 160022, 160021, 160024, 160025, 160026, 160027, + 150028, 160029, 140010, 160010, ], ResponseLengths: [ - 240000, 240001, 240001, 240002, 240004, 240005, 240006, 240007, 240008, 240009, 240010, 240011, 240011, 240012, - 240014, 240015, 240016, 240017, 240018, 240019, 240010, 240011, 240011, 240012, 240014, 240015, 240016, 240017, - 240018, 240019, 240020, 240020, + 230000, 240001, 240001, 240002, 220004, 240005, 240006, 240007, 200008, 240009, 240010, 240011, 240011, 240012, + 230014, 240015, 240016, 240017, 220018, 240019, 240010, 240011, 200011, 240012, 240014, 240015, 240016, 240017, + 230018, 240019, 240020, 240020, ], Status100: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], Status200: [ @@ -125,8 +126,8 @@ export const UsageWidget: React.FunctionComponent = (props) => useEffect(() => { if ( - currentPeriod.PeriodStartDate === '2021-01-01T00:00:00Z' || - currentPeriod.PeriodStartDate === '2021-03-01T00:00:00Z' + isSameDay(currentPeriod.PeriodStartDate, new Date('2021-01-01T00:00:00Z')) || + isSameDay(currentPeriod.PeriodStartDate, new Date('2021-03-01T00:00:00Z')) ) { setCurrentData(getUsageData1()) } else { @@ -162,16 +163,16 @@ export const UsageWidget: React.FunctionComponent = (props) => value={currentPeriod.PeriodStartDate} onChange={(event) => { setCurrentPeriod( - props.periodData.find((usageItem) => event.target.value === usageItem.PeriodStartDate) || + props.periodData.find((usageItem) => event.target.value === usageItem.PeriodStartDate.toString()) || props.periodData[props.periodData.length - 1], ) }}> {props.periodData.map((item, index) => { return ( - + - {dateUtils.formatDate(dateUtils.parseDate(item.PeriodStartDate as any), 'LLL dd yyyy')} -{' '} - {dateUtils.formatDate(dateUtils.parseDate(item.PeriodEndDate as any), 'LLL dd yyyy')} + {dateUtils.formatDate(item.PeriodStartDate, 'LLL dd yyyy')} -{' '} + {dateUtils.formatDate(item.PeriodEndDate, 'LLL dd yyyy')} ) diff --git a/apps/sensenet/src/components/settings/stats.tsx b/apps/sensenet/src/components/settings/stats.tsx index 9b3c85b2a..51dfe475e 100644 --- a/apps/sensenet/src/components/settings/stats.tsx +++ b/apps/sensenet/src/components/settings/stats.tsx @@ -1,6 +1,7 @@ import { useRepository, VersionInfo } from '@sensenet/hooks-react' import { Container } from '@material-ui/core' import clsx from 'clsx' +import { addMonths, isSameDay, parseISO } from 'date-fns' import React, { useEffect, useState } from 'react' import { useGlobalStyles } from '../../globalStyles' import { useLocalization } from '../../hooks' @@ -11,25 +12,47 @@ import { InstalledPackagesWidget } from './stats-installed-packages-widget' import { StorageWidget } from './stats-storage-widget' import { UsageWidget } from './stats-usage-widget' -const getPeriods = () => { - return [ - { - PeriodStartDate: '2021-01-01T00:00:00Z', - PeriodEndDate: '2021-02-01T00:00:00Z', - }, - { - PeriodStartDate: '2021-02-01T00:00:00Z', - PeriodEndDate: '2021-03-01T00:00:00Z', - }, - { - PeriodStartDate: '2021-03-01T00:00:00Z', - PeriodEndDate: '2021-04-01T00:00:00Z', - }, - { - PeriodStartDate: '2021-04-01T00:00:00Z', - PeriodEndDate: '2021-05-01T00:00:00Z', - }, - ] +export type RawPeriodData = { + Window: 'Hour' | 'Day' | 'Month' | 'Year' + Resolution: 'Minute' | 'Hour' | 'Day' | 'Month' + First: string + Last: string + Count: number +} + +const makePeriodArrayFromRawData = () => { + const periodArray = [] + const rawData = getPeriodFromBackend() + + let currentDate = parseISO(rawData.First) + const lastDate = parseISO(rawData.Last) + + while (!isSameDay(currentDate, lastDate)) { + const endDate = addMonths(currentDate, 1) + periodArray.push({ + PeriodStartDate: currentDate, + PeriodEndDate: endDate, + }) + currentDate = endDate + } + if (periodArray.length < rawData.Count) { + periodArray.push({ + PeriodStartDate: lastDate, + PeriodEndDate: new Date(Date.now()), + }) + } + + return periodArray +} + +const getPeriodFromBackend = () => { + return { + Window: 'Month', + Resolution: 'Day', + First: '2021-01-01T00:00:00Z', + Last: '2021-05-01T00:00:00Z', + Count: 4, + } } export const Stats: React.FunctionComponent = () => { @@ -75,7 +98,7 @@ export const Stats: React.FunctionComponent = () => { - + diff --git a/apps/sensenet/src/hooks/use-date-utils.ts b/apps/sensenet/src/hooks/use-date-utils.ts index d3321c872..d530805a9 100644 --- a/apps/sensenet/src/hooks/use-date-utils.ts +++ b/apps/sensenet/src/hooks/use-date-utils.ts @@ -1,6 +1,4 @@ -import format from 'date-fns/format' -import formatDistanceToNow from 'date-fns/formatDistanceToNow' -import parseISO from 'date-fns/parseISO' +import { format, formatDistanceToNow, parseISO } from 'date-fns' import { useCallback } from 'react' import { LocalizationObject } from '../context' import { usePersonalSettings } from '.' From 3e15a482f3945b601a507869d70339dd0a239940 Mon Sep 17 00:00:00 2001 From: pusztaie Date: Thu, 8 Jul 2021 17:03:51 +0200 Subject: [PATCH 5/5] call api instead of example data --- .../settings/stats-usage-widget.tsx | 118 +++++------------- .../src/components/settings/stats.tsx | 46 ++++--- 2 files changed, 57 insertions(+), 107 deletions(-) diff --git a/apps/sensenet/src/components/settings/stats-usage-widget.tsx b/apps/sensenet/src/components/settings/stats-usage-widget.tsx index cbe1f78f8..71d4b365e 100644 --- a/apps/sensenet/src/components/settings/stats-usage-widget.tsx +++ b/apps/sensenet/src/components/settings/stats-usage-widget.tsx @@ -1,91 +1,27 @@ import { formatSize } from '@sensenet/controls-react' +import { useRepository } from '@sensenet/hooks-react' import { createStyles, ListItemText, makeStyles, MenuItem, Paper, Select } from '@material-ui/core' -import { isSameDay } from 'date-fns' import React, { useEffect, useState } from 'react' import ReactFrappeChart from 'react-frappe-charts' import { widgetStyles } from '../../globalStyles' import { useLocalization } from '../../hooks' import { useDateUtils } from '../../hooks/use-date-utils' +import { FullScreenLoader } from '../full-screen-loader' export type PeriodData = { PeriodStartDate: Date PeriodEndDate: Date } -const getUsageData1 = () => { - return { - DataType: 'SampleApiCall', - Start: '2021-06-01T00:00:00Z', - End: '2021-07-01T00:00:00', - TimeWindow: 'Month', - Resolution: 'Day', - CallCount: [ - 3600, 3601, 3602, 3603, 3604, 3605, 3606, 3607, 3608, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, - 3619, 3620, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3628, 3629, 3630, - ], - RequestLengths: [ - 310000, 360001, 360002, 360003, 300004, 360005, 360006, 360007, 310008, 360009, 360010, 360011, 360012, 360013, - 310014, 360015, 360016, 360017, 300018, 360019, 360020, 360021, 310022, 360023, 360024, 360025, 360026, 360027, - 310028, 360029, 360030, - ], - ResponseLengths: [ - 340000, 300001, 340002, 340003, 310004, 340005, 340006, 340007, 340008, 340009, 340010, 340011, 340012, 340013, - 340014, 300015, 340016, 340017, 310018, 340019, 340020, 340021, 340022, 340023, 340024, 340025, 340026, 340027, - 340028, 300029, 340030, - ], - Status100: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - Status200: [ - 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, - 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, - ], - Status300: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - Status400: [ - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, - ], - Status500: [ - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, - ], - } -} - -const getUsageData2 = () => { - return { - DataType: 'SampleApiCall', - Start: '2021-05-01T00:00:00Z', - End: '2021-06-01T00:00:00', - TimeWindow: 'Month', - Resolution: 'Day', - CallCount: [ - 2600, 2601, 1602, 2602, 2604, 2605, 2606, 2607, 2608, 2609, 1610, 2611, 2612, 2612, 2614, 2615, 2616, 2617, 2618, - 2619, 2620, 2621, 2622, 2622, 2624, 2625, 2626, 2627, 2628, 1629, 2620, 2620, - ], - RequestLengths: [ - 150000, 160001, 140002, 160001, 130004, 160005, 160006, 110007, 160008, 160009, 160010, 160011, 160012, 160011, - 150014, 160015, 140016, 160017, 130018, 160019, 160020, 110021, 160022, 160021, 160024, 160025, 160026, 160027, - 150028, 160029, 140010, 160010, - ], - ResponseLengths: [ - 230000, 240001, 240001, 240002, 220004, 240005, 240006, 240007, 200008, 240009, 240010, 240011, 240011, 240012, - 230014, 240015, 240016, 240017, 220018, 240019, 240010, 240011, 200011, 240012, 240014, 240015, 240016, 240017, - 230018, 240019, 240020, 240020, - ], - Status100: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - Status200: [ - 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, - 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, - ], - Status300: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - Status400: [ - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, - ], - Status500: [ - 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, - 360, 360, 360, 360, 360, 360, 360, 360, - ], - } +export type ApiPeriod = { + DataType: String + Start: String + End: String + TimeWindow: 'Hour' | 'Day' | 'Month' | 'Year' + Resolution: 'Minute' | 'Hour' | 'Day' | 'Month' + CallCount: number[] + RequestLengths: number[] + ResponseLengths: number[] } const useWidgetStyles = makeStyles(widgetStyles) @@ -119,21 +55,29 @@ export const UsageWidget: React.FunctionComponent = (props) => const widgetClasses = useWidgetStyles() const localization = useLocalization().settings const dateUtils = useDateUtils() + const repository = useRepository() const [currentPeriod, setCurrentPeriod] = useState(props.periodData[props.periodData.length - 1]) - const [currentData, setCurrentData] = useState(getUsageData1()) + const [currentData, setCurrentData] = useState() - const dataTraffic = currentData.RequestLengths.map((request, index) => request + currentData.ResponseLengths[index]) + const dataTraffic = currentData?.RequestLengths.map((request, index) => request + currentData.ResponseLengths[index]) useEffect(() => { - if ( - isSameDay(currentPeriod.PeriodStartDate, new Date('2021-01-01T00:00:00Z')) || - isSameDay(currentPeriod.PeriodStartDate, new Date('2021-03-01T00:00:00Z')) - ) { - setCurrentData(getUsageData1()) - } else { - setCurrentData(getUsageData2()) - } - }, [currentPeriod]) + ;(async () => { + const response = await repository.executeAction({ + idOrPath: '/Root', + name: 'GetApiUsagePeriod', + method: 'POST', + body: { + timeWindow: 'Month', + }, + }) + + setCurrentData(response) + })() + }, [repository]) + + if (!dataTraffic) return + if (!currentPeriod) return null return (
@@ -181,7 +125,7 @@ export const UsageWidget: React.FunctionComponent = (props) =>
{localization.dataTraffic}
{formatSize(dataTraffic.reduce((a, b) => a + b, 0))}
{localization.apiCalls}
-
{currentData.CallCount.reduce((a, b) => a + b, 0)}
+
{currentData?.CallCount.reduce((a, b) => a + b, 0)}
diff --git a/apps/sensenet/src/components/settings/stats.tsx b/apps/sensenet/src/components/settings/stats.tsx index 51dfe475e..b269ee32f 100644 --- a/apps/sensenet/src/components/settings/stats.tsx +++ b/apps/sensenet/src/components/settings/stats.tsx @@ -12,17 +12,9 @@ import { InstalledPackagesWidget } from './stats-installed-packages-widget' import { StorageWidget } from './stats-storage-widget' import { UsageWidget } from './stats-usage-widget' -export type RawPeriodData = { - Window: 'Hour' | 'Day' | 'Month' | 'Year' - Resolution: 'Minute' | 'Hour' | 'Day' | 'Month' - First: string - Last: string - Count: number -} - -const makePeriodArrayFromRawData = () => { +const makePeriodArrayFromRawData = (periodData: RawPeriodData) => { const periodArray = [] - const rawData = getPeriodFromBackend() + const rawData = periodData let currentDate = parseISO(rawData.First) const lastDate = parseISO(rawData.Last) @@ -45,14 +37,12 @@ const makePeriodArrayFromRawData = () => { return periodArray } -const getPeriodFromBackend = () => { - return { - Window: 'Month', - Resolution: 'Day', - First: '2021-01-01T00:00:00Z', - Last: '2021-05-01T00:00:00Z', - Count: 4, - } +export type RawPeriodData = { + Window: 'Hour' | 'Day' | 'Month' | 'Year' + Resolution: 'Minute' | 'Hour' | 'Day' | 'Month' + First: string + Last: string + Count: number } export const Stats: React.FunctionComponent = () => { @@ -61,6 +51,22 @@ export const Stats: React.FunctionComponent = () => { const repository = useRepository() const [versionInfo, setVersionInfo] = useState() const [dashboardData, setDashboardData] = useState() + const [periodData, setPeriodData] = useState() + + useEffect(() => { + ;(async () => { + const response = await repository.executeAction({ + idOrPath: '/Root', + name: 'GetApiUsagePeriods', + method: 'POST', + body: { + timeWindow: 'Month', + }, + }) + + setPeriodData(response) + })() + }, [repository]) useEffect(() => { ;(async () => { @@ -89,7 +95,7 @@ export const Stats: React.FunctionComponent = () => { })() }, [repository]) - if (!versionInfo || !dashboardData) return + if (!versionInfo || !dashboardData || !periodData) return return (
@@ -98,7 +104,7 @@ export const Stats: React.FunctionComponent = () => {
- +