@postgres.ai/shared 3.5.0-pr-1027.1 → 4.0.0-pr-1028.1

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 (186) hide show
  1. package/components/DestroyCloneModal/index.js +3 -3
  2. package/components/DestroyCloneRestrictionModal/index.js +1 -1
  3. package/components/MenuButton/index.d.ts +2 -0
  4. package/components/MenuButton/index.js +1 -1
  5. package/components/ResetCloneModal/index.js +5 -3
  6. package/icons/ArrowDropDown/index.d.ts +1 -0
  7. package/icons/ArrowDropDown/index.js +1 -1
  8. package/icons/PostgresSQL/index.d.ts +2 -0
  9. package/icons/PostgresSQL/index.js +40 -0
  10. package/package.json +1 -1
  11. package/pages/Branches/Branch/context.d.ts +22 -0
  12. package/pages/Branches/Branch/context.js +3 -0
  13. package/pages/Branches/Branch/index.d.ts +9 -0
  14. package/pages/Branches/Branch/index.js +172 -0
  15. package/pages/Branches/Branch/stores/Main.d.ts +37 -0
  16. package/pages/Branches/Branch/stores/Main.js +90 -0
  17. package/pages/Branches/Branch/useCreatedStores.d.ts +6 -0
  18. package/pages/Branches/Branch/useCreatedStores.js +5 -0
  19. package/pages/Branches/components/BranchesTable/index.d.ts +10 -0
  20. package/pages/Branches/components/BranchesTable/index.js +107 -0
  21. package/pages/Branches/components/Modals/DeleteBranchModal/index.d.ts +11 -0
  22. package/pages/Branches/components/Modals/DeleteBranchModal/index.js +49 -0
  23. package/pages/Branches/components/Modals/types.d.ts +4 -0
  24. package/pages/Branches/components/Modals/types.js +1 -0
  25. package/pages/Branches/index.d.ts +6 -0
  26. package/pages/Branches/index.js +60 -0
  27. package/pages/Clone/context.d.ts +2 -0
  28. package/pages/Clone/index.d.ts +3 -1
  29. package/pages/Clone/index.js +54 -23
  30. package/pages/Clone/stores/Main.d.ts +4 -2
  31. package/pages/Clone/utils/index.d.ts +4 -0
  32. package/pages/Clone/utils/index.js +12 -0
  33. package/pages/CreateBranch/index.d.ts +17 -0
  34. package/pages/CreateBranch/index.js +135 -0
  35. package/pages/CreateBranch/stores/Main.d.ts +43 -0
  36. package/pages/CreateBranch/stores/Main.js +59 -0
  37. package/pages/CreateBranch/useCreatedStores.d.ts +6 -0
  38. package/pages/CreateBranch/useCreatedStores.js +5 -0
  39. package/pages/CreateBranch/useForm.d.ts +51 -0
  40. package/pages/CreateBranch/useForm.js +30 -0
  41. package/pages/CreateBranch/utils/index.d.ts +2 -0
  42. package/pages/CreateBranch/utils/index.js +10 -0
  43. package/pages/CreateClone/index.d.ts +4 -2
  44. package/pages/CreateClone/index.js +92 -40
  45. package/pages/CreateClone/stores/Main.d.ts +25 -2
  46. package/pages/CreateClone/stores/Main.js +26 -2
  47. package/pages/CreateClone/styles.module.scss +47 -4
  48. package/pages/CreateClone/useForm.d.ts +1 -0
  49. package/pages/CreateClone/useForm.js +1 -0
  50. package/pages/CreateClone/utils/index.d.ts +3 -0
  51. package/pages/CreateClone/utils/index.js +17 -0
  52. package/pages/CreateSnapshot/index.d.ts +17 -0
  53. package/pages/CreateSnapshot/index.js +117 -0
  54. package/pages/CreateSnapshot/stores/Main.d.ts +21 -0
  55. package/pages/CreateSnapshot/stores/Main.js +31 -0
  56. package/pages/CreateSnapshot/useCreatedStores.d.ts +6 -0
  57. package/pages/CreateSnapshot/useCreatedStores.js +5 -0
  58. package/pages/CreateSnapshot/useForm.d.ts +53 -0
  59. package/pages/CreateSnapshot/useForm.js +25 -0
  60. package/pages/CreateSnapshot/utils/index.d.ts +1 -0
  61. package/pages/CreateSnapshot/utils/index.js +3 -0
  62. package/pages/Instance/{components → Clones}/ClonesList/MenuCell/index.js +1 -1
  63. package/pages/Instance/{components → Clones}/ClonesList/MenuCell/utils.js +2 -2
  64. package/pages/Instance/Clones/ClonesList/index.js +96 -0
  65. package/pages/Instance/{components → Clones}/ClonesList/styles.module.scss +10 -0
  66. package/pages/Instance/{ClonesModal → Clones/ClonesModal}/index.js +5 -5
  67. package/pages/Instance/Clones/Header/styles.module.scss +4 -1
  68. package/pages/Instance/Clones/index.d.ts +5 -1
  69. package/pages/Instance/Clones/index.js +6 -8
  70. package/pages/{Configuration → Instance/Configuration}/InputWithTooltip/index.js +15 -11
  71. package/pages/{Configuration → Instance/Configuration}/index.d.ts +2 -1
  72. package/pages/{Configuration → Instance/Configuration}/index.js +9 -6
  73. package/pages/{Configuration → Instance/Configuration}/tooltipText.js +1 -1
  74. package/pages/Instance/Info/Disks/Disk/index.js +6 -4
  75. package/pages/Instance/Info/Retrieval/RetrievalModal/index.js +0 -4
  76. package/pages/Instance/Info/Retrieval/index.js +1 -3
  77. package/pages/Instance/Info/Snapshots/Calendar/utils.d.ts +4 -0
  78. package/pages/Instance/Info/Snapshots/index.js +10 -5
  79. package/pages/Instance/Info/Snapshots/utils.d.ts +13 -2
  80. package/pages/Instance/Info/Snapshots/utils.js +16 -6
  81. package/pages/Instance/Info/Status/index.js +2 -2
  82. package/pages/Instance/Info/index.js +2 -1
  83. package/pages/Instance/Snapshots/components/SnapshotHeader/index.d.ts +11 -0
  84. package/pages/Instance/Snapshots/components/SnapshotHeader/index.js +36 -0
  85. package/pages/Instance/Snapshots/components/SnapshotsList/index.d.ts +11 -0
  86. package/pages/Instance/Snapshots/components/SnapshotsList/index.js +157 -0
  87. package/pages/Instance/Snapshots/components/SnapshotsTable/index.d.ts +6 -0
  88. package/pages/Instance/Snapshots/components/SnapshotsTable/index.js +125 -0
  89. package/pages/Instance/Snapshots/index.d.ts +6 -0
  90. package/pages/Instance/Snapshots/index.js +92 -0
  91. package/pages/Instance/Snapshots/utils/index.d.ts +16 -0
  92. package/pages/Instance/Snapshots/utils/index.js +30 -0
  93. package/pages/Instance/SnapshotsModal/index.js +1 -1
  94. package/pages/Instance/Tabs/PlatformTabs.d.ts +10 -0
  95. package/pages/Instance/Tabs/PlatformTabs.js +51 -0
  96. package/pages/Instance/Tabs/index.d.ts +19 -2
  97. package/pages/Instance/Tabs/index.js +71 -36
  98. package/pages/Instance/Tabs/styles.d.ts +1 -0
  99. package/pages/Instance/Tabs/styles.js +62 -0
  100. package/pages/Instance/components/ModalReloadButton/index.js +1 -1
  101. package/pages/Instance/context.d.ts +7 -0
  102. package/pages/Instance/index.js +14 -13
  103. package/pages/Instance/stores/Main.d.ts +36 -10
  104. package/pages/Instance/stores/Main.js +83 -24
  105. package/pages/Instance/styles.scss +1 -4
  106. package/pages/Logs/hooks/useWsScroll.js +6 -8
  107. package/pages/Logs/index.d.ts +2 -1
  108. package/pages/Logs/index.js +42 -31
  109. package/pages/Logs/wsLogs.d.ts +3 -2
  110. package/pages/Logs/wsLogs.js +24 -8
  111. package/pages/Logs/wsSnackbar.js +7 -7
  112. package/pages/Snapshots/Snapshot/DestorySnapshotModal/index.d.ts +12 -0
  113. package/pages/Snapshots/Snapshot/DestorySnapshotModal/index.js +69 -0
  114. package/pages/Snapshots/Snapshot/context.d.ts +23 -0
  115. package/pages/Snapshots/Snapshot/context.js +3 -0
  116. package/pages/Snapshots/Snapshot/index.d.ts +9 -0
  117. package/pages/Snapshots/Snapshot/index.js +171 -0
  118. package/pages/Snapshots/Snapshot/stores/Main.d.ts +33 -0
  119. package/pages/Snapshots/Snapshot/stores/Main.js +71 -0
  120. package/pages/Snapshots/Snapshot/useCreatedStores.d.ts +6 -0
  121. package/pages/Snapshots/Snapshot/useCreatedStores.js +5 -0
  122. package/stores/Snapshots.d.ts +12 -3
  123. package/stores/Snapshots.js +27 -3
  124. package/types/api/endpoints/createBranch.d.ts +12 -0
  125. package/types/api/endpoints/createBranch.js +1 -0
  126. package/types/api/endpoints/createClone.d.ts +1 -0
  127. package/types/api/endpoints/createSnapshot.d.ts +5 -0
  128. package/types/api/endpoints/createSnapshot.js +1 -0
  129. package/types/api/endpoints/deleteBranch.d.ts +4 -0
  130. package/types/api/endpoints/deleteBranch.js +1 -0
  131. package/types/api/endpoints/destroySnapshot.d.ts +4 -0
  132. package/types/api/endpoints/destroySnapshot.js +1 -0
  133. package/types/api/endpoints/getBranchSnapshot.d.ts +5 -0
  134. package/types/api/endpoints/getBranchSnapshot.js +1 -0
  135. package/types/api/endpoints/getBranches.d.ts +18 -0
  136. package/types/api/endpoints/getBranches.js +5 -0
  137. package/types/api/endpoints/getConfig.d.ts +2 -2
  138. package/types/api/endpoints/getEngine.d.ts +1 -1
  139. package/types/api/endpoints/getFullConfig.d.ts +1 -1
  140. package/types/api/endpoints/getSnapshotList.d.ts +10 -0
  141. package/types/api/endpoints/getSnapshotList.js +1 -0
  142. package/types/api/endpoints/getSnapshots.d.ts +1 -0
  143. package/types/api/endpoints/updateConfig.d.ts +1 -1
  144. package/types/api/entities/branchSnapshot.d.ts +6 -0
  145. package/types/api/entities/branchSnapshot.js +1 -0
  146. package/types/api/entities/branchSnapshots.d.ts +15 -0
  147. package/types/api/entities/branchSnapshots.js +7 -0
  148. package/types/api/entities/clone.d.ts +6 -0
  149. package/types/api/entities/config.js +1 -1
  150. package/types/api/entities/createBranch.d.ts +5 -0
  151. package/types/api/entities/createBranch.js +1 -0
  152. package/types/api/entities/createSnapshot.d.ts +5 -0
  153. package/types/api/entities/createSnapshot.js +1 -0
  154. package/types/api/entities/dbSource.d.ts +1 -0
  155. package/types/api/entities/instance.d.ts +5 -0
  156. package/types/api/entities/instanceState.d.ts +5 -0
  157. package/types/api/entities/snapshot.d.ts +8 -0
  158. package/types/api/entities/snapshot.js +1 -1
  159. package/utils/date.d.ts +2 -0
  160. package/utils/date.js +7 -0
  161. package/utils/snapshot.d.ts +5 -2
  162. package/utils/snapshot.js +6 -1
  163. package/pages/Instance/components/ClonesList/index.js +0 -52
  164. /package/pages/Instance/{components → Clones}/ClonesList/ConnectionModal/index.d.ts +0 -0
  165. /package/pages/Instance/{components → Clones}/ClonesList/ConnectionModal/index.js +0 -0
  166. /package/pages/Instance/{components → Clones}/ClonesList/MenuCell/index.d.ts +0 -0
  167. /package/pages/Instance/{components → Clones}/ClonesList/MenuCell/utils.d.ts +0 -0
  168. /package/pages/Instance/{components → Clones}/ClonesList/index.d.ts +0 -0
  169. /package/pages/Instance/{ClonesModal → Clones/ClonesModal}/index.d.ts +0 -0
  170. /package/pages/Instance/{ClonesModal → Clones/ClonesModal}/utils.d.ts +0 -0
  171. /package/pages/Instance/{ClonesModal → Clones/ClonesModal}/utils.js +0 -0
  172. /package/pages/{Configuration → Instance/Configuration}/Header/index.d.ts +0 -0
  173. /package/pages/{Configuration → Instance/Configuration}/Header/index.js +0 -0
  174. /package/pages/{Configuration → Instance/Configuration}/InputWithTooltip/index.d.ts +0 -0
  175. /package/pages/{Configuration → Instance/Configuration}/ResponseMessage/index.d.ts +0 -0
  176. /package/pages/{Configuration → Instance/Configuration}/ResponseMessage/index.js +0 -0
  177. /package/pages/{Configuration → Instance/Configuration}/configOptions.d.ts +0 -0
  178. /package/pages/{Configuration → Instance/Configuration}/configOptions.js +0 -0
  179. /package/pages/{Configuration → Instance/Configuration}/styles.module.scss +0 -0
  180. /package/pages/{Configuration → Instance/Configuration}/tooltipText.d.ts +0 -0
  181. /package/pages/{Configuration → Instance/Configuration}/useForm.d.ts +0 -0
  182. /package/pages/{Configuration → Instance/Configuration}/useForm.js +0 -0
  183. /package/pages/{Configuration → Instance/Configuration}/utils/index.d.ts +0 -0
  184. /package/pages/{Configuration → Instance/Configuration}/utils/index.js +0 -0
  185. /package/pages/Instance/{SnapshotsModal → Snapshots/components/SnapshotsModal}/utils.d.ts +0 -0
  186. /package/pages/Instance/{SnapshotsModal → Snapshots/components/SnapshotsModal}/utils.js +0 -0
