feat: add app and config
This commit is contained in:
		| @@ -1,11 +1,14 @@ | ||||
| import { useEffect, useState } from 'react'; | ||||
| import { JSX, useEffect, useState } from 'react'; | ||||
| import { useConfigStore } from '../store/config'; | ||||
| import { CardBlank } from '@/components/card'; | ||||
| import { Button, ButtonGroup, Divider, Drawer, Tab, Tabs, Tooltip } from '@mui/material'; | ||||
| import { Edit, Plus, Save, Trash, X } from 'lucide-react'; | ||||
| import { Button, ButtonGroup, Divider, Drawer, FormControlLabel, Tab, Tabs, Tooltip, useTheme } from '@mui/material'; | ||||
| import { Edit, Plus, Save, Share, Trash, X } from 'lucide-react'; | ||||
| import ShareAltOutlined from '@ant-design/icons/ShareAltOutlined'; | ||||
| import { useModal } from '@kevisual/center-components/modal/Confirm.tsx'; | ||||
| import { useForm, Controller } from 'react-hook-form'; | ||||
| import { TextField } from '@mui/material'; | ||||
| import { useController } from 'react-hook-form'; | ||||
|  | ||||
| import { TextField, TextFieldLabel } from '@kevisual/center-components/input/TextField.tsx'; | ||||
| import { useTranslation } from 'react-i18next'; | ||||
| import { IconButton } from '@kevisual/center-components/button/index.tsx'; | ||||
| import { useShallow } from 'zustand/shallow'; | ||||
| @@ -13,7 +16,8 @@ import { load, dump } from 'js-yaml'; | ||||
| import CodeEditor from '@uiw/react-textarea-code-editor'; | ||||
| import { toast } from 'react-toastify'; | ||||
| import { isEmpty, pick } from 'lodash-es'; | ||||
|  | ||||
| import { usePermissionModal } from '@kevisual/resources/index.ts'; | ||||
| import React from 'react'; | ||||
| type DataYamlEditProps = { | ||||
|   onSave: (data: any) => Promise<void>; | ||||
|   type?: 'yaml' | 'json'; | ||||
| @@ -42,7 +46,6 @@ export const DataYamlEdit = ({ onSave, type }: DataYamlEditProps) => { | ||||
|       } | ||||
|     } | ||||
|   }, [formData]); | ||||
|   console.log(formData); | ||||
|   const handleSave = () => { | ||||
|     let data: any = {}; | ||||
|     try { | ||||
| @@ -109,14 +112,16 @@ export const DrawerEdit = () => { | ||||
|     await updateData({ ...values, id: formData.id }, { refresh: true }); | ||||
|   }; | ||||
|   const onSubmit = (data) => { | ||||
|     console.log('Form Data:', data); | ||||
|     const pickValue = pick(data, ['title', 'key', 'description']); | ||||
|     onSave(pickValue); | ||||
|   }; | ||||
|   const theme = useTheme(); | ||||
|   const defaultProps = theme.components?.MuiTextField?.defaultProps; | ||||
|   return ( | ||||
|     <Drawer | ||||
|       open={showEdit} | ||||
|       anchor='right' | ||||
|       container={document.getElementById('for-drawer')} | ||||
|       slotProps={{ | ||||
|         paper: { | ||||
|           sx: { | ||||
| @@ -139,22 +144,21 @@ export const DrawerEdit = () => { | ||||
|           <Tab label='JSON Config' value='json' /> | ||||
|         </Tabs> | ||||
|         {tab === 'base' && ( | ||||
|           <form onSubmit={handleSubmit(onSubmit)} className='w-full p-2'> | ||||
|             <Controller | ||||
|               name='title' | ||||
|               control={control} | ||||
|               render={({ field }) => <TextField {...field} label='Title' variant='outlined' fullWidth margin='normal' />} | ||||
|             /> | ||||
|           <form onSubmit={handleSubmit(onSubmit)} className='w-full p-2 flex flex-col gap-6'> | ||||
|             <Controller control={control} name='title' render={({ field }) => <TextField {...field} label='Title' />} /> | ||||
|             <Controller | ||||
|               name='key' | ||||
|               control={control} | ||||
|               render={({ field }) => <TextField {...field} label='Key' variant='outlined' fullWidth margin='normal' />} | ||||
|             /> | ||||
|             <Controller | ||||
|               name='description' | ||||
|               control={control} | ||||
|               render={({ field }) => <TextField {...field} label='Description' variant='outlined' fullWidth margin='normal' multiline rows={4} />} | ||||
|               render={({ field }) => ( | ||||
|                 <TextField | ||||
|                   {...field} | ||||
|                   label={ | ||||
|                     <TextFieldLabel label='Key' tips='Key is the unique identifier for the configuration. if set and id is none will change data by key;' /> | ||||
|                   } | ||||
|                 /> | ||||
|               )} | ||||
|             /> | ||||
|             <Controller name='description' control={control} render={({ field }) => <TextField {...field} label='Description' multiline rows={4} />} /> | ||||
|             <Button type='submit' variant='contained' color='primary'> | ||||
|               {t('Submit')} | ||||
|             </Button> | ||||
| @@ -174,14 +178,36 @@ export const DrawerEdit = () => { | ||||
|     </Drawer> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| export const MyController = React.forwardRef( | ||||
|   ({ control, name, Component, componentProps }: { control: any; name: string; Component: (props: any) => JSX.Element; componentProps: any }, ref) => { | ||||
|     const theme = useTheme(); | ||||
|     const defaultProps = theme.components?.MuiTextField?.defaultProps; | ||||
|     console.log(defaultProps, 'defaultProps'); | ||||
|     const { field } = useController({ control, name }); | ||||
|     return <Component {...field} {...componentProps} ref={ref} />; | ||||
|   }, | ||||
| ); | ||||
| export const List = () => { | ||||
|   const { list, getConfig, setShowEdit, setFormData, deleteConfig } = useConfigStore(); | ||||
|   const { list, getConfig, setShowEdit, setFormData, deleteConfig, updateData, formData } = useConfigStore(); | ||||
|   const [modal, contextHolder] = useModal(); | ||||
|   useEffect(() => { | ||||
|     getConfig(); | ||||
|   }, []); | ||||
|   const { setOpen, contextHolder: contextHolderPermission } = usePermissionModal({ | ||||
|     onSave: async (values) => { | ||||
|       const permission = values; | ||||
|       console.log(permission, formData.id); | ||||
|       if (permission && formData.id) { | ||||
|         const res = await updateData({ data: { permission }, id: formData.id }, { refresh: true }); | ||||
|         console.log(res); | ||||
|         return res.code === 200; | ||||
|       } | ||||
|       await new Promise((resolve) => setTimeout(resolve, 1000)); | ||||
|       return true; | ||||
|     }, | ||||
|   }); | ||||
|   console.log(list); | ||||
|   const { t } = useTranslation(); | ||||
|   return ( | ||||
|     <div className='w-full h-full flex bg-gray-100'> | ||||
|       <div className='h-full bg-white'> | ||||
| @@ -191,17 +217,26 @@ export const List = () => { | ||||
|               setShowEdit(true); | ||||
|               setFormData({}); | ||||
|             }}> | ||||
|             <Plus /> | ||||
|             <Plus size={16} /> | ||||
|           </IconButton> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div className=' grow p-4'> | ||||
|       <div className=' grow p-4 '> | ||||
|         <div className='w-full h-full bg-white rounded-lg p-2 scrollbar '> | ||||
|           <div className='flex flex-wrap gap-2'> | ||||
|           <div className='flex flex-wrap gap-2 '> | ||||
|             {list.map((item) => ( | ||||
|               <div className='card w-[300px]' key={item.id}> | ||||
|               <div className='card w-[300px] ' key={item.id}> | ||||
|                 <div className='card-title flex font-bold justify-between'>{item.title}</div> | ||||
|                 <div className='card-content'>{item.description}</div> | ||||
|                 <div className='card-content'> | ||||
|                   <div className='flex gap-2'> | ||||
|                     <div>{t('Description')}:</div> | ||||
|                     <div>{item.description}</div> | ||||
|                   </div> | ||||
|                   <div className='flex gap-2'> | ||||
|                     <div>{t('Key')}:</div> | ||||
|                     <div>{item.key}</div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div className='card-footer flex justify-end'> | ||||
|                   <ButtonGroup variant='contained'> | ||||
|                     <Button | ||||
| @@ -211,6 +246,15 @@ export const List = () => { | ||||
|                       }}> | ||||
|                       <Edit /> | ||||
|                     </Button> | ||||
|                     <Tooltip title={t('Permission')}> | ||||
|                       <Button | ||||
|                         onClick={() => { | ||||
|                           setFormData(item); | ||||
|                           setOpen(true, item.data?.permission); | ||||
|                         }}> | ||||
|                         <ShareAltOutlined style={{ fontSize: 20 }} /> | ||||
|                       </Button> | ||||
|                     </Tooltip> | ||||
|                     <Button | ||||
|                       onClick={() => { | ||||
|                         modal.confirm({ | ||||
| @@ -233,6 +277,7 @@ export const List = () => { | ||||
|       </div> | ||||
|       <DrawerEdit /> | ||||
|       {contextHolder} | ||||
|       {contextHolderPermission} | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user