react

import * as React from “react”;
import { GridReadyEvent, CellValueChangedEvent, GetContextMenuItemsParams } from “ag-grid-community”;
import { Guid } from “@cassini/model”;
import { BoxCurveConfigurationRow } from “@model”;
import { AgGridWrapper } from “@cassini/components”;
import { CellValidator } from “./CellValidator”;
import { columnDefs, columnDefsTenorDisable } from “./column-definitions”;
import { boxCurveRowDefaults } from “…/utils”;
import { genericGridOptions } from “@utils”;

interface Props {
updatedBoxCurveData: any;
isHistorical: boolean;
handleUpdatedBoxCurveData: (data: any) => void;
handleIsEditing: (editing: boolean) => void;
handleIsContextMenuRowEdit: (IsContextMenuRowEdit: boolean) => void;
isLoadingBoxCurve: boolean;
isCheckedIndexInput: boolean;
enableTenorEditing: boolean;
}

interface CopiedRow {
tenor?: string;
rate?: number;
}

export const BoxCurveConfiguration: React.FC = (props: Props) => {
const { updatedBoxCurveData, handleUpdatedBoxCurveData, handleIsEditing, isHistorical, isLoadingBoxCurve, isCheckedIndexInput, enableTenorEditing, handleIsContextMenuRowEdit } = props;
const gridApi = React.useRef();
const gridColumnApi = React.useRef();
const [colDefs, setcolDefs] = React.useState(columnDefs);
// const traderViewCheckedRef = React.useRef(true);
console.log("BoxCurveConfiguration: " + isCheckedIndexInput);
React.useEffect(() => {
if (gridApi?.current) {
if (isLoadingBoxCurve) {
gridApi.current.showLoadingOverlay();
} else {
gridApi.current.hideOverlay();
}
}
}, [isLoadingBoxCurve]);

// React.useEffect(() => {
// 	traderViewCheckedRef.current = isCheckedIndexInput;
// }, [isCheckedIndexInput]);

React.useEffect(() => {
	console.log("BoxCurveConfiguration useEffect: " + isCheckedIndexInput);
	if(gridApi && gridApi.current){
		if(isCheckedIndexInput){
		    const newupdatedBoxCurveData = updatedBoxCurveData.map((item: { rate: number; }) => {
		     	return {
		     		...item,
		     		rate: -item.rate
		     	};
		    });
			gridApi.current.setRowData(newupdatedBoxCurveData);	
		}else {
		    gridApi.current.setRowData(updatedBoxCurveData);
		}
	}
}, [updatedBoxCurveData, isCheckedIndexInput]);

// The role can't edit the tenor column value without enableTenorEditing permission, but could edit not empty value tenor cell when doing add row action.
React.useEffect(() => {
	if (enableTenorEditing) {
		setcolDefs(columnDefs);
	} else{
		setcolDefs(columnDefsTenorDisable);
	}
}, [enableTenorEditing]);

// NOTE: I cannot find a better way than this, changes to react state is not updated inside the context menu
React.useEffect(() => {
	if (gridApi?.current) {
		if (isHistorical) {
			gridApi.current.isReadOnly = true;
		} else {
			gridApi.current.isReadOnly = false;
		}
	}
}, [isHistorical]);

const onGridReadyHandler = (gridParams: GridReadyEvent) => {
	gridApi.current = gridParams.api!;
	gridColumnApi.current = gridParams.columnApi!;
};

// TODO can this be moved to column definition?
const updateColumns = (event: CellValueChangedEvent) => {
	const allData = gridApi.current.getModel().gridOptionsWrapper.gridOptions.rowData;
	const activeRow = event.rowIndex;
	if (event.colDef.field === "tenor") {
		allData[activeRow].tenor = event.value;
		allData[activeRow].end = event.value;
		handleUpdatedBoxCurveData([...allData]);
		handleIsEditing(true);
	}
	console.log("updateColumns: " + isCheckedIndexInput);
	if (event.colDef.field === "rate") {
		if(isCheckedIndexInput){
			allData[activeRow].rate = -event.value;
		}else {
			allData[activeRow].rate = event.value;
		}
		handleUpdatedBoxCurveData([...allData]);
		handleIsEditing(true);
	}
};

// Cannot access component state inside the context menu
const contextMenu = (gridParams: GetContextMenuItemsParams) => {
	gridApi.current = gridParams.api!;
	const allData = gridApi.current.getModel().gridOptionsWrapper.gridOptions.rowData;
	const {
		fitFlag = boxCurveRowDefaults.fitFlag,
		type = boxCurveRowDefaults.type,
		freq1 = boxCurveRowDefaults.freq1,
		freq2 = boxCurveRowDefaults.freq2,
		rollPolicy = boxCurveRowDefaults.rollPolicy
	} = allData[0];
	return [
		{
			name: "Add Row",
			disabled: gridApi.current.isReadOnly,
			action: () => {
				handleUpdatedBoxCurveData([
					...allData,
					{
						fitFlag,
						type,
						freq1,
						freq2,
						rollPolicy,
						OISIndex2: allData[0].OISIndex2,
						OISIndex: allData[0].OISIndex,
						id: Guid.newGuid()
					}
				]);
				handleIsEditing(true);
				handleIsContextMenuRowEdit(true);
			}
		},
		{
			name: "Remove Row",
			disabled: allData.length <= 1 || gridApi.current.isReadOnly,
			action: () => {
				console.log("Remove Row: " + isCheckedIndexInput);
				const updatedRows = allData.filter((row: BoxCurveConfigurationRow) => {
					return row.id !== gridParams?.node?.data?.id;
				});
				handleUpdatedBoxCurveData(updatedRows);
				handleIsEditing(true);
				handleIsContextMenuRowEdit(true);
			}
		},
		{
			name: "Clear All",
			disabled: gridApi.current.isReadOnly,
			action: () => {
				const rowData = [
					{
						...boxCurveRowDefaults,
						OISIndex2: allData[0].OISIndex2,
						OISIndex: allData[0].OISIndex,
						id: Guid.newGuid()
					}
				];
				handleUpdatedBoxCurveData(rowData);
				gridApi.current.sizeColumnsToFit();
				handleIsEditing(true);
				handleIsContextMenuRowEdit(true);
			}
		},
		"separator",
		"copy",
		"copyWithHeaders",
		"export"
	];
};

const getRowNodeId = (row: BoxCurveConfigurationRow) => {
	return row.id;
};

const gridOptions = {
	...genericGridOptions,
	defaultColDef: {
		flex: 1,
		minWidth: 75
	},
	stopEditingWhenGridLosesFocus: true,
	onCellValueChanged: (event: CellValueChangedEvent) => {
		updateColumns(event);
	},
	getContextMenuItems: contextMenu,
	suppressColumnVirtualisation: true,
	onGridReady: onGridReadyHandler,
	frameworkComponents: {
		cellValidator: CellValidator
	},
	immutableData: false,
	processDataFromClipboard: (params: any) => {
		const currentGridData = gridApi.current.getModel().gridOptionsWrapper.gridOptions.rowData;

		if (isEmptyLastRow(params.data)) {
			params.data.splice(params.data.length - 1, 1);
		}

		const lastIndex = gridApi.current.getModel().rowsToDisplay.length - 1;
		const focusedCell = gridApi.current.getFocusedCell();
		const focusedIndex = focusedCell.rowIndex;
		if (focusedIndex + params.data.length - 1 > lastIndex) {
			const newRowData = processNewRows(
				currentGridData,
				focusedIndex,
				lastIndex,
				params.data,
				focusedCell,
				gridColumnApi.current
			);
			handleUpdatedBoxCurveData([...currentGridData, ...newRowData]);
		}
		return params.data;
	},
	overlayLoadingTemplate: "Loading..."
};

const isEmptyLastRow = (clipbordRows: any) => {
	return clipbordRows[clipbordRows.length - 1][0] === "" && clipbordRows[clipbordRows.length - 1].length === 1;
};

const processNewRows = (
	currentGridData: any,
	focusedIndex: number,
	lastIndex: number,
	clipbordRows: any,
	focusedCell: any,
	gridColApi: any
) => {
	const {
		fitFlag = boxCurveRowDefaults.fitFlag,
		type = boxCurveRowDefaults.type,
		freq1 = boxCurveRowDefaults.freq1,
		freq2 = boxCurveRowDefaults.freq2,
		rollPolicy = boxCurveRowDefaults.rollPolicy
	} = currentGridData[0];

	const resultLastIndex = focusedIndex + (clipbordRows.length - 1);
	const addRowCount = resultLastIndex - lastIndex;
	const rowsToAdd = getRowsToAdd(addRowCount, clipbordRows);
	const newRowData = rowsToAdd.map(newRow => {
		let currColumn = focusedCell.column;
		const row = newRow.reduce((result: CopiedRow, i: any) => {
			const field = currColumn.colDef.field;
			result[field] = i;
			currColumn = gridColApi.getDisplayedColAfter(currColumn);

			return result;
		}, {});

		return {
			fitFlag,
			type,
			freq1,
			freq2,
			rollPolicy,
			OISIndex2: currentGridData[0].OISIndex2,
			OISIndex: currentGridData[0].OISIndex,
			end: row.tenor,
			id: Guid.newGuid(),
			tenor: row.tenor,
			rate: row.rate
		};
	});

	return newRowData;
};

const getRowsToAdd = (addRowCount: number, clipbordRows: any) => {
	let rowsToAdd = [];
	let addedRows = 0;
	let currIndex = clipbordRows.length - 1;
	while (addedRows < addRowCount) {
		const row = clipbordRows.splice(currIndex, 1)[0];
		rowsToAdd.push(row);
		addedRows++;
		currIndex--;
	}
	rowsToAdd = rowsToAdd.reverse();

	return [...rowsToAdd];
};

return (
	<div className='box-curve-config' data-cy='box-curve-config-grid'>
		<AgGridWrapper
			columnDefs={colDefs}
			rowData={updatedBoxCurveData}
			gridOptions={gridOptions}
			getRowNodeId={getRowNodeId}
		/>
	</div>
);

};

