Widget düzenlemesi
This commit is contained in:
parent
4d9ae1563d
commit
533e937307
10 changed files with 127 additions and 39 deletions
|
|
@ -13,4 +13,5 @@ public class WidgetEditDto
|
|||
public string SubTitle { get; set; }
|
||||
public string OnClick { get; set; }
|
||||
public string ClassName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ public class WidgetDto
|
|||
public int ColSpan { get; set; }
|
||||
public string ClassName { get; set; }
|
||||
public List<WidgetItemDto> Items { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public class WidgetItemDto
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ public class ListFormSelectAppService : PlatformAppService, IListFormSelectAppSe
|
|||
if (!listForm.WidgetsJson.IsNullOrWhiteSpace())
|
||||
{
|
||||
var widgetList = JsonSerializer.Deserialize<WidgetEditDto[]>(listForm.WidgetsJson) ?? [];
|
||||
foreach (var widget in widgetList)
|
||||
foreach (var widget in widgetList.Where(w => w.IsActive))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(widget.SqlQuery))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4957,6 +4957,12 @@
|
|||
"en": "Value Class Name",
|
||||
"tr": "Değer Sütun Sınıf Adı"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "ListForms.ListFormEdit.WidgetStatus",
|
||||
"en": "Status",
|
||||
"tr": "Durum"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "ListForms.ListFormEdit.WidgetColor",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public class Widget : ValueObject
|
|||
public string SubTitle { get; set; }
|
||||
public string OnClick { get; set; }
|
||||
public string ClassName { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
protected override IEnumerable<object> GetAtomicValues()
|
||||
{
|
||||
|
|
@ -30,5 +31,6 @@ public class Widget : ValueObject
|
|||
yield return SubTitle;
|
||||
yield return OnClick;
|
||||
yield return ClassName;
|
||||
yield return IsActive;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -792,6 +792,7 @@ export interface WidgetGroupDto {
|
|||
colSpan?: number
|
||||
className?: string
|
||||
items: WidgetEditDto[]
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
export interface WidgetEditDto {
|
||||
|
|
@ -806,6 +807,7 @@ export interface WidgetEditDto {
|
|||
icon: string
|
||||
subTitle: string
|
||||
onClick: string
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
export interface LayoutDto {
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ function FormTabWidgets(props: { listFormCode: string }) {
|
|||
<Th>{translate('::ListForms.ListFormEdit.WidgetSqlQuery')}</Th>
|
||||
<Th>{translate('::ListForms.ListFormEdit.WidgetClassName')}</Th>
|
||||
<Th>{translate('::ListForms.ListFormEdit.WidgetValueClassName')}</Th>
|
||||
<Th>{translate('::ListForms.ListFormEdit.WidgetStatus')}</Th>
|
||||
</Tr>
|
||||
</THead>
|
||||
<TBody>
|
||||
|
|
@ -108,6 +109,7 @@ function FormTabWidgets(props: { listFormCode: string }) {
|
|||
<Td>{row.sqlQuery}</Td>
|
||||
<Td>{row.className}</Td>
|
||||
<Td>{row.valueClassName}</Td>
|
||||
<Td>{row.isActive ? 'Active' : 'Inactive'}</Td>
|
||||
</Tr>
|
||||
))}
|
||||
</TBody>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
Dialog,
|
||||
FormContainer,
|
||||
FormItem,
|
||||
|
|
@ -97,6 +98,7 @@ function JsonRowOpDialogWidget({
|
|||
icon: 'Icon',
|
||||
subTitle: 'SubTitle',
|
||||
onClick: '',
|
||||
isActive: false,
|
||||
}
|
||||
}
|
||||
validationSchema={schema}
|
||||
|
|
@ -137,40 +139,55 @@ function JsonRowOpDialogWidget({
|
|||
<Form>
|
||||
<FormContainer size="sm">
|
||||
<div className="h-full overflow-y-auto p-2">
|
||||
<FormItem
|
||||
label="Column Gap (Sütun Boşluğu)"
|
||||
invalid={errors.colGap && touched.colGap}
|
||||
errorMessage={errors.colGap}
|
||||
>
|
||||
<Field
|
||||
type="number"
|
||||
autoComplete="off"
|
||||
name="colGap"
|
||||
placeholder="Column Gap"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
<div className="grid grid-cols-3 gap-4">
|
||||
<FormItem
|
||||
label="Column Gap (Sütun Boşluğu)"
|
||||
invalid={errors.colGap && touched.colGap}
|
||||
errorMessage={errors.colGap}
|
||||
>
|
||||
<Field
|
||||
type="number"
|
||||
autoComplete="off"
|
||||
name="colGap"
|
||||
placeholder="Column Gap"
|
||||
component={Input}
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="Column Span (Sütun Genişliği)"
|
||||
invalid={errors.colSpan && touched.colSpan}
|
||||
errorMessage={errors.colSpan}
|
||||
>
|
||||
<Field type="text" autoComplete="off" name="colSpan" placeholder="colSpan">
|
||||
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||
<Select
|
||||
field={field}
|
||||
form={form}
|
||||
isClearable={true}
|
||||
options={colSpanOptions}
|
||||
value={colSpanOptions?.filter(
|
||||
(option: any) => option.value === values.colSpan,
|
||||
)}
|
||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="Column Span (Sütun Genişliği)"
|
||||
invalid={errors.colSpan && touched.colSpan}
|
||||
errorMessage={errors.colSpan}
|
||||
>
|
||||
<Field type="text" autoComplete="off" name="colSpan" placeholder="colSpan">
|
||||
{({ field, form }: FieldProps<SelectBoxOption>) => (
|
||||
<Select
|
||||
field={field}
|
||||
form={form}
|
||||
isClearable={true}
|
||||
options={colSpanOptions}
|
||||
value={colSpanOptions?.filter(
|
||||
(option: any) => option.value === values.colSpan,
|
||||
)}
|
||||
onChange={(option) => form.setFieldValue(field.name, option?.value)}
|
||||
/>
|
||||
)}
|
||||
</Field>
|
||||
</FormItem>
|
||||
|
||||
<FormItem
|
||||
label="IsActive"
|
||||
invalid={errors.isActive && touched.isActive}
|
||||
errorMessage={errors.isActive}
|
||||
>
|
||||
<Field
|
||||
autoComplete="off"
|
||||
name="isActive"
|
||||
placeholder="IsActive"
|
||||
component={Checkbox}
|
||||
/>
|
||||
</FormItem>
|
||||
</div>
|
||||
|
||||
<FormItem
|
||||
label="Sql Query"
|
||||
|
|
@ -183,7 +200,6 @@ function JsonRowOpDialogWidget({
|
|||
name="sqlQuery"
|
||||
placeholder="Sql Query"
|
||||
component={Input}
|
||||
rows={6}
|
||||
textArea={true}
|
||||
/>
|
||||
</FormItem>
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ const Grid = (props: GridProps) => {
|
|||
|
||||
const gridRef = useRef<DataGrid>()
|
||||
const refListFormCode = useRef('')
|
||||
const widgetGroupRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const [gridDataSource, setGridDataSource] = useState<CustomStore<any, any>>()
|
||||
const [columnData, setColumnData] = useState<GridColumnData[]>()
|
||||
|
|
@ -95,6 +96,7 @@ const Grid = (props: GridProps) => {
|
|||
const [extraFilters, setExtraFilters] = useState<GridExtraFilterState[]>([])
|
||||
const [gridDto, setGridDto] = useState<GridDto>()
|
||||
const [isPopupFullScreen, setIsPopupFullScreen] = useState(false)
|
||||
const [widgetGroupHeight, setWidgetGroupHeight] = useState(0)
|
||||
|
||||
const preloadExportLibs = () => {
|
||||
import('exceljs')
|
||||
|
|
@ -593,6 +595,29 @@ const Grid = (props: GridProps) => {
|
|||
gridRef.current.instance.option('stateStoring', stateStoring)
|
||||
}, [columnData])
|
||||
|
||||
// WidgetGroup yüksekliğini hesapla
|
||||
useEffect(() => {
|
||||
const calculateWidgetHeight = () => {
|
||||
if (widgetGroupRef.current) {
|
||||
const height = widgetGroupRef.current.offsetHeight
|
||||
setWidgetGroupHeight(height)
|
||||
}
|
||||
}
|
||||
|
||||
// İlk render'da hesapla
|
||||
calculateWidgetHeight()
|
||||
|
||||
// Resize durumunda tekrar hesapla
|
||||
const resizeObserver = new ResizeObserver(calculateWidgetHeight)
|
||||
if (widgetGroupRef.current) {
|
||||
resizeObserver.observe(widgetGroupRef.current)
|
||||
}
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
}, [gridDto?.widgets])
|
||||
|
||||
const onExporting = async (e: DataGridTypes.ExportingEvent) => {
|
||||
// DevExtreme’in varsayılan export davranışını iptal ediyoruz; kendi akışımızı çalıştıracağız
|
||||
e.cancel = true
|
||||
|
|
@ -663,7 +688,9 @@ const Grid = (props: GridProps) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<WidgetGroup widgetGroups={gridDto?.widgets ?? []} />
|
||||
<div ref={widgetGroupRef}>
|
||||
<WidgetGroup widgetGroups={gridDto?.widgets ?? []} />
|
||||
</div>
|
||||
|
||||
<Container className={DX_CLASSNAMES}>
|
||||
{!isSubForm && (
|
||||
|
|
@ -682,7 +709,10 @@ const Grid = (props: GridProps) => {
|
|||
//dataSource={gridDataSource}
|
||||
//remoteOperations={{ groupPaging: true }}
|
||||
//remoteOperations={false}
|
||||
height={gridDto.gridOptions.height || 'calc(100vh - 150px)'}
|
||||
height={
|
||||
gridDto.gridOptions.height ||
|
||||
`calc(100vh - ${170 + widgetGroupHeight}px)`
|
||||
}
|
||||
width={gridDto.gridOptions.width || '100%'}
|
||||
allowColumnResizing={gridDto.gridOptions.columnOptionDto?.allowColumnResizing}
|
||||
allowColumnReordering={gridDto.gridOptions.columnOptionDto?.allowColumnReordering}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ const Tree = (props: TreeProps) => {
|
|||
|
||||
const gridRef = useRef<TreeListDx>()
|
||||
const refListFormCode = useRef('')
|
||||
const widgetGroupRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const [treeListDataSource, setTreeListDataSource] = useState<CustomStore<any, any>>()
|
||||
const [columnData, setColumnData] = useState<GridColumnData[]>()
|
||||
|
|
@ -88,6 +89,8 @@ const Tree = (props: TreeProps) => {
|
|||
const [extraFilters, setExtraFilters] = useState<GridExtraFilterState[]>([])
|
||||
const [gridDto, setGridDto] = useState<GridDto>()
|
||||
const [isPopupFullScreen, setIsPopupFullScreen] = useState(false)
|
||||
const [widgetGroupHeight, setWidgetGroupHeight] = useState(0)
|
||||
|
||||
const [expandedRowKeys, setExpandedRowKeys] = useState<any[]>([])
|
||||
|
||||
const preloadExportLibs = () => {
|
||||
|
|
@ -435,6 +438,29 @@ const Tree = (props: TreeProps) => {
|
|||
}
|
||||
}, [listFormCode])
|
||||
|
||||
// WidgetGroup yüksekliğini hesapla
|
||||
useEffect(() => {
|
||||
const calculateWidgetHeight = () => {
|
||||
if (widgetGroupRef.current) {
|
||||
const height = widgetGroupRef.current.offsetHeight
|
||||
setWidgetGroupHeight(height)
|
||||
}
|
||||
}
|
||||
|
||||
// İlk render'da hesapla
|
||||
calculateWidgetHeight()
|
||||
|
||||
// Resize durumunda tekrar hesapla
|
||||
const resizeObserver = new ResizeObserver(calculateWidgetHeight)
|
||||
if (widgetGroupRef.current) {
|
||||
resizeObserver.observe(widgetGroupRef.current)
|
||||
}
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect()
|
||||
}
|
||||
}, [gridDto?.widgets])
|
||||
|
||||
useEffect(() => {
|
||||
if (!gridDto) {
|
||||
return
|
||||
|
|
@ -565,7 +591,9 @@ const Tree = (props: TreeProps) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<WidgetGroup widgetGroups={gridDto?.widgets ?? []} />
|
||||
<div ref={widgetGroupRef}>
|
||||
<WidgetGroup widgetGroups={gridDto?.widgets ?? []} />
|
||||
</div>
|
||||
|
||||
<Container className={DX_CLASSNAMES}>
|
||||
{!isSubForm && (
|
||||
|
|
@ -580,7 +608,7 @@ const Tree = (props: TreeProps) => {
|
|||
<TreeListDx
|
||||
ref={gridRef as any}
|
||||
id={'TreeList-' + listFormCode}
|
||||
height={gridDto.gridOptions.height || 'calc(100vh - 150px)'}
|
||||
height={gridDto.gridOptions.height || `calc(100vh - ${170 + widgetGroupHeight}px)`}
|
||||
width={gridDto.gridOptions.width || '100%'}
|
||||
dataStructure="plain"
|
||||
keyExpr={gridDto.gridOptions.treeOptionDto?.keyExpr}
|
||||
|
|
|
|||
Loading…
Reference in a new issue