@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.
- package/components/DestroyCloneModal/index.js +3 -3
- package/components/DestroyCloneRestrictionModal/index.js +1 -1
- package/components/MenuButton/index.d.ts +2 -0
- package/components/MenuButton/index.js +1 -1
- package/components/ResetCloneModal/index.js +5 -3
- package/icons/ArrowDropDown/index.d.ts +1 -0
- package/icons/ArrowDropDown/index.js +1 -1
- package/icons/PostgresSQL/index.d.ts +2 -0
- package/icons/PostgresSQL/index.js +40 -0
- package/package.json +1 -1
- package/pages/Branches/Branch/context.d.ts +22 -0
- package/pages/Branches/Branch/context.js +3 -0
- package/pages/Branches/Branch/index.d.ts +9 -0
- package/pages/Branches/Branch/index.js +172 -0
- package/pages/Branches/Branch/stores/Main.d.ts +37 -0
- package/pages/Branches/Branch/stores/Main.js +90 -0
- package/pages/Branches/Branch/useCreatedStores.d.ts +6 -0
- package/pages/Branches/Branch/useCreatedStores.js +5 -0
- package/pages/Branches/components/BranchesTable/index.d.ts +10 -0
- package/pages/Branches/components/BranchesTable/index.js +107 -0
- package/pages/Branches/components/Modals/DeleteBranchModal/index.d.ts +11 -0
- package/pages/Branches/components/Modals/DeleteBranchModal/index.js +49 -0
- package/pages/Branches/components/Modals/types.d.ts +4 -0
- package/pages/Branches/components/Modals/types.js +1 -0
- package/pages/Branches/index.d.ts +6 -0
- package/pages/Branches/index.js +60 -0
- package/pages/Clone/context.d.ts +2 -0
- package/pages/Clone/index.d.ts +3 -1
- package/pages/Clone/index.js +54 -23
- package/pages/Clone/stores/Main.d.ts +4 -2
- package/pages/Clone/utils/index.d.ts +4 -0
- package/pages/Clone/utils/index.js +12 -0
- package/pages/CreateBranch/index.d.ts +17 -0
- package/pages/CreateBranch/index.js +135 -0
- package/pages/CreateBranch/stores/Main.d.ts +43 -0
- package/pages/CreateBranch/stores/Main.js +59 -0
- package/pages/CreateBranch/useCreatedStores.d.ts +6 -0
- package/pages/CreateBranch/useCreatedStores.js +5 -0
- package/pages/CreateBranch/useForm.d.ts +51 -0
- package/pages/CreateBranch/useForm.js +30 -0
- package/pages/CreateBranch/utils/index.d.ts +2 -0
- package/pages/CreateBranch/utils/index.js +10 -0
- package/pages/CreateClone/index.d.ts +4 -2
- package/pages/CreateClone/index.js +92 -40
- package/pages/CreateClone/stores/Main.d.ts +25 -2
- package/pages/CreateClone/stores/Main.js +26 -2
- package/pages/CreateClone/styles.module.scss +47 -4
- package/pages/CreateClone/useForm.d.ts +1 -0
- package/pages/CreateClone/useForm.js +1 -0
- package/pages/CreateClone/utils/index.d.ts +3 -0
- package/pages/CreateClone/utils/index.js +17 -0
- package/pages/CreateSnapshot/index.d.ts +17 -0
- package/pages/CreateSnapshot/index.js +117 -0
- package/pages/CreateSnapshot/stores/Main.d.ts +21 -0
- package/pages/CreateSnapshot/stores/Main.js +31 -0
- package/pages/CreateSnapshot/useCreatedStores.d.ts +6 -0
- package/pages/CreateSnapshot/useCreatedStores.js +5 -0
- package/pages/CreateSnapshot/useForm.d.ts +53 -0
- package/pages/CreateSnapshot/useForm.js +25 -0
- package/pages/CreateSnapshot/utils/index.d.ts +1 -0
- package/pages/CreateSnapshot/utils/index.js +3 -0
- package/pages/Instance/{components → Clones}/ClonesList/MenuCell/index.js +1 -1
- package/pages/Instance/{components → Clones}/ClonesList/MenuCell/utils.js +2 -2
- package/pages/Instance/Clones/ClonesList/index.js +96 -0
- package/pages/Instance/{components → Clones}/ClonesList/styles.module.scss +10 -0
- package/pages/Instance/{ClonesModal → Clones/ClonesModal}/index.js +5 -5
- package/pages/Instance/Clones/Header/styles.module.scss +4 -1
- package/pages/Instance/Clones/index.d.ts +5 -1
- package/pages/Instance/Clones/index.js +6 -8
- package/pages/{Configuration → Instance/Configuration}/InputWithTooltip/index.js +15 -11
- package/pages/{Configuration → Instance/Configuration}/index.d.ts +2 -1
- package/pages/{Configuration → Instance/Configuration}/index.js +9 -6
- package/pages/{Configuration → Instance/Configuration}/tooltipText.js +1 -1
- package/pages/Instance/Info/Disks/Disk/index.js +6 -4
- package/pages/Instance/Info/Retrieval/RetrievalModal/index.js +0 -4
- package/pages/Instance/Info/Retrieval/index.js +1 -3
- package/pages/Instance/Info/Snapshots/Calendar/utils.d.ts +4 -0
- package/pages/Instance/Info/Snapshots/index.js +10 -5
- package/pages/Instance/Info/Snapshots/utils.d.ts +13 -2
- package/pages/Instance/Info/Snapshots/utils.js +16 -6
- package/pages/Instance/Info/Status/index.js +2 -2
- package/pages/Instance/Info/index.js +2 -1
- package/pages/Instance/Snapshots/components/SnapshotHeader/index.d.ts +11 -0
- package/pages/Instance/Snapshots/components/SnapshotHeader/index.js +36 -0
- package/pages/Instance/Snapshots/components/SnapshotsList/index.d.ts +11 -0
- package/pages/Instance/Snapshots/components/SnapshotsList/index.js +157 -0
- package/pages/Instance/Snapshots/components/SnapshotsTable/index.d.ts +6 -0
- package/pages/Instance/Snapshots/components/SnapshotsTable/index.js +125 -0
- package/pages/Instance/Snapshots/index.d.ts +6 -0
- package/pages/Instance/Snapshots/index.js +92 -0
- package/pages/Instance/Snapshots/utils/index.d.ts +16 -0
- package/pages/Instance/Snapshots/utils/index.js +30 -0
- package/pages/Instance/SnapshotsModal/index.js +1 -1
- package/pages/Instance/Tabs/PlatformTabs.d.ts +10 -0
- package/pages/Instance/Tabs/PlatformTabs.js +51 -0
- package/pages/Instance/Tabs/index.d.ts +19 -2
- package/pages/Instance/Tabs/index.js +71 -36
- package/pages/Instance/Tabs/styles.d.ts +1 -0
- package/pages/Instance/Tabs/styles.js +62 -0
- package/pages/Instance/components/ModalReloadButton/index.js +1 -1
- package/pages/Instance/context.d.ts +7 -0
- package/pages/Instance/index.js +14 -13
- package/pages/Instance/stores/Main.d.ts +36 -10
- package/pages/Instance/stores/Main.js +83 -24
- package/pages/Instance/styles.scss +1 -4
- package/pages/Logs/hooks/useWsScroll.js +6 -8
- package/pages/Logs/index.d.ts +2 -1
- package/pages/Logs/index.js +42 -31
- package/pages/Logs/wsLogs.d.ts +3 -2
- package/pages/Logs/wsLogs.js +24 -8
- package/pages/Logs/wsSnackbar.js +7 -7
- package/pages/Snapshots/Snapshot/DestorySnapshotModal/index.d.ts +12 -0
- package/pages/Snapshots/Snapshot/DestorySnapshotModal/index.js +69 -0
- package/pages/Snapshots/Snapshot/context.d.ts +23 -0
- package/pages/Snapshots/Snapshot/context.js +3 -0
- package/pages/Snapshots/Snapshot/index.d.ts +9 -0
- package/pages/Snapshots/Snapshot/index.js +171 -0
- package/pages/Snapshots/Snapshot/stores/Main.d.ts +33 -0
- package/pages/Snapshots/Snapshot/stores/Main.js +71 -0
- package/pages/Snapshots/Snapshot/useCreatedStores.d.ts +6 -0
- package/pages/Snapshots/Snapshot/useCreatedStores.js +5 -0
- package/stores/Snapshots.d.ts +12 -3
- package/stores/Snapshots.js +27 -3
- package/types/api/endpoints/createBranch.d.ts +12 -0
- package/types/api/endpoints/createBranch.js +1 -0
- package/types/api/endpoints/createClone.d.ts +1 -0
- package/types/api/endpoints/createSnapshot.d.ts +5 -0
- package/types/api/endpoints/createSnapshot.js +1 -0
- package/types/api/endpoints/deleteBranch.d.ts +4 -0
- package/types/api/endpoints/deleteBranch.js +1 -0
- package/types/api/endpoints/destroySnapshot.d.ts +4 -0
- package/types/api/endpoints/destroySnapshot.js +1 -0
- package/types/api/endpoints/getBranchSnapshot.d.ts +5 -0
- package/types/api/endpoints/getBranchSnapshot.js +1 -0
- package/types/api/endpoints/getBranches.d.ts +18 -0
- package/types/api/endpoints/getBranches.js +5 -0
- package/types/api/endpoints/getConfig.d.ts +2 -2
- package/types/api/endpoints/getEngine.d.ts +1 -1
- package/types/api/endpoints/getFullConfig.d.ts +1 -1
- package/types/api/endpoints/getSnapshotList.d.ts +10 -0
- package/types/api/endpoints/getSnapshotList.js +1 -0
- package/types/api/endpoints/getSnapshots.d.ts +1 -0
- package/types/api/endpoints/updateConfig.d.ts +1 -1
- package/types/api/entities/branchSnapshot.d.ts +6 -0
- package/types/api/entities/branchSnapshot.js +1 -0
- package/types/api/entities/branchSnapshots.d.ts +15 -0
- package/types/api/entities/branchSnapshots.js +7 -0
- package/types/api/entities/clone.d.ts +6 -0
- package/types/api/entities/config.js +1 -1
- package/types/api/entities/createBranch.d.ts +5 -0
- package/types/api/entities/createBranch.js +1 -0
- package/types/api/entities/createSnapshot.d.ts +5 -0
- package/types/api/entities/createSnapshot.js +1 -0
- package/types/api/entities/dbSource.d.ts +1 -0
- package/types/api/entities/instance.d.ts +5 -0
- package/types/api/entities/instanceState.d.ts +5 -0
- package/types/api/entities/snapshot.d.ts +8 -0
- package/types/api/entities/snapshot.js +1 -1
- package/utils/date.d.ts +2 -0
- package/utils/date.js +7 -0
- package/utils/snapshot.d.ts +5 -2
- package/utils/snapshot.js +6 -1
- package/pages/Instance/components/ClonesList/index.js +0 -52
- /package/pages/Instance/{components → Clones}/ClonesList/ConnectionModal/index.d.ts +0 -0
- /package/pages/Instance/{components → Clones}/ClonesList/ConnectionModal/index.js +0 -0
- /package/pages/Instance/{components → Clones}/ClonesList/MenuCell/index.d.ts +0 -0
- /package/pages/Instance/{components → Clones}/ClonesList/MenuCell/utils.d.ts +0 -0
- /package/pages/Instance/{components → Clones}/ClonesList/index.d.ts +0 -0
- /package/pages/Instance/{ClonesModal → Clones/ClonesModal}/index.d.ts +0 -0
- /package/pages/Instance/{ClonesModal → Clones/ClonesModal}/utils.d.ts +0 -0
- /package/pages/Instance/{ClonesModal → Clones/ClonesModal}/utils.js +0 -0
- /package/pages/{Configuration → Instance/Configuration}/Header/index.d.ts +0 -0
- /package/pages/{Configuration → Instance/Configuration}/Header/index.js +0 -0
- /package/pages/{Configuration → Instance/Configuration}/InputWithTooltip/index.d.ts +0 -0
- /package/pages/{Configuration → Instance/Configuration}/ResponseMessage/index.d.ts +0 -0
- /package/pages/{Configuration → Instance/Configuration}/ResponseMessage/index.js +0 -0
- /package/pages/{Configuration → Instance/Configuration}/configOptions.d.ts +0 -0
- /package/pages/{Configuration → Instance/Configuration}/configOptions.js +0 -0
- /package/pages/{Configuration → Instance/Configuration}/styles.module.scss +0 -0
- /package/pages/{Configuration → Instance/Configuration}/tooltipText.d.ts +0 -0
- /package/pages/{Configuration → Instance/Configuration}/useForm.d.ts +0 -0
- /package/pages/{Configuration → Instance/Configuration}/useForm.js +0 -0
- /package/pages/{Configuration → Instance/Configuration}/utils/index.d.ts +0 -0
- /package/pages/{Configuration → Instance/Configuration}/utils/index.js +0 -0
- /package/pages/Instance/{SnapshotsModal → Snapshots/components/SnapshotsModal}/utils.d.ts +0 -0
- /package/pages/Instance/{SnapshotsModal → Snapshots/components/SnapshotsModal}/utils.js +0 -0
|
@@ -35,7 +35,7 @@ const useStyles = makeStyles({
|
|
|
35
35
|
fontSize: '12px',
|
|
36
36
|
},
|
|
37
37
|
}, { index: 1 });
|
|
38
|
-
export const Configuration = observer(({ switchActiveTab, reload, isConfigurationActive, disableConfigModification, }) => {
|
|
38
|
+
export const Configuration = observer(({ instanceId, switchActiveTab, reload, isConfigurationActive, disableConfigModification, }) => {
|
|
39
39
|
const classes = useStyles();
|
|
40
40
|
const stores = useStores();
|
|
41
41
|
const { config, isConfigurationLoading, updateConfig, getSeImages, fullConfig, testDbSource, configError, getFullConfig, getFullConfigError, getEngine, } = stores.main;
|
|
@@ -98,7 +98,7 @@ export const Configuration = observer(({ switchActiveTab, reload, isConfiguratio
|
|
|
98
98
|
await updateConfig({
|
|
99
99
|
...values,
|
|
100
100
|
tuningParams: formatTuningParamsToObj(values.tuningParams),
|
|
101
|
-
}).then((response) => {
|
|
101
|
+
}, instanceId).then((response) => {
|
|
102
102
|
if (response === null || response === void 0 ? void 0 : response.ok) {
|
|
103
103
|
setSubmitState({
|
|
104
104
|
status: 'success',
|
|
@@ -141,7 +141,10 @@ export const Configuration = observer(({ switchActiveTab, reload, isConfiguratio
|
|
|
141
141
|
},
|
|
142
142
|
},
|
|
143
143
|
});
|
|
144
|
-
testDbSource(
|
|
144
|
+
testDbSource({
|
|
145
|
+
...connectionData,
|
|
146
|
+
instanceId,
|
|
147
|
+
})
|
|
145
148
|
.then((res) => {
|
|
146
149
|
var _a;
|
|
147
150
|
if (res === null || res === void 0 ? void 0 : res.response) {
|
|
@@ -202,7 +205,7 @@ export const Configuration = observer(({ switchActiveTab, reload, isConfiguratio
|
|
|
202
205
|
}
|
|
203
206
|
};
|
|
204
207
|
const handleModalClick = async () => {
|
|
205
|
-
await getFullConfig();
|
|
208
|
+
await getFullConfig(instanceId);
|
|
206
209
|
setIsModalOpen(true);
|
|
207
210
|
};
|
|
208
211
|
const handleDeleteChip = (_, uniqueValue, id) => {
|
|
@@ -417,7 +420,7 @@ export const Configuration = observer(({ switchActiveTab, reload, isConfiguratio
|
|
|
417
420
|
}
|
|
418
421
|
}, [config]);
|
|
419
422
|
useEffect(() => {
|
|
420
|
-
getEngine().then((res) => {
|
|
423
|
+
getEngine(instanceId).then((res) => {
|
|
421
424
|
setDledition(String(res === null || res === void 0 ? void 0 : res.edition));
|
|
422
425
|
});
|
|
423
426
|
}, []);
|
|
@@ -426,7 +429,7 @@ export const Configuration = observer(({ switchActiveTab, reload, isConfiguratio
|
|
|
426
429
|
if (formik.dirty &&
|
|
427
430
|
!isCeEdition &&
|
|
428
431
|
!customOrGenericImage(configData === null || configData === void 0 ? void 0 : configData.dockerImageType)) {
|
|
429
|
-
await getFullConfig().then(async (data) => {
|
|
432
|
+
await getFullConfig(instanceId).then(async (data) => {
|
|
430
433
|
if (data) {
|
|
431
434
|
await fetchSeImages({
|
|
432
435
|
packageGroup: configData === null || configData === void 0 ? void 0 : configData.dockerImageType,
|
|
@@ -17,5 +17,5 @@ export const tooltipText = {
|
|
|
17
17
|
restoreParallelJobs: () => (_jsx("div", { children: "Number of parallel workers used to restore databases from dump to Postgres managed by DBLab. For initial data retrieval (very first data refresh), it is recommended to use the number of vCPUs available on machine running DBLab. With this approach, we have faster restore time, but we need to keep in mind that we can also have higher usage of CPU and disk IO on this machine (up to temporary saturation of resources). For subsequent refreshes, if DBLab is constantly used, it is recommended to reduce this value by 50% to keep some room for normal use of DBLab (such as work with clones)." })),
|
|
18
18
|
pgRestoreCustomOptions: () => (_jsx("div", { children: "pg_restore options to be used to restore from a database dump, for example: '--exclude-schema=repack --exclude-schema=\"camelStyleSchemaName\"'. Note that due to security reasons, the current implementation supports only letters, numbers, hyphen, underscore, equal sign, and double quotes." })),
|
|
19
19
|
timetable: () => (_jsxs("div", { children: ["Schedule for full data refreshes, in", ' ', _jsx("a", { target: '_blank', href: 'https://en.wikipedia.org/wiki/Cron#Overview', className: styles.externalLink, children: "crontab format" }), "."] })),
|
|
20
|
-
tuningParams: () =>
|
|
20
|
+
tuningParams: () => (_jsxs("div", { children: ["Query tuning parameters. This is essential to ensure that cloned PostgreSQL most likely generates the same plans as on the source (specifically, it is crutial for query performance troubleshooting and optimization, including working with EXPLAIN plans). For details, see the", ' ', _jsx("a", { target: '_blank', href: 'https://postgres.ai/docs/how-to-guides/administration/postgresql-configuration#postgresql-configuration-in-clones', className: styles.externalLink, children: "docs" }), "."] })),
|
|
21
21
|
};
|
|
@@ -4,7 +4,7 @@ import { formatDistanceToNowStrict } from 'date-fns';
|
|
|
4
4
|
import { colors } from '@postgres.ai/shared/styles/colors';
|
|
5
5
|
import { formatBytesIEC } from '@postgres.ai/shared/utils/units';
|
|
6
6
|
import { Status as PerformanceStatus } from '@postgres.ai/shared/components/Status';
|
|
7
|
-
import { formatUTC } from '@postgres.ai/shared/utils/date';
|
|
7
|
+
import { formatUTC, isValidDate } from '@postgres.ai/shared/utils/date';
|
|
8
8
|
import { Property } from '../../components/Property';
|
|
9
9
|
import { ActionsMenu } from './ActionsMenu';
|
|
10
10
|
import { Status } from './Status';
|
|
@@ -63,7 +63,9 @@ export const Disk = (props) => {
|
|
|
63
63
|
const shouldShowWarning = props.status === 'active' &&
|
|
64
64
|
getPercent(props.usedDataSize, props.totalDataSize) >
|
|
65
65
|
WARNING_THRESHOLD_PERCENT;
|
|
66
|
-
return (_jsxs("div", { className: classes.root, children: [_jsxs("div", { className: classes.header, children: [_jsxs("div", { className: classes.titleWrapper, children: [_jsx("h6", { title: props.name, className: classes.title, children: props.name }), _jsx(ActionsMenu, { poolId: props.id, poolName: props.name, isActive: props.status === 'active' })] }), _jsx(Status, { value: props.status, hasWarning: shouldShowWarning })] }), _jsx(Property, { name: "Mode", classes: { content: classes.uppercaseContent }, children: props.mode }), props.status === 'refreshing' && props.refreshingStartDate && (_jsx("div", { className: classes.content, children: _jsxs(Property, { name: "Refreshing started at", children: [formatUTC(props.refreshingStartDate, 'yyyy-MM-dd HH:mm:ss'), " UTC (",
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
return (_jsxs("div", { className: classes.root, children: [_jsxs("div", { className: classes.header, children: [_jsxs("div", { className: classes.titleWrapper, children: [_jsx("h6", { title: props.name, className: classes.title, children: props.name }), _jsx(ActionsMenu, { poolId: props.id, poolName: props.name, isActive: props.status === 'active' })] }), _jsx(Status, { value: props.status, hasWarning: shouldShowWarning })] }), _jsx(Property, { name: "Mode", classes: { content: classes.uppercaseContent }, children: props.mode }), props.status === 'refreshing' && props.refreshingStartDate && (_jsx("div", { className: classes.content, children: _jsxs(Property, { name: "Refreshing started at", children: [formatUTC(props.refreshingStartDate, 'yyyy-MM-dd HH:mm:ss'), " UTC (", isValidDate(props.refreshingStartDate)
|
|
67
|
+
? formatDistanceToNowStrict(props.refreshingStartDate, {
|
|
68
|
+
addSuffix: true,
|
|
69
|
+
})
|
|
70
|
+
: '-', ")"] }) })), _jsxs("div", { className: classes.content, children: [_jsx(Property, { name: "Clones", children: props.clonesCount }), _jsx(Property, { name: "Snapshots", children: props.snapshotsCount })] }), _jsxs("div", { className: classes.content, children: [_jsx(Property, { name: "Size", children: formatBytesIEC(props.totalDataSize) }), _jsxs(Property, { name: _jsxs(_Fragment, { children: ["Used\u00A0", _jsx(Marker, { className: classes.markerUsed })] }), children: [formatBytesIEC(props.usedDataSize), " /", ' ', getPercent(props.usedDataSize, props.totalDataSize), " %"] }), _jsxs(Property, { name: _jsxs(_Fragment, { children: ["Free\u00A0", _jsx(Marker, { className: classes.markerFree })] }), children: [formatBytesIEC(props.freeDataSize), " /", ' ', getPercent(props.freeDataSize, props.totalDataSize), " %"] })] }), _jsx(ProgressBar, { value: props.usedDataSize, total: props.totalDataSize, thresholdPercent: WARNING_THRESHOLD_PERCENT }), shouldShowWarning && (_jsxs(PerformanceStatus, { type: "warning", className: classes.warningMessage, children: ["+", WARNING_THRESHOLD_PERCENT, "% disk usage may result in performance degradation"] }))] }));
|
|
69
71
|
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect } from 'react';
|
|
3
2
|
import { Modal } from '@postgres.ai/shared/components/Modal';
|
|
4
3
|
import { useStores } from '@postgres.ai/shared/pages/Instance/context';
|
|
5
4
|
import { ModalReloadButton } from '@postgres.ai/shared/pages/Instance/components/ModalReloadButton';
|
|
@@ -8,8 +7,5 @@ import styles from './styles.module.scss';
|
|
|
8
7
|
export const RetrievalModal = ({ isOpen, onClose, data, }) => {
|
|
9
8
|
const stores = useStores();
|
|
10
9
|
const { isReloadingInstanceRetrieval, reloadInstanceRetrieval } = stores.main;
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
reloadInstanceRetrieval();
|
|
13
|
-
}, []);
|
|
14
10
|
return (_jsx(Modal, { title: "Retrieval activity details", isOpen: isOpen, onClose: onClose, size: "md", titleRightContent: _jsx(ModalReloadButton, { isReloading: isReloadingInstanceRetrieval, onReload: reloadInstanceRetrieval }), children: _jsxs("div", { className: styles.tableContainer, children: [_jsx(RetrievalTable, { data: data === null || data === void 0 ? void 0 : data.source, activity: "source" }), _jsx(RetrievalTable, { data: data === null || data === void 0 ? void 0 : data.target, activity: "target" })] }) }));
|
|
15
11
|
};
|
|
@@ -7,8 +7,6 @@ import { Status } from '@postgres.ai/shared/components/Status';
|
|
|
7
7
|
import { capitalize } from '@postgres.ai/shared/utils/strings';
|
|
8
8
|
import { formatDateStd } from '@postgres.ai/shared/utils/date';
|
|
9
9
|
import { Button } from '@postgres.ai/shared/components/Button2';
|
|
10
|
-
import { Tooltip } from '@postgres.ai/shared/components/Tooltip';
|
|
11
|
-
import { InfoIcon } from '@postgres.ai/shared/icons/Info';
|
|
12
10
|
import { Section } from '../components/Section';
|
|
13
11
|
import { Property } from '../components/Property';
|
|
14
12
|
import { RefreshFailedAlert } from './RefreshFailedAlert';
|
|
@@ -41,7 +39,7 @@ export const Retrieval = observer(() => {
|
|
|
41
39
|
const { mode, status, activity } = instanceRetrieval;
|
|
42
40
|
const isVisible = mode !== 'physical' && !isRetrievalUnknown(mode);
|
|
43
41
|
const isActive = mode === 'logical' && status === 'refreshing';
|
|
44
|
-
return (_jsxs(Section, { title: "Retrieval", children: [_jsx(Property, { name: "Status", children: _jsxs(Status, { type: getTypeByStatus(retrieving.status), children: [capitalize(retrieving.status), isVisible && (
|
|
42
|
+
return (_jsxs(Section, { title: "Retrieval", children: [_jsx(Property, { name: "Status", children: _jsxs(Status, { type: getTypeByStatus(retrieving.status), children: [capitalize(retrieving.status), isVisible && (_jsx(_Fragment, { children: _jsx(Button, { theme: "primary", onClick: () => setIsModalOpen(true), isDisabled: !isActive, className: classes.detailsButton, children: "Show details" }) }))] }) }), _jsx(Property, { name: "Mode", children: retrieving.mode }), _jsx(Property, { name: "Last refresh", children: retrieving.lastRefresh
|
|
45
43
|
? formatDateStd(retrieving.lastRefresh, { withDistance: true })
|
|
46
44
|
: '-' }), _jsx(Property, { name: "Next refresh", children: retrieving.nextRefresh
|
|
47
45
|
? formatDateStd(retrieving.nextRefresh, { withDistance: true })
|
|
@@ -7,12 +7,16 @@ export declare const getCalendar: (monthStartDate: Date, snapshots: Snapshot[])
|
|
|
7
7
|
snapshots: {
|
|
8
8
|
createdAtDate: Date;
|
|
9
9
|
dataStateAtDate: Date;
|
|
10
|
+
numClones: string | number;
|
|
11
|
+
clones: string[];
|
|
10
12
|
createdAt: string;
|
|
11
13
|
dataStateAt: string;
|
|
12
14
|
id: string;
|
|
13
15
|
pool: string;
|
|
14
16
|
physicalSize: number;
|
|
15
17
|
logicalSize: number;
|
|
18
|
+
message: string;
|
|
19
|
+
branch: string;
|
|
16
20
|
}[];
|
|
17
21
|
isBreak: boolean;
|
|
18
22
|
isDisabled: boolean;
|
|
@@ -12,6 +12,7 @@ import { Button } from '@postgres.ai/shared/components/Button2';
|
|
|
12
12
|
import { Spinner } from '@postgres.ai/shared/components/Spinner';
|
|
13
13
|
import { ErrorStub } from '@postgres.ai/shared/components/ErrorStub';
|
|
14
14
|
import { useStores } from '@postgres.ai/shared/pages/Instance/context';
|
|
15
|
+
import { isValidDate } from '@postgres.ai/shared/utils/date';
|
|
15
16
|
import { Section } from '../components/Section';
|
|
16
17
|
import { Property } from '../components/Property';
|
|
17
18
|
import { getEdgeSnapshots } from './utils';
|
|
@@ -27,9 +28,13 @@ export const Snapshots = observer(() => {
|
|
|
27
28
|
const { snapshots } = stores.main;
|
|
28
29
|
const classes = useStyles();
|
|
29
30
|
const { firstSnapshot, lastSnapshot } = getEdgeSnapshots((_a = snapshots.data) !== null && _a !== void 0 ? _a : []);
|
|
30
|
-
return (_jsxs(Section, { title: "Snapshots", rightContent: !snapshots.data && !snapshots.error && _jsx(Spinner, { size: "sm" }), children: [snapshots.error && _jsx(ErrorStub, { message: snapshots.error, size: "normal" }), snapshots.data && !snapshots.error && (_jsxs(_Fragment, { children: [_jsx(Property, { name: "Number of snapshots", children: snapshots.data.length }), _jsxs(Property, { name: "Oldest data state time", children: [lastSnapshot && (_jsxs(_Fragment, { children: [lastSnapshot.dataStateAt, " (",
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
return (_jsxs(Section, { title: "Snapshots", rightContent: !snapshots.data && !snapshots.error && _jsx(Spinner, { size: "sm" }), children: [snapshots.error && _jsx(ErrorStub, { message: snapshots.error, size: "normal" }), snapshots.data && !snapshots.error && (_jsxs(_Fragment, { children: [_jsx(Property, { name: "Number of snapshots", children: snapshots.data.length }), _jsxs(Property, { name: "Oldest data state time", children: [lastSnapshot && (_jsxs(_Fragment, { children: [lastSnapshot.dataStateAt, " (", isValidDate(lastSnapshot.dataStateAtDate)
|
|
32
|
+
? formatDistanceToNowStrict(lastSnapshot.dataStateAtDate, {
|
|
33
|
+
addSuffix: true,
|
|
34
|
+
})
|
|
35
|
+
: '-', ")"] })), !lastSnapshot && '-'] }), _jsxs(Property, { name: "Newest data state time", children: [firstSnapshot && (_jsxs(_Fragment, { children: [firstSnapshot.dataStateAt, " (", isValidDate(firstSnapshot.dataStateAtDate)
|
|
36
|
+
? formatDistanceToNowStrict(firstSnapshot.dataStateAtDate, {
|
|
37
|
+
addSuffix: true,
|
|
38
|
+
})
|
|
39
|
+
: '-', ")"] })), !firstSnapshot && '-'] }), _jsx(Calendar, { snapshots: snapshots.data, onSelectDate: (date) => stores.snapshotsModal.openModal({ date }) }), _jsx(Button, { className: classes.button, onClick: () => stores.snapshotsModal.openModal(), children: "Show all snapshots" })] }))] }));
|
|
35
40
|
});
|
|
@@ -1,23 +1,34 @@
|
|
|
1
1
|
import { Snapshot } from '@postgres.ai/shared/types/api/entities/snapshot';
|
|
2
2
|
export declare const getEdgeSnapshots: (snapshots: Snapshot[]) => {
|
|
3
|
+
firstSnapshot: null;
|
|
4
|
+
lastSnapshot: null;
|
|
5
|
+
} | {
|
|
3
6
|
firstSnapshot: {
|
|
4
7
|
createdAtDate: Date;
|
|
5
8
|
dataStateAtDate: Date;
|
|
9
|
+
numClones: string | number;
|
|
10
|
+
clones: string[];
|
|
6
11
|
createdAt: string;
|
|
7
12
|
dataStateAt: string;
|
|
8
13
|
id: string;
|
|
9
14
|
pool: string;
|
|
10
15
|
physicalSize: number;
|
|
11
16
|
logicalSize: number;
|
|
12
|
-
|
|
17
|
+
message: string;
|
|
18
|
+
branch: string;
|
|
19
|
+
};
|
|
13
20
|
lastSnapshot: {
|
|
14
21
|
createdAtDate: Date;
|
|
15
22
|
dataStateAtDate: Date;
|
|
23
|
+
numClones: string | number;
|
|
24
|
+
clones: string[];
|
|
16
25
|
createdAt: string;
|
|
17
26
|
dataStateAt: string;
|
|
18
27
|
id: string;
|
|
19
28
|
pool: string;
|
|
20
29
|
physicalSize: number;
|
|
21
30
|
logicalSize: number;
|
|
22
|
-
|
|
31
|
+
message: string;
|
|
32
|
+
branch: string;
|
|
33
|
+
};
|
|
23
34
|
};
|
|
@@ -5,12 +5,22 @@
|
|
|
5
5
|
*--------------------------------------------------------------------------
|
|
6
6
|
*/
|
|
7
7
|
export const getEdgeSnapshots = (snapshots) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
if (!snapshots.length) {
|
|
9
|
+
return {
|
|
10
|
+
firstSnapshot: null,
|
|
11
|
+
lastSnapshot: null
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const sortedList = [...snapshots].sort((a, b) => {
|
|
15
|
+
var _a, _b, _c, _d;
|
|
16
|
+
const aTime = (_b = (_a = a.dataStateAtDate) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0;
|
|
17
|
+
const bTime = (_d = (_c = b.dataStateAtDate) === null || _c === void 0 ? void 0 : _c.getTime()) !== null && _d !== void 0 ? _d : 0;
|
|
18
|
+
return bTime - aTime;
|
|
19
|
+
});
|
|
20
|
+
const [first] = sortedList;
|
|
21
|
+
const [last] = sortedList.slice(-1);
|
|
12
22
|
return {
|
|
13
|
-
firstSnapshot:
|
|
14
|
-
lastSnapshot:
|
|
23
|
+
firstSnapshot: first !== null && first !== void 0 ? first : null,
|
|
24
|
+
lastSnapshot: last !== null && last !== void 0 ? last : null // oldest
|
|
15
25
|
};
|
|
16
26
|
};
|
|
@@ -21,11 +21,11 @@ import styles from './styles.module.scss';
|
|
|
21
21
|
export const Status = observer(() => {
|
|
22
22
|
const [isOpenInstanceResponseModal, setIsOpenInstanceResponseModal] = useState(false);
|
|
23
23
|
const stores = useStores();
|
|
24
|
-
const { instance } = stores.main;
|
|
24
|
+
const { instance, uiVersion, config } = stores.main;
|
|
25
25
|
if (!instance || !instance.state)
|
|
26
26
|
return null;
|
|
27
27
|
const { code, message } = instance.state.status;
|
|
28
28
|
const { version, startedAt } = instance.state.engine;
|
|
29
29
|
const isStatusOk = code === 'OK';
|
|
30
|
-
return (_jsxs(Section, { title: "Status", children: [_jsx(Property, { name: "Status", children: _jsxs(StatusIndicator, { type: getType(code), children: [getText(code), !isStatusOk && (_jsxs(_Fragment, { children: [_jsx("br", {}), message] }))] }) }), startedAt && (_jsx(Property, { name: "Started", children: formatDateStd(startedAt, { withDistance: true }) })), instance.createdAt && (_jsx(Property, { name: "Registered", children: formatDateStd(instance.createdAt, { withDistance: true }) })), version && _jsx(Property, { name: "
|
|
30
|
+
return (_jsxs(Section, { title: "Status", children: [_jsx(Property, { name: "Status", children: _jsxs(StatusIndicator, { type: getType(code), children: [getText(code), !isStatusOk && (_jsxs(_Fragment, { children: [_jsx("br", {}), message] }))] }) }), startedAt && (_jsx(Property, { name: "Started", children: formatDateStd(startedAt, { withDistance: true }) })), instance.createdAt && (_jsx(Property, { name: "Registered", children: formatDateStd(instance.createdAt, { withDistance: true }) })), uiVersion && _jsx(Property, { name: "UI version", children: `v${uiVersion}` }), version && _jsx(Property, { name: "Engine version", children: version }), (config === null || config === void 0 ? void 0 : config.dockerPath) && (_jsx(Property, { name: "Docker image", children: config === null || config === void 0 ? void 0 : config.dockerPath })), !isStatusOk && (_jsxs("div", { className: styles.controls, children: [_jsx(Button, { onClick: () => setIsOpenInstanceResponseModal(true), className: styles.button, children: "Show full response" }), _jsx(GatewayLink, { className: styles.button, href: linksConfig.support, children: _jsx(Button, { theme: "accent", children: "Ask support" }) })] })), _jsx(InstanceResponseModal, { isOpen: isOpenInstanceResponseModal, onClose: () => setIsOpenInstanceResponseModal(false) })] }));
|
|
31
31
|
});
|
|
@@ -65,11 +65,12 @@ const useStyles = makeStyles((theme) => ({
|
|
|
65
65
|
export const Info = () => {
|
|
66
66
|
const classes = useStyles();
|
|
67
67
|
const width = useWindowDimensions();
|
|
68
|
+
const [onHover, setOnHover] = useState(false);
|
|
68
69
|
const isMobileScreen = width <= SMALL_BREAKPOINT_PX;
|
|
69
70
|
const [isCollapsed, setIsCollapsed] = useState(() => localStorage.getItem(SIDEBAR_COLLAPSED_PARAM) === '1' && !isMobileScreen);
|
|
70
71
|
const handleClick = () => {
|
|
71
72
|
setIsCollapsed(!isCollapsed);
|
|
72
73
|
localStorage.setItem(SIDEBAR_COLLAPSED_PARAM, isCollapsed ? '0' : '1');
|
|
73
74
|
};
|
|
74
|
-
return (_jsxs("div", { className: cn(classes.container, !isCollapsed ? classes.root : classes.collapsed), children: [!isMobileScreen && (_jsx(Button, { className: classes.collapseBtn, onClick: handleClick, isCollapsed: isCollapsed, icon: isCollapsed ? (_jsx(ArrowLeft, { className: classes.arrowImage })) : (_jsx(ArrowRight, { className: classes.arrowImage })), children:
|
|
75
|
+
return (_jsxs("div", { className: cn(classes.container, !isCollapsed ? classes.root : classes.collapsed), children: [!isMobileScreen && (_jsx(Button, { onMouseEnter: () => setOnHover(true), onMouseLeave: () => setOnHover(false), className: classes.collapseBtn, onClick: handleClick, isCollapsed: isCollapsed, type: "button", icon: isCollapsed ? (_jsx(ArrowLeft, { className: classes.arrowImage })) : (_jsx(ArrowRight, { className: classes.arrowImage })), children: onHover && 'Collapse' })), !isCollapsed && (_jsxs("div", { children: [_jsx(Status, {}), _jsx(Retrieval, {}), _jsx(Connection, {}), _jsx(Disks, {}), _jsx(Snapshots, {})] }))] }));
|
|
75
76
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
interface SnapshotHeaderProps {
|
|
3
|
+
branches: string[] | null;
|
|
4
|
+
selectedBranch: string;
|
|
5
|
+
setMessageFilter: (value: string) => void;
|
|
6
|
+
setSelectedBranch: (value: string) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare const SnapshotHeader: (({ branches, selectedBranch, setMessageFilter, setSelectedBranch, }: SnapshotHeaderProps) => JSX.Element) & {
|
|
9
|
+
displayName: string;
|
|
10
|
+
};
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { observer } from 'mobx-react-lite';
|
|
3
|
+
import { makeStyles, TextField } from '@material-ui/core';
|
|
4
|
+
import { Select } from '@postgres.ai/shared/components/Select';
|
|
5
|
+
const useStyles = makeStyles({
|
|
6
|
+
outerContainer: {
|
|
7
|
+
display: 'flex',
|
|
8
|
+
justifyContent: 'space-between',
|
|
9
|
+
alignItems: 'center',
|
|
10
|
+
paddingBottom: '6px',
|
|
11
|
+
},
|
|
12
|
+
select: {
|
|
13
|
+
width: '200px',
|
|
14
|
+
},
|
|
15
|
+
inputContainer: {
|
|
16
|
+
width: '300px',
|
|
17
|
+
'& input': {
|
|
18
|
+
padding: '8px',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
}, { index: 1 });
|
|
22
|
+
export const SnapshotHeader = observer(({ branches, selectedBranch, setMessageFilter, setSelectedBranch, }) => {
|
|
23
|
+
const classes = useStyles();
|
|
24
|
+
return (_jsxs("div", { className: classes.outerContainer, children: [_jsx(Select, { fullWidth: true, label: "Branch", className: classes.select, value: selectedBranch, disabled: !branches, onChange: (e) => {
|
|
25
|
+
setSelectedBranch(e.target.value);
|
|
26
|
+
}, items: branches
|
|
27
|
+
? branches.map((branch) => {
|
|
28
|
+
return {
|
|
29
|
+
value: branch,
|
|
30
|
+
children: _jsx("div", { children: branch }),
|
|
31
|
+
};
|
|
32
|
+
})
|
|
33
|
+
: [] }), _jsx(TextField, { variant: "outlined", className: classes.inputContainer, onChange: (e) => setMessageFilter(e.target.value), label: 'Filter by message', InputLabelProps: {
|
|
34
|
+
shrink: true,
|
|
35
|
+
} })] }));
|
|
36
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { Snapshot } from '@postgres.ai/shared/types/api/entities/snapshot';
|
|
3
|
+
export declare const SnapshotsList: (({ routes, filteredSnapshots, instanceId, }: {
|
|
4
|
+
routes: {
|
|
5
|
+
snapshot: (snapshotId: string) => string;
|
|
6
|
+
};
|
|
7
|
+
filteredSnapshots: Snapshot[];
|
|
8
|
+
instanceId: string;
|
|
9
|
+
}) => JSX.Element) & {
|
|
10
|
+
displayName: string;
|
|
11
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { observer } from 'mobx-react-lite';
|
|
4
|
+
import { makeStyles } from '@material-ui/core';
|
|
5
|
+
import copy from 'copy-to-clipboard';
|
|
6
|
+
import { HorizontalScrollContainer } from '@postgres.ai/shared/components/HorizontalScrollContainer';
|
|
7
|
+
import { DestroySnapshotModal } from '@postgres.ai/shared/pages/Snapshots/Snapshot/DestorySnapshotModal';
|
|
8
|
+
import { useHost, useStores } from '@postgres.ai/shared/pages/Instance/context';
|
|
9
|
+
import { IconButton } from '@mui/material';
|
|
10
|
+
import { icons } from '@postgres.ai/shared/styles/icons';
|
|
11
|
+
import { RowMenu } from '@postgres.ai/shared/components/Table/RowMenu';
|
|
12
|
+
import { generateSnapshotPageId, groupSnapshotsByCreatedAtDate, } from '@postgres.ai/shared/pages/Instance/Snapshots/utils';
|
|
13
|
+
import { format, formatDistanceToNowStrict } from 'date-fns';
|
|
14
|
+
import { formatBytesIEC } from '@postgres.ai/shared/utils/units';
|
|
15
|
+
import { useHistory } from 'react-router';
|
|
16
|
+
const useStyles = makeStyles({
|
|
17
|
+
pointerCursor: {
|
|
18
|
+
cursor: 'pointer',
|
|
19
|
+
padding: '0 8px',
|
|
20
|
+
'&:hover': {
|
|
21
|
+
backgroundColor: '#f9f9f9',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
commitItem: {
|
|
25
|
+
display: 'flex',
|
|
26
|
+
justifyContent: 'space-between',
|
|
27
|
+
padding: '14px 0',
|
|
28
|
+
borderBottom: '1px solid #ddd',
|
|
29
|
+
'&:last-child': {
|
|
30
|
+
borderBottom: 'none',
|
|
31
|
+
marginBottom: '12px',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
infoBlock: {
|
|
35
|
+
display: 'flex',
|
|
36
|
+
flexDirection: 'column',
|
|
37
|
+
justifyContent: 'center',
|
|
38
|
+
overflow: 'hidden',
|
|
39
|
+
},
|
|
40
|
+
header: {
|
|
41
|
+
fontWeight: 500,
|
|
42
|
+
},
|
|
43
|
+
infoContent: {
|
|
44
|
+
fontSize: '12px',
|
|
45
|
+
color: '#808080',
|
|
46
|
+
display: 'flex',
|
|
47
|
+
alignItems: 'center',
|
|
48
|
+
gap: '5px',
|
|
49
|
+
},
|
|
50
|
+
snapshotId: {
|
|
51
|
+
fontSize: '12px',
|
|
52
|
+
overflow: 'hidden',
|
|
53
|
+
textOverflow: 'ellipsis',
|
|
54
|
+
whiteSpace: 'nowrap',
|
|
55
|
+
padding: '0 10px',
|
|
56
|
+
},
|
|
57
|
+
actionsContainer: {
|
|
58
|
+
overflow: 'hidden',
|
|
59
|
+
display: 'flex',
|
|
60
|
+
height: 'max-content',
|
|
61
|
+
alignItems: 'center',
|
|
62
|
+
justifyContent: 'flex-end',
|
|
63
|
+
border: '1px solid #ddd',
|
|
64
|
+
borderRadius: '5px',
|
|
65
|
+
padding: '0 14px',
|
|
66
|
+
justifySelf: 'end',
|
|
67
|
+
maxWidth: '100%',
|
|
68
|
+
'& .MuiButtonBase-root, .MuiTableCell-root': {
|
|
69
|
+
padding: '0!important',
|
|
70
|
+
borderBottom: 'none',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
dateGroup: {
|
|
74
|
+
fontSize: '14px',
|
|
75
|
+
fontWeight: 'bold',
|
|
76
|
+
padding: '14px 0 5px 0',
|
|
77
|
+
borderBottom: '1px solid #ddd',
|
|
78
|
+
},
|
|
79
|
+
rowMenuContainer: {
|
|
80
|
+
paddingLeft: '10px',
|
|
81
|
+
'& .MuiButtonBase-root': {
|
|
82
|
+
width: '20px',
|
|
83
|
+
height: '20px',
|
|
84
|
+
padding: '8px',
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
copyButtonContainer: {
|
|
88
|
+
'& .MuiButtonBase-root': {
|
|
89
|
+
borderLeft: '1px solid #ddd',
|
|
90
|
+
borderRadius: '0',
|
|
91
|
+
borderRight: '1px solid #ddd',
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
copyButton: {
|
|
95
|
+
width: '32px',
|
|
96
|
+
height: '32px',
|
|
97
|
+
padding: '8px',
|
|
98
|
+
},
|
|
99
|
+
tooltipInfo: {
|
|
100
|
+
fontSize: '12px',
|
|
101
|
+
},
|
|
102
|
+
gridContainer: {
|
|
103
|
+
width: '100%',
|
|
104
|
+
display: 'grid',
|
|
105
|
+
columnGap: '20px',
|
|
106
|
+
gridTemplateColumns: 'repeat(5, 0.75fr) 1fr',
|
|
107
|
+
},
|
|
108
|
+
}, { index: 1 });
|
|
109
|
+
const SnapshotListItem = ({ snapshot, setSnapshotModal, openClonesModal, }) => {
|
|
110
|
+
var _a, _b;
|
|
111
|
+
const classes = useStyles();
|
|
112
|
+
const timeAgo = formatDistanceToNowStrict(snapshot.createdAtDate);
|
|
113
|
+
const history = useHistory();
|
|
114
|
+
const host = useHost();
|
|
115
|
+
return (_jsx("div", { className: classes.commitItem, children: _jsxs("div", { className: classes.gridContainer, children: [_jsxs("div", { className: classes.infoBlock, children: [_jsx("div", { className: classes.header, children: snapshot.message || '-' }), _jsxs("div", { className: classes.infoContent, title: snapshot.dataStateAt, children: [timeAgo, " ago"] })] }), _jsxs("div", { className: classes.infoBlock, children: [_jsx("div", { className: classes.header, children: "Pool" }), _jsx("div", { className: classes.infoContent, children: (_a = snapshot.pool) !== null && _a !== void 0 ? _a : '-' })] }), _jsxs("div", { className: classes.infoBlock, children: [_jsx("div", { className: classes.header, children: "Number of clones" }), _jsx("div", { className: classes.infoContent, children: (_b = snapshot.numClones) !== null && _b !== void 0 ? _b : '-' })] }), _jsxs("div", { className: classes.infoBlock, children: [_jsx("div", { className: classes.header, children: "Logical Size" }), _jsx("div", { className: classes.infoContent, children: snapshot.logicalSize ? formatBytesIEC(snapshot.logicalSize) : '-' })] }), _jsxs("div", { className: classes.infoBlock, children: [_jsx("div", { className: classes.header, children: "Physical Size" }), _jsx("div", { className: classes.infoContent, children: snapshot.physicalSize
|
|
116
|
+
? formatBytesIEC(snapshot.physicalSize)
|
|
117
|
+
: '-' })] }), _jsxs("div", { className: classes.actionsContainer, onClick: (e) => e.stopPropagation(), children: [_jsx("div", { className: classes.snapshotId, children: snapshot.id }), _jsx("div", { className: classes.copyButtonContainer, title: "Copy snapshot ID", children: _jsx(IconButton, { className: classes.copyButton, onClick: (e) => {
|
|
118
|
+
e.stopPropagation();
|
|
119
|
+
copy(snapshot.id);
|
|
120
|
+
}, children: icons.copyIcon }) }), _jsx("div", { className: classes.rowMenuContainer, title: "Actions", children: _jsx(RowMenu, { actions: [
|
|
121
|
+
{
|
|
122
|
+
name: 'Show related clones',
|
|
123
|
+
onClick: () => openClonesModal(),
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: 'Create new clone',
|
|
127
|
+
onClick: () => history.push(host.routes.createClone()),
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'Delete snapshot',
|
|
131
|
+
onClick: () => setSnapshotModal({
|
|
132
|
+
isOpen: true,
|
|
133
|
+
snapshotId: snapshot.id,
|
|
134
|
+
}),
|
|
135
|
+
}
|
|
136
|
+
] }) })] })] }) }));
|
|
137
|
+
};
|
|
138
|
+
export const SnapshotsList = observer(({ routes, filteredSnapshots, instanceId, }) => {
|
|
139
|
+
const classes = useStyles();
|
|
140
|
+
const stores = useStores();
|
|
141
|
+
const history = useHistory();
|
|
142
|
+
const groupedSnapshots = groupSnapshotsByCreatedAtDate(filteredSnapshots);
|
|
143
|
+
const [snapshotModal, setSnapshotModal] = React.useState({
|
|
144
|
+
isOpen: false,
|
|
145
|
+
snapshotId: '',
|
|
146
|
+
});
|
|
147
|
+
return (_jsxs(HorizontalScrollContainer, { children: [groupedSnapshots.map((group, index) => {
|
|
148
|
+
const groupDateFormatted = format(group[0].createdAtDate, 'MMM dd, yyyy');
|
|
149
|
+
return (_jsxs("div", { children: [_jsx("div", { className: classes.dateGroup, children: groupDateFormatted }), group.map((snapshot) => {
|
|
150
|
+
const snapshotPageId = generateSnapshotPageId(snapshot.id);
|
|
151
|
+
return (_jsx("div", { className: classes.pointerCursor, onClick: () => snapshotPageId &&
|
|
152
|
+
history.push(routes.snapshot(snapshotPageId)), children: _jsx(SnapshotListItem, { snapshot: snapshot, setSnapshotModal: setSnapshotModal, openClonesModal: () => stores.clonesModal.openModal({
|
|
153
|
+
snapshotId: snapshot.id,
|
|
154
|
+
}) }) }, snapshot.id));
|
|
155
|
+
})] }, index));
|
|
156
|
+
}), snapshotModal.isOpen && snapshotModal.snapshotId && (_jsx(DestroySnapshotModal, { isOpen: snapshotModal.isOpen, onClose: () => setSnapshotModal({ isOpen: false, snapshotId: '' }), snapshotId: snapshotModal.snapshotId, instanceId: instanceId, afterSubmitClick: () => stores.main.load(instanceId), destroySnapshot: stores.main.destroySnapshot }))] }));
|
|
157
|
+
});
|