diff --git a/app/src/frontend/building/container-header.css b/app/src/frontend/building/container-header.css index e15f38d3..04c81d33 100644 --- a/app/src/frontend/building/container-header.css +++ b/app/src/frontend/building/container-header.css @@ -33,7 +33,7 @@ .section-header .section-header-actions { display: inline-block; - flex-basis: 200px; + flex-basis: 400px; display: flex; flex-flow: row wrap; align-items: center; diff --git a/app/src/frontend/building/data-container.tsx b/app/src/frontend/building/data-container.tsx index 4df867d9..cf8c8776 100644 --- a/app/src/frontend/building/data-container.tsx +++ b/app/src/frontend/building/data-container.tsx @@ -19,6 +19,8 @@ import { ViewEditControl } from './header-buttons/view-edit-control'; import './data-container.css'; import { dataFields } from '../config/data-fields-config' +import { EditHistoryLatest } from './edit-history/edit-history-latest'; + interface DataContainerProps { title: string; cat: string; @@ -330,7 +332,7 @@ const withCopyEdit: (wc: React.ComponentType) => DataContaine History + >Edit History ) => DataContaine }
+ { this.props.inactive ? diff --git a/app/src/frontend/building/edit-history/building-edit-latest.tsx b/app/src/frontend/building/edit-history/building-edit-latest.tsx new file mode 100644 index 00000000..a56cd135 --- /dev/null +++ b/app/src/frontend/building/edit-history/building-edit-latest.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + +import './building-edit-summary.css'; + +import { Category } from '../../config/categories-config'; +import { DataFieldDefinition, dataFields } from '../../config/data-fields-config'; +import { arrayToDictionary, parseDate } from '../../helpers'; +import { EditHistoryEntry } from '../../models/edit-history-entry'; + +import { CategoryEditSummary } from './category-edit-summary'; + +interface BuildingEditLatestProps { + historyEntry: EditHistoryEntry; + showBuildingId?: boolean; + hyperlinkCategories?: boolean; +} + +function formatDate(dt: Date) { + return dt.toLocaleString(undefined, { + weekday: 'short', + year: 'numeric', + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit' + }); +} + +function enrichHistoryEntries(forwardPatch: object, reversePatch: object) { + return Object + .entries(forwardPatch) + .map(([key, value]) => { + const { + title = `Unknown field (${key})`, + category = undefined + } = dataFields[key] as DataFieldDefinition ?? {}; + + return { + title, + category, + value, + oldValue: reversePatch && reversePatch[key] + }; + }); +} + +const BuildingEditLatest: React.FunctionComponent = ({ + historyEntry, + showBuildingId = false, + hyperlinkCategories = false +}) => { + const entriesWithMetadata = enrichHistoryEntries(historyEntry.forward_patch, historyEntry.reverse_patch); + const entriesByCategory = arrayToDictionary(entriesWithMetadata, x => x.category); + + const categoryHyperlinkTemplate = hyperlinkCategories && historyEntry.building_id != undefined ? + `/edit/$category/${historyEntry.building_id}` : + undefined; + + return ( +

Building last edited on {formatDate(parseDate(historyEntry.revision_timestamp))}

+ ); +}; + +export { + BuildingEditLatest +}; diff --git a/app/src/frontend/building/edit-history/edit-history-latest.tsx b/app/src/frontend/building/edit-history/edit-history-latest.tsx new file mode 100644 index 00000000..0abe5cef --- /dev/null +++ b/app/src/frontend/building/edit-history/edit-history-latest.tsx @@ -0,0 +1,46 @@ +import React, { useEffect, useState } from 'react'; + +import './edit-history.css'; + +import { apiGet } from '../../apiHelpers'; +import { Building } from '../../models/building'; +import { EditHistoryEntry } from '../../models/edit-history-entry'; +import ContainerHeader from '../container-header'; + +import { BuildingEditLatest } from './building-edit-latest'; + +interface EditHistoryLatestProps { + building: Building; +} + +const EditHistoryLatest: React.FunctionComponent = (props) => { + const [history, setHistory] = useState(undefined); + + useEffect(() => { + const fetchData = async () => { + const {history} = await apiGet(`/api/buildings/${props.building.building_id}/history.json`); + + setHistory(history); + }; + + if (props.building != undefined) { // only call fn if there is a building provided + fetchData(); // define and call, because effect cannot return anything and an async fn always returns a Promise + } + }, [props.building]); // only re-run effect on building prop change + + return ( + <> +
    + {history && history.map(entry => ( +
  • + +
  • + ))} +
+ + ); +}; + +export { + EditHistoryLatest +}; diff --git a/app/src/frontend/building/edit-history/edit-history.css b/app/src/frontend/building/edit-history/edit-history.css index 8aa5cfe2..c4ca8399 100644 --- a/app/src/frontend/building/edit-history/edit-history.css +++ b/app/src/frontend/building/edit-history/edit-history.css @@ -5,4 +5,11 @@ .edit-history-list { list-style: none; padding-left: 1rem; +} + +ul[id="first-only"] li{ + display: none; +} +ul[id="first-only"] li:first-of-type { + display: block; } \ No newline at end of file