Skip to content

Commit

Permalink
Add FacilityName filter
Browse files Browse the repository at this point in the history
  • Loading branch information
razvanMiu committed Oct 5, 2022
1 parent 94317bf commit 2e719ca
Show file tree
Hide file tree
Showing 6 changed files with 320 additions and 20 deletions.
101 changes: 86 additions & 15 deletions src/components/manage/Blocks/FiltersBlock/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ const getSites = (value) => {
const db_version =
process.env.RAZZLE_DB_VERSION || config.settings.db_version || 'latest';
const query = `SELECT siteName
FROM [IED].[${db_version}].[SiteMap]
WHERE [siteName] COLLATE Latin1_General_CI_AI LIKE '%${value}%'
GROUP BY siteName
ORDER BY [siteName]`;
FROM [IED].[${db_version}].[SiteMap]
WHERE [siteName] COLLATE Latin1_General_CI_AI LIKE '%${value}%'
GROUP BY siteName
ORDER BY [siteName]`;

return axios.get(
providerUrl + `?${getEncodedQueryString(query)}&p=1&nrOfHits=6`,
Expand All @@ -43,11 +43,27 @@ const getLocations = (value, providers_data) => {
);
};

const getFacilities = (value) => {
const providerUrl = config.settings.providerUrl;
const db_version =
process.env.RAZZLE_DB_VERSION || config.settings.db_version || 'latest';
const query = `SELECT facilityName
FROM [IED].[${db_version}].[ProductionFacility]
WHERE [facilityName] COLLATE Latin1_General_CI_AI LIKE '%${value}%'
GROUP BY facilityName
ORDER BY [facilityName]`;

return axios.get(
providerUrl + `?${getEncodedQueryString(query)}&p=1&nrOfHits=6`,
);
};

const Search = ({ data, providers_data, query, setQuery, ...props }) => {
const searchContainer = React.useRef();
const [loading, setLoading] = React.useState(false);
const [showResults, setShowResults] = React.useState(false);
const [sites, setSites] = React.useState([]);
const [facilities, setFacilities] = React.useState([]);
const [locations, setLocations] = React.useState([]);

const value = React.useMemo(() => {
Expand All @@ -69,18 +85,65 @@ const Search = ({ data, providers_data, query, setQuery, ...props }) => {

const items = React.useMemo(() => {
if (loading) return [];
const half = MAX_RESULTS / 2;
let _locations = locations.slice(0, half);
let _sites = sites.slice(0, half);
if (_locations.length < half) {
_sites = sites.slice(0, MAX_RESULTS - _locations.length);
const slices = MAX_RESULTS / 3;
let total_entities = 1;
let empty_slices = 0;
let entities = 0;
let _locations = locations.slice(0, slices);
let _sites = sites.slice(0, slices);
let _facilities = facilities.slice(0, slices);

if (_locations.length < slices) {
empty_slices += slices - _locations.length;
entities++;
} else if (_locations.length <= slices) {
total_entities++;
}
if (_sites.length < half) {
_locations = locations.slice(0, MAX_RESULTS - _sites.length);
if (_sites.length < slices) {
empty_slices += slices - _sites.length;
entities++;
} else if (_sites.length <= slices) {
total_entities++;
}
if (_facilities.length < slices) {
empty_slices += slices - _facilities.length;
entities++;
} else if (_facilities.length <= slices) {
total_entities++;
}

if (locations.length > slices && empty_slices > 0) {
const used_slices = Math.round(
empty_slices / (total_entities - entities),
);
_locations = locations.slice(0, slices + used_slices);
empty_slices -= used_slices;
} else {
total_entities--;
}

if (sites.length > slices && empty_slices > 0) {
const used_slices = Math.round(
empty_slices / (total_entities - entities),
);
_sites = sites.slice(0, slices + used_slices);
empty_slices -= used_slices;
} else {
total_entities--;
}

return [..._locations, ..._sites];
}, [sites, locations, loading]);
if (facilities.length > slices && empty_slices > 0) {
const used_slices = Math.round(
empty_slices / (total_entities - entities),
);
_facilities = facilities.slice(0, slices + used_slices);
empty_slices -= used_slices;
} else {
total_entities--;
}

return [..._locations, ..._sites, ..._facilities];
}, [sites, facilities, locations, loading]);

const handleClickOutside = React.useCallback((event) => {
if (!doesNodeContainClick(searchContainer.current, event)) {
Expand All @@ -96,6 +159,7 @@ const Search = ({ data, providers_data, query, setQuery, ...props }) => {
const requests = [];
if (value.length >= 3) {
requests.push(getSites(value));
requests.push(getFacilities(value));
requests.push(getLocations(value, providers_data));

Promise.all(requests).then((responses) => {
Expand All @@ -105,17 +169,24 @@ const Search = ({ data, providers_data, query, setQuery, ...props }) => {
type: 'site',
})) || [],
);
setFacilities(
responses[1].data?.results?.map((item) => ({
text: item.facilityName,
type: 'facility',
})) || [],
);
setLocations(
responses[1].data?.suggestions?.map((item) => ({
responses[2].data?.suggestions?.map((item) => ({
...item,
type: 'location',
})) || [],
);
setLoading(false);
});
setLoading(false);
} else {
setLoading(false);
setSites([]);
setFacilities([]);
setLocations([]);
}
},
Expand Down
11 changes: 7 additions & 4 deletions src/components/manage/Blocks/IndustryDataTable/View.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ const getConditions = (query) => {
};

const View = (props) => {
const table = React.useRef();
const context = React.useContext(ConnectorContext);
const [openedRow, setOpenedRow] = React.useState(null);
const {
Expand Down Expand Up @@ -218,7 +219,7 @@ const View = (props) => {
}, [JSON.stringify(query)]);

return (
<div className="industry-table">
<div ref={table} className="industry-table">
{row_size && tableData ? (
<Table
textAlign="left"
Expand Down Expand Up @@ -456,7 +457,9 @@ const View = (props) => {
<Menu.Item
as="a"
icon
disabled={props.isPending || pagination.activePage === 1}
disabled={
props.loadingProviderData || pagination.activePage === 1
}
onClick={() => {
if (pagination.activePage > 1) {
updatePagination({
Expand All @@ -469,7 +472,7 @@ const View = (props) => {
</Menu.Item>
<Menu.Item fitted>
<Loader
disabled={!props.isPending}
disabled={!props.loadingProviderData}
active
inline
size="tiny"
Expand All @@ -479,7 +482,7 @@ const View = (props) => {
as="a"
icon
disabled={
props.isPending ||
props.loadingProviderData ||
pagination.activePage === pagination.lastPage
}
onClick={() => {
Expand Down
26 changes: 26 additions & 0 deletions src/components/manage/Blocks/IndustryMap/View.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
getLayerBaseURL,
getLocationExtent,
getSiteExtent,
getFacilityExtent,
getCountriesExtent,
getWhereStatement,
} from './index';
Expand Down Expand Up @@ -197,6 +198,31 @@ class View extends React.PureComponent {
});
}
});
} else if (filter_change.type === 'search-facility') {
getFacilityExtent(filter_search).then(({ data }) => {
const extent = data?.results?.[0] || {};
if (
extent.MIN_X === null ||
extent.MIN_Y === null ||
extent.MAX_X === null ||
extent.MAX_Y === null
) {
toast.warn(
<Toast
warn
title=""
content={`No results for ${filter_search.text}`}
/>,
);
} else {
this.map.current
.getView()
.fit([extent.MIN_X, extent.MIN_Y, extent.MAX_X, extent.MAX_Y], {
maxZoom: 16,
duration: 1000,
});
}
});
} else if (
(filter_change.type === 'advanced-filter' ||
filter_change.type === 'simple-filter') &&
Expand Down
20 changes: 19 additions & 1 deletion src/components/manage/Blocks/IndustryMap/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,31 @@ export const getSiteExtent = (data) => {
MAX(shape_wm.STX) AS MAX_X,
MAX(shape_wm.STY) AS MAX_Y
FROM [IED].[${db_version}].[SiteMap]
WHERE [siteName] COLLATE Latin1_General_CI_AI LIKE '%${data.text.replace(
WHERE [siteName] COLLATE Latin1_General_CI_AI LIKE '%${data.text.replaceAll(
"'",
"''",
)}%'`)}`,
);
};

export const getFacilityExtent = (data) => {
const db_version =
process.env.RAZZLE_DB_VERSION || config.settings.db_version || 'latest';

let text = data.text.replaceAll('\n', '');
text = text.replaceAll("'", "''");

return axios.get(
`${config.settings.providerUrl}?${getEncodedQueryString(`SELECT
MIN(shape_wm.STX) AS MIN_X,
MIN(shape_wm.STY) AS MIN_Y,
MAX(shape_wm.STX) AS MAX_X,
MAX(shape_wm.STY) AS MAX_Y
FROM [IED].[${db_version}].[SiteMap]
WHERE [facilityNames] COLLATE Latin1_General_CI_AI LIKE '%${text}%'`)}`,
);
};

export const getCountriesExtent = (countries) => {
const requests = [];
countries.forEach((country) => {
Expand Down
117 changes: 117 additions & 0 deletions src/customizations/volto/components/theme/View/DefaultView.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* Document view component.
* @module components/theme/View/DefaultView
*/

import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl';

import { Container, Segment, Grid, Label } from 'semantic-ui-react';
import config from '@plone/volto/registry';
import { getSchema } from '@plone/volto/actions';
import { getWidget } from '@plone/volto/helpers/Widget/utils';
import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks';

import { hasBlocksData, getBaseUrl } from '@plone/volto/helpers';
import { useDispatch, useSelector } from 'react-redux';

/**
* Component to display the default view.
* @function DefaultView
* @param {Object} content Content object.
* @returns {string} Markup of the component.
*/
const DefaultView = (props) => {
const { content, location } = props;
const path = getBaseUrl(location?.pathname || '');
const dispatch = useDispatch();
const { views } = config.widgets;
const contentSchema = useSelector((state) => state.schema?.schema);
const fieldsetsToExclude = [
'categorization',
'dates',
'ownership',
'settings',
];
const fieldsets = contentSchema?.fieldsets.filter(
(fs) => !fieldsetsToExclude.includes(fs.id),
);

React.useEffect(() => {
content?.['@type'] &&
!hasBlocksData(content) &&
dispatch(getSchema(content['@type'], location.pathname));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return hasBlocksData(content) ? (
<div id="page-document" className="ui container">
<RenderBlocks {...props} path={path} />
</div>
) : (
<Container id="page-document">
{fieldsets?.map((fs) => {
return (
<div className="fieldset" key={fs.id}>
{fs.id !== 'default' && <h2>{fs.title}</h2>}
{fs.fields?.map((f, key) => {
let field = {
...contentSchema?.properties[f],
id: f,
widget: getWidget(f, contentSchema?.properties[f]),
};
let Widget = views?.getWidget(field);
return f !== 'title' ? (
<Grid celled="internally" key={key}>
<Grid.Row>
<Label>{field.title}:</Label>
</Grid.Row>
<Grid.Row>
<Segment basic>
<Widget value={content[f]} />
</Segment>
</Grid.Row>
</Grid>
) : (
<Widget key={key} value={content[f]} />
);
})}
</div>
);
})}
</Container>
);
};

/**
* Property types.
* @property {Object} propTypes Property types.
* @static
*/
DefaultView.propTypes = {
/**
* Content of the object
*/
content: PropTypes.shape({
/**
* Title of the object
*/
title: PropTypes.string,
/**
* Description of the object
*/
description: PropTypes.string,
/**
* Text of the object
*/
text: PropTypes.shape({
/**
* Data of the text of the object
*/
data: PropTypes.string,
}),
}).isRequired,
};

export default injectIntl(DefaultView);
Loading

0 comments on commit 2e719ca

Please sign in to comment.