From 2cd5578ada2b4d1651753cd9670251179646eb37 Mon Sep 17 00:00:00 2001 From: Purvesh Date: Sat, 23 Nov 2024 12:49:17 +1300 Subject: [PATCH] single field support added --- react-admin/src/locales/en.json | 2 + react-admin/src/pages/page/PageCreate.tsx | 59 ++++ react-admin/src/pages/page/PageEdit.tsx | 319 ++++++++++-------- react-admin/src/pages/page/PageFieldModal.tsx | 270 ++++++++------- .../src/pages/page/SingleImageModal.tsx | 148 ++++++++ react-admin/src/types/page/IPageModel.ts | 3 +- .../misc/install_demo_data_api_handler.rs | 4 +- 7 files changed, 541 insertions(+), 264 deletions(-) create mode 100644 react-admin/src/pages/page/SingleImageModal.tsx diff --git a/react-admin/src/locales/en.json b/react-admin/src/locales/en.json index 93b3a6fd..219daad9 100644 --- a/react-admin/src/locales/en.json +++ b/react-admin/src/locales/en.json @@ -55,6 +55,7 @@ "text_editor_field": "Text editor field", "radio_field": "Radio field", "checkbox_field": "Checkbox field", + "single_image_field": "Single image field", "field_content": "Field content", "identifier": "Identifier", "created_at": "Created at", @@ -107,6 +108,7 @@ "get_setting": "Get Settings", "cms_frontend_auth_token": "CMS Api bearer auth token", "save_setting": "Save Setting", + "select_asset": "Select asset", "generate_token": "Generate token", "site_name": "Site Name", "settings": "Settings", diff --git a/react-admin/src/pages/page/PageCreate.tsx b/react-admin/src/pages/page/PageCreate.tsx index d4a867a9..7b0a2d96 100644 --- a/react-admin/src/pages/page/PageCreate.tsx +++ b/react-admin/src/pages/page/PageCreate.tsx @@ -23,11 +23,16 @@ import { import _ from "lodash"; import SimpleMdeReact from "react-simplemde-editor"; import { PageFieldModal } from "./PageFieldModal"; +import {SingleImageModal} from "./SingleImageModal"; +import IAssetModel from "../../types/asset/IAssetModel"; +import AvoRedButton, {ButtonType} from "../../components/AvoRedButton"; function PageCreate() { const [t] = useTranslation("global"); const [isOpen, setIsOpen] = useState(false); const [currentIndex, setCurrentIndex] = useState(0); + const backend_url = import.meta.env.VITE_AVORED_BACKEND_BASE_URL; + const [isSingleAssetModalOpen, setisSingleAssetModalOpen] = useState(false); const { control, @@ -222,6 +227,43 @@ function PageCreate() { /> ); + case AvoRedPageFieldType.SingleImage: + return ( +
+ +
+
+ + {`${getValues(`page_fields.${index}.name`)}`} +
+ selectedAsset(index ,asset)} + /> + +
+ +
+
+
+ ); default: return (
@@ -235,6 +277,23 @@ function PageCreate() { } }; + const selectedAsset = (index: number, selectedAsset: IAssetModel) => { + setValue(`page_fields.${index}.field_content.text_value.text_value`, selectedAsset.path); + closeSingleAssetModal(); + } + const singleImageButtonOnClick = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + openSingleAssetModal() + console.log("test") + } + const openSingleAssetModal = () => { + setisSingleAssetModalOpen(true); + }; + + const closeSingleAssetModal = () => { + setisSingleAssetModalOpen(false); + }; const saveAsPublishedOnClick = ((e: React.MouseEvent) => { e.preventDefault() e.stopPropagation() diff --git a/react-admin/src/pages/page/PageEdit.tsx b/react-admin/src/pages/page/PageEdit.tsx index 41f63b18..bae475a9 100644 --- a/react-admin/src/pages/page/PageEdit.tsx +++ b/react-admin/src/pages/page/PageEdit.tsx @@ -13,7 +13,8 @@ import { PutPageIdentifierType } from "../../types/page/PutPageIdentifierType"; import { usePutPageIdentifier } from "./hooks/usePutPageIdentifier"; import { AvoRedPageDataType, - AvoRedPageFieldType, AvoRedPageStatus, + AvoRedPageFieldType, + AvoRedPageStatus, } from "../../types/page/IPageModel"; import _ from "lodash"; import { @@ -26,11 +27,15 @@ import { } from "../../types/page/CreatablePageType"; import SimpleMdeReact from "react-simplemde-editor"; import { PageFieldModal } from "./PageFieldModal"; +import AvoRedButton, { ButtonType } from "../../components/AvoRedButton"; +import {SingleImageModal} from "./SingleImageModal"; +import IAssetModel from "../../types/asset/IAssetModel"; function PageEdit() { const [isOpen, setIsOpen] = useState(false); + const [isSingleAssetModalOpen, setisSingleAssetModalOpen] = useState(false); const [currentIndex, setCurrentIndex] = useState(0); - + const backend_url = import.meta.env.VITE_AVORED_BACKEND_BASE_URL; const params = useParams(); const [t] = useTranslation("global"); const [isEditableIdentifier, setIsEditableIdentifier] = @@ -245,6 +250,43 @@ function PageEdit() { )}
); + case AvoRedPageFieldType.SingleImage: + return ( +
+ +
+
+ + {`${getValues(`page_fields.${index}.name`)}`} +
+ selectedAsset(index ,asset)} + /> + +
+ +
+
+
+ ); default: return (
@@ -284,23 +326,41 @@ function PageEdit() { setIsOpen(true); }; + const selectedAsset = (index: number, selectedAsset: IAssetModel) => { + setValue(`page_fields.${index}.field_content.text_value.text_value`, selectedAsset.path); + closeSingleAssetModal(); + } + const singleImageButtonOnClick = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + openSingleAssetModal() + console.log("test") + } + const openSingleAssetModal = () => { + setisSingleAssetModalOpen(true); + }; + + const closeSingleAssetModal = () => { + setisSingleAssetModalOpen(false); + }; + const submitHandler = async (data: SavePageType) => { - data.status = AvoRedPageStatus.Draft + data.status = AvoRedPageStatus.Draft; mutate(data); }; - const saveAsPublishedOnClick = ((e: React.MouseEvent) => { - e.preventDefault() - e.stopPropagation() + const saveAsPublishedOnClick = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); const data: SavePageType = { name: getValues("name"), identifier: getValues("identifier"), page_fields: getValues("page_fields"), - status: AvoRedPageStatus.Published + status: AvoRedPageStatus.Published, }; - mutate(data) - }) + mutate(data); + }; return (
@@ -315,182 +375,177 @@ function PageEdit() {
{_.size(fields) > 0 ? ( - <> - - + <> + + ) : ( - <> + <> )} -
{isEditableIdentifier ? ( - <> - - {t("edit_identifier")} - - + <> + + {t("edit_identifier")} + + ) : ( - <> - - - + <> + + + )}
{fields.map((field, index) => { return ( -
- { - return ( - <> -
-
-
-
-
- {page_field.value.name} - - ({page_field.value.identifier}) - -
-
-
- -
-
- deletePageFieldOnClick(e, index) - } - className="ml-3" - > - -
-
-
- - - - {renderField(page_field.value, index)} +
+ { + return ( + <> +
+
+
+
+
+ {page_field.value.name} + + ({page_field.value.identifier}) + +
+
+
+ +
+
+ deletePageFieldOnClick(e, index) + } + className="ml-3" + > +
- - ); - }} - control={control} - /> -
+ + + + {renderField(page_field.value, index)} +
+
+
+ + ); + }} + control={control} + /> +
); })}
- -
{t("cancel")}
- -
diff --git a/react-admin/src/pages/page/PageFieldModal.tsx b/react-admin/src/pages/page/PageFieldModal.tsx index 797808dd..8f6194b7 100644 --- a/react-admin/src/pages/page/PageFieldModal.tsx +++ b/react-admin/src/pages/page/PageFieldModal.tsx @@ -573,140 +573,152 @@ export const PageFieldModal = (({ return ( setIsOpen(false)} - modal_body={ -
-
-
-
- -
-
- -
- -
- {renderFieldData(currentIndex)} -
-
-
-
-
- onPageFieldChange( - currentIndex, - AvoRedPageFieldType.TEXT, - AvoRedPageDataType.TEXT, - ) - } - className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.TEXT ? "bg-primary-200" : "bg-gray-300"} + closeModal={() => setIsOpen(false)} + modal_body={ +
+
+
+
+ +
+
+ +
+ +
{renderFieldData(currentIndex)}
+
+
+
+
+ onPageFieldChange( + currentIndex, + AvoRedPageFieldType.TEXT, + AvoRedPageDataType.TEXT, + ) + } + className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.TEXT ? "bg-primary-200" : "bg-gray-300"} ring-1 ring-gray-300 hover:cursor-pointer hover:ring-primary-300 p-3 rounded`} - > - {t("text_field")} -
-
- onPageFieldChange( - currentIndex, - AvoRedPageFieldType.TEXTAREA, - AvoRedPageDataType.TEXT, - ) - } - className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.TEXTAREA ? "bg-primary-200" : "bg-gray-300"} + > + {t("text_field")} +
+
+ onPageFieldChange( + currentIndex, + AvoRedPageFieldType.TEXTAREA, + 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")} -
-
- onPageFieldChange( - currentIndex, - AvoRedPageFieldType.SELECT, - AvoRedPageDataType.TEXT, - ) - } - className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.SELECT ? "bg-primary-200" : "bg-gray-300"} + > + {t("textarea_field")} +
+
+ 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")} -
- -
- onPageFieldChange( - currentIndex, - AvoRedPageFieldType.TextEditor, - AvoRedPageDataType.TEXT, - ) - } - className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.TextEditor ? "bg-primary-200" : "bg-gray-300"} + > + {t("select_field")} +
+ +
+ onPageFieldChange( + currentIndex, + AvoRedPageFieldType.TextEditor, + AvoRedPageDataType.TEXT, + ) + } + className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.TextEditor ? "bg-primary-200" : "bg-gray-300"} ring-1 mt-2 ring-gray-300 hover:cursor-pointer hover:ring-primary-300 p-3 rounded`} - > - {t("text_editor_field")} -
-
- onPageFieldChange( - currentIndex, - AvoRedPageFieldType.Radio, - AvoRedPageDataType.TEXT, - ) - } - className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.Radio ? "bg-primary-200" : "bg-gray-300"} + > + {t("text_editor_field")} +
+ +
+ onPageFieldChange( + currentIndex, + AvoRedPageFieldType.Radio, + AvoRedPageDataType.TEXT, + ) + } + className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.Radio ? "bg-primary-200" : "bg-gray-300"} ring-1 mt-2 ring-gray-300 hover:cursor-pointer hover:ring-primary-300 p-3 rounded`} - > - {t("radio_field")} -
-
- onPageFieldChange( - currentIndex, - AvoRedPageFieldType.Checkbox, - AvoRedPageDataType.Array_Text, - ) - } - className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.Checkbox ? "bg-primary-200" : "bg-gray-300"} + > + {t("radio_field")} +
+ +
+ onPageFieldChange( + currentIndex, + AvoRedPageFieldType.Checkbox, + AvoRedPageDataType.Array_Text, + ) + } + className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.Checkbox ? "bg-primary-200" : "bg-gray-300"} ring-1 mt-2 ring-gray-300 hover:cursor-pointer hover:ring-primary-300 p-3 rounded`} - > - {t("checkbox_field")} -
-
-
-
-
-
-
-
- setIsOpen(false)} - className="bg-primary-500" - label={t("create_page_field")} - /> -
-
- setIsOpen(false)} - label={t("cancel")} - /> -
-
-
-
- } - modal_header={`Page Field`} - isOpen={isOpen} - > + > + {t("checkbox_field")} +
+ +
+ onPageFieldChange( + currentIndex, + AvoRedPageFieldType.SingleImage, + AvoRedPageDataType.TEXT, + ) + } + className={`${getValues(`page_fields.${currentIndex}.field_type`) === AvoRedPageFieldType.SingleImage ? "bg-primary-200" : "bg-gray-300"} + ring-1 mt-2 ring-gray-300 hover:cursor-pointer hover:ring-primary-300 p-3 rounded`} + > + {t("single_image_field")} +
+
+
+
+
+
+
+
+ setIsOpen(false)} + className="bg-primary-500" + label={t("create_page_field")} + /> +
+
+ setIsOpen(false)} + label={t("cancel")} + /> +
+
+
+
+ } + modal_header={`Page Field`} + isOpen={isOpen} + >
); }) diff --git a/react-admin/src/pages/page/SingleImageModal.tsx b/react-admin/src/pages/page/SingleImageModal.tsx new file mode 100644 index 00000000..d146b59d --- /dev/null +++ b/react-admin/src/pages/page/SingleImageModal.tsx @@ -0,0 +1,148 @@ +import InputField from "../../components/InputField"; +import AvoredModal from "../../components/AvoredModal"; +import React, {useEffect, useState} from "react"; +import {useTranslation} from "react-i18next"; +import IAssetModel from "../../types/asset/IAssetModel"; +import {DisplayAsset} from "../asset/DisplayAsset"; +import _ from "lodash"; +import {useAssetTable} from "../asset/hooks/useAssetTable"; +import {Link, useParams} from "react-router-dom"; +import {RenameAssetModal} from "../asset/RenameAssetModal"; +import {Menu, MenuButton, MenuItem, MenuItems} from "@headlessui/react"; +import {EllipsisHorizontalCircleIcon, FolderPlusIcon} from "@heroicons/react/24/outline"; +import {useAxios} from "../../hooks/useAxios"; +import AvoRedButton from "../../components/AvoRedButton"; + +type SingleImageModalProps = { + isOpen: any, + onCloseModal: any, + selectedAsset: any +} + +export const SingleImageModal = (({ + isOpen, + onCloseModal, + selectedAsset +}: SingleImageModalProps) => { + const [t] = useTranslation("global"); + const client = useAxios(); + const [assets, setAssets]= useState>([]); + + const backend_url = import.meta.env.VITE_AVORED_BACKEND_BASE_URL; + const openFolder = async (e: React.MouseEvent, asset_id: string) => { + e.preventDefault(); + await fetchAssets(asset_id) + }; + + const selectAssetButtonOnClick = (e: React.MouseEvent, asset: IAssetModel) => { + selectedAsset(asset) + } + + const fetchAssets = async (asset_id: string) => { + const assetUrl: string = _.isEmpty(asset_id) ? '/asset' : '/asset?parent_id=' + asset_id; + + const asset_api_table_response = await client.get(assetUrl) + const test: Array = _.get( + asset_api_table_response, + "data.data", + [], + ); + setAssets(test) + } + + useEffect(() => { + const asset_id: string = '' + const fetchData = async () => { + await fetchAssets(asset_id); + } + fetchData() + .catch(console.error) + + }, []) + + return ( + <> +
+ +
+
+
+
+
+
+
+ {assets.map((asset: IAssetModel) => { + return ( +
+ +
+ {asset.asset_type === "FOLDER" ? ( + <> + + + ) : ( + <> + {asset.name} + + )} +
+
+
+ {asset.asset_type === "FOLDER" ? ( + <> + + + ) : ( + <> +
+ {/** ADD COPY ICON AND Allow them to copy the file name **/} + {asset.name} +
+
+ ) => selectAssetButtonOnClick(e, asset)} + className="bg-primary-600 hover:bg-primary-500 focus:ring-primary-500 mt-3" + label={t!("select_asset")} /> +
+ + )} +
+
+
+ ); + })} +
+
+
+
+
+
+
+
+ } + /> +
+ + + ) +}) \ No newline at end of file diff --git a/react-admin/src/types/page/IPageModel.ts b/react-admin/src/types/page/IPageModel.ts index 2155aab4..5afe5763 100644 --- a/react-admin/src/types/page/IPageModel.ts +++ b/react-admin/src/types/page/IPageModel.ts @@ -28,5 +28,6 @@ export enum AvoRedPageFieldType { SELECT = "Select", TextEditor = "TextEditor", Radio = "Radio", - Checkbox = "Checkbox" + Checkbox = "Checkbox", + SingleImage = "SingleImage" } diff --git a/src/api/handlers/misc/install_demo_data_api_handler.rs b/src/api/handlers/misc/install_demo_data_api_handler.rs index adf362ce..42da49eb 100644 --- a/src/api/handlers/misc/install_demo_data_api_handler.rs +++ b/src/api/handlers/misc/install_demo_data_api_handler.rs @@ -72,7 +72,7 @@ pub async fn install_demo_data_api_handler( identifier: 'rate-us-number', data_type: 'TEXT', field_type: 'Text', - field_content: { text_value: '82' } + field_content: { text_value: '85' } }, { name: 'rate us title', @@ -93,7 +93,7 @@ pub async fn install_demo_data_api_handler( identifier: 'commit-number', data_type: 'TEXT', field_type: 'Text', - field_content: { text_value: '809' } + field_content: { text_value: '856' } }, { name: 'commit title',