@postgres.ai/shared 3.5.1-pr-1027.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.
Files changed (202) hide show
  1. package/.gitlab-ci.yml +60 -0
  2. package/components/AlertSnackbar/index.tsx +23 -0
  3. package/components/AlertSnackbar/useAlertSnackbar.tsx +65 -0
  4. package/components/Button/index.tsx +79 -0
  5. package/components/Button2/index.tsx +43 -0
  6. package/components/Button2/styles.module.scss +82 -0
  7. package/components/DestroyCloneModal/index.tsx +56 -0
  8. package/components/DestroyCloneRestrictionModal/index.tsx +50 -0
  9. package/components/ErrorStub/index.tsx +83 -0
  10. package/components/FormattedText/index.tsx +44 -0
  11. package/components/FormattedText/styles.module.scss +34 -0
  12. package/components/GatewayLink/index.tsx +33 -0
  13. package/components/HorizontalScrollContainer/index.tsx +131 -0
  14. package/components/HorizontalScrollContainer/types.ts +12 -0
  15. package/components/HorizontalScrollContainer/utils.ts +16 -0
  16. package/components/ImportantText/index.tsx +29 -0
  17. package/components/Link2/index.tsx +31 -0
  18. package/components/Link2/styles.module.scss +12 -0
  19. package/components/MenuButton/index.tsx +80 -0
  20. package/components/MenuButton/styles.module.scss +42 -0
  21. package/components/Modal/index.tsx +93 -0
  22. package/components/PageSpinner/index.tsx +18 -0
  23. package/components/PageSpinner/styles.module.scss +13 -0
  24. package/components/ResetCloneModal/index.tsx +154 -0
  25. package/components/SectionTitle/index.tsx +74 -0
  26. package/components/Select/index.tsx +42 -0
  27. package/components/SimpleModalControls/index.tsx +56 -0
  28. package/components/Spinner/icon.tsx +29 -0
  29. package/components/Spinner/index.tsx +16 -0
  30. package/components/Spinner/styles.module.scss +33 -0
  31. package/components/Status/index.tsx +61 -0
  32. package/components/Status/styles.module.scss +45 -0
  33. package/components/StubContainer/index.tsx +41 -0
  34. package/components/StubSpinner/index.tsx +49 -0
  35. package/components/StubSpinnerFlex/index.tsx +20 -0
  36. package/components/StubSpinnerFlex/styles.module.scss +20 -0
  37. package/components/SyntaxHighlight/index.tsx +107 -0
  38. package/components/Table/RowMenu/index.tsx +111 -0
  39. package/components/Table/index.tsx +140 -0
  40. package/components/Text/index.tsx +28 -0
  41. package/components/TextField/index.tsx +117 -0
  42. package/components/Tooltip/index.tsx +52 -0
  43. package/config/index.ts +32 -0
  44. package/config/links.ts +6 -0
  45. package/craco.config.js +80 -0
  46. package/helpers/getEntropy.ts +232 -0
  47. package/helpers/localStorage.ts +15 -0
  48. package/helpers/request.ts +47 -0
  49. package/hooks/useWindowDimensions.ts +16 -0
  50. package/icons/ArrowDropDown/index.tsx +29 -0
  51. package/icons/Circle/index.tsx +27 -0
  52. package/icons/External/index.tsx +14 -0
  53. package/icons/Info/index.tsx +12 -0
  54. package/icons/Renewable/index.tsx +65 -0
  55. package/icons/Shield/index.tsx +33 -0
  56. package/icons/Warning/index.tsx +29 -0
  57. package/meta.json +1 -0
  58. package/package.json +55 -0
  59. package/pages/Clone/Status/index.tsx +73 -0
  60. package/pages/Clone/context.ts +22 -0
  61. package/pages/Clone/index.tsx +634 -0
  62. package/pages/Clone/stores/Main.ts +206 -0
  63. package/pages/Clone/useCreatedStores.ts +11 -0
  64. package/pages/Configuration/Header/index.tsx +84 -0
  65. package/pages/Configuration/InputWithTooltip/index.tsx +240 -0
  66. package/pages/Configuration/ResponseMessage/index.tsx +71 -0
  67. package/pages/Configuration/configOptions.ts +60 -0
  68. package/pages/Configuration/index.tsx +1184 -0
  69. package/pages/Configuration/styles.module.scss +122 -0
  70. package/pages/Configuration/tooltipText.tsx +157 -0
  71. package/pages/Configuration/useForm.ts +108 -0
  72. package/pages/Configuration/utils/index.ts +153 -0
  73. package/pages/CreateClone/index.tsx +311 -0
  74. package/pages/CreateClone/stores/Main.ts +107 -0
  75. package/pages/CreateClone/styles.module.scss +71 -0
  76. package/pages/CreateClone/useCreatedStores.ts +11 -0
  77. package/pages/CreateClone/useForm.ts +36 -0
  78. package/pages/Instance/Clones/Header/Item/index.tsx +15 -0
  79. package/pages/Instance/Clones/Header/Item/styles.module.scss +17 -0
  80. package/pages/Instance/Clones/Header/index.tsx +74 -0
  81. package/pages/Instance/Clones/Header/styles.module.scss +11 -0
  82. package/pages/Instance/Clones/index.tsx +135 -0
  83. package/pages/Instance/ClonesModal/index.tsx +71 -0
  84. package/pages/Instance/ClonesModal/utils.ts +21 -0
  85. package/pages/Instance/InactiveInstance/index.tsx +165 -0
  86. package/pages/Instance/InactiveInstance/utils.ts +9 -0
  87. package/pages/Instance/Info/Connection/ConnectModal/Content/index.tsx +176 -0
  88. package/pages/Instance/Info/Connection/ConnectModal/Content/utils.ts +24 -0
  89. package/pages/Instance/Info/Connection/ConnectModal/index.tsx +36 -0
  90. package/pages/Instance/Info/Connection/index.tsx +81 -0
  91. package/pages/Instance/Info/Details/index.tsx +20 -0
  92. package/pages/Instance/Info/Disks/Disk/ActionsMenu/index.tsx +100 -0
  93. package/pages/Instance/Info/Disks/Disk/Marker/index.tsx +26 -0
  94. package/pages/Instance/Info/Disks/Disk/ProgressBar/PointerIcon.tsx +20 -0
  95. package/pages/Instance/Info/Disks/Disk/ProgressBar/index.tsx +73 -0
  96. package/pages/Instance/Info/Disks/Disk/Status/index.tsx +75 -0
  97. package/pages/Instance/Info/Disks/Disk/index.tsx +168 -0
  98. package/pages/Instance/Info/Disks/index.tsx +65 -0
  99. package/pages/Instance/Info/Icons/index.tsx +39 -0
  100. package/pages/Instance/Info/Retrieval/RefreshFailedAlert/index.tsx +32 -0
  101. package/pages/Instance/Info/Retrieval/RefreshFailedAlert/styles.module.scss +33 -0
  102. package/pages/Instance/Info/Retrieval/RetrievalModal/index.tsx +49 -0
  103. package/pages/Instance/Info/Retrieval/RetrievalModal/styles.module.scss +6 -0
  104. package/pages/Instance/Info/Retrieval/RetrievalTable/index.tsx +53 -0
  105. package/pages/Instance/Info/Retrieval/RetrievalTable/styles.module.scss +29 -0
  106. package/pages/Instance/Info/Retrieval/index.tsx +95 -0
  107. package/pages/Instance/Info/Retrieval/utils.ts +10 -0
  108. package/pages/Instance/Info/Snapshots/Calendar/Day/index.tsx +125 -0
  109. package/pages/Instance/Info/Snapshots/Calendar/index.tsx +133 -0
  110. package/pages/Instance/Info/Snapshots/Calendar/utils.ts +74 -0
  111. package/pages/Instance/Info/Snapshots/TimeLine/Day/index.tsx +79 -0
  112. package/pages/Instance/Info/Snapshots/TimeLine/index.tsx +57 -0
  113. package/pages/Instance/Info/Snapshots/index.tsx +97 -0
  114. package/pages/Instance/Info/Snapshots/utils.ts +18 -0
  115. package/pages/Instance/Info/Status/InstanceResponseModal/index.tsx +32 -0
  116. package/pages/Instance/Info/Status/InstanceResponseModal/styles.module.scss +3 -0
  117. package/pages/Instance/Info/Status/index.tsx +85 -0
  118. package/pages/Instance/Info/Status/styles.module.scss +12 -0
  119. package/pages/Instance/Info/Status/utils.ts +24 -0
  120. package/pages/Instance/Info/components/Property/index.tsx +32 -0
  121. package/pages/Instance/Info/components/Property/styles.module.scss +21 -0
  122. package/pages/Instance/Info/components/Section/index.tsx +50 -0
  123. package/pages/Instance/Info/components/ValueStatus/index.tsx +51 -0
  124. package/pages/Instance/Info/index.tsx +129 -0
  125. package/pages/Instance/SnapshotsModal/index.tsx +169 -0
  126. package/pages/Instance/SnapshotsModal/utils.ts +17 -0
  127. package/pages/Instance/Tabs/index.tsx +98 -0
  128. package/pages/Instance/components/ClonesList/ConnectionModal/index.tsx +196 -0
  129. package/pages/Instance/components/ClonesList/MenuCell/index.tsx +98 -0
  130. package/pages/Instance/components/ClonesList/MenuCell/utils.ts +21 -0
  131. package/pages/Instance/components/ClonesList/index.tsx +189 -0
  132. package/pages/Instance/components/ClonesList/styles.module.scss +32 -0
  133. package/pages/Instance/components/ErrorStub/index.tsx +77 -0
  134. package/pages/Instance/components/ModalReloadButton/index.tsx +43 -0
  135. package/pages/Instance/components/Tags/Tag/index.tsx +60 -0
  136. package/pages/Instance/components/Tags/index.tsx +42 -0
  137. package/pages/Instance/context.ts +39 -0
  138. package/pages/Instance/index.tsx +235 -0
  139. package/pages/Instance/stores/ClonesModal.ts +35 -0
  140. package/pages/Instance/stores/Main.ts +335 -0
  141. package/pages/Instance/stores/SnapshotsModal.ts +35 -0
  142. package/pages/Instance/styles.scss +40 -0
  143. package/pages/Instance/useCreatedStores.ts +14 -0
  144. package/pages/Logs/Icons/PlusIcon.tsx +8 -0
  145. package/pages/Logs/constants/index.ts +7 -0
  146. package/pages/Logs/hooks/useWsScroll.tsx +44 -0
  147. package/pages/Logs/index.tsx +267 -0
  148. package/pages/Logs/utils/index.ts +20 -0
  149. package/pages/Logs/wsLogs.ts +110 -0
  150. package/pages/Logs/wsSnackbar.ts +27 -0
  151. package/postgres.ai-shared-3.5.0.tgz +0 -0
  152. package/react-app-env.d.ts +71 -0
  153. package/scripts/copy-assets.js +30 -0
  154. package/scripts/pack.js +70 -0
  155. package/stores/Snapshots.ts +54 -0
  156. package/styles/colors.ts +67 -0
  157. package/styles/global.scss +29 -0
  158. package/styles/icons.tsx +1917 -0
  159. package/styles/mixins.scss +30 -0
  160. package/styles/styles.ts +87 -0
  161. package/styles/theme.ts +53 -0
  162. package/styles/vars.scss +43 -0
  163. package/styles/vars.ts +40 -0
  164. package/tsconfig.build.json +37 -0
  165. package/tsconfig.json +30 -0
  166. package/types/api/endpoints/createClone.ts +10 -0
  167. package/types/api/endpoints/destroyClone.ts +7 -0
  168. package/types/api/endpoints/getClone.ts +6 -0
  169. package/types/api/endpoints/getConfig.ts +6 -0
  170. package/types/api/endpoints/getEngine.ts +13 -0
  171. package/types/api/endpoints/getFullConfig.ts +4 -0
  172. package/types/api/endpoints/getInstance.ts +6 -0
  173. package/types/api/endpoints/getInstanceRetrieval.ts +6 -0
  174. package/types/api/endpoints/getSeImages.ts +22 -0
  175. package/types/api/endpoints/getSnapshots.ts +6 -0
  176. package/types/api/endpoints/getWSToken.ts +6 -0
  177. package/types/api/endpoints/initWS.ts +1 -0
  178. package/types/api/endpoints/refreshInstance.ts +4 -0
  179. package/types/api/endpoints/resetClone.ts +8 -0
  180. package/types/api/endpoints/testDbSource.ts +48 -0
  181. package/types/api/endpoints/updateClone.ts +10 -0
  182. package/types/api/endpoints/updateConfig.ts +6 -0
  183. package/types/api/entities/clone.ts +42 -0
  184. package/types/api/entities/config.ts +114 -0
  185. package/types/api/entities/dbSource.ts +13 -0
  186. package/types/api/entities/instance.ts +67 -0
  187. package/types/api/entities/instanceRetrieval.ts +46 -0
  188. package/types/api/entities/instanceState.ts +102 -0
  189. package/types/api/entities/pool.ts +27 -0
  190. package/types/api/entities/snapshot.ts +18 -0
  191. package/types/api/entities/wsToken.ts +7 -0
  192. package/types/byte-size/index.d.ts +22 -0
  193. package/utils/api.ts +30 -0
  194. package/utils/clone.ts +31 -0
  195. package/utils/connection.ts +38 -0
  196. package/utils/date.ts +87 -0
  197. package/utils/instance.ts +10 -0
  198. package/utils/numbers.ts +11 -0
  199. package/utils/react.ts +10 -0
  200. package/utils/snapshot.ts +4 -0
  201. package/utils/strings.ts +11 -0
  202. package/utils/units.ts +23 -0
