added crud support for reports w/ burnettk
This commit is contained in:
parent
0ed60ab6e7
commit
0aa158d13b
|
@ -13,6 +13,8 @@ import ProcessModelEdit from './ProcessModelEdit';
|
||||||
import ProcessInstanceShow from './ProcessInstanceShow';
|
import ProcessInstanceShow from './ProcessInstanceShow';
|
||||||
import UserService from '../services/UserService';
|
import UserService from '../services/UserService';
|
||||||
import ProcessInstanceReportList from './ProcessInstanceReportList';
|
import ProcessInstanceReportList from './ProcessInstanceReportList';
|
||||||
|
import ProcessInstanceReportNew from './ProcessInstanceReportNew';
|
||||||
|
import ProcessInstanceReportEdit from './ProcessInstanceReportEdit';
|
||||||
|
|
||||||
export default function AdminRoutes() {
|
export default function AdminRoutes() {
|
||||||
if (UserService.hasRole(['admin'])) {
|
if (UserService.hasRole(['admin'])) {
|
||||||
|
@ -78,6 +80,14 @@ export default function AdminRoutes() {
|
||||||
// @ts-expect-error TS(2786) FIXME: 'ProcessInstanceReport' cannot be used as a JSX co... Remove this comment to see the full error message
|
// @ts-expect-error TS(2786) FIXME: 'ProcessInstanceReport' cannot be used as a JSX co... Remove this comment to see the full error message
|
||||||
element={<ProcessInstanceReportShow />}
|
element={<ProcessInstanceReportShow />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="process-models/:process_group_id/:process_model_id/process-instances/reports/new"
|
||||||
|
element={<ProcessInstanceReportNew />}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="process-models/:process_group_id/:process_model_id/process-instances/reports/:report_identifier/edit"
|
||||||
|
element={<ProcessInstanceReportEdit />}
|
||||||
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,189 @@
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import { Button } from 'react-bootstrap';
|
||||||
|
import { BACKEND_BASE_URL, HOT_AUTH_TOKEN } from '../config';
|
||||||
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
|
|
||||||
|
type ReportColumn = {
|
||||||
|
Header: string;
|
||||||
|
accessor: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ReportFilterBy = {
|
||||||
|
field_name: string;
|
||||||
|
operator: string;
|
||||||
|
field_value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ProcessInstanceReportEdit() {
|
||||||
|
const params = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [columns, setColumns] = useState('');
|
||||||
|
const [orderBy, setOrderBy] = useState('');
|
||||||
|
const [filterBy, setFilterBy] = useState('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function getProcessInstanceReport() {
|
||||||
|
fetch(
|
||||||
|
`${BACKEND_BASE_URL}/process-models/${params.process_group_id}/${params.process_model_id}/process-instances/reports/${params.report_identifier}?per_page=1`,
|
||||||
|
{
|
||||||
|
headers: new Headers({
|
||||||
|
Authorization: `Bearer ${HOT_AUTH_TOKEN}`,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then(
|
||||||
|
(result) => {
|
||||||
|
const reportMetadata = result.report_metadata;
|
||||||
|
const columnCsv = reportMetadata.columns
|
||||||
|
.map((column: ReportColumn) => column.accessor)
|
||||||
|
.join(',');
|
||||||
|
setColumns(columnCsv);
|
||||||
|
|
||||||
|
if (reportMetadata.order_by) {
|
||||||
|
setOrderBy(reportMetadata.order_by.join(','));
|
||||||
|
}
|
||||||
|
const filterByCsv = reportMetadata.filter_by
|
||||||
|
.map(
|
||||||
|
(filterByItem: ReportFilterBy) =>
|
||||||
|
`${filterByItem.field_name}=${filterByItem.field_value}`
|
||||||
|
)
|
||||||
|
.join(',');
|
||||||
|
setFilterBy(filterByCsv);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getProcessInstanceReport();
|
||||||
|
}, [params]);
|
||||||
|
|
||||||
|
const editProcessInstanceReport = (event: any) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const columnArray = columns.split(',').map((column) => {
|
||||||
|
return { Header: column, accessor: column };
|
||||||
|
});
|
||||||
|
const orderByArray = orderBy.split(',').filter((n) => n);
|
||||||
|
|
||||||
|
const filterByArray = filterBy
|
||||||
|
.split(',')
|
||||||
|
.map((filterByItem) => {
|
||||||
|
const [fieldName, fieldValue] = filterByItem.split('=');
|
||||||
|
if (fieldValue) {
|
||||||
|
return {
|
||||||
|
field_name: fieldName,
|
||||||
|
operator: 'equals',
|
||||||
|
field_value: fieldValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.filter((n) => n);
|
||||||
|
|
||||||
|
fetch(
|
||||||
|
`${BACKEND_BASE_URL}/process-models/${params.process_group_id}/${params.process_model_id}/process-instances/reports/${params.report_identifier}`,
|
||||||
|
{
|
||||||
|
headers: new Headers({
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${HOT_AUTH_TOKEN}`,
|
||||||
|
}),
|
||||||
|
method: 'PUT',
|
||||||
|
body: JSON.stringify({
|
||||||
|
report_metadata: {
|
||||||
|
columns: columnArray,
|
||||||
|
order_by: orderByArray,
|
||||||
|
filter_by: filterByArray,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
).then(
|
||||||
|
() => {
|
||||||
|
navigate(
|
||||||
|
`/admin/process-models/${params.process_group_id}/${params.process_model_id}/process-instances/reports/${params.report_identifier}`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// Note: it's important to handle errors here
|
||||||
|
// instead of a catch() block so that we don't swallow
|
||||||
|
// exceptions from actual bugs in components.
|
||||||
|
(newError) => {
|
||||||
|
console.log(newError);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteProcessInstanceReport = () => {
|
||||||
|
fetch(
|
||||||
|
`${BACKEND_BASE_URL}/process-models/${params.process_group_id}/${params.process_model_id}/process-instances/reports/${params.report_identifier}`,
|
||||||
|
{
|
||||||
|
headers: new Headers({
|
||||||
|
Authorization: `Bearer ${HOT_AUTH_TOKEN}`,
|
||||||
|
}),
|
||||||
|
method: 'DELETE',
|
||||||
|
}
|
||||||
|
).then(
|
||||||
|
() => {
|
||||||
|
navigate(
|
||||||
|
`/admin/process-models/${params.process_group_id}/${params.process_model_id}/process-instances/reports`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main style={{ padding: '1rem 0' }}>
|
||||||
|
<ProcessBreadcrumb />
|
||||||
|
<h2>Edit Process Instance Report: {params.report_identifier}</h2>
|
||||||
|
<Button onClick={deleteProcessInstanceReport} variant="danger">
|
||||||
|
Delete report
|
||||||
|
</Button>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<form onSubmit={editProcessInstanceReport}>
|
||||||
|
<label htmlFor="columns">
|
||||||
|
columns:
|
||||||
|
<input
|
||||||
|
name="columns"
|
||||||
|
id="columns"
|
||||||
|
type="text"
|
||||||
|
value={columns}
|
||||||
|
onChange={(e) => setColumns(e.target.value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label htmlFor="order_by">
|
||||||
|
order_by:
|
||||||
|
<input
|
||||||
|
name="order_by"
|
||||||
|
id="order_by"
|
||||||
|
type="text"
|
||||||
|
value={orderBy}
|
||||||
|
onChange={(e) => setOrderBy(e.target.value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<p>Like: month=3,milestone=2</p>
|
||||||
|
<label htmlFor="filter_by">
|
||||||
|
filter_by:
|
||||||
|
<input
|
||||||
|
name="filter_by"
|
||||||
|
id="filter_by"
|
||||||
|
type="text"
|
||||||
|
value={filterBy}
|
||||||
|
onChange={(e) => setFilterBy(e.target.value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Table } from 'react-bootstrap';
|
import { Button, Table } from 'react-bootstrap';
|
||||||
import { useParams, Link } from 'react-router-dom';
|
import { useParams, Link } from 'react-router-dom';
|
||||||
import { BACKEND_BASE_URL, HOT_AUTH_TOKEN } from '../config';
|
import { BACKEND_BASE_URL, HOT_AUTH_TOKEN } from '../config';
|
||||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
|
@ -68,6 +68,11 @@ export default function ProcessInstanceReportList() {
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
{headerStuff}
|
{headerStuff}
|
||||||
|
<Button
|
||||||
|
href={`/admin/process-models/${params.process_group_id}/${params.process_model_id}/process-instances/reports/new`}
|
||||||
|
>
|
||||||
|
Add a process instance report
|
||||||
|
</Button>
|
||||||
{buildTable()}
|
{buildTable()}
|
||||||
</main>
|
</main>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import { BACKEND_BASE_URL, HOT_AUTH_TOKEN } from '../config';
|
||||||
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
|
|
||||||
|
export default function ProcessInstanceReportNew() {
|
||||||
|
const params = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [identifier, setIdentifier] = useState('');
|
||||||
|
const [columns, setColumns] = useState('');
|
||||||
|
const [orderBy, setOrderBy] = useState('');
|
||||||
|
const [filterBy, setFilterBy] = useState('');
|
||||||
|
|
||||||
|
const addProcessInstanceReport = (event: any) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const columnArray = columns.split(',').map((column) => {
|
||||||
|
return { Header: column, accessor: column };
|
||||||
|
});
|
||||||
|
const orderByArray = orderBy.split(',').filter((n) => n);
|
||||||
|
|
||||||
|
const filterByArray = filterBy
|
||||||
|
.split(',')
|
||||||
|
.map((filterByItem) => {
|
||||||
|
const [fieldName, fieldValue] = filterByItem.split('=');
|
||||||
|
if (fieldValue) {
|
||||||
|
return {
|
||||||
|
field_name: fieldName,
|
||||||
|
operator: 'equals',
|
||||||
|
field_value: fieldValue,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.filter((n) => n);
|
||||||
|
|
||||||
|
fetch(
|
||||||
|
`${BACKEND_BASE_URL}/process-models/${params.process_group_id}/${params.process_model_id}/process-instances/reports`,
|
||||||
|
{
|
||||||
|
headers: new Headers({
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: `Bearer ${HOT_AUTH_TOKEN}`,
|
||||||
|
}),
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
identifier,
|
||||||
|
report_metadata: {
|
||||||
|
columns: columnArray,
|
||||||
|
order_by: orderByArray,
|
||||||
|
filter_by: filterByArray,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
).then(
|
||||||
|
() => {
|
||||||
|
navigate(
|
||||||
|
`/admin/process-models/${params.process_group_id}/${params.process_model_id}/process-instances/reports/${identifier}`
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// Note: it's important to handle errors here
|
||||||
|
// instead of a catch() block so that we don't swallow
|
||||||
|
// exceptions from actual bugs in components.
|
||||||
|
(newError) => {
|
||||||
|
console.log(newError);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main style={{ padding: '1rem 0' }}>
|
||||||
|
<ProcessBreadcrumb />
|
||||||
|
<h2>Add Process Model</h2>
|
||||||
|
<form onSubmit={addProcessInstanceReport}>
|
||||||
|
<label htmlFor="identifier">
|
||||||
|
identifier:
|
||||||
|
<input
|
||||||
|
name="identifier"
|
||||||
|
id="identifier"
|
||||||
|
type="text"
|
||||||
|
value={identifier}
|
||||||
|
onChange={(e) => setIdentifier(e.target.value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label htmlFor="columns">
|
||||||
|
columns:
|
||||||
|
<input
|
||||||
|
name="columns"
|
||||||
|
id="columns"
|
||||||
|
type="text"
|
||||||
|
value={columns}
|
||||||
|
onChange={(e) => setColumns(e.target.value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<label htmlFor="order_by">
|
||||||
|
order_by:
|
||||||
|
<input
|
||||||
|
name="order_by"
|
||||||
|
id="order_by"
|
||||||
|
type="text"
|
||||||
|
value={orderBy}
|
||||||
|
onChange={(e) => setOrderBy(e.target.value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<p>Like: month=3,milestone=2</p>
|
||||||
|
<label htmlFor="filter_by">
|
||||||
|
filter_by:
|
||||||
|
<input
|
||||||
|
name="filter_by"
|
||||||
|
id="filter_by"
|
||||||
|
type="text"
|
||||||
|
value={filterBy}
|
||||||
|
onChange={(e) => setFilterBy(e.target.value)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useParams, useSearchParams } from 'react-router-dom';
|
import { useParams, useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
import { Table } from 'react-bootstrap';
|
import { Button, Table } from 'react-bootstrap';
|
||||||
import { BACKEND_BASE_URL, HOT_AUTH_TOKEN } from '../config';
|
import { BACKEND_BASE_URL, HOT_AUTH_TOKEN } from '../config';
|
||||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
|
|
||||||
|
@ -46,7 +46,6 @@ export default function ProcessInstanceReport() {
|
||||||
(result) => {
|
(result) => {
|
||||||
const processInstancesFromApi = result.results;
|
const processInstancesFromApi = result.results;
|
||||||
setProcessInstances(processInstancesFromApi);
|
setProcessInstances(processInstancesFromApi);
|
||||||
console.log('result.report_metaadata', result.report_metadata);
|
|
||||||
setReportMetadata(result.report_metadata);
|
setReportMetadata(result.report_metadata);
|
||||||
setPagination(result.pagination);
|
setPagination(result.pagination);
|
||||||
},
|
},
|
||||||
|
@ -97,6 +96,11 @@ export default function ProcessInstanceReport() {
|
||||||
linkProcessModel="true"
|
linkProcessModel="true"
|
||||||
/>
|
/>
|
||||||
<h2>Process Instance Report: {params.report_identifier}</h2>
|
<h2>Process Instance Report: {params.report_identifier}</h2>
|
||||||
|
<Button
|
||||||
|
href={`/admin/process-models/${params.process_group_id}/${params.process_model_id}/process-instances/reports/${params.report_identifier}/edit`}
|
||||||
|
>
|
||||||
|
Edit process instance report
|
||||||
|
</Button>
|
||||||
<PaginationForTable
|
<PaginationForTable
|
||||||
page={page}
|
page={page}
|
||||||
perPage={perPage}
|
perPage={perPage}
|
||||||
|
|
Loading…
Reference in New Issue