Skip to content

Commit

Permalink
Merge pull request #445 from City-of-Helsinki/807-history-tree-with-p…
Browse files Browse the repository at this point in the history
…lotsearch

807 history tree with plotsearch
  • Loading branch information
NC-jsAhonen authored Nov 8, 2023
2 parents 01b03b5 + 1be80fc commit bc3c6cb
Show file tree
Hide file tree
Showing 15 changed files with 723 additions and 224 deletions.
99 changes: 85 additions & 14 deletions src/components/inputs/LeaseSelectInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,23 @@ import debounce from 'lodash/debounce';
import AsyncSelect from '$components/form/AsyncSelect';
import {getContentLeaseIdentifier} from '$src/leases/helpers';
import {fetchLeases} from '$src/leases/requestsAsync';
import {
fetchAreaSearches,
fetchTargetStatuses,
fetchPlotSearches,
} from "$src/leases/requestsAsync";
import { getLabelOfOption, getFieldOptions } from "$src/util/helpers";
import {getAttributes as getLeaseAttributes} from '$src/leases/selectors';
import {store} from '$src/root/startApp';
import { LeaseFieldPaths, LeaseHistoryItemTypes, LeaseHistoryContentTypes } from "$src/leases/enums";

type Props = {
disabled?: boolean,
name: string,
onBlur?: Function,
onChange: Function,
placeholder?: string,
relatedLeases: Array<Object>,
leaseHistoryItems: Array<Object>,
value?: Object,
}

