@platformatic/ui-components 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +2 -0
- package/package.json +17 -4
- package/src/components/ApiSummary.jsx +2 -2
- package/src/components/GHLoginButton.jsx +0 -1
- package/src/components/LoginButton.jsx +2 -2
- package/src/components/LoginButton.test.jsx +25 -0
- package/src/components/Main.jsx +2 -2
- package/src/components/PullRequest.jsx +54 -19
- package/src/components/PullRequest.module.css +17 -2
- package/src/components/Status.jsx +26 -0
- package/src/lib/utils.js +3 -0
- package/src/stories/BorderedBox.stories.jsx +11 -2
- package/src/stories/Button.jsx +11 -11
- package/src/stories/Button.stories.jsx +5 -5
- package/src/stories/PullRequest.stories.jsx +31 -5
- package/src/stories/Status.stories.jsx +31 -0
- package/vitest.config.js +14 -0
- package/src/components/Api/Status.jsx +0 -20
package/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import TwoColumnsLayout from './src/components/layouts/TwoColumnsLayout'
|
|
|
12
12
|
import Playground from './src/components/Playground'
|
|
13
13
|
import PullRequest from './src/components/PullRequest'
|
|
14
14
|
import SearchBar from './src/components/SearchBar'
|
|
15
|
+
import Status from './src/components/Status'
|
|
15
16
|
import TabbedWindow from './src/components/TabbedWindow'
|
|
16
17
|
import TextWithLabel from './src/components/TextWithLabel'
|
|
17
18
|
import Versions from './src/components/Versions'
|
|
@@ -29,6 +30,7 @@ export {
|
|
|
29
30
|
Playground,
|
|
30
31
|
PullRequest,
|
|
31
32
|
SearchBar,
|
|
33
|
+
Status,
|
|
32
34
|
TabbedWindow,
|
|
33
35
|
TextWithLabel,
|
|
34
36
|
Versions,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/ui-components",
|
|
3
3
|
"description": "Platformatic UI Components",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.12",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"scripts": {
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
"build-storybook": "NODE_OPTIONS='--openssl-legacy-provider' build-storybook",
|
|
13
13
|
"tailwind:watch": "tailwindcss -i ./src/styles/main.css -o ./dist/main.css --watch",
|
|
14
14
|
"tailwind": "tailwindcss -i ./src/styles/main.css -o ./dist/main.css",
|
|
15
|
-
"lint": "standard
|
|
15
|
+
"lint": "standard src | snazzy",
|
|
16
|
+
"lint:fix": "standard src --fix",
|
|
17
|
+
"test": "vitest run"
|
|
16
18
|
},
|
|
17
19
|
"dependencies": {
|
|
18
20
|
"@fortawesome/fontawesome-svg-core": "^6.2.0",
|
|
@@ -34,17 +36,28 @@
|
|
|
34
36
|
"@storybook/builder-vite": "^0.2.4",
|
|
35
37
|
"@storybook/react": "^6.5.12",
|
|
36
38
|
"@storybook/testing-library": "^0.0.13",
|
|
39
|
+
"@testing-library/jest-dom": "^5.16.5",
|
|
40
|
+
"@testing-library/react": "^13.4.0",
|
|
37
41
|
"@types/react": "^18.0.17",
|
|
38
42
|
"@types/react-dom": "^18.0.6",
|
|
39
43
|
"@vitejs/plugin-react": "^2.1.0",
|
|
40
44
|
"babel-loader": "^8.2.5",
|
|
45
|
+
"jsdom": "^20.0.1",
|
|
46
|
+
"react-test-renderer": "^18.2.0",
|
|
47
|
+
"snazzy": "^9.0.0",
|
|
41
48
|
"standard": "^17.0.0",
|
|
42
49
|
"tailwindcss": "^3.1.8",
|
|
43
|
-
"vite": "^3.1.0"
|
|
50
|
+
"vite": "^3.1.0",
|
|
51
|
+
"vitest": "^0.24.3"
|
|
44
52
|
},
|
|
45
53
|
"standard": {
|
|
46
|
-
"
|
|
54
|
+
"globals": [
|
|
55
|
+
"expect",
|
|
56
|
+
"test",
|
|
47
57
|
"alert"
|
|
58
|
+
],
|
|
59
|
+
"ignore": [
|
|
60
|
+
"/dist"
|
|
48
61
|
]
|
|
49
62
|
}
|
|
50
63
|
}
|
|
@@ -8,7 +8,7 @@ import ApiIcon from './icons/ApiIcon'
|
|
|
8
8
|
import ApiIconClosed from './icons/ApiIconClosed'
|
|
9
9
|
import VerticalSeparator from './VerticalSeparator'
|
|
10
10
|
import TextWithLabel from './TextWithLabel'
|
|
11
|
-
import
|
|
11
|
+
import Status from './Status'
|
|
12
12
|
import BorderedBox from './BorderedBox'
|
|
13
13
|
import HorizontalSeparator from './HorizontalSeparator'
|
|
14
14
|
import styles from './Api.module.css'
|
|
@@ -41,7 +41,7 @@ export default function ApiSummary (props) {
|
|
|
41
41
|
<ApiVersion version={version} />
|
|
42
42
|
</div>
|
|
43
43
|
<div className={styles.status}>
|
|
44
|
-
<
|
|
44
|
+
<Status color={color} status={online ? 'online' : 'offline'} />
|
|
45
45
|
</div>
|
|
46
46
|
|
|
47
47
|
</div>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import PropTypes from 'prop-types'
|
|
3
2
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
4
3
|
import styles from './LoginButton.module.css'
|
|
5
4
|
|
|
@@ -8,9 +7,10 @@ export default function LoginButton ({ icon, label, onClick, ...props }) {
|
|
|
8
7
|
<div className={styles.container} onClick={onClick}>
|
|
9
8
|
<div
|
|
10
9
|
className={styles.button}
|
|
10
|
+
data-testid='login-button'
|
|
11
11
|
{...props}
|
|
12
12
|
>
|
|
13
|
-
{icon ? <FontAwesomeIcon icon={icon} className='mr-2' /> : null} {label}
|
|
13
|
+
{icon ? <FontAwesomeIcon icon={icon} className='mr-2' data-testid='login-button-icon' /> : null} {label}
|
|
14
14
|
</div>
|
|
15
15
|
</div>
|
|
16
16
|
)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { render, screen } from '@testing-library/react'
|
|
3
|
+
import '@testing-library/jest-dom/extend-expect'
|
|
4
|
+
import LoginButton from './LoginButton'
|
|
5
|
+
import { faTwitter } from '@fortawesome/free-brands-svg-icons'
|
|
6
|
+
|
|
7
|
+
test('<LoginButton /> with label', () => {
|
|
8
|
+
const label = 'My Button'
|
|
9
|
+
render(
|
|
10
|
+
<LoginButton label={label} />
|
|
11
|
+
)
|
|
12
|
+
expect(screen.getByTestId('login-button')).toHaveTextContent(label)
|
|
13
|
+
const icon = screen.queryByTestId('login-button-icon')
|
|
14
|
+
expect(icon).not.toBeInTheDocument()
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
test('<LoginButton /> with label and twitter icon', () => {
|
|
18
|
+
const label = 'My Twitter Button'
|
|
19
|
+
render(
|
|
20
|
+
<LoginButton label={label} icon={faTwitter} />
|
|
21
|
+
)
|
|
22
|
+
expect(screen.getByTestId('login-button')).toHaveTextContent(label)
|
|
23
|
+
const icon = screen.queryByTestId('login-button-icon')
|
|
24
|
+
expect(icon).toBeInTheDocument()
|
|
25
|
+
})
|
package/src/components/Main.jsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
import SearchBar from './SearchBar'
|
|
4
|
-
import Api from './Api'
|
|
5
4
|
import ApiDetails from './ApiDetail'
|
|
5
|
+
import ApiSummary from './ApiSummary'
|
|
6
6
|
import TabbedWindow from './TabbedWindow'
|
|
7
7
|
import Prs from './PullRequest'
|
|
8
8
|
import Playground from './Playground'
|
|
@@ -63,7 +63,7 @@ export default function Main () {
|
|
|
63
63
|
<TabbedWindow
|
|
64
64
|
tabs={tabs}
|
|
65
65
|
/>
|
|
66
|
-
{apis.map((api) => { return (<
|
|
66
|
+
{apis.map((api) => { return (<ApiSummary key={api.id} data={api} />) })}
|
|
67
67
|
</>
|
|
68
68
|
)
|
|
69
69
|
}
|
|
@@ -6,26 +6,61 @@ import PullRequestIcon from './icons/PullRequestIcon'
|
|
|
6
6
|
import styles from './PullRequest.module.css'
|
|
7
7
|
import TextWithLabel from './TextWithLabel'
|
|
8
8
|
import VerticalSeparator from './VerticalSeparator'
|
|
9
|
-
|
|
9
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
10
|
+
import { faStopCircle, faRotateRight } from '@fortawesome/free-solid-svg-icons'
|
|
11
|
+
import Status from './Status'
|
|
12
|
+
export default function PullRequest ({ id, title, lastCommit, url, status, onStop, onReload }) {
|
|
13
|
+
let prStatusColor
|
|
14
|
+
if (status === 'available') {
|
|
15
|
+
prStatusColor = 'white'
|
|
16
|
+
} else if (status === 'running') {
|
|
17
|
+
prStatusColor = 'green'
|
|
18
|
+
} else if (status === 'unavailable') {
|
|
19
|
+
prStatusColor = 'white'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function handleStop () {
|
|
23
|
+
if (onStop) {
|
|
24
|
+
onStop()
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function handleReload () {
|
|
28
|
+
if (onReload) {
|
|
29
|
+
onReload()
|
|
30
|
+
}
|
|
31
|
+
}
|
|
10
32
|
return (
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
33
|
+
<div className={status === 'unavailable' ? styles.unavailable : null}>
|
|
34
|
+
<BorderedBox color={prStatusColor}>
|
|
35
|
+
<div className={styles.header}>
|
|
36
|
+
<div className={styles.title}>
|
|
37
|
+
<PullRequestIcon />
|
|
38
|
+
<span className={styles.id}>#{id}</span>
|
|
39
|
+
<span><a href={url} target='_blank' rel='noreferrer'>{url}</a></span>
|
|
40
|
+
</div>
|
|
41
|
+
<div className={styles.status}>
|
|
42
|
+
<Status color={prStatusColor} status={status} />
|
|
43
|
+
<VerticalSeparator />
|
|
44
|
+
<div className={styles.icons}>
|
|
45
|
+
<FontAwesomeIcon icon={faStopCircle} mask={['circle']} onClick={handleStop} />
|
|
46
|
+
<FontAwesomeIcon icon={faRotateRight} mask={['circle']} onClick={handleReload} />
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
<div className={styles.content}>
|
|
51
|
+
<TextWithLabel label='PR Title' text={title} />
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<HorizontalSeparator />
|
|
55
|
+
<div className={styles.footer}>
|
|
56
|
+
<TextWithLabel label='Last commit by' text={lastCommit.author} />
|
|
57
|
+
<VerticalSeparator />
|
|
58
|
+
<TextWithLabel label='Commit SHA' text={lastCommit.sha} />
|
|
59
|
+
<VerticalSeparator />
|
|
60
|
+
<TextWithLabel label='Last Update' text={lastCommit.date} />
|
|
61
|
+
</div>
|
|
62
|
+
</BorderedBox>
|
|
63
|
+
</div>
|
|
20
64
|
|
|
21
|
-
<HorizontalSeparator />
|
|
22
|
-
<div className={styles.footer}>
|
|
23
|
-
<TextWithLabel label='Last commit by' text={lastCommit.author} />
|
|
24
|
-
<VerticalSeparator />
|
|
25
|
-
<TextWithLabel label='Commit SHA' text={lastCommit.sha} />
|
|
26
|
-
<VerticalSeparator />
|
|
27
|
-
<TextWithLabel label='Last Update' text={lastCommit.date} />
|
|
28
|
-
</div>
|
|
29
|
-
</BorderedBox>
|
|
30
65
|
)
|
|
31
66
|
}
|
|
@@ -5,8 +5,23 @@
|
|
|
5
5
|
@apply text-xl text-main-green font-semibold;
|
|
6
6
|
}
|
|
7
7
|
.header {
|
|
8
|
-
@apply flex items-center
|
|
8
|
+
@apply flex items-center justify-between mb-4;
|
|
9
|
+
}
|
|
10
|
+
.title {
|
|
11
|
+
@apply flex items-center gap-x-4;
|
|
9
12
|
}
|
|
10
13
|
.footer {
|
|
11
|
-
@apply flex items-center
|
|
14
|
+
@apply flex items-center;
|
|
15
|
+
}
|
|
16
|
+
.status {
|
|
17
|
+
@apply flex items-center;
|
|
18
|
+
}
|
|
19
|
+
.unavailable {
|
|
20
|
+
@apply opacity-30;
|
|
21
|
+
}
|
|
22
|
+
.icons {
|
|
23
|
+
@apply flex justify-between gap-x-2;
|
|
24
|
+
}
|
|
25
|
+
.icons > *:hover {
|
|
26
|
+
@apply cursor-pointer;
|
|
12
27
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
4
|
+
import { faCircle } from '@fortawesome/free-solid-svg-icons'
|
|
5
|
+
export default function Status (props) {
|
|
6
|
+
const { color, status } = props
|
|
7
|
+
|
|
8
|
+
function getColorClass (color) {
|
|
9
|
+
switch (color) {
|
|
10
|
+
case 'green':
|
|
11
|
+
return 'text-main-green'
|
|
12
|
+
case 'red':
|
|
13
|
+
return 'text-error-red'
|
|
14
|
+
case 'white':
|
|
15
|
+
default:
|
|
16
|
+
return 'text-white'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const colorClass = getColorClass(color)
|
|
20
|
+
return (
|
|
21
|
+
<div className={colorClass}>
|
|
22
|
+
<FontAwesomeIcon icon={faCircle} size='2xs' className={`text-${colorClass} mr-2`} />
|
|
23
|
+
{status}
|
|
24
|
+
</div>
|
|
25
|
+
)
|
|
26
|
+
}
|
package/src/lib/utils.js
CHANGED
|
@@ -5,7 +5,10 @@ export default {
|
|
|
5
5
|
component: BorderedBox,
|
|
6
6
|
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
|
7
7
|
argTypes: {
|
|
8
|
-
color: {
|
|
8
|
+
color: {
|
|
9
|
+
options: ['green', 'red', 'white'],
|
|
10
|
+
control: { type: ' radio' }
|
|
11
|
+
}
|
|
9
12
|
}
|
|
10
13
|
}
|
|
11
14
|
|
|
@@ -13,7 +16,7 @@ export default {
|
|
|
13
16
|
const Template = (args) => <BorderedBox {...args}>Hello Platformatic</BorderedBox>
|
|
14
17
|
|
|
15
18
|
export const Green = Template.bind({})
|
|
16
|
-
|
|
19
|
+
|
|
17
20
|
Green.args = {
|
|
18
21
|
color: 'green'
|
|
19
22
|
}
|
|
@@ -22,3 +25,9 @@ export const Red = Template.bind({})
|
|
|
22
25
|
Red.args = {
|
|
23
26
|
color: 'red'
|
|
24
27
|
}
|
|
28
|
+
|
|
29
|
+
export const White = Template.bind({})
|
|
30
|
+
|
|
31
|
+
White.args = {
|
|
32
|
+
color: 'white'
|
|
33
|
+
}
|
package/src/stories/Button.jsx
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import PropTypes from 'prop-types'
|
|
3
|
-
import './button.css'
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import './button.css'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Primary UI component for user interaction
|
|
7
7
|
*/
|
|
8
8
|
export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
|
|
9
|
-
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary'
|
|
9
|
+
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary'
|
|
10
10
|
return (
|
|
11
11
|
<button
|
|
12
|
-
type=
|
|
12
|
+
type='button'
|
|
13
13
|
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
|
|
14
14
|
style={backgroundColor && { backgroundColor }}
|
|
15
15
|
{...props}
|
|
16
16
|
>
|
|
17
17
|
{label}
|
|
18
18
|
</button>
|
|
19
|
-
)
|
|
20
|
-
}
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
21
|
|
|
22
22
|
Button.propTypes = {
|
|
23
23
|
/**
|
|
@@ -39,12 +39,12 @@ Button.propTypes = {
|
|
|
39
39
|
/**
|
|
40
40
|
* Optional click handler
|
|
41
41
|
*/
|
|
42
|
-
onClick: PropTypes.func
|
|
43
|
-
}
|
|
42
|
+
onClick: PropTypes.func
|
|
43
|
+
}
|
|
44
44
|
|
|
45
45
|
Button.defaultProps = {
|
|
46
46
|
backgroundColor: null,
|
|
47
47
|
primary: false,
|
|
48
48
|
size: 'medium',
|
|
49
|
-
onClick: undefined
|
|
50
|
-
}
|
|
49
|
+
onClick: undefined
|
|
50
|
+
}
|
|
@@ -9,7 +9,7 @@ export default {
|
|
|
9
9
|
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
|
|
10
10
|
argTypes: {
|
|
11
11
|
backgroundColor: { control: 'color' }
|
|
12
|
-
}
|
|
12
|
+
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
|
|
@@ -20,21 +20,21 @@ export const Primary = Template.bind({})
|
|
|
20
20
|
Primary.args = {
|
|
21
21
|
primary: true,
|
|
22
22
|
label: 'Button'
|
|
23
|
-
}
|
|
23
|
+
}
|
|
24
24
|
|
|
25
25
|
export const Secondary = Template.bind({})
|
|
26
26
|
Secondary.args = {
|
|
27
27
|
label: 'Button'
|
|
28
|
-
}
|
|
28
|
+
}
|
|
29
29
|
|
|
30
30
|
export const Large = Template.bind({})
|
|
31
31
|
Large.args = {
|
|
32
32
|
size: 'large',
|
|
33
33
|
label: 'Button'
|
|
34
|
-
}
|
|
34
|
+
}
|
|
35
35
|
|
|
36
36
|
export const Small = Template.bind({})
|
|
37
37
|
Small.args = {
|
|
38
38
|
size: 'small',
|
|
39
39
|
label: 'Button'
|
|
40
|
-
}
|
|
40
|
+
}
|
|
@@ -4,14 +4,13 @@ export default {
|
|
|
4
4
|
title: 'Platformatic/PullRequest',
|
|
5
5
|
component: PullRequest,
|
|
6
6
|
argTypes: {
|
|
7
|
-
color: { control: 'color' }
|
|
8
7
|
}
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
const Template = (args) => <PullRequest {...args}
|
|
10
|
+
const Template = (args) => <PullRequest {...args} />
|
|
12
11
|
|
|
13
|
-
export const
|
|
14
|
-
|
|
12
|
+
export const Available = Template.bind({})
|
|
13
|
+
Available.args = {
|
|
15
14
|
id: '88',
|
|
16
15
|
title: 'doc: host => hostname, binded to 0.0.0.0 to be more container friendly',
|
|
17
16
|
url: 'http://example.com',
|
|
@@ -19,5 +18,32 @@ Standard.args = {
|
|
|
19
18
|
sha: 'bgb3ffe3',
|
|
20
19
|
author: 'Foobar',
|
|
21
20
|
date: '2022-10-11'
|
|
22
|
-
}
|
|
21
|
+
},
|
|
22
|
+
status: 'available'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const Running = Template.bind({})
|
|
26
|
+
Running.args = {
|
|
27
|
+
id: '88',
|
|
28
|
+
title: 'doc: host => hostname, binded to 0.0.0.0 to be more container friendly',
|
|
29
|
+
url: 'http://example.com',
|
|
30
|
+
lastCommit: {
|
|
31
|
+
sha: 'bgb3ffe3',
|
|
32
|
+
author: 'Foobar',
|
|
33
|
+
date: '2022-10-11'
|
|
34
|
+
},
|
|
35
|
+
status: 'running'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const Unavailable = Template.bind({})
|
|
39
|
+
Unavailable.args = {
|
|
40
|
+
id: '88',
|
|
41
|
+
title: 'doc: host => hostname, binded to 0.0.0.0 to be more container friendly',
|
|
42
|
+
url: 'http://example.com',
|
|
43
|
+
lastCommit: {
|
|
44
|
+
sha: 'bgb3ffe3',
|
|
45
|
+
author: 'Foobar',
|
|
46
|
+
date: '2022-10-11'
|
|
47
|
+
},
|
|
48
|
+
status: 'unavailable'
|
|
23
49
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
import Status from '../components/Status'
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: 'Platformatic/Status',
|
|
6
|
+
component: Status,
|
|
7
|
+
argTypes: {}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const Template = (args) => <Status {...args} />
|
|
11
|
+
|
|
12
|
+
export const White = Template.bind({})
|
|
13
|
+
|
|
14
|
+
White.args = {
|
|
15
|
+
color: 'white',
|
|
16
|
+
status: 'available'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const Green = Template.bind({})
|
|
20
|
+
|
|
21
|
+
Green.args = {
|
|
22
|
+
color: 'green',
|
|
23
|
+
status: 'online'
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const Red = Template.bind({})
|
|
27
|
+
|
|
28
|
+
Red.args = {
|
|
29
|
+
color: 'red',
|
|
30
|
+
status: 'offline'
|
|
31
|
+
}
|
package/vitest.config.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="vitest" />
|
|
2
|
+
|
|
3
|
+
import { defineConfig } from 'vite'
|
|
4
|
+
import react from '@vitejs/plugin-react'
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [react()],
|
|
8
|
+
test: {
|
|
9
|
+
globals: true,
|
|
10
|
+
environment: 'jsdom',
|
|
11
|
+
exclude: ['node_modules']
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
})
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
4
|
-
import { faCircle } from '@fortawesome/free-solid-svg-icons'
|
|
5
|
-
export default function ApiStatus (props) {
|
|
6
|
-
const { online } = props
|
|
7
|
-
const colorClass = online ? 'text-main-green' : 'text-error-red'
|
|
8
|
-
return (
|
|
9
|
-
<div className={colorClass}>
|
|
10
|
-
<FontAwesomeIcon icon={faCircle} size='2xs' className={`text-${colorClass} mr-1`} />
|
|
11
|
-
{online && (
|
|
12
|
-
'Online'
|
|
13
|
-
)}
|
|
14
|
-
|
|
15
|
-
{!online && (
|
|
16
|
-
'Offline'
|
|
17
|
-
)}
|
|
18
|
-
</div>
|
|
19
|
-
)
|
|
20
|
-
}
|