Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move service unit filter next to basic search in leases view #477

2 changes: 1 addition & 1 deletion src/components/inputs/UserServiceUnitSelectInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class UserServiceUnitSelectInput extends Component<Props, State> {
<FormFieldLabel
htmlFor={'userServiceUnitSelect'}
>
Palvelukokonaisuus
Oma palvelukokonaisuus
</FormFieldLabel>
<div className={'form-field__component'}>
<div className={'form-field__select'}>
Expand Down
3 changes: 3 additions & 0 deletions src/components/table/TableFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ type Props = {
filterOptions: Array<Object>,
filterValue: Array<string>,
onFilterChange?: Function,
componentToRenderUnderLabel?: React$Node,
}
const TableFilters = ({
alignFiltersRight,
amountText,
filterOptions,
filterValue,
onFilterChange,
componentToRenderUnderLabel = null
}: Props): React$Node => {
const handleFilterChange = (values: Array<Object>) => {
if(onFilterChange) {
Expand All @@ -33,6 +35,7 @@ const TableFilters = ({
{!!filterOptions.length &&
<p className='table__filters_filter-wrapper_title'>Suodatus</p>
}
{!!componentToRenderUnderLabel && componentToRenderUnderLabel}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest two possible options for renaming componentToRenderUnderLabel:

  • componentToRenderUnderTitle: The p element above is not a label but a title. I was a bit confused about where there should be a label.
  • serviceUnitFilterComponent: Describes more clearly about what the component is. There are no other components to be rendered in this position, so I think it is fine to state it more explicitly what component is rendered there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed it to componentToRenderUnderTitle. Though serviceUnitFilterComponent tells more in this use case, I still think the TableFilter component does not have to know what React component is being injected.

<CheckboxInput
checkboxName='lease-type-checkbox'
legend='Suodata'
Expand Down
2 changes: 1 addition & 1 deletion src/components/topNavigation/TopNavigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ class TopNavigation extends Component<Props, State> {
<UserServiceUnitSelectInput userServiceUnits={userServiceUnits} userActiveServiceUnit={userActiveServiceUnit} />
) : (
<div className="user-service-unit-text">
<div className="service-unit-label">Palvelukokonaisuus</div>
<div className="service-unit-label">Oma palvelukokonaisuus</div>
<div className="service-unit-name">{userActiveServiceUnit.name}</div>
</div>
)}
Expand Down
81 changes: 66 additions & 15 deletions src/leases/components/LeaseListPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import debounce from 'lodash/debounce';
import isArray from 'lodash/isArray';
import isEmpty from 'lodash/isEmpty';

import {FieldTypes} from '$src/enums';
import FieldTypeSelect from '$components/form/FieldTypeSelect';
import SearchContainer from '$components/search/SearchContainer';
import FormField from '$components/form/FormField';
import SearchInputColumn from '$components/search/SearchInputColumn';
import SearchLabel from '$components/search/SearchLabel';
import SearchLabelColumn from '$components/search/SearchLabelColumn';
import SearchRow from '$components/search/SearchRow';
import AddButtonSecondary from '$components/form/AddButtonSecondary';
import Authorization from '$components/authorization/Authorization';
import AuthorizationError from '$components/authorization/AuthorizationError';
Expand Down Expand Up @@ -126,6 +134,8 @@ type State = {
sortKey: string,
sortOrder: string,
visualizationType: string,
serviceUnitOptions: Array<Object>,
selectedServiceUnitOptionValue: mixed // empty string if no value, otherwise number
}

class LeaseListPage extends PureComponent<Props, State> {
Expand All @@ -142,6 +152,8 @@ class LeaseListPage extends PureComponent<Props, State> {
sortKey: DEFAULT_SORT_KEY,
sortOrder: DEFAULT_SORT_ORDER,
visualizationType: VisualizationTypes.TABLE,
serviceUnitOptions: [],
selectedServiceUnitOptionValue: ''
}

static contextTypes = {
Expand All @@ -157,6 +169,7 @@ class LeaseListPage extends PureComponent<Props, State> {
lessors,
receiveTopNavigationSettings,
serviceUnits,
leaseAttributes
} = this.props;

setPageTitle('Vuokraukset');
Expand All @@ -179,12 +192,14 @@ class LeaseListPage extends PureComponent<Props, State> {

window.addEventListener('popstate', this.handlePopState);
this._isMounted = true;

this.setState({serviceUnitOptions: getFieldOptions(leaseAttributes, 'service_unit', true)});
}

componentDidUpdate(prevProps) {
const {location: {search: currentSearch}, userActiveServiceUnit} = this.props;
const {location: {search: currentSearch}, userActiveServiceUnit, leaseAttributes} = this.props;
const {visualizationType} = this.state;
const {location: {search: prevSearch}, userActiveServiceUnit: prevUserActiveServiceUnit} = prevProps;
const {location: {search: prevSearch}} = prevProps;

const initializeSearch = () => {
const searchQuery = getUrlParams(currentSearch);
Expand Down Expand Up @@ -218,16 +233,20 @@ class LeaseListPage extends PureComponent<Props, State> {
initializeSearch();
this._hasFetchedLeases = true;

} else if(userActiveServiceUnit !== prevUserActiveServiceUnit
&& !currentSearch.includes('service_unit')) {
// Search again after changing user active service unit only if not explicitly setting the service unit filter
searchByType();
}
}

if (currentSearch !== prevSearch) {
searchByType();
}

// Update service unit options if they have changed
if (
this.props.leaseAttributes?.service_unit &&
leaseAttributes?.service_unit?.choices.length !== prevProps.leaseAttributes?.service_unit?.choices.length
) {
this.setState({serviceUnitOptions: getFieldOptions(leaseAttributes, 'service_unit', true)});
}
}

componentWillUnmount() {
Expand Down Expand Up @@ -256,7 +275,7 @@ class LeaseListPage extends PureComponent<Props, State> {
}

setSearchFormValues = () => {
const {location: {search}, initialize, userActiveServiceUnit} = this.props;
const {location: {search}, initialize} = this.props;
const searchQuery = getUrlParams(search);
const page = searchQuery.page ? Number(searchQuery.page) : 1;
const states = this.getLeaseStates(searchQuery);
Expand All @@ -272,8 +291,10 @@ class LeaseListPage extends PureComponent<Props, State> {
? searchQuery.tenantcontact_type
: searchQuery.tenantcontact_type ? [searchQuery.tenantcontact_type] : [];

if(initialValues.service_unit === undefined && userActiveServiceUnit) {
initialValues.service_unit = userActiveServiceUnit.id;
if (initialValues.service_unit === undefined) {
initialValues.service_unit = "";
} else {
this.setState({selectedServiceUnitOptionValue: initialValues.service_unit});
}

if(onlyActiveLeases != undefined) {
Expand Down Expand Up @@ -319,7 +340,7 @@ class LeaseListPage extends PureComponent<Props, State> {
}

search = () => {
const {fetchLeases, location: {search}, userActiveServiceUnit} = this.props;
const {fetchLeases, location: {search}} = this.props;
const searchQuery = getUrlParams(search);
const page = searchQuery.page ? Number(searchQuery.page) : 1;
const leaseStates = this.getLeaseStates(searchQuery);
Expand All @@ -340,8 +361,8 @@ class LeaseListPage extends PureComponent<Props, State> {
searchQuery.sort_key = searchQuery.sort_key || DEFAULT_SORT_KEY;
searchQuery.sort_order = searchQuery.sort_order || DEFAULT_SORT_ORDER;

if(searchQuery.service_unit === undefined && userActiveServiceUnit) {
searchQuery.service_unit = userActiveServiceUnit.id;
if(searchQuery.service_unit === undefined) {
searchQuery.service_unit = "";
}

searchQuery.limit = LIST_TABLE_PAGE_SIZE;
Expand All @@ -354,7 +375,7 @@ class LeaseListPage extends PureComponent<Props, State> {
}

searchByBBox = () => {
const {fetchLeasesByBBox, location: {search}, userActiveServiceUnit} = this.props;
const {fetchLeasesByBBox, location: {search}} = this.props;
const searchQuery = getUrlParams(search);
const leaseStates = this.getLeaseStates(searchQuery);
const onlyActiveLeases = this.getOnlyActiveLeasesValue(searchQuery);
Expand All @@ -371,8 +392,8 @@ class LeaseListPage extends PureComponent<Props, State> {
searchQuery.lease_state = leaseStates;
}

if(searchQuery.service_unit === undefined && userActiveServiceUnit) {
searchQuery.service_unit = userActiveServiceUnit.id;
if(searchQuery.service_unit === undefined) {
searchQuery.service_unit = "";
}

searchQuery.limit = 10000;
Expand Down Expand Up @@ -430,6 +451,16 @@ class LeaseListPage extends PureComponent<Props, State> {
});
}

handleServiceUnitChange = (value : mixed) => {
const {location: {search}} = this.props;

// get other form values from query params
const query = getUrlParams(search);

this.handleSearchChange(Object.assign(query, {service_unit: value}));
this.setState({selectedServiceUnitOptionValue: value});
}

handleRowClick = (id) => {
const {history, location: {search}} = this.props;

Expand Down Expand Up @@ -578,6 +609,8 @@ class LeaseListPage extends PureComponent<Props, State> {
sortKey,
sortOrder,
visualizationType,
serviceUnitOptions,
selectedServiceUnitOptionValue
} = this.state;
const {
createLease,
Expand All @@ -600,6 +633,23 @@ class LeaseListPage extends PureComponent<Props, State> {

if(!isMethodAllowed(leaseMethods, Methods.GET)) return <PageContainer><AuthorizationError text={PermissionMissingTexts.LEASE} /></PageContainer>;

const serviceUnitFilter = <SearchRow>
<SearchLabelColumn>
<SearchLabel>{LeaseFieldTitles.SERVICE_UNIT}</SearchLabel>
</SearchLabelColumn>
<SearchInputColumn>
<FieldTypeSelect
autoBlur={false}
disabled={false}
displayError={false}
input={{onChange: this.handleServiceUnitChange, onBlur: () => {}, value: selectedServiceUnitOptionValue}}
isDirty={false}
options={serviceUnitOptions}
placeholder=""
setRefForField={() => {}} />
</SearchInputColumn>
</SearchRow>

return (
<PageContainer>
<Authorization allow={isMethodAllowed(leaseMethods, Methods.POST)}>
Expand Down Expand Up @@ -635,6 +685,7 @@ class LeaseListPage extends PureComponent<Props, State> {
filterOptions={leaseStateFilterOptions}
filterValue={leaseStates}
onFilterChange={this.handleLeaseStatesChange}
componentToRenderUnderLabel={serviceUnitFilter}
/>
}
visualizationComponent={
Expand Down
24 changes: 1 addition & 23 deletions src/leases/components/search/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class Search extends PureComponent<Props, State> {
newState.municipalityOptions = getFieldOptions(props.leaseAttributes, LeaseFieldPaths.MUNICIPALITY);
newState.tenantTypeOptions = getFieldOptions(props.leaseAttributes, LeaseTenantContactSetFieldPaths.TYPE, false);
newState.typeOptions = getFieldOptions(props.leaseAttributes, LeaseFieldPaths.TYPE);
newState.serviceUnitOptions = getFieldOptions(props.leaseAttributes, 'service_unit', true);
//newState.serviceUnitOptions = getFieldOptions(props.leaseAttributes, 'service_unit', true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isSearchBasicMode method beginning on line 147 delete searchQuery.service_unit; needs to be added so that the detailed search view would not render when the service unit filter is being modified. Now it will render when the page is refreshed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

}

if(props.lessors !== state.lessors) {
Expand Down Expand Up @@ -737,28 +737,6 @@ class Search extends PureComponent<Props, State> {
/>
</SearchInputColumn>
</SearchRow>

<SearchRow>
<SearchLabelColumn>
<SearchLabel>Palvelukokonaisuus</SearchLabel>
</SearchLabelColumn>
<SearchInputColumn>
<FormField
autoBlur
disableDirty
fieldAttributes={{
label: 'Palvelukokonaisuus',
type: FieldTypes.CHOICE,
read_only: false,
}}
invisibleLabel
name='service_unit'
overrideValues={{
options: serviceUnitOptions,
}}
/>
</SearchInputColumn>
</SearchRow>
</Column>
</Row>
</Fragment>
Expand Down