Expand All @@ -22,27 +31,89 @@ const LeaseSelectInput = ({
onBlur,
onChange,
placeholder,
relatedLeases,
leaseHistoryItems,
value,
}: Props) => {
const getLeaseOptions = (leases: Array<Object>): Array<Object> =>
leases
.filter((lease) => relatedLeases.find((relatedLease) => lease.id === relatedLease.lease.id) ? false : true)
const leaseAttributes = getLeaseAttributes(store.getState());
const getHistoryItemOptions = (leases: Array<Object>, plotSearches: Array<Object>,plotApplications: Array<Object>, areaSearches: Array<Object>): Array<Object> => {
const filterOutExisting = (item) => leaseHistoryItems.find((leaseHistoryItem) => item.id === leaseHistoryItem.lease.id) ? false : true

leases = leases
.filter(filterOutExisting)
.map((lease) => {
const stateOptions = getFieldOptions(leaseAttributes, LeaseFieldPaths.STATE)
return {
value: lease.id,
label: getContentLeaseIdentifier(lease),
label: `${getContentLeaseIdentifier(lease) || ''}, ${getLabelOfOption(stateOptions, lease.state) || ''}`,
type: 'lease'
};
});

const getLeases = debounce(async(inputValue: string, callback: Function) => {
const leases = await fetchLeases({
succinct: true,
identifier: inputValue,
limit: 10,
});
plotSearches = plotSearches
.filter(filterOutExisting)
.map((plotSearch) => {
const maxLength = 24
const displayName = plotSearch.name.length > maxLength ? plotSearch.name.substr(0,maxLength) + "..." : plotSearch.name
return {
value: plotSearch.id,
label: `${displayName}, ${LeaseHistoryItemTypes.PLOTSEARCH}`,
type: 'related_plot_application',
content_type_model: LeaseHistoryContentTypes.PLOTSEARCH
};
});

plotApplications = plotApplications
.filter(filterOutExisting)
.map((plotApplication) => {
return {
value: plotApplication.id,
label: `${plotApplication.application_identifier}, ${LeaseHistoryItemTypes.PLOT_APPLICATION}`,
type: 'related_plot_application',
content_type_model: LeaseHistoryContentTypes.TARGET_STATUS
};
});

areaSearches = areaSearches
.filter(filterOutExisting)
.map((areaSearch) => {
return {
value: areaSearch.id,
label: `${areaSearch.identifier}, ${LeaseHistoryItemTypes.AREA_SEARCH}`,
type: 'related_plot_application',
content_type_model: LeaseHistoryContentTypes.AREA_SEARCH
};
});

return [...leases, ...plotSearches, ...plotApplications, ...areaSearches].sort((a, b) => (a.label && b.label) && a.label > b.label ? 1 : -1)
}

const getHistoryItems = debounce(async(inputValue: string, callback: Function) => {

const [
leases,
plotSearches,
plotApplications,
areaSearches,
] = await Promise.all([
fetchLeases({
succinct: true,
identifier: inputValue,
limit: 10,
}),
fetchPlotSearches({
name: inputValue,
limit: 10,
}),
fetchTargetStatuses({
identifier: inputValue,
limit: 10,
}),
fetchAreaSearches({
identifier: inputValue,
limit: 10,
})])

callback(getLeaseOptions(leases));
callback(getHistoryItemOptions(leases, plotSearches, plotApplications, areaSearches));
}, 500);

const input = {
Expand All @@ -56,7 +127,7 @@ const LeaseSelectInput = ({
<AsyncSelect
disabled={disabled}
displayError={false}
getOptions={getLeases}
getOptions={getHistoryItems}
input={input}
isDirty={false}
placeholder={placeholder}
Expand Down
197 changes: 197 additions & 0 deletions src/leases/components/leaseSections/summary/LeaseHistory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// @flow
import React, {PureComponent} from 'react';
import {connect} from 'react-redux';

import LeaseHistoryItem from './LeaseHistoryItem';
import TitleH3 from '$components/content/TitleH3';
import { LeaseFieldPaths, LeaseFieldTitles, LeaseHistoryContentTypes, LeaseHistoryItemTypes } from '$src/leases/enums';
import {getContentRelatedLeasesFrom, getContentRelatedLeasesTo, sortRelatedLeasesFrom} from '$src/leases/helpers';
import {getFieldOptions} from '$src/util/helpers';
import {getUiDataLeaseKey} from '$src/uiData/helpers';
import {
getAttributes as getLeaseAttributes,
getCurrentLease,
} from '$src/leases/selectors';

import type {Attributes} from '$src/types';
import type {Lease} from '$src/leases/types';
import { restructureLease, sortRelatedHistoryItems } from "$src/leases/helpers";

type Props = {
currentLease: Lease,
leaseAttributes: Attributes,
}

type State = {
currentLease: Lease,
leaseAttributes: Attributes,
relatedLeasesFrom: Array<Object>,
relatedLeasesTo: Array<Object>,
stateOptions: Array<Object>,
}

class LeaseHistory extends PureComponent<Props, State> {
state = {
currentLease: {},
leaseAttributes: null,
relatedLeasesFrom: [],
relatedLeasesTo: [],
stateOptions: [],
}

static getDerivedStateFromProps(props: Props, state: State) {
const newState = {};

if(props.leaseAttributes !== state.leaseAttributes) {
newState.leaseAttributes = props.leaseAttributes;
newState.stateOptions = getFieldOptions(props.leaseAttributes, LeaseFieldPaths.STATE);
}

if(props.currentLease !== state.currentLease) {
newState.currentLease = props.currentLease;
newState.relatedLeasesFrom = sortRelatedLeasesFrom(getContentRelatedLeasesFrom(props.currentLease));
newState.relatedLeasesTo = getContentRelatedLeasesTo(props.currentLease);
}

return newState;
}

render() {
const {currentLease} = this.props;
const {
relatedLeasesFrom,
relatedLeasesTo,
stateOptions,
} = this.state;

const renderLeaseWithPlotSearchesAndApplications = (lease, active) => {
const historyItems = []

if (lease.plot_searches?.length) {
lease.plot_searches.forEach((plotSearch) => {
historyItems.push({
key: `plot-search-${plotSearch.name}-${Math.random().toString()}`,
id: plotSearch.id,
itemTitle: plotSearch.name,
startDate: plotSearch.begin_at,
endDate: plotSearch.end_at,
plotSearchType: plotSearch.type,
plotSearchSubtype: plotSearch.subtype,
itemType: LeaseHistoryItemTypes.PLOTSEARCH,
})
})
}

if (lease.target_statuses?.length) {
lease.target_statuses.forEach((plotApplication) => {
historyItems.push({
key: `plot-application-${plotApplication.application_identifier}-${Math.random().toString()}`,
id: plotApplication.id,
itemTitle: plotApplication.application_identifier,
receivedAt: plotApplication.received_at,
itemType: LeaseHistoryItemTypes.PLOT_APPLICATION,
})
})
}

if (lease.area_searches?.length) {
lease.area_searches.forEach((areaSearch) => {
historyItems.push({
key: `area-search-${areaSearch.identifier}-${Math.random().toString()}`,
id: areaSearch.id,
itemTitle: areaSearch.identifier,
receivedAt: areaSearch.received_date,
applicantName: `${areaSearch.applicant_names.join(" ")}`,
itemType: LeaseHistoryItemTypes.AREA_SEARCH,
})
})
}

if (lease.related_plot_applications?.length) {
lease.related_plot_applications.forEach((relatedPlotApplication) => {
if (relatedPlotApplication.content_type?.model === LeaseHistoryContentTypes.PLOTSEARCH) {
const { content_object } = relatedPlotApplication
historyItems.push({
key: `related-plot-application-plotsearch-${content_object.id}-${Math.random().toString()}`,
id: content_object.id,
itemTitle: content_object.name,
startDate: content_object.begin_at,
endDate: content_object.end_at,
plotSearchType: content_object.type,
plotSearchSubtype: content_object.subtype,
itemType: LeaseHistoryItemTypes.PLOTSEARCH,
})
}
if (relatedPlotApplication.content_type?.model === LeaseHistoryContentTypes.TARGET_STATUS) {
const { content_object } = relatedPlotApplication
historyItems.push({
key: `related-plot-application-targetstatus-${content_object.id}-${Math.random().toString()}`,
id: content_object.id,
itemTitle: content_object.application_identifier,
receivedAt: content_object.received_at,
itemType: LeaseHistoryItemTypes.PLOT_APPLICATION,
})
}
else if (relatedPlotApplication.content_type?.model === LeaseHistoryContentTypes.AREA_SEARCH) {
const { content_object } = relatedPlotApplication
historyItems.push({
key: `related-plot-application-areasearch-${content_object.id}-${Math.random().toString()}`,
id: content_object.id,
itemTitle: content_object.identifier,
applicantName: `${content_object.applicant_names.join(" ")}`,
receivedAt: content_object.received_date,
itemType: LeaseHistoryItemTypes.AREA_SEARCH,
})
}
})
}

let leaseProps: any = {
key: `lease-${lease.id}-${Math.random().toString()}`,
id: lease.id,
lease: lease,
startDate: lease.start_date,
endDate: lease.end_date,
}

// used for highlighting the current lease
if (typeof active === "boolean") {
leaseProps.active = active
}
historyItems.push(leaseProps)
historyItems.sort(sortRelatedHistoryItems)
return historyItems.map((item) => { return <LeaseHistoryItem {...item} stateOptions={this.state.stateOptions} />})
}

return (
<div className="summary__related-leases">
<TitleH3 uiDataKey={getUiDataLeaseKey(LeaseFieldPaths.HISTORY)}>
{LeaseFieldTitles.HISTORY }
</TitleH3>
<div className="summary__related-leases_items">
<div className="summary__related-leases_items_border-left" />
{!!relatedLeasesTo && !!relatedLeasesTo.length &&
relatedLeasesTo
.map(restructureLease)
.map(renderLeaseWithPlotSearchesAndApplications)}

{!!currentLease && renderLeaseWithPlotSearchesAndApplications(currentLease, true)}

{!!relatedLeasesFrom && !!relatedLeasesFrom.length &&
relatedLeasesFrom
.map(restructureLease)
.map(renderLeaseWithPlotSearchesAndApplications)}
</div>
</div>
);
}
}

export default connect(
(state) => {
return {
currentLease: getCurrentLease(state),
leaseAttributes: getLeaseAttributes(state),
};
}
)(LeaseHistory);
Loading

0 comments on commit bc3c6cb

Please sign in to comment.