Skip to content

Commit

Permalink
WIP: Use relatedPlanIndicators in umbrella plan instead of planindica…
Browse files Browse the repository at this point in the history
…tors. Filter by relatedPlanIndicators common categories instead of planIndicator categories
  • Loading branch information
Bhavatu committed Oct 15, 2024
1 parent 3567ba4 commit 33ad638
Showing 1 changed file with 206 additions and 43 deletions.
249 changes: 206 additions & 43 deletions components/indicators/IndicatorList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,85 @@ const createFilterUnusedCategories =
)
);

const getFilterConfig = (categoryType, indicators) => ({
const createFilterUnusedCommonCategories =
(indicators: Indicator[]) => (commonCategory: any) =>
indicators.find(({ categories }) =>
categories.find(
(category) =>
category.common && category.common.id === commonCategory.id
)
);

const collectCommonCategories = (indicators) => {
const commonCategories = {};
indicators.forEach((indicator) => {
indicator.categories.forEach((category) => {
if (category.common) {
const typeIdentifier = category.type.identifier;
if (!commonCategories[typeIdentifier]) {
commonCategories[typeIdentifier] = {
categories: new Set(),
type: { ...category.type },
};
}
commonCategories[typeIdentifier].categories.add(category.common);
}
});
});
return Object.entries(commonCategories).map(([typeIdentifier, data]) => ({
typeIdentifier,
categories: Array.from(data.categories),
type: data.type,
}));
};

const includeRelatedPlanIndicators = true;

const getFilterConfig = (categoryType, indicators, commonCategories) => ({
mainFilters: [
{
__typename: 'CategoryTypeFilterBlock',
field: 'category',
id: '817256d7-a6fb-4af1-bbba-096171eb0d36',
style: 'dropdown',
showAllLabel: '',
depth: null,
categoryType: {
...categoryType,
categories: categoryType.categories.filter(
createFilterUnusedCategories(indicators)
),
hideCategoryIdentifiers: true,
selectionType: 'SINGLE',
},
},
...(includeRelatedPlanIndicators
? commonCategories.map(({ typeIdentifier, categories, type }) => ({
__typename: 'CategoryTypeFilterBlock',
field: 'category',
id: `common_${typeIdentifier}`,
style: 'dropdown',
showAllLabel: '',
depth: null,
categoryType: {
...type,
name: type.name || typeIdentifier,
categories: categories.filter(
createFilterUnusedCommonCategories(indicators)
),
hideCategoryIdentifiers: true,
selectionType: 'SINGLE',
},
}))
: [
{
__typename: 'CategoryTypeFilterBlock',
field: 'category',
id: '817256d7-a6fb-4af1-bbba-096171eb0d36',
style: 'dropdown',
showAllLabel: '',
depth: null,
categoryType: {
...categoryType,
categories: categoryType.categories.filter(
createFilterUnusedCategories(indicators)
),
hideCategoryIdentifiers: true,
selectionType: 'SINGLE',
},
},
]),
],
primaryFilters: [],
advancedFilters: [],
});

const GET_INDICATOR_LIST = gql`
query IndicatorList($plan: ID!) {
query IndicatorList($plan: ID!, $relatedPlanIndicators: Boolean!) {
plan(id: $plan) {
id
features {
Expand Down Expand Up @@ -134,7 +188,7 @@ const GET_INDICATOR_LIST = gql`
}
hasIndicatorRelationships
}
planIndicators(plan: $plan) {
planIndicators(plan: $plan) @skip(if: $relatedPlanIndicators) {
id
common {
id
Expand Down Expand Up @@ -162,6 +216,63 @@ const GET_INDICATOR_LIST = gql`
}
}
}
relatedPlanIndicators(plan: $plan) @include(if: $relatedPlanIndicators) {
id
name
level(plan: $plan)
timeResolution
organization {
id
name
}
common {
id
name
normalizations {
unit {
shortName
}
normalizer {
name
id
identifier
}
}
}
latestGraph {
id
}
latestValue {
id
date
value
normalizedValues {
normalizerId
value
}
}
unit {
shortName
}
categories {
id
name
parent {
id
}
type {
id
identifier
name
}
common {
id
identifier
name
order
}
}
}
}
`;

Expand All @@ -175,26 +286,67 @@ const filterIndicators = (
filters: Filters,
categoryIdentifier?: string
) => {
const filterByCategory = (indicator) =>
!categoryIdentifier ||
!filters[getCategoryString(categoryIdentifier)] ||
!!indicator.categories.find(
const filterByCategory = (indicator) => {
if (
!categoryIdentifier ||
!filters[getCategoryString(categoryIdentifier)]
) {
return true;
}
return indicator.categories.some(
({ type, id }) => filters[getCategoryString(type.identifier)] === id
);
};

const filterBySearch = (indicator) =>
!filters['name'] ||
indicator.name.toLowerCase().includes(filters['name'].toLowerCase());
const filterByCommonCategory = (indicator) => {
if (
!categoryIdentifier ||
!filters[getCategoryString(categoryIdentifier)]
) {
return true;
}

return indicators.filter(
(indicator) => filterByCategory(indicator) && filterBySearch(indicator)
);
const filterValue = filters[getCategoryString(categoryIdentifier)];

const ret = indicator.categories.some((category) => {
if (category.common) {
console.log(category.common.id, filterValue);
return category.common.id === filterValue;
}
return true;
});

console.log('filterByCommonCategory result:', ret);
return ret;
};

const filterBySearch = (indicator) => {
if (!filters['name']) {
return true;
}
return indicator.name.toLowerCase().includes(filters['name'].toLowerCase());
};

const reti = indicators.filter((indicator) => {
const categoryResult = filterByCategory(indicator);
const commonCategoryResult = filterByCommonCategory(indicator);
const searchResult = filterBySearch(indicator);

console.log(`All filter results for indicator ${indicator.id}:`, {
category: categoryResult,
commonCategory: commonCategoryResult,
search: searchResult,
});
return (
(!includeRelatedPlanIndicators ? categoryResult : commonCategoryResult) &&
searchResult
);
});

console.log('Filtered indicators:', reti.length);
return reti;
};

/**
* IndicatorListFiltered currently only accepts and displays a single category type,
* so we use the first usableForIndicators category type which has associated indicators.
*/
const getFirstUsableCategoryType = (categoryTypes, indicators) =>
categoryTypes.find((categoryType) =>
indicators.find((indicator) =>
Expand All @@ -215,7 +367,10 @@ const IndicatorList = ({ leadContent, displayInsights }: Props) => {
const { loading, error, data } = useQuery<IndicatorListQuery>(
GET_INDICATOR_LIST,
{
variables: { plan: plan.identifier },
variables: {
plan: plan.identifier,
relatedPlanIndicators: includeRelatedPlanIndicators,
},
}
);

Expand All @@ -228,23 +383,22 @@ const IndicatorList = ({ leadContent, displayInsights }: Props) => {
);

const handleFilterChange = (id: string, val: FilterValue) => {
console.log(`Filter changed: ${id} = ${val}`);
setFilters((state) => {
const newFilters = { ...state, [id]: val };

console.log('New filters:', newFilters);
updateSearchParams(newFilters);

return newFilters;
});
};

const hasInsights = (data) => {
const { plan } = data;
// Check if any of the indicators has causality link
return plan.hasIndicatorRelationships === true;
};

const getIndicatorListProps = (data) => {
const { plan } = data;
const { plan, relatedPlanIndicators } = data;
const displayMunicipality = plan.features.hasActionPrimaryOrgs === true;
const displayNormalizedValues =
undefined !==
Expand All @@ -258,7 +412,6 @@ const IndicatorList = ({ leadContent, displayInsights }: Props) => {

const indicators = indicatorLevels.map((il) => {
const { indicator, level } = il;

return { ...indicator, level: level.toLowerCase() };
});

Expand All @@ -274,16 +427,26 @@ const IndicatorList = ({ leadContent, displayInsights }: Props) => {
if (error) return <ErrorMessage message={error.message} />;

const indicatorListProps = getIndicatorListProps(data);
const hierarchy = processCommonIndicatorHierarchy(data?.planIndicators);

const indicators = includeRelatedPlanIndicators
? data.relatedPlanIndicators
: indicatorListProps.indicators;

const commonCategories = collectCommonCategories(indicators);
const hierarchy = processCommonIndicatorHierarchy(
includeRelatedPlanIndicators
? data?.relatedPlanIndicators
: data?.planIndicators
);
const showInsights = (displayInsights ?? true) && hasInsights(data);

const categoryType = getFirstUsableCategoryType(
data?.plan?.categoryTypes,
indicatorListProps.indicators
indicators
);

const filterConfig = categoryType
? getFilterConfig(categoryType, indicatorListProps.indicators)
? getFilterConfig(categoryType, indicators, commonCategories)
: {};

const filterSections: ActionListFilterSection[] =
Expand All @@ -297,7 +460,7 @@ const IndicatorList = ({ leadContent, displayInsights }: Props) => {
});

const filteredIndicators = filterIndicators(
indicatorListProps.indicators,
indicators,
filters,
categoryType?.identifier
);
Expand Down

0 comments on commit 33ad638

Please sign in to comment.