Skip to content

Commit c22800f

Browse files
committed
implemented allLoaded state
resolves #86
1 parent ee17df6 commit c22800f

29 files changed

+237
-171
lines changed

app/@newrecord/(.)new-record/page.jsx

Lines changed: 0 additions & 9 deletions
This file was deleted.

app/@newrecord/default.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

app/api/page.jsx

Lines changed: 0 additions & 8 deletions
This file was deleted.

app/new-record/page.jsx

Lines changed: 0 additions & 5 deletions
This file was deleted.

components/InstitutionContainer/InstitutionContainer.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export function InstitutionContainer({ institutionName, isInstitutionOpen }) {
2121
handlers: formHandlers = { handleInstitutionOpen },
2222
} = useFormContext();
2323

24+
console.log("container getValues", getValues("institutions"));
2425
// Fast solution to allow edit name of newly created institution
2526
// Will be replaced whith https://github.com/users/skorphil/projects/4/views/1?pane=issue&itemId=53834705
2627
const institutionIndex = parseInt(institutionName.split(".")[1]);
Lines changed: 5 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
11
"use client";
22

33
import { InstitutionsTabsList } from "../InstitutionsTabsList";
4-
import { InstitutionContainer } from "../InstitutionContainer";
5-
import {
6-
Tabs,
7-
Text,
8-
TabPanels,
9-
TabPanel,
10-
Center,
11-
Heading,
12-
VStack,
13-
Image,
14-
} from "@chakra-ui/react";
4+
import { Tabs } from "@chakra-ui/react";
155
import { useVisualViewportSize } from "../../app/hooks";
166
import classes from "./InstitutionsList.module.css";
177
import { useFormContext } from "react-hook-form";
8+
import { InstitutionPanel } from "./components";
189

