121 lines
6.5 KiB
TypeScript
121 lines
6.5 KiB
TypeScript
|
|
import React, { useEffect, useMemo, useState, useContext } from "react";
|
|
import { createPortal } from "react-dom";
|
|
import './../../../css/components/entityHistory.css';
|
|
import { HistoryContext } from "../../contexts/HistoryContext";
|
|
|
|
//Тип с параметрами сущности, история по которой будет выводиться
|
|
export type EntityHistoryProps = {
|
|
changeAction: string, //Совершенное действие: создание, удаление, редактирование, архивирование и т.д.
|
|
changeAuthor: string, //Автор изменения: логин, сервисная УЗ
|
|
changeDate: Date //Объект даты изменения. В объекте будет либо время (тогда показываем), либо время будет отсутствовать (тогда не показываем) //что будем передавать? объект new Date или библиотечный объект для работы с датами?
|
|
changeTime?: string //Время изменений. Передавать не нужно, на этабе сборки компонента будет формироваться на основе пропса changeDate
|
|
// changeDetails?: HistoryEntityElDetails[] //Массив объектов с деталями изменений формата: изменяемое свойство(поле, например) - значение изменяемого свойства
|
|
changeDetails?: Record<string, string> //Массив объектов с деталями изменений формата: изменяемое свойство(поле, например) - значение изменяемого свойства
|
|
};
|
|
|
|
//Тип с деталями изменений
|
|
// type HistoryEntityElDetails = {
|
|
// propName: string, //Имя измененного свойства
|
|
// propValue: string //Значение измененного свойства
|
|
// }
|
|
|
|
//Компонент отображения истории изменений сущности
|
|
export default function EntityHistory ()
|
|
{
|
|
//ГАВРИЛОВ
|
|
//ИДЕНТИЧНЫЙ СПРАВОЧНИК УКАЗАН НА СТОРОНЕ ЛАРАВЕЛЬ APP/ENUMS/LOGBUSINESSEVENTS. ЕСТЬ ВОЗМОЖНОСТЬ ОБЪЕДИНИТЬ ИХ?
|
|
const HistoryActions = {
|
|
create: 'создание',
|
|
edit: 'редактирование',
|
|
archive: 'архивация',
|
|
restore: 'восстановление',
|
|
delete: 'удаление',
|
|
cancel: 'отмена',
|
|
}
|
|
const historyContext = useContext(HistoryContext);
|
|
//Перестраиваем объект с изменениями, группируя их по датам
|
|
const groupDataByDate = useMemo( () => {
|
|
let changesByDate = {},
|
|
historyContent = historyContext.content.length ? historyContext.content : []
|
|
//Сортируем все изменения от большего к меньшему по дате и времени
|
|
//ГАВРИЛОВ. или нужно отсортировать от меньшего к большему? мы хотим сверху самые актуальные данные а ниже менее актуальные или наоборот?
|
|
//ПРОВЕРИТЬ СОРТИРУЕТСЯ ЛИ ПО ДАТАМ
|
|
historyContent.sort( (a, b) => {return b.changeDate - a.changeDate} )
|
|
//console.log(historyContext)
|
|
historyContent.forEach( (changeEl: EntityHistoryProps) => {
|
|
let dateToString = changeEl.changeDate.toLocaleString('ru-RU').split(',')[0];
|
|
if ( !(dateToString in changesByDate) ) {
|
|
changesByDate[dateToString] = [];
|
|
}
|
|
changesByDate[dateToString].push(changeEl);
|
|
});
|
|
|
|
return changesByDate;
|
|
}, [historyContext.content]);
|
|
|
|
|
|
//Сокрытие блока показа истории
|
|
function hideHistoryBlock(){
|
|
historyContext.hideHistory()
|
|
}
|
|
|
|
return (
|
|
historyContext.content && historyContext.visible ?
|
|
createPortal(
|
|
<div>
|
|
<div className="entity-hist-container">
|
|
<div className="hist__header-block">
|
|
<div className="hist__header__title">
|
|
<h3>{ historyContext.headerText.length ? historyContext.headerText : `История изменений запроса ${historyContext.entityId}` }</h3>
|
|
</div>
|
|
<div className="hist__header__buttons" onClick={hideHistoryBlock}>
|
|
<i className="fa fa-plus header__buttons__close"></i>
|
|
</div>
|
|
</div>
|
|
<div className="hist__content-block">
|
|
{Object.entries(groupDataByDate).map( (dateChanges, dateIndex) =>
|
|
<div key={dateIndex} className="hist-container__date-block">
|
|
<div className="date-block__date">
|
|
<div>{ dateChanges[0] }</div>
|
|
</div>
|
|
<div className="date-block__changes">
|
|
{ dateChanges[1].map( (changeEl: EntityHistoryProps, elIndex: number) =>
|
|
<div className="changes__action-block" key={ elIndex }>
|
|
<div className="action-block__action-name">
|
|
{ HistoryActions[changeEl.changeAction] }
|
|
</div>
|
|
<div className="changes__date-time-block">
|
|
<div>
|
|
{ changeEl.changeAuthor }
|
|
</div>
|
|
<div>
|
|
{ changeEl.changeTime }
|
|
</div>
|
|
</div>
|
|
<div className="changes__details">
|
|
{Object.entries(changeEl.changeDetails).map( (detail, detailIndex) =>
|
|
<div className="changes__details__el" key={ detailIndex }>
|
|
<div className="changes__details__el__prop-name">
|
|
{ (historyContext.dataFields && historyContext.dataFields[detail[0]]) ? historyContext.dataFields[detail[0]] : detail[0] }
|
|
</div>
|
|
<div className="changes__details__el__prop-val">
|
|
{ detail[1] }
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>,
|
|
document.body
|
|
)
|
|
: ''
|
|
)
|
|
}
|