@stack-spot/portal-components 2.26.0 → 2.27.0
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/CHANGELOG.md +621 -614
- package/dist/components/AnimatedHeight.d.ts +1 -1
- package/dist/components/AnimatedHeight.js +26 -26
- package/dist/components/AsyncContent.d.ts +1 -1
- package/dist/components/AsyncContent.js +1 -1
- package/dist/components/BannerWarning.d.ts +1 -1
- package/dist/components/BannerWarning.js +1 -1
- package/dist/components/Breadcrumb/index.d.ts +2 -2
- package/dist/components/Breadcrumb/index.js +1 -1
- package/dist/components/Breadcrumb/styled.js +31 -31
- package/dist/components/ButtonLoading.d.ts +1 -1
- package/dist/components/ButtonLoading.js +1 -1
- package/dist/components/ChatBot.d.ts +1 -1
- package/dist/components/ChatBot.js +1 -1
- package/dist/components/ContentValidateFilter.d.ts +1 -1
- package/dist/components/ContentValidateFilter.js +1 -1
- package/dist/components/FadingOverflow.d.ts +1 -1
- package/dist/components/FadingOverflow.js +69 -69
- package/dist/components/FileTreeView/More.d.ts +1 -1
- package/dist/components/FileTreeView/More.js +1 -1
- package/dist/components/FileTreeView/index.d.ts +1 -1
- package/dist/components/FileTreeView/index.js +1 -1
- package/dist/components/InfiniteScroll.d.ts +1 -1
- package/dist/components/InfiniteScroll.js +1 -1
- package/dist/components/InfoMaintenanceBanner.d.ts +1 -1
- package/dist/components/InfoMaintenanceBanner.js +2 -2
- package/dist/components/LazyMarkdown/BlockquoteMd.d.ts +1 -1
- package/dist/components/LazyMarkdown/BlockquoteMd.js +1 -1
- package/dist/components/LazyMarkdown/CodeViewer.d.ts +1 -1
- package/dist/components/LazyMarkdown/CodeViewer.js +76 -76
- package/dist/components/LazyMarkdown/Markdown.d.ts +1 -1
- package/dist/components/LazyMarkdown/Markdown.js +1 -1
- package/dist/components/LazyMarkdown/MarkdownButton.d.ts +1 -1
- package/dist/components/LazyMarkdown/MarkdownButton.js +1 -1
- package/dist/components/LazyMarkdown/Video.d.ts +1 -1
- package/dist/components/LazyMarkdown/Video.js +1 -1
- package/dist/components/LazyMarkdown/index.d.ts +1 -1
- package/dist/components/LazyMarkdown/index.js +1 -1
- package/dist/components/Placeholder.d.ts +3 -3
- package/dist/components/Placeholder.js +1 -1
- package/dist/components/ScrollView.js +16 -16
- package/dist/components/Select/BadgeItem.d.ts +1 -1
- package/dist/components/Select/BadgeItem.js +1 -1
- package/dist/components/Select/ClearInput.d.ts +1 -1
- package/dist/components/Select/ClearInput.js +1 -1
- package/dist/components/Select/CloseItem.d.ts +1 -1
- package/dist/components/Select/CloseItem.js +1 -1
- package/dist/components/Select/CreatableSelect.js +1 -1
- package/dist/components/Select/CustomMenu.d.ts +1 -1
- package/dist/components/Select/CustomMenu.js +1 -1
- package/dist/components/Select/LabelItem.d.ts +1 -1
- package/dist/components/Select/LabelItem.js +1 -1
- package/dist/components/Select/MultiValue.d.ts +1 -1
- package/dist/components/Select/MultiValue.js +1 -1
- package/dist/components/Select/SelectInfiniteScroll.d.ts +1 -1
- package/dist/components/Select/SelectInfiniteScroll.js +1 -1
- package/dist/components/Select/SelectSearch.d.ts +1 -1
- package/dist/components/Select/SelectSearch.js +1 -1
- package/dist/components/SelectionList.d.ts +1 -1
- package/dist/components/SelectionList.js +61 -61
- package/dist/components/StatusCircle.d.ts +1 -1
- package/dist/components/StatusCircle.js +6 -6
- package/dist/components/Stepper/Navigation.js +4 -4
- package/dist/components/Stepper/Step.js +3 -3
- package/dist/components/Stepper/Stepper.js +6 -6
- package/dist/components/Stepper/headers.js +22 -22
- package/dist/components/Table/HeaderItem.js +1 -1
- package/dist/components/Table/SettingsVerticalMenu.d.ts +1 -1
- package/dist/components/Table/SettingsVerticalMenu.js +1 -1
- package/dist/components/Table/StyledLinkTable.d.ts +1 -1
- package/dist/components/Table/StyledLinkTable.js +5 -5
- package/dist/components/Table/TableData.d.ts +1 -1
- package/dist/components/Table/TableData.js +25 -25
- package/dist/components/TimelineSection.d.ts +1 -1
- package/dist/components/TimelineSection.js +14 -14
- package/dist/components/error/ErrorFeedback.d.ts +1 -1
- package/dist/components/error/ErrorFeedback.js +35 -35
- package/dist/components/error/NotFound.d.ts +1 -1
- package/dist/components/error/NotFound.js +1 -1
- package/dist/components/error/UnderMaintenance.d.ts +1 -1
- package/dist/components/error/UnderMaintenance.js +1 -1
- package/dist/components/form/Form/Form.d.ts +1 -1
- package/dist/components/form/Form/Form.js +1 -1
- package/dist/components/form/Form/FormGroup.d.ts +2 -2
- package/dist/components/form/Form/FormGroup.js +1 -1
- package/dist/components/form/SearchInput.d.ts +1 -1
- package/dist/components/form/SearchInput.js +1 -1
- package/dist/components/form/Select/CustomSelect.d.ts +1 -1
- package/dist/components/form/Select/CustomSelect.js +1 -1
- package/dist/components/form/Select/DetailedSelect.d.ts +1 -1
- package/dist/components/form/Select/DetailedSelect.js +1 -1
- package/dist/components/form/Select/Select.d.ts +1 -1
- package/dist/components/form/Select/Select.js +1 -1
- package/dist/components/form/Select/styled.js +161 -161
- package/dist/components/form/Select/utils.js +1 -1
- package/dist/components/notification/NotificationComponent.d.ts +1 -1
- package/dist/components/notification/NotificationComponent.js +54 -54
- package/dist/components/notification/NotificationItem.d.ts +1 -1
- package/dist/components/notification/NotificationItem.js +1 -1
- package/dist/components/notification/NotificationList.d.ts +1 -1
- package/dist/components/notification/NotificationList.js +43 -43
- package/dist/components/notification/NotificationPlaceholder.d.ts +1 -1
- package/dist/components/notification/NotificationPlaceholder.js +9 -9
- package/dist/components/notification/NotificationPlaceholder.js.map +1 -1
- package/dist/containers/NotificationsPage.d.ts +1 -1
- package/dist/containers/NotificationsPage.js +10 -10
- package/dist/context/anchor.d.ts +1 -1
- package/dist/context/anchor.js +1 -1
- package/dist/context/loading.d.ts +1 -1
- package/dist/context/loading.js +1 -1
- package/dist/context/notification/context.d.ts +1 -1
- package/dist/context/notification/context.js +1 -1
- package/dist/hooks/date.js +1 -1
- package/dist/hooks/service-now.js +28 -28
- package/dist/svg/AI.d.ts +1 -1
- package/dist/svg/AI.js +1 -1
- package/dist/svg/CS.d.ts +1 -1
- package/dist/svg/CS.js +1 -1
- package/dist/svg/EDP.d.ts +1 -1
- package/dist/svg/EDP.js +1 -1
- package/dist/svg/Forbidden.d.ts +1 -1
- package/dist/svg/Forbidden.js +1 -1
- package/dist/svg/GenericPlaceholder.d.ts +1 -1
- package/dist/svg/GenericPlaceholder.js +1 -1
- package/dist/svg/HUB.d.ts +1 -1
- package/dist/svg/HUB.js +1 -1
- package/dist/svg/Logo.d.ts +1 -1
- package/dist/svg/Logo.js +1 -1
- package/dist/svg/MiniLogo.d.ts +1 -1
- package/dist/svg/MiniLogo.js +1 -1
- package/dist/svg/NotFound.d.ts +1 -1
- package/dist/svg/NotFound.js +1 -1
- package/dist/svg/ServerError.d.ts +1 -1
- package/dist/svg/ServerError.js +1 -1
- package/dist/svg/Unauthenticated.d.ts +1 -1
- package/dist/svg/Unauthenticated.js +1 -1
- package/package.json +6 -6
- package/readme.md +66 -66
- package/src/components/AnimatedHeight.tsx +174 -174
- package/src/components/AsyncContent.tsx +78 -78
- package/src/components/BannerWarning.tsx +91 -91
- package/src/components/Breadcrumb/index.tsx +76 -76
- package/src/components/Breadcrumb/styled.ts +37 -37
- package/src/components/ButtonLoading.tsx +29 -29
- package/src/components/ChatBot.tsx +82 -82
- package/src/components/ContentValidateFilter.tsx +15 -15
- package/src/components/FadingOverflow.tsx +265 -265
- package/src/components/FileTreeView/More.tsx +114 -114
- package/src/components/FileTreeView/index.tsx +186 -186
- package/src/components/InfiniteScroll.tsx +24 -24
- package/src/components/InfoMaintenanceBanner.tsx +29 -29
- package/src/components/LazyMarkdown/BlockquoteMd.tsx +107 -107
- package/src/components/LazyMarkdown/CodeViewer.tsx +161 -161
- package/src/components/LazyMarkdown/Markdown.tsx +122 -122
- package/src/components/LazyMarkdown/MarkdownButton.tsx +24 -24
- package/src/components/LazyMarkdown/Video.tsx +13 -13
- package/src/components/LazyMarkdown/index.tsx +21 -21
- package/src/components/Placeholder.tsx +118 -118
- package/src/components/ScrollView.tsx +57 -57
- package/src/components/Select/BadgeItem.tsx +58 -58
- package/src/components/Select/ClearInput.tsx +24 -24
- package/src/components/Select/CloseItem.tsx +38 -38
- package/src/components/Select/CreatableSelect.tsx +155 -155
- package/src/components/Select/CustomMenu.tsx +16 -16
- package/src/components/Select/LabelItem.tsx +8 -8
- package/src/components/Select/MultiValue.tsx +49 -49
- package/src/components/Select/SelectInfiniteScroll.tsx +82 -82
- package/src/components/Select/SelectSearch.tsx +195 -195
- package/src/components/Select/index.tsx +7 -7
- package/src/components/Select/types.ts +8 -8
- package/src/components/SelectionList.tsx +427 -427
- package/src/components/StatusCircle.tsx +67 -67
- package/src/components/Stepper/Navigation.tsx +97 -97
- package/src/components/Stepper/Step.tsx +30 -30
- package/src/components/Stepper/Stepper.tsx +113 -113
- package/src/components/Stepper/headers.tsx +64 -64
- package/src/components/Stepper/index.ts +3 -3
- package/src/components/Table/HeaderItem.tsx +52 -52
- package/src/components/Table/SettingsVerticalMenu.tsx +50 -50
- package/src/components/Table/StyledLinkTable.tsx +22 -22
- package/src/components/Table/TableData.tsx +251 -251
- package/src/components/Table/index.tsx +2 -2
- package/src/components/TimelineSection.tsx +66 -66
- package/src/components/error/ErrorFeedback.tsx +217 -217
- package/src/components/error/NotFound.tsx +24 -24
- package/src/components/error/UnderMaintenance.tsx +30 -30
- package/src/components/error/index.ts +4 -4
- package/src/components/form/Form/Form.tsx +101 -101
- package/src/components/form/Form/FormGroup.tsx +221 -221
- package/src/components/form/Form/index.ts +2 -2
- package/src/components/form/SearchInput.tsx +69 -69
- package/src/components/form/Select/CustomSelect.tsx +232 -232
- package/src/components/form/Select/DetailedSelect.tsx +85 -85
- package/src/components/form/Select/Select.tsx +67 -67
- package/src/components/form/Select/index.ts +4 -4
- package/src/components/form/Select/styled.ts +165 -165
- package/src/components/form/Select/types.ts +112 -112
- package/src/components/form/Select/utils.tsx +28 -28
- package/src/components/notification/NotificationComponent.tsx +340 -340
- package/src/components/notification/NotificationItem.tsx +336 -336
- package/src/components/notification/NotificationList.tsx +178 -178
- package/src/components/notification/NotificationPlaceholder.tsx +43 -43
- package/src/components/notification/types.ts +72 -72
- package/src/containers/NotificationsPage.tsx +98 -98
- package/src/context/anchor.tsx +37 -37
- package/src/context/loading.tsx +36 -36
- package/src/context/notification/LazyNotificationList.ts +103 -103
- package/src/context/notification/NotificationController.ts +104 -104
- package/src/context/notification/context.tsx +23 -23
- package/src/context/notification/hooks.ts +98 -98
- package/src/context/notification/types.ts +65 -65
- package/src/hooks/date.ts +31 -31
- package/src/hooks/keyboard.tsx +128 -128
- package/src/hooks/manual-render.tsx +10 -10
- package/src/hooks/service-now.tsx +233 -233
- package/src/hooks/text.tsx +30 -30
- package/src/hooks/title.tsx +28 -28
- package/src/hooks/use-effect-once.tsx +43 -43
- package/src/index.ts +19 -19
- package/src/notifications.ts +11 -11
- package/src/svg/AI.tsx +41 -41
- package/src/svg/CS.tsx +48 -48
- package/src/svg/EDP.tsx +31 -31
- package/src/svg/Forbidden.tsx +22 -22
- package/src/svg/GenericPlaceholder.tsx +20 -20
- package/src/svg/HUB.tsx +48 -48
- package/src/svg/Logo.tsx +16 -16
- package/src/svg/MiniLogo.tsx +12 -12
- package/src/svg/NotFound.tsx +16 -16
- package/src/svg/ServerError.tsx +33 -33
- package/src/svg/Unauthenticated.tsx +16 -16
- package/src/svg/index.ts +11 -11
- package/src/utils/accessibility.ts +135 -135
- package/src/utils/cookie.ts +73 -73
- package/src/utils/promise.ts +5 -5
- package/src/utils/read-file.ts +16 -16
- package/tsconfig.json +10 -10
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
|
|
2
|
-
import { Button, Flex, IconBox, SxProp, Text } from '@citric/core'
|
|
3
|
-
import { ExclamationTriangle, TimesCircleFill } from '@citric/icons'
|
|
4
|
-
import { Alert } from '@citric/ui'
|
|
5
|
-
import { useState } from 'react'
|
|
6
|
-
import { getCookie, setCookie } from '../utils/cookie'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* A styled and dismissible alert box for showing important warnings for the user.
|
|
10
|
-
*
|
|
11
|
-
* This renders a yellow box with an exclamation icon. The content passed as parameter is placed on the right of the icon.
|
|
12
|
-
* @param props an object containing the content (children) to show inside the alert box.
|
|
13
|
-
*/
|
|
14
|
-
export const BannerWarning = ({ children, showCloseButton = true }:
|
|
15
|
-
{ children: React.ReactNode, sx?: SxProp, showCloseButton?: boolean }) => {
|
|
16
|
-
const bannerKey = 'bannerClosed'
|
|
17
|
-
|
|
18
|
-
const [isVisible, setIsVisible] = useState(() => {
|
|
19
|
-
if (typeof window !== 'undefined') {
|
|
20
|
-
const isBannerClosed = getCookie(bannerKey) === 'true'
|
|
21
|
-
return !isBannerClosed
|
|
22
|
-
}
|
|
23
|
-
return false
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
const handleClose = () => {
|
|
27
|
-
setCookie(bannerKey, 'true')
|
|
28
|
-
setIsVisible(false)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (!isVisible) {
|
|
32
|
-
return null
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<Flex sx={{ zIndex: '1', w: '12', mb: 7 }}>
|
|
37
|
-
<Alert
|
|
38
|
-
colorScheme="warning"
|
|
39
|
-
sx={{
|
|
40
|
-
position: 'relative',
|
|
41
|
-
px: 3,
|
|
42
|
-
py: 1,
|
|
43
|
-
alignItems: 'center',
|
|
44
|
-
display: 'flex',
|
|
45
|
-
justifyContent: 'space-between',
|
|
46
|
-
height: 'auto',
|
|
47
|
-
padding: `${showCloseButton ? '0.5rem' : '1rem'}`,
|
|
48
|
-
}}
|
|
49
|
-
>
|
|
50
|
-
<Flex
|
|
51
|
-
sx={{
|
|
52
|
-
alignItems: 'center',
|
|
53
|
-
flexWrap: 'nowrap',
|
|
54
|
-
}}
|
|
55
|
-
>
|
|
56
|
-
<IconBox
|
|
57
|
-
size="sm"
|
|
58
|
-
colorIcon="light.500"
|
|
59
|
-
>
|
|
60
|
-
<ExclamationTriangle />
|
|
61
|
-
</IconBox>
|
|
62
|
-
<Text
|
|
63
|
-
sx={{
|
|
64
|
-
ml: 5,
|
|
65
|
-
}}
|
|
66
|
-
appearance="body2"
|
|
67
|
-
colorScheme="warning.contrastText"
|
|
68
|
-
>
|
|
69
|
-
{children}
|
|
70
|
-
</Text>
|
|
71
|
-
</Flex>
|
|
72
|
-
|
|
73
|
-
{showCloseButton && <Button
|
|
74
|
-
appearance={'text'}
|
|
75
|
-
onClick={handleClose}
|
|
76
|
-
sx={{
|
|
77
|
-
p: 0,
|
|
78
|
-
ml: 2,
|
|
79
|
-
}}
|
|
80
|
-
>
|
|
81
|
-
<IconBox
|
|
82
|
-
size="lg"
|
|
83
|
-
colorIcon="light.500"
|
|
84
|
-
>
|
|
85
|
-
<TimesCircleFill />
|
|
86
|
-
</IconBox>
|
|
87
|
-
</Button>}
|
|
88
|
-
</Alert>
|
|
89
|
-
</Flex>
|
|
90
|
-
)
|
|
91
|
-
}
|
|
1
|
+
|
|
2
|
+
import { Button, Flex, IconBox, SxProp, Text } from '@citric/core'
|
|
3
|
+
import { ExclamationTriangle, TimesCircleFill } from '@citric/icons'
|
|
4
|
+
import { Alert } from '@citric/ui'
|
|
5
|
+
import { useState } from 'react'
|
|
6
|
+
import { getCookie, setCookie } from '../utils/cookie'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A styled and dismissible alert box for showing important warnings for the user.
|
|
10
|
+
*
|
|
11
|
+
* This renders a yellow box with an exclamation icon. The content passed as parameter is placed on the right of the icon.
|
|
12
|
+
* @param props an object containing the content (children) to show inside the alert box.
|
|
13
|
+
*/
|
|
14
|
+
export const BannerWarning = ({ children, showCloseButton = true }:
|
|
15
|
+
{ children: React.ReactNode, sx?: SxProp, showCloseButton?: boolean }) => {
|
|
16
|
+
const bannerKey = 'bannerClosed'
|
|
17
|
+
|
|
18
|
+
const [isVisible, setIsVisible] = useState(() => {
|
|
19
|
+
if (typeof window !== 'undefined') {
|
|
20
|
+
const isBannerClosed = getCookie(bannerKey) === 'true'
|
|
21
|
+
return !isBannerClosed
|
|
22
|
+
}
|
|
23
|
+
return false
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const handleClose = () => {
|
|
27
|
+
setCookie(bannerKey, 'true')
|
|
28
|
+
setIsVisible(false)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!isVisible) {
|
|
32
|
+
return null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Flex sx={{ zIndex: '1', w: '12', mb: 7 }}>
|
|
37
|
+
<Alert
|
|
38
|
+
colorScheme="warning"
|
|
39
|
+
sx={{
|
|
40
|
+
position: 'relative',
|
|
41
|
+
px: 3,
|
|
42
|
+
py: 1,
|
|
43
|
+
alignItems: 'center',
|
|
44
|
+
display: 'flex',
|
|
45
|
+
justifyContent: 'space-between',
|
|
46
|
+
height: 'auto',
|
|
47
|
+
padding: `${showCloseButton ? '0.5rem' : '1rem'}`,
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
<Flex
|
|
51
|
+
sx={{
|
|
52
|
+
alignItems: 'center',
|
|
53
|
+
flexWrap: 'nowrap',
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
<IconBox
|
|
57
|
+
size="sm"
|
|
58
|
+
colorIcon="light.500"
|
|
59
|
+
>
|
|
60
|
+
<ExclamationTriangle />
|
|
61
|
+
</IconBox>
|
|
62
|
+
<Text
|
|
63
|
+
sx={{
|
|
64
|
+
ml: 5,
|
|
65
|
+
}}
|
|
66
|
+
appearance="body2"
|
|
67
|
+
colorScheme="warning.contrastText"
|
|
68
|
+
>
|
|
69
|
+
{children}
|
|
70
|
+
</Text>
|
|
71
|
+
</Flex>
|
|
72
|
+
|
|
73
|
+
{showCloseButton && <Button
|
|
74
|
+
appearance={'text'}
|
|
75
|
+
onClick={handleClose}
|
|
76
|
+
sx={{
|
|
77
|
+
p: 0,
|
|
78
|
+
ml: 2,
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
<IconBox
|
|
82
|
+
size="lg"
|
|
83
|
+
colorIcon="light.500"
|
|
84
|
+
>
|
|
85
|
+
<TimesCircleFill />
|
|
86
|
+
</IconBox>
|
|
87
|
+
</Button>}
|
|
88
|
+
</Alert>
|
|
89
|
+
</Flex>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
import { Text } from '@citric/core'
|
|
2
|
-
import { Skeleton } from '@citric/ui'
|
|
3
|
-
import { last } from 'lodash'
|
|
4
|
-
import { useEffect, useMemo } from 'react'
|
|
5
|
-
import { useAnchorTag } from '../../context/anchor'
|
|
6
|
-
import { titleEffect } from '../../hooks/title'
|
|
7
|
-
import { Box } from './styled'
|
|
8
|
-
|
|
9
|
-
export type AnchorComponent = (props: React.AnchorHTMLAttributes<HTMLAnchorElement>) => React.ReactElement
|
|
10
|
-
|
|
11
|
-
interface BreadcrumbItem {
|
|
12
|
-
/**
|
|
13
|
-
* A unique id for this link of the breadcrumb. If not provided, the label will be used.
|
|
14
|
-
*/
|
|
15
|
-
key?: string,
|
|
16
|
-
/**
|
|
17
|
-
* Label for this route in the breadcrumb.
|
|
18
|
-
*/
|
|
19
|
-
label: string,
|
|
20
|
-
/**
|
|
21
|
-
* If this route is accessible, the link to it.
|
|
22
|
-
*/
|
|
23
|
-
href?: string,
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface Props {
|
|
27
|
-
/**
|
|
28
|
-
* The items to show.
|
|
29
|
-
*/
|
|
30
|
-
items: BreadcrumbItem[],
|
|
31
|
-
/**
|
|
32
|
-
* When true, a loading feedback (skeleton) will show instead of the list.
|
|
33
|
-
*/
|
|
34
|
-
isLoading?: boolean,
|
|
35
|
-
/**
|
|
36
|
-
* If set to true, after mounted, as soon as loading is false, the page title will be prepended with `$name - `, where `$name` is the
|
|
37
|
-
* label of the last item in `items`.
|
|
38
|
-
*
|
|
39
|
-
* When unmounted, the title will go back to the previous value.
|
|
40
|
-
*
|
|
41
|
-
* @default false
|
|
42
|
-
*/
|
|
43
|
-
shouldUpdatePageTitle?: boolean,
|
|
44
|
-
/**
|
|
45
|
-
* Key of the current page. If an item has this key, it won't be rendered as a link and will be marked as active.
|
|
46
|
-
*/
|
|
47
|
-
currentPageKey?: string,
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface ItemProps extends Pick<Props, 'currentPageKey'> {
|
|
51
|
-
item: BreadcrumbItem,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const BreadcrumbItem = ({ item: { label, href, key }, currentPageKey }: ItemProps) => {
|
|
55
|
-
const text = <Text appearance="breadcrumb">{label}</Text>
|
|
56
|
-
const Link = useAnchorTag()
|
|
57
|
-
const shouldBeLink = href && currentPageKey != key
|
|
58
|
-
return <li>{shouldBeLink ? <Link href={href}>{text}</Link> : text}</li>
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Builds a breadcrumb navigator based on the items passed in the properties.
|
|
63
|
-
*
|
|
64
|
-
* If the breadcrumb is obtained asynchronously, pass `isLoading = true` in order to show a loading feedback.
|
|
65
|
-
*/
|
|
66
|
-
export const BreadcrumbList = ({ items, isLoading, shouldUpdatePageTitle, currentPageKey }: Props) => {
|
|
67
|
-
const listItems = useMemo(
|
|
68
|
-
() => items.map(item => <BreadcrumbItem key={item.key || item.label} item={item} currentPageKey={currentPageKey} />),
|
|
69
|
-
[items],
|
|
70
|
-
)
|
|
71
|
-
useEffect(() => {
|
|
72
|
-
const title = last(items)?.label
|
|
73
|
-
if (shouldUpdatePageTitle && title && !isLoading) return titleEffect(title)
|
|
74
|
-
}, [items, isLoading])
|
|
75
|
-
return <Box>{isLoading ? <Skeleton height="21px" /> : <ul>{listItems}</ul>}</Box>
|
|
76
|
-
}
|
|
1
|
+
import { Text } from '@citric/core'
|
|
2
|
+
import { Skeleton } from '@citric/ui'
|
|
3
|
+
import { last } from 'lodash'
|
|
4
|
+
import { useEffect, useMemo } from 'react'
|
|
5
|
+
import { useAnchorTag } from '../../context/anchor'
|
|
6
|
+
import { titleEffect } from '../../hooks/title'
|
|
7
|
+
import { Box } from './styled'
|
|
8
|
+
|
|
9
|
+
export type AnchorComponent = (props: React.AnchorHTMLAttributes<HTMLAnchorElement>) => React.ReactElement
|
|
10
|
+
|
|
11
|
+
interface BreadcrumbItem {
|
|
12
|
+
/**
|
|
13
|
+
* A unique id for this link of the breadcrumb. If not provided, the label will be used.
|
|
14
|
+
*/
|
|
15
|
+
key?: string,
|
|
16
|
+
/**
|
|
17
|
+
* Label for this route in the breadcrumb.
|
|
18
|
+
*/
|
|
19
|
+
label: string,
|
|
20
|
+
/**
|
|
21
|
+
* If this route is accessible, the link to it.
|
|
22
|
+
*/
|
|
23
|
+
href?: string,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface Props {
|
|
27
|
+
/**
|
|
28
|
+
* The items to show.
|
|
29
|
+
*/
|
|
30
|
+
items: BreadcrumbItem[],
|
|
31
|
+
/**
|
|
32
|
+
* When true, a loading feedback (skeleton) will show instead of the list.
|
|
33
|
+
*/
|
|
34
|
+
isLoading?: boolean,
|
|
35
|
+
/**
|
|
36
|
+
* If set to true, after mounted, as soon as loading is false, the page title will be prepended with `$name - `, where `$name` is the
|
|
37
|
+
* label of the last item in `items`.
|
|
38
|
+
*
|
|
39
|
+
* When unmounted, the title will go back to the previous value.
|
|
40
|
+
*
|
|
41
|
+
* @default false
|
|
42
|
+
*/
|
|
43
|
+
shouldUpdatePageTitle?: boolean,
|
|
44
|
+
/**
|
|
45
|
+
* Key of the current page. If an item has this key, it won't be rendered as a link and will be marked as active.
|
|
46
|
+
*/
|
|
47
|
+
currentPageKey?: string,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface ItemProps extends Pick<Props, 'currentPageKey'> {
|
|
51
|
+
item: BreadcrumbItem,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const BreadcrumbItem = ({ item: { label, href, key }, currentPageKey }: ItemProps) => {
|
|
55
|
+
const text = <Text appearance="breadcrumb">{label}</Text>
|
|
56
|
+
const Link = useAnchorTag()
|
|
57
|
+
const shouldBeLink = href && currentPageKey != key
|
|
58
|
+
return <li>{shouldBeLink ? <Link href={href}>{text}</Link> : text}</li>
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Builds a breadcrumb navigator based on the items passed in the properties.
|
|
63
|
+
*
|
|
64
|
+
* If the breadcrumb is obtained asynchronously, pass `isLoading = true` in order to show a loading feedback.
|
|
65
|
+
*/
|
|
66
|
+
export const BreadcrumbList = ({ items, isLoading, shouldUpdatePageTitle, currentPageKey }: Props) => {
|
|
67
|
+
const listItems = useMemo(
|
|
68
|
+
() => items.map(item => <BreadcrumbItem key={item.key || item.label} item={item} currentPageKey={currentPageKey} />),
|
|
69
|
+
[items],
|
|
70
|
+
)
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const title = last(items)?.label
|
|
73
|
+
if (shouldUpdatePageTitle && title && !isLoading) return titleEffect(title)
|
|
74
|
+
}, [items, isLoading])
|
|
75
|
+
return <Box>{isLoading ? <Skeleton height="21px" /> : <ul>{listItems}</ul>}</Box>
|
|
76
|
+
}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import { getFontAppearance } from '@citric/core/dist/utils/theme'
|
|
2
|
-
import { theme } from '@stack-spot/portal-theme'
|
|
3
|
-
import { styled } from 'styled-components'
|
|
4
|
-
|
|
5
|
-
// the type below should be inferred, but a bug in TS+PNPM prevents it: https://github.com/microsoft/TypeScript/issues/42873
|
|
6
|
-
export const Box: React.FC<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>> = styled.nav`
|
|
7
|
-
margin-bottom: 24px;
|
|
8
|
-
|
|
9
|
-
ul {
|
|
10
|
-
display: flex;
|
|
11
|
-
flex-direction: row;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
li {
|
|
15
|
-
display: flex;
|
|
16
|
-
flex-direction: row;
|
|
17
|
-
|
|
18
|
-
&:before {
|
|
19
|
-
content: '/';
|
|
20
|
-
font: ${({ theme }) => getFontAppearance(theme as any, 'breadcrumb') as any};
|
|
21
|
-
margin: 0 10px;
|
|
22
|
-
color: ${theme.color.light['700']};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
&:first-child:before {
|
|
26
|
-
content: none;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
a {
|
|
31
|
-
color: ${theme.color.light['700']};
|
|
32
|
-
&:hover {
|
|
33
|
-
text-decoration: underline;
|
|
34
|
-
color: ${theme.color.light.contrastText};
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
`
|
|
1
|
+
import { getFontAppearance } from '@citric/core/dist/utils/theme'
|
|
2
|
+
import { theme } from '@stack-spot/portal-theme'
|
|
3
|
+
import { styled } from 'styled-components'
|
|
4
|
+
|
|
5
|
+
// the type below should be inferred, but a bug in TS+PNPM prevents it: https://github.com/microsoft/TypeScript/issues/42873
|
|
6
|
+
export const Box: React.FC<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>> = styled.nav`
|
|
7
|
+
margin-bottom: 24px;
|
|
8
|
+
|
|
9
|
+
ul {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: row;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
li {
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-direction: row;
|
|
17
|
+
|
|
18
|
+
&:before {
|
|
19
|
+
content: '/';
|
|
20
|
+
font: ${({ theme }) => getFontAppearance(theme as any, 'breadcrumb') as any};
|
|
21
|
+
margin: 0 10px;
|
|
22
|
+
color: ${theme.color.light['700']};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
&:first-child:before {
|
|
26
|
+
content: none;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
a {
|
|
31
|
+
color: ${theme.color.light['700']};
|
|
32
|
+
&:hover {
|
|
33
|
+
text-decoration: underline;
|
|
34
|
+
color: ${theme.color.light.contrastText};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
`
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { Button, Text } from '@citric/core'
|
|
2
|
-
import { ButtonProps } from '@citric/core/dist/Button'
|
|
3
|
-
import { LoadingCircular } from '@citric/ui'
|
|
4
|
-
import { ReactNode } from 'react'
|
|
5
|
-
|
|
6
|
-
interface Props extends ButtonProps {
|
|
7
|
-
isLoading?: boolean,
|
|
8
|
-
loadingSize?: 'sm' | 'md' | 'lg',
|
|
9
|
-
children: ReactNode,
|
|
10
|
-
onClick?: () => void,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const ButtonLoading = ({ isLoading, loadingSize = 'sm', children, disabled, sx, ...props }: Props) => (
|
|
14
|
-
<Button
|
|
15
|
-
type="submit"
|
|
16
|
-
{...props}
|
|
17
|
-
disabled={isLoading || disabled}
|
|
18
|
-
sx={{ ...sx, position: 'relative' }}
|
|
19
|
-
>
|
|
20
|
-
<Text as="span" sx={{ visibility: isLoading ? 'hidden' : 'visible' }}>
|
|
21
|
-
{children}
|
|
22
|
-
</Text>
|
|
23
|
-
<LoadingCircular
|
|
24
|
-
colorScheme={props.colorScheme}
|
|
25
|
-
size={loadingSize}
|
|
26
|
-
sx={{ visibility: isLoading ? 'visible' : 'hidden', position: 'absolute' }}
|
|
27
|
-
/>
|
|
28
|
-
</Button>
|
|
29
|
-
)
|
|
1
|
+
import { Button, Text } from '@citric/core'
|
|
2
|
+
import { ButtonProps } from '@citric/core/dist/Button'
|
|
3
|
+
import { LoadingCircular } from '@citric/ui'
|
|
4
|
+
import { ReactNode } from 'react'
|
|
5
|
+
|
|
6
|
+
interface Props extends ButtonProps {
|
|
7
|
+
isLoading?: boolean,
|
|
8
|
+
loadingSize?: 'sm' | 'md' | 'lg',
|
|
9
|
+
children: ReactNode,
|
|
10
|
+
onClick?: () => void,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const ButtonLoading = ({ isLoading, loadingSize = 'sm', children, disabled, sx, ...props }: Props) => (
|
|
14
|
+
<Button
|
|
15
|
+
type="submit"
|
|
16
|
+
{...props}
|
|
17
|
+
disabled={isLoading || disabled}
|
|
18
|
+
sx={{ ...sx, position: 'relative' }}
|
|
19
|
+
>
|
|
20
|
+
<Text as="span" sx={{ visibility: isLoading ? 'hidden' : 'visible' }}>
|
|
21
|
+
{children}
|
|
22
|
+
</Text>
|
|
23
|
+
<LoadingCircular
|
|
24
|
+
colorScheme={props.colorScheme}
|
|
25
|
+
size={loadingSize}
|
|
26
|
+
sx={{ visibility: isLoading ? 'visible' : 'hidden', position: 'absolute' }}
|
|
27
|
+
/>
|
|
28
|
+
</Button>
|
|
29
|
+
)
|
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
import { Button, Flex, IconBox, Styles } from '@citric/core'
|
|
2
|
-
import { QuestionAnswer, Times } from '@citric/icons'
|
|
3
|
-
import { CHAT_BUTTON_ID, CHAT_BUTTON_WRAPPER_ID, getServiceNowLauncher, hideChatWindow, showChatWindow } from '../hooks/service-now'
|
|
4
|
-
|
|
5
|
-
const styles: Styles = {
|
|
6
|
-
content: {
|
|
7
|
-
position: 'fixed',
|
|
8
|
-
bottom: '80px',
|
|
9
|
-
right: '0',
|
|
10
|
-
visibility: 'visible',
|
|
11
|
-
'&.opened .times': {
|
|
12
|
-
display: 'block',
|
|
13
|
-
},
|
|
14
|
-
'&.opened .question': {
|
|
15
|
-
display: 'none',
|
|
16
|
-
},
|
|
17
|
-
'.times': {
|
|
18
|
-
display: 'none',
|
|
19
|
-
},
|
|
20
|
-
'.question': {
|
|
21
|
-
display: 'block',
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
button: {
|
|
25
|
-
position: 'fixed',
|
|
26
|
-
right: '15px',
|
|
27
|
-
width: '64px',
|
|
28
|
-
height: '64px',
|
|
29
|
-
borderRadius: '50%',
|
|
30
|
-
border: 'none',
|
|
31
|
-
opacity: '0',
|
|
32
|
-
'&.show': {
|
|
33
|
-
opacity: '1',
|
|
34
|
-
},
|
|
35
|
-
'&:hover, &:focus': {
|
|
36
|
-
background: 'primary.500',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
icon: {
|
|
40
|
-
position: 'absolute',
|
|
41
|
-
top: '50%',
|
|
42
|
-
left: '50%',
|
|
43
|
-
transform: 'translate(-50%, -50%)',
|
|
44
|
-
},
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* A button for opening or closing the service-now chat window.
|
|
49
|
-
*
|
|
50
|
-
* This is a circular orange button with a chat icon if the chat window is closed or a close icon if the chat window is open.
|
|
51
|
-
*/
|
|
52
|
-
export const ChatBot = () => {
|
|
53
|
-
const handleOpenChatBot = () => {
|
|
54
|
-
const chatIframe = getServiceNowLauncher()
|
|
55
|
-
if (chatIframe) {
|
|
56
|
-
const isVisible = chatIframe.classList.contains('show')
|
|
57
|
-
if (isVisible) {
|
|
58
|
-
hideChatWindow()
|
|
59
|
-
} else {
|
|
60
|
-
showChatWindow()
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
<Flex id={CHAT_BUTTON_WRAPPER_ID} sx={styles.content}>
|
|
67
|
-
<Button
|
|
68
|
-
onClick={handleOpenChatBot}
|
|
69
|
-
id={CHAT_BUTTON_ID}
|
|
70
|
-
sx={styles.button}
|
|
71
|
-
>
|
|
72
|
-
<IconBox
|
|
73
|
-
colorIcon="light.400"
|
|
74
|
-
sx={styles.icon}
|
|
75
|
-
size="lg">
|
|
76
|
-
<Times className="times" />
|
|
77
|
-
<QuestionAnswer className="question" />
|
|
78
|
-
</IconBox>
|
|
79
|
-
</Button>
|
|
80
|
-
</Flex>
|
|
81
|
-
)
|
|
82
|
-
}
|
|
1
|
+
import { Button, Flex, IconBox, Styles } from '@citric/core'
|
|
2
|
+
import { QuestionAnswer, Times } from '@citric/icons'
|
|
3
|
+
import { CHAT_BUTTON_ID, CHAT_BUTTON_WRAPPER_ID, getServiceNowLauncher, hideChatWindow, showChatWindow } from '../hooks/service-now'
|
|
4
|
+
|
|
5
|
+
const styles: Styles = {
|
|
6
|
+
content: {
|
|
7
|
+
position: 'fixed',
|
|
8
|
+
bottom: '80px',
|
|
9
|
+
right: '0',
|
|
10
|
+
visibility: 'visible',
|
|
11
|
+
'&.opened .times': {
|
|
12
|
+
display: 'block',
|
|
13
|
+
},
|
|
14
|
+
'&.opened .question': {
|
|
15
|
+
display: 'none',
|
|
16
|
+
},
|
|
17
|
+
'.times': {
|
|
18
|
+
display: 'none',
|
|
19
|
+
},
|
|
20
|
+
'.question': {
|
|
21
|
+
display: 'block',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
button: {
|
|
25
|
+
position: 'fixed',
|
|
26
|
+
right: '15px',
|
|
27
|
+
width: '64px',
|
|
28
|
+
height: '64px',
|
|
29
|
+
borderRadius: '50%',
|
|
30
|
+
border: 'none',
|
|
31
|
+
opacity: '0',
|
|
32
|
+
'&.show': {
|
|
33
|
+
opacity: '1',
|
|
34
|
+
},
|
|
35
|
+
'&:hover, &:focus': {
|
|
36
|
+
background: 'primary.500',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
icon: {
|
|
40
|
+
position: 'absolute',
|
|
41
|
+
top: '50%',
|
|
42
|
+
left: '50%',
|
|
43
|
+
transform: 'translate(-50%, -50%)',
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* A button for opening or closing the service-now chat window.
|
|
49
|
+
*
|
|
50
|
+
* This is a circular orange button with a chat icon if the chat window is closed or a close icon if the chat window is open.
|
|
51
|
+
*/
|
|
52
|
+
export const ChatBot = () => {
|
|
53
|
+
const handleOpenChatBot = () => {
|
|
54
|
+
const chatIframe = getServiceNowLauncher()
|
|
55
|
+
if (chatIframe) {
|
|
56
|
+
const isVisible = chatIframe.classList.contains('show')
|
|
57
|
+
if (isVisible) {
|
|
58
|
+
hideChatWindow()
|
|
59
|
+
} else {
|
|
60
|
+
showChatWindow()
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<Flex id={CHAT_BUTTON_WRAPPER_ID} sx={styles.content}>
|
|
67
|
+
<Button
|
|
68
|
+
onClick={handleOpenChatBot}
|
|
69
|
+
id={CHAT_BUTTON_ID}
|
|
70
|
+
sx={styles.button}
|
|
71
|
+
>
|
|
72
|
+
<IconBox
|
|
73
|
+
colorIcon="light.400"
|
|
74
|
+
sx={styles.icon}
|
|
75
|
+
size="lg">
|
|
76
|
+
<Times className="times" />
|
|
77
|
+
<QuestionAnswer className="question" />
|
|
78
|
+
</IconBox>
|
|
79
|
+
</Button>
|
|
80
|
+
</Flex>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { PlaceholderResourceEmptySearch } from './Placeholder'
|
|
2
|
-
|
|
3
|
-
export const ContentValidateFilter = ({
|
|
4
|
-
searchText,
|
|
5
|
-
listLength,
|
|
6
|
-
children,
|
|
7
|
-
}: {
|
|
8
|
-
searchText?: string,
|
|
9
|
-
listLength: number,
|
|
10
|
-
children: React.ReactNode,
|
|
11
|
-
}) => {
|
|
12
|
-
if (!listLength && searchText) return <PlaceholderResourceEmptySearch />
|
|
13
|
-
return <>{children}</>
|
|
14
|
-
}
|
|
15
|
-
|
|
1
|
+
import { PlaceholderResourceEmptySearch } from './Placeholder'
|
|
2
|
+
|
|
3
|
+
export const ContentValidateFilter = ({
|
|
4
|
+
searchText,
|
|
5
|
+
listLength,
|
|
6
|
+
children,
|
|
7
|
+
}: {
|
|
8
|
+
searchText?: string,
|
|
9
|
+
listLength: number,
|
|
10
|
+
children: React.ReactNode,
|
|
11
|
+
}) => {
|
|
12
|
+
if (!listLength && searchText) return <PlaceholderResourceEmptySearch />
|
|
13
|
+
return <>{children}</>
|
|
14
|
+
}
|
|
15
|
+
|