1910
function InstitutionsList({
11+
institutionPanelOverlay,
2012
simulateKeyboard = false,
2113
isInstitutionOpen,
2214
selectedInstitution,
@@ -38,7 +30,8 @@ function InstitutionsList({
3830
variant="grid"
3931
padding={isInstitutionOpen || 2}
4032
>
41-
<ContentPanel
33+
<InstitutionPanel
34+
institutionPanelOverlay={institutionPanelOverlay}
4235
institutions={institutions}
4336
selectedInstitution={selectedInstitution}
4437
isInstitutionOpen={isInstitutionOpen}
@@ -55,55 +48,3 @@ function InstitutionsList({
5548
}
5649

5750
export { InstitutionsList };
58-
59-
function ContentPanel({
60-
institutions,
61-
selectedInstitution,
62-
isInstitutionOpen,
63-
}) {
64-
return (
65-
<TabPanels
66-
bg="gray.800"
67-
borderRadius={isInstitutionOpen || "lg"}
68-
h="100%"
69-
minHeight="260px"
70-
flexGrow={1}
71-
flexShrink={1}
72-
>
73-
{selectedInstitution === null ? (
74-
<ContentPanelOverlay
75-
image="/institutions-loaded.svg"
76-
headingText="Institutions loaded from latest&nbsp;record"
77-
text="Edit institutions to reflect asset updates"
78-
/>
79-
) : (
80-
false
81-
)}
82-
{institutions.map((institution, index) => (
83-
<TabPanel p={0} key={institution.id} h="100%">
84-
<InstitutionContainer
85-
institutionName={`institutions.${index}`}
86-
isInstitutionOpen={isInstitutionOpen}
87-
/>
88-
</TabPanel>
89-
))}
90-
</TabPanels>
91-
);
92-
}
93-
94-
function ContentPanelOverlay({ image, headingText, text }) {
95-
return (
96-
<Center h="100%" p={2}>
97-
<VStack gap={12}>
98-
<Image src={image} alt="Illustration" boxSize="140px" />
99-
100-
<VStack>
101-
<Heading textAlign="center" size="md">
102-
{headingText}
103-
</Heading>
104-
<Text>{text}</Text>
105-
</VStack>
106-
</VStack>
107-
</Center>
108-
);
109-
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"use client";
2+
import { InstitutionContainer } from "../../InstitutionContainer";
3+
import { TabPanels, TabPanel } from "@chakra-ui/react";
4+
import { useFormContext } from "react-hook-form";
5+
import { getInstitutionPanelOverlayState } from "../utils/getInstitutionPanelOverlayState";
6+
import { InstitutionPanelOverlayAllDeleted } from "./InstitutionPanelOverlayAllDeleted";
7+
import { InstitutionPanelOverlayInstitutionsLoaded } from "./InstitutionPanelOverlayInstitutionsLoaded";
8+
9+
// TODO add all instituion deleted state
10+
export function InstitutionPanel({
11+
institutions,
12+
selectedInstitution,
13+
isInstitutionOpen,
14+
}) {
15+
const {
16+
formState: { defaultValues },
17+
getValues,
18+
} = useFormContext();
19+
20+
const overlayState = getInstitutionPanelOverlayState(
21+
defaultValues,
22+
getValues
23+
);
24+
25+
return (
26+
<TabPanels
27+
bg="gray.800"
28+
borderRadius={isInstitutionOpen || "lg"}
29+
h="100%"
30+
minHeight="260px"
31+
flexGrow={1}
32+
flexShrink={1}
33+
>
34+
{selectedInstitution !== null ? (
35+
institutions.map((institution, index) => (
36+
<TabPanel p={0} key={institution.id} h="100%" overflow="auto">
37+
<InstitutionContainer
38+
institutionName={`institutions.${index}`}
39+
isInstitutionOpen={isInstitutionOpen}
40+
/>
41+
</TabPanel>
42+
))
43+
) : overlayState == "success" && selectedInstitution == null ? (
44+
<InstitutionPanelOverlayInstitutionsLoaded />
45+
) : overlayState == "allDeleted" && selectedInstitution == null ? (
46+
<InstitutionPanelOverlayAllDeleted />
47+
) : (
48+
false
49+
)}
50+
</TabPanels>
51+
);
52+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Text, Center, Heading, VStack, Image } from "@chakra-ui/react";
2+
3+
export function InstitutionPanelOverlay({ image, headingText, text }) {
4+
return (
5+
<Center h="100%" p={2}>
6+
<VStack gap={12}>
7+
<Image src={image} alt="Illustration" boxSize="240px" />
8+
9+
<VStack>
10+
<Heading textAlign="center" size="md">
11+
{headingText}
12+
</Heading>
13+
<Text>{text}</Text>
14+
</VStack>
15+
</VStack>
16+
</Center>
17+
);
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { InstitutionPanelOverlay } from "./InstitutionPanelOverlay";
2+
3+
export function InstitutionPanelOverlayAllDeleted() {
4+
return (
5+
<InstitutionPanelOverlay
6+
image="/empty.svg"
7+
headingText="No institutions left&nbsp;in&nbsp;the&nbsp;record"
8+
text="Add or restore institutions"
9+
/>
10+
);
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { InstitutionPanelOverlay } from "./InstitutionPanelOverlay";
2+
3+
export function InstitutionPanelOverlayInstitutionsLoaded() {
4+
return (
5+
<InstitutionPanelOverlay
6+
image="/institutions-loaded.svg"
7+
headingText="Institutions loaded from latest&nbsp;record"
8+
text="Edit institutions to reflect asset updates"
9+
/>
10+
);
11+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { InstitutionPanel } from "./InstitutionPanel";

components/InstitutionsList/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export { InstitutionsList } from "./InstitutionsList";
22
export { institutionsListStyle } from "./InstitutionList.chakra";
3+
export { InstitutionPanelOverlay } from "./components/InstitutionPanelOverlay";
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { DefaultValues, FieldValues, UseFormGetValues } from "react-hook-form";
2+
3+
/**
4+
* Function for deriving the InstitutionPanelOverlay state
5+
* from useFormContext
6+
*/
7+
export function getInstitutionPanelOverlayState(defaultValues:DefaultValues<FieldValues>, getValues:UseFormGetValues<FieldValues>) {
8+
const formValues = getValues("institutions");
9+
const isAllDeleted = isAllInstitutionsDeleted(formValues);
10+
const isFetchedPrevious = isFetchedPreviousRecords(defaultValues, isAllDeleted);
11+
// console.log("isFetchedPrevious TS", isFetchedPrevious);
12+
// console.log("isAllDeleted TS", isAllDeleted);
13+
14+
if (isFetchedPrevious && !isAllDeleted) {
15+
return 'success'
16+
} else if (isAllDeleted) {
17+
return 'allDeleted'
18+
} else return false;
19+
}
20+
21+
function isAllInstitutionsDeleted(formValues) {
22+
const institutionsIndexes = formValues.map((institution, index) => ({
23+
index,
24+
isDeleted: institution.isDeleted,
25+
}));
26+
const availableIndexes = institutionsIndexes
27+
.filter((institution) => institution.isDeleted != true)
28+
.map((institution) => institution.index);
29+
30+
if (institutionsIndexes.length > 0 && availableIndexes.length == 0) {
31+
return true;
32+
} else return false;
33+
}
34+
35+
function isFetchedPreviousRecords(defaultValues, isAllDeleted) {
36+
if (defaultValues.institutions && !isAllDeleted) {
37+
return true;
38+
} else return false;
39+
}
40+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { getInstitutionPanelOverlayState } from "./getInstitutionPanelOverlayState";

components/RecordForm/RecordForm.jsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { useState } from "react";
1313
import { Button, Progress, useToast } from "@chakra-ui/react";
1414
import { InstitutionsList } from "components/InstitutionsList";
1515
import { FormHeader } from "components/FormHeader";
16-
import { FormStateOverlay, FormWarning } from "./components";
16+
import { FormOverlay, FormAlert } from "./components";
1717

1818
import { appendRecord } from "serverActions/appendRecord";
1919
import { getDefaultValues } from "./utils";
@@ -25,15 +25,15 @@ export function RecordForm() {
2525
const [selectedInstitutionIndex, setSelectedInstitutionIndex] =
2626
useState(null);
2727
const [formOverlay, setFormOverlay] = useState(false);
28-
const [warningState, setWarningState] = useState(null);
28+
const [formAlert, setFormAlert] = useState(null);
2929
const toast = useToast({ position: "top" });
3030
const router = useRouter();
3131
const arrayName = "institutions";
3232
const { control, ...form } = useForm({
3333
defaultValues: async () =>
3434
getDefaultValues({
3535
setFormOverlay,
36-
setWarningState,
36+
setFormAlert,
3737
handleInstitutionCreate: formMethods.handlers.handleInstitutionCreate,
3838
}),
3939
});
@@ -106,11 +106,11 @@ export function RecordForm() {
106106
</>
107107
}
108108
/>
109-
{warningState?.isVisible && (
110-
<FormWarning
111-
{...warningState}
109+
{formAlert?.isVisible && (
110+
<FormAlert
111+
{...formAlert}
112112
onHide={() =>
113-
setWarningState((current) => ({
113+
setFormAlert((current) => ({
114114
...current,
115115
isVisible: false,
116116
}))
@@ -123,12 +123,12 @@ export function RecordForm() {
123123
{form.formState.isLoading ? (
124124
<Progress size="xs" isIndeterminate />
125125
) : formOverlay ? (
126-
<FormStateOverlay
126+
<FormOverlay
127127
image={formOverlay.image}
128128
errorMessage={formOverlay.errorMessage}
129129
>
130130
{formOverlay.children}
131-
</FormStateOverlay>
131+
</FormOverlay>
132132
) : (
133133
<form className={classes.RecordForm}>
134134
<InstitutionsList
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {
2+
Button,
3+
Accordion,
4+
AccordionButton,
5+
AccordionItem,
6+
AccordionIcon,
7+
Box,
8+
AccordionPanel,
9+
Text,
10+
} from "@chakra-ui/react";
11+
12+
/**
13+
* Alert, appended to the top of RecordForm. Used for non-blocking warnings or information.
14+
* Can be expanded and explicitly closed until reload of the form.
15+
* @param {string} heading - heading text (always visible)
16+
* @param {string} message - collapsed text
17+
* @param {function} [onHide] - handler for hideWarning button
18+
* @returns
19+
*/
20+
export function FormAlert({ heading, message, onHide }) {
21+
return (
22+
<Box bg="yellow.900" m={2} borderRadius="md">
23+
<Accordion w="100%" allowToggle>
24+
<AccordionItem borderStyle="none">
25+
<AccordionButton>
26+
<Box as="span" flex="1" textAlign="left">
27+
{heading}
28+
</Box>
29+
<AccordionIcon />
30+
</AccordionButton>
31+
<AccordionPanel maxH="180px" overflow="auto" pb={4}>
32+
<Text>{message}</Text>
33+
{onHide && (
34+
<Button mt={2} variant="link" onClick={onHide}>
35+
Hide warning
36+
</Button>
37+
)}
38+
</AccordionPanel>
39+
</AccordionItem>
40+
</Accordion>
41+
</Box>
42+
);
43+
}

components/RecordForm/components/FormStateOverlay.jsx renamed to components/RecordForm/components/FormOverlay.jsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,15 @@ import {
1212
AccordionPanel,
1313
} from "@chakra-ui/react";
1414

15-
export function FormStateOverlay({ image, errorMessage, children }) {
16-
/**
17-
* Overlay to display errors or states in RecordForm
18-
*/
15+
/**
16+
* Overlays form body. Used for empty states and blocking errors.
17+
* Can contain hidden system error text.
18+
*
19+
* @param {string} [image] - The path to state illustartion
20+
* @param {string} [errorMessage] - System error message
21+
* @param children – overlay content
22+
*/
23+
export function FormOverlay({ image, errorMessage, children }) {
1924
return (
2025
<VStack justifyContent="space-between" h="100%">
2126
<Center flexGrow={1}>

0 commit comments

Comments
 (0)