Skip to content
This repository was archived by the owner on Aug 23, 2023. It is now read-only.

Commit 3d2a4a9

Browse files
committed
Merge branch 'release/v1.0.84'
2 parents c2ee34f + beae245 commit 3d2a4a9

12 files changed

Lines changed: 506 additions & 433 deletions

File tree

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@hisptz/react-ui",
33
"homepage": "https://hisptz.github.io/react-ui",
4-
"version": "1.0.83",
4+
"version": "1.0.84",
55
"description": "A collection of reusable complex DHIS2 react ui components.",
66
"license": "BSD-3-Clause",
77
"scripts": {
@@ -37,7 +37,7 @@
3737
"@dhis2/cli-utils-cypress": "^9.0.2",
3838
"@dhis2/cypress-commands": "^9.0.2",
3939
"@dhis2/cypress-plugins": "^9.0.2",
40-
"@dhis2/ui": "^8.6.2",
40+
"@dhis2/ui": "^8.7.6",
4141
"@hookform/devtools": "^4.1.0",
4242
"@storybook/addon-actions": "^6.5.9",
4343
"@storybook/addon-essentials": "^6.5.9",
@@ -83,7 +83,7 @@
8383
"dependencies": {
8484
"@google/earthengine": "^0.1.330",
8585
"@hisptz/dhis2-utils": "^1.0.0-alpha.2",
86-
"@iapps/period-utilities": "^1.0.0-beta.7",
86+
"@iapps/period-utilities": "1.0.0-beta.7",
8787
"@material-ui/core": "^4.12.4",
8888
"@material-ui/icons": "^4.11.3",
8989
"async-es": "^3.2.4",
@@ -97,7 +97,7 @@
9797
"leaflet": "^1.8.0",
9898
"leaflet-easyprint": "^2.1.9",
9999
"leaflet.fullscreen": "^2.4.0",
100-
"luxon": "^2.4.0",
100+
"luxon": "^3.2.1",
101101
"material-ui": "^0.20.2",
102102
"print-message": "^3.0.1",
103103
"react-beautiful-dnd": "^13.1.0",

src/components/OrgUnitSelector/OrgUnitSelector.stories.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ Default.args = {
1212
console.log(value);
1313
},
1414
};
15+
16+
export const SelectedOrgUnit = Template.bind({});
17+
SelectedOrgUnit.args = {
18+
value: {
19+
orgUnits: [
20+
{
21+
path: "/ImspTQPwCqd/Vth0fbpFcsO/LhaAPLxdSFH/AvGz949akv4",
22+
children: [],
23+
id: "AvGz949akv4",
24+
},
25+
],
26+
},
27+
onUpdate: (value) => {
28+
console.log(value);
29+
},
30+
};
1531
export const SingleSelection = Template.bind({});
1632
SingleSelection.args = {
1733
value: { orgUnits: [] },

src/components/OrgUnitSelector/components/OrgUnitSearch/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ import { useFilterOrgUnits } from "../../hooks";
77
export function OrgUnitSearch({ searchable }: { searchable?: boolean }) {
88
const [keyword, setKeyword] = useState<string | undefined>();
99
const { onSearch } = useFilterOrgUnits();
10-
const search = useRef(onSearch ? debounce(onSearch, 500) : null);
10+
const search = onSearch;
1111

1212
const onSearchChange = useCallback(
1313
({ value }: { value: string }) => {
1414
setKeyword(value);
15-
search.current?.(value);
15+
if (onSearch) {
16+
onSearch(value);
17+
}
1618
},
1719
[search]
1820
);

src/components/OrgUnitSelector/components/OrgUnitTree/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ function Tree({
3737
const { searchMode, searchValue, expanded, filtering, filteredOrgUnits, handleExpand } = useFilterOrgUnits();
3838
const selectedOrgUnits = value?.orgUnits ?? [];
3939

40+
console.log(expanded);
41+
4042
const onSelect = (orgUnit: any) => {
4143
const orgUnitLevel = orgUnit.level ?? orgUnit.path.split("/").length - 1;
4244
const allowSelection = limitSelectionToLevels?.includes(orgUnitLevel) ?? true;
@@ -75,6 +77,7 @@ function Tree({
7577
</div>
7678
) : (
7779
<OrganisationUnitTree
80+
initiallyExpanded={expanded}
7881
forceReload
7982
filter={filteredOrgUnits}
8083
disableSelection={disableSelections}

src/components/OrgUnitSelector/states/filter.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useDataQuery } from "@dhis2/app-runtime";
22
import type { OrganisationUnit } from "@hisptz/dhis2-utils";
3-
import { compact, isEmpty } from "lodash";
4-
import React, { createContext, ReactNode, useCallback, useEffect, useMemo, useState } from "react";
3+
import { compact, debounce, isEmpty } from "lodash";
4+
import React, { createContext, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from "react";
55
import { orgUnitSearchQuery } from "../services";
66
import { sanitizeExpansionPaths, sanitizeFilters } from "../utils";
77

@@ -73,14 +73,12 @@ export function FilterStateProvider({
7373
}
7474
}, [orgUnitsPaths]);
7575

76-
const onSearch = useCallback(
77-
async (keyword: string) => {
76+
const onSearch = useRef(
77+
debounce(async (keyword: string) => {
7878
setSearchValue(keyword);
7979
return await getSearch(keyword);
80-
},
81-
[getSearch]
82-
);
83-
80+
}, 500)
81+
)?.current;
8482
const handleExpand = ({ path }: { path: string }) => {
8583
setExpanded((prevState) => {
8684
if (prevState.includes(path)) {

src/components/OrgUnitSelector/utils/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,16 @@ export const sanitizeFilters = (filters: Array<OrganisationUnit>): Array<string>
118118
};
119119

120120
export const sanitizeExpansionPaths = (orgUnitPaths: string[]): string[] => {
121-
return orgUnitPaths.map((path: string) => path.split("/").slice(0, -1).join("/"));
121+
return uniq(
122+
orgUnitPaths
123+
.map((path: string) => {
124+
const orgUnits = path.split("/").filter((value) => !isEmpty(value));
125+
return orgUnits
126+
.map((orgUnit, index) => {
127+
return `/${orgUnits.slice(0, -(index + 1)).join("/")}`;
128+
})
129+
.filter((value) => value !== "/");
130+
})
131+
.flat()
132+
);
122133
};

src/components/PeriodSelector/PeriodSelector.stories.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,23 @@ SelectedPeriods.args = {
100100
calendar: CalendarTypes.GREGORIAN,
101101
};
102102

103+
export const WithAllowedFuturePeriods = Template.bind({});
104+
WithAllowedFuturePeriods.args = {
105+
onSelect: ({ items }) => {
106+
console.log(items);
107+
},
108+
enableDateRange: true,
109+
selectedPeriods: [
110+
{
111+
id: "2022",
112+
name: "2022",
113+
},
114+
],
115+
allowFuturePeriods: false,
116+
excludedPeriodTypes: [],
117+
calendar: CalendarTypes.GREGORIAN,
118+
};
119+
103120
export const DateRange = Template.bind({});
104121
DateRange.args = {
105122
onSelect: ({ items }) => {

src/components/PeriodSelector/components/CalendarSpecificPeriodDimension/index.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ import { CalendarTypes } from "./constants/calendar";
88
import { PeriodCategories } from "./constants/period";
99
import { CalendarSpecificPeriodSelectorProps } from "./interfaces/props";
1010
import "../../../../styles/styles.css";
11+
import { DateTime, Interval } from "luxon";
12+
13+
function filterFuturePeriods(periods: PeriodInterface[]): PeriodInterface[] {
14+
return periods.filter((period) => {
15+
if (period.startDate && period.endDate) {
16+
const startDate = DateTime.fromFormat(period.startDate, "dd-MM-yyyy");
17+
const endDate = DateTime.fromFormat(period.endDate, "dd-MM-yyyy");
18+
return startDate.diffNow("days").days < 0 || Interval.fromDateTimes(startDate, endDate).contains(DateTime.now());
19+
} else {
20+
return true;
21+
}
22+
});
23+
}
1124

1225
export default function CalendarSpecificPeriodSelector({
1326
excludedPeriodTypes,
@@ -17,6 +30,7 @@ export default function CalendarSpecificPeriodSelector({
1730
excludeFixedPeriods,
1831
excludeRelativePeriods,
1932
singleSelection,
33+
allowFuturePeriods,
2034
}: CalendarSpecificPeriodSelectorProps) {
2135
const periodInstance = new Period().setCalendar(CalendarTypes.ETHIOPIAN);
2236

@@ -78,13 +92,21 @@ export default function CalendarSpecificPeriodSelector({
7892
}
7993
if (selectedFixedPeriodType) {
8094
if (selectedPeriodCategory.key === PeriodCategories.FIXED.key) {
81-
return new Period()
95+
const periods = new Period()
8296
.setPreferences({ openFuturePeriods: 4, allowFuturePeriods: true })
8397
.setCalendar(calendar)
8498
.setYear(year)
8599
.setType(selectedFixedPeriodType)
86100
.get()
87101
.list();
102+
103+
console.log(periods);
104+
105+
if (allowFuturePeriods) {
106+
return periods;
107+
} else {
108+
return filterFuturePeriods(periods);
109+
}
88110
}
89111
}
90112
}

src/components/PeriodSelector/components/CalendarSpecificPeriodDimension/interfaces/props.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ export interface CalendarSpecificPeriodSelectorProps {
99
selectedPeriods?: Array<PeriodInterface>;
1010
excludeRelativePeriods?: boolean;
1111
excludeFixedPeriods?: boolean;
12+
allowFuturePeriods?: boolean;
1213
}

src/components/PeriodSelector/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default function PeriodSelector({
1818
singleSelection,
1919
enableDateRange,
2020
defaultInputType,
21+
allowFuturePeriods,
2122
}: PeriodSelectorProps) {
2223
const initialInputType = useMemo(() => {
2324
if (!isEmpty(selectedPeriods)) {
@@ -61,6 +62,7 @@ export default function PeriodSelector({
6162
)}
6263
{inputType === "period" && (
6364
<CalendarSpecificPeriodSelector
65+
allowFuturePeriods={allowFuturePeriods}
6466
singleSelection={singleSelection}
6567
excludedPeriodTypes={excludedPeriodTypes ?? []}
6668
calendar={calendar ?? CalendarTypes.GREGORIAN}

0 commit comments

Comments
 (0)