From b759c67c1424829ff3550f7af289064deb11499c Mon Sep 17 00:00:00 2001 From: Purvesh Date: Sun, 30 Jun 2024 12:48:35 +1200 Subject: [PATCH] support for dropdown in progress --- react-admin/package-lock.json | 16 ++ react-admin/package.json | 1 + .../src/components/AvoRedMultiSelectField.tsx | 2 +- react-admin/src/locales/en.json | 1 + .../src/pages/admin-user/AdminUserEdit.tsx | 2 +- react-admin/src/pages/page/PageCreate.tsx | 167 +++++++++---- react-admin/src/pages/page/PageEdit.tsx | 153 ++++++++---- react-admin/src/pages/page/PageTable.tsx | 227 +++++++++--------- react-admin/src/types/page/ICreatablePage.ts | 1 + react-admin/src/types/page/IEditablePage.ts | 1 + 10 files changed, 376 insertions(+), 195 deletions(-) diff --git a/react-admin/package-lock.json b/react-admin/package-lock.json index 82cc1e40..3666d914 100644 --- a/react-admin/package-lock.json +++ b/react-admin/package-lock.json @@ -43,6 +43,7 @@ "@types/swagger-ui-react": "^4.18.3", "autoprefixer": "^10.4.19", "postcss": "^8.4.38", + "prettier": "^3.3.2", "tailwindcss": "^3.4.3", "typescript": "^4.9.5" } @@ -17527,6 +17528,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", diff --git a/react-admin/package.json b/react-admin/package.json index 5b34aea7..862c7d3e 100644 --- a/react-admin/package.json +++ b/react-admin/package.json @@ -63,6 +63,7 @@ "@types/swagger-ui-react": "^4.18.3", "autoprefixer": "^10.4.19", "postcss": "^8.4.38", + "prettier": "^3.3.2", "tailwindcss": "^3.4.3", "typescript": "^4.9.5" } diff --git a/react-admin/src/components/AvoRedMultiSelectField.tsx b/react-admin/src/components/AvoRedMultiSelectField.tsx index 59aa6b65..7f86d161 100644 --- a/react-admin/src/components/AvoRedMultiSelectField.tsx +++ b/react-admin/src/components/AvoRedMultiSelectField.tsx @@ -30,7 +30,7 @@ const AvoRedMultiSelectField = ({ className="w-full cursor-default h-8 rounded py-2 pl-3 pr-10 text-left text-sm shadow ring-1 ring-gray-400 focus:ring-primary-500 active:ring-primary-500 focus:outline-none" > - {selectedOption.map((optionId: any) => getOption(optionId).label ?? '').join(", ")} + {selectedOption.map((optionId: string) => getOption(optionId)?.label ?? '').join(", ")}
({ - resolver: joiResolver(usePageCreateSchema(), {allowUnknown: true}), + resolver: joiResolver(usePageCreateSchema(), { allowUnknown: true }), }); - const { - fields: components_content, - append - } = useFieldArray({ + const { fields: components_content, append } = useFieldArray({ control, name: "components_content", //rename fields }); + const setSelectedFieldDataOption = ((selected: Array, pageComponentIndex: number, componentFieldIndex: number) => { + let val = selected.pop() ?? '' + setValue(`components_content.${pageComponentIndex}.fields.${componentFieldIndex}.field_content`, val) + }) + + const getSelectFieldDataOptionCurrentValue = ((pageComponentIndex: number, componentFieldIndex: number) => { + + let val = getValues(`components_content.${pageComponentIndex}.fields.${componentFieldIndex}.field_content`) + if (val) { + return [val] + } + return [] + }) + const component_all_api_response = useComponentAll(); const components = _.get(component_all_api_response, "data.data", []); + const { mutate, error } = useStorePage(); - const {mutate} = useStorePage(); - - const renderComponentFieldType = (componentField: ICreatablePageComponentFieldModel, pageComponentIndex: number, componentFieldIndex: number) => { + const renderComponentFieldType = ( + componentField: ICreatablePageComponentFieldModel, + pageComponentIndex: number, + componentFieldIndex: number, + ) => { switch (componentField.field_type) { case "textarea": - return
{t("textarea")}
; + return ( +
+ + +
+ ); + case "select": + return ( +
+ ) => setSelectedFieldDataOption(val, pageComponentIndex, componentFieldIndex))} + > + +
+ ); case "radio": return (
- -
@@ -68,17 +121,28 @@ function PageCreate() {
); } }; - const renderComponentField = (componentField: ICreatablePageComponentFieldModel, pageComponentIndex: number, componentFieldIndex: number) => { + const renderComponentField = ( + componentField: ICreatablePageComponentFieldModel, + pageComponentIndex: number, + componentFieldIndex: number, + ) => { return (
- {renderComponentFieldType(componentField, pageComponentIndex, componentFieldIndex)} + {JSON.stringify(componentField)} + {renderComponentFieldType( + componentField, + pageComponentIndex, + componentFieldIndex, + )}
); }; @@ -86,11 +150,11 @@ function PageCreate() { const componentSelected = (e: React.MouseEvent, componentId: string) => { e.preventDefault(); const selectedComponent = components.find( - (component: IComponentModel) => component.id === componentId + (component: IComponentModel) => component.id === componentId, ); setIsComponentTableModalOpen(false); - append(selectedComponent) + append(selectedComponent); }; const addComponentOnClick = () => { @@ -101,7 +165,10 @@ function PageCreate() { setIsComponentTableModalOpen(false); }; - const renderComponent = (pageComponent: ICreatablePageComponentModel, pageComponentIndex: number) => { + const renderComponent = ( + pageComponent: ICreatablePageComponentModel, + pageComponentIndex: number, + ) => { return (
Component Fields {pageComponent.fields.map((componentField, componentFieldIndex) => { - return renderComponentField(componentField, pageComponentIndex, componentFieldIndex); + return renderComponentField( + componentField, + pageComponentIndex, + componentFieldIndex, + ); })}
@@ -129,10 +200,9 @@ function PageCreate() {

- {t("pages.information")} + {t("page_information")}

- {/*

Use a permanent address where you can*/} - {/* receive mail.

*/} +
+
+
@@ -161,10 +241,10 @@ function PageCreate() { className="flex" onClick={addComponentOnClick} > - + - {t("add_component")} - + {t("add_component")} +
@@ -173,7 +253,10 @@ function PageCreate() { modal_header={t("select_component")} modal_body={
- +
} isOpen={isComponentTableModalOpen} diff --git a/react-admin/src/pages/page/PageEdit.tsx b/react-admin/src/pages/page/PageEdit.tsx index eb706c82..fc7d45ea 100644 --- a/react-admin/src/pages/page/PageEdit.tsx +++ b/react-admin/src/pages/page/PageEdit.tsx @@ -1,22 +1,23 @@ -import React, {useState} from "react"; -import {Link, useParams} from "react-router-dom"; -import {PlusIcon} from "@heroicons/react/24/solid"; +import React, { useState } from "react"; +import { Link, useParams } from "react-router-dom"; +import { PlusIcon } from "@heroicons/react/24/solid"; import AvoredModal from "../../components/AvoredModal"; import InputField from "../../components/InputField"; import _ from "lodash"; -import {useComponentAll} from "./hooks/useComponentAll"; -import {useGetPage} from "./hooks/useGetPage"; -import {useUpdatePage} from "./hooks/useUpdatePage"; -import {useTranslation} from "react-i18next"; -import {useFieldArray, useForm} from "react-hook-form"; -import {joiResolver} from "@hookform/resolvers/joi"; +import { useComponentAll } from "./hooks/useComponentAll"; +import { useGetPage } from "./hooks/useGetPage"; +import { useUpdatePage } from "./hooks/useUpdatePage"; +import { useTranslation } from "react-i18next"; +import { useFieldArray, useForm } from "react-hook-form"; +import { joiResolver } from "@hookform/resolvers/joi"; import PageComponentTable from "./PageComponentTable"; import IEditablePage, { IEditablePageComponentFieldModel, - IEditablePageComponentModel + IEditablePageComponentModel, } from "../../types/page/IEditablePage"; -import {usePageEditSchema} from "./schemas/page.edit.schema"; +import { usePageEditSchema } from "./schemas/page.edit.schema"; +import AvoRedMultiSelectField from "../../components/AvoRedMultiSelectField"; function PageEdit() { const [isComponentTableModalOpen, setIsComponentTableModalOpen] = @@ -27,34 +28,82 @@ function PageEdit() { const component_all_api_response = useComponentAll(); const components = _.get(component_all_api_response, "data.data", []); - const {mutate} = useUpdatePage(params.page_id ?? ''); - - const {data} = useGetPage(params.page_id ?? ''); - const values = data?.data.page_model + const { mutate } = useUpdatePage(params.page_id ?? ""); + const { data } = useGetPage(params.page_id ?? ""); + const values = data?.data.page_model; const { control, register, handleSubmit, - formState: {errors} + formState: { errors }, + getValues, + setValue } = useForm({ - resolver: joiResolver(usePageEditSchema(), {allowUnknown: true}), - values + resolver: joiResolver(usePageEditSchema(), { allowUnknown: true }), + values, }); - const { - fields: components_content, - append - } = useFieldArray({ + const { fields: components_content, append } = useFieldArray({ control, name: "components_content", }); - const renderComponentFieldType = (componentField: IEditablePageComponentFieldModel, pageComponentIndex: number, pageComponentFieldIndex: number) => { + const setSelectedFieldDataOption = ((selected: Array, pageComponentIndex: number, componentFieldIndex: number) => { + let val = selected.pop() ?? '' + setValue(`components_content.${pageComponentIndex}.fields.${componentFieldIndex}.field_content`, val) + }) + + const getSelectFieldDataOptionCurrentValue = ((pageComponentIndex: number, componentFieldIndex: number) => { + + let val = getValues(`components_content.${pageComponentIndex}.fields.${componentFieldIndex}.field_content`) + console.log(val) + if (val) { + return [val] + } + return [] + }) + + const renderComponentFieldType = ( + componentField: IEditablePageComponentFieldModel, + pageComponentIndex: number, + pageComponentFieldIndex: number, + ) => { switch (componentField.field_type) { case "textarea": - return
Textarea
; + return ( +
+ + +
+ ); + case "select": + return ( +
+ ) => setSelectedFieldDataOption(val, pageComponentIndex, pageComponentFieldIndex))} + > + +
+ ); case "text": default: return ( @@ -63,17 +112,29 @@ function PageEdit() { label={componentField.name} type="text" name={componentField.identifier} - register={register(`components_content.${pageComponentIndex}.fields.${pageComponentFieldIndex}.field_content`)} + register={register( + `components_content.${pageComponentIndex}.fields.${pageComponentFieldIndex}.field_content`, + )} />
); } }; - const renderComponentField = (componentField: IEditablePageComponentFieldModel, pageComponentIndex: number, pageComponentFieldIndex: number) => { + const renderComponentField = ( + componentField: IEditablePageComponentFieldModel, + pageComponentIndex: number, + pageComponentFieldIndex: number, + ) => { return ( +
- {renderComponentFieldType(componentField, pageComponentIndex, pageComponentFieldIndex)} + {JSON.stringify(componentField)} + {renderComponentFieldType( + componentField, + pageComponentIndex, + pageComponentFieldIndex, + )}
); }; @@ -81,12 +142,11 @@ function PageEdit() { const componentSelected = (e: React.MouseEvent, componentId: string) => { e.preventDefault(); const selectedComponent = components.find( - (component: IEditablePageComponentModel) => component.id === componentId + (component: IEditablePageComponentModel) => component.id === componentId, ); setIsComponentTableModalOpen(false); - append(selectedComponent) - + append(selectedComponent); }; const addComponentOnClick = () => { @@ -97,20 +157,27 @@ function PageEdit() { setIsComponentTableModalOpen(false); }; - - const renderComponent = (pageComponent: IEditablePageComponentModel, pageComponentIndex: number) => { + const renderComponent = ( + pageComponent: IEditablePageComponentModel, + pageComponentIndex: number, + ) => { return (
+
component name: {pageComponent.name}
component identifier: {pageComponent.identifier}
Component Fields - {components_content.map((componentField, pageComponentFieldIndex) => { + {pageComponent.fields.map((componentField, pageComponentFieldIndex) => { // @ts-ignore - return renderComponentField(componentField, pageComponentIndex, pageComponentFieldIndex); + return renderComponentField( + componentField, + pageComponentIndex, + pageComponentFieldIndex, + ); })}
@@ -118,7 +185,7 @@ function PageEdit() { }; const submitHandler = async (data: IEditablePage) => { - mutate(data) + mutate(data); }; return ( @@ -137,14 +204,14 @@ function PageEdit() { placeholder={t("name")} label={t("name")} name="name" - register={register('name')} + register={register("name")} />
@@ -160,10 +227,10 @@ function PageEdit() { className="flex" onClick={addComponentOnClick} > - + - {t("add_component")} - + {t("add_component")} +
@@ -172,8 +239,10 @@ function PageEdit() { modal_header={t("select_component")} modal_body={
- +
} isOpen={isComponentTableModalOpen} diff --git a/react-admin/src/pages/page/PageTable.tsx b/react-admin/src/pages/page/PageTable.tsx index db98f061..2bcc8eab 100644 --- a/react-admin/src/pages/page/PageTable.tsx +++ b/react-admin/src/pages/page/PageTable.tsx @@ -1,123 +1,132 @@ -import { Link } from "react-router-dom" -import _ from 'lodash' -import { usePageTable } from "./hooks/usePageTable" -import { useTranslation } from "react-i18next" -import {createColumnHelper, getCoreRowModel, SortingState, useReactTable} from "@tanstack/react-table"; +import { Link } from "react-router-dom"; +import _ from "lodash"; +import { usePageTable } from "./hooks/usePageTable"; +import { useTranslation } from "react-i18next"; +import { + createColumnHelper, + getCoreRowModel, + SortingState, + useReactTable, +} from "@tanstack/react-table"; import { getFormattedDate } from "../../lib/common"; import IPageModel from "../../types/page/IPageModel"; import AvoRedTable from "../../components/AvoRedTable"; import HasPermission from "../../components/HasPermission"; -import {useQueryClient} from "@tanstack/react-query"; -import {useState} from "react"; +import { useQueryClient } from "@tanstack/react-query"; +import { useState } from "react"; function PageTable() { - const queryClient = useQueryClient() - const [sorting, setSorting] = useState([]); - const [t] = useTranslation("global") - const page_api_table_response = usePageTable({ - order: sorting.map((s) => `${s.id}:${s.desc ? 'DESC' : 'ASC'}`).join(','), - }); - const pages: Array = _.get(page_api_table_response, 'data.data.data', []) + const queryClient = useQueryClient(); + const [sorting, setSorting] = useState([]); + const [t] = useTranslation("global"); + const page_api_table_response = usePageTable({ + order: sorting.map((s) => `${s.id}:${s.desc ? "DESC" : "ASC"}`).join(","), + }); + const pages: Array = _.get( + page_api_table_response, + "data.data.data", + [], + ); - const customSorting = ((sorting: any) => { - queryClient.invalidateQueries( {queryKey: ['page-table']}); - setSorting(sorting) - }) + const customSorting = (sorting: any) => { + queryClient.invalidateQueries({ queryKey: ["page-table"] }); + setSorting(sorting); + }; - const columnHelper = createColumnHelper() - const columns = [ - columnHelper.accessor('id', { - cell: info => info.getValue(), - header: t("id") - }), - columnHelper.accessor('name', { - cell: info => info.getValue(), - header: t("name") - }), - columnHelper.accessor('identifier', { - cell: info => info.getValue(), - header: t("identifier") - }), - columnHelper.accessor('created_at', { - id: "created_at", - cell: info => getFormattedDate(info.getValue()), - header: t("created_at") - }), - columnHelper.accessor('created_by', { - cell: info => info.getValue(), - header: t("created_by") - }), - columnHelper.accessor('updated_at', { - cell: info => getFormattedDate(info.getValue()), - header: t("updated_at") - }), - columnHelper.accessor('updated_by', { - cell: info => info.getValue(), - header: t("updated_by") - }), - columnHelper.accessor('action', { - cell: info => { - return ( - - - {t("edit")} - - - ) - }, - enableSorting: false, - header: t("action"), - enableHiding: false - }), - ] + const columnHelper = createColumnHelper(); + const columns = [ + columnHelper.accessor("id", { + cell: (info) => info.getValue(), + header: t("id"), + }), + columnHelper.accessor("name", { + cell: (info) => info.getValue(), + header: t("name"), + }), + columnHelper.accessor("identifier", { + cell: (info) => info.getValue(), + header: t("identifier"), + }), + columnHelper.accessor("created_at", { + id: "created_at", + cell: (info) => getFormattedDate(info.getValue()), + header: t("created_at"), + }), + columnHelper.accessor("created_by", { + cell: (info) => info.getValue(), + header: t("created_by"), + }), + columnHelper.accessor("updated_at", { + cell: (info) => getFormattedDate(info.getValue()), + header: t("updated_at"), + }), + columnHelper.accessor("updated_by", { + cell: (info) => info.getValue(), + header: t("updated_by"), + }), + columnHelper.accessor("action", { + cell: (info) => { + return ( + + + {t("edit")} + + + ); + }, + enableSorting: false, + header: t("action"), + enableHiding: false, + }), + ]; - const table = useReactTable({ - data: pages, - columns, - getCoreRowModel: getCoreRowModel(), - initialState: { - columnVisibility: { - created_at: false, - created_by: false - } - }, - manualSorting: true, - onSortingChange: customSorting, - state: { - sorting - }, - }) + const table = useReactTable({ + data: pages, + columns, + getCoreRowModel: getCoreRowModel(), + initialState: { + columnVisibility: { + created_at: false, + created_by: false, + }, + }, + manualSorting: true, + onSortingChange: customSorting, + state: { + sorting, + }, + }); - return ( -
-
-
-
- {t("pages")} -
-
- - - {t("create")} - - -
-
+ return ( +
+
+
+
+ {t("page")} +
+
+ + + {t("create")} + + +
+
-
- - - -
-
+
+ + +
- ); +
+
+ ); } -export default PageTable +export default PageTable; diff --git a/react-admin/src/types/page/ICreatablePage.ts b/react-admin/src/types/page/ICreatablePage.ts index a9843496..8afefabc 100644 --- a/react-admin/src/types/page/ICreatablePage.ts +++ b/react-admin/src/types/page/ICreatablePage.ts @@ -24,6 +24,7 @@ export interface ICreatablePageComponentFieldModel { identifier: string; field_type: string; field_content: string; + field_data?: Array; created_at: string; updated_at: string; created_by: string; diff --git a/react-admin/src/types/page/IEditablePage.ts b/react-admin/src/types/page/IEditablePage.ts index b1e8920a..99846028 100644 --- a/react-admin/src/types/page/IEditablePage.ts +++ b/react-admin/src/types/page/IEditablePage.ts @@ -25,6 +25,7 @@ export interface IEditablePageComponentFieldModel { identifier: string; field_type: string; field_content: string; + field_data?: Array; created_at: string; updated_at: string; created_by: string;