Skip to content

Commit

Permalink
select field support added
Browse files Browse the repository at this point in the history
  • Loading branch information
indpurvesh committed Sep 26, 2024
1 parent 3636ff8 commit 23fdbe6
Show file tree
Hide file tree
Showing 13 changed files with 658 additions and 125 deletions.
7 changes: 5 additions & 2 deletions react-admin/src/components/AvoRedButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ type ButtonPropsType = {
isPending?: boolean;
label: string,
type?: ButtonType,
className?: string
className?: string,
onClick?: any
}

const AvoRedButton = (({
label,
isPending,
type = ButtonType.submit,
className = ""
className = "",
onClick
}: ButtonPropsType) => {
return (
<>
<button
onClick={onClick}
type={type}
className={`bg-gray-300 w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white focus:outline-none focus:ring-2 focus:ring-offset-2 ${className}`}
>
Expand Down
2 changes: 2 additions & 0 deletions react-admin/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@
"add_field": "Add page field",
"page_field_name": "Field name",
"page_field_identifier": "Field identifier",
"create_page_field": "Create page field",
"page_field_content": "Field content",
"text_field": "Text field",
"textarea_field": "Textarea field",
"select_field": "Select field",
"field_content": "Field content",
"identifier": "Identifier",
"created_at": "Created at",
Expand Down
319 changes: 264 additions & 55 deletions react-admin/src/pages/page/PageCreate.tsx

Large diffs are not rendered by default.

227 changes: 203 additions & 24 deletions react-admin/src/pages/page/PageEdit.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from "react";
import { Link, useParams } from "react-router-dom";
import { Cog8ToothIcon, PlusIcon, TrashIcon } from "@heroicons/react/24/solid";
import {Cog8ToothIcon, MinusIcon, PlusIcon, TrashIcon} from "@heroicons/react/24/solid";
import AvoredModal from "../../components/AvoredModal";
import InputField from "../../components/InputField";
import { useGetPage } from "./hooks/useGetPage";
Expand All @@ -17,10 +17,11 @@ import {
EditablePageType,
} from "../../types/page/EditablePageType";
import {
AvoRedPageDataTYpe,
AvoRedPageDataType,
AvoRedPageFieldType,
} from "../../types/page/IPageModel";
import _ from "lodash";
import {AvoRedPageFieldSelectFieldDataOptions, CreatableFieldType} from "../../types/page/CreatablePageType";

function PageEdit() {
const [isOpen, setIsOpen] = useState<boolean>(false);
Expand Down Expand Up @@ -88,40 +89,200 @@ function PageEdit() {
const onPageFieldChange = async (
index: number,
field_type: AvoRedPageFieldType,
data_type: AvoRedPageDataTYpe,
data_type: AvoRedPageDataType,
) => {
setValue(`page_fields.${index}.field_type`, field_type);
setValue(`page_fields.${index}.data_type`, data_type);
await trigger(`page_fields.${index}`);
};

const renderField = (field: EditableFieldType, index: number) => {
const optionAddOnClick = (async (e: React.MouseEvent<HTMLButtonElement>, field_index: number) => {
e.preventDefault()
const page_field: CreatableFieldType = getValues(`page_fields.${field_index}`);
const empty_option: AvoRedPageFieldSelectFieldDataOptions = {
label: '',
value: ''
};

page_field.field_data?.select_field_options.push(empty_option)

await trigger("page_fields")
})

const renderFieldData = (current_index: number) => {
const page_field: CreatableFieldType = getValues(
`page_fields.${current_index}`,
);

switch (page_field.field_type) {
case AvoRedPageFieldType.SELECT:
return (
<>
{page_field.field_data?.select_field_options.map((option, option_index) => {
return (
<div key={option_index} className="block mt-3 w-full">
<div className="flex w-full items-center">
<div className="w-1/2">
<div className="block">
<input
value={option.label}
onChange={(e) =>
optionLabelOnChange(
e,
current_index,
option_index,
)
}
placeholder={t("label")}
className="appearance-none rounded-md ring-1 ring-gray-400
relative border-0 block w-full px-3 py-2 placeholder-gray-500 text-gray-900
active::ring-primary-500
focus:ring-primary-500 focus:outline-none focus:z-10
disabled:bg-gray-200 disabled:opacity-70
sm:text-sm "
/>
</div>
</div>
<div className="w-1/2 ml-3">
<div className="flex items-center w-full">
<div>
<input
value={option.value}
onChange={(e) =>
optionValueOnChange(
e,
current_index,
option_index,
)
}
placeholder={t("value")}
className="appearance-none rounded-md ring-1 ring-gray-400
relative border-0 block w-full px-3 py-2 placeholder-gray-500 text-gray-900
active::ring-primary-500
focus:ring-primary-500 focus:outline-none focus:z-10
disabled:bg-gray-200 disabled:opacity-70
sm:text-sm "
/>
</div>
<div>
{getValues(
`page_fields.${current_index}.field_data.select_field_options`,
).length ===
option_index + 1 ? (
<>
<button
onClick={(e) =>
optionAddOnClick(e, currentIndex)
}
className="ml-2"
>
<PlusIcon className="w-5 h-5" />
</button>
</>
) : (
<>
<button
onClick={(e) =>
optionRemoveOnClick(
e,
currentIndex,
option_index,
)
}
className="ml-2"
>
<MinusIcon className="w-5 h-5" />
</button>
</>
)}
</div>
</div>
</div>
</div>
</div>
);
})}
</>
)
default:
return (
<></>
)
}
};

const optionRemoveOnClick = (async (e: React.MouseEvent<HTMLButtonElement>, field_index: number, option_index: number) => {
e.preventDefault()
const page_field: CreatableFieldType = getValues(`page_fields.${field_index}`);
page_field.field_data?.select_field_options.splice(option_index, 1);

await trigger(`page_fields.${field_index}`)
})

const optionLabelOnChange = (async (e: any, field_index: number, option_index: number) => {
setValue(`page_fields.${field_index}.field_data.select_field_options.${option_index}.label`, e.target.value)
await trigger("page_fields")
})

const optionValueOnChange = (async (e: any, field_index: number, option_index: number) => {
setValue(`page_fields.${field_index}.field_data.select_field_options.${option_index}.value`, e.target.value)
await trigger("page_fields")
})

const renderField = (field: CreatableFieldType, index: number) => {
switch (field.field_type) {
case "TEXT":
case AvoRedPageFieldType.TEXTAREA:
return (
<div className="mb-4">
<InputField
label={t("field_content")}
placeholder={t("field_content")}
register={register(`page_fields.${index}.field_content`)}
/>
</div>
<div className="mb-4">
<label className="text-sm text-gray-600">
{t!("field_content")}
</label>
<textarea
className="w-full rounded"
{...register(`page_fields.${index}.field_content`)}
></textarea>
</div>
);
case AvoRedPageFieldType.SELECT:
return (
<div className="mb-4">
<label className="text-sm text-gray-600">
{t!("field_content")}
</label>

<select {...register(`page_fields.${index}.field_content`)}
className="w-full rounded border-0 ring-1 ring-primary-400 outline-none appearance-none">
{field.field_data?.select_field_options.map((option) => {
return <option key={option.value} value={option.value}>{option.label}</option>;
})}

</select>
</div>
);
case AvoRedPageFieldType.TEXT:
return (
<div className="mb-4">
<InputField
label={t("field_content")}
placeholder={t("field_content")}
register={register(`page_fields.${index}.field_content`)}
/>
</div>
);
default:
return (
<div className="mb-4">
<label className="text-sm text-gray-600">
{t!("field_content")}
</label>
<textarea
className="w-full rounded"
{...register(`page_fields.${index}.field_content`)}
></textarea>
</div>
<div className="mb-4">
<InputField
label={t("field_content")}
placeholder={t("field_content")}
register={register(`page_fields.${index}.field_content`)}
/>
</div>
);
}
};


const addFieldOnClick = async (
e: React.MouseEvent<HTMLElement>,
max_index: number,
Expand All @@ -131,7 +292,7 @@ function PageEdit() {
append({
name: "",
identifier: "",
data_type: AvoRedPageDataTYpe.TEXT,
data_type: AvoRedPageDataType.TEXT,
field_type: AvoRedPageFieldType.TEXT,
field_content: "",
});
Expand Down Expand Up @@ -182,6 +343,11 @@ function PageEdit() {
)}
/>
</div>

<div className="w-full">
{renderFieldData(currentIndex)}
</div>

</div>
<div className="ml-auto">
<div className="w-64 border-l p-3 mr-auto">
Expand All @@ -190,7 +356,7 @@ function PageEdit() {
onPageFieldChange(
currentIndex,
AvoRedPageFieldType.TEXT,
AvoRedPageDataTYpe.TEXT,
AvoRedPageDataType.TEXT,
)
}
className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.TEXT ? "bg-primary-200" : "bg-gray-300"}
Expand All @@ -203,14 +369,27 @@ function PageEdit() {
onPageFieldChange(
currentIndex,
AvoRedPageFieldType.TEXTAREA,
AvoRedPageDataTYpe.TEXT,
AvoRedPageDataType.TEXT,
)
}
className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.TEXTAREA ? "bg-primary-200" : "bg-gray-300"}
ring-1 mt-2 ring-gray-300 hover:cursor-pointer hover:ring-primary-300 p-3 rounded`}
>
{t("textarea_field")}
</div>
<div
onClick={() =>
onPageFieldChange(
currentIndex,
AvoRedPageFieldType.SELECT,
AvoRedPageDataType.TEXT,
)
}
className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.SELECT ? "bg-primary-200" : "bg-gray-300"}
ring-1 mt-2 ring-gray-300 hover:cursor-pointer hover:ring-primary-300 p-3 rounded`}
>
{t("select_field")}
</div>
</div>
</div>
</div>
Expand Down
13 changes: 11 additions & 2 deletions react-admin/src/types/page/CreatablePageType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {AvoRedPageDataTYpe, AvoRedPageFieldType} from "./IPageModel";
import {AvoRedPageDataType, AvoRedPageFieldType} from "./IPageModel";

export type CreatablePageType = {
name: string;
Expand All @@ -9,8 +9,17 @@ export type CreatablePageType = {
export type CreatableFieldType = {
name: string;
identifier: string;
data_type: AvoRedPageDataTYpe;
data_type: AvoRedPageDataType;
field_type: AvoRedPageFieldType;
field_content: string | number;
field_data?: AvoRedPageFieldData
}

export type AvoRedPageFieldData = {
select_field_options: Array<AvoRedPageFieldSelectFieldDataOptions>
}

export type AvoRedPageFieldSelectFieldDataOptions = {
label: string;
value: string;
}
8 changes: 5 additions & 3 deletions react-admin/src/types/page/EditablePageType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {PageDataType, PageFieldType} from "./IPageModel";
import {AvoRedPageFieldData} from "./CreatablePageType";
import {AvoRedPageDataType, AvoRedPageFieldType} from "./IPageModel";


export type EditablePageType = {
Expand All @@ -11,8 +12,9 @@ export type EditablePageType = {
export type EditableFieldType = {
name: string;
identifier: string;
data_type: PageDataType;
field_type: PageFieldType;
data_type: AvoRedPageDataType;
field_type: AvoRedPageFieldType;
field_content: string | number;
field_data?: AvoRedPageFieldData
}

7 changes: 4 additions & 3 deletions react-admin/src/types/page/IPageModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ export default interface IPageModel {
}


export enum AvoRedPageDataTYpe {
export enum AvoRedPageDataType {
TEXT = "TEXT",
INT = "INT"
}


export enum AvoRedPageFieldType {
TEXT = "TEXT",
TEXTAREA = "TEXTAREA"
TEXT = "Text",
TEXTAREA = "Textarea",
SELECT = "Select"
}
Loading

0 comments on commit 23fdbe6

Please sign in to comment.