ExtraFilterDto ControlType eklendi

This commit is contained in:
Sedat ÖZTÜRK 2025-09-18 09:56:04 +03:00
parent fef0623349
commit 6ae74813e0
10 changed files with 103 additions and 38 deletions

View file

@ -8,6 +8,7 @@ public class ExtraFilterDto
public string Caption { get; set; } public string Caption { get; set; }
public string Operator { get; set; } public string Operator { get; set; }
public string DefaultValue { get; set; } public string DefaultValue { get; set; }
public string ControlType { get; set; }
public List<ExtraFilterItemsDto> Items { get; set; } public List<ExtraFilterItemsDto> Items { get; set; }
} }

View file

@ -12292,6 +12292,12 @@
"en": "Default Value", "en": "Default Value",
"tr": "Varsayılan Değer" "tr": "Varsayılan Değer"
}, },
{
"resourceName": "Platform",
"key": "ListForms.ListFormEdit.ExtraControlType",
"en": "Control Type",
"tr": "Kontrol Türü"
},
{ {
"resourceName": "Platform", "resourceName": "Platform",
"key": "ListForms.ListFormEdit.ExtraSqlQuery", "key": "ListForms.ListFormEdit.ExtraSqlQuery",

View file

@ -9,6 +9,7 @@ public class ExtraFilter : ValueObject
public string Caption { get; set; } public string Caption { get; set; }
public string Operator { get; set; } public string Operator { get; set; }
public string DefaultValue { get; set; } public string DefaultValue { get; set; }
public string ControlType { get; set; }
public string SqlQuery { get; set; } public string SqlQuery { get; set; }
protected override IEnumerable<object> GetAtomicValues() protected override IEnumerable<object> GetAtomicValues()

View file

@ -82,3 +82,8 @@ export const ListFormEditTabs = {
Customization: 'customization', Customization: 'customization',
ExtraFilter: 'extraFilter', ExtraFilter: 'extraFilter',
} as const } as const
export const extraFilterControlTypeOptions = [
{ value: 'Select', label: 'Select' },
{ value: 'TextBox', label: 'TextBox' },
]

View file

@ -731,6 +731,7 @@ export interface ExtraFilterDto {
caption: string caption: string
operator: string operator: string
defaultValue?: string defaultValue?: string
controlType: string
items?: ExtraFilterItemsDto[] items?: ExtraFilterItemsDto[]
} }

View file

@ -58,6 +58,7 @@ function FormTabExtraFilters(props: { listFormCode: string }) {
<Th>{translate('::ListForms.ListFormEdit.ExtraCaption')}</Th> <Th>{translate('::ListForms.ListFormEdit.ExtraCaption')}</Th>
<Th>{translate('::ListForms.ListFormEdit.ExtraOperator')}</Th> <Th>{translate('::ListForms.ListFormEdit.ExtraOperator')}</Th>
<Th>{translate('::ListForms.ListFormEdit.ExtraDefaultValue')}</Th> <Th>{translate('::ListForms.ListFormEdit.ExtraDefaultValue')}</Th>
<Th>{translate('::ListForms.ListFormEdit.ExtraControlType')}</Th>
<Th>{translate('::ListForms.ListFormEdit.ExtraSqlQuery')}</Th> <Th>{translate('::ListForms.ListFormEdit.ExtraSqlQuery')}</Th>
</Tr> </Tr>
</THead> </THead>
@ -107,6 +108,7 @@ function FormTabExtraFilters(props: { listFormCode: string }) {
<Td>{row.caption}</Td> <Td>{row.caption}</Td>
<Td>{row.operator}</Td> <Td>{row.operator}</Td>
<Td>{row.defaultValue}</Td> <Td>{row.defaultValue}</Td>
<Td>{row.controlType}</Td>
<Td>{row.sqlQuery}</Td> <Td>{row.sqlQuery}</Td>
</Tr> </Tr>
))} ))}

View file