@@ -0,0 +1,206 @@
1
+ /*--------------------------------------------------------------------------
2
+ * Copyright (c) 2019-2021, Postgres.ai, Nikolay Samokhvalov nik@postgres.ai
3
+ * All Rights Reserved. Proprietary and confidential.
4
+ * Unauthorized copying of this file, via any medium is strictly prohibited
5
+ *--------------------------------------------------------------------------
6
+ */
7
+
8
+ import { makeAutoObservable } from 'mobx'
9
+
10
+ import { GetInstance } from '@postgres.ai/shared/types/api/endpoints/getInstance'
11
+ import { GetClone } from '@postgres.ai/shared/types/api/endpoints/getClone'
12
+ import { ResetClone } from '@postgres.ai/shared/types/api/endpoints/resetClone'
13
+ import { DestroyClone } from '@postgres.ai/shared/types/api/endpoints/destroyClone'
14
+ import { UpdateClone } from '@postgres.ai/shared/types/api/endpoints/updateClone'
15
+ import {
16
+ SnapshotsStore,
17
+ SnapshotsApi,
18
+ } from '@postgres.ai/shared/stores/Snapshots'
19
+ import { Clone } from '@postgres.ai/shared/types/api/entities/clone'
20
+ import { Instance } from '@postgres.ai/shared/types/api/entities/instance'
21
+ import { checkIsCloneStable } from '@postgres.ai/shared/utils/clone'
22
+ import { getTextFromUnknownApiError } from '@postgres.ai/shared/utils/api'
23
+
24
+ const UNSTABLE_CLONE_UPDATE_TIMEOUT = 1000
25
+
26
+ export type Api = SnapshotsApi & {
27
+ getInstance: GetInstance
28
+ getClone: GetClone
29
+ resetClone: ResetClone
30
+ destroyClone: DestroyClone
31
+ updateClone: UpdateClone
32
+ }
33
+
34
+ type Error = {
35
+ title?: string
36
+ message: string
37
+ }
38
+
39
+ export class MainStore {
40
+ instance: Instance | null = null
41
+ instanceError: Error | null = null
42
+
43
+ clone: Clone | null = null
44
+ cloneError: Error | null = null
45
+
46
+ readonly snapshots: SnapshotsStore
47
+
48
+ isResettingClone = false
49
+ resetCloneError: string | null = null
50
+
51
+ isDestroyingClone = false
52
+ destroyCloneError: string | null = null
53
+
54
+ isUpdatingClone = false
55
+ updateCloneError: string | null = null
56
+
57
+ isReloading = false
58
+
59
+ private cloneUpdateTimeout?: number
60
+
61
+ private readonly api: Api
62
+
63
+ constructor(api: Api) {
64
+ this.snapshots = new SnapshotsStore(api)
65
+ this.api = api
66
+
67
+ makeAutoObservable(this)
68
+ }
69
+
70
+ get isCloneStable() {
71
+ if (!this.clone) return false
72
+ return checkIsCloneStable(this.clone)
73
+ }
74
+
75
+ load = async (instanceId: string, cloneId: string) => {
76
+ const [isInstanceOk, isCloneOk, isSnapshotsLoaded] = await Promise.all([
77
+ this.loadInstance(instanceId),
78
+ this.loadClone(instanceId, cloneId),
79
+ this.snapshots.load(instanceId),
80
+ ])
81
+
82
+ return isInstanceOk && isCloneOk && isSnapshotsLoaded
83
+ }
84
+
85
+ reload = async () => {
86
+ if (!this.instance || !this.clone) return false
87
+ this.isReloading = true
88
+ const isSuccess = await this.load(this.instance.id, this.clone.id)
89
+ this.isReloading = false
90
+ return isSuccess
91
+ }
92
+
93
+ private loadInstance = async (instanceId: string) => {
94
+ const { response, error } = await this.api.getInstance({
95
+ instanceId,
96
+ })
97
+
98
+ if (response) {
99
+ this.instance = response
100
+ } else {
101
+ this.instanceError = {
102
+ title: 'Error',
103
+ message: `Instance "${instanceId}" not found`,
104
+ }
105
+ }
106
+
107
+ if (error) {
108
+ this.instanceError = {
109
+ message: await getTextFromUnknownApiError(error),
110
+ }
111
+ }
112
+
113
+ return Boolean(response)
114
+ }
115
+
116
+ private loadClone = async (instanceId: string, cloneId: string) => {
117
+ window.clearTimeout(this.cloneUpdateTimeout)
118
+
119
+ const { response, error } = await this.api.getClone({ instanceId, cloneId })
120
+
121
+ if (response) {
122
+ this.clone = response
123
+
124
+ if (!this.isCloneStable)
125
+ this.cloneUpdateTimeout = window.setTimeout(
126
+ () => this.loadClone(instanceId, cloneId),
127
+ UNSTABLE_CLONE_UPDATE_TIMEOUT,
128
+ )
129
+ }
130
+
131
+ if (error) {
132
+ if (error.status === 404) {
133
+ this.cloneError = {
134
+ title: 'Error',
135
+ message: `Clone "${cloneId}" not found`,
136
+ }
137
+ } else {
138
+ this.cloneError = {
139
+ message: await getTextFromUnknownApiError(error),
140
+ }
141
+ }
142
+ }
143
+
144
+ return Boolean(response)
145
+ }
146
+
147
+ resetClone = async (snapshotId: string) => {
148
+ if (!this.instance || !this.clone) return false
149
+
150
+ this.isResettingClone = true
151
+
152
+ const { response, error } = await this.api.resetClone({
153
+ instanceId: this.instance.id,
154
+ cloneId: this.clone.id,
155
+ snapshotId,
156
+ })
157
+
158
+ if (response) await this.loadClone(this.instance.id, this.clone.id)
159
+
160
+ if (error) this.resetCloneError = await getTextFromUnknownApiError(error)
161
+
162
+ this.isResettingClone = false
163
+
164
+ return Boolean(response)
165
+ }
166
+
167
+ destroyClone = async () => {
168
+ if (!this.instance || !this.clone) return false
169
+
170
+ this.isDestroyingClone = true
171
+
172
+ const { response, error } = await this.api.destroyClone({
173
+ instanceId: this.instance.id,
174
+ cloneId: this.clone.id,
175
+ })
176
+
177
+ if (error) this.destroyCloneError = await getTextFromUnknownApiError(error)
178
+
179
+ this.isDestroyingClone = false
180
+
181
+ return Boolean(response)
182
+ }
183
+
184
+ updateClone = async (isProtected: boolean) => {
185
+ if (!this.instance || !this.clone) return
186
+
187
+ this.isUpdatingClone = true
188
+
189
+ const prevIsProtected = this.clone.protected
190
+ this.clone.protected = isProtected
191
+
192
+ const { response, error } = await this.api.updateClone({
193
+ instanceId: this.instance.id,
194
+ cloneId: this.clone.id,
195
+ clone: {
196
+ isProtected,
197
+ },
198
+ })
199
+
200
+ if (!response) this.clone.protected = prevIsProtected
201
+
202
+ if (error) this.updateCloneError = await getTextFromUnknownApiError(error)
203
+
204
+ this.isUpdatingClone = false
205
+ }
206
+ }
@@ -0,0 +1,11 @@
1
+ import { useMemo } from 'react'
2
+
3
+ import { MainStore } from './stores/Main'
4
+
5
+ import { Host } from './context'
6
+
7
+ export const useCreatedStores = (host: Host) => ({
8
+ main: useMemo(() => new MainStore(host.api), []),
9
+ })
10
+
11
+ export type Stores = ReturnType<typeof useCreatedStores>
@@ -0,0 +1,84 @@
1
+ /*--------------------------------------------------------------------------
2
+ * Copyright (c) 2019-2021, Postgres.ai, Nikolay Samokhvalov nik@postgres.ai
3
+ * All Rights Reserved. Proprietary and confidential.
4
+ * Unauthorized copying of this file, via any medium is strictly prohibited
5
+ *--------------------------------------------------------------------------
6
+ */
7
+
8
+ import classNames from 'classnames'
9
+ import { Link, Typography } from '@material-ui/core'
10
+ import Box from '@mui/material/Box'
11
+ import { SectionTitle } from '@postgres.ai/shared/components/SectionTitle'
12
+ import { ExternalIcon } from '@postgres.ai/shared/icons/External'
13
+
14
+ import styles from '../styles.module.scss'
15
+
16
+ type Props = {
17
+ retrievalMode: string
18
+ setOpen: () => void
19
+ }
20
+
21
+ export const ConfigSectionTitle = ({ tag }: { tag: string }) => (
22
+ <SectionTitle
23
+ level={2}
24
+ tag="h2"
25
+ text={
26
+ <div className={styles.sectionTitle}>
27
+ <p>Section</p>
28
+ <p>"{tag}"</p>
29
+ </div>
30
+ }
31
+ />
32
+ )
33
+
34
+ const DOCS_URL =
35
+ 'https://postgres.ai/docs/reference-guides/database-lab-engine-configuration-reference'
36
+
37
+ export const Header = (props: Props) => (
38
+ <div className={styles.root}>
39
+ <Box mb={3}>
40
+ <Typography paragraph>
41
+ Only select parameters can be changed here.
42
+ </Typography>
43
+ <Typography paragraph>
44
+ However, you can still see{' '}
45
+ <Link
46
+ href="#"
47
+ underline="always"
48
+ onClick={props.setOpen}
49
+ className={styles.externalLink}
50
+ >
51
+ the full config
52
+ </Link>
53
+ . For details, read{' '}
54
+ <a href={DOCS_URL} target="_blank" className={styles.externalLink}>
55
+ the docs
56
+ <ExternalIcon className={styles.externalIcon} />
57
+ </a>
58
+ .
59
+ </Typography>
60
+ <Typography paragraph>
61
+ <strong>Data retrieval mode</strong>: {props.retrievalMode}
62
+ </Typography>
63
+ </Box>
64
+ <ConfigSectionTitle tag="global" />
65
+ </div>
66
+ )
67
+
68
+ export const ModalTitle = () => (
69
+ <div>
70
+ <Typography className={styles.modalTitle}>
71
+ Full configuration file (view only)
72
+ </Typography>
73
+ <Typography variant="h3">
74
+ Sensitive values are masked. For details, read{' '}
75
+ <a href={DOCS_URL} target="_blank" className={styles.externalLink}>
76
+ the docs
77
+ <ExternalIcon
78
+ className={classNames(styles.externalIcon, styles.largeIcon)}
79
+ />
80
+ </a>
81
+ .
82
+ </Typography>
83
+ </div>
84
+ )
@@ -0,0 +1,240 @@
1
+ import classNames from 'classnames'
2
+ import Box from '@mui/material/Box'
3
+ import { TextField, Chip, makeStyles } from '@material-ui/core'
4
+
5
+ import { Select } from '@postgres.ai/shared/components/Select'
6
+ import { InfoIcon } from '@postgres.ai/shared/icons/Info'
7
+ import { Tooltip } from '@postgres.ai/shared/components/Tooltip'
8
+ import { Spinner } from '@postgres.ai/shared/components/Spinner'
9
+
10
+ import { uniqueChipValue } from '../utils'
11
+
12
+ import styles from '../styles.module.scss'
13
+
14
+ const useStyles = makeStyles(
15
+ {
16
+ textField: {
17
+ '& .MuiOutlinedInput-notchedOutline': {
18
+ borderColor: '#000',
19
+ },
20
+ },
21
+ selectField: {
22
+ marginTop: '0',
23
+ '& .MuiInputBase-root': {
24
+ padding: '6px',
25
+ },
26
+
27
+ '& .MuiSelect-select:focus': {
28
+ backgroundColor: 'inherit',
29
+ },
30
+ },
31
+ label: {
32
+ display: 'block',
33
+ },
34
+ error: {
35
+ color: '#f44336',
36
+ },
37
+ absoluteSpinner: {
38
+ position: 'absolute',
39
+ left: 'calc(50% - 40px)',
40
+ top: 'calc(50% - 5px)',
41
+ },
42
+ },
43
+ { index: 1 },
44
+ )
45
+
46
+ export const InputWithTooltip = ({
47
+ value,
48
+ label,
49
+ error,
50
+ onChange,
51
+ tooltipText,
52
+ disabled,
53
+ type,
54
+ }: {
55
+ value?: string
56
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
57
+ tooltipText: () => React.ReactNode
58
+ label: string
59
+ error?: string
60
+ disabled: boolean | undefined
61
+ type?: string
62
+ }) => {
63
+ const classes = useStyles()
64
+
65
+ return (
66
+ <Box
67
+ mt={2}
68
+ mb={2}
69
+ display="flex"
70
+ flexDirection="column"
71
+ justifyContent="flex-start"
72
+ alignItems="flex-start"
73
+ gap="5px"
74
+ >
75
+ <label className={classNames(error && classes.error, classes.label)}>
76
+ {label}
77
+ </label>
78
+ <Box display="flex" alignItems="center" width="100%">
79
+ <TextField
80
+ type={type || 'text'}
81
+ className={classNames(
82
+ !disabled && classes.textField,
83
+ styles.textField,
84
+ )}
85
+ variant="outlined"
86
+ size="small"
87
+ value={value}
88
+ error={Boolean(error)}
89
+ onChange={onChange}
90
+ disabled={disabled}
91
+ multiline={type === 'textarea'}
92
+ spellCheck={false}
93
+ />
94
+ <Tooltip interactive content={<p>{tooltipText()}</p>}>
95
+ <InfoIcon className={styles.infoIcon} />
96
+ </Tooltip>
97
+ </Box>
98
+ </Box>
99
+ )
100
+ }
101
+
102
+ export const InputWithChip = ({
103
+ value,
104
+ label,
105
+ id,
106
+ onChange,
107
+ tooltipText,
108
+ disabled,
109
+ handleDeleteChip,
110
+ }: {
111
+ value: string
112
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
113
+ tooltipText: () => React.ReactNode
114
+ handleDeleteChip: (
115
+ event: React.FormEvent<HTMLInputElement>,
116
+ uniqueValue: string,
117
+ label: string,
118
+ ) => void
119
+ label: string
120
+ id: string
121
+ disabled: boolean | undefined
122
+ }) => {
123
+ const classes = useStyles()
124
+
125
+ return (
126
+ <Box
127
+ mt={2}
128
+ mb={1}
129
+ display="flex"
130
+ flexDirection="column"
131
+ justifyContent="flex-start"
132
+ alignItems="flex-start"
133
+ gap="5px"
134
+ >
135
+ <label className={classes.label}>{label}</label>
136
+ <Box display="flex" alignItems="center" width="100%">
137
+ <TextField
138
+ className={classNames(
139
+ !disabled && classes.textField,
140
+ styles.textField,
141
+ )}
142
+ variant="outlined"
143
+ onChange={onChange}
144
+ value={value}
145
+ multiline
146
+ disabled={disabled}
147
+ inputProps={{
148
+ name: id,
149
+ id: id,
150
+ }}
151
+ InputLabelProps={{
152
+ shrink: true,
153
+ }}
154
+ />
155
+ <Tooltip interactive content={<p>{tooltipText()}</p>}>
156
+ <InfoIcon className={styles.infoIcon} />
157
+ </Tooltip>
158
+ </Box>
159
+ {value && (
160
+ <div className={styles.chipContainer}>
161
+ {uniqueChipValue(value)
162
+ .split(' ')
163
+ .map((uniqueValue, index) => {
164
+ if (uniqueValue !== '') {
165
+ return (
166
+ <Chip
167
+ key={index}
168
+ className={styles.chip}
169
+ label={uniqueValue}
170
+ disabled={disabled}
171
+ onDelete={(event) =>
172
+ handleDeleteChip(event, uniqueValue, id)
173
+ }
174
+ color="primary"
175
+ />
176
+ )
177
+ }
178
+ })}
179
+ </div>
180
+ )}
181
+ </Box>
182
+ )
183
+ }
184
+
185
+ export const SelectWithTooltip = ({
186
+ value,
187
+ label,
188
+ error,
189
+ onChange,
190
+ tooltipText,
191
+ disabled,
192
+ loading,
193
+ items,
194
+ }: {
195
+ value: string
196
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void
197
+ tooltipText: () => React.ReactNode
198
+ label: string
199
+ error?: boolean
200
+ disabled: boolean | undefined
201
+ loading?: boolean
202
+ items: { value: string; children: React.ReactNode }[]
203
+ }) => {
204
+ const classes = useStyles()
205
+
206
+ return (
207
+ <Box
208
+ mt={1}
209
+ display="flex"
210
+ flexDirection="column"
211
+ justifyContent="flex-start"
212
+ alignItems="flex-start"
213
+ position="relative"
214
+ gap="5px"
215
+ >
216
+ <label className={classNames(error && classes.error, classes.label)}>
217
+ {label}
218
+ </label>
219
+ <Box display="flex" alignItems="center" width="100%">
220
+ {loading && <Spinner className={classes.absoluteSpinner} />}
221
+ <Select
222
+ className={classNames(
223
+ classes.selectField,
224
+ !disabled && classes.textField,
225
+ styles.textField,
226
+ )}
227
+ label=""
228
+ error={error}
229
+ value={value}
230
+ disabled={disabled}
231
+ onChange={onChange}
232
+ items={items}
233
+ />
234
+ <Tooltip interactive content={<p>{tooltipText()}</p>}>
235
+ <InfoIcon className={styles.infoIcon} />
236
+ </Tooltip>
237
+ </Box>
238
+ </Box>
239
+ )
240
+ }
@@ -0,0 +1,71 @@
1
+ import Box from '@mui/material/Box'
2
+ import { makeStyles } from '@material-ui/core'
3
+ import BlockIcon from '@material-ui/icons/Block'
4
+ import CheckCircleOutlineIcon from '@material-ui/icons/CheckCircleOutline'
5
+ import WarningIcon from '@material-ui/icons/Warning'
6
+
7
+ const useStyles = makeStyles(
8
+ {
9
+ successIcon: {
10
+ marginRight: 8,
11
+ color: 'green',
12
+ },
13
+ success: {
14
+ color: 'green',
15
+ alignItems: 'center',
16
+ display: 'flex',
17
+ },
18
+ errorIcon: {
19
+ marginRight: 8,
20
+ color: 'red',
21
+ },
22
+ error: {
23
+ color: 'red',
24
+ alignItems: 'center',
25
+ display: 'flex',
26
+ },
27
+ warning: {
28
+ color: '#FD8411',
29
+ alignItems: 'center',
30
+ display: 'flex',
31
+ },
32
+ warningIcon: {
33
+ marginRight: 8,
34
+ color: '#FD8411',
35
+ },
36
+ },
37
+ { index: 1 },
38
+ )
39
+
40
+ export const ResponseMessage = ({
41
+ type,
42
+ message,
43
+ }: {
44
+ type: string
45
+ message: string | React.ReactNode | null
46
+ }) => {
47
+ const classes = useStyles()
48
+
49
+ return (
50
+ <Box mt={1} mb={1}>
51
+ <span
52
+ className={
53
+ type === 'success' || type === 'ok'
54
+ ? classes.success
55
+ : type === 'warning' || type === 'notice'
56
+ ? classes.warning
57
+ : classes.error
58
+ }
59
+ >
60
+ {type === 'success' || type === 'ok' ? (
61
+ <CheckCircleOutlineIcon className={classes.successIcon} />
62
+ ) : type === 'warning' || type === 'notice' ? (
63
+ <WarningIcon className={classes.warningIcon} />
64
+ ) : (
65
+ <BlockIcon className={classes.errorIcon} />
66
+ )}
67
+ {message}
68
+ </span>
69
+ </Box>
70
+ )
71
+ }
@@ -0,0 +1,60 @@
1
+ export const dockerImageOptions = [
2
+ {
3
+ name: 'Generic Postgres (postgresai/extended-postgres)',
4
+ type: 'Generic Postgres',
5
+ },
6
+ { name: 'Generic Postgres with PostGIS', type: 'postgis' },
7
+ { name: 'Amazon RDS for Postgres', type: 'rds' },
8
+ { name: 'Amazon RDS Aurora for Postgres', type: 'aurora' },
9
+ { name: 'Heroku Postgres', type: 'heroku' },
10
+ { name: 'Supabase Postgres', type: 'supabase' },
11
+ { name: 'Google Cloud SQL for PostgreSQL', type: 'google-cloud-sql' },
12
+ {
13
+ name: 'Timescale Cloud',
14
+ type: 'timescale-cloud',
15
+ },
16
+ { name: 'Custom image', type: 'custom' },
17
+ ]
18
+
19
+ export const imagePgOptions = [
20
+ {
21
+ optionType: 'Generic Postgres',
22
+ pgDumpOptions: [],
23
+ pgRestoreOptions: [],
24
+ },
25
+ {
26
+ optionType: 'postgis',
27
+ pgDumpOptions: [],
28
+ pgRestoreOptions: [],
29
+ },
30
+ {
31
+ optionType: 'rds',
32
+ pgDumpOptions: ['--exclude-schema=awsdms'],
33
+ pgRestoreOptions: [],
34
+ },
35
+ {
36
+ optionType: 'aurora',
37
+ pgDumpOptions: ['--exclude-schema=awsdms'],
38
+ pgRestoreOptions: [],
39
+ },
40
+ {
41
+ optionType: 'heroku',
42
+ pgDumpOptions: [],
43
+ pgRestoreOptions: [],
44
+ },
45
+ {
46
+ optionType: 'supabase',
47
+ pgDumpOptions: [],
48
+ pgRestoreOptions: [],
49
+ },
50
+ {
51
+ optionType: 'google-cloud-sql',
52
+ pgDumpOptions: [],
53
+ pgRestoreOptions: [],
54
+ },
55
+ {
56
+ optionType: 'timescale-cloud',
57
+ pgDumpOptions: [],
58
+ pgRestoreOptions: [],
59
+ },
60
+ ]