@@ -0,0 +1,125 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*--------------------------------------------------------------------------
3
+ * Copyright (c) 2019-2021, Postgres.ai, Nikolay Samokhvalov nik@postgres.ai
4
+ * All Rights Reserved. Proprietary and confidential.
5
+ * Unauthorized copying of this file, via any medium is strictly prohibited
6
+ *--------------------------------------------------------------------------
7
+ */
8
+ import React from 'react';
9
+ import cn from 'classnames';
10
+ import { observer } from 'mobx-react-lite';
11
+ import { makeStyles } from '@material-ui/core';
12
+ import { formatDistanceToNowStrict } from 'date-fns';
13
+ import copy from 'copy-to-clipboard';
14
+ import { useHistory } from 'react-router-dom';
15
+ import { HorizontalScrollContainer } from '@postgres.ai/shared/components/HorizontalScrollContainer';
16
+ import { generateSnapshotPageId } from '@postgres.ai/shared/pages/Instance/Snapshots/utils';
17
+ import { DestroySnapshotModal } from '@postgres.ai/shared/pages/Snapshots/Snapshot/DestorySnapshotModal';
18
+ import { useStores } from '@postgres.ai/shared/pages/Instance/context';
19
+ import { ArrowDropDownIcon } from '@postgres.ai/shared/icons/ArrowDropDown';
20
+ import { formatBytesIEC } from '@postgres.ai/shared/utils/units';
21
+ import { isSameDayUTC, isValidDate } from '@postgres.ai/shared/utils/date';
22
+ import { Table, TableHead, TableRow, TableBody, TableHeaderCell, TableBodyCell, TableBodyCellMenu, } from '@postgres.ai/shared/components/Table';
23
+ const useStyles = makeStyles({
24
+ cellContentCentered: {
25
+ display: 'flex',
26
+ alignItems: 'center',
27
+ },
28
+ pointerCursor: {
29
+ cursor: 'pointer',
30
+ },
31
+ sortIcon: {
32
+ marginLeft: '8px',
33
+ width: '10px',
34
+ cursor: 'pointer',
35
+ transition: 'transform 0.15s ease-in-out',
36
+ },
37
+ sortIconUp: {
38
+ transform: 'rotate(180deg)',
39
+ },
40
+ hideSortIcon: {
41
+ opacity: 0,
42
+ },
43
+ verticalCentered: {
44
+ display: 'flex',
45
+ alignItems: 'center',
46
+ },
47
+ }, { index: 1 });
48
+ export const SnapshotsTable = observer(({ instanceId }) => {
49
+ var _a, _b;
50
+ const history = useHistory();
51
+ const classes = useStyles();
52
+ const stores = useStores();
53
+ const { snapshots } = stores.main;
54
+ const [snapshotModal, setSnapshotModal] = React.useState({
55
+ isOpen: false,
56
+ snapshotId: '',
57
+ });
58
+ const filteredSnapshots = (_a = snapshots === null || snapshots === void 0 ? void 0 : snapshots.data) === null || _a === void 0 ? void 0 : _a.filter((snapshot) => {
59
+ const isMatchedByDate = !stores.snapshotsModal.date ||
60
+ isSameDayUTC(snapshot.dataStateAtDate, stores.snapshotsModal.date);
61
+ const isMatchedByPool = !stores.snapshotsModal.pool ||
62
+ snapshot.pool === stores.snapshotsModal.pool;
63
+ return isMatchedByDate && isMatchedByPool;
64
+ });
65
+ const [state, setState] = React.useState({
66
+ sortByCreatedDate: 'desc',
67
+ snapshots: filteredSnapshots !== null && filteredSnapshots !== void 0 ? filteredSnapshots : [],
68
+ });
69
+ const handleSortByCreatedDate = () => {
70
+ const sortByCreatedDate = state.sortByCreatedDate === 'desc' ? 'asc' : 'desc';
71
+ const sortedSnapshots = [...state.snapshots].sort((a, b) => {
72
+ if (sortByCreatedDate === 'asc') {
73
+ return (new Date(a.createdAtDate).getTime() -
74
+ new Date(b.createdAtDate).getTime());
75
+ }
76
+ else {
77
+ return (new Date(b.createdAtDate).getTime() -
78
+ new Date(a.createdAtDate).getTime());
79
+ }
80
+ });
81
+ setState({
82
+ ...state,
83
+ sortByCreatedDate,
84
+ snapshots: sortedSnapshots,
85
+ });
86
+ };
87
+ if (!snapshots.data)
88
+ return null;
89
+ return (_jsx(HorizontalScrollContainer, { children: _jsxs(Table, { children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableHeaderCell, {}), _jsx(TableHeaderCell, { children: "Data state time" }), _jsx(TableHeaderCell, { children: _jsxs("div", { className: cn(classes.pointerCursor, classes.verticalCentered), onClick: handleSortByCreatedDate, children: ["Created", _jsx(ArrowDropDownIcon, { className: cn(state.sortByCreatedDate === 'asc' && classes.sortIconUp, classes.sortIcon) })] }) }), _jsx(TableHeaderCell, { children: "Pool" }), _jsx(TableHeaderCell, { children: "Number of clones" }), _jsx(TableHeaderCell, { children: "Logical Size" }), _jsx(TableHeaderCell, { children: "Physical Size" })] }) }), _jsx(TableBody, { children: (_b = state.snapshots) === null || _b === void 0 ? void 0 : _b.map((snapshot) => {
90
+ var _a, _b;
91
+ const snapshotPageId = generateSnapshotPageId(snapshot.id);
92
+ return (_jsxs(TableRow, { hover: true, onClick: () => snapshotPageId &&
93
+ history.push(`/instance/snapshots/${snapshotPageId}`), className: classes.pointerCursor, children: [_jsx(TableBodyCellMenu, { actions: [
94
+ {
95
+ name: 'Copy snapshot ID',
96
+ onClick: () => copy(snapshot.id),
97
+ },
98
+ {
99
+ name: 'Show related clones',
100
+ onClick: () => stores.clonesModal.openModal({
101
+ snapshotId: snapshot.id,
102
+ }),
103
+ },
104
+ {
105
+ name: 'Delete snapshot',
106
+ onClick: () => setSnapshotModal({
107
+ isOpen: true,
108
+ snapshotId: snapshot.id,
109
+ }),
110
+ },
111
+ ] }), _jsxs(TableBodyCell, { children: [snapshot.dataStateAt, " (", isValidDate(snapshot.dataStateAtDate)
112
+ ? formatDistanceToNowStrict(snapshot.dataStateAtDate, {
113
+ addSuffix: true,
114
+ })
115
+ : '-', ")"] }), _jsxs(TableBodyCell, { children: [snapshot.createdAt, " (", isValidDate(snapshot.createdAtDate)
116
+ ? formatDistanceToNowStrict(snapshot.createdAtDate, {
117
+ addSuffix: true,
118
+ })
119
+ : '-', ")"] }), _jsx(TableBodyCell, { children: (_a = snapshot.pool) !== null && _a !== void 0 ? _a : '-' }), _jsx(TableBodyCell, { children: (_b = snapshot.numClones) !== null && _b !== void 0 ? _b : '-' }), _jsx(TableBodyCell, { children: snapshot.logicalSize
120
+ ? formatBytesIEC(snapshot.logicalSize)
121
+ : '-' }), _jsx(TableBodyCell, { children: snapshot.physicalSize
122
+ ? formatBytesIEC(snapshot.physicalSize)
123
+ : '-' })] }, snapshot.id));
124
+ }) }), snapshotModal.isOpen && snapshotModal.snapshotId && (_jsx(DestroySnapshotModal, { isOpen: snapshotModal.isOpen, onClose: () => setSnapshotModal({ isOpen: false, snapshotId: '' }), snapshotId: snapshotModal.snapshotId, instanceId: instanceId, afterSubmitClick: () => { var _a, _b, _c; return (_a = stores.main) === null || _a === void 0 ? void 0 : _a.reload((_c = (_b = stores.main.instance) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : ''); }, destroySnapshot: stores.main.destroySnapshot }))] }) }));
125
+ });
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" />
2
+ interface SnapshotsProps {
3
+ instanceId: string;
4
+ }
5
+ export declare const Snapshots: React.FC<SnapshotsProps>;
6
+ export {};
@@ -0,0 +1,92 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*--------------------------------------------------------------------------
3
+ * Copyright (c) 2019-2021, Postgres.ai, Nikolay Samokhvalov nik@postgres.ai
4
+ * All Rights Reserved. Proprietary and confidential.
5
+ * Unauthorized copying of this file, via any medium is strictly prohibited
6
+ *--------------------------------------------------------------------------
7
+ */
8
+ import { useHistory } from 'react-router';
9
+ import { observer } from 'mobx-react-lite';
10
+ import { makeStyles } from '@material-ui/core';
11
+ import { useStores, useHost } from '@postgres.ai/shared/pages/Instance/context';
12
+ import { SnapshotsList } from '@postgres.ai/shared/pages/Instance/Snapshots/components/SnapshotsList';
13
+ import { SectionTitle } from '@postgres.ai/shared/components/SectionTitle';
14
+ import { Spinner } from '@postgres.ai/shared/components/Spinner';
15
+ import { ErrorStub } from '@postgres.ai/shared/components/ErrorStub';
16
+ import { Button } from '@postgres.ai/shared/components/Button2';
17
+ import { Tooltip } from '@postgres.ai/shared/components/Tooltip';
18
+ import { InfoIcon } from '@postgres.ai/shared/icons/Info';
19
+ import { useEffect, useMemo, useState } from 'react';
20
+ import { SnapshotHeader } from './components/SnapshotHeader';
21
+ const useStyles = makeStyles({
22
+ sectionTitle: {
23
+ borderBottom: 0,
24
+ },
25
+ marginTop: {
26
+ marginTop: '16px',
27
+ },
28
+ infoIcon: {
29
+ height: '12px',
30
+ width: '12px',
31
+ marginLeft: '8px',
32
+ color: '#808080',
33
+ },
34
+ spinner: {
35
+ position: 'absolute',
36
+ right: '50%',
37
+ transform: 'translate(-50%, -50%)',
38
+ },
39
+ }, { index: 1 });
40
+ export const Snapshots = observer(({ instanceId }) => {
41
+ var _a;
42
+ const host = useHost();
43
+ const stores = useStores();
44
+ const classes = useStyles();
45
+ const history = useHistory();
46
+ const { getBranches, instance, snapshots } = stores.main;
47
+ const [messageFilter, setMessageFilter] = useState('');
48
+ const [branches, setBranches] = useState(null);
49
+ const [selectedBranch, setSelectedBranch] = useState('All branches');
50
+ const [isLoadingBranches, setIsLoadingBranches] = useState(true);
51
+ const filteredSnapshots = useMemo(() => {
52
+ if (!snapshots.data)
53
+ return [];
54
+ if (!messageFilter.trim()) {
55
+ return snapshots.data;
56
+ }
57
+ return snapshots.data.filter((snapshot) => { var _a, _b; return (_b = (_a = snapshot === null || snapshot === void 0 ? void 0 : snapshot.message) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === null || _b === void 0 ? void 0 : _b.includes(messageFilter.toLowerCase()); });
58
+ }, [snapshots.data, messageFilter]);
59
+ const clonesList = ((_a = instance === null || instance === void 0 ? void 0 : instance.state) === null || _a === void 0 ? void 0 : _a.cloning.clones) || [];
60
+ const isEmpty = !(filteredSnapshots === null || filteredSnapshots === void 0 ? void 0 : filteredSnapshots.length);
61
+ const hasClones = Boolean(clonesList === null || clonesList === void 0 ? void 0 : clonesList.length);
62
+ const goToSnapshotAddPage = () => history.push(host.routes.createSnapshot());
63
+ const snapshotPagePath = (snapshotId) => host.routes.snapshot(snapshotId);
64
+ useEffect(() => {
65
+ const fetchInitialData = async () => {
66
+ var _a;
67
+ try {
68
+ setIsLoadingBranches(true);
69
+ const branches = await getBranches(instanceId);
70
+ const branchNames = (_a = branches === null || branches === void 0 ? void 0 : branches.map(({ name }) => name)) !== null && _a !== void 0 ? _a : [];
71
+ setBranches(['All branches', ...branchNames]);
72
+ }
73
+ catch (error) {
74
+ console.error('Error fetching initial data:', error);
75
+ }
76
+ finally {
77
+ setIsLoadingBranches(false);
78
+ }
79
+ };
80
+ fetchInitialData();
81
+ }, []);
82
+ useEffect(() => {
83
+ if (selectedBranch) {
84
+ stores.main.reloadSnapshots(selectedBranch === 'All branches' ? '' : selectedBranch);
85
+ }
86
+ }, [selectedBranch]);
87
+ if (!instance && !snapshots.isLoading)
88
+ return _jsx(_Fragment, {});
89
+ if (snapshots === null || snapshots === void 0 ? void 0 : snapshots.error)
90
+ return _jsx(ErrorStub, { message: snapshots === null || snapshots === void 0 ? void 0 : snapshots.error });
91
+ return (_jsx("div", { className: classes.marginTop, children: snapshots.isLoading || isLoadingBranches ? (_jsx(Spinner, { size: "lg", className: classes.spinner })) : (_jsxs(_Fragment, { children: [_jsx(SectionTitle, { level: 2, tag: "h2", text: `Snapshots (${(filteredSnapshots === null || filteredSnapshots === void 0 ? void 0 : filteredSnapshots.length) || 0})`, className: classes.sectionTitle, rightContent: _jsxs(_Fragment, { children: [_jsx(Button, { theme: "primary", onClick: goToSnapshotAddPage, isDisabled: !hasClones, children: "Create snapshot" }), !hasClones && (_jsx(Tooltip, { content: "No clones", children: _jsx("div", { style: { display: 'flex' }, children: _jsx(InfoIcon, { className: classes.infoIcon }) }) }))] }) }), _jsx(SnapshotHeader, { branches: branches, selectedBranch: selectedBranch, setMessageFilter: setMessageFilter, setSelectedBranch: setSelectedBranch }), !isEmpty ? (_jsx(SnapshotsList, { routes: { snapshot: snapshotPagePath }, instanceId: instanceId, filteredSnapshots: filteredSnapshots })) : (_jsx("p", { className: classes.marginTop, children: messageFilter.length || selectedBranch ? (_jsx("span", { children: "No active snapshots found. Try removing the filter and checking again" })) : (_jsx("span", { children: " This instance has no active snapshots" })) }))] })) }));
92
+ });
@@ -0,0 +1,16 @@
1
+ import { Snapshot } from '@postgres.ai/shared/types/api/entities/snapshot';
2
+ export declare const generateSnapshotPageId: (id: string) => string | null;
3
+ export declare const groupSnapshotsByCreatedAtDate: (snapshots: Snapshot[]) => {
4
+ createdAtDate: Date;
5
+ dataStateAtDate: Date;
6
+ numClones: string | number;
7
+ clones: string[];
8
+ createdAt: string;
9
+ dataStateAt: string;
10
+ id: string;
11
+ pool: string;
12
+ physicalSize: number;
13
+ logicalSize: number;
14
+ message: string;
15
+ branch: string;
16
+ }[][];
@@ -0,0 +1,30 @@
1
+ import { isSameDayUTC } from '@postgres.ai/shared/utils/date';
2
+ export const generateSnapshotPageId = (id) => {
3
+ if (!id.includes('@'))
4
+ return null;
5
+ const snapshotIdPart = id.split('@')[1];
6
+ return snapshotIdPart.startsWith('snapshot_')
7
+ ? snapshotIdPart.substring(9)
8
+ : snapshotIdPart;
9
+ };
10
+ export const groupSnapshotsByCreatedAtDate = (snapshots) => {
11
+ const groups = [];
12
+ snapshots.forEach((snapshot) => {
13
+ let grouped = false;
14
+ for (const group of groups) {
15
+ const groupDate = new Date(group[0].createdAtDate);
16
+ if (isSameDayUTC(snapshot.createdAtDate, groupDate)) {
17
+ group.push(snapshot);
18
+ grouped = true;
19
+ break;
20
+ }
21
+ }
22
+ if (!grouped) {
23
+ groups.push([snapshot]);
24
+ }
25
+ });
26
+ groups.sort((a, b) => {
27
+ return b[0].createdAtDate.getTime() - a[0].createdAtDate.getTime();
28
+ });
29
+ return groups;
30
+ };
@@ -18,7 +18,7 @@ import { formatBytesIEC } from '@postgres.ai/shared/utils/units';
18
18
  import { isSameDayUTC } from '@postgres.ai/shared/utils/date';
19
19
  import { Tags } from '@postgres.ai/shared/pages/Instance/components/Tags';
20
20
  import { ModalReloadButton } from '@postgres.ai/shared/pages/Instance/components/ModalReloadButton';
21
- import { getTags } from './utils';
21
+ import { getTags } from '../Snapshots/components/SnapshotsModal/utils';
22
22
  const useStyles = makeStyles({
23
23
  root: {
24
24
  fontSize: '14px',
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ declare type Props = {
3
+ value: number;
4
+ handleChange: (event: React.ChangeEvent<{}>, newValue: number) => void;
5
+ hasLogs: boolean;
6
+ isPlatform?: boolean;
7
+ hideInstanceTabs?: boolean;
8
+ };
9
+ export declare const PlatformTabs: ({ value, handleChange, hasLogs, hideInstanceTabs, }: Props) => JSX.Element;
10
+ export {};
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Link, useParams } from 'react-router-dom';
3
+ import { Tab as TabComponent, Tabs as TabsComponent } from '@material-ui/core';
4
+ import { TABS_INDEX } from '.';
5
+ import { useTabsStyles } from './styles';
6
+ import { PostgresSQLIcon } from '@postgres.ai/shared/icons/PostgresSQL';
7
+ export const PlatformTabs = ({ value, handleChange, hasLogs, hideInstanceTabs, }) => {
8
+ const classes = useTabsStyles();
9
+ const { org, instanceId } = useParams();
10
+ const tabs = [
11
+ {
12
+ label: '👁️ Overview',
13
+ to: 'overview',
14
+ value: TABS_INDEX.OVERVIEW,
15
+ },
16
+ {
17
+ label: '🖖 Branches',
18
+ to: 'branches',
19
+ value: TABS_INDEX.BRANCHES,
20
+ hide: hideInstanceTabs,
21
+ },
22
+ {
23
+ label: '⚡ Snapshots',
24
+ to: 'snapshots',
25
+ value: TABS_INDEX.SNAPSHOTS,
26
+ hide: hideInstanceTabs,
27
+ },
28
+ {
29
+ label: (_jsxs("div", { className: classes.flexRow, children: [_jsx(PostgresSQLIcon, {}), " Clones"] })),
30
+ to: 'clones',
31
+ value: TABS_INDEX.CLONES,
32
+ hide: hideInstanceTabs,
33
+ },
34
+ {
35
+ label: '📓 Logs',
36
+ to: 'logs',
37
+ value: TABS_INDEX.LOGS,
38
+ disabled: !hasLogs,
39
+ hide: hideInstanceTabs,
40
+ },
41
+ {
42
+ label: '🛠️ Configuration',
43
+ to: 'configuration',
44
+ value: TABS_INDEX.CONFIGURATION,
45
+ hide: hideInstanceTabs,
46
+ },
47
+ ];
48
+ return (_jsx(TabsComponent, { value: value, onChange: handleChange, classes: { root: classes.tabsRoot, indicator: classes.tabsIndicator }, children: tabs.map(({ label, to, value, hide, disabled }) => (_jsx(Link, { to: `/${org}/instances/${instanceId}/${to}`, children: _jsx(TabComponent, { label: label, value: value, disabled: disabled, classes: {
49
+ root: hide ? classes.tabHidden : classes.tabRoot,
50
+ }, onClick: (event) => handleChange(event, value) }) }, value))) }));
51
+ };
@@ -1,9 +1,26 @@
1
1
  import React from 'react';
2
- declare type Props = {
2
+ export declare const TABS_INDEX: {
3
+ OVERVIEW: number;
4
+ BRANCHES: number;
5
+ SNAPSHOTS: number;
6
+ CLONES: number;
7
+ LOGS: number;
8
+ CONFIGURATION: number;
9
+ };
10
+ export interface TabsProps {
3
11
  value: number;
4
12
  handleChange: (event: React.ChangeEvent<{}>, newValue: number) => void;
5
13
  hasLogs: boolean;
6
14
  isPlatform?: boolean;
15
+ hideInstanceTabs?: boolean;
16
+ }
17
+ export declare const Tabs: ({ value, handleChange, hasLogs, hideInstanceTabs, }: TabsProps) => JSX.Element;
18
+ declare type InstanceTabProps = {
19
+ tab: number;
20
+ isPlatform?: boolean;
21
+ onTabChange?: (tabID: number) => void;
22
+ instanceId: string;
23
+ hasLogs: boolean;
7
24
  };
8
- export declare const Tabs: (props: Props) => JSX.Element;
25
+ export declare const InstanceTabs: (props: InstanceTabProps) => JSX.Element;
9
26
  export {};
@@ -1,40 +1,75 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { makeStyles, Tab as TabComponent, Tabs as TabsComponent, } from '@material-ui/core';
3
- import { colors } from '@postgres.ai/shared/styles/colors';
4
- const useStyles = makeStyles({
5
- tabsRoot: {
6
- minHeight: 0,
7
- marginTop: '-8px',
8
- },
9
- tabsIndicator: {
10
- height: '3px',
11
- },
12
- tabRoot: {
13
- fontWeight: 400,
14
- minWidth: 0,
15
- minHeight: 0,
16
- padding: '6px 16px',
17
- borderBottom: `3px solid ${colors.consoleStroke}`,
18
- '& + $tabRoot': {
19
- marginLeft: '10px',
2
+ import { Link } from 'react-router-dom';
3
+ import { Tab as TabComponent, Tabs as TabsComponent } from '@material-ui/core';
4
+ import { PostgresSQLIcon } from '@postgres.ai/shared/icons/PostgresSQL';
5
+ import { useTabsStyles } from './styles';
6
+ import { PlatformTabs } from "./PlatformTabs";
7
+ import { useCreatedStores } from "../useCreatedStores";
8
+ export const TABS_INDEX = {
9
+ OVERVIEW: 0,
10
+ BRANCHES: 1,
11
+ SNAPSHOTS: 2,
12
+ CLONES: 3,
13
+ LOGS: 4,
14
+ CONFIGURATION: 5,
15
+ };
16
+ export const Tabs = ({ value, handleChange, hasLogs, hideInstanceTabs, }) => {
17
+ const classes = useTabsStyles();
18
+ const tabData = [
19
+ { label: '👁️ Overview', to: '/instance', value: TABS_INDEX.OVERVIEW },
20
+ {
21
+ label: '🖖 Branches',
22
+ to: '/instance/branches',
23
+ value: TABS_INDEX.BRANCHES,
24
+ hide: hideInstanceTabs,
25
+ },
26
+ {
27
+ label: '⚡ Snapshots',
28
+ to: '/instance/snapshots',
29
+ value: TABS_INDEX.SNAPSHOTS,
30
+ hide: hideInstanceTabs,
31
+ },
32
+ {
33
+ label: (_jsxs("div", { className: classes.flexRow, children: [_jsx(PostgresSQLIcon, {}), " Clones"] })),
34
+ to: '/instance/clones',
35
+ value: TABS_INDEX.CLONES,
36
+ hide: hideInstanceTabs,
20
37
  },
21
- '&.Mui-disabled': {
22
- opacity: 1,
23
- color: colors.pgaiDarkGray,
38
+ {
39
+ label: '📓 Logs',
40
+ to: '/instance/logs',
41
+ value: TABS_INDEX.LOGS,
42
+ disabled: !hasLogs,
24
43
  },
25
- },
26
- tabHidden: {
27
- display: 'none',
28
- },
29
- }, { index: 1 });
30
- export const Tabs = (props) => {
31
- const classes = useStyles();
32
- const { value, handleChange, hasLogs } = props;
33
- return (_jsxs(TabsComponent, { value: value, onChange: handleChange, classes: { root: classes.tabsRoot, indicator: classes.tabsIndicator }, children: [_jsx(TabComponent, { label: "Overview", classes: {
34
- root: classes.tabRoot,
35
- }, value: 0 }), _jsx(TabComponent, { label: "Logs", disabled: !hasLogs, classes: {
36
- root: props.isPlatform ? classes.tabHidden : classes.tabRoot,
37
- }, value: 1 }), _jsx(TabComponent, { label: "Configuration", classes: {
38
- root: props.isPlatform ? classes.tabHidden : classes.tabRoot,
39
- }, value: 2 })] }));
44
+ {
45
+ label: '🛠️ Configuration',
46
+ to: '/instance/configuration',
47
+ value: TABS_INDEX.CONFIGURATION,
48
+ hide: hideInstanceTabs,
49
+ },
50
+ ];
51
+ return (_jsx(TabsComponent, { value: value, onChange: handleChange, classes: { root: classes.tabsRoot, indicator: classes.tabsIndicator }, children: tabData.map(({ label, to, value, hide, disabled }) => (_jsx(Link, { to: to, children: _jsx(TabComponent, { label: label, value: value, disabled: disabled, classes: {
52
+ root: hide ? classes.tabHidden : classes.tabRoot,
53
+ } }) }, value))) }));
54
+ };
55
+ export const InstanceTabs = (props) => {
56
+ const stores = useCreatedStores({});
57
+ const { load, } = stores.main;
58
+ const switchTab = (_, tabID) => {
59
+ const contentElement = document.getElementById('content-container');
60
+ if (props.onTabChange) {
61
+ props.onTabChange(tabID);
62
+ }
63
+ if (tabID === 0) {
64
+ load(props.instanceId);
65
+ }
66
+ contentElement === null || contentElement === void 0 ? void 0 : contentElement.scrollTo(0, 0);
67
+ };
68
+ const tabProps = {
69
+ value: props.tab,
70
+ handleChange: switchTab,
71
+ hasLogs: Boolean(props.hasLogs),
72
+ hideInstanceTabs: false,
73
+ };
74
+ return props.isPlatform ? _jsx(PlatformTabs, { ...tabProps }) : _jsx(Tabs, { ...tabProps });
40
75
  };
@@ -0,0 +1 @@
1
+ export declare const useTabsStyles: (props?: any) => import("@material-ui/styles").ClassNameMap<"tabsRoot" | "flexRow" | "tabsIndicator" | "tabRoot" | "tabHidden">;
@@ -0,0 +1,62 @@
1
+ import { makeStyles } from '@material-ui/core';
2
+ import { colors } from '@postgres.ai/shared/styles/colors';
3
+ export const useTabsStyles = makeStyles({
4
+ tabsRoot: {
5
+ minHeight: 0,
6
+ marginTop: '-8px',
7
+ '& .MuiTabs-fixed': {
8
+ overflowX: 'auto!important',
9
+ scrollbarWidth: 'none',
10
+ '&::-webkit-scrollbar': {
11
+ display: 'none',
12
+ },
13
+ '& div:first-child': {
14
+ '@media (max-width: 700px)': {
15
+ display: 'flex',
16
+ },
17
+ },
18
+ },
19
+ '& .postgres-logo': {
20
+ width: '18px',
21
+ height: '18px',
22
+ },
23
+ '& a': {
24
+ color: colors.black,
25
+ textDecoration: 'none',
26
+ '@media (max-width: 700px)': {
27
+ display: 'flex',
28
+ width: '100%',
29
+ },
30
+ },
31
+ },
32
+ flexRow: {
33
+ display: 'flex',
34
+ flexDirection: 'row',
35
+ gap: '5px',
36
+ width: '100%',
37
+ },
38
+ tabsIndicator: {
39
+ height: '3px',
40
+ },
41
+ tabRoot: {
42
+ fontWeight: 400,
43
+ minWidth: 0,
44
+ minHeight: 0,
45
+ width: '100%',
46
+ padding: '6px 16px',
47
+ borderBottom: `3px solid ${colors.consoleStroke}`,
48
+ '& + $tabRoot': {
49
+ marginLeft: '10px',
50
+ },
51
+ '&.Mui-disabled': {
52
+ opacity: 1,
53
+ color: colors.pgaiDarkGray,
54
+ },
55
+ '@media (max-width: 700px)': {
56
+ width: 'max-content',
57
+ },
58
+ },
59
+ tabHidden: {
60
+ display: 'none',
61
+ },
62
+ }, { index: 1 });
@@ -18,5 +18,5 @@ const useStyles = makeStyles({
18
18
  }, { index: 1 });
19
19
  export const ModalReloadButton = (props) => {
20
20
  const classes = useStyles();
21
- return (_jsx(Button, { onClick: props.onReload, className: classes.content, isLoading: props.isReloading, isDisabled: props.isReloading, children: "Reload info" }));
21
+ return (_jsx(Button, { onClick: props.onReload, className: classes.content, isLoading: props.isReloading, children: "Reload info" }));
22
22
  };
@@ -4,7 +4,12 @@ export declare type Host = {
4
4
  instanceId: string;
5
5
  routes: {
6
6
  createClone: () => string;
7
+ createBranch: () => string;
8
+ createSnapshot: () => string;
7
9
  clone: (cloneId: string) => string;
10
+ branch: (branchId: string) => string;
11
+ branches: () => string;
12
+ snapshot: (snapshotId: string) => string;
8
13
  };
9
14
  api: Api;
10
15
  title: string;
@@ -16,6 +21,8 @@ export declare type Host = {
16
21
  breadcrumbs: React.ReactNode;
17
22
  };
18
23
  wsHost?: string;
24
+ hideInstanceTabs?: boolean;
25
+ renderCurrentTab?: number;
19
26
  isPlatform?: boolean;
20
27
  setProjectAlias?: (alias: string) => void;
21
28
  };