erp-platform/ui/src/views/list/Pivot.tsx
2025-05-06 14:03:45 +03:00

364 lines
13 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.

/* eslint-disable @typescript-eslint/no-explicit-any */
import Container from '@/components/shared/Container'
import { DX_CLASSNAMES } from '@/constants/app.constant'
import { GridDto, ListFormCustomizationTypeEnum } from '@/proxy/form'
import { getList } from '@/proxy/form/form.service'
import {
getListFormCustomization,
postListFormCustomization,
} from '@/proxy/form/list-form-customization.service'
import { useListFormColumns } from '@/shared/useListFormColumns'
import { useListFormCustomDataSource } from '@/shared/useListFormCustomDataSource'
import { useLocalization } from '@/utils/hooks/useLocalization'
import Chart, { CommonSeriesSettings, Size, Tooltip } from 'devextreme-react/chart'
import PivotGrid, {
FieldChooser,
FieldPanel,
HeaderFilter,
IStateStoringProps,
PivotGridTypes,
Scrolling,
Search,
} from 'devextreme-react/pivot-grid'
import CustomStore from 'devextreme/data/custom_store'
import PivotGridDataSource, { Field } from 'devextreme/ui/pivot_grid/data_source'
import { useCallback, useEffect, useRef, useState } from 'react'
import { Helmet } from 'react-helmet'
import { GridColumnData } from './GridColumnData'
import {
addCss,
addJs,
controlStyleCondition,
pivotFieldConvertDataType,
setGridPanelColor,
} from './Utils'
import { useFilters } from './useFilters'
interface GridProps {
listFormCode: string
searchParams?: URLSearchParams
isSubForm?: boolean
level?: number
refreshData?: () => Promise<void>
}
const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' // kullanici tanimli gridState ile islem gormus gridin paneline ait renk
const Pivot = (props: GridProps) => {
const { listFormCode, searchParams, isSubForm, level } = props
const { translate } = useLocalization()
const gridRef = useRef<PivotGrid>()
const chartRef = useRef<Chart>(null)
const refListFormCode = useRef('')
const [gridDto, setGridDto] = useState<GridDto>()
const [gridDataSource, setGridDataSource] = useState<CustomStore<any, any>>()
const [columnData, setColumnData] = useState<GridColumnData[]>()
const { filterToolbarData, ...filterData } = useFilters({
gridDto,
gridRef,
listFormCode,
})
const { createSelectDataSource } = useListFormCustomDataSource({ pivotRef: gridRef })
const { getBandedColumns } = useListFormColumns({
gridDto,
listFormCode,
isSubForm,
})
function onCellPrepared(e: any) {
const columnFormats = gridDto?.columnFormats
if (!columnFormats) {
return
}
// satir, hucre yada header vb. kisimlara conditional style uygulamak icin
for (let indxCol = 0; indxCol < columnFormats.length; indxCol++) {
const colFormat = columnFormats[indxCol]
for (let indxStyl = 0; indxStyl < colFormat.columnStylingDto.length; indxStyl++) {
const colStyle = colFormat.columnStylingDto[indxStyl] // uygulanacak style
if (e.rowType == colStyle.rowType) {
// header, filter, data, group, summaries ..her birisine style uygulanabilir
// style bütün satıra uygulansın olarak seçili ise yada sadece ilgili field üzerinde ise
if (colStyle.useRow || e.column?.dataField == colFormat.fieldName) {
if (
!colStyle.conditionValue ||
controlStyleCondition(e.data, colFormat.fieldName, colStyle)
) {
// css sınıf ismi var ise uygula
if (colStyle.cssClassName) {
e.cellElement.addClass(colStyle.cssClassName)
}
// css inline style var ise uygula
if (colStyle.cssStyles) {
e.cellElement.attr('style', e.cellElement.attr('style') + ';' + colStyle.cssStyles)
}
}
}
}
}
}
}
const customSaveState = useCallback(
(state: any) =>
postListFormCustomization({
listFormCode: listFormCode,
customizationType: ListFormCustomizationTypeEnum.GridState,
filterName: `pivot-${gridRef.current?.instance.option('stateStoring')?.storageKey ?? ''}`,
customizationData: JSON.stringify(state),
}).then(() => {
setGridPanelColor(statedGridPanelColor)
}),
[listFormCode],
)
const customLoadState = useCallback(
() =>
getListFormCustomization(
listFormCode,
ListFormCustomizationTypeEnum.GridState,
`pivot-${gridRef.current?.instance.option('stateStoring')?.storageKey ?? ''}`,
).then((response: any) => {
setGridPanelColor(statedGridPanelColor)
if (response.data?.length > 0) {
return JSON.parse(response.data[0].customizationData)
}
}),
[listFormCode],
)
useEffect(() => {
if (gridRef?.current) {
gridRef.current.instance.option('remoteOperations', false)
gridRef.current.instance.option('dataSource', undefined)
gridRef.current.instance.option('stateStoring', undefined)
}
const initializeGrid = async () => {
const response = await getList({ listFormCode })
setGridDto(response.data)
}
if (refListFormCode.current !== listFormCode) {
initializeGrid()
}
}, [listFormCode])
useEffect(() => {
if (!gridDto) {
return
}
// Set js and css
const grdOpt = gridDto.gridOptions
if (grdOpt.customJsSources.length) {
for (const js of grdOpt.customJsSources) {
addJs(js)
}
}
if (grdOpt.customStyleSources.length) {
for (const css of grdOpt.customStyleSources) {
addCss(css)
}
}
}, [gridDto])
useEffect(() => {
if (!gridDto) {
return
}
// Set columns
const cols = getBandedColumns()
setColumnData(cols?.filter((a) => a.colData?.pivotSettingsDto.isPivot))
// Set data source
const dataSource: CustomStore<any, any> = createSelectDataSource(
gridDto.gridOptions,
listFormCode,
searchParams,
cols,
)
setGridDataSource(dataSource)
}, [gridDto, searchParams])
useEffect(() => {
refListFormCode.current = listFormCode
if (!gridRef?.current) {
return
}
const fields: any = columnData?.map((b) => {
return {
dataField: b.dataField,
caption: b.caption,
dataType: pivotFieldConvertDataType(b.dataType),
area: b.colData?.pivotSettingsDto.area,
format: b.colData?.pivotSettingsDto.format,
summaryType: b.colData?.pivotSettingsDto.summaryType,
groupInterval: b.colData?.pivotSettingsDto.groupInterval,
sortOrder: b.colData?.pivotSettingsDto.sortOrder,
expanded: b.colData?.pivotSettingsDto.expanded,
wordWrapEnabled: b.colData?.pivotSettingsDto.wordWrapEnabled,
visible: true,
width: b.width,
} as Field
})
PivotGridDataSource
const dataSource: PivotGridTypes.Properties['dataSource'] = {
remoteOperations: true,
store: gridDataSource,
fields,
}
gridRef.current.instance.option('dataSource', dataSource)
gridRef.current.instance.option('state', null)
const stateStoring: IStateStoringProps = {
enabled: gridDto?.gridOptions.stateStoringDto?.enabled,
type: gridDto?.gridOptions.stateStoringDto?.type,
savingTimeout: gridDto?.gridOptions.stateStoringDto?.savingTimeout,
storageKey: gridDto?.gridOptions.stateStoringDto?.storageKey,
}
if (
gridDto?.gridOptions.stateStoringDto?.enabled &&
gridDto?.gridOptions.stateStoringDto?.type === 'custom'
) {
stateStoring.customSave = customSaveState
stateStoring.customLoad = customLoadState
}
gridRef.current.instance.option('stateStoring', stateStoring)
//chart Integration
if (gridRef && chartRef) {
gridRef?.current?.instance.bindChart(chartRef?.current?.instance, {
dataFieldsDisplayMode: 'splitPanes',
alternateDataFields: false,
})
}
}, [columnData])
return (
<Container className={DX_CLASSNAMES}>
{!isSubForm && (
<Helmet
titleTemplate="%s | Kurs Platform"
title={translate('::' + gridDto?.gridOptions.title)}
defaultTitle="Kurs Platform"
></Helmet>
)}
{gridDto && columnData && (
<>
{gridDto.gridOptions.columnOptionDto.showChart && (
<Chart ref={chartRef as any}>
<Size height={gridDto.gridOptions.columnOptionDto.chartHeight} />
<Tooltip enabled={true}></Tooltip>
<CommonSeriesSettings
type={gridDto.gridOptions.columnOptionDto.chartCommonSeriesType}
/>
</Chart>
)}
<PivotGrid
ref={gridRef as any}
id={'Pivot-' + listFormCode}
allowFiltering={gridDto.gridOptions.filterRowDto.visible}
allowSorting={gridDto.gridOptions.sortMode !== 'none'}
allowSortingBySummary={gridDto.gridOptions.sortMode !== 'none'}
height={gridDto.gridOptions.height || '100%'}
width={gridDto.gridOptions.width || '100%'}
showBorders={gridDto.gridOptions.columnOptionDto?.showBorders}
rtlEnabled={gridDto.gridOptions.columnOptionDto?.rtlEnabled}
hoverStateEnabled={gridDto.gridOptions.columnOptionDto?.hoverStateEnabled}
onCellPrepared={onCellPrepared}
>
<HeaderFilter
allowSelectAll={gridDto.gridOptions.selectionDto.allowSelectAll}
width={gridDto.gridOptions.headerFilterDto.width}
height={gridDto.gridOptions.headerFilterDto.height}
>
<Search
enabled={gridDto.gridOptions.headerFilterDto.allowSearch}
timeout={gridDto.gridOptions.headerFilterDto.searchTimeout}
></Search>
</HeaderFilter>
<FieldPanel
allowFieldDragging={gridDto.gridOptions.columnOptionDto.allowFieldDragging}
visible={gridDto.gridOptions.columnOptionDto.showFieldPanel}
showDataFields={gridDto.gridOptions.columnOptionDto.showDataFields}
showColumnFields={gridDto.gridOptions.columnOptionDto.showColumnFields}
showRowFields={gridDto.gridOptions.columnOptionDto.showRowFields}
showFilterFields={gridDto.gridOptions.columnOptionDto.showFilterFields}
/>
<FieldChooser
enabled={gridDto.gridOptions.columnOptionDto.columnChooserEnabled}
height={500}
/>
<Scrolling mode={gridDto.gridOptions.pagerOptionDto.scrollingMode} />
</PivotGrid>
</>
)}
</Container>
)
}
export default Pivot
/*
<Toolbar visible={toolbarData.length > 0 || filterToolbarData.length > 0}>
{toolbarData.map((item) => (
<Item key={item.name} {...item}></Item>
))}
{filterToolbarData.map((item) => (
<Item key={item.name} {...item}></Item>
))}
</Toolbar>
<Sorting mode={gridDto.gridOptions?.sortMode}></Sorting>
<FilterRow
visible={gridDto.gridOptions.filterRowDto?.visible}
applyFilter={gridDto.gridOptions.filterRowDto?.applyFilter}
></FilterRow>
<FilterPanel visible={gridDto.gridOptions.filterPanelDto.visible}></FilterPanel>
<HeaderFilter visible={gridDto.gridOptions.headerFilterDto.visible}></HeaderFilter>
<SearchPanel
visible={gridDto.gridOptions.searchPanelDto.visible}
width={gridDto.gridOptions.searchPanelDto.width}
></SearchPanel>
<GroupPanel visible={gridDto.gridOptions.groupPanelDto?.visible}></GroupPanel>
<Grouping autoExpandAll={gridDto.gridOptions.groupPanelDto?.autoExpandAll}></Grouping>
<Selection
mode={gridDto.gridOptions.selectionDto?.mode}
allowSelectAll={gridDto.gridOptions.selectionDto?.allowSelectAll}
selectAllMode={gridDto.gridOptions.selectionDto?.selectAllMode}
showCheckBoxesMode={gridDto.gridOptions.selectionDto?.showCheckBoxesMode}
></Selection>
<Pager
visible={gridDto.gridOptions.pagerOptionDto?.visible}
allowedPageSizes={gridDto.gridOptions.pagerOptionDto?.allowedPageSizes
?.split(',')
.map((a) => +a)}
showPageSizeSelector={gridDto.gridOptions.pagerOptionDto?.showPageSizeSelector}
showInfo={gridDto.gridOptions.pagerOptionDto?.showInfo}
showNavigationButtons={gridDto.gridOptions.pagerOptionDto?.showNavigationButtons}
infoText={gridDto.gridOptions.pagerOptionDto?.infoText}
displayMode={gridDto.gridOptions.pagerOptionDto?.displayMode}
></Pager>
<ColumnChooser
enabled={gridDto.gridOptions.columnOptionDto?.columnChooserEnabled}
mode={gridDto.gridOptions.columnOptionDto?.columnChooserMode}
></ColumnChooser>
<ColumnFixing
enabled={gridDto.gridOptions.columnOptionDto?.columnFixingEnabled}
></ColumnFixing>
<Scrolling mode={gridDto.gridOptions.pagerOptionDto?.scrollingMode}></Scrolling>
<LoadPanel
enabled={gridDto.gridOptions.pagerOptionDto?.loadPanelEnabled}
text={gridDto.gridOptions.pagerOptionDto?.loadPanelText}
></LoadPanel>
*/