Skip to content

Commit

Permalink
Merge pull request #7086 from TheThingsNetwork/feature/network-activi…
Browse files Browse the repository at this point in the history
…ty-panel

Blurry network activity panel
  • Loading branch information
PavelJankoski authored May 17, 2024
2 parents da4c443 + 2523b33 commit 4910962
Show file tree
Hide file tree
Showing 19 changed files with 434 additions and 17 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"@sentry/integrations": "^7.111.0",
"@tabler/icons-react": "^3.0.2",
"@tippyjs/react": "^4.2.6",
"apexcharts": "^3.48.0",
"autobind-decorator": "^2.4.0",
"axios": "^1.5.1",
"brace": "^0.11.1",
Expand All @@ -110,6 +111,7 @@
"query-string": "^9.0.0",
"react": "^17.0.1",
"react-ace": "^6.6.0",
"react-apexcharts": "^1.4.1",
"react-display-name": "^0.2.5",
"react-dom": "^17.0.1",
"react-focus-lock": "^2.12.1",
Expand Down
Binary file added pkg/webui/assets/misc/blurry-heatmap-big.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pkg/webui/assets/misc/blurry-heatmap-small.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 8 additions & 2 deletions pkg/webui/components/button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,14 @@ const assembleClassnames = ({
})

const buttonChildren = props => {
const { dropdownItems, icon, busy, message, noDropdownIcon, children } = props
const { dropdownItems, icon, busy, message, messageValues, noDropdownIcon, children } = props

const content = (
<>
{icon && <Icon className={style.icon} icon={icon} />}
{message && <Message content={message} className={style.linkButtonMessage} />}
{message && (
<Message content={message} values={messageValues} className={style.linkButtonMessage} />
)}
{children}
{dropdownItems && (
<>
Expand Down Expand Up @@ -225,6 +227,8 @@ const AnchorLinkButton = props => {
const commonPropTypes = {
/** The message to be displayed within the button. */
message: PropTypes.message,
/** The message values. */
messageValues: PropTypes.object,
/**
* A flag specifying whether the `danger` styling should applied to the
* button.
Expand Down Expand Up @@ -287,12 +291,14 @@ buttonChildren.propTypes = {
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
icon: commonPropTypes.icon,
message: commonPropTypes.message,
messageValues: commonPropTypes.messageValues,
}

buttonChildren.defaultProps = {
busy: undefined,
icon: undefined,
message: undefined,
messageValues: undefined,
children: null,
small: false,
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/webui/components/link/link.styl
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
&.primary
color: var(--c-text-brand-normal)

&:active,
&:hover
&:active:not(.disabled),
&:hover:not(.disabled)
color: var(--c-text-brand-normal-hover)
text-decoration: underline

Expand All @@ -32,8 +32,8 @@

&.secondary
color: var(--c-text-neutral-light)
&:active,
&:hover
&:active:not(.disabled),
&:hover:not(.disabled)
color: var(--c-text-neutral-heavy)

&.link-visited
Expand Down
15 changes: 13 additions & 2 deletions pkg/webui/components/panel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import Toggle from './toggle'
import styles from './panel.styl'

const PanelError = ({ className, children }) => (
<div className={classnames(className, 'd-flex', 'j-center')}>{children}</div>
<div className={classnames(className, 'd-flex', 'j-center', 'h-full', 'al-center')}>
{children}
</div>
)

PanelError.propTypes = {
Expand All @@ -52,6 +54,7 @@ const Panel = ({
messageDecorators,
divider,
shortCutLinkTarget,
shortCutLinkDisabled,
}) => (
<div className={classnames(styles.panel, className)}>
<div className="d-flex j-between al-center mb-cs-m gap-cs-m">
Expand All @@ -64,7 +67,13 @@ const Panel = ({
<Toggle options={toggleOptions} active={activeToggle} onToggleChange={onToggleClick} />
) : (
shortCutLinkTitle && (
<Link primary to={shortCutLinkPath} className={styles.button} target={shortCutLinkTarget}>
<Link
primary
to={shortCutLinkPath}
className={styles.button}
target={shortCutLinkTarget}
disabled={shortCutLinkDisabled}
>
<Message content={shortCutLinkTitle} />
</Link>
)
Expand All @@ -83,6 +92,7 @@ Panel.propTypes = {
icon: PropTypes.icon,
messageDecorators: PropTypes.node,
onToggleClick: PropTypes.func,
shortCutLinkDisabled: PropTypes.bool,
shortCutLinkPath: PropTypes.string,
shortCutLinkTarget: PropTypes.string,
shortCutLinkTitle: PropTypes.message,
Expand All @@ -98,6 +108,7 @@ Panel.defaultProps = {
className: undefined,
messageDecorators: undefined,
divider: false,
shortCutLinkDisabled: undefined,
shortCutLinkPath: undefined,
shortCutLinkTitle: undefined,
shortCutLinkTarget: undefined,
Expand Down
2 changes: 1 addition & 1 deletion pkg/webui/components/panel/panel.styl
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
text-decoration: none transparent
transition: text-decoration $ad.s ease-in-out

&:hover
&:hover:not(:disabled)
color: var(--c-text-brand-normal)
text-decoration: underline
text-decoration-thickness: 2px
Expand Down
6 changes: 1 addition & 5 deletions pkg/webui/components/panel/toggle/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,7 @@ import PropTypes from '@ttn-lw/lib/prop-types'
import styles from './toggle.styl'

const Toggle = ({ className, options, onToggleChange, active, fullWidth }) => (
<div
className={classnames(styles.toggle, className, {
'w-full': fullWidth,
})}
>
<div className={classnames(styles.toggle, className)}>
{options.map(({ label, value }) => {
const buttonClassName = classnames(styles.toggleButton, {
[styles.toggleButtonActive]: value === active,
Expand Down
3 changes: 0 additions & 3 deletions pkg/webui/components/panel/toggle/toggle.styl
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,5 @@
background: var(--c-bg-neutral-min-hover)

@container panel (max-width: 485px)
.toggle
width: 100%

.toggle-button
width: 100%
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright © 2024 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

.panel
height: 100%
display: flex
flex-direction: column
position: relative

.content
position: relative
height: 100%
min-height: 15rem
margin-top: $cs.xl

.upseller
height: 100%
background-image: url('../../../assets/misc/blurry-heatmap-big.png')
background-repeat: no-repeat
background-size: 100% 100%
transition: background-image $ad.m
display: flex
flex-direction: column
justify-content: center
align-items: center
&.small
background-image: url('../../../assets/misc/blurry-heatmap-small.png')

.chart-date
color: var(--c-text-neutral-light)
font-size: $fs.s

Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright © 2024 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import React, { useCallback, useState } from 'react'
import classnames from 'classnames'

import { IconChartBar, IconBolt } from '@ttn-lw/components/icon'
import Panel from '@ttn-lw/components/panel'
import Toggle from '@ttn-lw/components/panel/toggle'
import Button from '@ttn-lw/components/button'

import Message from '@ttn-lw/lib/components/message'

import sharedMessages from '@ttn-lw/lib/shared-messages'

import style from './blurry-network-activity-panel.styl'

const toggleOptions = [
{ label: sharedMessages.packetsPerDataRate, value: 0 },
{ label: sharedMessages.packetsPerChannel, value: 1 },
]

const BlurryNetworkActivityPanel = () => {
const [activeToggle, setActiveToggle] = useState(0)

const handleToggleChange = useCallback((_, value) => {
setActiveToggle(value)
}, [])

return (
<Panel
title={sharedMessages.networkActivity}
icon={IconChartBar}
shortCutLinkTitle={sharedMessages.noc}
shortCutLinkPath="#"
shortCutLinkTarget="_blank"
shortCutLinkDisabled
className={style.panel}
>
<Toggle
options={toggleOptions}
active={activeToggle}
onToggleChange={handleToggleChange}
fullWidth
/>
<div className={style.content}>
<div
className={classnames(style.upseller, {
[style.small]: activeToggle === 0,
})}
>
<Message
className="c-text-neutral-heavy fw-bold fs-l text-center"
content={sharedMessages.unlockTheNoc}
/>
<Message
className="c-text-neutral-light fs-m text-center mb-cs-l"
content={sharedMessages.quicklyTroubleshoot}
/>
<Button.AnchorLink
primary
message={sharedMessages.upgradeNow}
icon={IconBolt}
href="https://www.thethingsindustries.com/stack/plans/"
target="_blank"
/>
</div>
</div>
</Panel>
)
}

export default BlurryNetworkActivityPanel
88 changes: 88 additions & 0 deletions pkg/webui/console/components/heatmap-chart/chart-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright © 2024 The Things Network Foundation, The Things Industries B.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

const options = {
chart: {
type: 'heatmap',
toolbar: {
show: false,
},
animations: {
enabled: false,
},
zoom: {
enabled: false,
},
events: {
mounted: chart => {
chart.windowResizeHandler()
},
},
},
dataLabels: {
enabled: false,
},
colors: ['#152F66'],
grid: {
show: false,
strokeDashArray: 0,
padding: {
left: 0,
right: 0,
bottom: -13,
top: -30,
},
},
yaxis: {
labels: {
align: 'left',
offsetX: 10,
},
},
xaxis: {
labels: {
show: false,
},
axisBorder: {
show: false,
},
tooltip: {
enabled: false,
},
},
tooltip: {
x: {
show: false,
},
marker: {
show: false,
},
custom: ({ series, seriesIndex, dataPointIndex, w }) => {
const val = series[seriesIndex][dataPointIndex]
const date = new Date(w.globals.seriesX[seriesIndex][dataPointIndex])
const formattedDate = date.toLocaleDateString('en-US', {
month: '2-digit',
day: '2-digit',
})
const formattedTime = date.toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit',
hour12: false,
})
return `<div class="pl-cs-s pr-cs-s pt-cs-xs pb-cs-xs"><strong>${formattedDate} ${formattedTime}</strong>: ${val}</div>`
},
},
}

export default options
Loading

0 comments on commit 4910962

Please sign in to comment.