some updates to fix up saving perspectives w/ burnettk

This commit is contained in:
jasquat 2022-12-05 14:07:26 -05:00
parent ebcc523871
commit 3aae7a4018
5 changed files with 165 additions and 115 deletions

View File

@ -2,8 +2,8 @@ import { useState } from 'react';
import { import {
Button, Button,
TextInput, TextInput,
Form,
Stack, Stack,
Modal,
// @ts-ignore // @ts-ignore
} from '@carbon/react'; } from '@carbon/react';
import { import {
@ -42,26 +42,31 @@ export default function ProcessInstanceListSaveAsReport({
startToSeconds, startToSeconds,
endFromSeconds, endFromSeconds,
endToSeconds, endToSeconds,
buttonText = 'Save as Perspective',
buttonClassName, buttonClassName,
buttonText = 'Save as Perspective',
reportMetadata, reportMetadata,
}: OwnProps) { }: OwnProps) {
const [identifier, setIdentifier] = useState<string>( const [identifier, setIdentifier] = useState<string>(
processInstanceReportSelection?.identifier || '' processInstanceReportSelection?.identifier || ''
); );
const [showSaveForm, setShowSaveForm] = useState<boolean>(false);
const hasIdentifier = () => { const isEditMode = () => {
return identifier?.length > 0; return (
processInstanceReportSelection &&
processInstanceReportSelection.identifier === identifier
);
}; };
const responseHandler = (result: any) => { const responseHandler = (result: any) => {
if (result) { if (result) {
onSuccess(result); onSuccess(result, isEditMode() ? 'edit' : 'new');
} }
}; };
const isEditMode = () => { const handleSaveFormClose = () => {
return !!processInstanceReportSelection; setIdentifier(processInstanceReportSelection?.identifier || '');
setShowSaveForm(false);
}; };
const addProcessInstanceReport = (event: any) => { const addProcessInstanceReport = (event: any) => {
@ -148,36 +153,53 @@ export default function ProcessInstanceListSaveAsReport({
}, },
}, },
}); });
handleSaveFormClose();
}; };
let textInputComponent = null; let textInputComponent = null;
if (!isEditMode()) { textInputComponent = (
textInputComponent = ( <TextInput
<TextInput id="identifier"
id="identifier" name="identifier"
name="identifier" labelText="Identifier"
labelText="Identifier" className="no-wrap"
className="no-wrap" inline
inline value={identifier}
value={identifier} onChange={(e: any) => setIdentifier(e.target.value)}
onChange={(e: any) => setIdentifier(e.target.value)} />
/> );
);
let descriptionText =
'Save the current columns and filters as a perspective so you can come back to this view in the future.';
if (processInstanceReportSelection) {
descriptionText =
'Keep the identifier the same and click Save to update the current perspective. Change the identifier if you want to save the current view with a new name.';
} }
return ( return (
<Form onSubmit={addProcessInstanceReport}> <Stack gap={5} orientation="horizontal">
<Stack gap={5} orientation="horizontal"> <Modal
open={showSaveForm}
modalHeading="Save Perspective"
primaryButtonText="Save"
primaryButtonDisabled={!identifier}
onRequestSubmit={addProcessInstanceReport}
onRequestClose={handleSaveFormClose}
hasScrollingContent
>
<p className="data-table-description">{descriptionText}</p>
{textInputComponent} {textInputComponent}
<Button </Modal>
disabled={!hasIdentifier()} <Button
size="sm" kind=""
type="submit" className={buttonClassName}
className={buttonClassName} onClick={() => {
> setIdentifier(processInstanceReportSelection?.identifier || '');
{buttonText} setShowSaveForm(true);
</Button> }}
</Stack> >
</Form> {buttonText}
</Button>
</Stack>
); );
} }

View File

