Grid Widget güncellemesi

This commit is contained in:
Sedat ÖZTÜRK 2025-09-12 14:26:35 +03:00
parent b94719b925
commit 928894e5c5
14 changed files with 2100 additions and 1995 deletions

View file

@ -10,7 +10,7 @@ public class WidgetEditDto
public string ValueClassName { get; set; } = "text-3xl"; public string ValueClassName { get; set; } = "text-3xl";
public string Color { get; set; } public string Color { get; set; }
public string Icon { get; set; } public string Icon { get; set; }
public string Subtitle { get; set; } public string SubTitle { get; set; }
public string OnClick { get; set; } public string OnClick { get; set; }
public string ClassName { get; set; } public string ClassName { get; set; }
} }

View file

@ -4,6 +4,7 @@ public class WidgetDto
{ {
public int ColGap { get; set; } public int ColGap { get; set; }
public int ColSpan { get; set; } public int ColSpan { get; set; }
public string ClassName { get; set; }
public List<WidgetItemDto> Items { get; set; } public List<WidgetItemDto> Items { get; set; }
} }
@ -14,7 +15,6 @@ public class WidgetItemDto
public string ValueClassName { get; set; } = "text-3xl"; public string ValueClassName { get; set; } = "text-3xl";
public string Color { get; set; } public string Color { get; set; }
public string Icon { get; set; } public string Icon { get; set; }
public string Subtitle { get; set; } public string SubTitle { get; set; }
public string OnClick { get; set; } public string OnClick { get; set; }
public string ClassName { get; set; }
} }

View file

@ -228,6 +228,7 @@ public class ListFormSelectAppService : PlatformAppService, IListFormSelectAppSe
{ {
ColGap = widget.ColGap, ColGap = widget.ColGap,
ColSpan = widget.ColSpan, ColSpan = widget.ColSpan,
ClassName = widget.ClassName,
Items = [] Items = []
}; };
@ -244,9 +245,8 @@ public class ListFormSelectAppService : PlatformAppService, IListFormSelectAppSe
Value = dynamicItem.ContainsKey(widget.Value) ? dynamicItem[widget.Value]?.ToString() : string.Empty, Value = dynamicItem.ContainsKey(widget.Value) ? dynamicItem[widget.Value]?.ToString() : string.Empty,
Color = dynamicItem.ContainsKey(widget.Color) ? dynamicItem[widget.Color]?.ToString() : string.Empty, Color = dynamicItem.ContainsKey(widget.Color) ? dynamicItem[widget.Color]?.ToString() : string.Empty,
Icon = dynamicItem.ContainsKey(widget.Icon) ? dynamicItem[widget.Icon]?.ToString() : string.Empty, Icon = dynamicItem.ContainsKey(widget.Icon) ? dynamicItem[widget.Icon]?.ToString() : string.Empty,
Subtitle = dynamicItem.ContainsKey(widget.Subtitle) ? dynamicItem[widget.Subtitle]?.ToString() : string.Empty, SubTitle = dynamicItem.ContainsKey(widget.SubTitle) ? dynamicItem[widget.SubTitle]?.ToString() : string.Empty,
OnClick = dynamicItem.ContainsKey(widget.OnClick) ? dynamicItem[widget.OnClick]?.ToString() : string.Empty, OnClick = dynamicItem.ContainsKey(widget.OnClick) ? dynamicItem[widget.OnClick]?.ToString() : string.Empty,
ClassName = dynamicItem.ContainsKey(widget.ClassName) ? dynamicItem[widget.ClassName]?.ToString() : string.Empty,
}); });
} }
} }

View file

@ -13,7 +13,7 @@ public class Widget : ValueObject
public string ValueClassName { get; set; } = "text-3xl"; public string ValueClassName { get; set; } = "text-3xl";
public string Color { get; set; } public string Color { get; set; }
public string Icon { get; set; } public string Icon { get; set; }
public string Subtitle { get; set; } public string SubTitle { get; set; }
public string OnClick { get; set; } public string OnClick { get; set; }
public string ClassName { get; set; } public string ClassName { get; set; }
@ -27,7 +27,7 @@ public class Widget : ValueObject
yield return ValueClassName; yield return ValueClassName;
yield return Color; yield return Color;
yield return Icon; yield return Icon;
yield return Subtitle; yield return SubTitle;
yield return OnClick; yield return OnClick;
yield return ClassName; yield return ClassName;
} }

View file

@ -82,7 +82,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
"revision": "3ca0b8505b4bec776b69afdba2768812" "revision": "3ca0b8505b4bec776b69afdba2768812"
}, { }, {
"url": "index.html", "url": "index.html",
"revision": "0.buc1mitnpmo" "revision": "0.h9qpsacvko"
}], {}); }], {});
workbox.cleanupOutdatedCaches(); workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

View file

