erp-platform/ui/src/views/list/useToolbar.tsx
2025-12-03 00:07:31 +03:00

340 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Button, Notification, toast } from '@/components/ui'
import { GridDto, UiCommandButtonPositionTypeEnum } from '@/proxy/form/models'
import { dynamicFetch } from '@/services/form.service'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { usePermission } from '@/utils/hooks/usePermission'
import { DataGridTypes } from 'devextreme-react/data-grid'
import { ToolbarItem } from 'devextreme/ui/data_grid_types'
import { useEffect, useState } from 'react'
import { useDialogContext } from '../shared/DialogContext'
import { usePWA } from '@/utils/hooks/usePWA'
import { layoutTypes, ListViewLayoutType } from '../admin/listForm/edit/types'
type ToolbarModalData = {
open: boolean
content?: JSX.Element
}
// https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxDataGrid/Configuration/toolbar/
// item.name > Accepted Values: 'addRowButton', 'applyFilterButton', 'columnChooserButton', 'exportButton', 'groupPanel', 'revertButton', 'saveButton', 'searchPanel'
const useToolbar = ({
gridDto,
listFormCode,
getSelectedRowKeys,
getSelectedRowsData,
refreshData,
getFilter,
layout,
expandAll,
collapseAll,
}: {
gridDto?: GridDto
listFormCode: string
getSelectedRowKeys: () => void
getSelectedRowsData: () => any
refreshData: () => void
getFilter: () => void
layout: ListViewLayoutType | string
expandAll?: () => void
collapseAll?: () => void
}): {
toolbarData: ToolbarItem[]
toolbarModalData: ToolbarModalData | undefined
setToolbarModalData: (data: ToolbarModalData | undefined) => void
} => {
const dialog: any = useDialogContext()
const { translate } = useLocalization()
const { checkPermission } = usePermission()
const isPwaMode = usePWA()
const [toolbarData, setToolbarData] = useState<ToolbarItem[]>([])
const [toolbarModalData, setToolbarModalData] = useState<ToolbarModalData>()
const grdOpt = gridDto?.gridOptions
function getToolbarData() {
const items: ToolbarItem[] = []
if (!gridDto || !grdOpt) {
setToolbarData(items)
return
}
// Add searchPanel
if (grdOpt.searchPanelDto?.visible) {
items.push({
locateInMenu: 'auto',
showText: 'inMenu',
name: 'searchPanel',
})
}
items.push({
widget: 'dxButton',
name: 'refreshButton',
options: {
icon: 'refresh',
onClick: refreshData,
text: translate('::ListForms.ListForm.Refresh'),
},
location: 'after',
})
// Add Expand All button for TreeList
if (layout === layoutTypes.tree && grdOpt.treeOptionDto?.parentIdExpr) {
items.push({
widget: 'dxButton',
name: 'expandAllButton',
options: {
icon: 'plus',
text: translate('::ListForms.ListFormEdit.ExpandAll'),
onClick: expandAll,
},
location: 'after',
})
// Add Collapse All button for TreeList
items.push({
widget: 'dxButton',
name: 'collapseAllButton',
options: {
icon: 'minus',
text: translate('::ListForms.ListFormEdit.CollapseAll'),
onClick: collapseAll,
},
location: 'after',
})
}
// field chooser panel
if (grdOpt.columnOptionDto?.columnChooserEnabled) {
items.push({
locateInMenu: 'auto',
showText: 'inMenu',
name: 'columnChooserButton',
})
}
// Add InsertNewRecord button
if (grdOpt.editingOptionDto?.allowAdding && checkPermission(grdOpt.permissionDto?.c)) {
items.push({
locateInMenu: 'auto',
showText: 'always',
name: 'addRowButton',
location: 'after',
})
}
// Add group panel
if (grdOpt.groupPanelDto?.visible) {
items.push({
locateInMenu: 'auto',
showText: 'inMenu',
name: 'groupPanel',
})
}
// Add DeleteSelectedRecords button
// coklu silme icin
if (grdOpt.editingOptionDto?.allowDeleting && checkPermission(grdOpt.permissionDto?.d)) {
items.push({
location: 'after',
widget: 'dxButton',
locateInMenu: 'auto',
showText: 'inMenu',
name: 'deleteSelectedRecords',
options: {
text: translate('::ListForms.ListForm.DeleteSelectedRecords'),
icon: 'trash',
visible: false,
onClick() {
if (!grdOpt.deleteServiceAddress) {
return
}
dynamicFetch(grdOpt.deleteServiceAddress, 'POST', null, {
keys: getSelectedRowKeys(),
listFormCode,
}).then(() => {
refreshData()
})
},
},
})
// Add DeleteAllRecords button
// butun kayitlari (filtreli) icin
if (grdOpt.editingOptionDto?.allowAllDeleting) {
const buttonDeleteAll: DataGridTypes.ToolbarItem = {
location: 'after',
widget: 'dxButton',
name: 'deleteAllRecords',
options: {
text: translate('::ListForms.ListForm.DeleteAllRecords'),
hint: translate('::ListForms.ListForm.DeleteAllRecords'),
icon: 'trash',
visible: true,
onClick() {
const parameters = {
listFormCode,
filter: JSON.stringify(getFilter()),
onlyTotalCountQuery: true,
createDeleteQuery: false,
}
dynamicFetch('list-form-select/select', 'GET', parameters).then((r: any) => {
setToolbarModalData({
open: true,
content: (
<>
<h5 className="mb-4">Delete All Records</h5>
<p>Are you sure to delete all {r.data.totalCount} records?</p>
<div className="text-right mt-6">
<Button
className="ltr:mr-2 rtl:ml-2"
variant="plain"
onClick={() => setToolbarModalData(undefined)}
>
Cancel
</Button>
<Button
variant="solid"
onClick={() => {
//delete parameters.onlyTotalCountQuery
parameters.createDeleteQuery = true // tumunu silme islemi parametresi > set
dynamicFetch('list-form-select/select', 'GET', parameters).then(() => {
toast.push(
<Notification type="success" duration={2000}>
{'Tüm kayıtlar silindi.'}
</Notification>,
{
placement: 'top-end',
},
)
refreshData()
setToolbarModalData(undefined)
})
}}
>
Save
</Button>
</div>
</>
),
})
})
},
},
}
items.push(buttonDeleteAll)
}
}
// #region Toolbar icin kullanici tanimli dinamik butonlari ekler
for (let i = 0; i < grdOpt.commandColumnDto.length; i++) {
const action = grdOpt.commandColumnDto[i]
// action.buttonPosition == 1 ise Toolbar butonudur, burada sadece Toolbar butonunu eklenir
if (action.buttonPosition !== UiCommandButtonPositionTypeEnum.Toolbar) {
continue
}
if (checkPermission(action.authName)) {
const buttonCustom: DataGridTypes.ToolbarItem = {
location: 'after',
widget: 'dxButton',
name: action.hint,
options: {
hint: action.hint,
text: action.text,
icon: action.icon,
visible: true,
onClick(e: any) {
if (typeof e.event?.preventDefault === 'function') {
e?.event?.preventDefault()
}
if (action.url) {
let url = action.url
// griddeki secili satirlari al
const selectedRowsData = getSelectedRowsData()
// constsa her bir secili satir icin donguye gir
for (let i = 0; i < selectedRowsData.length; i++) {
// secili satirin objesine ait property verilerini al
const keys = Object.keys(selectedRowsData[i])
// secili satirin her bir property si icin donguye gir
for (let j = 0; j < keys.length; j++) {
// secili satirin j indexine sahip property ismini al
const fieldName = keys[j]
// secili satirin j indexine sahip property isminin degerini al
const fieldValue = selectedRowsData[i][fieldName]
// url icerisindeki {PropertyName} seklindeki anahtarlari secili satirdaki uyusan propertyler ile degistir
url = url.replace(`@${fieldName}`, fieldValue)
}
break // Url cagirmak icin kullanilacak parametreler sadece secili olan ilk satirdan alinir!
}
window.open(url, isPwaMode ? '_self' : action.urlTarget)
} else if (action.dialogName) {
if (action.dialogParameters) {
var dynamicMap = JSON.parse(action.dialogParameters)
for (const [key, value] of Object.entries<string>(dynamicMap)) {
dynamicMap[key] = value.startsWith('@')
? e.row.data[value.replace('@', '')]
: value
}
dialog.setConfig({
component: action.dialogName,
props: dynamicMap,
})
}
} else if (action.onClick) {
eval(action.onClick)
}
},
},
}
items.push(buttonCustom)
}
}
// #endregion
// batch editing icin kaydet ve geri al butonu
if (
grdOpt.editingOptionDto?.allowUpdating &&
grdOpt.editingOptionDto?.mode == 'batch' &&
checkPermission(grdOpt.permissionDto?.u)
) {
items.push({
locateInMenu: 'auto',
showText: 'inMenu',
name: 'saveButton',
})
items.push({
locateInMenu: 'auto',
showText: 'inMenu',
name: 'revertButton',
})
}
// #endregion
setToolbarData(items)
}
useEffect(() => {
if (!gridDto && !listFormCode) return
getToolbarData()
}, [gridDto, listFormCode])
return {
toolbarData,
toolbarModalData,
setToolbarModalData,
}
}
export { useToolbar }