erp-platform/ui/src/views/form/FormButtons.tsx
2025-10-22 17:58:27 +03:00

325 lines
9.6 KiB
TypeScript

import { Badge, Button, Dialog, Notification, toast } from '@/components/ui'
import navigationIcon from '@/configs/navigation-icon.config'
import { useLocalization } from '@/utils/hooks/useLocalization'
import CustomStore from 'devextreme/data/custom_store'
import { useState } from 'react'
import {
FaChevronLeft,
FaTrashAlt,
FaPlusCircle,
FaPencilAlt,
FaEye,
FaSave,
FaCog,
} from 'react-icons/fa'
import { useNavigate } from 'react-router-dom'
import { GridColumnData } from '../list/GridColumnData'
import { useToolbar } from '../list/useToolbar'
import { PermissionResults, RowMode } from './types'
import { GridDto } from '@/proxy/form/models'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { usePermission } from '@/utils/hooks/usePermission'
import { GridExtraFilterState } from '../list/Utils'
import { usePWA } from '@/utils/hooks/usePWA'
const FormButtons = (props: {
isSubForm?: boolean
mode: RowMode
listFormCode: string
id?: string
gridDto: GridDto
commandColumnData: GridColumnData
dataSource: CustomStore<any, any>
permissions: PermissionResults
handleSubmit: (e: any) => void
refreshData: () => void
getSelectedRowKeys: () => void
getSelectedRowsData: () => any[]
getFilter: () => void
onActionEdit?: () => void
onActionNew?: () => void
onActionView?: () => void
}) => {
const {
isSubForm,
mode,
listFormCode,
id,
gridDto,
commandColumnData,
dataSource,
permissions,
handleSubmit,
refreshData,
getSelectedRowKeys,
getSelectedRowsData,
getFilter,
onActionEdit,
onActionNew,
onActionView,
} = props
const [loading, setLoading] = useState(false)
const [deleteRowId, setDeleteRowId] = useState<string>()
const [extraFilters, setExtraFilters] = useState<GridExtraFilterState[]>([])
const { checkPermission } = usePermission()
const isPwaMode = usePWA()
const navigate = useNavigate()
const { translate } = useLocalization()
const { toolbarData } = useToolbar({
gridDto,
listFormCode,
getSelectedRowKeys,
getSelectedRowsData,
refreshData,
getFilter,
})
const handleDelete = async (e: any) => {
//auth check
e.preventDefault()
if (!dataSource || !id) {
return
}
setLoading(true)
try {
await dataSource.remove(id)
setDeleteRowId(undefined)
if (props.onActionNew) {
props.onActionNew()
} else {
navigate(-1)
}
toast.push(
<Notification type="success" duration={2000}>
{translate('::ListForms.FormBilgileriSilindi')}
</Notification>,
{
placement: 'top-end',
},
)
} catch (error: any) {
toast.push(<Notification title={error.message} type="danger" />, {
placement: 'top-end',
})
} finally {
setLoading(false)
}
}
return (
<>
<div className="flex flex-row items-center gap-1">
{toolbarData
?.filter(
(item) =>
item.widget == 'dxButton' &&
item.name != 'deleteAllRecords' &&
item.name != 'deleteSelectedRecords',
)
.map((item, i) => {
const IconComp = navigationIcon[item.options?.icon] // React bileşeni olabilir ya da undefined
const hasValidIcon =
IconComp &&
(typeof IconComp === 'function' ||
(typeof IconComp === 'object' && 'render' in IconComp))
return (
<Button
key={'toolbarButton-' + i}
variant="default"
size="xs"
icon={
hasValidIcon ? <IconComp className="text-gray-400" /> : null // 🔒 güvenli render
}
onClick={item.options?.onClick}
>
{item.options?.text}
</Button>
)
})}
{!!toolbarData?.filter(
(item) =>
item.widget == 'dxButton' &&
item.name != 'deleteAllRecords' &&
item.name != 'deleteSelectedRecords',
).length && <Badge innerClass="bg-blue-500" />}
{commandColumnData?.buttons
?.filter((item) => typeof item !== 'string')
.map((item, i) => {
return (
<Button
key={'commandColumnButton-' + i}
variant="default"
size="xs"
title={item.hint}
onClick={(e: any) => {
if (item.onClick) {
const [rowData] = getSelectedRowsData()
e.row = { data: rowData }
item.onClick(e)
}
}}
>
{item.text}
</Button>
)
})}
{!!commandColumnData?.buttons?.filter((item) => typeof item !== 'string').length && (
<Badge innerClass="bg-blue-500" />
)}
{!isSubForm && (
<Button
size="xs"
variant="default"
className="dx-button dx-button-mode-contained dx-button-normal"
icon={<FaChevronLeft />}
color="gray-500"
title={translate('::Cancel')}
onClick={() => {
if (onActionView && id) {
onActionView()
} else {
navigate(-1)
}
}}
></Button>
)}
{mode != 'new' && (
<Button
size="xs"
variant="default"
className="dx-button dx-button-mode-contained dx-button-normal"
icon={<FaTrashAlt />}
color="red-500"
title={translate('::Delete')}
onClick={() => {
setDeleteRowId(id)
}}
{...(permissions.d ? {} : { disabled: true })}
></Button>
)}
{mode != 'new' && (
<Button
size="xs"
variant="default"
className="dx-button dx-button-mode-contained dx-button-normal"
icon={<FaPlusCircle />}
title={translate('::AddNew')}
onClick={() => {
if (onActionNew) {
onActionNew()
} else {
navigate(ROUTES_ENUM.protected.admin.formNew
.replace(':listFormCode', listFormCode))
}
}}
{...(permissions.c ? {} : { disabled: true })}
></Button>
)}
{mode == 'view' && (
<Button
size="xs"
variant="default"
className="dx-button dx-button-mode-contained dx-button-normal"
icon={<FaPencilAlt />}
title={translate('::Edit')}
onClick={() => {
if (onActionEdit) {
onActionEdit()
} else {
navigate(
ROUTES_ENUM.protected.admin.formEdit
.replace(':listFormCode', listFormCode)
.replace(':id', id!),
)
}
}}
{...(permissions.u ? {} : { disabled: true })}
></Button>
)}
{(mode == 'edit' || (onActionView && mode == 'new')) && (
<Button
size="xs"
variant="default"
className="dx-button dx-button-mode-contained dx-button-normal"
icon={<FaEye />}
title={translate('::Detail')}
onClick={() => {
if (onActionView) {
onActionView()
} else {
navigate(
ROUTES_ENUM.protected.admin.formView
.replace(':listFormCode', listFormCode)
.replace(':id', id!),
)
}
}}
{...(permissions.r ? {} : { disabled: true })}
></Button>
)}
{(mode == 'edit' || mode == 'new') && (
<Button
size="xs"
variant="default"
className="dx-button dx-button-mode-contained dx-button-normal"
icon={<FaSave />}
title={translate('::Save')}
onClick={handleSubmit}
{...(permissions.c || permissions.u ? {} : { disabled: true })}
></Button>
)}
{checkPermission(gridDto?.gridOptions.permissionDto.c) && !isSubForm && (
<Button
size="xs"
variant="default"
className="dx-button dx-button-mode-contained dx-button-normal"
icon={<FaCog />}
color="green-500"
title={translate('::ListForms.ListForm.Manage')}
onClick={() => {
window.open(
ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(
':listFormCode',
listFormCode,
),
isPwaMode ? '_self' : '_blank',
)
}}
></Button>
)}
</div>
<Dialog
id="confirmDelete"
isOpen={!!deleteRowId}
onClose={() => setDeleteRowId(undefined)}
onRequestClose={() => setDeleteRowId(undefined)}
>
<h5 className="mb-4">Delete</h5>
<p>Silmek istediğinize emin misiniz?</p>
<div className="text-right mt-6">
<Button
className="ltr:mr-2 rtl:ml-2"
variant="plain"
onClick={() => {
setDeleteRowId(undefined)
}}
>
Cancel
</Button>
<Button variant="solid" color="red-500" onClick={handleDelete}>
Delete
</Button>
</div>
</Dialog>
</>
)
}
export default FormButtons