pgadmin4/web/pgadmin/misc/bgprocess/static/js/Processes.jsx
2022-08-11 10:49:45 +05:30

291 lines
8.1 KiB
JavaScript

/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import React, { useEffect } from 'react';
import PgTable from 'sources/components/PgTable';
import gettext from 'sources/gettext';
import PropTypes from 'prop-types';
import { makeStyles } from '@material-ui/core/styles';
import pgAdmin from 'sources/pgadmin';
import { BgProcessManagerEvents, BgProcessManagerProcessState } from './BgProcessManager';
import { PgIconButton } from '../../../../static/js/components/Buttons';
import CancelIcon from '@material-ui/icons/Cancel';
import DescriptionOutlinedIcon from '@material-ui/icons/DescriptionOutlined';
import DeleteIcon from '@material-ui/icons/Delete';
import HelpIcon from '@material-ui/icons/HelpRounded';
import url_for from 'sources/url_for';
import { Box } from '@material-ui/core';
const useStyles = makeStyles((theme) => ({
stopButton: {
color: theme.palette.error.main
},
buttonClick: {
backgroundColor: theme.palette.grey[400]
},
emptyPanel: {
minHeight: '100%',
minWidth: '100%',
background: theme.otherVars.emptySpaceBg,
overflow: 'auto',
padding: '8px',
display: 'flex',
},
panelIcon: {
width: '80%',
margin: '0 auto',
marginTop: '25px !important',
position: 'relative',
textAlign: 'center',
},
panelMessage: {
marginLeft: '0.5rem',
fontSize: '0.875rem',
},
autoResizer: {
height: '100% !important',
width: '100% !important',
background: theme.palette.grey[400],
padding: '7.5px',
overflow: 'auto !important',
minHeight: '100%',
minWidth: '100%',
},
noPadding: {
padding: 0,
},
bgSucess: {
backgroundColor: theme.palette.success.light,
height: '100%',
padding: '4px',
},
bgFailed: {
backgroundColor: theme.palette.error.light,
height: '100%',
padding: '4px',
},
bgTerm: {
backgroundColor: theme.palette.warning.light,
height: '100%',
padding: '4px',
},
bgRunning: {
backgroundColor: theme.palette.primary.light,
height: '100%',
padding: '4px',
},
}));
const ProcessStateTextAndColor = {
[BgProcessManagerProcessState.PROCESS_NOT_STARTED]: [gettext('Not started'), 'bgRunning'],
[BgProcessManagerProcessState.PROCESS_STARTED]: [gettext('Running'), 'bgRunning'],
[BgProcessManagerProcessState.PROCESS_FINISHED]: [gettext('Finished'), 'bgSucess'],
[BgProcessManagerProcessState.PROCESS_TERMINATED]: [gettext('Terminated'), 'bgTerm'],
[BgProcessManagerProcessState.PROCESS_TERMINATING]: [gettext('Terminating...'), 'bgTerm'],
[BgProcessManagerProcessState.PROCESS_FAILED]: [gettext('Failed'), 'bgFailed'],
};
export default function Processes() {
const classes = useStyles();
const [tableData, setTableData] = React.useState([]);
const [selectedRows, setSelectedRows] = React.useState([]);
let columns = [
{
accessor: 'stop_process',
Header: () => null,
sortable: false,
resizable: false,
disableGlobalFilter: true,
width: 35,
maxWidth: 35,
minWidth: 35,
id: 'btn-stop',
// eslint-disable-next-line react/display-name
Cell: ({ row }) => {
return (
<PgIconButton
size="xs"
noBorder
icon={<CancelIcon />}
className={classes.stopButton}
disabled={row.original.process_state != BgProcessManagerProcessState.PROCESS_STARTED
|| row.original.server_id != null}
onClick={(e) => {
e.preventDefault();
pgAdmin.Browser.BgProcessManager.stopProcess(row.original.id);
}}
aria-label="Stop Process"
title={gettext('Stop Process')}
></PgIconButton>
);
},
},
{
accessor: 'view_details',
Header: () => null,
sortable: false,
resizable: false,
disableGlobalFilter: true,
width: 35,
maxWidth: 35,
minWidth: 35,
id: 'btn-logs',
// eslint-disable-next-line react/display-name
Cell: ({ row }) => {
return (
<PgIconButton
size="xs"
icon={<DescriptionOutlinedIcon />}
noBorder
onClick={(e) => {
e.preventDefault();
pgAdmin.Browser.BgProcessManager.viewJobDetails(row.original.id);
}}
aria-label="View details"
title={gettext('View details')}
/>
);
},
},
{
Header: gettext('PID'),
accessor: 'utility_pid',
sortable: true,
resizable: false,
width: 70,
minWidth: 70,
disableGlobalFilter: false,
},
{
Header: gettext('Type'),
accessor: (row)=>row.details?.type,
sortable: true,
resizable: true,
width: 100,
minWidth: 70,
disableGlobalFilter: false,
},
{
Header: gettext('Server'),
accessor: (row)=>row.details?.server,
sortable: true,
resizable: true,
width: 200,
minWidth: 120,
disableGlobalFilter: false,
},
{
Header: gettext('Object'),
accessor: (row)=>row.details?.object,
sortable: true,
resizable: true,
width: 200,
minWidth: 120,
disableGlobalFilter: false,
},
{
id: 'stime',
Header: gettext('Start Time'),
sortable: true,
resizable: true,
disableGlobalFilter: true,
width: 150,
minWidth: 150,
accessor: (row)=>(new Date(row.stime)),
Cell: ({row})=>(new Date(row.original.stime).toLocaleString()),
},
{
Header: gettext('Status'),
sortable: true,
resizable: false,
disableGlobalFilter: false,
width: 120,
minWidth: 120,
accessor: (row)=>ProcessStateTextAndColor[row.process_state][0],
dataClassName: classes.noPadding,
Cell: ({row})=>{
const [text, bgcolor] = ProcessStateTextAndColor[row.original.process_state];
return <Box className={classes[bgcolor]}>{text}</Box>;
},
},
{
Header: gettext('Time Taken'),
accessor: 'execution_time',
sortable: true,
resizable: true,
disableGlobalFilter: true,
},
];
const updateList = ()=>{
if(pgAdmin.Browser.BgProcessManager.procList) {
setTableData([...pgAdmin.Browser.BgProcessManager.procList]);
}
};
useEffect(() => {
updateList();
pgAdmin.Browser.BgProcessManager.registerListener(BgProcessManagerEvents.LIST_UPDATED, updateList);
return ()=>{
pgAdmin.Browser.BgProcessManager.deregisterListener(BgProcessManagerEvents.LIST_UPDATED, updateList);
};
}, []);
return (
<>
<PgTable
data-test="processes"
className={classes.autoResizer}
columns={columns}
data={tableData}
sortOptions={[{id: 'stime', desc: true}]}
getSelectedRows={(rows)=>{setSelectedRows(rows);}}
isSelectRow={true}
CustomHeader={()=>{
return (
<Box>
<PgIconButton
className={classes.dropButton}
icon={<DeleteIcon/>}
aria-label="Acknowledge and Remove"
title={gettext('Acknowledge and Remove')}
onClick={() => {
pgAdmin.Browser.BgProcessManager.acknowledge(selectedRows.map((p)=>p.original.id));
}}
disabled={selectedRows.length <= 0}
></PgIconButton>
<PgIconButton
icon={<HelpIcon/>}
aria-label="Help"
title={gettext('Help')}
style={{marginLeft: '8px'}}
onClick={() => {
window.open(url_for('help.static', {'filename': 'processes.html'}));
}}
></PgIconButton>
</Box>
);
}}
></PgTable>
</>
);
}
Processes.propTypes = {
res: PropTypes.array,
nodeData: PropTypes.object,
treeNodeInfo: PropTypes.object,
node: PropTypes.func,
item: PropTypes.object,
row: PropTypes.object,
};