2023-09-25 15:28:02 UTC INFO [main] — /tmp/workspace/icg-msst-cassini-172868/icg-msst-cassini-172868-yield-curves-ui.feature-c160561-8884-cvm-r (depth 0)
2023-09-25 15:28:02 UTC INFO [main] — LERNA - Lerna
2023-09-25 15:28:02 UTC INFO [main] — Found file: /tmp/workspace/icg-msst-cassini-172868/icg-msst-cassini-172868-yield-curves-ui.feature-c160561-8884-cvm-r/lerna.json
2023-09-25 15:28:02 UTC INFO [main] — GIT - Git
2023-09-25 15:28:02 UTC INFO [main] — Found file: /tmp/workspace/icg-msst-cassini-172868/icg-msst-cassini-172868-yield-curves-ui.feature-c160561-8884-cvm-r/.git
2023-09-25 15:28:02 UTC INFO [main] — Found executable: /usr/bin/git
2023-09-25 15:28:02 UTC INFO [main] — ----------------------------------
2023-09-25 15:28:02 UTC INFO [main] — Detectors actions finished.
2023-09-25 15:28:02 UTC INFO [main] — ----------------------------------
2023-09-25 15:28:02 UTC INFO [main] — Project name: 172868/cassini/yield-curves-ui
2023-09-25 15:28:02 UTC INFO [main] — Project version: feature-c160561-888-2-afbb940
2023-09-25 15:28:02 UTC INFO [main] — ----------------------------------
2023-09-25 15:28:02 UTC INFO [main] — Signature Scanner tool will not be run.
2023-09-25 15:28:02 UTC INFO [main] — ----------------------------------
2023-09-25 15:28:02 UTC INFO [main] — Vulnerability Impact Analysis tool will not be run.
2023-09-25 15:28:02 UTC INFO [main] — ----------------------------------
2023-09-25 15:28:02 UTC INFO [main] — IaC Scanner tool will not be run.
2023-09-25 15:28:02 UTC INFO [main] —
2023-09-25 15:28:02 UTC INFO [main] —
2023-09-25 15:28:02 UTC INFO [main] — Creating status file: /home/jenkins/blackduck/runs/2023-09-25-15-28-01-080/status/status.json
2023-09-25 15:28:02 UTC INFO [main] —
2023-09-25 15:28:02 UTC INFO [main] — Status file has been deleted. To preserve status file, turn off cleanup actions.
2023-09-25 15:28:02 UTC INFO [main] —
2023-09-25 15:28:02 UTC INFO [main] —
2023-09-25 15:28:02 UTC INFO [main] — ======== Detect Issues ========
2023-09-25 15:28:02 UTC INFO [main] —
2023-09-25 15:28:02 UTC INFO [main] — DETECTORS:
2023-09-25 15:28:02 UTC INFO [main] — Detector Issue
2023-09-25 15:28:02 UTC INFO [main] — /tmp/workspace/icg-msst-cassini-172868/icg-msst-cassini-172868-yield-curves-ui.feature-c160561-8884-cvm-r
2023-09-25 15:28:02 UTC INFO [main] — Not Extractable: LERNA - Lerna
2023-09-25 15:28:02 UTC INFO [main] — No lerna executable was found.
2023-09-25 15:28:02 UTC INFO [main] —
2023-09-25 15:28:02 UTC INFO [main] — DEPRECATIONS:
2023-09-25 15:28:02 UTC INFO [main] — detect.bom.aggregate.name
2023-09-25 15:28:02 UTC INFO [main] — This property is being removed. Use detect.bdio.file.name to control the name of the bdio file Detect generates. Currently detect.bdio.file.name has the same effects as this property. In the future, Detect will always operate in SUBPROJECT aggregation mode regardless of how it is configured; detect.bdio.file.name will only control the BDIO file name. This property will be removed in 8.0.0.
2023-09-25 15:28:02 UTC INFO [main] —
2023-09-25 15:28:02 UTC INFO [main] — ======== Detect Status ========
2023-09-25 15:28:02 UTC INFO [main] —
2023-09-25 15:28:02 UTC INFO [main] — GIT: SUCCESS
2023-09-25 15:28:02 UTC INFO [main] — LERNA: FAILURE
2023-09-25 15:28:02 UTC INFO [main] — Overall Status: FAILURE_DETECTOR - Detect had one or more detector failures while extracting dependencies. Check that all projects build and your environment is configured correctly.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值