@ -8,7 +8,7 @@ import {
Select, Select,
toast, toast,
} from '@/components/ui' } from '@/components/ui'
import { ListFormJsonRowDto } from '@/proxy/admin/list-form/models' import { extraFilterControlTypeOptions, ListFormJsonRowDto } from '@/proxy/admin/list-form/models'
import { SelectBoxOption } from '@/shared/types' import { SelectBoxOption } from '@/shared/types'
import { useStoreActions, useStoreState } from '@/store' import { useStoreActions, useStoreState } from '@/store'
import { useLocalization } from '@/utils/hooks/useLocalization' import { useLocalization } from '@/utils/hooks/useLocalization'
@ -32,7 +32,12 @@ const schema = object().shape({
caption: string().required('Caption Required'), caption: string().required('Caption Required'),
operator: string().required('Operator Required'), operator: string().required('Operator Required'),
defaultValue: string(), defaultValue: string(),
sqlQuery: string().required('SQL Query Required'), controlType: string().required('Control Type Required'),
sqlQuery: string().when('controlType', {
is: (val: string) => val === 'Select',
then: (schema) => schema.required('SQL Query Required'),
otherwise: (schema) => schema.notRequired(),
}),
}) })
function JsonRowOpDialogExtraFilter({ function JsonRowOpDialogExtraFilter({
@ -48,27 +53,9 @@ function JsonRowOpDialogExtraFilter({
data: JsonRowDialogData | undefined data: JsonRowDialogData | undefined
setData: Dispatch<SetStateAction<JsonRowDialogData | undefined>> setData: Dispatch<SetStateAction<JsonRowDialogData | undefined>>
}) { }) {
const [permissionOptions, setPermissionOptions] = useState<SelectBoxOption[]>([])
const { translate } = useLocalization() const { translate } = useLocalization()
const permissions: Record<string, boolean> | undefined = useStoreState(
(state) => state.abpConfig.config?.auth.grantedPolicies,
)
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([]) const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
useEffect(() => {
if (permissions) {
setPermissionOptions(
Object.keys(permissions).map((key) => {
return {
value: key,
label: key,
}
}),
)
}
}, [permissions])
const { setJsonValue } = useStoreActions((a) => a.admin) const { setJsonValue } = useStoreActions((a) => a.admin)
const handleClose = async (e?: any) => { const handleClose = async (e?: any) => {
@ -147,6 +134,7 @@ function JsonRowOpDialogExtraFilter({
caption: '', caption: '',
operator: '=', operator: '=',
defaultValue: '', defaultValue: '',
controlType: 'Select',
sqlQuery: '', sqlQuery: '',
} }
} }
@ -260,6 +248,26 @@ function JsonRowOpDialogExtraFilter({
/> />
</FormItem> </FormItem>
<FormItem
label="Control Type"
invalid={errors.fieldName && touched.fieldName}
errorMessage={errors.fieldName}
>
<Field name="controlType">
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
options={extraFilterControlTypeOptions}
value={extraFilterControlTypeOptions.find(
(option: any) => option.value === values.controlType,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem <FormItem
label="Sql Query (Key, Value)" label="Sql Query (Key, Value)"
invalid={errors.sqlQuery && touched.sqlQuery} invalid={errors.sqlQuery && touched.sqlQuery}

View file

@ -533,6 +533,7 @@ const Grid = (props: GridProps) => {
gridDto.gridOptions.extraFilterDto.map((f) => ({ gridDto.gridOptions.extraFilterDto.map((f) => ({
fieldName: f.fieldName, fieldName: f.fieldName,
operator: f.operator, operator: f.operator,
controlType: f.controlType,
value: f.defaultValue ?? '', value: f.defaultValue ?? '',
})), })),
) )

View file

@ -4,6 +4,7 @@ import { ColumnFormatDto, GridBoxOptionsDto, TagBoxOptionsDto } from '../../prox
export interface GridExtraFilterState { export interface GridExtraFilterState {
fieldName: string fieldName: string
operator: string operator: string
controlType: string
value: string value: string
} }

View file

@ -1,4 +1,5 @@
import { GridExtraFilterState } from './GridColumnData' import { GridExtraFilterState } from './GridColumnData'
import { useState } from 'react'
export function GridExtraFilterToolbar({ export function GridExtraFilterToolbar({
filters, filters,
@ -9,31 +10,69 @@ export function GridExtraFilterToolbar({
extraFilters: GridExtraFilterState[] extraFilters: GridExtraFilterState[]
setExtraFilters: React.Dispatch<React.SetStateAction<GridExtraFilterState[]>> setExtraFilters: React.Dispatch<React.SetStateAction<GridExtraFilterState[]>>
}) { }) {
// input için geçici state tutuyoruz
const [inputValues, setInputValues] = useState<Record<string, string>>({})
return ( return (
<div className="flex gap-4"> <div className="flex gap-4">
{filters.map((fs) => { {filters.map((fs) => {
const current = extraFilters.find((f) => f.fieldName === fs.fieldName) const current = extraFilters.find((f) => f.fieldName === fs.fieldName)
const handleSave = (value: string) => {
setExtraFilters((prev) => {
const exists = prev.find((f) => f.fieldName === fs.fieldName)
if (exists) {
return prev.map((f) => (f.fieldName === fs.fieldName ? { ...f, value } : f))
}
return [
...prev,
{
fieldName: fs.fieldName,
operator: fs.operator,
controlType: fs.controlType,
value,
},
]
})
}
return ( return (
<div key={fs.fieldName} className="flex items-center gap-2"> <div key={fs.fieldName} className="flex items-center gap-2">
<label>{fs.caption}</label> <label>{fs.caption}</label>
{fs.controlType === 'Select' ? (
<select <select
className="border rounded px-0.5 py-0.5" className="border rounded px-0.5 py-0.5"
value={current?.value ?? ''} value={current?.value ?? ''}
onChange={(e) => onChange={(e) => handleSave(e.target.value)}
setExtraFilters((prev) =>
prev.map((f) =>
f.fieldName === fs.fieldName ? { ...f, value: e.target.value } : f,
),
)
}
> >
{!fs.defaultValue && <option value="">Seçiniz</option>} {!fs.defaultValue && <option value="">Seçiniz</option>}
{fs.items.map((item: any) => ( {fs.items?.map((item: any) => (
<option key={item.key} value={item.key}> <option key={item.key} value={item.key}>
{item.value} {item.value}
</option> </option>
))} ))}
</select> </select>
) : (
<input
type="text"
className="border rounded px-1 py-0.5"
value={inputValues[fs.fieldName] ?? current?.value ?? ''}
placeholder={fs.caption}
onChange={(e) =>
setInputValues((prev) => ({
...prev,
[fs.fieldName]: e.target.value,
}))
}
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleSave(inputValues[fs.fieldName] ?? '')
}
}}
onBlur={(e) => handleSave(e.target.value)}
/>
)}
</div> </div>
) )
})} })}