@platformatic/ui-components 0.1.32 → 0.1.34
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/.github/workflows/ci.yml +26 -26
- package/.nvmrc +1 -1
- package/LICENSE +201 -201
- package/README.md +30 -26
- package/dist/main.css +35 -23
- package/fonts/Montserrat/README.txt +81 -81
- package/index.html +12 -12
- package/index.js +62 -58
- package/package.json +76 -76
- package/postcss.config.cjs +8 -8
- package/public/api-icon-closed.svg +6 -6
- package/public/api-icon.svg +9 -9
- package/src/App.jsx +12 -12
- package/src/components/BorderedBox.jsx +16 -16
- package/src/components/BorderedBox.module.css +2 -2
- package/src/components/BorderedText.jsx +8 -8
- package/src/components/BorderedText.module.css +2 -2
- package/src/components/Box.jsx +14 -14
- package/src/components/Box.module.css +7 -7
- package/src/components/Button.jsx +23 -23
- package/src/components/Button.module.css +68 -21
- package/src/components/ButtonFullRounded.jsx +17 -0
- package/src/components/ButtonFullRounded.module.css +28 -0
- package/src/components/Checkbox.jsx +11 -0
- package/src/components/Checkbox.module.css +18 -0
- package/src/components/Common.module.css +7 -7
- package/src/components/DetailedMetric.jsx +32 -32
- package/src/components/DetailedMetric.module.css +2 -2
- package/src/components/DropDown.jsx +35 -35
- package/src/components/DropDown.module.css +22 -22
- package/src/components/FollowUs.jsx +35 -35
- package/src/components/FollowUs.module.css +11 -11
- package/src/components/GHLoginButton.jsx +14 -14
- package/src/components/HorizontalSeparator.jsx +10 -5
- package/src/components/HorizontalSeparator.module.css +23 -0
- package/src/components/Input.jsx +11 -11
- package/src/components/Input.module.css +7 -7
- package/src/components/List.jsx +20 -20
- package/src/components/List.module.css +11 -11
- package/src/components/ListElement.jsx +23 -23
- package/src/components/ListElement.module.css +23 -23
- package/src/components/Loadable.jsx +34 -34
- package/src/components/Loadable.module.css +13 -13
- package/src/components/LoginButton.jsx +17 -17
- package/src/components/LoginButton.module.css +7 -7
- package/src/components/LoginButton.test.jsx +25 -25
- package/src/components/Logo.jsx +58 -58
- package/src/components/Main.jsx +33 -33
- package/src/components/MetricValue.jsx +15 -15
- package/src/components/MetricValue.module.css +7 -7
- package/src/components/Modal.jsx +61 -29
- package/src/components/Modal.module.css +37 -25
- package/src/components/Playground.jsx +9 -9
- package/src/components/SearchBar.jsx +63 -63
- package/src/components/SearchBar.module.css +20 -20
- package/src/components/SimpleMetric.jsx +32 -32
- package/src/components/SimpleMetric.module.css +6 -6
- package/src/components/Status.jsx +26 -26
- package/src/components/TabbedWindow.jsx +34 -34
- package/src/components/TabbedWindow.module.css +16 -16
- package/src/components/TextWithLabel.jsx +11 -11
- package/src/components/TextWithLabel.module.css +8 -8
- package/src/components/Versions.jsx +9 -9
- package/src/components/VerticalSeparator.jsx +5 -5
- package/src/components/icons/ApiEmptyIcon.jsx +107 -107
- package/src/components/icons/ApiIcon.jsx +29 -29
- package/src/components/icons/ApiIconClosed.jsx +19 -19
- package/src/components/icons/CloseModalGreenHoverIcon.jsx +37 -0
- package/src/components/icons/CloseModalGreenIcon.jsx +27 -0
- package/src/components/icons/CloseModalIcon.jsx +26 -26
- package/src/components/icons/PullRequestIcon.jsx +31 -31
- package/src/components/icons/index.js +11 -9
- package/src/components/layouts/Layout.jsx +11 -11
- package/src/components/layouts/TwoColumnsLayout.jsx +12 -12
- package/src/components/layouts/TwoColumnsLayout.module.css +9 -9
- package/src/hooks/useEscapeKey.js +20 -20
- package/src/lib/utils.js +23 -23
- package/src/main.jsx +9 -9
- package/src/stories/BorderedBox.stories.jsx +33 -33
- package/src/stories/BorderedText.stories.jsx +24 -24
- package/src/stories/Button.stories.jsx +124 -107
- package/src/stories/ButtonFullRounded.stories.jsx +61 -0
- package/src/stories/Checkbox.stories.jsx +27 -0
- package/src/stories/DetailedMetric.stories.jsx +33 -33
- package/src/stories/DropDown.stories.jsx +62 -62
- package/src/stories/FollowUs.stories.jsx +14 -14
- package/src/stories/GHLoginButton.stories.jsx +14 -14
- package/src/stories/HorizontalSeparator.stories.jsx +12 -12
- package/src/stories/Input.stories.jsx +15 -15
- package/src/stories/Introduction.stories.mdx +211 -211
- package/src/stories/List.stories.jsx +29 -29
- package/src/stories/ListElement.stories.jsx +15 -15
- package/src/stories/Loadable.stories.jsx +75 -75
- package/src/stories/LoginButton.stories.jsx +15 -15
- package/src/stories/Logo.stories.jsx +17 -17
- package/src/stories/Modal.stories.jsx +94 -65
- package/src/stories/SearchBar.stories.jsx +28 -28
- package/src/stories/SimpleMetric.stories.jsx +41 -41
- package/src/stories/Status.stories.jsx +31 -31
- package/src/stories/TextWithLabel.stories.jsx +25 -25
- package/src/stories/TwoColumnsLayout.stories.jsx +42 -42
- package/src/styles/main.css +15 -15
- package/tailwind.config.cjs +42 -37
- package/vite.config.js +6 -6
- package/vitest.config.js +14 -14
- package/dist/api-icon-closed.svg +0 -6
- package/dist/api-icon.svg +0 -9
- package/dist/assets/index.5ac5acb7.js +0 -797
- package/dist/assets/index.d3f5882c.css +0 -1
- package/dist/index.html +0 -14
- package/dist/vite.svg +0 -1
package/src/components/Modal.jsx
CHANGED
|
@@ -1,29 +1,61 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import useEscapeKey from '../hooks/useEscapeKey'
|
|
3
|
-
import CloseModalIcon from './icons/CloseModalIcon'
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import useEscapeKey from '../hooks/useEscapeKey'
|
|
3
|
+
import CloseModalIcon from './icons/CloseModalIcon'
|
|
4
|
+
import CloseModalGreenIcon from './icons/CloseModalGreenIcon'
|
|
5
|
+
import CloseModalGreenHoverIcon from './icons/CloseModalGreenHoverIcon'
|
|
6
|
+
import styles from './Modal.module.css'
|
|
7
|
+
export default function Modal (props) {
|
|
8
|
+
const { setIsOpen, title, layout = 'info' } = props
|
|
9
|
+
const [isHoverCloseModal, setIsHoverCloseModal] = useState(false)
|
|
10
|
+
useEscapeKey(() => setIsOpen(false))
|
|
11
|
+
|
|
12
|
+
let whichModal = <></>
|
|
13
|
+
switch (layout) {
|
|
14
|
+
case 'info':
|
|
15
|
+
whichModal = (
|
|
16
|
+
<>
|
|
17
|
+
<div className={styles.blur} onClick={() => setIsOpen(false)} />
|
|
18
|
+
<div className={`${styles.container} ${styles.centered}`}>
|
|
19
|
+
<div className={`${styles.modal} ${styles.modalInfo}`}>
|
|
20
|
+
<div className={styles.header}>
|
|
21
|
+
<div className={styles.title}>{title}</div>
|
|
22
|
+
<div className={styles.close} onClick={() => setIsOpen(false)}>
|
|
23
|
+
<CloseModalIcon />
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
<div>
|
|
27
|
+
{props.children}
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</>
|
|
32
|
+
)
|
|
33
|
+
break
|
|
34
|
+
case 'invite':
|
|
35
|
+
whichModal = (
|
|
36
|
+
<>
|
|
37
|
+
<div className={styles.blur} onClick={() => setIsOpen(false)} />
|
|
38
|
+
<div className={`${styles.container} ${styles.centered}`}>
|
|
39
|
+
<div className={`${styles.modal} ${styles.modalInvite}`}>
|
|
40
|
+
<div className={styles.headerInvite}>
|
|
41
|
+
<div
|
|
42
|
+
className={styles.close}
|
|
43
|
+
onClick={() => setIsOpen(false)}
|
|
44
|
+
onMouseEnter={() => setIsHoverCloseModal(true)}
|
|
45
|
+
onMouseLeave={() => setIsHoverCloseModal(false)}
|
|
46
|
+
>
|
|
47
|
+
{isHoverCloseModal ? <CloseModalGreenHoverIcon /> : <CloseModalGreenIcon />}
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
<p className={styles.titleInvite}>{title}</p>
|
|
51
|
+
<div>{props.children}</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</>
|
|
55
|
+
)
|
|
56
|
+
break
|
|
57
|
+
default:
|
|
58
|
+
break
|
|
59
|
+
}
|
|
60
|
+
return whichModal
|
|
61
|
+
}
|
|
@@ -1,25 +1,37 @@
|
|
|
1
|
-
.blur {
|
|
2
|
-
@apply absolute top-[50%] left-[50%] z-0 w-[100vw] h-[100vh] translate-x-[-50%] translate-y-[-50%] z-[9999];
|
|
3
|
-
background-color: rgba(0, 0, 0, 0.75);
|
|
4
|
-
}
|
|
5
|
-
.container {
|
|
6
|
-
@apply z-[9999];
|
|
7
|
-
}
|
|
8
|
-
.centered {
|
|
9
|
-
@apply fixed top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]
|
|
10
|
-
}
|
|
11
|
-
.modal {
|
|
12
|
-
@apply
|
|
13
|
-
}
|
|
14
|
-
.
|
|
15
|
-
@apply
|
|
16
|
-
}
|
|
17
|
-
.
|
|
18
|
-
@apply
|
|
19
|
-
}
|
|
20
|
-
.
|
|
21
|
-
@apply
|
|
22
|
-
}
|
|
23
|
-
.
|
|
24
|
-
@apply
|
|
25
|
-
}
|
|
1
|
+
.blur {
|
|
2
|
+
@apply absolute top-[50%] left-[50%] z-0 w-[100vw] h-[100vh] translate-x-[-50%] translate-y-[-50%] z-[9999];
|
|
3
|
+
background-color: rgba(0, 0, 0, 0.75);
|
|
4
|
+
}
|
|
5
|
+
.container {
|
|
6
|
+
@apply z-[9999];
|
|
7
|
+
}
|
|
8
|
+
.centered {
|
|
9
|
+
@apply fixed top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]
|
|
10
|
+
}
|
|
11
|
+
.modal {
|
|
12
|
+
@apply p-4 rounded-md mx-auto my-auto min-w-[480px] max-h-[85vh] overflow-y-auto;
|
|
13
|
+
}
|
|
14
|
+
.modalInfo {
|
|
15
|
+
@apply bg-light-blue;
|
|
16
|
+
}
|
|
17
|
+
.modalInvite {
|
|
18
|
+
@apply bg-main-dark-blue border-light-green border shadow-wrap shadow-main-green max-w-[432px] max-h-[300px];
|
|
19
|
+
}
|
|
20
|
+
.header {
|
|
21
|
+
@apply flex justify-between items-center;
|
|
22
|
+
}
|
|
23
|
+
.headerInvite {
|
|
24
|
+
@apply flex justify-end;
|
|
25
|
+
}
|
|
26
|
+
.close {
|
|
27
|
+
@apply hover:cursor-pointer;
|
|
28
|
+
}
|
|
29
|
+
.hr {
|
|
30
|
+
@apply text-[#00283D] my-2 opacity-20;
|
|
31
|
+
}
|
|
32
|
+
.title {
|
|
33
|
+
@apply font-bold text-lg;
|
|
34
|
+
}
|
|
35
|
+
.titleInvite {
|
|
36
|
+
@apply font-bold text-lg text-main-green text-center;
|
|
37
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import BorderedBox from './BorderedBox'
|
|
4
|
-
|
|
5
|
-
export default function Playground () {
|
|
6
|
-
return (
|
|
7
|
-
<BorderedBox color='green'>Playground</BorderedBox>
|
|
8
|
-
)
|
|
9
|
-
}
|
|
1
|
+
'use strict'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import BorderedBox from './BorderedBox'
|
|
4
|
+
|
|
5
|
+
export default function Playground () {
|
|
6
|
+
return (
|
|
7
|
+
<BorderedBox color='green'>Playground</BorderedBox>
|
|
8
|
+
)
|
|
9
|
+
}
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
import React, { useRef, useState } from 'react'
|
|
3
|
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
4
|
-
import { faSearch } from '@fortawesome/free-solid-svg-icons'
|
|
5
|
-
import styles from './SearchBar.module.css'
|
|
6
|
-
import commonStyles from './Common.module.css'
|
|
7
|
-
export default function SearchBar (props) {
|
|
8
|
-
const inputRef = useRef()
|
|
9
|
-
const [wrapperClassName, setWrapperClassName] = useState(normalClassName())
|
|
10
|
-
const [isOnFocus, setIsOnFocus] = useState(false)
|
|
11
|
-
const { onSubmit, onChange, title } = props
|
|
12
|
-
|
|
13
|
-
function handleSearch () {
|
|
14
|
-
if (onSubmit) {
|
|
15
|
-
const value = inputRef.current.value
|
|
16
|
-
return onSubmit(value)
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function handleChange () {
|
|
21
|
-
if (onChange) {
|
|
22
|
-
const value = inputRef.current.value
|
|
23
|
-
return onChange(value)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function onFocus () {
|
|
28
|
-
if (!isOnFocus) {
|
|
29
|
-
setIsOnFocus(true)
|
|
30
|
-
setWrapperClassName(onFocusClassName())
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function onBlur () {
|
|
35
|
-
setIsOnFocus(false)
|
|
36
|
-
setWrapperClassName(normalClassName())
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function onFocusClassName () {
|
|
40
|
-
return `${styles.input} ${commonStyles.padded} ${styles.onFocus}`
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function normalClassName () {
|
|
44
|
-
return `${styles.input} ${commonStyles.padded} ${styles.onBlur}`
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function iconClassName () {
|
|
48
|
-
return isOnFocus ? 'text-main-green' : 'text-white'
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<div>
|
|
53
|
-
{title && <h1 className={styles.title}>{title}</h1>}
|
|
54
|
-
<div className={wrapperClassName}>
|
|
55
|
-
<input type='text' placeholder='Search' className='grow' ref={inputRef} onChange={handleChange} onFocus={onFocus} onBlur={onBlur} />
|
|
56
|
-
<button onClick={handleSearch} onFocus={onFocus} onBlur={onBlur}>
|
|
57
|
-
<FontAwesomeIcon className={iconClassName()} icon={faSearch} />
|
|
58
|
-
</button>
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
|
-
|
|
62
|
-
)
|
|
63
|
-
}
|
|
1
|
+
'use strict'
|
|
2
|
+
import React, { useRef, useState } from 'react'
|
|
3
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
4
|
+
import { faSearch } from '@fortawesome/free-solid-svg-icons'
|
|
5
|
+
import styles from './SearchBar.module.css'
|
|
6
|
+
import commonStyles from './Common.module.css'
|
|
7
|
+
export default function SearchBar (props) {
|
|
8
|
+
const inputRef = useRef()
|
|
9
|
+
const [wrapperClassName, setWrapperClassName] = useState(normalClassName())
|
|
10
|
+
const [isOnFocus, setIsOnFocus] = useState(false)
|
|
11
|
+
const { onSubmit, onChange, title } = props
|
|
12
|
+
|
|
13
|
+
function handleSearch () {
|
|
14
|
+
if (onSubmit) {
|
|
15
|
+
const value = inputRef.current.value
|
|
16
|
+
return onSubmit(value)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function handleChange () {
|
|
21
|
+
if (onChange) {
|
|
22
|
+
const value = inputRef.current.value
|
|
23
|
+
return onChange(value)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function onFocus () {
|
|
28
|
+
if (!isOnFocus) {
|
|
29
|
+
setIsOnFocus(true)
|
|
30
|
+
setWrapperClassName(onFocusClassName())
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function onBlur () {
|
|
35
|
+
setIsOnFocus(false)
|
|
36
|
+
setWrapperClassName(normalClassName())
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function onFocusClassName () {
|
|
40
|
+
return `${styles.input} ${commonStyles.padded} ${styles.onFocus}`
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function normalClassName () {
|
|
44
|
+
return `${styles.input} ${commonStyles.padded} ${styles.onBlur}`
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function iconClassName () {
|
|
48
|
+
return isOnFocus ? 'text-main-green' : 'text-white'
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<div>
|
|
53
|
+
{title && <h1 className={styles.title}>{title}</h1>}
|
|
54
|
+
<div className={wrapperClassName}>
|
|
55
|
+
<input type='text' placeholder='Search' className='grow' ref={inputRef} onChange={handleChange} onFocus={onFocus} onBlur={onBlur} />
|
|
56
|
+
<button onClick={handleSearch} onFocus={onFocus} onBlur={onBlur}>
|
|
57
|
+
<FontAwesomeIcon className={iconClassName()} icon={faSearch} />
|
|
58
|
+
</button>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
)
|
|
63
|
+
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
.input {
|
|
2
|
-
@apply flex justify-between w-full h-10 text-white border border-solid box-border rounded-md;
|
|
3
|
-
}
|
|
4
|
-
.onFocus {
|
|
5
|
-
@apply border-main-green;
|
|
6
|
-
}
|
|
7
|
-
.onBlur {
|
|
8
|
-
@apply border-white;
|
|
9
|
-
}
|
|
10
|
-
.fillGreen {
|
|
11
|
-
@apply fill-main-green;
|
|
12
|
-
}
|
|
13
|
-
.fillWhite {
|
|
14
|
-
@apply fill-white;
|
|
15
|
-
}
|
|
16
|
-
.input > input:focus {
|
|
17
|
-
@apply outline-none;
|
|
18
|
-
}
|
|
19
|
-
.title {
|
|
20
|
-
@apply font-semibold text-white text-3xl pb-4;
|
|
1
|
+
.input {
|
|
2
|
+
@apply flex justify-between w-full h-10 text-white border border-solid box-border rounded-md;
|
|
3
|
+
}
|
|
4
|
+
.onFocus {
|
|
5
|
+
@apply border-main-green;
|
|
6
|
+
}
|
|
7
|
+
.onBlur {
|
|
8
|
+
@apply border-white;
|
|
9
|
+
}
|
|
10
|
+
.fillGreen {
|
|
11
|
+
@apply fill-main-green;
|
|
12
|
+
}
|
|
13
|
+
.fillWhite {
|
|
14
|
+
@apply fill-white;
|
|
15
|
+
}
|
|
16
|
+
.input > input:focus {
|
|
17
|
+
@apply outline-none;
|
|
18
|
+
}
|
|
19
|
+
.title {
|
|
20
|
+
@apply font-semibold text-white text-3xl pb-4;
|
|
21
21
|
}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
import React from 'react'
|
|
4
|
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
5
|
-
// The icon that is in design is not in the free version of fontawesome
|
|
6
|
-
// Temporary using this one
|
|
7
|
-
import { faCircleExclamation } from '@fortawesome/free-solid-svg-icons'
|
|
8
|
-
import ReactTooltip from 'react-tooltip'
|
|
9
|
-
import BorderedBox from './BorderedBox'
|
|
10
|
-
import styles from './SimpleMetric.module.css'
|
|
11
|
-
import MetricValue from './MetricValue'
|
|
12
|
-
|
|
13
|
-
export default function SimpleMetric ({ title, pre, color, unit, value, tooltip, children }) {
|
|
14
|
-
return (
|
|
15
|
-
<>
|
|
16
|
-
<BorderedBox>
|
|
17
|
-
<div className={styles.header}>
|
|
18
|
-
<span className={styles.title}>{title}</span>
|
|
19
|
-
<FontAwesomeIcon
|
|
20
|
-
icon={faCircleExclamation}
|
|
21
|
-
data-tip={tooltip}
|
|
22
|
-
/>
|
|
23
|
-
</div>
|
|
24
|
-
<div>
|
|
25
|
-
<MetricValue pre={pre} color={color} unit={unit} value={value} />
|
|
26
|
-
{children}
|
|
27
|
-
</div>
|
|
28
|
-
</BorderedBox>
|
|
29
|
-
<ReactTooltip />
|
|
30
|
-
</>
|
|
31
|
-
)
|
|
32
|
-
}
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
|
5
|
+
// The icon that is in design is not in the free version of fontawesome
|
|
6
|
+
// Temporary using this one
|
|
7
|
+
import { faCircleExclamation } from '@fortawesome/free-solid-svg-icons'
|
|
8
|
+
import ReactTooltip from 'react-tooltip'
|
|
9
|
+
import BorderedBox from './BorderedBox'
|
|
10
|
+
import styles from './SimpleMetric.module.css'
|
|
11
|
+
import MetricValue from './MetricValue'
|
|
12
|
+
|
|
13
|
+
export default function SimpleMetric ({ title, pre, color, unit, value, tooltip, children }) {
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
<BorderedBox>
|
|
17
|
+
<div className={styles.header}>
|
|
18
|
+
<span className={styles.title}>{title}</span>
|
|
19
|
+
<FontAwesomeIcon
|
|
20
|
+
icon={faCircleExclamation}
|
|
21
|
+
data-tip={tooltip}
|
|
22
|
+
/>
|
|
23
|
+
</div>
|
|
24
|
+
<div>
|
|
25
|
+
<MetricValue pre={pre} color={color} unit={unit} value={value} />
|
|
26
|
+
{children}
|
|
27
|
+
</div>
|
|
28
|
+
</BorderedBox>
|
|
29
|
+
<ReactTooltip />
|
|
30
|
+
</>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
.header {
|
|
2
|
-
@apply flex justify-between items-center font-bold;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.title {
|
|
6
|
-
@apply text-xl;
|
|
1
|
+
.header {
|
|
2
|
+
@apply flex justify-between items-center font-bold;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.title {
|
|
6
|
+
@apply text-xl;
|
|
7
7
|
}
|
|
@@ -1,26 +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
|
-
}
|
|
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
|
+
}
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
import React, { useEffect, useState } from 'react'
|
|
3
|
-
import styles from './TabbedWindow.module.css'
|
|
4
|
-
|
|
5
|
-
export default function TabbedWindow (props) {
|
|
6
|
-
const [selected, setSelected] = useState(0)
|
|
7
|
-
const { tabs } = props
|
|
8
|
-
const headers = []
|
|
9
|
-
const components = []
|
|
10
|
-
tabs.forEach((tab) => {
|
|
11
|
-
headers.push(tab.label)
|
|
12
|
-
components.push(tab.component)
|
|
13
|
-
})
|
|
14
|
-
let currentComponent = components[selected]
|
|
15
|
-
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
currentComponent = components[selected]
|
|
18
|
-
}, [selected])
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<div className={styles['tabbed-container']}>
|
|
22
|
-
<div className={styles['tabs-header']}>
|
|
23
|
-
{headers.map((header, index) => {
|
|
24
|
-
return (
|
|
25
|
-
<span onClick={() => setSelected(index)} key={index} className={`${styles.tab} ${selected === index ? styles['selected-tab'] : ''}`}>
|
|
26
|
-
{header}
|
|
27
|
-
</span>
|
|
28
|
-
)
|
|
29
|
-
})}
|
|
30
|
-
</div>
|
|
31
|
-
<div className={styles['tabs-content']}>{currentComponent()}</div>
|
|
32
|
-
</div>
|
|
33
|
-
)
|
|
34
|
-
}
|
|
1
|
+
'use strict'
|
|
2
|
+
import React, { useEffect, useState } from 'react'
|
|
3
|
+
import styles from './TabbedWindow.module.css'
|
|
4
|
+
|
|
5
|
+
export default function TabbedWindow (props) {
|
|
6
|
+
const [selected, setSelected] = useState(0)
|
|
7
|
+
const { tabs } = props
|
|
8
|
+
const headers = []
|
|
9
|
+
const components = []
|
|
10
|
+
tabs.forEach((tab) => {
|
|
11
|
+
headers.push(tab.label)
|
|
12
|
+
components.push(tab.component)
|
|
13
|
+
})
|
|
14
|
+
let currentComponent = components[selected]
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
currentComponent = components[selected]
|
|
18
|
+
}, [selected])
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div className={styles['tabbed-container']}>
|
|
22
|
+
<div className={styles['tabs-header']}>
|
|
23
|
+
{headers.map((header, index) => {
|
|
24
|
+
return (
|
|
25
|
+
<span onClick={() => setSelected(index)} key={index} className={`${styles.tab} ${selected === index ? styles['selected-tab'] : ''}`}>
|
|
26
|
+
{header}
|
|
27
|
+
</span>
|
|
28
|
+
)
|
|
29
|
+
})}
|
|
30
|
+
</div>
|
|
31
|
+
<div className={styles['tabs-content']}>{currentComponent()}</div>
|
|
32
|
+
</div>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
.tabbed-container {
|
|
2
|
-
@apply bg-main-dark-blue;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.tabs-header {
|
|
6
|
-
@apply flex justify-start text-white uppercase hover:cursor-pointer mb-4 tracking-[.25rem] h-[2rem];
|
|
7
|
-
}
|
|
8
|
-
.tab {
|
|
9
|
-
@apply mx-8 min-w-[105px] text-center text-sm first:ml-0 last:mr-0;
|
|
10
|
-
}
|
|
11
|
-
.selected-tab {
|
|
12
|
-
@apply underline text-main-green underline-offset-8 font-bold;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.tabs-content {
|
|
16
|
-
@apply h-screen
|
|
1
|
+
.tabbed-container {
|
|
2
|
+
@apply bg-main-dark-blue;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.tabs-header {
|
|
6
|
+
@apply flex justify-start text-white uppercase hover:cursor-pointer mb-4 tracking-[.25rem] h-[2rem];
|
|
7
|
+
}
|
|
8
|
+
.tab {
|
|
9
|
+
@apply mx-8 min-w-[105px] text-center text-sm first:ml-0 last:mr-0;
|
|
10
|
+
}
|
|
11
|
+
.selected-tab {
|
|
12
|
+
@apply underline text-main-green underline-offset-8 font-bold;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.tabs-content {
|
|
16
|
+
@apply h-screen
|
|
17
17
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import styles from './TextWithLabel.module.css'
|
|
3
|
-
export default function TextWithLabel ({ label, text, children }) {
|
|
4
|
-
return (
|
|
5
|
-
<div className={styles.container}>
|
|
6
|
-
<span className={styles.label}>{label}:</span>
|
|
7
|
-
{text && <span className={styles.text}>{text}</span>}
|
|
8
|
-
{children && <span>{children}</span>}
|
|
9
|
-
</div>
|
|
10
|
-
)
|
|
11
|
-
}
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import styles from './TextWithLabel.module.css'
|
|
3
|
+
export default function TextWithLabel ({ label, text, children }) {
|
|
4
|
+
return (
|
|
5
|
+
<div className={styles.container}>
|
|
6
|
+
<span className={styles.label}>{label}:</span>
|
|
7
|
+
{text && <span className={styles.text}>{text}</span>}
|
|
8
|
+
{children && <span>{children}</span>}
|
|
9
|
+
</div>
|
|
10
|
+
)
|
|
11
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
.container {
|
|
2
|
-
@apply text-white
|
|
3
|
-
}
|
|
4
|
-
.label {
|
|
5
|
-
@apply font-thin mr-2;
|
|
6
|
-
}
|
|
7
|
-
.text {
|
|
8
|
-
@apply font-semibold;
|
|
1
|
+
.container {
|
|
2
|
+
@apply text-white
|
|
3
|
+
}
|
|
4
|
+
.label {
|
|
5
|
+
@apply font-thin mr-2;
|
|
6
|
+
}
|
|
7
|
+
.text {
|
|
8
|
+
@apply font-semibold;
|
|
9
9
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import BorderedBox from './BorderedBox'
|
|
4
|
-
|
|
5
|
-
export default function Versions () {
|
|
6
|
-
return (
|
|
7
|
-
<BorderedBox color='green'>Versions</BorderedBox>
|
|
8
|
-
)
|
|
9
|
-
}
|
|
1
|
+
'use strict'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import BorderedBox from './BorderedBox'
|
|
4
|
+
|
|
5
|
+
export default function Versions () {
|
|
6
|
+
return (
|
|
7
|
+
<BorderedBox color='green'>Versions</BorderedBox>
|
|
8
|
+
)
|
|
9
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
export default function VerticalSeparator () {
|
|
4
|
-
return <span className='text-dark-green m-3'> | </span>
|
|
5
|
-
}
|
|
1
|
+
'use strict'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
export default function VerticalSeparator () {
|
|
4
|
+
return <span className='text-dark-green m-3'> | </span>
|
|
5
|
+
}
|