Listeleri mükemmelleştirme ikon vs.
This commit is contained in:
parent
9ea283712e
commit
1d36fc8225
7 changed files with 151 additions and 27 deletions
|
|
@ -22763,7 +22763,7 @@
|
|||
"accountHolder": "Özlem Öztürk",
|
||||
"branch": "03663 / Enpara",
|
||||
"accountNumber": "73941177",
|
||||
"iban": "TR65 0011 1000 0000 0073 9411 77"
|
||||
"iban": "TR11 0015 7000 0000 0073 9411 77"
|
||||
},
|
||||
"workHour": {
|
||||
"weekday": "Public.contact.workHours.weekday",
|
||||
|
|
|
|||
|
|
@ -806,6 +806,7 @@ public class SelectQueryManager : PlatformDomainService, ISelectQueryManager
|
|||
var sql = $@"
|
||||
SELECT {string.Join(", ", selectParts)}
|
||||
FROM [{listform.SelectCommand}]
|
||||
{GetWhereString()}
|
||||
GROUP BY {argumentExpression}";
|
||||
|
||||
return sql;
|
||||
|
|
|
|||
|
|
@ -288,11 +288,23 @@ const useListFormColumns = ({
|
|||
}
|
||||
|
||||
if (hasUpdate) {
|
||||
column.buttons.push('edit')
|
||||
// column.buttons.push('edit')
|
||||
column.buttons.push({
|
||||
icon: 'edit',
|
||||
hint: translate('::Edit'),
|
||||
name: 'edit',
|
||||
text: translate('::Edit'),
|
||||
})
|
||||
}
|
||||
|
||||
if (hasDelete) {
|
||||
column.buttons.push('delete')
|
||||
// column.buttons.push('delete')
|
||||
column.buttons.push({
|
||||
icon: 'trash',
|
||||
hint: translate('::Delete'),
|
||||
name: 'delete',
|
||||
text: translate('::Delete'),
|
||||
})
|
||||
}
|
||||
|
||||
gridDto.gridOptions.commandColumnDto.forEach((action) => {
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ import { captionize } from 'devextreme/core/utils/inflector'
|
|||
import { useListFormCustomDataSource } from '@/shared/useListFormCustomDataSource'
|
||||
import { Button, Pagination, Select } from '@/components/ui'
|
||||
import classNames from 'classnames'
|
||||
import { FaSearch } from 'react-icons/fa'
|
||||
import { FaCog, FaSearch } from 'react-icons/fa'
|
||||
import FormDevExpress from '../form/FormDevExpress'
|
||||
import { GroupItem } from 'devextreme/ui/form'
|
||||
import { Form as FormDx } from 'devextreme-react/form'
|
||||
import FormButtons from '../form/FormButtons'
|
||||
import { Link, useNavigate } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import CustomStore from 'devextreme/data/custom_store'
|
||||
import { PermissionResults, SimpleItemWithColData } from '../form/types'
|
||||
|
|
@ -20,6 +20,7 @@ import { Container, Loading } from '@/components/shared'
|
|||
import WidgetGroup from '@/components/common/WidgetGroup'
|
||||
import { GridExtraFilterState } from './Utils'
|
||||
import { useStoreActions, useStoreState } from '@/store/store'
|
||||
import { usePWA } from '@/utils/hooks/usePWA'
|
||||
|
||||
const CardItem = ({
|
||||
isSubForm,
|
||||
|
|
@ -41,8 +42,9 @@ const CardItem = ({
|
|||
const [formData, setFormData] = useState(row)
|
||||
const refForm = useRef<FormDx>(null)
|
||||
const navigate = useNavigate()
|
||||
const { checkPermission } = usePermission()
|
||||
const { translate } = useLocalization()
|
||||
const { checkPermission } = usePermission()
|
||||
const isPwaMode = usePWA()
|
||||
|
||||
const keyField = gridDto.gridOptions.keyFieldName
|
||||
const rowId = row[keyField!]
|
||||
|
|
@ -204,6 +206,8 @@ const Card = (props: CardProps) => {
|
|||
const [searchText, setSearchText] = useState('')
|
||||
const [prevValue, setPrevValue] = useState('')
|
||||
const [loading, setLoading] = useState(false)
|
||||
const { checkPermission } = usePermission()
|
||||
const isPwaMode = usePWA()
|
||||
const [extraFilters, setExtraFilters] = useState<GridExtraFilterState[]>([])
|
||||
|
||||
const { states } = useStoreState((state) => state.base.lists)
|
||||
|
|
@ -355,7 +359,7 @@ const Card = (props: CardProps) => {
|
|||
<WidgetGroup widgetGroups={gridDto.widgets || []} />
|
||||
|
||||
<Container>
|
||||
<div className="p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 ">
|
||||
<div className="bg-white dark:bg-neutral-800 dark:border-neutral-700 ">
|
||||
<div className="flex justify-end items-center">
|
||||
<div className="relative py-1 flex gap-1 border-b-1">
|
||||
<FaSearch className="absolute left-2 top-1/2 -translate-y-1/2 text-gray-400 text-sm" />
|
||||
|
|
@ -444,6 +448,26 @@ const Card = (props: CardProps) => {
|
|||
>
|
||||
5
|
||||
</Button>
|
||||
|
||||
{checkPermission(gridDto?.gridOptions.permissionDto.u) && (
|
||||
<Button
|
||||
size="xs"
|
||||
variant={'default'}
|
||||
className="text-sm"
|
||||
onClick={() => {
|
||||
window.open(
|
||||
ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(
|
||||
':listFormCode',
|
||||
listFormCode,
|
||||
),
|
||||
isPwaMode ? '_self' : '_blank',
|
||||
)
|
||||
}}
|
||||
title="Form Manager"
|
||||
>
|
||||
<FaCog className="w-3 h-3" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { Container } from '@/components/shared'
|
|||
import { DX_CLASSNAMES } from '@/constants/app.constant'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import DxChart from 'devextreme-react/chart'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useParams, useSearchParams } from 'react-router-dom'
|
||||
import { useListFormCustomDataSource } from '@/shared/useListFormCustomDataSource'
|
||||
|
|
@ -13,7 +13,7 @@ import { usePermission } from '@/utils/hooks/usePermission'
|
|||
import { Button } from '@/components/ui'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { usePWA } from '@/utils/hooks/usePWA'
|
||||
import { FaInfoCircle, FaSyncAlt } from 'react-icons/fa'
|
||||
import { FaCog, FaSearch, FaSyncAlt } from 'react-icons/fa'
|
||||
import { buildSeriesDto } from './Utils'
|
||||
|
||||
interface ChartProps extends CommonProps, Meta {
|
||||
|
|
@ -39,13 +39,19 @@ const Chart = (props: ChartProps) => {
|
|||
const params = useParams()
|
||||
const _listFormCode = props?.listFormCode ?? params?.listFormCode ?? ''
|
||||
|
||||
const [searchText, setSearchText] = useState('')
|
||||
const [prevValue, setPrevValue] = useState('')
|
||||
const [urlSearchParams, setUrlSearchParams] = useState<URLSearchParams>(
|
||||
searchParams ? new URLSearchParams(searchParams) : new URLSearchParams(),
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (!gridDto) return
|
||||
|
||||
const dataSource = createSelectDataSource(
|
||||
gridDto.gridOptions,
|
||||
listFormCode,
|
||||
searchParams,
|
||||
urlSearchParams,
|
||||
[],
|
||||
true,
|
||||
)
|
||||
|
|
@ -94,7 +100,53 @@ const Chart = (props: ChartProps) => {
|
|||
}
|
||||
|
||||
setChartOptions(options)
|
||||
}, [gridDto, searchParams])
|
||||
}, [gridDto, searchParams, urlSearchParams])
|
||||
|
||||
const onFilter = useCallback(
|
||||
(value?: string) => {
|
||||
const text = value !== undefined ? value.trim() : searchText.trim()
|
||||
|
||||
if (!gridDto?.columnFormats) return
|
||||
|
||||
const newParams = new URLSearchParams(urlSearchParams.toString())
|
||||
|
||||
if (!text) {
|
||||
newParams.delete('filter')
|
||||
setUrlSearchParams(newParams)
|
||||
return
|
||||
}
|
||||
|
||||
const merged = gridDto.columnFormats
|
||||
.filter(
|
||||
(col) =>
|
||||
col.dataType === 'string' &&
|
||||
col.visible &&
|
||||
col.width &&
|
||||
col.allowSearch &&
|
||||
col.width > 0,
|
||||
)
|
||||
.map((col) => [col.fieldName, 'contains', text])
|
||||
|
||||
let filter: any = null
|
||||
if (merged.length === 1) {
|
||||
filter = merged[0]
|
||||
} else if (merged.length > 1) {
|
||||
filter = merged.reduce((acc, f, idx) => {
|
||||
if (idx === 0) return f
|
||||
return [acc, 'or', f]
|
||||
}, null as any)
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
newParams.set('filter', JSON.stringify(filter))
|
||||
} else {
|
||||
newParams.delete('filter')
|
||||
}
|
||||
|
||||
setUrlSearchParams(newParams)
|
||||
},
|
||||
[gridDto, urlSearchParams, searchText],
|
||||
)
|
||||
|
||||
return (
|
||||
<Container className={DX_CLASSNAMES}>
|
||||
|
|
@ -109,6 +161,32 @@ const Chart = (props: ChartProps) => {
|
|||
<div className="p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 h-full">
|
||||
<div className="flex justify-end items-center h-full">
|
||||
<div className="relative pb-1 flex gap-1 border-b-1">
|
||||
<FaSearch className="absolute left-2 top-1/2 -translate-y-1/2 text-gray-400 text-sm" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
value={searchText}
|
||||
onChange={(e) => setSearchText(e.target.value)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
onFilter(e.currentTarget.value)
|
||||
setPrevValue(e.currentTarget.value.trim()) // Enter ile tetiklenirse güncelle
|
||||
}
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
const newValue = e.currentTarget.value.trim()
|
||||
|
||||
// 1. Değer değişmemişse => hiçbir şey yapma
|
||||
if (newValue === prevValue) return
|
||||
|
||||
// 2. Yeni değer boş, ama eskiden değer vardı => filtre temizle
|
||||
// 3. Yeni değer dolu ve eskisinden farklı => filtre uygula
|
||||
onFilter(newValue)
|
||||
setPrevValue(newValue)
|
||||
}}
|
||||
className="p-1 pl-6 pr-2 border border-1 outline-none text-xs text-gray-700 dark:text-gray-200 placeholder-gray-400 rounded"
|
||||
/>
|
||||
|
||||
<Button
|
||||
size="xs"
|
||||
variant={'default'}
|
||||
|
|
@ -116,7 +194,7 @@ const Chart = (props: ChartProps) => {
|
|||
onClick={async () => {
|
||||
await props.refreshGridDto()
|
||||
}}
|
||||
title="Reset Grid State"
|
||||
title="Refresh Data"
|
||||
>
|
||||
<FaSyncAlt className="w-3 h-3" />
|
||||
</Button>
|
||||
|
|
@ -136,7 +214,7 @@ const Chart = (props: ChartProps) => {
|
|||
}}
|
||||
title="Form Manager"
|
||||
>
|
||||
<FaInfoCircle className="w-3 h-3" />
|
||||
<FaCog className="w-3 h-3" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,15 @@ import {
|
|||
import { useFilters } from './useFilters'
|
||||
import WidgetGroup from '@/components/common/WidgetGroup'
|
||||
import { Button } from '@/components/ui'
|
||||
import { FaInfoCircle, FaSyncAlt, FaTrash, FaTrashAlt } from 'react-icons/fa'
|
||||
import {
|
||||
FaCog,
|
||||
FaInfoCircle,
|
||||
FaSyncAlt,
|
||||
FaTimes,
|
||||
FaTrash,
|
||||
FaTrashAlt,
|
||||
FaUndo,
|
||||
} from 'react-icons/fa'
|
||||
import { usePermission } from '@/utils/hooks/usePermission'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { usePWA } from '@/utils/hooks/usePWA'
|
||||
|
|
@ -317,7 +325,7 @@ const Pivot = (props: PivotProps) => {
|
|||
onClick={clearPivotFilters}
|
||||
title="Remove Filter"
|
||||
>
|
||||
<FaTrash className="w-3 h-3" />
|
||||
<FaTimes className="w-3 h-3" />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
|
|
@ -327,7 +335,7 @@ const Pivot = (props: PivotProps) => {
|
|||
onClick={resetPivotGridState}
|
||||
title="Reset Grid State"
|
||||
>
|
||||
<FaSyncAlt className="w-3 h-3" />
|
||||
<FaUndo className="w-3 h-3" />
|
||||
</Button>
|
||||
|
||||
{checkPermission(gridDto?.gridOptions.permissionDto.u) && (
|
||||
|
|
@ -346,7 +354,7 @@ const Pivot = (props: PivotProps) => {
|
|||
}}
|
||||
title="Form Manager"
|
||||
>
|
||||
<FaInfoCircle className="w-3 h-3" />
|
||||
<FaCog className="w-3 h-3" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -129,15 +129,7 @@ const useFilters = ({
|
|||
menus.push({
|
||||
text: translate('::ListForms.ListForm.ResetGridState'),
|
||||
id: 'resetGridState',
|
||||
icon: 'refresh',
|
||||
})
|
||||
}
|
||||
|
||||
if (checkPermission(gridDto?.gridOptions.permissionDto.u)) {
|
||||
menus.push({
|
||||
text: translate('::ListForms.ListForm.Manage'),
|
||||
id: 'openManage',
|
||||
icon: 'preferences',
|
||||
icon: 'revert',
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -149,6 +141,14 @@ const useFilters = ({
|
|||
})
|
||||
}
|
||||
|
||||
if (checkPermission(gridDto?.gridOptions.permissionDto.u)) {
|
||||
menus.push({
|
||||
text: translate('::ListForms.ListForm.Manage'),
|
||||
id: 'openManage',
|
||||
icon: 'preferences',
|
||||
})
|
||||
}
|
||||
|
||||
if (checkPermission(gridDto?.gridOptions.permissionDto.e)) {
|
||||
items.push({
|
||||
locateInMenu: 'auto',
|
||||
|
|
@ -228,6 +228,7 @@ const useFilters = ({
|
|||
{
|
||||
text: translate('::ListForms.ListForm.GridMenu'),
|
||||
items: menus,
|
||||
icon: 'overflow',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue