From 1d36fc822550d6c6866dce0ac5e6d38e59cf2875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?= <76204082+iamsedatozturk@users.noreply.github.com> Date: Mon, 29 Sep 2025 11:33:51 +0300 Subject: [PATCH] =?UTF-8?q?Listeleri=20m=C3=BCkemmelle=C5=9Ftirme=20ikon?= =?UTF-8?q?=20vs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Seeds/SeederData.json | 2 +- .../Queries/SelectQueryManager.cs | 1 + ui/src/shared/useListFormColumns.ts | 16 +++- ui/src/views/list/Card.tsx | 32 ++++++- ui/src/views/list/Chart.tsx | 90 +++++++++++++++++-- ui/src/views/list/Pivot.tsx | 18 ++-- ui/src/views/list/useFilters.tsx | 19 ++-- 7 files changed, 151 insertions(+), 27 deletions(-) diff --git a/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json b/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json index 923715af..6219c3e2 100644 --- a/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json +++ b/api/src/Kurs.Platform.DbMigrator/Seeds/SeederData.json @@ -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", diff --git a/api/src/Kurs.Platform.Domain/Queries/SelectQueryManager.cs b/api/src/Kurs.Platform.Domain/Queries/SelectQueryManager.cs index 1829d290..aa597fac 100644 --- a/api/src/Kurs.Platform.Domain/Queries/SelectQueryManager.cs +++ b/api/src/Kurs.Platform.Domain/Queries/SelectQueryManager.cs @@ -806,6 +806,7 @@ public class SelectQueryManager : PlatformDomainService, ISelectQueryManager var sql = $@" SELECT {string.Join(", ", selectParts)} FROM [{listform.SelectCommand}] +{GetWhereString()} GROUP BY {argumentExpression}"; return sql; diff --git a/ui/src/shared/useListFormColumns.ts b/ui/src/shared/useListFormColumns.ts index 0aec2333..573bc63e 100644 --- a/ui/src/shared/useListFormColumns.ts +++ b/ui/src/shared/useListFormColumns.ts @@ -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) => { diff --git a/ui/src/views/list/Card.tsx b/ui/src/views/list/Card.tsx index 73c5d8d3..a24fdecc 100644 --- a/ui/src/views/list/Card.tsx +++ b/ui/src/views/list/Card.tsx @@ -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(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([]) const { states } = useStoreState((state) => state.base.lists) @@ -355,7 +359,7 @@ const Card = (props: CardProps) => { -
+
@@ -444,6 +448,26 @@ const Card = (props: CardProps) => { > 5 + + {checkPermission(gridDto?.gridOptions.permissionDto.u) && ( + + )}
diff --git a/ui/src/views/list/Chart.tsx b/ui/src/views/list/Chart.tsx index 95696ef3..e0d6f575 100644 --- a/ui/src/views/list/Chart.tsx +++ b/ui/src/views/list/Chart.tsx @@ -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( + 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 ( @@ -109,6 +161,32 @@ const Chart = (props: ChartProps) => {
+ + 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" + /> + @@ -136,7 +214,7 @@ const Chart = (props: ChartProps) => { }} title="Form Manager" > - + )}
diff --git a/ui/src/views/list/Pivot.tsx b/ui/src/views/list/Pivot.tsx index 289b4b16..6b8b8840 100644 --- a/ui/src/views/list/Pivot.tsx +++ b/ui/src/views/list/Pivot.tsx @@ -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' @@ -46,7 +54,7 @@ interface PivotProps { level?: number refreshData?: () => Promise gridDto?: GridDto - refreshGridDto: () => Promise + refreshGridDto: () => Promise } const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' // kullanici tanimli gridState ile islem gormus gridin paneline ait renk @@ -317,7 +325,7 @@ const Pivot = (props: PivotProps) => { onClick={clearPivotFilters} title="Remove Filter" > - + {checkPermission(gridDto?.gridOptions.permissionDto.u) && ( @@ -346,7 +354,7 @@ const Pivot = (props: PivotProps) => { }} title="Form Manager" > - + )}
diff --git a/ui/src/views/list/useFilters.tsx b/ui/src/views/list/useFilters.tsx index 6c923267..883bd8f2 100644 --- a/ui/src/views/list/useFilters.tsx +++ b/ui/src/views/list/useFilters.tsx @@ -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', }, ], },