@ -639,13 +639,14 @@ export default function ProcessInstanceListTable({
} }
return ( return (
<ProcessInstanceListSaveAsReport <ProcessInstanceListSaveAsReport
onSuccess={(result: any) => onSaveReportSuccess(result, 'new')} onSuccess={onSaveReportSuccess}
buttonClassName="narrow-button" buttonClassName="button-white-background narrow-button"
columnArray={reportColumns()} columnArray={reportColumns()}
orderBy="" orderBy=""
buttonText="Save New Perspective" buttonText="Save"
processModelSelection={processModelSelection} processModelSelection={processModelSelection}
processStatusSelection={processStatusSelection} processStatusSelection={processStatusSelection}
processInstanceReportSelection={processInstanceReportSelection}
reportMetadata={reportMetadata} reportMetadata={reportMetadata}
startFromSeconds={startFromSeconds} startFromSeconds={startFromSeconds}
startToSeconds={startToSeconds} startToSeconds={startToSeconds}
@ -871,8 +872,10 @@ export default function ProcessInstanceListTable({
reportColumnToReportColumnForEditing(reportColumn); reportColumnToReportColumnForEditing(reportColumn);
let tagType = 'cool-gray'; let tagType = 'cool-gray';
let tagTypeClass = '';
if (reportColumnForEditing.filterable) { if (reportColumnForEditing.filterable) {
tagType = 'green'; tagType = 'green';
tagTypeClass = 'tag-type-green';
} }
let reportColumnLabel = reportColumnForEditing.Header; let reportColumnLabel = reportColumnForEditing.Header;
if (reportColumnForEditing.filter_field_value) { if (reportColumnForEditing.filter_field_value) {
@ -883,7 +886,7 @@ export default function ProcessInstanceListTable({
<Button <Button
kind="ghost" kind="ghost"
size="sm" size="sm"
className="button-tag-icon" className={`button-tag-icon ${tagTypeClass}`}
title={`Edit ${reportColumnForEditing.accessor}`} title={`Edit ${reportColumnForEditing.accessor}`}
onClick={() => { onClick={() => {
setReportColumnToOperateOn(reportColumnForEditing); setReportColumnToOperateOn(reportColumnForEditing);
@ -897,7 +900,7 @@ export default function ProcessInstanceListTable({
data-qa="remove-report-column" data-qa="remove-report-column"
renderIcon={Close} renderIcon={Close}
iconDescription="Remove Column" iconDescription="Remove Column"
className="button-tag-icon" className={`button-tag-icon ${tagTypeClass}`}
hasIconOnly hasIconOnly
size="sm" size="sm"
kind="ghost" kind="ghost"
@ -1004,9 +1007,6 @@ export default function ProcessInstanceListTable({
</Column> </Column>
</Grid> </Grid>
<Grid fullWidth className="with-bottom-margin"> <Grid fullWidth className="with-bottom-margin">
<Column sm={4} md={4} lg={8}>
{saveAsReportComponent()}
</Column>
<Column sm={4} md={4} lg={8}> <Column sm={4} md={4} lg={8}>
<ButtonSet> <ButtonSet>
<Button <Button
@ -1026,6 +1026,9 @@ export default function ProcessInstanceListTable({
</Button> </Button>
</ButtonSet> </ButtonSet>
</Column> </Column>
<Column sm={4} md={4} lg={8}>
{saveAsReportComponent()}
</Column>
</Grid> </Grid>
</> </>
); );
@ -1139,8 +1142,6 @@ export default function ProcessInstanceListTable({
const reportSearchComponent = () => { const reportSearchComponent = () => {
if (showReports) { if (showReports) {
const { startFromSeconds, startToSeconds, endFromSeconds, endToSeconds } =
calculateStartAndEndSeconds();
const columns = [ const columns = [
<Column sm={2} md={4} lg={7}> <Column sm={2} md={4} lg={7}>
<ProcessInstanceReportSearch <ProcessInstanceReportSearch
@ -1149,31 +1150,6 @@ export default function ProcessInstanceListTable({
/> />
</Column>, </Column>,
]; ];
if (
processInstanceReportSelection &&
showFilterOptions &&
reportMetadata
) {
columns.push(
<Column sm={2} md={4} lg={2}>
<ProcessInstanceListSaveAsReport
buttonClassName="with-tiny-top-margin"
onSuccess={(result: any) => onSaveReportSuccess(result, 'edit')}
columnArray={reportColumns()}
orderBy=""
buttonText="Save"
processModelSelection={processModelSelection}
processStatusSelection={processStatusSelection}
reportMetadata={reportMetadata}
startFromSeconds={startFromSeconds}
startToSeconds={startToSeconds}
endFromSeconds={endFromSeconds}
endToSeconds={endToSeconds}
processInstanceReportSelection={processInstanceReportSelection}
/>
</Column>
);
}
return ( return (
<Grid className="with-tiny-bottom-margin" fullWidth> <Grid className="with-tiny-bottom-margin" fullWidth>
{columns} {columns}

View File

@ -5,6 +5,7 @@ import {
FormLabel, FormLabel,
// @ts-ignore // @ts-ignore
} from '@carbon/react'; } from '@carbon/react';
import { useSearchParams } from 'react-router-dom';
import { truncateString } from '../helpers'; import { truncateString } from '../helpers';
import { ProcessInstanceReport } from '../interfaces'; import { ProcessInstanceReport } from '../interfaces';
import HttpService from '../services/HttpService'; import HttpService from '../services/HttpService';
@ -24,6 +25,9 @@ export default function ProcessInstanceReportSearch({
ProcessInstanceReport[] | null ProcessInstanceReport[] | null
>(null); >(null);
const [searchParams] = useSearchParams();
const reportId = searchParams.get('report_id');
useEffect(() => { useEffect(() => {
function setProcessInstanceReportsFromResult( function setProcessInstanceReportsFromResult(
result: ProcessInstanceReport[] result: ProcessInstanceReport[]
@ -31,12 +35,11 @@ export default function ProcessInstanceReportSearch({
setProcessInstanceReports(result); setProcessInstanceReports(result);
} }
setProcessInstanceReports([]);
HttpService.makeCallToBackend({ HttpService.makeCallToBackend({
path: `/process-instances/reports`, path: `/process-instances/reports`,
successCallback: setProcessInstanceReportsFromResult, successCallback: setProcessInstanceReportsFromResult,
}); });
}, []); }, [reportId]);
const reportSelectionString = ( const reportSelectionString = (
processInstanceReport: ProcessInstanceReport processInstanceReport: ProcessInstanceReport

View File

@ -1,9 +1,17 @@
import { useState } from 'react'; import { useState } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import {
Button,
ButtonSet,
Form,
Stack,
TextInput,
Grid,
Column,
// @ts-ignore
} from '@carbon/react';
// @ts-ignore // @ts-ignore
import { Button, ButtonSet, Form, Stack, TextInput } from '@carbon/react'; import { AddAlt, TrashCan } from '@carbon/icons-react';
// @ts-ignore
import { AddAlt } from '@carbon/icons-react';
import { modifyProcessIdentifierForPathParam, slugifyString } from '../helpers'; import { modifyProcessIdentifierForPathParam, slugifyString } from '../helpers';
import HttpService from '../services/HttpService'; import HttpService from '../services/HttpService';
import { MetadataExtractionPath, ProcessModel } from '../interfaces'; import { MetadataExtractionPath, ProcessModel } from '../interfaces';
@ -96,43 +104,59 @@ export default function ProcessModelForm({
metadataExtractionPath: MetadataExtractionPath metadataExtractionPath: MetadataExtractionPath
) => { ) => {
return ( return (
<> <Grid>
<TextInput <Column md={3} lg={7} sm={1}>
id="process-model-metadata-extraction-path-key" <TextInput
labelText="Extraction Key" id={`process-model-metadata-extraction-path-key-${index}`}
value={metadataExtractionPath.key} labelText="Extraction Key"
onChange={(event: any) => { value={metadataExtractionPath.key}
const cep: MetadataExtractionPath[] = onChange={(event: any) => {
processModel.metadata_extraction_paths || []; const cep: MetadataExtractionPath[] =
const newMeta = { ...metadataExtractionPath }; processModel.metadata_extraction_paths || [];
newMeta.key = event.target.value; const newMeta = { ...metadataExtractionPath };
cep[index] = newMeta; newMeta.key = event.target.value;
updateProcessModel({ metadata_extraction_paths: cep }); cep[index] = newMeta;
}} updateProcessModel({ metadata_extraction_paths: cep });
/> }}
<TextInput />
id="process-model-metadata-extraction-path" </Column>
labelText="Extraction Path" <Column md={4} lg={8} sm={2}>
value={metadataExtractionPath.path} <TextInput
onChange={(event: any) => { id={`process-model-metadata-extraction-path-${index}`}
const cep: MetadataExtractionPath[] = labelText="Extraction Path"
processModel.metadata_extraction_paths || []; value={metadataExtractionPath.path}
const newMeta = { ...metadataExtractionPath }; onChange={(event: any) => {
newMeta.path = event.target.value; const cep: MetadataExtractionPath[] =
cep[index] = newMeta; processModel.metadata_extraction_paths || [];
updateProcessModel({ metadata_extraction_paths: cep }); const newMeta = { ...metadataExtractionPath };
}} newMeta.path = event.target.value;
/> cep[index] = newMeta;
</> updateProcessModel({ metadata_extraction_paths: cep });
}}
/>
</Column>
<Column md={1} lg={1} sm={1}>
<Button
kind="ghost"
renderIcon={TrashCan}
iconDescription="Remove Key"
hasIconOnly
size="lg"
className="with-extra-top-margin"
onClick={() => {
const cep: MetadataExtractionPath[] =
processModel.metadata_extraction_paths || [];
cep.splice(index, 1);
updateProcessModel({ metadata_extraction_paths: cep });
}}
/>
</Column>
</Grid>
); );
}; };
const metadataExtractionPathFormArea = () => { const metadataExtractionPathFormArea = () => {
if (processModel.metadata_extraction_paths) { if (processModel.metadata_extraction_paths) {
console.log(
'processModel.metadata_extraction_paths',
processModel.metadata_extraction_paths
);
return processModel.metadata_extraction_paths.map( return processModel.metadata_extraction_paths.map(
(metadataExtractionPath: MetadataExtractionPath, index: number) => { (metadataExtractionPath: MetadataExtractionPath, index: number) => {
return metadataExtractionPathForm(index, metadataExtractionPath); return metadataExtractionPathForm(index, metadataExtractionPath);
@ -207,20 +231,36 @@ export default function ProcessModelForm({
/> />
); );
textInputs.push(<h2>Metadata Extractions</h2>);
textInputs.push(
<Grid>
<Column md={8} lg={16} sm={4}>
<p className="data-table-description">
You can provide one or more metadata extractions to pull data from
your process instances to provide quick access in searches and
perspectives.
</p>
</Column>
</Grid>
);
textInputs.push(<>{metadataExtractionPathFormArea()}</>); textInputs.push(<>{metadataExtractionPathFormArea()}</>);
textInputs.push( textInputs.push(
<Button <Grid>
data-qa="add-metadata-extraction-path-button" <Column md={4} lg={8} sm={2}>
renderIcon={AddAlt} <Button
className="button-white-background" data-qa="add-metadata-extraction-path-button"
kind="" renderIcon={AddAlt}
size="sm" className="button-white-background"
onClick={() => { kind=""
addBlankMetadataExtractionPath(); size="sm"
}} onClick={() => {
> addBlankMetadataExtractionPath();
Add Metadata Extraction Path }}
</Button> >
Add Metadata Extraction Path
</Button>
</Column>
</Grid>
); );
return textInputs; return textInputs;

View File

@ -169,6 +169,10 @@ h1.with-icons {
margin-top: 1em; margin-top: 1em;
} }
.with-extra-top-margin {
margin-top: 1.3em;
}
.with-tiny-top-margin { .with-tiny-top-margin {
margin-top: 4px; margin-top: 4px;
} }
@ -353,3 +357,8 @@ td.actions-cell {
word-break: normal; word-break: normal;
} }
.tag-type-green:hover {
background-color: #00FF00;
}