@stack-spot/portal-components 2.27.0 → 2.27.2

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.
Files changed (250) hide show
  1. package/CHANGELOG.md +635 -621
  2. package/dist/components/AnimatedHeight.d.ts +1 -1
  3. package/dist/components/AnimatedHeight.js +26 -26
  4. package/dist/components/AsyncContent.d.ts +1 -1
  5. package/dist/components/AsyncContent.js +1 -1
  6. package/dist/components/BannerWarning.d.ts +1 -1
  7. package/dist/components/BannerWarning.js +1 -1
  8. package/dist/components/Breadcrumb/index.d.ts +2 -2
  9. package/dist/components/Breadcrumb/index.js +1 -1
  10. package/dist/components/Breadcrumb/styled.js +31 -31
  11. package/dist/components/ButtonLoading.d.ts +1 -1
  12. package/dist/components/ButtonLoading.js +1 -1
  13. package/dist/components/ChatBot.d.ts +1 -1
  14. package/dist/components/ChatBot.js +1 -1
  15. package/dist/components/ContentValidateFilter.d.ts +1 -1
  16. package/dist/components/ContentValidateFilter.js +1 -1
  17. package/dist/components/FadingOverflow.d.ts +1 -1
  18. package/dist/components/FadingOverflow.js +69 -69
  19. package/dist/components/FileTreeView/More.d.ts +1 -1
  20. package/dist/components/FileTreeView/More.js +1 -1
  21. package/dist/components/FileTreeView/index.d.ts +1 -1
  22. package/dist/components/FileTreeView/index.js +1 -1
  23. package/dist/components/InfiniteScroll.d.ts +1 -1
  24. package/dist/components/InfiniteScroll.js +1 -1
  25. package/dist/components/InfoMaintenanceBanner.d.ts +1 -1
  26. package/dist/components/InfoMaintenanceBanner.js +2 -2
  27. package/dist/components/LazyMarkdown/BlockquoteMd.d.ts +1 -1
  28. package/dist/components/LazyMarkdown/BlockquoteMd.js +1 -1
  29. package/dist/components/LazyMarkdown/CodeViewer.d.ts +1 -1
  30. package/dist/components/LazyMarkdown/CodeViewer.js +76 -76
  31. package/dist/components/LazyMarkdown/Markdown.d.ts +1 -1
  32. package/dist/components/LazyMarkdown/Markdown.js +1 -1
  33. package/dist/components/LazyMarkdown/MarkdownButton.d.ts +1 -1
  34. package/dist/components/LazyMarkdown/MarkdownButton.js +1 -1
  35. package/dist/components/LazyMarkdown/Video.d.ts +1 -1
  36. package/dist/components/LazyMarkdown/Video.js +1 -1
  37. package/dist/components/LazyMarkdown/index.d.ts +1 -1
  38. package/dist/components/LazyMarkdown/index.js +1 -1
  39. package/dist/components/Placeholder.d.ts +7 -3
  40. package/dist/components/Placeholder.d.ts.map +1 -1
  41. package/dist/components/Placeholder.js +3 -3
  42. package/dist/components/Placeholder.js.map +1 -1
  43. package/dist/components/ScrollView.js +16 -16
  44. package/dist/components/Select/BadgeItem.d.ts +1 -1
  45. package/dist/components/Select/BadgeItem.js +1 -1
  46. package/dist/components/Select/ClearInput.d.ts +1 -1
  47. package/dist/components/Select/ClearInput.js +1 -1
  48. package/dist/components/Select/CloseItem.d.ts +1 -1
  49. package/dist/components/Select/CloseItem.js +1 -1
  50. package/dist/components/Select/CreatableSelect.js +1 -1
  51. package/dist/components/Select/CustomMenu.d.ts +1 -1
  52. package/dist/components/Select/CustomMenu.js +1 -1
  53. package/dist/components/Select/LabelItem.d.ts +1 -1
  54. package/dist/components/Select/LabelItem.js +1 -1
  55. package/dist/components/Select/MultiValue.d.ts +1 -1
  56. package/dist/components/Select/MultiValue.js +1 -1
  57. package/dist/components/Select/SelectInfiniteScroll.d.ts +1 -1
  58. package/dist/components/Select/SelectInfiniteScroll.js +1 -1
  59. package/dist/components/Select/SelectSearch.d.ts +1 -1
  60. package/dist/components/Select/SelectSearch.js +1 -1
  61. package/dist/components/SelectionList.d.ts +1 -1
  62. package/dist/components/SelectionList.js +61 -61
  63. package/dist/components/StatusCircle.d.ts +1 -1
  64. package/dist/components/StatusCircle.js +6 -6
  65. package/dist/components/Stepper/Navigation.js +4 -4
  66. package/dist/components/Stepper/Step.js +3 -3
  67. package/dist/components/Stepper/Stepper.js +6 -6
  68. package/dist/components/Stepper/headers.js +22 -22
  69. package/dist/components/Table/HeaderItem.js +1 -1
  70. package/dist/components/Table/SettingsVerticalMenu.d.ts +1 -1
  71. package/dist/components/Table/SettingsVerticalMenu.js +1 -1
  72. package/dist/components/Table/StyledLinkTable.d.ts +1 -1
  73. package/dist/components/Table/StyledLinkTable.js +5 -5
  74. package/dist/components/Table/TableData.d.ts +1 -1
  75. package/dist/components/Table/TableData.js +25 -25
  76. package/dist/components/TimelineSection.d.ts +1 -1
  77. package/dist/components/TimelineSection.js +14 -14
  78. package/dist/components/error/ErrorFeedback.d.ts +1 -1
  79. package/dist/components/error/ErrorFeedback.js +35 -35
  80. package/dist/components/error/NotFound.d.ts +1 -1
  81. package/dist/components/error/NotFound.js +1 -1
  82. package/dist/components/error/UnderMaintenance.d.ts +1 -1
  83. package/dist/components/error/UnderMaintenance.js +1 -1
  84. package/dist/components/form/Form/Form.d.ts +1 -1
  85. package/dist/components/form/Form/Form.js +1 -1
  86. package/dist/components/form/Form/FormGroup.d.ts +2 -2
  87. package/dist/components/form/Form/FormGroup.js +1 -1
  88. package/dist/components/form/SearchInput.d.ts +1 -1
  89. package/dist/components/form/SearchInput.js +1 -1
  90. package/dist/components/form/Select/CustomSelect.d.ts +1 -1
  91. package/dist/components/form/Select/CustomSelect.js +1 -1
  92. package/dist/components/form/Select/DetailedSelect.d.ts +1 -1
  93. package/dist/components/form/Select/DetailedSelect.js +1 -1
  94. package/dist/components/form/Select/Select.d.ts +1 -1
  95. package/dist/components/form/Select/Select.js +1 -1
  96. package/dist/components/form/Select/styled.js +161 -161
  97. package/dist/components/form/Select/utils.js +1 -1
  98. package/dist/components/notification/NotificationComponent.d.ts +1 -1
  99. package/dist/components/notification/NotificationComponent.js +54 -54
  100. package/dist/components/notification/NotificationItem.d.ts +1 -1
  101. package/dist/components/notification/NotificationItem.d.ts.map +1 -1
  102. package/dist/components/notification/NotificationItem.js +11 -5
  103. package/dist/components/notification/NotificationItem.js.map +1 -1
  104. package/dist/components/notification/NotificationList.d.ts +1 -1
  105. package/dist/components/notification/NotificationList.d.ts.map +1 -1
  106. package/dist/components/notification/NotificationList.js +44 -44
  107. package/dist/components/notification/NotificationList.js.map +1 -1
  108. package/dist/components/notification/NotificationPlaceholder.d.ts +1 -1
  109. package/dist/components/notification/NotificationPlaceholder.d.ts.map +1 -1
  110. package/dist/components/notification/NotificationPlaceholder.js +2 -2
  111. package/dist/components/notification/NotificationPlaceholder.js.map +1 -1
  112. package/dist/containers/NotificationsPage.d.ts +1 -1
  113. package/dist/containers/NotificationsPage.d.ts.map +1 -1
  114. package/dist/containers/NotificationsPage.js +24 -11
  115. package/dist/containers/NotificationsPage.js.map +1 -1
  116. package/dist/context/anchor.d.ts +1 -1
  117. package/dist/context/anchor.js +1 -1
  118. package/dist/context/loading.d.ts +1 -1
  119. package/dist/context/loading.js +1 -1
  120. package/dist/context/notification/context.d.ts +1 -1
  121. package/dist/context/notification/context.js +1 -1
  122. package/dist/context/notification/types.d.ts +1 -0
  123. package/dist/context/notification/types.d.ts.map +1 -1
  124. package/dist/hooks/date.js +1 -1
  125. package/dist/hooks/service-now.js +28 -28
  126. package/dist/svg/AI.d.ts +1 -1
  127. package/dist/svg/AI.js +1 -1
  128. package/dist/svg/CS.d.ts +1 -1
  129. package/dist/svg/CS.js +1 -1
  130. package/dist/svg/EDP.d.ts +1 -1
  131. package/dist/svg/EDP.js +1 -1
  132. package/dist/svg/Forbidden.d.ts +1 -1
  133. package/dist/svg/Forbidden.js +1 -1
  134. package/dist/svg/GenericPlaceholder.d.ts +4 -2
  135. package/dist/svg/GenericPlaceholder.d.ts.map +1 -1
  136. package/dist/svg/GenericPlaceholder.js +2 -2
  137. package/dist/svg/GenericPlaceholder.js.map +1 -1
  138. package/dist/svg/HUB.d.ts +1 -1
  139. package/dist/svg/HUB.js +1 -1
  140. package/dist/svg/Logo.d.ts +1 -1
  141. package/dist/svg/Logo.js +1 -1
  142. package/dist/svg/MiniLogo.d.ts +1 -1
  143. package/dist/svg/MiniLogo.js +1 -1
  144. package/dist/svg/NotFound.d.ts +1 -1
  145. package/dist/svg/NotFound.js +1 -1
  146. package/dist/svg/ServerError.d.ts +1 -1
  147. package/dist/svg/ServerError.js +1 -1
  148. package/dist/svg/Unauthenticated.d.ts +1 -1
  149. package/dist/svg/Unauthenticated.js +1 -1
  150. package/package.json +6 -6
  151. package/readme.md +66 -66
  152. package/src/components/AnimatedHeight.tsx +174 -174
  153. package/src/components/AsyncContent.tsx +78 -78
  154. package/src/components/BannerWarning.tsx +91 -91
  155. package/src/components/Breadcrumb/index.tsx +76 -76
  156. package/src/components/Breadcrumb/styled.ts +37 -37
  157. package/src/components/ButtonLoading.tsx +29 -29
  158. package/src/components/ChatBot.tsx +82 -82
  159. package/src/components/ContentValidateFilter.tsx +15 -15
  160. package/src/components/FadingOverflow.tsx +265 -265
  161. package/src/components/FileTreeView/More.tsx +114 -114
  162. package/src/components/FileTreeView/index.tsx +186 -186
  163. package/src/components/InfiniteScroll.tsx +24 -24
  164. package/src/components/InfoMaintenanceBanner.tsx +29 -29
  165. package/src/components/LazyMarkdown/BlockquoteMd.tsx +107 -107
  166. package/src/components/LazyMarkdown/CodeViewer.tsx +161 -161
  167. package/src/components/LazyMarkdown/Markdown.tsx +122 -122
  168. package/src/components/LazyMarkdown/MarkdownButton.tsx +24 -24
  169. package/src/components/LazyMarkdown/Video.tsx +13 -13
  170. package/src/components/LazyMarkdown/index.tsx +21 -21
  171. package/src/components/Placeholder.tsx +123 -118
  172. package/src/components/ScrollView.tsx +57 -57
  173. package/src/components/Select/BadgeItem.tsx +58 -58
  174. package/src/components/Select/ClearInput.tsx +24 -24
  175. package/src/components/Select/CloseItem.tsx +38 -38
  176. package/src/components/Select/CreatableSelect.tsx +155 -155
  177. package/src/components/Select/CustomMenu.tsx +16 -16
  178. package/src/components/Select/LabelItem.tsx +8 -8
  179. package/src/components/Select/MultiValue.tsx +49 -49
  180. package/src/components/Select/SelectInfiniteScroll.tsx +82 -82
  181. package/src/components/Select/SelectSearch.tsx +195 -195
  182. package/src/components/Select/index.tsx +7 -7
  183. package/src/components/Select/types.ts +8 -8
  184. package/src/components/SelectionList.tsx +427 -427
  185. package/src/components/StatusCircle.tsx +67 -67
  186. package/src/components/Stepper/Navigation.tsx +97 -97
  187. package/src/components/Stepper/Step.tsx +30 -30
  188. package/src/components/Stepper/Stepper.tsx +113 -113
  189. package/src/components/Stepper/headers.tsx +64 -64
  190. package/src/components/Stepper/index.ts +3 -3
  191. package/src/components/Table/HeaderItem.tsx +52 -52
  192. package/src/components/Table/SettingsVerticalMenu.tsx +50 -50
  193. package/src/components/Table/StyledLinkTable.tsx +22 -22
  194. package/src/components/Table/TableData.tsx +251 -251
  195. package/src/components/Table/index.tsx +2 -2
  196. package/src/components/TimelineSection.tsx +66 -66
  197. package/src/components/error/ErrorFeedback.tsx +217 -217
  198. package/src/components/error/NotFound.tsx +24 -24
  199. package/src/components/error/UnderMaintenance.tsx +30 -30
  200. package/src/components/error/index.ts +4 -4
  201. package/src/components/form/Form/Form.tsx +101 -101
  202. package/src/components/form/Form/FormGroup.tsx +221 -221
  203. package/src/components/form/Form/index.ts +2 -2
  204. package/src/components/form/SearchInput.tsx +69 -69
  205. package/src/components/form/Select/CustomSelect.tsx +232 -232
  206. package/src/components/form/Select/DetailedSelect.tsx +85 -85
  207. package/src/components/form/Select/Select.tsx +67 -67
  208. package/src/components/form/Select/index.ts +4 -4
  209. package/src/components/form/Select/styled.ts +165 -165
  210. package/src/components/form/Select/types.ts +112 -112
  211. package/src/components/form/Select/utils.tsx +28 -28
  212. package/src/components/notification/NotificationComponent.tsx +340 -340
  213. package/src/components/notification/NotificationItem.tsx +345 -336
  214. package/src/components/notification/NotificationList.tsx +179 -178
  215. package/src/components/notification/NotificationPlaceholder.tsx +44 -43
  216. package/src/components/notification/types.ts +72 -72
  217. package/src/containers/NotificationsPage.tsx +119 -98
  218. package/src/context/anchor.tsx +37 -37
  219. package/src/context/loading.tsx +36 -36
  220. package/src/context/notification/LazyNotificationList.ts +103 -103
  221. package/src/context/notification/NotificationController.ts +104 -104
  222. package/src/context/notification/context.tsx +23 -23
  223. package/src/context/notification/hooks.ts +98 -98
  224. package/src/context/notification/types.ts +66 -65
  225. package/src/hooks/date.ts +31 -31
  226. package/src/hooks/keyboard.tsx +128 -128
  227. package/src/hooks/manual-render.tsx +10 -10
  228. package/src/hooks/service-now.tsx +233 -233
  229. package/src/hooks/text.tsx +30 -30
  230. package/src/hooks/title.tsx +28 -28
  231. package/src/hooks/use-effect-once.tsx +43 -43
  232. package/src/index.ts +19 -19
  233. package/src/notifications.ts +11 -11
  234. package/src/svg/AI.tsx +41 -41
  235. package/src/svg/CS.tsx +48 -48
  236. package/src/svg/EDP.tsx +31 -31
  237. package/src/svg/Forbidden.tsx +22 -22
  238. package/src/svg/GenericPlaceholder.tsx +20 -20
  239. package/src/svg/HUB.tsx +48 -48
  240. package/src/svg/Logo.tsx +16 -16
  241. package/src/svg/MiniLogo.tsx +12 -12
  242. package/src/svg/NotFound.tsx +16 -16
  243. package/src/svg/ServerError.tsx +33 -33
  244. package/src/svg/Unauthenticated.tsx +16 -16
  245. package/src/svg/index.ts +11 -11
  246. package/src/utils/accessibility.ts +135 -135
  247. package/src/utils/cookie.ts +73 -73
  248. package/src/utils/promise.ts +5 -5
  249. package/src/utils/read-file.ts +16 -16
  250. package/tsconfig.json +10 -10
@@ -1,217 +1,217 @@
1
- import { Button, LinkBox, Text } from '@citric/core'
2
- import { listToClass, theme } from '@stack-spot/portal-theme'
3
- import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
4
- import { useState } from 'react'
5
- import { styled } from 'styled-components'
6
- import { Forbidden } from '../../svg/Forbidden'
7
- import { Logo } from '../../svg/Logo'
8
- import { NotFound } from '../../svg/NotFound'
9
- import { ServerError } from '../../svg/ServerError'
10
- import { Unauthenticated } from '../../svg/Unauthenticated'
11
-
12
- const imageStyle: React.CSSProperties = {
13
- width: '200px',
14
- height: '200px',
15
- }
16
-
17
- const imageMap: Record<number, React.ReactElement> = {
18
- 401: <Unauthenticated style={imageStyle} />,
19
- 403: <Forbidden style={imageStyle} />,
20
- 404: <NotFound style={imageStyle} />,
21
- }
22
-
23
- export interface ErrorDescription {
24
- /**
25
- * The HTTP Error code if this is a network error.
26
- */
27
- code?: number,
28
- /**
29
- * The error message. This is only visible if debug is true.
30
- */
31
- message?: string,
32
- /**
33
- * Whether or not the application is in debug mode.
34
- */
35
- debug?: boolean,
36
- /**
37
- * The title for this error. Overwrites anything preset by "code".
38
- */
39
- title?: string,
40
- /**
41
- * The error description. Overwrites anything preset by "code".
42
- */
43
- description?: string,
44
- /**
45
- * A help text to aid the user. Overwrites anything preset by "code".
46
- */
47
- help?: string,
48
- /**
49
- * A button so the user can take some action.
50
- */
51
- action?: { label: string, onClick: () => void },
52
- /**
53
- * The content for this error. Overwrites anything preset by "code", "description", "help" or "button".
54
- */
55
- body?: React.ReactNode,
56
- /**
57
- * The image for the error. Overwrites anything preset by "code".
58
- */
59
- image?: React.ReactElement,
60
- /**
61
- * Whether to show the feedback horizontally (row) or vertically (column).
62
- *
63
- * @default 'row'
64
- */
65
- direction?: 'row' | 'column',
66
- style?: React.CSSProperties,
67
- className?: string,
68
- }
69
-
70
- const FeedbackBox = styled.div`
71
- background-color: ${theme.color.light[400]};
72
- padding: 24px;
73
- .content {
74
- display: flex;
75
- justify-content: center;
76
- align-items: center;
77
- &.row {
78
- flex-direction: row;
79
- gap: 40px;
80
- }
81
- &.column {
82
- flex-direction: column;
83
- .text-content {
84
- align-items: center;
85
- }
86
- }
87
- .text-content {
88
- display: flex;
89
- flex-direction: column;
90
- gap: 12px;
91
- }
92
- .buttons {
93
- display: flex;
94
- flex-direction: row;
95
- gap: '10px';
96
- }
97
- .details {
98
- background-color: ${theme.color.danger[500]};
99
- color: ${theme.color.danger.contrastText};
100
- padding: 12px;
101
- border-radius: 5px;
102
- }
103
- }
104
- `
105
-
106
- /**
107
- * A box with an icon and an error message. This is used for giving error feedbacks to the user.
108
- *
109
- * If the application is in debug mode, a button is rendered to show the error message.
110
- *
111
- * @param options the error code, the error message and whether or not the application is in debug mode.
112
- */
113
- export const ErrorFeedback = (
114
- { code = 0, message, debug, title, body, image, action, description, help, direction = 'row', style, className }: ErrorDescription,
115
- ) => {
116
- const t = useTranslate(dictionary) as Record<string, string>
117
- const [showDetails, setShowDetails] = useState(false)
118
- const shouldShowButtons = !!(action || (debug && message))
119
-
120
- function renderBody() {
121
- return typeof body === 'string' ? <Text appearance="body1" colorScheme="inverse" className="description">{body}</Text> : body
122
- }
123
-
124
- return (
125
- <FeedbackBox style={style} className={className}>
126
- <div className={listToClass(['content', direction])}>
127
- <div className="image">{image ?? imageMap[code] ?? <ServerError style={imageStyle} />}</div>
128
- <div className="text-content">
129
- <LinkBox href="/" className="logo">
130
- <Logo style={{ width: '130px', height: '30px' }} />
131
- </LinkBox>
132
- <Text appearance="h4" mt={5} colorScheme="inverse" className="title">
133
- {(code && !title) ? `${t.errorLabel} ${code}. ` : ''}
134
- <Text appearance="h4" as="span" colorScheme="light.700">
135
- {title ?? t[`${code}.title`]}
136
- </Text>
137
- </Text>
138
- {body ? renderBody() : (
139
- <>
140
- <Text appearance="body1" mt={5} colorScheme="inverse" className="description"
141
- sx={{
142
- maxWidth: '70ch',
143
- whiteSpace: 'normal',
144
- wordBreak: 'break-word',
145
- }}
146
- >
147
- {description ?? t[`${code}.description`]}
148
- </Text>
149
-
150
- <Text appearance="body1" colorScheme="light.700" className="help">
151
- {help ?? t[`${code}.help`]}
152
- </Text>
153
- </>
154
- )}
155
- {shouldShowButtons && (
156
- <div className="buttons">
157
- {action && (
158
- <Button colorScheme="inverse" onClick={action.onClick}>
159
- {action.label}
160
- </Button>
161
- )}
162
- {debug && message && (
163
- <Button appearance="outlined" colorScheme="inverse" onClick={() => setShowDetails(v => !v)}>
164
- {showDetails ? t.hideDetails : t.showDetails}
165
- </Button>
166
- )}
167
- </div>
168
- )}
169
- {showDetails && (
170
- <div className="details">
171
- <Text appearance="microtext1">{message}</Text>
172
- </div>
173
- )}
174
- </div>
175
- </div>
176
- </FeedbackBox>
177
- )
178
- }
179
-
180
- const dictionary = {
181
- en: {
182
- altLogo: 'Logo Stackspot',
183
- '0.title': 'Something didn’t go as expected',
184
- '0.description': 'This can happen from time to time. Try refreshing the page. If it still doesn’t work, reach out. We’re here to help.',
185
- '401.title': 'You need a valid credential',
186
- '401.description': 'We couldn’t verify your credentials. Check the link or log in with a different account to continue.',
187
- '403.title': 'Access restricted to your organization',
188
- '403.help': 'Log in with an account from your organization or request access from your Account Holder.',
189
- '404.title': 'This resource is no longer available',
190
- '404.description': 'It may have been moved or removed. You can try again or ask your organization’s Account Holder for a new link.',
191
- '500.title': 'We\'re making some adjustments',
192
- '500.description':
193
- 'Something unexpected happened on our side. It might just be a momentary glitch. Try refreshing later to pick up where you left off.',
194
- showDetails: 'Show Details',
195
- hideDetails: 'Hide Details',
196
- errorLabel: 'Error',
197
- },
198
- pt: {
199
- altLogo: 'Logo Stackspot',
200
- '0.title': 'Algo saiu diferente do esperado',
201
- '0.description':
202
- 'Isso pode acontecer de vez em quando. Tente recarregar a página. Se ainda não funcionar, chama a gente. Estamos por aqui para ajudar.',
203
- '401.title': 'Você precisa de uma credencial válida',
204
- '401.description': 'Não conseguimos confirmar suas credenciais. Verifique o link ou faça login com outra conta para continuar.',
205
- '403.title': 'Acesso exclusivo da sua organização',
206
- '403.help': 'Faça login com uma conta da sua organização ou peça acesso ao Account Holder.',
207
- '404.title': 'Este recurso não está mais disponível',
208
- '404.description':
209
- 'Ele pode ter sido movido ou removido. Você pode tentar de novo ou pedir um novo link ao Account Holder da sua organização.',
210
- '500.title': 'Estamos ajustando o sistema',
211
- '500.description':
212
- 'Algo inesperado aconteceu do nosso lado. Pode ser só por alguns instantes. Tente recarregar mais tarde para continuar de onde parou.',
213
- showDetails: 'Ver Detalhes',
214
- hideDetails: 'Esconder Detalhes',
215
- errorLabel: 'Erro',
216
- },
217
- } satisfies Dictionary
1
+ import { Button, LinkBox, Text } from '@citric/core'
2
+ import { listToClass, theme } from '@stack-spot/portal-theme'
3
+ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
4
+ import { useState } from 'react'
5
+ import { styled } from 'styled-components'
6
+ import { Forbidden } from '../../svg/Forbidden'
7
+ import { Logo } from '../../svg/Logo'
8
+ import { NotFound } from '../../svg/NotFound'
9
+ import { ServerError } from '../../svg/ServerError'
10
+ import { Unauthenticated } from '../../svg/Unauthenticated'
11
+
12
+ const imageStyle: React.CSSProperties = {
13
+ width: '200px',
14
+ height: '200px',
15
+ }
16
+
17
+ const imageMap: Record<number, React.ReactElement> = {
18
+ 401: <Unauthenticated style={imageStyle} />,
19
+ 403: <Forbidden style={imageStyle} />,
20
+ 404: <NotFound style={imageStyle} />,
21
+ }
22
+
23
+ export interface ErrorDescription {
24
+ /**
25
+ * The HTTP Error code if this is a network error.
26
+ */
27
+ code?: number,
28
+ /**
29
+ * The error message. This is only visible if debug is true.
30
+ */
31
+ message?: string,
32
+ /**
33
+ * Whether or not the application is in debug mode.
34
+ */
35
+ debug?: boolean,
36
+ /**
37
+ * The title for this error. Overwrites anything preset by "code".
38
+ */
39
+ title?: string,
40
+ /**
41
+ * The error description. Overwrites anything preset by "code".
42
+ */
43
+ description?: string,
44
+ /**
45
+ * A help text to aid the user. Overwrites anything preset by "code".
46
+ */
47
+ help?: string,
48
+ /**
49
+ * A button so the user can take some action.
50
+ */
51
+ action?: { label: string, onClick: () => void },
52
+ /**
53
+ * The content for this error. Overwrites anything preset by "code", "description", "help" or "button".
54
+ */
55
+ body?: React.ReactNode,
56
+ /**
57
+ * The image for the error. Overwrites anything preset by "code".
58
+ */
59
+ image?: React.ReactElement,
60
+ /**
61
+ * Whether to show the feedback horizontally (row) or vertically (column).
62
+ *
63
+ * @default 'row'
64
+ */
65
+ direction?: 'row' | 'column',
66
+ style?: React.CSSProperties,
67
+ className?: string,
68
+ }
69
+
70
+ const FeedbackBox = styled.div`
71
+ background-color: ${theme.color.light[400]};
72
+ padding: 24px;
73
+ .content {
74
+ display: flex;
75
+ justify-content: center;
76
+ align-items: center;
77
+ &.row {
78
+ flex-direction: row;
79
+ gap: 40px;
80
+ }
81
+ &.column {
82
+ flex-direction: column;
83
+ .text-content {
84
+ align-items: center;
85
+ }
86
+ }
87
+ .text-content {
88
+ display: flex;
89
+ flex-direction: column;
90
+ gap: 12px;
91
+ }
92
+ .buttons {
93
+ display: flex;
94
+ flex-direction: row;
95
+ gap: '10px';
96
+ }
97
+ .details {
98
+ background-color: ${theme.color.danger[500]};
99
+ color: ${theme.color.danger.contrastText};
100
+ padding: 12px;
101
+ border-radius: 5px;
102
+ }
103
+ }
104
+ `
105
+
106
+ /**
107
+ * A box with an icon and an error message. This is used for giving error feedbacks to the user.
108
+ *
109
+ * If the application is in debug mode, a button is rendered to show the error message.
110
+ *
111
+ * @param options the error code, the error message and whether or not the application is in debug mode.
112
+ */
113
+ export const ErrorFeedback = (
114
+ { code = 0, message, debug, title, body, image, action, description, help, direction = 'row', style, className }: ErrorDescription,
115
+ ) => {
116
+ const t = useTranslate(dictionary) as Record<string, string>
117
+ const [showDetails, setShowDetails] = useState(false)
118
+ const shouldShowButtons = !!(action || (debug && message))
119
+
120
+ function renderBody() {
121
+ return typeof body === 'string' ? <Text appearance="body1" colorScheme="inverse" className="description">{body}</Text> : body
122
+ }
123
+
124
+ return (
125
+ <FeedbackBox style={style} className={className}>
126
+ <div className={listToClass(['content', direction])}>
127
+ <div className="image">{image ?? imageMap[code] ?? <ServerError style={imageStyle} />}</div>
128
+ <div className="text-content">
129
+ <LinkBox href="/" className="logo">
130
+ <Logo style={{ width: '130px', height: '30px' }} />
131
+ </LinkBox>
132
+ <Text appearance="h4" mt={5} colorScheme="inverse" className="title">
133
+ {(code && !title) ? `${t.errorLabel} ${code}. ` : ''}
134
+ <Text appearance="h4" as="span" colorScheme="light.700">
135
+ {title ?? t[`${code}.title`]}
136
+ </Text>
137
+ </Text>
138
+ {body ? renderBody() : (
139
+ <>
140
+ <Text appearance="body1" mt={5} colorScheme="inverse" className="description"
141
+ sx={{
142
+ maxWidth: '70ch',
143
+ whiteSpace: 'normal',
144
+ wordBreak: 'break-word',
145
+ }}
146
+ >
147
+ {description ?? t[`${code}.description`]}
148
+ </Text>
149
+
150
+ <Text appearance="body1" colorScheme="light.700" className="help">
151
+ {help ?? t[`${code}.help`]}
152
+ </Text>
153
+ </>
154
+ )}
155
+ {shouldShowButtons && (
156
+ <div className="buttons">
157
+ {action && (
158
+ <Button colorScheme="inverse" onClick={action.onClick}>
159
+ {action.label}
160
+ </Button>
161
+ )}
162
+ {debug && message && (
163
+ <Button appearance="outlined" colorScheme="inverse" onClick={() => setShowDetails(v => !v)}>
164
+ {showDetails ? t.hideDetails : t.showDetails}
165
+ </Button>
166
+ )}
167
+ </div>
168
+ )}
169
+ {showDetails && (
170
+ <div className="details">
171
+ <Text appearance="microtext1">{message}</Text>
172
+ </div>
173
+ )}
174
+ </div>
175
+ </div>
176
+ </FeedbackBox>
177
+ )
178
+ }
179
+
180
+ const dictionary = {
181
+ en: {
182
+ altLogo: 'Logo Stackspot',
183
+ '0.title': 'Something didn’t go as expected',
184
+ '0.description': 'This can happen from time to time. Try refreshing the page. If it still doesn’t work, reach out. We’re here to help.',
185
+ '401.title': 'You need a valid credential',
186
+ '401.description': 'We couldn’t verify your credentials. Check the link or log in with a different account to continue.',
187
+ '403.title': 'Access restricted to your organization',
188
+ '403.help': 'Log in with an account from your organization or request access from your Account Holder.',
189
+ '404.title': 'This resource is no longer available',
190
+ '404.description': 'It may have been moved or removed. You can try again or ask your organization’s Account Holder for a new link.',
191
+ '500.title': 'We\'re making some adjustments',
192
+ '500.description':
193
+ 'Something unexpected happened on our side. It might just be a momentary glitch. Try refreshing later to pick up where you left off.',
194
+ showDetails: 'Show Details',
195
+ hideDetails: 'Hide Details',
196
+ errorLabel: 'Error',
197
+ },
198
+ pt: {
199
+ altLogo: 'Logo Stackspot',
200
+ '0.title': 'Algo saiu diferente do esperado',
201
+ '0.description':
202
+ 'Isso pode acontecer de vez em quando. Tente recarregar a página. Se ainda não funcionar, chama a gente. Estamos por aqui para ajudar.',
203
+ '401.title': 'Você precisa de uma credencial válida',
204
+ '401.description': 'Não conseguimos confirmar suas credenciais. Verifique o link ou faça login com outra conta para continuar.',
205
+ '403.title': 'Acesso exclusivo da sua organização',
206
+ '403.help': 'Faça login com uma conta da sua organização ou peça acesso ao Account Holder.',
207
+ '404.title': 'Este recurso não está mais disponível',
208
+ '404.description':
209
+ 'Ele pode ter sido movido ou removido. Você pode tentar de novo ou pedir um novo link ao Account Holder da sua organização.',
210
+ '500.title': 'Estamos ajustando o sistema',
211
+ '500.description':
212
+ 'Algo inesperado aconteceu do nosso lado. Pode ser só por alguns instantes. Tente recarregar mais tarde para continuar de onde parou.',
213
+ showDetails: 'Ver Detalhes',
214
+ hideDetails: 'Esconder Detalhes',
215
+ errorLabel: 'Erro',
216
+ },
217
+ } satisfies Dictionary
@@ -1,24 +1,24 @@
1
- import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
2
- import { ErrorFeedback } from './ErrorFeedback'
3
-
4
- export const PageNotFound = ({ goHome }: { goHome?: () => void }) => {
5
- const t = useTranslate(dictionary)
6
- return (
7
- <ErrorFeedback
8
- code={404}
9
- action={goHome ? {
10
- label: t.homePage,
11
- onClick: goHome,
12
- } : undefined}
13
- />
14
- )
15
- }
16
-
17
- const dictionary = {
18
- en: {
19
- homePage: 'Home Page',
20
- },
21
- pt: {
22
- homePage: 'Página Inicial',
23
- },
24
- } satisfies Dictionary
1
+ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
2
+ import { ErrorFeedback } from './ErrorFeedback'
3
+
4
+ export const PageNotFound = ({ goHome }: { goHome?: () => void }) => {
5
+ const t = useTranslate(dictionary)
6
+ return (
7
+ <ErrorFeedback
8
+ code={404}
9
+ action={goHome ? {
10
+ label: t.homePage,
11
+ onClick: goHome,
12
+ } : undefined}
13
+ />
14
+ )
15
+ }
16
+
17
+ const dictionary = {
18
+ en: {
19
+ homePage: 'Home Page',
20
+ },
21
+ pt: {
22
+ homePage: 'Página Inicial',
23
+ },
24
+ } satisfies Dictionary
@@ -1,30 +1,30 @@
1
- import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
2
- import { ErrorFeedback } from './ErrorFeedback'
3
-
4
- export const UnderMaintenance = ({ refresh }: { refresh?: () => void }) => {
5
- const t = useTranslate(dictionary)
6
- return <ErrorFeedback
7
- title={t.underMaintenance}
8
- description={t.underMaintenanceDescription}
9
- help={t.underMaintenanceHelp}
10
- action={refresh ? {
11
- label: t.refresh,
12
- onClick: refresh,
13
- } : undefined}
14
- />
15
- }
16
-
17
- const dictionary = {
18
- en: {
19
- underMaintenance: 'Under maintenance',
20
- underMaintenanceDescription: 'The site is currently undergoing maintenance.',
21
- underMaintenanceHelp: 'Please, try again in a few minutes.',
22
- refresh: 'Refresh page',
23
- },
24
- pt: {
25
- underMaintenance: 'Em manutenção',
26
- underMaintenanceDescription: 'O site está em manutenção.',
27
- underMaintenanceHelp: 'Por favor, tente novamente em alguns minutos.',
28
- refresh: 'Atualizar página',
29
- },
30
- } satisfies Dictionary
1
+ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
2
+ import { ErrorFeedback } from './ErrorFeedback'
3
+
4
+ export const UnderMaintenance = ({ refresh }: { refresh?: () => void }) => {
5
+ const t = useTranslate(dictionary)
6
+ return <ErrorFeedback
7
+ title={t.underMaintenance}
8
+ description={t.underMaintenanceDescription}
9
+ help={t.underMaintenanceHelp}
10
+ action={refresh ? {
11
+ label: t.refresh,
12
+ onClick: refresh,
13
+ } : undefined}
14
+ />
15
+ }
16
+
17
+ const dictionary = {
18
+ en: {
19
+ underMaintenance: 'Under maintenance',
20
+ underMaintenanceDescription: 'The site is currently undergoing maintenance.',
21
+ underMaintenanceHelp: 'Please, try again in a few minutes.',
22
+ refresh: 'Refresh page',
23
+ },
24
+ pt: {
25
+ underMaintenance: 'Em manutenção',
26
+ underMaintenanceDescription: 'O site está em manutenção.',
27
+ underMaintenanceHelp: 'Por favor, tente novamente em alguns minutos.',
28
+ refresh: 'Atualizar página',
29
+ },
30
+ } satisfies Dictionary
@@ -1,4 +1,4 @@
1
- export { ErrorDescription, ErrorFeedback } from './ErrorFeedback'
2
- export { PageNotFound } from './NotFound'
3
- export { UnderMaintenance } from './UnderMaintenance'
4
-
1
+ export { ErrorDescription, ErrorFeedback } from './ErrorFeedback'
2
+ export { PageNotFound } from './NotFound'
3
+ export { UnderMaintenance } from './UnderMaintenance'
4
+