Skip to content

Commit

Permalink
Merge 4f2f35a into df894d9
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphaël Benitte committed Aug 16, 2017
2 parents df894d9 + 4f2f35a commit 41e64f8
Show file tree
Hide file tree
Showing 20 changed files with 1,215 additions and 364 deletions.
108 changes: 102 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ You can see a live demo of the widgets [here](http://mozaik-gitlab.herokuapp.com

## Widgets

- [Branches](#gitlab-branches)
- [Build Histogram](#gitlab-build-histogram)
- [Build History](#gitlab-build-history)
- [Project](#gitlab-project)
- [Project Members](#gitlab-project-members)
- [Project Contributors](#gitlab-project-contributors)
- [Project](#gitlab-project)

- [Branches](#gitlab-branches)
- Builds
- [Build Histogram](#gitlab-build-histogram)
- [Build History](#gitlab-build-history)
- Labels
- [Labels Bubble chart](#gitlab-labels-bubble-chart)
- [Labels Pie](#gitlab-labels-pie)
- [Labels Tree map](#gitlab-labels-tree-map)

### GitLab Branches

Expand Down Expand Up @@ -202,6 +206,98 @@ dashboards:
y: 0
```

### GitLab labels bubble chart

> Show GitLab project's labels stats using a bubble chart.
![Gitlab labels bubble chart](https://raw.githubusercontent.com/plouc/mozaik-ext-gitlab/master/preview/gitlab_labels_bubble.png)

#### parameters

key | required | default | description
----------|----------|-----------------------|----------------
`project` | yes | *n/a* | *ID or NAMESPACE/PROJECT_NAME of a project*
`countBy` | yes | `'open_issues_count'` | *Defines which count to use, must be one of: `'open_issues_count'`, `'closed_issues_count'`, `'open_merge_requests_count'`*
`title` | no | *n/a* | *Overrides widget title*

#### usage

``` yaml
# config.yml
dashboards:
- #
widgets:
- extension: gitlab
widget: LabelsBubble
project: gitlab-org/gitlab-ce
columns: 1
rows: 1
x: 0
y: 0
```


### GitLab labels pie

> Show GitLab project's labels stats using a pie chart.
![Gitlab labels pie](https://raw.githubusercontent.com/plouc/mozaik-ext-gitlab/master/preview/gitlab_labels_pie.png)

#### parameters

key | required | default | description
----------|----------|-----------------------|----------------
`project` | yes | *n/a* | *ID or NAMESPACE/PROJECT_NAME of a project*
`countBy` | yes | `'open_issues_count'` | *Defines which count to use, must be one of: `'open_issues_count'`, `'closed_issues_count'`, `'open_merge_requests_count'`*
`title` | no | *n/a* | *Overrides widget title*

#### usage

``` yaml
# config.yml
dashboards:
- #
widgets:
- extension: gitlab
widget: LabelsPie
project: gitlab-org/gitlab-ce
columns: 1
rows: 1
x: 0
y: 0
```


### GitLab labels tree map

> Show GitLab project's labels stats using a tree map chart.
![Gitlab labels tree map](https://raw.githubusercontent.com/plouc/mozaik-ext-gitlab/master/preview/gitlab_labels_treemap.png)

#### parameters

key | required | default | description
----------|----------|-----------------------|----------------
`project` | yes | *n/a* | *ID or NAMESPACE/PROJECT_NAME of a project*
`countBy` | yes | `'open_issues_count'` | *Defines which count to use, must be one of: `'open_issues_count'`, `'closed_issues_count'`, `'open_merge_requests_count'`*
`title` | no | *n/a* | *Overrides widget title*

#### usage

``` yaml
# config.yml
dashboards:
- #
widgets:
- extension: gitlab
widget: LabelsTreemap
project: gitlab-org/gitlab-ce
columns: 1
rows: 1
x: 0
y: 0
```


[license-image]: https://img.shields.io/github/license/plouc/mozaik-ext-gitlab.svg?style=flat-square
[license-url]: https://github.com/plouc/mozaik-ext-gitlab/blob/master/LICENSE.md
Expand All @@ -213,6 +309,6 @@ dashboards:
[gemnasium-url]: https://gemnasium.com/plouc/mozaik-ext-gitlab
[coverage-image]: https://img.shields.io/coveralls/plouc/mozaik-ext-gitlab.svg?style=flat-square
[coverage-url]: https://coveralls.io/github/plouc/mozaik-ext-gitlab
[widget-count-image]: https://img.shields.io/badge/widgets-x6-green.svg?style=flat-square
[widget-count-image]: https://img.shields.io/badge/widgets-x9-green.svg?style=flat-square
[heroku-image]: https://www.herokucdn.com/deploy/button.svg
[heroku-url]: https://heroku.com/deploy?template=https://github.com/plouc/mozaik-ext-gitlab/tree/demo
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"husky": "^0.14.3",
"jest": "^20.0.4",
"lint-staged": "^4.0.2",
"nivo": "^0.12.0",
"nock": "^9.0.14",
"prettier": "^1.5.3",
"react": "^15.6.1",
Expand All @@ -63,7 +64,7 @@
},
"peerDependencies": {
"@mozaik/ui": "^2.0.0-alpha.11",
"nivo": "^0.1.0",
"nivo": "^0.12.0",
"react": "^15.6.1"
},
"scripts": {
Expand All @@ -73,6 +74,7 @@
"test:cover": "jest --verbose --coverage",
"coverage": "cat ./coverage/lcov.info | coveralls",
"build:commonjs": "cross-env BABEL_ENV=commonjs babel src --out-dir lib",
"build:commonjs:watch": "npm run build:commonjs -- --watch",
"build:es": "cross-env BABEL_ENV=es babel src --out-dir es",
"build:es:watch": "npm run build:es -- --watch",
"build": "npm run build:commonjs && npm run build:es",
Expand Down
Binary file added preview/gitlab_labels_bubble.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added preview/gitlab_labels_pie.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added preview/gitlab_labels_treemap.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ const client = mozaik => {
}
})
},
projectLabels({ project }) {
return Promise.all([
operations.project({ project }),
buildApiRequest(`/projects/${encodeURIComponent(project)}/labels`).then(
res => res.body
),
]).then(([project, labels]) => ({
project,
labels,
}))
},
}

return operations
Expand Down
2 changes: 2 additions & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import BuildHistory from './BuildHistory'
import BuildHistogram from './BuildHistogram'
import Branches from './Branches'
//import MergeRequestsGauge from './MergeRequestsGauge'
import * as labels from './labels'

export default {
Project,
Expand All @@ -14,4 +15,5 @@ export default {
BuildHistogram,
Branches,
//MergeRequestsGauge,
...labels,
}
42 changes: 42 additions & 0 deletions src/components/labels/LabelsBubble.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { Component } from 'react'
import { ResponsiveBubble } from 'nivo'
import LabelsChart from './LabelsChart'

const margin = {
top: 10,
right: 10,
bottom: 10,
left: 10,
}

export default class LabelsBubble extends Component {
static getApiRequest = LabelsChart.getApiRequest

render() {
return (
<LabelsChart {...this.props}>
{({ labels, countBy, animate }) => {
const data = {
name: 'labels',
color: '#000',
children: labels,
}

return (
<ResponsiveBubble
root={data}
margin={margin}
labelSkipRadius={12}
value={countBy}
label={d => `${d.name} ${d[countBy]}`}
labelTextColor="inherit:darker(1.6)"
leavesOnly={true}
colorBy={d => d.color}
animate={animate}
/>
)
}}
</LabelsChart>
)
}
}
87 changes: 87 additions & 0 deletions src/components/labels/LabelsChart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import LabelsIcon from 'react-icons/lib/fa/tags'
import { TrapApiError, Widget, WidgetHeader, WidgetBody, WidgetLoader } from '@mozaik/ui'
import { countTypes, countLabel } from './counts'

export default class LabelsChart extends Component {
static propTypes = {
project: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
countBy: PropTypes.oneOf(countTypes).isRequired,
apiData: PropTypes.shape({
project: PropTypes.shape({
name: PropTypes.string.isRequired,
web_url: PropTypes.string.isRequired,
}).isRequired,
labels: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
color: PropTypes.string.isRequired,
open_issues_count: PropTypes.number.isRequired,
closed_issues_count: PropTypes.number.isRequired,
open_merge_requests_count: PropTypes.number.isRequired,
})
).isRequired,
}),
apiError: PropTypes.object,
title: PropTypes.string,
animate: PropTypes.bool.isRequired,
children: PropTypes.func.isRequired,
theme: PropTypes.object.isRequired,
}

static defaultProps = {
countBy: 'open_issues_count',
animate: false,
}

static getApiRequest({ project }) {
return {
id: `gitlab.projectLabels.${project}`,
params: { project },
}
}

render() {
const { apiData, apiError, title, countBy, animate, children, theme } = this.props

let body = <WidgetLoader />
let subject = null
let count = 0
if (apiData) {
const { project, labels } = apiData

count = labels.length

subject = (
<a href={project.web_url} target="_blank">
{project.name}
</a>
)

body = children({
labels,
countBy,
animate,
theme: theme.charts,
})
}

return (
<Widget>
<WidgetHeader
title={title || `Labels by ${countLabel(countBy)}`}
subject={title ? null : subject}
count={count}
icon={LabelsIcon}
/>
<WidgetBody>
<TrapApiError error={apiError}>
{body}
</TrapApiError>
</WidgetBody>
</Widget>
)
}
}
48 changes: 48 additions & 0 deletions src/components/labels/LabelsPie.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { Component } from 'react'
import { ResponsivePie } from 'nivo'
import LabelsChart from './LabelsChart'

const margin = {
top: 30,
right: 60,
bottom: 30,
left: 60,
}

const skipAngle = 5

export default class LabelsPie extends Component {
static getApiRequest = LabelsChart.getApiRequest

render() {
return (
<LabelsChart {...this.props}>
{({ labels, countBy, animate, theme }) => {
const data = labels.map(label => ({
...label,
id: `${label.id}`,
label: label.name,
value: label[countBy],
}))

return (
<ResponsivePie
data={data}
margin={margin}
colorBy={d => d.color}
innerRadius={0.6}
padAngle={1}
radialLabel="name"
radialLabelsSkipAngle={skipAngle}
slicesLabel={countBy}
slicesLabelsSkipAngle={skipAngle}
slicesLabelsTextColor="inherit:darker(1.6)"
animate={animate}
theme={theme}
/>
)
}}
</LabelsChart>
)
}
}

0 comments on commit 41e64f8

Please sign in to comment.