139 lines
5.3 KiB
TypeScript
139 lines
5.3 KiB
TypeScript
import React, { Component } from "react";
|
|
import deepFind from "../../utils/deepfind";
|
|
import Column from "./columns";
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
import { faBook, faBookJournalWhills, faEdit, faTrash } from "@fortawesome/free-solid-svg-icons";
|
|
import { Link } from "react-router-dom";
|
|
import ConfirmButton from "./ConfirmButton";
|
|
import { Buffer } from 'buffer';
|
|
import Button, { ButtonType } from "./Button";
|
|
import { DateView } from "./DateView";
|
|
|
|
export interface AuditParams{
|
|
entityName : string,
|
|
primaryKey : string
|
|
}
|
|
|
|
export interface TableBodyProps<T>{
|
|
data : T[] | undefined;
|
|
keyName : string;
|
|
columns : Column<T>[];
|
|
editPath? : string;
|
|
selectedRow? : T;
|
|
canEdit? : ( item : T ) => boolean;
|
|
canDelete? : ( item : T ) => boolean;
|
|
onDelete?: ( item? : T ) => void;
|
|
onAuditParams?: ( item : T ) => AuditParams;
|
|
onSelectRow? : ( item : T ) => void;
|
|
showSecondaryAudit : boolean;
|
|
}
|
|
|
|
class TableBody<T> extends Component<TableBodyProps<T>> {
|
|
resolvePath = ( path : string, args : string[]) => {
|
|
let modifiedPath = path;
|
|
|
|
let index : number = 0;
|
|
while ( index < args.length )
|
|
{
|
|
modifiedPath = modifiedPath.replace("{"+index+"}", args[index])
|
|
index++;
|
|
}
|
|
|
|
return modifiedPath;
|
|
}
|
|
|
|
renderCell = (item : T, column : Column<T>) => {
|
|
const {keyName} = this.props;
|
|
if (column.content) return column.content(item);
|
|
|
|
const foundItem = deepFind(item, column.path || column.key)
|
|
|
|
let columnContent : JSX.Element;
|
|
|
|
if (foundItem instanceof Date) {
|
|
columnContent = <DateView value={foundItem}/>
|
|
}
|
|
else if (typeof foundItem === "object"){
|
|
columnContent = <></>;
|
|
}
|
|
else {
|
|
columnContent = <>
|
|
{foundItem}
|
|
</>;
|
|
}
|
|
|
|
const linkPath = column.link;
|
|
|
|
if (linkPath !== undefined){
|
|
const resolvedlinkPath = this.resolvePath( linkPath, [ (item as any)[keyName] ] );
|
|
columnContent = <Link to={resolvedlinkPath}>{columnContent}</Link>;
|
|
}
|
|
|
|
return <>
|
|
{columnContent}
|
|
</>;
|
|
};
|
|
|
|
clickRow = ( value : T ) =>
|
|
{
|
|
const { onSelectRow } = this.props;
|
|
|
|
if (onSelectRow !== undefined)
|
|
onSelectRow( value );
|
|
}
|
|
|
|
createKey = (item : T, column : Column<T>) => {
|
|
const { keyName } = this.props;
|
|
|
|
return (item as any)[keyName] + '_' + (column.path || column.key);
|
|
};
|
|
|
|
handleAuditParams = ( item : T, primaryOnly : boolean ) => {
|
|
const { onAuditParams } = this.props;
|
|
if (onAuditParams !== undefined) {
|
|
var auditParams = onAuditParams(item);
|
|
let json = JSON.stringify(auditParams);
|
|
var params = Buffer.from(json).toString('base64') ;
|
|
|
|
var queryString = "";
|
|
if (primaryOnly===false)
|
|
queryString += "?primaryOnly=" + primaryOnly;
|
|
|
|
return "/audit/" + params + queryString;
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
render() {
|
|
const { data, keyName, selectedRow, columns, editPath, canEdit, canDelete, onDelete, onAuditParams, showSecondaryAudit } = this.props;
|
|
const showDelete:boolean = onDelete != null;
|
|
const showEdit:boolean = (editPath != null) && (editPath !== "");
|
|
const showAudit:boolean = onAuditParams !== undefined;
|
|
|
|
return (
|
|
<tbody>
|
|
{data?.map((item) => {
|
|
let classNames = "";
|
|
if (selectedRow === item)
|
|
{
|
|
classNames+="table-primary";
|
|
}
|
|
|
|
return (<tr className={classNames} key={(item as any)[keyName]}>
|
|
{columns.map((column) => (
|
|
<td key={this.createKey(item, column)} onClick={ () => this.clickRow(item)}>{this.renderCell(item, column)}</td>
|
|
))}
|
|
{showEdit && <td className="align-middle">{(canEdit === undefined || canEdit(item)) && <Button buttonType={ButtonType.primary} to={this.resolvePath( editPath!, [ (item as any)[keyName] ] )}><FontAwesomeIcon icon={faEdit}/></Button>}</td>}
|
|
{showDelete && <td className="align-middle">{(canDelete === undefined || canDelete(item)) && <ConfirmButton buttonType={ButtonType.primary} keyValue={item} onClick={onDelete} confirmMessage={"Press again to delete"} ><FontAwesomeIcon icon={faTrash}/></ConfirmButton>}</td>}
|
|
{showAudit && <td className="align-middle"><Link to={this.handleAuditParams(item, true)}><Button buttonType={ButtonType.primary}><FontAwesomeIcon icon={faBook}/></Button></Link></td>}
|
|
{showAudit && showSecondaryAudit && <td className="align-middle"><Link to={this.handleAuditParams(item, false)}><Button buttonType={ButtonType.secondary}><FontAwesomeIcon icon={faBookJournalWhills}/></Button></Link></td>}
|
|
</tr>)
|
|
})}
|
|
</tbody>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default TableBody;
|