@ -18,9 +18,9 @@ interface WidgetProps {
title: string title: string
value: string | number value: string | number
valueClassName?: string valueClassName?: string
color: colorType color?: colorType
icon: (typeof iconList)[number] icon?: (typeof iconList)[number]
subtitle?: string subTitle?: string
onClick?: () => void onClick?: () => void
className?: string className?: string
} }
@ -29,9 +29,9 @@ export default function Widget({
title, title,
value, value,
valueClassName = 'text-3xl', valueClassName = 'text-3xl',
color, color = 'blue',
icon, icon = 'FaChartBar',
subtitle, subTitle = '-',
onClick, onClick,
className, className,
}: WidgetProps) { }: WidgetProps) {
@ -42,7 +42,7 @@ export default function Widget({
useEffect(() => { useEffect(() => {
let isMounted = true let isMounted = true
import('react-icons/fa').then((icons) => { import('react-icons/fa').then((icons) => {
if (isMounted && icon in icons) { if (isMounted && icon && icon in icons) {
setIconComponent(() => (icons as any)[icon]) setIconComponent(() => (icons as any)[icon])
} }
}) })
@ -64,6 +64,8 @@ export default function Widget({
orange: { bg: 'from-orange-100 to-orange-200', text: 'text-orange-600' }, orange: { bg: 'from-orange-100 to-orange-200', text: 'text-orange-600' },
} }
const safeColor = color && colorMap[color] ? color : 'green'
return ( return (
<div <div
onClick={onClick} onClick={onClick}
@ -76,13 +78,15 @@ export default function Widget({
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div> <div>
<p className="text-sm font-semibold text-gray-600 uppercase tracking-wide">{title}</p> <p className="text-sm font-semibold text-gray-600 uppercase tracking-wide">{title}</p>
<p className={`${valueClassName} font-bold mt-1 ${colorMap[color].text}`}>{value}</p> <p className={`${valueClassName} font-bold mt-1 ${colorMap[safeColor].text}`}>{value}</p>
{subtitle && <p className="text-sm text-gray-500 mt-1">{subtitle}</p>} <p className="text-sm text-gray-500 mt-1">{subTitle}</p>
</div> </div>
<div <div
className={`w-12 h-12 bg-gradient-to-br ${colorMap[color].bg} rounded-xl flex items-center justify-center shadow-sm`} className={`w-12 h-12 bg-gradient-to-br ${colorMap[safeColor].bg} rounded-xl flex items-center justify-center shadow-sm`}
> >
{IconComponent ? <IconComponent className={`w-6 h-6 ${colorMap[color].text}`} /> : null} {IconComponent ? (
<IconComponent className={`w-6 h-6 ${colorMap[safeColor].text}`} />
) : null}
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,29 +1,30 @@
import classNames from 'classnames' import classNames from 'classnames'
import Widget, { type colorType } from './Widget' import Widget, { type colorType } from './Widget'
import { WidgetEditDto } from '@/proxy/form/models' import { WidgetEditDto, WidgetGroupDto } from '@/proxy/form/models'
interface WidgetGroup { export default function WidgetGroup({ widgetGroups }: { widgetGroups: WidgetGroupDto[] }) {
colGap?: number return (
colSpan?: number <div>
items: WidgetEditDto[] {widgetGroups.map((group, gIdx) => (
} <div
key={gIdx}
export default function WidgetGroup(widgets: WidgetGroup[]) { className={classNames(`grid grid-cols-12 gap-${group.colGap} ${group.className || ''}`)}
return widgets.map((group, gIdx) => ( >
<div key={gIdx} className={classNames(`grid grid-cols-12 gap-${group.colGap ?? 4}`)}> {group.items.map((item: WidgetEditDto, order: number) => (
{group.items.map((item: WidgetEditDto, order: number) => ( <div key={`${gIdx}-${order}`} className={classNames(`col-span-${group.colSpan}`)}>
<div key={`${gIdx}-${order}`} className={classNames(`col-span-${group.colSpan ?? 3}`)}> <Widget
<Widget title={item.title}
title={item.title} value={item.value}
value={item.value} color={item.color as colorType}
color={item.color as colorType} icon={item.icon}
icon={item.icon ?? 'FaChartBar'} subTitle={item.subTitle}
subtitle={item.subTitle} valueClassName={item.valueClassName}
valueClassName={item.valueClassName} onClick={eval(item.onClick)}
onClick={() => item.onClick} />
/> </div>
))}
</div> </div>
))} ))}
</div> </div>
)) )
} }

File diff suppressed because it is too large Load diff

View file

@ -702,10 +702,18 @@ export enum ColumnSortDirectionEnum {
'Desc' = 'desc', 'Desc' = 'desc',
} }
export interface WidgetGroupDto {
colGap?: number
colSpan?: number
className?: string
items: WidgetEditDto[]
}
export interface WidgetEditDto { export interface WidgetEditDto {
colGap: number colGap: number
colSpan: number colSpan: number
sqlQuery?: string sqlQuery?: string
className?: string
title: string title: string
value: string value: string
valueClassName: string valueClassName: string
@ -713,5 +721,4 @@ export interface WidgetEditDto {
icon: string icon: string
subTitle: string subTitle: string
onClick: string onClick: string
className: string
} }

View file

@ -1,9 +1,9 @@
import DataGrid from 'devextreme-react/data-grid' import DataGrid from 'devextreme-react/data-grid'
import PivotGrid from 'devextreme-react/pivot-grid' import PivotGrid from 'devextreme-react/pivot-grid'
import CustomStore from 'devextreme/data/custom_store' import CustomStore from 'devextreme/data/custom_store'
import { MutableRefObject, useCallback } from 'react' import { MutableRefObject, useCallback, useState } from 'react'
import { getLoadOptions, getServiceAddress, setGridPanelColor } from '../views/list/Utils' import { getLoadOptions, getServiceAddress, setGridPanelColor } from '../views/list/Utils'
import { GridOptionsDto } from '../proxy/form/models' import { GridOptionsDto, WidgetGroupDto } from '../proxy/form/models'
import { GridColumnData } from '../views/list/GridColumnData' import { GridColumnData } from '../views/list/GridColumnData'
import { dynamicFetch } from '../services/form.service' import { dynamicFetch } from '../services/form.service'
import { MULTIVALUE_DELIMITER } from '../constants/app.constant' import { MULTIVALUE_DELIMITER } from '../constants/app.constant'
@ -23,6 +23,7 @@ const useListFormCustomDataSource = ({
listFormCode: string, listFormCode: string,
searchParams?: URLSearchParams, searchParams?: URLSearchParams,
cols?: GridColumnData[], cols?: GridColumnData[],
setWidgetGroups?: (widgetGroups: WidgetGroupDto[]) => void,
) => { ) => {
return new CustomStore({ return new CustomStore({
key: gridOptions.keyFieldName, key: gridOptions.keyFieldName,
@ -71,6 +72,8 @@ const useListFormCustomDataSource = ({
parameters.filter = JSON.stringify(parameters.filter) parameters.filter = JSON.stringify(parameters.filter)
const response = await dynamicFetch('list-form-select/select', 'GET', parameters) const response = await dynamicFetch('list-form-select/select', 'GET', parameters)
if (setWidgetGroups) setWidgetGroups(response.data.widgets ?? [])
// Column format multiValue ise, gelen stringi array yapmaliyiz // Column format multiValue ise, gelen stringi array yapmaliyiz
if (columns) { if (columns) {
columns.forEach((col: any) => { columns.forEach((col: any) => {
@ -123,6 +126,7 @@ const useListFormCustomDataSource = ({
totalCount: response.data.totalCount, totalCount: response.data.totalCount,
summary: response.data.summary, summary: response.data.summary,
groupCount: response.data.groupCount, groupCount: response.data.groupCount,
widgets: response.data.widgets,
} }
return retValue return retValue
} catch (error: any) { } catch (error: any) {

View file

@ -9,7 +9,7 @@ import { ListFormEditTabs } from '@/proxy/admin/list-form/models'
import { useStoreState } from '@/store' import { useStoreState } from '@/store'
import { useLocalization } from '@/utils/hooks/useLocalization' import { useLocalization } from '@/utils/hooks/useLocalization'
import { useState } from 'react' import { useState } from 'react'
import { FaEdit, FaFileMedical, FaTrash } from 'react-icons/fa'; import { FaEdit, FaFileMedical, FaTrash } from 'react-icons/fa'
import JsonRowOpDialogEditForm from './json-row-operations/JsonRowOpDialogEditForm' import JsonRowOpDialogEditForm from './json-row-operations/JsonRowOpDialogEditForm'
import { JsonRowDialogData } from './json-row-operations/types' import { JsonRowDialogData } from './json-row-operations/types'
import JsonRowOpDialogWidget from './json-row-operations/JsonRowOpDialogWidget' import JsonRowOpDialogWidget from './json-row-operations/JsonRowOpDialogWidget'
@ -58,14 +58,14 @@ function FormTabWidgets(props: { listFormCode: string }) {
<Th>{translate('::ListForms.ListFormEdit.WidgetColGap')}</Th> <Th>{translate('::ListForms.ListFormEdit.WidgetColGap')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetColSpan')}</Th> <Th>{translate('::ListForms.ListFormEdit.WidgetColSpan')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetSqlQuery')}</Th> <Th>{translate('::ListForms.ListFormEdit.WidgetSqlQuery')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetClassName')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetValueClassName')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetTitle')}</Th> <Th>{translate('::ListForms.ListFormEdit.WidgetTitle')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetValue')}</Th> <Th>{translate('::ListForms.ListFormEdit.WidgetValue')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetValueClassName')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetColor')}</Th> <Th>{translate('::ListForms.ListFormEdit.WidgetColor')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetIcon')}</Th> <Th>{translate('::ListForms.ListFormEdit.WidgetIcon')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetSubtitle')}</Th> <Th>{translate('::ListForms.ListFormEdit.WidgetSubtitle')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetOnClick')}</Th> <Th>{translate('::ListForms.ListFormEdit.WidgetOnClick')}</Th>
<Th>{translate('::ListForms.ListFormEdit.WidgetClassName')}</Th>
</Tr> </Tr>
</THead> </THead>
<TBody> <TBody>
@ -113,14 +113,14 @@ function FormTabWidgets(props: { listFormCode: string }) {
<Td>{row.colGap}</Td> <Td>{row.colGap}</Td>
<Td>{row.colSpan}</Td> <Td>{row.colSpan}</Td>
<Td>{row.sqlQuery}</Td> <Td>{row.sqlQuery}</Td>
<Td>{row.className}</Td>
<Td>{row.valueClassName}</Td>
<Td>{row.title}</Td> <Td>{row.title}</Td>
<Td>{row.value}</Td> <Td>{row.value}</Td>
<Td>{row.valueClassName}</Td>
<Td>{row.color}</Td> <Td>{row.color}</Td>
<Td>{row.icon}</Td> <Td>{row.icon}</Td>
<Td>{row.subTitle}</Td> <Td>{row.subTitle}</Td>
<Td>{row.onClick}</Td> <Td>{row.onClick}</Td>
<Td>{row.className}</Td>
</Tr> </Tr>
))} ))}
</TBody> </TBody>

View file

@ -5,13 +5,14 @@ import {
FormItem, FormItem,
Input, Input,
Notification, Notification,
Select,
toast, toast,
} from '@/components/ui' } from '@/components/ui'
import { ListFormJsonRowDto } from '@/proxy/admin/list-form/models' import { 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'
import { Field, Form, Formik } from 'formik' import { Field, FieldProps, Form, Formik } from 'formik'
import { Dispatch, SetStateAction, useEffect, useState } from 'react' import { Dispatch, SetStateAction, useEffect, useState } from 'react'
import { number, object, string } from 'yup' import { number, object, string } from 'yup'
import { JsonRowDialogData } from './types' import { JsonRowDialogData } from './types'
@ -21,6 +22,7 @@ import {
postListFormJsonRow, postListFormJsonRow,
putListFormJsonRow, putListFormJsonRow,
} from '@/services/admin/list-form.service' } from '@/services/admin/list-form.service'
import { colSpanOptions } from '../options'
const schema = object().shape({ const schema = object().shape({
colGap: number().required('Column Gap Required'), colGap: number().required('Column Gap Required'),
@ -103,15 +105,15 @@ function JsonRowOpDialogWidget({
data.widgetValues ?? { data.widgetValues ?? {
colGap: 0, colGap: 0,
colSpan: 0, colSpan: 0,
sqlQuery: '',
title: '',
value: '',
valueClassName: '',
color: '',
icon: '',
subTitle: '',
onClick: '',
className: '', className: '',
sqlQuery: '',
title: 'Title',
value: 'Value',
valueClassName: '',
color: 'Color',
icon: 'Icon',
subTitle: 'SubTitle',
onClick: '',
} }
} }
validationSchema={schema} validationSchema={schema}
@ -153,31 +155,38 @@ function JsonRowOpDialogWidget({
<FormContainer size="sm"> <FormContainer size="sm">
<div className="max-h-96 overflow-y-auto p-2"> <div className="max-h-96 overflow-y-auto p-2">
<FormItem <FormItem
label="Column Gap" label="Column Gap (Sütun Boşluğu)"
invalid={errors.colGap && touched.colGap} invalid={errors.colGap && touched.colGap}
errorMessage={errors.colGap} errorMessage={errors.colGap}
> >
<Field <Field
type="text" type="number"
autoComplete="off" autoComplete="off"
name="colGap" name="colGap"
placeholder="Column Gap" placeholder="Column Gap"
component={Input} component={Input}
/> />
</FormItem> </FormItem>
<FormItem <FormItem
label="Column Span" label="Column Span (Sütun Genişliği)"
invalid={errors.colSpan && touched.colSpan} invalid={errors.colSpan && touched.colSpan}
errorMessage={errors.colSpan} errorMessage={errors.colSpan}
> >
<Field <Field type="text" autoComplete="off" name="colSpan" placeholder="colSpan">
type="text" {({ field, form }: FieldProps<SelectBoxOption>) => (
autoComplete="off" <Select
name="colSpan" field={field}
placeholder="Column Span" form={form}
component={Input} isClearable={true}
/> options={colSpanOptions}
value={colSpanOptions?.filter(
(option: any) => option.value === values.colSpan,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem> </FormItem>
<FormItem <FormItem
@ -191,6 +200,36 @@ function JsonRowOpDialogWidget({
name="sqlQuery" name="sqlQuery"
placeholder="Sql Query" placeholder="Sql Query"
component={Input} component={Input}
rows={6}
textArea={true}
/>
</FormItem>
<FormItem
label="Class Name"
invalid={errors.className && touched.className}
errorMessage={errors.className}
>
<Field
type="text"
autoComplete="off"
name="className"
placeholder="Class Name"
component={Input}
/>
</FormItem>
<FormItem
label="Value Class Name"
invalid={errors.valueClassName && touched.valueClassName}
errorMessage={errors.valueClassName}
>
<Field
type="text"
autoComplete="off"
name="valueClassName"
placeholder="Value Class Name"
component={Input}
/> />
</FormItem> </FormItem>
@ -223,21 +262,7 @@ function JsonRowOpDialogWidget({
</FormItem> </FormItem>
<FormItem <FormItem
label="Value Class Name" label="Color Field"
invalid={errors.valueClassName && touched.valueClassName}
errorMessage={errors.valueClassName}
>
<Field
type="text"
autoComplete="off"
name="valueClassName"
placeholder="Value Class Name"
component={Input}
/>
</FormItem>
<FormItem
label="Color"
invalid={errors.color && touched.color} invalid={errors.color && touched.color}
errorMessage={errors.color} errorMessage={errors.color}
> >
@ -251,7 +276,7 @@ function JsonRowOpDialogWidget({
</FormItem> </FormItem>
<FormItem <FormItem
label="Icon" label="Icon Field"
invalid={errors.icon && touched.icon} invalid={errors.icon && touched.icon}
errorMessage={errors.icon} errorMessage={errors.icon}
> >
@ -264,6 +289,48 @@ function JsonRowOpDialogWidget({
/> />
</FormItem> </FormItem>
{/* <FormItem
label="Color"
invalid={errors.color && touched.color}
errorMessage={errors.color}
>
<Field type="text" autoComplete="off" name="color" placeholder="Color">
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={widgetColorOptions}
value={widgetColorOptions?.filter(
(option: any) => option.value === values.color,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label="Icon"
invalid={errors.icon && touched.icon}
errorMessage={errors.icon}
>
<Field type="text" autoComplete="off" name="icon" placeholder="Icon">
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={widgetIconOptions}
value={widgetIconOptions?.filter(
(option: any) => option.value === values.icon,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem> */}
<FormItem <FormItem
label="Sub Title" label="Sub Title"
invalid={errors.subTitle && touched.subTitle} invalid={errors.subTitle && touched.subTitle}
@ -272,7 +339,7 @@ function JsonRowOpDialogWidget({
<Field <Field
type="text" type="text"
autoComplete="off" autoComplete="off"
name="subtitle" name="subTitle"
placeholder="Sub Title" placeholder="Sub Title"
component={Input} component={Input}
/> />
@ -291,21 +358,6 @@ function JsonRowOpDialogWidget({
component={Input} component={Input}
/> />
</FormItem> </FormItem>
<FormItem
label="Class Name"
invalid={errors.className && touched.className}
errorMessage={errors.className}
>
<Field
type="text"
autoComplete="off"
name="className"
placeholder="Class Name"
component={Input}
/>
</FormItem>
</div> </div>
<div className="text-right mt-4"> <div className="text-right mt-4">
<Button className="ltr:mr-2 rtl:ml-2" variant="plain" onClick={handleClose}> <Button className="ltr:mr-2 rtl:ml-2" variant="plain" onClick={handleClose}>

View file

@ -25,6 +25,8 @@ import {
GridColumnJoinTypeListEnum, GridColumnJoinTypeListEnum,
} from '../../../../proxy/admin/list-form-field/models' } from '../../../../proxy/admin/list-form-field/models'
import { enumToList } from '../../../../utils/enumUtils' import { enumToList } from '../../../../utils/enumUtils'
import { colSpan, iconList, WidgetColorEnum } from '@/components/ui/Widget/iconList'
import { SelectBoxOption } from '@/shared/types'
export const sortModeOptions = [ export const sortModeOptions = [
{ value: 'none', label: 'None' }, { value: 'none', label: 'None' },
@ -216,3 +218,13 @@ export const cascadeFilterOperator = enumToList<string>(ColumnCascadeFilterOpera
export const pivotSettingsAreaOptions = enumToList<string>(PivotSettingsAreaEnum) export const pivotSettingsAreaOptions = enumToList<string>(PivotSettingsAreaEnum)
export const pivotSettingsGroupIntervalOptions = enumToList<string>(PivotSettingsGroupIntervalEnum) export const pivotSettingsGroupIntervalOptions = enumToList<string>(PivotSettingsGroupIntervalEnum)
export const pivotSortDirectionOptions = enumToList<string>(ColumnSortDirectionEnum) export const pivotSortDirectionOptions = enumToList<string>(ColumnSortDirectionEnum)
export const widgetColorOptions = enumToList<string>(WidgetColorEnum)
export const widgetIconOptions = iconList.map((icon) => ({
value: icon,
label: icon,
}))
export const colSpanOptions = colSpan.map((span) => ({
value: span,
label: span,
}))

View file

@ -7,6 +7,7 @@ import {
GridDto, GridDto,
ListFormCustomizationTypeEnum, ListFormCustomizationTypeEnum,
PlatformEditorTypes, PlatformEditorTypes,
WidgetGroupDto,
} from '@/proxy/form/models' } from '@/proxy/form/models'
import { getList } from '@/services/form.service' import { getList } from '@/services/form.service'
import { import {
@ -64,6 +65,7 @@ import { TagBoxEditorComponent } from './editors/TagBoxEditorComponent'
import { useFilters } from './useFilters' import { useFilters } from './useFilters'
import { useToolbar } from './useToolbar' import { useToolbar } from './useToolbar'
import { ImportDashboard } from '@/components/importManager/ImportDashboard' import { ImportDashboard } from '@/components/importManager/ImportDashboard'
import WidgetGroup from '@/components/ui/Widget/WidgetGroup'
interface GridProps { interface GridProps {
listFormCode: string listFormCode: string
@ -88,6 +90,7 @@ const Grid = (props: GridProps) => {
const [columnData, setColumnData] = useState<GridColumnData[]>() const [columnData, setColumnData] = useState<GridColumnData[]>()
const [formData, setFormData] = useState<any>() const [formData, setFormData] = useState<any>()
const [mode, setMode] = useState<RowMode>('view') const [mode, setMode] = useState<RowMode>('view')
const [widgetGroups, setWidgetGroups] = useState<WidgetGroupDto[]>([])
const preloadExportLibs = () => { const preloadExportLibs = () => {
import('exceljs') import('exceljs')
@ -404,7 +407,9 @@ const Grid = (props: GridProps) => {
listFormCode, listFormCode,
searchParams, searchParams,
cols, cols,
setWidgetGroups,
) )
setGridDataSource(dataSource) setGridDataSource(dataSource)
}, [gridDto, searchParams]) }, [gridDto, searchParams])
@ -503,271 +508,275 @@ const Grid = (props: GridProps) => {
} }
return ( return (
<Container className={DX_CLASSNAMES}> <>
{!isSubForm && ( <WidgetGroup widgetGroups={widgetGroups} />
<Helmet
titleTemplate="%s | Kurs Platform"
title={translate('::' + gridDto?.gridOptions.title)}
defaultTitle="Kurs Platform"
></Helmet>
)}
{gridDto && columnData && (
<>
<DataGrid
ref={gridRef as any}
id={'Grid-' + listFormCode}
//dataSource={gridDataSource}
//remoteOperations={{ groupPaging: true }}
//remoteOperations={false}
height={gridDto.gridOptions.height || '100%'}
width={gridDto.gridOptions.width || '100%'}
allowColumnResizing={gridDto.gridOptions.columnOptionDto?.allowColumnResizing}
allowColumnReordering={gridDto.gridOptions.columnOptionDto?.allowColumnReordering}
showBorders={gridDto.gridOptions.columnOptionDto?.showBorders}
showRowLines={gridDto.gridOptions.columnOptionDto?.showRowLines}
showColumnLines={gridDto.gridOptions.columnOptionDto?.showColumnLines}
columnResizingMode={gridDto.gridOptions.columnOptionDto?.columnResizingMode}
columnAutoWidth={gridDto.gridOptions.columnOptionDto?.columnAutoWidth}
rtlEnabled={gridDto.gridOptions.columnOptionDto?.rtlEnabled}
rowAlternationEnabled={gridDto.gridOptions.columnOptionDto?.rowAlternationEnabled}
hoverStateEnabled={gridDto.gridOptions.columnOptionDto?.hoverStateEnabled}
columnHidingEnabled={gridDto.gridOptions.columnOptionDto?.columnHidingEnabled}
focusedRowEnabled={gridDto.gridOptions.columnOptionDto?.focusedRowEnabled}
showColumnHeaders={gridDto.gridOptions.columnOptionDto?.showColumnHeaders}
filterSyncEnabled={true}
onSelectionChanged={onSelectionChanged}
onInitNewRow={onInitNewRow}
onCellPrepared={onCellPrepared}
onRowInserting={onRowInserting}
onRowUpdating={onRowUpdating}
onEditingStart={onEditingStart}
onDataErrorOccurred={onDataErrorOccurred}
onExporting={onExporting}
onEditCanceled={() => {
setMode('view')
}}
onSaved={() => {
setMode('view')
}}
onRowInserted={() => {
props.refreshData?.()
}}
onRowUpdated={() => {
props.refreshData?.()
}}
onRowRemoved={() => {
props.refreshData?.()
}}
>
<Export
enabled={true}
allowExportSelectedData={false}
formats={['pdf', 'xlsx', 'csv']}
/>
<Editing
refreshMode={gridDto.gridOptions.editingOptionDto?.refreshMode}
mode={smaller.md ? 'form' : gridDto.gridOptions.editingOptionDto?.mode}
allowDeleting={gridDto.gridOptions.editingOptionDto?.allowDeleting}
allowUpdating={gridDto.gridOptions.editingOptionDto?.allowUpdating}
allowAdding={gridDto.gridOptions.editingOptionDto?.allowAdding}
useIcons={gridDto.gridOptions.editingOptionDto?.useIcons}
confirmDelete={gridDto.gridOptions.editingOptionDto?.confirmDelete}
newRowPosition={gridDto.gridOptions.editingOptionDto?.newRowPosition}
selectTextOnEditStart={gridDto.gridOptions.editingOptionDto?.selectTextOnEditStart}
startEditAction={gridDto.gridOptions.editingOptionDto?.startEditAction}
popup={{
title: gridDto.gridOptions.editingOptionDto?.popup?.title,
showTitle: gridDto.gridOptions.editingOptionDto?.popup?.showTitle,
hideOnOutsideClick: gridDto.gridOptions.editingOptionDto?.popup?.hideOnOutsideClick,
width: gridDto.gridOptions.editingOptionDto?.popup?.width,
height: gridDto.gridOptions.editingOptionDto?.popup?.height,
fullScreen: gridDto.gridOptions.editingOptionDto?.popup?.fullScreen,
}}
form={{
items:
gridDto.gridOptions.editingFormDto?.length > 0
? gridDto.gridOptions.editingFormDto
?.sort((a: any, b: any) => {
return a.order >= b.order ? 1 : -1
})
.map((e: any) => {
return {
itemType: e.itemType,
colCount: e.colCount,
colSpan: e.colSpan,
caption: e.caption,
items: e.items
?.sort((a: any, b: any) => {
return a.order >= b.order ? 1 : -1
})
.map((i: EditingFormItemDto) => {
let editorOptions = {}
try {
editorOptions = i.editorOptions && JSON.parse(i.editorOptions)
// Eğer default value varsa, bu editörü readonly yapıyoruz <Container className={DX_CLASSNAMES}>
if (searchParams?.has(i.dataField)) { {!isSubForm && (
<Helmet
titleTemplate="%s | Kurs Platform"
title={translate('::' + gridDto?.gridOptions.title)}
defaultTitle="Kurs Platform"
></Helmet>
)}
{gridDto && columnData && (
<>
<DataGrid
ref={gridRef as any}
id={'Grid-' + listFormCode}
//dataSource={gridDataSource}
//remoteOperations={{ groupPaging: true }}
//remoteOperations={false}
height={gridDto.gridOptions.height || '100%'}
width={gridDto.gridOptions.width || '100%'}
allowColumnResizing={gridDto.gridOptions.columnOptionDto?.allowColumnResizing}
allowColumnReordering={gridDto.gridOptions.columnOptionDto?.allowColumnReordering}
showBorders={gridDto.gridOptions.columnOptionDto?.showBorders}
showRowLines={gridDto.gridOptions.columnOptionDto?.showRowLines}
showColumnLines={gridDto.gridOptions.columnOptionDto?.showColumnLines}
columnResizingMode={gridDto.gridOptions.columnOptionDto?.columnResizingMode}
columnAutoWidth={gridDto.gridOptions.columnOptionDto?.columnAutoWidth}
rtlEnabled={gridDto.gridOptions.columnOptionDto?.rtlEnabled}
rowAlternationEnabled={gridDto.gridOptions.columnOptionDto?.rowAlternationEnabled}
hoverStateEnabled={gridDto.gridOptions.columnOptionDto?.hoverStateEnabled}
columnHidingEnabled={gridDto.gridOptions.columnOptionDto?.columnHidingEnabled}
focusedRowEnabled={gridDto.gridOptions.columnOptionDto?.focusedRowEnabled}
showColumnHeaders={gridDto.gridOptions.columnOptionDto?.showColumnHeaders}
filterSyncEnabled={true}
onSelectionChanged={onSelectionChanged}
onInitNewRow={onInitNewRow}
onCellPrepared={onCellPrepared}
onRowInserting={onRowInserting}
onRowUpdating={onRowUpdating}
onEditingStart={onEditingStart}
onDataErrorOccurred={onDataErrorOccurred}
onExporting={onExporting}
onEditCanceled={() => {
setMode('view')
}}
onSaved={() => {
setMode('view')
}}
onRowInserted={() => {
props.refreshData?.()
}}
onRowUpdated={() => {
props.refreshData?.()
}}
onRowRemoved={() => {
props.refreshData?.()
}}
>
<Export
enabled={true}
allowExportSelectedData={false}
formats={['pdf', 'xlsx', 'csv']}
/>
<Editing
refreshMode={gridDto.gridOptions.editingOptionDto?.refreshMode}
mode={smaller.md ? 'form' : gridDto.gridOptions.editingOptionDto?.mode}
allowDeleting={gridDto.gridOptions.editingOptionDto?.allowDeleting}
allowUpdating={gridDto.gridOptions.editingOptionDto?.allowUpdating}
allowAdding={gridDto.gridOptions.editingOptionDto?.allowAdding}
useIcons={gridDto.gridOptions.editingOptionDto?.useIcons}
confirmDelete={gridDto.gridOptions.editingOptionDto?.confirmDelete}
newRowPosition={gridDto.gridOptions.editingOptionDto?.newRowPosition}
selectTextOnEditStart={gridDto.gridOptions.editingOptionDto?.selectTextOnEditStart}
startEditAction={gridDto.gridOptions.editingOptionDto?.startEditAction}
popup={{
title: gridDto.gridOptions.editingOptionDto?.popup?.title,
showTitle: gridDto.gridOptions.editingOptionDto?.popup?.showTitle,
hideOnOutsideClick:
gridDto.gridOptions.editingOptionDto?.popup?.hideOnOutsideClick,
width: gridDto.gridOptions.editingOptionDto?.popup?.width,
height: gridDto.gridOptions.editingOptionDto?.popup?.height,
fullScreen: gridDto.gridOptions.editingOptionDto?.popup?.fullScreen,
}}
form={{
items:
gridDto.gridOptions.editingFormDto?.length > 0
? gridDto.gridOptions.editingFormDto
?.sort((a: any, b: any) => {
return a.order >= b.order ? 1 : -1
})
.map((e: any) => {
return {
itemType: e.itemType,
colCount: e.colCount,
colSpan: e.colSpan,
caption: e.caption,
items: e.items
?.sort((a: any, b: any) => {
return a.order >= b.order ? 1 : -1
})
.map((i: EditingFormItemDto) => {
let editorOptions = {}
try {
editorOptions = i.editorOptions && JSON.parse(i.editorOptions)
// Eğer default value varsa, bu editörü readonly yapıyoruz
if (searchParams?.has(i.dataField)) {
editorOptions = {
...editorOptions,
readOnly: true,
}
}
} catch {}
const fieldName = i.dataField.split(':')[0]
const listFormField = gridDto.columnFormats.find(
(x: any) => x.fieldName === fieldName,
)
if (listFormField?.sourceDbType === DbTypeEnum.Date) {
editorOptions = { editorOptions = {
...{
type: 'date',
dateSerializationFormat: 'yyyy-MM-dd',
displayFormat: 'shortDate',
},
...editorOptions, ...editorOptions,
}
} else if (
listFormField?.sourceDbType === DbTypeEnum.DateTime ||
listFormField?.sourceDbType === DbTypeEnum.DateTime2 ||
listFormField?.sourceDbType === DbTypeEnum.DateTimeOffset
) {
editorOptions = {
...{
type: 'datetime',
dateSerializationFormat: 'yyyy-MM-ddTHH:mm:ssxxx',
displayFormat: 'shortDateShortTime',
},
...editorOptions,
}
}
const item: SimpleItemWithColData = {
canRead: listFormField?.canRead ?? false,
canUpdate: listFormField?.canUpdate ?? false,
canCreate: listFormField?.canCreate ?? false,
canExport: listFormField?.canExport ?? false,
dataField: i.dataField,
name: i.dataField,
editorType2: i.editorType2,
editorType:
i.editorType2 == PlatformEditorTypes.dxGridBox
? 'dxDropDownBox'
: i.editorType2,
colSpan: i.colSpan,
isRequired: i.isRequired,
editorOptions,
}
if (i.dataField.indexOf(':') >= 0) {
item.label = { text: captionize(i.dataField.split(':')[1]) }
}
if (
(mode == 'edit' && !item.canUpdate) ||
(mode == 'new' && !item.canCreate)
) {
item.editorOptions = {
...item.editorOptions,
readOnly: true, readOnly: true,
} }
} }
} catch {}
const fieldName = i.dataField.split(':')[0]
const listFormField = gridDto.columnFormats.find(
(x: any) => x.fieldName === fieldName,
)
if (listFormField?.sourceDbType === DbTypeEnum.Date) {
editorOptions = {
...{
type: 'date',
dateSerializationFormat: 'yyyy-MM-dd',
displayFormat: 'shortDate',
},
...editorOptions,
}
} else if (
listFormField?.sourceDbType === DbTypeEnum.DateTime ||
listFormField?.sourceDbType === DbTypeEnum.DateTime2 ||
listFormField?.sourceDbType === DbTypeEnum.DateTimeOffset
) {
editorOptions = {
...{
type: 'datetime',
dateSerializationFormat: 'yyyy-MM-ddTHH:mm:ssxxx',
displayFormat: 'shortDateShortTime',
},
...editorOptions,
}
}
const item: SimpleItemWithColData = {
canRead: listFormField?.canRead ?? false,
canUpdate: listFormField?.canUpdate ?? false,
canCreate: listFormField?.canCreate ?? false,
canExport: listFormField?.canExport ?? false,
dataField: i.dataField,
name: i.dataField,
editorType2: i.editorType2,
editorType:
i.editorType2 == PlatformEditorTypes.dxGridBox
? 'dxDropDownBox'
: i.editorType2,
colSpan: i.colSpan,
isRequired: i.isRequired,
editorOptions,
}
if (i.dataField.indexOf(':') >= 0) {
item.label = { text: captionize(i.dataField.split(':')[1]) }
}
if (
(mode == 'edit' && !item.canUpdate) ||
(mode == 'new' && !item.canCreate)
) {
item.editorOptions = {
...item.editorOptions,
readOnly: true,
}
}
return item return item
}) })
.filter((a: any) => { .filter((a: any) => {
// return a.canRead // return a.canRead
if (mode === 'view') { if (mode === 'view') {
return a.canRead return a.canRead
} else if (mode === 'new') { } else if (mode === 'new') {
return a.canCreate || a.canRead return a.canCreate || a.canRead
} else if (mode === 'edit') { } else if (mode === 'edit') {
return a.canUpdate || a.canRead return a.canUpdate || a.canRead
} else { } else {
return false return false
} }
}), }),
} as GroupItem } as GroupItem
}) })
: undefined, : undefined,
}} }}
></Editing> ></Editing>
<Template name={'cellEditTagBox'} render={TagBoxEditorComponent} /> <Template name={'cellEditTagBox'} render={TagBoxEditorComponent} />
<Template name={'cellEditGridBox'} render={GridBoxEditorComponent} /> <Template name={'cellEditGridBox'} render={GridBoxEditorComponent} />
<Toolbar visible={toolbarData.length > 0 || filterToolbarData.length > 0}> <Toolbar visible={toolbarData.length > 0 || filterToolbarData.length > 0}>
{toolbarData.map((item) => ( {toolbarData.map((item) => (
<Item key={item.name} {...item}></Item> <Item key={item.name} {...item}></Item>
))}
{filterToolbarData.map((item) => (
<Item key={item.name} {...item}></Item>
))}
</Toolbar>
<Sorting mode={gridDto.gridOptions?.sortMode}></Sorting>
<FilterRow
visible={gridDto.gridOptions.filterRowDto?.visible}
applyFilter={gridDto.gridOptions.filterRowDto?.applyFilter}
></FilterRow>
<FilterPanel visible={gridDto.gridOptions.filterPanelDto.visible}></FilterPanel>
<HeaderFilter visible={gridDto.gridOptions.headerFilterDto.visible}></HeaderFilter>
<SearchPanel
visible={gridDto.gridOptions.searchPanelDto.visible}
width={gridDto.gridOptions.searchPanelDto.width}
></SearchPanel>
<GroupPanel visible={gridDto.gridOptions.groupPanelDto?.visible}></GroupPanel>
<Grouping autoExpandAll={gridDto.gridOptions.groupPanelDto?.autoExpandAll}></Grouping>
<Selection
mode={gridDto.gridOptions.selectionDto?.mode}
allowSelectAll={gridDto.gridOptions.selectionDto?.allowSelectAll}
selectAllMode={gridDto.gridOptions.selectionDto?.selectAllMode}
showCheckBoxesMode={gridDto.gridOptions.selectionDto?.showCheckBoxesMode}
></Selection>
{/* <Paging pageSize={gridDto.gridOptions.pageSize ?? 0}></Paging> */}
<Pager
visible={gridDto.gridOptions.pagerOptionDto?.visible}
allowedPageSizes={gridDto.gridOptions.pagerOptionDto?.allowedPageSizes
?.split(',')
.map((a: any) => +a)}
showPageSizeSelector={gridDto.gridOptions.pagerOptionDto?.showPageSizeSelector}
showInfo={gridDto.gridOptions.pagerOptionDto?.showInfo}
showNavigationButtons={gridDto.gridOptions.pagerOptionDto?.showNavigationButtons}
infoText={gridDto.gridOptions.pagerOptionDto?.infoText}
displayMode={gridDto.gridOptions.pagerOptionDto?.displayMode}
></Pager>
<ColumnChooser
enabled={gridDto.gridOptions.columnOptionDto?.columnChooserEnabled}
mode={gridDto.gridOptions.columnOptionDto?.columnChooserMode}
></ColumnChooser>
<ColumnFixing
enabled={gridDto.gridOptions.columnOptionDto?.columnFixingEnabled}
></ColumnFixing>
<Scrolling mode={gridDto.gridOptions.pagerOptionDto?.scrollingMode}></Scrolling>
<LoadPanel
enabled={gridDto.gridOptions.pagerOptionDto?.loadPanelEnabled}
text={gridDto.gridOptions.pagerOptionDto?.loadPanelText}
></LoadPanel>
<Summary>
{gridDto.columnFormats
.filter((x: any) => !!x.columnTotalSummaryDto?.summaryType)
.map((x: any) => (
<TotalItem
key={`Total_${x.fieldName}`}
column={x.fieldName}
summaryType={x.columnTotalSummaryDto.summaryType as any}
showInColumn={x.columnTotalSummaryDto.showInColumn}
valueFormat={x.columnTotalSummaryDto.valueFormat}
displayFormat={x.columnTotalSummaryDto.displayFormat}
/>
))} ))}
{gridDto.columnFormats {filterToolbarData.map((item) => (
.filter((x: any) => !!x.columnGroupSummaryDto?.summaryType) <Item key={item.name} {...item}></Item>
.map((x: any) => (
<GroupItemDx
key={`Group_${x.fieldName}`}
column={x.fieldName}
summaryType={x.columnGroupSummaryDto.summaryType as any}
showInColumn={x.columnGroupSummaryDto.showInColumn}
valueFormat={x.columnGroupSummaryDto.valueFormat}
displayFormat={x.columnGroupSummaryDto.displayFormat}
/>
))} ))}
</Summary> </Toolbar>
{/* <Column <Sorting mode={gridDto.gridOptions?.sortMode}></Sorting>
<FilterRow
visible={gridDto.gridOptions.filterRowDto?.visible}
applyFilter={gridDto.gridOptions.filterRowDto?.applyFilter}
></FilterRow>
<FilterPanel visible={gridDto.gridOptions.filterPanelDto.visible}></FilterPanel>
<HeaderFilter visible={gridDto.gridOptions.headerFilterDto.visible}></HeaderFilter>
<SearchPanel
visible={gridDto.gridOptions.searchPanelDto.visible}
width={gridDto.gridOptions.searchPanelDto.width}
></SearchPanel>
<GroupPanel visible={gridDto.gridOptions.groupPanelDto?.visible}></GroupPanel>
<Grouping autoExpandAll={gridDto.gridOptions.groupPanelDto?.autoExpandAll}></Grouping>
<Selection
mode={gridDto.gridOptions.selectionDto?.mode}
allowSelectAll={gridDto.gridOptions.selectionDto?.allowSelectAll}
selectAllMode={gridDto.gridOptions.selectionDto?.selectAllMode}
showCheckBoxesMode={gridDto.gridOptions.selectionDto?.showCheckBoxesMode}
></Selection>
{/* <Paging pageSize={gridDto.gridOptions.pageSize ?? 0}></Paging> */}
<Pager
visible={gridDto.gridOptions.pagerOptionDto?.visible}
allowedPageSizes={gridDto.gridOptions.pagerOptionDto?.allowedPageSizes
?.split(',')
.map((a: any) => +a)}
showPageSizeSelector={gridDto.gridOptions.pagerOptionDto?.showPageSizeSelector}
showInfo={gridDto.gridOptions.pagerOptionDto?.showInfo}
showNavigationButtons={gridDto.gridOptions.pagerOptionDto?.showNavigationButtons}
infoText={gridDto.gridOptions.pagerOptionDto?.infoText}
displayMode={gridDto.gridOptions.pagerOptionDto?.displayMode}
></Pager>
<ColumnChooser
enabled={gridDto.gridOptions.columnOptionDto?.columnChooserEnabled}
mode={gridDto.gridOptions.columnOptionDto?.columnChooserMode}
></ColumnChooser>
<ColumnFixing
enabled={gridDto.gridOptions.columnOptionDto?.columnFixingEnabled}
></ColumnFixing>
<Scrolling mode={gridDto.gridOptions.pagerOptionDto?.scrollingMode}></Scrolling>
<LoadPanel
enabled={gridDto.gridOptions.pagerOptionDto?.loadPanelEnabled}
text={gridDto.gridOptions.pagerOptionDto?.loadPanelText}
></LoadPanel>
<Summary>
{gridDto.columnFormats
.filter((x: any) => !!x.columnTotalSummaryDto?.summaryType)
.map((x: any) => (
<TotalItem
key={`Total_${x.fieldName}`}
column={x.fieldName}
summaryType={x.columnTotalSummaryDto.summaryType as any}
showInColumn={x.columnTotalSummaryDto.showInColumn}
valueFormat={x.columnTotalSummaryDto.valueFormat}
displayFormat={x.columnTotalSummaryDto.displayFormat}
/>
))}
{gridDto.columnFormats
.filter((x: any) => !!x.columnGroupSummaryDto?.summaryType)
.map((x: any) => (
<GroupItemDx
key={`Group_${x.fieldName}`}
column={x.fieldName}
summaryType={x.columnGroupSummaryDto.summaryType as any}
showInColumn={x.columnGroupSummaryDto.showInColumn}
valueFormat={x.columnGroupSummaryDto.valueFormat}
displayFormat={x.columnGroupSummaryDto.displayFormat}
/>
))}
</Summary>
{/* <Column
dataField="Quantity" dataField="Quantity"
width={160} width={160}
alignment="right" alignment="right"
@ -777,34 +786,35 @@ const Grid = (props: GridProps) => {
> >
<Format type="fixedPoint" precision={2} /> <Format type="fixedPoint" precision={2} />
</Column> */} </Column> */}
</DataGrid> </DataGrid>
{gridDto?.gridOptions?.subFormsDto?.length > 0 && ( {gridDto?.gridOptions?.subFormsDto?.length > 0 && (
<> <>
<hr className="my-4" /> <hr className="my-4" />
<SubForms gridDto={gridDto!} formData={formData} level={level ?? 0} /> <SubForms gridDto={gridDto!} formData={formData} level={level ?? 0} />
</> </>
)} )}
<Dialog <Dialog
width={smaller.md ? '100%' : 1000} width={smaller.md ? '100%' : 1000}
isOpen={filterData.isImportModalOpen || false} isOpen={filterData.isImportModalOpen || false}
onClose={() => filterData.setIsImportModalOpen(false)} onClose={() => filterData.setIsImportModalOpen(false)}
onRequestClose={() => filterData.setIsImportModalOpen(false)} onRequestClose={() => filterData.setIsImportModalOpen(false)}
> >
<ImportDashboard gridDto={gridDto} /> <ImportDashboard gridDto={gridDto} />
</Dialog> </Dialog>
</> </>
)} )}
<Dialog <Dialog
isOpen={toolbarModalData?.open || false} isOpen={toolbarModalData?.open || false}
onClose={() => setToolbarModalData(undefined)} onClose={() => setToolbarModalData(undefined)}
onRequestClose={() => setToolbarModalData(undefined)} onRequestClose={() => setToolbarModalData(undefined)}
> >
{toolbarModalData?.content} {toolbarModalData?.content}
</Dialog> </Dialog>
<GridFilterDialogs gridRef={gridRef} listFormCode={listFormCode} {...filterData} /> <GridFilterDialogs gridRef={gridRef} listFormCode={listFormCode} {...filterData} />
</Container> </Container>
</>
) )
} }