Skip to content

Commit

Permalink
Merge pull request #11 from haryle/10-set-defaultvalue-for-select-com…
Browse files Browse the repository at this point in the history
…ponent-for-put-request

10 set defaultvalue for select component for put request
  • Loading branch information
harryle95 authored May 11, 2024
2 parents ef9e571 + e86e33e commit ad34419
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 61 deletions.
85 changes: 43 additions & 42 deletions src/components/form/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React from "react";
import { Form, FormProps, useFetcher, Link } from "react-router-dom";
import { styled } from "@ailiyah-ui/factory";
import { createBox } from "@ailiyah-ui/box";
import { capitalise, toSnakeCase } from "../helpers";
import { capitalise, removeId, toSnakeCase } from "../helpers";
import { InputProps } from "./form.types";
import { AddButton } from "@ailiyah-ui/button";
import { AbstractDataType } from "../../handlers";
Expand Down Expand Up @@ -62,8 +62,8 @@ const Input = styled("input");
*/
const Select = React.memo(
React.forwardRef<HTMLSelectElement, SelectProps>((props, ref) => {
let { url, name, ...rest } = props;
name = name + "Id";
let { name, ...rest } = props;
const url = removeId(name);
const fetcher = useFetcherData(url);
const data = fetcher.data
? (fetcher.data as unknown as Array<AbstractDataType> | null)
Expand All @@ -77,6 +77,7 @@ const Select = React.memo(
aria-label={`${name}-select`}
ref={ref}
>
<option value="" hidden label="Select from dropdown" />
{data &&
data.map((dataItem) => (
<option
Expand Down Expand Up @@ -107,47 +108,47 @@ const Select = React.memo(
* @params - name - name of input field
*/
const InputField = React.memo(
React.forwardRef<HTMLInputElement | HTMLSelectElement, InputProps>(
(props, ref) => {
let { id, name, required, hidden, type, ...rest } = props;
if (!id) id = React.useId();
React.forwardRef<
HTMLInputElement | HTMLSelectElement,
InputProps | SelectProps
>((props, ref) => {
let { id, name, required, hidden, type, ...rest } = props;
if (!id) id = React.useId();

// Process label name and input name
let labelName = capitalise(name);
let inputName = toSnakeCase(name);
if (required) labelName = labelName + "*";
// Process label name and input name
let labelName = removeId(capitalise(name));
if (required) labelName = labelName + "*";

return (
<LabelGroup themeName="FormLabelGroup">
<Label htmlFor={id} hidden={hidden} themeName="FormLabel">
{labelName}
</Label>
{type === "select" ? (
<Select
url={name}
hidden={hidden}
name={inputName}
id={id}
ref={ref as React.Ref<HTMLSelectElement>}
required={required}
themeName="FormSelect"
/>
) : (
<Input
type={type}
{...rest}
hidden={hidden}
name={inputName}
id={id}
ref={ref}
required={required}
themeName="FormInput"
/>
)}
</LabelGroup>
);
}
)
return (
<LabelGroup themeName="FormLabelGroup">
<Label htmlFor={id} hidden={hidden} themeName="FormLabel">
{hidden ? "" : labelName}
</Label>
{type === "select" ? (
<Select
{...(rest as SelectProps)}
hidden={hidden}
name={name}
id={id}
ref={ref as React.Ref<HTMLSelectElement>}
required={required}
themeName="FormSelect"
/>
) : (
<Input
{...(rest as InputProps)}
type={type}
hidden={hidden}
name={name}
id={id}
ref={ref}
required={required}
themeName="FormInput"
/>
)}
</LabelGroup>
);
})
);

const FormComponent = React.forwardRef<
Expand Down
24 changes: 16 additions & 8 deletions src/components/form/form.types.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import { TailwindComponentProps } from "@ailiyah-ui/factory";
import React from "react";

interface FormComponentOwnProp {
children: React.ReactNode;
}

interface InputProps
extends Omit<
TailwindComponentProps<"input">,
"name" | "hidden" | "required"
> {
interface InputSelectOwnProps {
type: React.HTMLInputTypeAttribute;
name: string;
required: boolean;
hidden: boolean;
}

interface SelectProps extends TailwindComponentProps<"select"> {
url: string;
}
interface InputProps
extends Omit<
TailwindComponentProps<"input">,
"name" | "hidden" | "required" | "type"
>,
InputSelectOwnProps {}

interface SelectProps
extends Omit<
TailwindComponentProps<"select">,
"name" | "hidden" | "required" | "children" | "type"
>,
InputSelectOwnProps {}

export type { FormComponentOwnProp, InputProps, SelectProps };
13 changes: 12 additions & 1 deletion src/components/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { capitalise, string2Date, toSnakeCase } from "./helpers";
import { capitalise, removeId, string2Date, toSnakeCase } from "./helpers";
import { describe, expect, test } from "vitest";

const capitaliseFixture = [
Expand Down Expand Up @@ -47,3 +47,14 @@ describe.each(string2DateFixture)("given %s", (inputValue, expValue) => {
}
});
});

const removeIdFixture = [
["investigation", "investigation"],
["investigationId", "investigation"],
];

describe.each(removeIdFixture)("given %s", (inputValue, expValue) => {
test(`removeId returns ${expValue}`, () => {
expect(removeId(inputValue)).toBe(expValue);
});
});
6 changes: 5 additions & 1 deletion src/components/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const capitalise = (text: string) => {
return processedText[0]!.toUpperCase() + processedText.slice(1);
};

const removeId = (text: string) => {
return text.endsWith("Id") ? text.substring(0, text.length - 2) : text;
};

const string2Date = (text?: string | null) => {
if (text) {
let parsedDate = new Date(text);
Expand All @@ -24,4 +28,4 @@ const string2Date = (text?: string | null) => {
return null;
};

export { capitalise, toSnakeCase, string2Date };
export { capitalise, toSnakeCase, string2Date, removeId };
9 changes: 2 additions & 7 deletions src/handlers/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const createHandlers = <T extends AbstractDataType>(
};

const createData = async (data: T): Promise<T> => {
console.log(data);
const response = await fetch(url, {
method: "POST",
headers: {
Expand Down Expand Up @@ -116,14 +117,8 @@ const createLoaderAction = <T extends AbstractDataType, Key extends string>(
acc[key] = value;
}
} else {
let subKey = key.substring(0, key.length - 2);
if (subKey in schema) {
acc[subKey] = value;
} else {
throw new Error("Key cannot be found in schema: " + key);
}
throw new Error("Key cannot be found in schema: " + key);
}

return acc;
}, {} as any) as T;
};
Expand Down
2 changes: 1 addition & 1 deletion src/routes/study/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"type": "text",
"placeholder": "Study objective"
},
"investigation": {
"investigationId": {
"required": true,
"type": "select"
}
Expand Down
2 changes: 1 addition & 1 deletion src/routes/study/study.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface StudyType extends AbstractDataType {
startDate: string | Date;
endDate: string | Date | null;
objective: string;
investigation: string;
investigationId: string;
}

type StudySchema = AbstractSchemaType<StudyType>;
Expand Down

0 comments on commit ad34419

Please sign in to comment.