CardView düzenlemesi
This commit is contained in:
parent
330c1aed19
commit
45a89bd41a
1 changed files with 78 additions and 120 deletions
|
|
@ -1,3 +1,12 @@
|
||||||
|
// URLSearchParams'ı primitive objeye çeviren yardımcı fonksiyon
|
||||||
|
function getSearchParamsObject(searchParams?: URLSearchParams) {
|
||||||
|
if (!searchParams) return undefined;
|
||||||
|
const obj: Record<string, string> = {};
|
||||||
|
for (const [key, value] of searchParams.entries()) {
|
||||||
|
obj[key] = value;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
import Container from '@/components/shared/Container'
|
import Container from '@/components/shared/Container'
|
||||||
import { Notification, toast } from '@/components/ui'
|
import { Notification, toast } from '@/components/ui'
|
||||||
import { DX_CLASSNAMES } from '@/constants/app.constant'
|
import { DX_CLASSNAMES } from '@/constants/app.constant'
|
||||||
|
|
@ -395,13 +404,6 @@ const CardView = (props: CardViewProps) => {
|
||||||
}, [listFormCode])
|
}, [listFormCode])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cardViewRef?.current) {
|
|
||||||
const instance = cardViewRef?.current?.instance()
|
|
||||||
if (instance) {
|
|
||||||
instance.option('dataSource', undefined)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refListFormCode.current !== listFormCode) {
|
if (refListFormCode.current !== listFormCode) {
|
||||||
setColumnData(undefined)
|
setColumnData(undefined)
|
||||||
}
|
}
|
||||||
|
|
@ -631,104 +633,27 @@ const CardView = (props: CardViewProps) => {
|
||||||
loadLookups()
|
loadLookups()
|
||||||
}, [columnsWithLookup])
|
}, [columnsWithLookup])
|
||||||
|
|
||||||
// DataSource oluştur - sadece gridDto ve listFormCode değiştiğinde (useMemo ile cache'le)
|
|
||||||
const cardViewDataSource = useMemo(() => {
|
|
||||||
if (!gridDto) return null
|
|
||||||
|
|
||||||
|
// Kolonları oluştur - Grid ile aynı şekilde columnData state ile yönet
|
||||||
|
useEffect(() => {
|
||||||
|
if (!gridDto || !config) return
|
||||||
const cols = getBandedColumns()
|
const cols = getBandedColumns()
|
||||||
if (!cols || cols.length === 0) return null
|
setColumnData(cols)
|
||||||
|
}, [gridDto, config])
|
||||||
|
|
||||||
const baseStore = createSelectDataSource(
|
// DataSource'u columnData'ya göre oluştur
|
||||||
|
const [cardViewDataSource, setCardViewDataSource] = useState<CustomStore<any, any>>()
|
||||||
|
useEffect(() => {
|
||||||
|
if (!gridDto || !columnData) return
|
||||||
|
const ds = createSelectDataSource(
|
||||||
gridDto.gridOptions,
|
gridDto.gridOptions,
|
||||||
listFormCode,
|
listFormCode,
|
||||||
searchParams,
|
searchParams,
|
||||||
layoutTypes.cardView,
|
layoutTypes.cardView,
|
||||||
cols,
|
columnData
|
||||||
)
|
)
|
||||||
|
setCardViewDataSource(ds)
|
||||||
// CardView için sadece 1 select çağrısı yapacak wrapper
|
}, [gridDto, listFormCode, searchParams, columnData])
|
||||||
let cachedData: any[] | null = null
|
|
||||||
let cachedTotalCount: number = 0
|
|
||||||
let isLoading = false
|
|
||||||
const keyExpr = gridDto.gridOptions.keyFieldName
|
|
||||||
|
|
||||||
const clearCache = () => {
|
|
||||||
cachedData = null
|
|
||||||
cachedTotalCount = 0
|
|
||||||
isLoading = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache temizleme fonksiyonunu dışarıya expose et
|
|
||||||
;(window as any).__clearCardViewCache = clearCache
|
|
||||||
|
|
||||||
const optimizedStore: any = new CustomStore({
|
|
||||||
key: keyExpr,
|
|
||||||
load: async (loadOptions: any) => {
|
|
||||||
// Zaten yüklenmişse cache'den dön
|
|
||||||
if (cachedData !== null && !isLoading) {
|
|
||||||
return {
|
|
||||||
data: cachedData,
|
|
||||||
totalCount: cachedTotalCount,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Yükleme devam ediyorsa bekle
|
|
||||||
if (isLoading) {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
||||||
if (cachedData !== null) {
|
|
||||||
return {
|
|
||||||
data: cachedData,
|
|
||||||
totalCount: cachedTotalCount,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isLoading = true
|
|
||||||
try {
|
|
||||||
const result = await baseStore.load(loadOptions)
|
|
||||||
cachedData = result?.data || []
|
|
||||||
cachedTotalCount = result?.totalCount || 0
|
|
||||||
return result
|
|
||||||
} finally {
|
|
||||||
isLoading = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
byKey: async (key: any) => {
|
|
||||||
// Cache'de ara
|
|
||||||
if (cachedData && keyExpr) {
|
|
||||||
const item = cachedData.find((row: any) => row?.[keyExpr] === key)
|
|
||||||
if (item) return item
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bulamazsa server'a git
|
|
||||||
return baseStore.byKey(key)
|
|
||||||
},
|
|
||||||
insert: async (values: any) => {
|
|
||||||
const result = await baseStore.insert(values)
|
|
||||||
clearCache()
|
|
||||||
return result
|
|
||||||
},
|
|
||||||
update: async (key: any, values: any) => {
|
|
||||||
const result = await baseStore.update(key, values)
|
|
||||||
clearCache()
|
|
||||||
return result
|
|
||||||
},
|
|
||||||
remove: async (key: any) => {
|
|
||||||
const result = await baseStore.remove(key)
|
|
||||||
clearCache()
|
|
||||||
return result
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
// DataSource içine sar
|
|
||||||
return new DataSource({
|
|
||||||
store: optimizedStore,
|
|
||||||
reshapeOnPush: true,
|
|
||||||
paginate: true,
|
|
||||||
pageSize: pageSize,
|
|
||||||
})
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [gridDto, listFormCode])
|
|
||||||
|
|
||||||
// extraFilters değişikliğini izlemek için ref
|
// extraFilters değişikliğini izlemek için ref
|
||||||
const extraFiltersInitialized = useRef(false)
|
const extraFiltersInitialized = useRef(false)
|
||||||
|
|
@ -860,7 +785,6 @@ const CardView = (props: CardViewProps) => {
|
||||||
const extCol = col as any
|
const extCol = col as any
|
||||||
const colData = gridDto?.columnFormats.find((c) => c.fieldName === col.dataField)
|
const colData = gridDto?.columnFormats.find((c) => c.fieldName === col.dataField)
|
||||||
|
|
||||||
// Column props
|
|
||||||
const columnProps: any = {
|
const columnProps: any = {
|
||||||
dataField: col.dataField,
|
dataField: col.dataField,
|
||||||
caption: col.caption ? translate('::' + col.caption) : captionize(col.dataField || ''),
|
caption: col.caption ? translate('::' + col.caption) : captionize(col.dataField || ''),
|
||||||
|
|
@ -924,26 +848,60 @@ const CardView = (props: CardViewProps) => {
|
||||||
const onCardsPerRowChanged = useCallback(
|
const onCardsPerRowChanged = useCallback(
|
||||||
(value: number) => {
|
(value: number) => {
|
||||||
setCardsPerRow(value)
|
setCardsPerRow(value)
|
||||||
// localStorage'a kaydet
|
|
||||||
const storageKey = `cardview-cardsPerRow-${listFormCode}`
|
|
||||||
localStorage.setItem(storageKey, value.toString())
|
|
||||||
},
|
},
|
||||||
[listFormCode],
|
[],
|
||||||
)
|
)
|
||||||
|
useEffect(() => {
|
||||||
// Page size değiştiğinde
|
if (!gridDto) {
|
||||||
const onPageSizeChanged = useCallback((newPageSize: number) => {
|
return
|
||||||
setPageSize(newPageSize)
|
|
||||||
const instance = cardViewRef.current?.instance()
|
|
||||||
if (instance) {
|
|
||||||
instance.pageSize(newPageSize)
|
|
||||||
}
|
}
|
||||||
}, [])
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gridDto?.gridOptions.extraFilterDto) {
|
||||||
|
const extras = gridDto.gridOptions.extraFilterDto.map((f) => ({
|
||||||
|
fieldName: f.fieldName,
|
||||||
|
caption: f.caption,
|
||||||
|
operator: f.operator || '=',
|
||||||
|
value: f.defaultValue || '',
|
||||||
|
controlType: f.controlType,
|
||||||
|
}))
|
||||||
|
// Sadece ilk yüklemede extraFilters'ı set et, her gridDto değişiminde değil
|
||||||
|
setExtraFilters((prev) => {
|
||||||
|
if (prev.length === 0) return extras
|
||||||
|
return prev
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gridDto?.gridOptions.editingOptionDto?.popup) {
|
||||||
|
setIsPopupFullScreen(gridDto.gridOptions.editingOptionDto.popup.fullScreen)
|
||||||
|
}
|
||||||
|
|
||||||
|
// cardsPerRow başlangıç değeri sadece gridDto'dan alınır
|
||||||
|
if (gridDto?.gridOptions.layoutDto?.cardLayoutColumn) {
|
||||||
|
setCardsPerRow(gridDto.gridOptions.layoutDto.cardLayoutColumn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pageSize başlangıç değeri sadece gridDto'dan alınır
|
||||||
|
if (gridDto?.gridOptions.pageSize) {
|
||||||
|
setPageSize(gridDto.gridOptions.pageSize)
|
||||||
|
}
|
||||||
|
}, [gridDto, listFormCode])
|
||||||
|
|
||||||
// Toolbar items
|
// Toolbar items
|
||||||
const toolbarItems = useMemo(() => {
|
const toolbarItems = useMemo(() => {
|
||||||
if (!gridDto) return []
|
if (!gridDto) return []
|
||||||
|
|
||||||
const items: any[] = [
|
const items: any[] = [
|
||||||
{ name: 'addCardButton' },
|
{ name: 'addCardButton' },
|
||||||
{ name: 'searchPanel' },
|
{ name: 'searchPanel' },
|
||||||
|
|
@ -1032,8 +990,8 @@ const CardView = (props: CardViewProps) => {
|
||||||
const pagerConfig = useMemo(() => {
|
const pagerConfig = useMemo(() => {
|
||||||
const allowedSizes = gridDto?.gridOptions.pagerOptionDto?.allowedPageSizes
|
const allowedSizes = gridDto?.gridOptions.pagerOptionDto?.allowedPageSizes
|
||||||
?.split(',')
|
?.split(',')
|
||||||
.map((s) => Number(s.trim()))
|
.map((s: string) => Number(s.trim()))
|
||||||
.filter((n) => !isNaN(n) && n > 0) || [10, 20, 50, 100]
|
.filter((n: number) => !isNaN(n) && n > 0) || [10, 20, 50, 100]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
visible: gridDto?.gridOptions.pagerOptionDto?.visible !== false,
|
visible: gridDto?.gridOptions.pagerOptionDto?.visible !== false,
|
||||||
|
|
@ -1099,7 +1057,7 @@ const CardView = (props: CardViewProps) => {
|
||||||
? `calc(100vh - ${170 + widgetGroupHeight}px)`
|
? `calc(100vh - ${170 + widgetGroupHeight}px)`
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
remoteOperations={false}
|
remoteOperations={true}
|
||||||
onSelectionChanged={onSelectionChanged as any}
|
onSelectionChanged={onSelectionChanged as any}
|
||||||
onInitNewCard={onInitNewCard as any}
|
onInitNewCard={onInitNewCard as any}
|
||||||
onCardInserting={onCardInserting as any}
|
onCardInserting={onCardInserting as any}
|
||||||
|
|
@ -1135,11 +1093,7 @@ const CardView = (props: CardViewProps) => {
|
||||||
props.refreshData?.()
|
props.refreshData?.()
|
||||||
}, 100)
|
}, 100)
|
||||||
}}
|
}}
|
||||||
onOptionChanged={(e: any) => {
|
// onOptionChanged kaldırıldı, pageSize sadece state ve useEffect ile kontrol ediliyor
|
||||||
if (e.name === 'paging.pageSize' && e.value !== pageSize) {
|
|
||||||
setPageSize(e.value)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{/* Toolbar */}
|
{/* Toolbar */}
|
||||||
<Toolbar items={toolbarItems} />
|
<Toolbar items={toolbarItems} />
|
||||||
|
|
@ -1180,7 +1134,11 @@ const CardView = (props: CardViewProps) => {
|
||||||
<ColumnChooser enabled={true} mode="select" />
|
<ColumnChooser enabled={true} mode="select" />
|
||||||
|
|
||||||
{/* Paging */}
|
{/* Paging */}
|
||||||
<Paging enabled={pagingConfig.enabled} defaultPageSize={pagingConfig.pageSize} />
|
<Paging
|
||||||
|
enabled={pagingConfig.enabled}
|
||||||
|
pageSize={pageSize}
|
||||||
|
onPageSizeChange={setPageSize}
|
||||||
|
/>
|
||||||
|
|
||||||
{/* Pager */}
|
{/* Pager */}
|
||||||
<Pager
|
<Pager
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue