From 0fcc4ee955aabe55588536866356cff2961352fc Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Fri, 4 Aug 2017 16:49:42 +0200 Subject: [PATCH 01/12] Update Widget props. Rename "error" to "hasError" and "loading" to "isLoading" --- components/widget.js | 6 +++--- .../widgets/bitbucket/pull-request-count.js | 16 ++++++++-------- components/widgets/elasticsearch/hit-count.js | 17 ++++++++--------- components/widgets/github/issue-count.js | 16 ++++++++-------- components/widgets/jenkins/index.js | 16 ++++++++-------- components/widgets/jira/issue-count.js | 16 ++++++++-------- .../widgets/jira/sprint-days-remaining.js | 16 ++++++++-------- components/widgets/pagespeed-insights/score.js | 16 ++++++++-------- components/widgets/pagespeed-insights/stats.js | 16 ++++++++-------- components/widgets/sonarqube/index.js | 16 ++++++++-------- 10 files changed, 75 insertions(+), 76 deletions(-) diff --git a/components/widget.js b/components/widget.js index 0f23cef7..db3d8d52 100644 --- a/components/widget.js +++ b/components/widget.js @@ -19,12 +19,12 @@ const Title = styled.h1` text-align: center; ` -export default ({ children, error = false, loading = false, title = '' }) => { +export default ({ children, hasError = false, isLoading = false, title = '' }) => { let content - if (loading) { + if (isLoading) { content = - } else if (error) { + } else if (hasError) { content = } else { content =
{children}
diff --git a/components/widgets/bitbucket/pull-request-count.js b/components/widgets/bitbucket/pull-request-count.js index d38bb5f9..70a60fe2 100644 --- a/components/widgets/bitbucket/pull-request-count.js +++ b/components/widgets/bitbucket/pull-request-count.js @@ -24,8 +24,8 @@ export default class BitbucketPullRequestCount extends Component { state = { count: 0, - error: false, - loading: true + hasError: false, + isLoading: true } componentDidMount () { @@ -33,7 +33,7 @@ export default class BitbucketPullRequestCount extends Component { .then(() => this.fetchInformation()) .catch((err) => { console.error(`${err.name} @ ${this.constructor.name}`, err.errors) - this.setState({ error: true, loading: false }) + this.setState({ hasError: true, isLoading: false }) }) } @@ -56,19 +56,19 @@ export default class BitbucketPullRequestCount extends Component { count = json.size } - this.setState({ count, error: false, loading: false }) - } catch (error) { - this.setState({ error: true, loading: false }) + this.setState({ count, hasError: false, isLoading: false }) + } catch (err) { + this.setState({ hasError: true, isLoading: false }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { count, error, loading } = this.state + const { count, hasError, isLoading } = this.state const { title } = this.props return ( - + ) diff --git a/components/widgets/elasticsearch/hit-count.js b/components/widgets/elasticsearch/hit-count.js index 72017486..c5dae8d6 100644 --- a/components/widgets/elasticsearch/hit-count.js +++ b/components/widgets/elasticsearch/hit-count.js @@ -21,8 +21,8 @@ export default class ElasticsearchHitCount extends Component { state = { count: 0, - error: false, - loading: true + hasError: false, + isLoading: true } componentDidMount () { @@ -30,7 +30,7 @@ export default class ElasticsearchHitCount extends Component { .then(() => this.fetchInformation()) .catch((err) => { console.error(`${err.name} @ ${this.constructor.name}`, err.errors) - this.setState({ error: true, loading: false }) + this.setState({ hasError: true, isLoading: false }) }) } @@ -46,20 +46,19 @@ export default class ElasticsearchHitCount extends Component { const res = await fetch(`${url}/${index}/_search?q=${query}`, opts) const json = await res.json() - this.setState({ count: json.hits.total, error: false, loading: false }) - } catch (error) { - this.setState({ error: true, loading: false }) - console.log(error) + this.setState({ count: json.hits.total, hasError: false, isLoading: false }) + } catch (err) { + this.setState({ hasError: true, isLoading: false }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { count, error, loading } = this.state + const { count, hasError, isLoading } = this.state const { title } = this.props return ( - + ) diff --git a/components/widgets/github/issue-count.js b/components/widgets/github/issue-count.js index 98dc79be..a7480ade 100644 --- a/components/widgets/github/issue-count.js +++ b/components/widgets/github/issue-count.js @@ -21,8 +21,8 @@ export default class GitHubIssueCount extends Component { state = { count: 0, - error: false, - loading: true + hasError: false, + isLoading: true } componentDidMount () { @@ -30,7 +30,7 @@ export default class GitHubIssueCount extends Component { .then(() => this.fetchInformation()) .catch((err) => { console.error(`${err.name} @ ${this.constructor.name}`, err.errors) - this.setState({ error: true, loading: false }) + this.setState({ hasError: true, isLoading: false }) }) } @@ -46,19 +46,19 @@ export default class GitHubIssueCount extends Component { const res = await fetch(`https://api.github.com/repos/${owner}/${repository}`, opts) const json = await res.json() - this.setState({ count: json.open_issues_count, error: false, loading: false }) - } catch (error) { - this.setState({ error: true, loading: false }) + this.setState({ count: json.open_issues_count, hasError: false, isLoading: false }) + } catch (err) { + this.setState({ hasError: true, isLoading: false }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { count, error, loading } = this.state + const { count, hasError, isLoading } = this.state const { title } = this.props return ( - + ) diff --git a/components/widgets/jenkins/index.js b/components/widgets/jenkins/index.js index 2024c809..d154fd98 100644 --- a/components/widgets/jenkins/index.js +++ b/components/widgets/jenkins/index.js @@ -44,8 +44,8 @@ export default class Jenkins extends Component { } state = { - loading: true, - error: false + isLoading: true, + hasError: false } componentDidMount () { @@ -53,7 +53,7 @@ export default class Jenkins extends Component { .then(() => this.fetchInformation()) .catch((err) => { console.error(`${err.name} @ ${this.constructor.name}`, err.errors) - this.setState({ error: true, loading: false }) + this.setState({ hasError: true, isLoading: false }) }) } @@ -79,20 +79,20 @@ export default class Jenkins extends Component { }) ) - this.setState({ error: false, loading: false, builds }) - } catch (error) { - this.setState({ error: true, loading: false }) + this.setState({ hasError: false, isLoading: false, builds }) + } catch (err) { + this.setState({ hasError: true, isLoading: false }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { loading, error, builds } = this.state + const { isLoading, hasError, builds } = this.state const { title } = this.props return ( - + {builds && builds.map(build => ( diff --git a/components/widgets/jira/issue-count.js b/components/widgets/jira/issue-count.js index 42f192a6..a1456fe6 100644 --- a/components/widgets/jira/issue-count.js +++ b/components/widgets/jira/issue-count.js @@ -21,8 +21,8 @@ export default class JiraIssueCount extends Component { state = { count: 0, - error: false, - loading: true + hasError: false, + isLoading: true } componentDidMount () { @@ -30,7 +30,7 @@ export default class JiraIssueCount extends Component { .then(() => this.fetchInformation()) .catch((err) => { console.error(`${err.name} @ ${this.constructor.name}`, err.errors) - this.setState({ error: true, loading: false }) + this.setState({ hasError: true, isLoading: false }) }) } @@ -46,19 +46,19 @@ export default class JiraIssueCount extends Component { const res = await fetch(`${url}/rest/api/2/search?jql=${query}`, opts) const json = await res.json() - this.setState({ count: json.total, error: false, loading: false }) - } catch (error) { - this.setState({ error: true, loading: false }) + this.setState({ count: json.total, hasError: false, isLoading: false }) + } catch (err) { + this.setState({ hasError: true, isLoading: false }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { count, error, loading } = this.state + const { count, hasError, isLoading } = this.state const { title } = this.props return ( - + ) diff --git a/components/widgets/jira/sprint-days-remaining.js b/components/widgets/jira/sprint-days-remaining.js index ce6f45ac..429c495a 100644 --- a/components/widgets/jira/sprint-days-remaining.js +++ b/components/widgets/jira/sprint-days-remaining.js @@ -21,8 +21,8 @@ export default class JiraSprintDaysRemaining extends Component { state = { days: 0, - error: false, - loading: true + hasError: false, + isLoading: true } componentDidMount () { @@ -30,7 +30,7 @@ export default class JiraSprintDaysRemaining extends Component { .then(() => this.fetchInformation()) .catch((err) => { console.error(`${err.name} @ ${this.constructor.name}`, err.errors) - this.setState({ error: true, loading: false }) + this.setState({ hasError: true, isLoading: false }) }) } @@ -56,19 +56,19 @@ export default class JiraSprintDaysRemaining extends Component { const json = await res.json() const days = this.calculateDays(json.values[0].endDate) - this.setState({ days, error: false, loading: false }) - } catch (error) { - this.setState({ error: true, loading: false }) + this.setState({ days, hasError: false, isLoading: false }) + } catch (err) { + this.setState({ hasError: true, isLoading: false }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { days, error, loading } = this.state + const { days, hasError, isLoading } = this.state const { title } = this.props return ( - + ) diff --git a/components/widgets/pagespeed-insights/score.js b/components/widgets/pagespeed-insights/score.js index 36216378..62df6523 100644 --- a/components/widgets/pagespeed-insights/score.js +++ b/components/widgets/pagespeed-insights/score.js @@ -22,8 +22,8 @@ export default class PageSpeedInsightsScore extends Component { state = { score: 0, - loading: true, - error: false + isLoading: true, + hasError: false } componentDidMount () { @@ -31,7 +31,7 @@ export default class PageSpeedInsightsScore extends Component { .then(() => this.fetchInformation()) .catch((err) => { console.error(`${err.name} @ ${this.constructor.name}`, err.errors) - this.setState({ error: true, loading: false }) + this.setState({ hasError: true, isLoading: false }) }) } @@ -52,19 +52,19 @@ export default class PageSpeedInsightsScore extends Component { const res = await fetch(`https://www.googleapis.com/pagespeedonline/v2/runPagespeed?${searchParams}`) const json = await res.json() - this.setState({ error: false, loading: false, score: json.ruleGroups.SPEED.score }) - } catch (error) { - this.setState({ error: true, loading: false }) + this.setState({ hasError: false, isLoading: false, score: json.ruleGroups.SPEED.score }) + } catch (err) { + this.setState({ hasError: true, isLoading: false }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { error, loading, score } = this.state + const { hasError, isLoading, score } = this.state const { title } = this.props return ( - + ) diff --git a/components/widgets/pagespeed-insights/stats.js b/components/widgets/pagespeed-insights/stats.js index 381408a0..c77cd6a1 100644 --- a/components/widgets/pagespeed-insights/stats.js +++ b/components/widgets/pagespeed-insights/stats.js @@ -22,8 +22,8 @@ export default class PageSpeedInsightsStats extends Component { state = { stats: {}, - loading: true, - error: false + isLoading: true, + hasError: false } componentDidMount () { @@ -31,7 +31,7 @@ export default class PageSpeedInsightsStats extends Component { .then(() => this.fetchInformation()) .catch((err) => { console.error(`${err.name} @ ${this.constructor.name}`, err.errors) - this.setState({ error: true, loading: false }) + this.setState({ hasError: true, isLoading: false }) }) } @@ -69,19 +69,19 @@ export default class PageSpeedInsightsStats extends Component { otherSize: this.bytesToKilobytes(pageStats.otherResponseBytes) } - this.setState({ error: false, loading: false, stats }) - } catch (error) { - this.setState({ error: true, loading: false }) + this.setState({ hasError: false, isLoading: false, stats }) + } catch (err) { + this.setState({ hasError: true, isLoading: false }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { error, loading, stats } = this.state + const { hasError, isLoading, stats } = this.state const { title } = this.props return ( - +
diff --git a/components/widgets/sonarqube/index.js b/components/widgets/sonarqube/index.js index 8c8b3b92..48a66044 100644 --- a/components/widgets/sonarqube/index.js +++ b/components/widgets/sonarqube/index.js @@ -55,8 +55,8 @@ export default class SonarQube extends Component { state = { measures: [], - loading: true, - error: false + isLoading: true, + hasError: false } componentDidMount () { @@ -64,7 +64,7 @@ export default class SonarQube extends Component { .then(() => this.fetchInformation()) .catch((err) => { console.error(`${err.name} @ ${this.constructor.name}`, err.errors) - this.setState({ error: true, loading: false }) + this.setState({ hasError: true, isLoading: false }) }) } @@ -87,9 +87,9 @@ export default class SonarQube extends Component { const res = await fetch(`${url}/api/measures/component?componentKey=${componentKey}&metricKeys=${metricKeys}`, opts) const json = await res.json() - this.setState({ error: false, loading: false, measures: json.component.measures }) - } catch (error) { - this.setState({ error: true, loading: false }) + this.setState({ hasError: false, isLoading: false, measures: json.component.measures }) + } catch (err) { + this.setState({ hasError: true, isLoading: false }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } @@ -120,7 +120,7 @@ export default class SonarQube extends Component { } render () { - const { error, loading, measures } = this.state + const { hasError, isLoading, measures } = this.state const { title } = this.props const alertStatus = this.getMetricValue(measures, 'alert_status') @@ -134,7 +134,7 @@ export default class SonarQube extends Component { const duplicatedLinesDensity = this.getMetricValue(measures, 'duplicated_lines_density') return ( - +
From 2a656de506fae36da3f3bf1519c25d8639090c2b Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Mon, 7 Aug 2017 19:50:52 +0200 Subject: [PATCH 02/12] Add alert prototype --- components/widget.js | 17 +++++++++++++---- lib/alert.js | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 lib/alert.js diff --git a/components/widget.js b/components/widget.js index db3d8d52..ef0012b2 100644 --- a/components/widget.js +++ b/components/widget.js @@ -1,13 +1,22 @@ -import styled from 'styled-components' +import styled, { css } from 'styled-components' import { size } from 'polished' import LoadingIndicator from './loading-indicator' import ErrorIcon from './error-icon' +import { NONE, WARNING, CRITICAL } from '../lib/alert' const Container = styled.div` ${size('20em')} align-items: center; background-color: ${props => props.theme.palette.canvasColor}; - border: 1px solid ${props => props.theme.palette.borderColor}; + ${props => props.alertSeverity === NONE && css` + border: 1px solid ${props => props.theme.palette.borderColor}; + `} + ${props => props.alertSeverity === WARNING && css` + border: 1px solid ${props => props.theme.palette.warnColor}; + `} + ${props => props.alertSeverity === CRITICAL && css` + border: 1px solid ${props => props.theme.palette.errorColor}; + `} display: flex; flex-direction: column; justify-content: center; @@ -19,7 +28,7 @@ const Title = styled.h1` text-align: center; ` -export default ({ children, hasError = false, isLoading = false, title = '' }) => { +export default ({ children, hasError = false, isLoading = false, alertSeverity = NONE, title = '' }) => { let content if (isLoading) { @@ -31,7 +40,7 @@ export default ({ children, hasError = false, isLoading = false, title = '' }) = } return ( - + {title ? {title} : ''} {content} diff --git a/lib/alert.js b/lib/alert.js new file mode 100644 index 00000000..afeadd87 --- /dev/null +++ b/lib/alert.js @@ -0,0 +1,26 @@ +export const NONE = 'none' +export const WARNING = 'warning' +export const CRITICAL = 'critical' + +export const severity = (value, alert) => ( + Number.isInteger(value) ? severityAsInteger(value, alert) : severityAsString(value, alert) +) + +const severityAsInteger = (value, alert) => { + const alertSeverityCritical = alert.find(item => item.severity === CRITICAL) + if (alertSeverityCritical && value >= alertSeverityCritical.value) { + return CRITICAL + } + + const alertSeverityWarning = alert.find(item => item.severity === WARNING) + if (alertSeverityWarning && value >= alertSeverityWarning.value) { + return WARNING + } + + return NONE +} + +const severityAsString = (value, alert) => { + const alertItem = alert.find(item => item.value === value) + return alertItem ? alertItem.severity : NONE +} From 2487a071d0519e34bed8c1a82ba8e84810b46f2f Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Mon, 7 Aug 2017 19:52:14 +0200 Subject: [PATCH 03/12] Add alert feature to the JiraIssueCount widget --- components/widgets/jira/issue-count.js | 27 +++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/components/widgets/jira/issue-count.js b/components/widgets/jira/issue-count.js index a1456fe6..eef61bdb 100644 --- a/components/widgets/jira/issue-count.js +++ b/components/widgets/jira/issue-count.js @@ -4,13 +4,18 @@ import yup from 'yup' import Widget from '../../widget' import Counter from '../../counter' import { basicAuthHeader } from '../../../lib/auth' +import { severity, NONE } from '../../../lib/alert' const schema = yup.object().shape({ url: yup.string().url().required(), query: yup.string().required(), interval: yup.number(), title: yup.string(), - authKey: yup.string() + authKey: yup.string(), + alert: yup.array(yup.object({ + severity: yup.string().required(), + value: yup.number().required() + })) }) export default class JiraIssueCount extends Component { @@ -22,7 +27,8 @@ export default class JiraIssueCount extends Component { state = { count: 0, hasError: false, - isLoading: true + isLoading: true, + alertSeverity: NONE } componentDidMount () { @@ -39,26 +45,33 @@ export default class JiraIssueCount extends Component { } async fetchInformation () { - const { authKey, url, query } = this.props + const { authKey, url, query, alert } = this.props const opts = authKey ? { headers: basicAuthHeader(authKey) } : {} try { const res = await fetch(`${url}/rest/api/2/search?jql=${query}`, opts) const json = await res.json() + const total = json.total - this.setState({ count: json.total, hasError: false, isLoading: false }) + this.setState({ + count: total, + hasError: false, + isLoading: false, + alertSeverity: severity(total, alert) + }) } catch (err) { - this.setState({ hasError: true, isLoading: false }) + this.setState({ hasError: true, isLoading: false, alertSeverity: NONE }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { count, hasError, isLoading } = this.state + const { count, hasError, isLoading, alertSeverity } = this.state const { title } = this.props + return ( - + ) From 11a36e42342016d21a751710fbb846ba4df280d7 Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Mon, 7 Aug 2017 19:52:27 +0200 Subject: [PATCH 04/12] Add alert example --- pages/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pages/index.js b/pages/index.js index 2b00d27d..d57ac733 100644 --- a/pages/index.js +++ b/pages/index.js @@ -27,6 +27,10 @@ export default () => ( title='JIRA Open Bugs' url='https://crossorigin.me/https://jira.atlassian.com' query='type=Bug AND project="Bitbucket Server" AND resolution=Unresolved ORDER BY priority DESC,created DESC' + alert={[ + { severity: 'warning', value: 5 }, + { severity: 'critical', value: 10 } + ]} /> Date: Wed, 9 Aug 2017 17:55:08 +0200 Subject: [PATCH 05/12] Set "border-color" instead of "border" --- components/widget.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/components/widget.js b/components/widget.js index ef0012b2..56fd69cf 100644 --- a/components/widget.js +++ b/components/widget.js @@ -8,14 +8,16 @@ const Container = styled.div` ${size('20em')} align-items: center; background-color: ${props => props.theme.palette.canvasColor}; + border-style: solid; + border-width: 1px; ${props => props.alertSeverity === NONE && css` - border: 1px solid ${props => props.theme.palette.borderColor}; + border-color: ${props => props.theme.palette.borderColor}; `} ${props => props.alertSeverity === WARNING && css` - border: 1px solid ${props => props.theme.palette.warnColor}; + border-color: ${props => props.theme.palette.warnColor}; `} ${props => props.alertSeverity === CRITICAL && css` - border: 1px solid ${props => props.theme.palette.errorColor}; + border-color: ${props => props.theme.palette.errorColor}; `} display: flex; flex-direction: column; From 61daae2e5e338288cebfefc33f6cefc184393a98 Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Sun, 20 Aug 2017 09:39:11 +0200 Subject: [PATCH 06/12] Cleanup component styling --- components/widget.js | 16 +++------------- styles/dark-theme.js | 5 +++++ styles/light-theme.js | 7 +++++++ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/components/widget.js b/components/widget.js index 56fd69cf..b894ebf3 100644 --- a/components/widget.js +++ b/components/widget.js @@ -1,24 +1,14 @@ -import styled, { css } from 'styled-components' +import styled from 'styled-components' import { size } from 'polished' import LoadingIndicator from './loading-indicator' import ErrorIcon from './error-icon' -import { NONE, WARNING, CRITICAL } from '../lib/alert' +import { NONE } from '../lib/alert' const Container = styled.div` ${size('20em')} align-items: center; background-color: ${props => props.theme.palette.canvasColor}; - border-style: solid; - border-width: 1px; - ${props => props.alertSeverity === NONE && css` - border-color: ${props => props.theme.palette.borderColor}; - `} - ${props => props.alertSeverity === WARNING && css` - border-color: ${props => props.theme.palette.warnColor}; - `} - ${props => props.alertSeverity === CRITICAL && css` - border-color: ${props => props.theme.palette.errorColor}; - `} + border: 1px solid ${props => props.theme.atoms.Widget[props.alertSeverity].border}; display: flex; flex-direction: column; justify-content: center; diff --git a/styles/dark-theme.js b/styles/dark-theme.js index f76f3ffd..0a5f42cf 100644 --- a/styles/dark-theme.js +++ b/styles/dark-theme.js @@ -28,5 +28,10 @@ export default { successColor: colors.green500, successSecondaryColor: colors.lime500, disabledColor: colors.grey400 + }, + Widget: { + none: { border: colors.grey700 }, + warning: { border: colors.amber500 }, + critical: { border: colors.red500 } } } diff --git a/styles/light-theme.js b/styles/light-theme.js index 0585f1d1..13105d13 100644 --- a/styles/light-theme.js +++ b/styles/light-theme.js @@ -28,5 +28,12 @@ export default { successColor: colors.greenA700, successSecondaryColor: colors.lightGreenA700, disabledColor: colors.grey400 + }, + atoms: { + Widget: { + none: { border: colors.grey200 }, + warning: { border: colors.amberA700 }, + critical: { border: colors.redA700 } + } } } From b369224dc5ab30b18fd527049b186e819cc7434a Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Sun, 20 Aug 2017 09:50:50 +0200 Subject: [PATCH 07/12] Improve readability --- lib/alert.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/alert.js b/lib/alert.js index afeadd87..b4fcc908 100644 --- a/lib/alert.js +++ b/lib/alert.js @@ -3,7 +3,9 @@ export const WARNING = 'warning' export const CRITICAL = 'critical' export const severity = (value, alert) => ( - Number.isInteger(value) ? severityAsInteger(value, alert) : severityAsString(value, alert) + Number.isInteger(value) + ? severityAsInteger(value, alert) + : severityAsString(value, alert) ) const severityAsInteger = (value, alert) => { From 1130610eaf855270627689d3cc14e2c6b6393ec7 Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Sat, 26 Aug 2017 08:51:45 +0200 Subject: [PATCH 08/12] Add atoms --- styles/dark-theme.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/styles/dark-theme.js b/styles/dark-theme.js index 0a5f42cf..59bb93c5 100644 --- a/styles/dark-theme.js +++ b/styles/dark-theme.js @@ -29,9 +29,11 @@ export default { successSecondaryColor: colors.lime500, disabledColor: colors.grey400 }, - Widget: { - none: { border: colors.grey700 }, - warning: { border: colors.amber500 }, - critical: { border: colors.red500 } + atoms: { + Widget: { + none: { border: colors.grey700 }, + warning: { border: colors.amber500 }, + critical: { border: colors.red500 } + } } } From 19586f38c6c34d861910d2a96887d118853628d5 Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Sun, 27 Aug 2017 10:26:18 +0200 Subject: [PATCH 09/12] Add alert feature to the ElasticsearchHitCount widget --- components/widgets/elasticsearch/hit-count.js | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/components/widgets/elasticsearch/hit-count.js b/components/widgets/elasticsearch/hit-count.js index c5dae8d6..c2c9b8ae 100644 --- a/components/widgets/elasticsearch/hit-count.js +++ b/components/widgets/elasticsearch/hit-count.js @@ -4,13 +4,18 @@ import yup from 'yup' import Widget from '../../widget' import Counter from '../../counter' import { basicAuthHeader } from '../../../lib/auth' +import { severity, NONE } from '../../../lib/alert' const schema = yup.object().shape({ url: yup.string().url().required(), index: yup.string().required(), query: yup.string().required(), interval: yup.number(), - title: yup.string() + title: yup.string(), + alert: yup.array(yup.object({ + severity: yup.string().required(), + value: yup.number().required() + })) }) export default class ElasticsearchHitCount extends Component { @@ -22,7 +27,8 @@ export default class ElasticsearchHitCount extends Component { state = { count: 0, hasError: false, - isLoading: true + isLoading: true, + alertSeverity: NONE } componentDidMount () { @@ -39,26 +45,33 @@ export default class ElasticsearchHitCount extends Component { } async fetchInformation () { - const { authKey, index, query, url } = this.props + const { authKey, index, query, url, alert } = this.props const opts = authKey ? { headers: basicAuthHeader(authKey) } : {} try { const res = await fetch(`${url}/${index}/_search?q=${query}`, opts) const json = await res.json() + const total = json.hits.total - this.setState({ count: json.hits.total, hasError: false, isLoading: false }) + this.setState({ + count: total, + hasError: false, + isLoading: false, + alertSeverity: severity(total, alert) + }) } catch (err) { - this.setState({ hasError: true, isLoading: false }) + this.setState({ hasError: true, isLoading: false, alertSeverity: NONE }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { count, hasError, isLoading } = this.state + const { count, hasError, isLoading, alertSeverity } = this.state const { title } = this.props + return ( - + ) From c4971968a7cb997811845a67e4f23792703baeed Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Sun, 27 Aug 2017 10:29:29 +0200 Subject: [PATCH 10/12] Add alert feature to the GitHubIssueCount widget --- components/widgets/github/issue-count.js | 26 +++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/components/widgets/github/issue-count.js b/components/widgets/github/issue-count.js index a7480ade..7ff339e1 100644 --- a/components/widgets/github/issue-count.js +++ b/components/widgets/github/issue-count.js @@ -4,13 +4,18 @@ import yup from 'yup' import Widget from '../../widget' import Counter from '../../counter' import { basicAuthHeader } from '../../../lib/auth' +import { severity, NONE } from '../../../lib/alert' const schema = yup.object().shape({ owner: yup.string().required(), repository: yup.string().required(), interval: yup.number(), title: yup.string(), - authKey: yup.string() + authKey: yup.string(), + alert: yup.array(yup.object({ + severity: yup.string().required(), + value: yup.number().required() + })) }) export default class GitHubIssueCount extends Component { @@ -22,7 +27,8 @@ export default class GitHubIssueCount extends Component { state = { count: 0, hasError: false, - isLoading: true + isLoading: true, + alertSeverity: NONE } componentDidMount () { @@ -39,26 +45,32 @@ export default class GitHubIssueCount extends Component { } async fetchInformation () { - const { authKey, owner, repository } = this.props + const { authKey, owner, repository, alert } = this.props const opts = authKey ? { headers: basicAuthHeader(authKey) } : {} try { const res = await fetch(`https://api.github.com/repos/${owner}/${repository}`, opts) const json = await res.json() + const total = json.open_issues_count - this.setState({ count: json.open_issues_count, hasError: false, isLoading: false }) + this.setState({ + count: total, + hasError: false, + isLoading: false, + alertSeverity: severity(total, alert) + }) } catch (err) { - this.setState({ hasError: true, isLoading: false }) + this.setState({ hasError: true, isLoading: false, alertSeverity: NONE }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { count, hasError, isLoading } = this.state + const { count, hasError, isLoading, alertSeverity } = this.state const { title } = this.props return ( - + ) From f0e88e42900f4d7a38ce86d4fad4e84b7d2921dc Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Sun, 27 Aug 2017 10:31:54 +0200 Subject: [PATCH 11/12] Add alert feature to the BitbucketPullRequestCount widget --- .../widgets/bitbucket/pull-request-count.js | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/components/widgets/bitbucket/pull-request-count.js b/components/widgets/bitbucket/pull-request-count.js index 70a60fe2..ffbd0247 100644 --- a/components/widgets/bitbucket/pull-request-count.js +++ b/components/widgets/bitbucket/pull-request-count.js @@ -4,6 +4,7 @@ import yup from 'yup' import Widget from '../../widget' import Counter from '../../counter' import { basicAuthHeader } from '../../../lib/auth' +import { severity, NONE } from '../../../lib/alert' const schema = yup.object().shape({ url: yup.string().url().required(), @@ -12,7 +13,11 @@ const schema = yup.object().shape({ interval: yup.number(), title: yup.string(), users: yup.array().of(yup.string()), - authKey: yup.string() + authKey: yup.string(), + alert: yup.array(yup.object({ + severity: yup.string().required(), + value: yup.number().required() + })) }) export default class BitbucketPullRequestCount extends Component { @@ -25,7 +30,8 @@ export default class BitbucketPullRequestCount extends Component { state = { count: 0, hasError: false, - isLoading: true + isLoading: true, + alertSeverity: NONE } componentDidMount () { @@ -42,7 +48,7 @@ export default class BitbucketPullRequestCount extends Component { } async fetchInformation () { - const { authKey, url, project, repository, users } = this.props + const { authKey, url, project, repository, users, alert } = this.props const opts = authKey ? { headers: basicAuthHeader(authKey) } : {} try { @@ -56,19 +62,24 @@ export default class BitbucketPullRequestCount extends Component { count = json.size } - this.setState({ count, hasError: false, isLoading: false }) + this.setState({ + count, + hasError: false, + isLoading: false, + alertSeverity: severity(count, alert) + }) } catch (err) { - this.setState({ hasError: true, isLoading: false }) + this.setState({ hasError: true, isLoading: false, alertSeverity: NONE }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { count, hasError, isLoading } = this.state + const { count, hasError, isLoading, alertSeverity } = this.state const { title } = this.props return ( - + ) From 713532f52754b1e913712eb27d6941d7a17891b0 Mon Sep 17 00:00:00 2001 From: Daniel Bayerlein Date: Sun, 27 Aug 2017 10:35:02 +0200 Subject: [PATCH 12/12] Add alert feature to the PageSpeedInsightsScore widget --- .../widgets/pagespeed-insights/score.js | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/components/widgets/pagespeed-insights/score.js b/components/widgets/pagespeed-insights/score.js index 62df6523..e60275c1 100644 --- a/components/widgets/pagespeed-insights/score.js +++ b/components/widgets/pagespeed-insights/score.js @@ -3,13 +3,18 @@ import fetch from 'isomorphic-unfetch' import yup from 'yup' import CircleProgress from '../../circle-progress' import Widget from '../../widget' +import { severity, NONE } from '../../../lib/alert' const schema = yup.object().shape({ url: yup.string().url().required(), filterThirdPartyResources: yup.boolean(), interval: yup.number(), strategy: yup.string(), - title: yup.string() + title: yup.string(), + alert: yup.array(yup.object({ + severity: yup.string().required(), + value: yup.number().required() + })) }) export default class PageSpeedInsightsScore extends Component { @@ -23,7 +28,8 @@ export default class PageSpeedInsightsScore extends Component { state = { score: 0, isLoading: true, - hasError: false + hasError: false, + alertSeverity: NONE } componentDidMount () { @@ -40,7 +46,7 @@ export default class PageSpeedInsightsScore extends Component { } async fetchInformation () { - const { url, filterThirdPartyResources, strategy } = this.props + const { url, filterThirdPartyResources, strategy, alert } = this.props const searchParams = [ `url=${url}`, @@ -51,20 +57,27 @@ export default class PageSpeedInsightsScore extends Component { try { const res = await fetch(`https://www.googleapis.com/pagespeedonline/v2/runPagespeed?${searchParams}`) const json = await res.json() + const score = json.ruleGroups.SPEED.score - this.setState({ hasError: false, isLoading: false, score: json.ruleGroups.SPEED.score }) + this.setState({ + score, + hasError: false, + isLoading: false, + alertSeverity: severity(score, alert) + }) } catch (err) { - this.setState({ hasError: true, isLoading: false }) + this.setState({ hasError: true, isLoading: false, alertSeverity: NONE }) } finally { this.interval = setInterval(() => this.fetchInformation(), this.props.interval) } } render () { - const { hasError, isLoading, score } = this.state + const { hasError, isLoading, score, alertSeverity } = this.state const { title } = this.props + return ( - + )