Pivot ve Chart ile ilgili değişiklikler

This commit is contained in:
Sedat Öztürk 2025-09-27 23:25:21 +03:00
parent b3c07ae19f
commit 4d1416d5a1
20 changed files with 1767 additions and 1530 deletions

View file

@ -4,6 +4,7 @@ public class GridPivotOptionDto
{ {
/// <summary> pivot grid için eklenmiş sütunlardır. /// <summary> pivot grid için eklenmiş sütunlardır.
/// </summary> /// </summary>
public bool ColumnChooserEnabled { get; set; }
public bool AllowFieldDragging { get; set; } = true; public bool AllowFieldDragging { get; set; } = true;
public bool ShowFieldPanel { get; set; } = true; public bool ShowFieldPanel { get; set; } = true;
public bool ShowDataFields { get; set; } = true; public bool ShowDataFields { get; set; } = true;

View file

@ -89,7 +89,7 @@ public class ListFormCustomizationAppService : PlatformAppService
{ {
throw new BadHttpRequestException("Type UI veya Grid olmalıdır"); throw new BadHttpRequestException("Type UI veya Grid olmalıdır");
} }
if (input.CustomizationData.IsNullOrWhiteSpace()) if (!(input.CustomizationType == ListFormCustomizationTypeEnum.GridState) && input.CustomizationData.IsNullOrWhiteSpace())
{ {
throw new BadHttpRequestException("Filter data boş olamaz"); throw new BadHttpRequestException("Filter data boş olamaz");
} }

View file

@ -7526,7 +7526,7 @@
{ {
"key": "admin.chart", "key": "admin.chart",
"path": "/admin/chart/:listFormCode", "path": "/admin/chart/:listFormCode",
"componentPath": "@/views/chart/Chart", "componentPath": "@/views/list/Chart",
"routeType": "protected", "routeType": "protected",
"authority": [] "authority": []
}, },

View file

@ -358,6 +358,7 @@ export interface GridColumnOptionDto {
} }
export interface GridPivotOptionDto { export interface GridPivotOptionDto {
columnChooserEnabled: boolean
allowFieldDragging: boolean allowFieldDragging: boolean
showFieldPanel: boolean showFieldPanel: boolean
showDataFields: boolean showDataFields: boolean

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, useState } from 'react' import { MutableRefObject, useCallback } from 'react'
import { getLoadOptions, getServiceAddress, setGridPanelColor } from '../views/list/Utils' import { getLoadOptions, getServiceAddress, setGridPanelColor } from '../views/list/Utils'
import { GridOptionsDto, WidgetGroupDto } from '../proxy/form/models' import { GridOptionsDto } 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,8 @@ const useListFormCustomDataSource = ({
listFormCode: string, listFormCode: string,
searchParams?: URLSearchParams, searchParams?: URLSearchParams,
cols?: GridColumnData[], cols?: GridColumnData[],
group?: string,
groupSummary?: string
) => { ) => {
const store: any = new CustomStore({ const store: any = new CustomStore({
key: gridOptions.keyFieldName, key: gridOptions.keyFieldName,
@ -32,7 +34,8 @@ const useListFormCustomDataSource = ({
listFormCode, listFormCode,
filter: '', filter: '',
createDeleteQuery: searchParams?.get('createDeleteQuery'), createDeleteQuery: searchParams?.get('createDeleteQuery'),
group: '', group,
groupSummary
}) })
// 1. Default filter'ı al // 1. Default filter'ı al

View file

@ -29,7 +29,6 @@ function ChartTabAnimation(props: FormEditProps) {
{({ touched, errors, resetForm, isSubmitting, values }) => ( {({ touched, errors, resetForm, isSubmitting, values }) => (
<Form> <Form>
<FormContainer size="sm"> <FormContainer size="sm">
<Card className="my-2">
<FormItem <FormItem
label="Enabled" label="Enabled"
invalid={!!(errors.animationDto?.enabled && touched.animationDto?.enabled)} invalid={!!(errors.animationDto?.enabled && touched.animationDto?.enabled)}
@ -79,7 +78,6 @@ function ChartTabAnimation(props: FormEditProps) {
> >
<Field type="number" name="animationDto.maxPointCountSupported" component={Input} /> <Field type="number" name="animationDto.maxPointCountSupported" component={Input} />
</FormItem> </FormItem>
</Card>
<div className="mt-4"> <div className="mt-4">
<Button block variant="solid" loading={isSubmitting} type="submit"> <Button block variant="solid" loading={isSubmitting} type="submit">
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')} {isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}

View file

@ -170,7 +170,8 @@ function ChartTabAnnotations(props: FormEditProps) {
/> />
</TabContent> </TabContent>
<TabContent value="annotations_common"> <TabContent value="annotations_common">
<Card className="my-2"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
<Card className="my-2" header="General">
<FormItem <FormItem
label="Tooltip Enabled" label="Tooltip Enabled"
invalid={ invalid={
@ -181,7 +182,10 @@ function ChartTabAnnotations(props: FormEditProps) {
} }
errorMessage={errors.commonAnnotationSettingsDto?.tooltipEnabled} errorMessage={errors.commonAnnotationSettingsDto?.tooltipEnabled}
> >
<Field name="commonAnnotationSettingsDto.tooltipEnabled" component={Checkbox} /> <Field
name="commonAnnotationSettingsDto.tooltipEnabled"
component={Checkbox}
/>
</FormItem> </FormItem>
<FormItem <FormItem
@ -228,7 +232,8 @@ function ChartTabAnnotations(props: FormEditProps) {
options={SeriesList()} options={SeriesList()}
isClearable={true} isClearable={true}
value={SeriesList()?.find( value={SeriesList()?.find(
(option) => option.value === values.commonAnnotationSettingsDto.series, (option) =>
option.value === values.commonAnnotationSettingsDto.series,
)} )}
onChange={(option) => form.setFieldValue(field.name, option?.value)} onChange={(option) => form.setFieldValue(field.name, option?.value)}
/> />
@ -470,7 +475,7 @@ function ChartTabAnnotations(props: FormEditProps) {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Common Annotations - Border"> <Card className="my-2" header="Border">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
@ -481,7 +486,10 @@ function ChartTabAnnotations(props: FormEditProps) {
} }
errorMessage={errors.commonAnnotationSettingsDto?.border?.visible} errorMessage={errors.commonAnnotationSettingsDto?.border?.visible}
> >
<Field name="commonAnnotationSettingsDto.border.visible" component={Checkbox} /> <Field
name="commonAnnotationSettingsDto.border.visible"
component={Checkbox}
/>
</FormItem> </FormItem>
<FormItem <FormItem
@ -520,7 +528,8 @@ function ChartTabAnnotations(props: FormEditProps) {
isClearable={true} isClearable={true}
value={chartSeriesDashStyleOptions.filter( value={chartSeriesDashStyleOptions.filter(
(option) => (option) =>
option.value === values.commonAnnotationSettingsDto.border.dashStyle, option.value ===
values.commonAnnotationSettingsDto.border.dashStyle,
)} )}
onChange={(option) => form.setFieldValue(field.name, option?.value)} onChange={(option) => form.setFieldValue(field.name, option?.value)}
/> />
@ -563,7 +572,7 @@ function ChartTabAnnotations(props: FormEditProps) {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Common Annotations - Font"> <Card className="my-2" header="Font">
<FormItem <FormItem
label="Color" label="Color"
invalid={ invalid={
@ -624,6 +633,7 @@ function ChartTabAnnotations(props: FormEditProps) {
/> />
</FormItem> </FormItem>
</Card> </Card>
</div>
</TabContent> </TabContent>
</Tabs> </Tabs>
<div className="mt-4"> <div className="mt-4">

View file

@ -163,7 +163,8 @@ function ChartTabAxis(props: FormEditProps) {
/> />
</TabContent> </TabContent>
<TabContent value="axis_argument"> <TabContent value="axis_argument">
<Card className="my-2"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
<Card className="my-2" header="General">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
@ -293,7 +294,8 @@ function ChartTabAxis(props: FormEditProps) {
options={chartArgumentAxisIntervalListOptions} options={chartArgumentAxisIntervalListOptions}
isClearable={true} isClearable={true}
value={chartArgumentAxisIntervalListOptions.filter( value={chartArgumentAxisIntervalListOptions.filter(
(option) => option.value === values.argumentAxisDto.aggregationInterval, (option) =>
option.value === values.argumentAxisDto.aggregationInterval,
)} )}
onChange={(option) => form.setFieldValue(field.name, option?.value)} onChange={(option) => form.setFieldValue(field.name, option?.value)}
/> />
@ -302,7 +304,7 @@ function ChartTabAxis(props: FormEditProps) {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Argument Axis - Grid"> <Card className="my-2" header="Grid">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
@ -320,7 +322,8 @@ function ChartTabAxis(props: FormEditProps) {
label="Color" label="Color"
invalid={ invalid={
!!( !!(
errors.argumentAxisDto?.grid?.color && touched.argumentAxisDto?.grid?.color errors.argumentAxisDto?.grid?.color &&
touched.argumentAxisDto?.grid?.color
) )
} }
errorMessage={errors.argumentAxisDto?.grid?.color} errorMessage={errors.argumentAxisDto?.grid?.color}
@ -332,7 +335,8 @@ function ChartTabAxis(props: FormEditProps) {
label="Width" label="Width"
invalid={ invalid={
!!( !!(
errors.argumentAxisDto?.grid?.width && touched.argumentAxisDto?.grid?.width errors.argumentAxisDto?.grid?.width &&
touched.argumentAxisDto?.grid?.width
) )
} }
errorMessage={errors.argumentAxisDto?.grid?.width} errorMessage={errors.argumentAxisDto?.grid?.width}
@ -341,7 +345,7 @@ function ChartTabAxis(props: FormEditProps) {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Argument Axis - Label"> <Card className="my-2" header="Label">
<FormItem <FormItem
label="Position" label="Position"
invalid={ invalid={
@ -412,9 +416,11 @@ function ChartTabAxis(props: FormEditProps) {
</Field> </Field>
</FormItem> </FormItem>
</Card> </Card>
</div>
</TabContent> </TabContent>
<TabContent value="axis_common"> <TabContent value="axis_common">
<Card className="my-2"> <div className="grid grid-cols-1 lg:grid-cols-2 gap-3">
<Card className="my-2" header="General">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
@ -432,7 +438,8 @@ function ChartTabAxis(props: FormEditProps) {
label="Title" label="Title"
invalid={ invalid={
!!( !!(
errors.commonAxisSettingsDto?.title && touched.commonAxisSettingsDto?.title errors.commonAxisSettingsDto?.title &&
touched.commonAxisSettingsDto?.title
) )
} }
errorMessage={errors.commonAxisSettingsDto?.title} errorMessage={errors.commonAxisSettingsDto?.title}
@ -444,7 +451,8 @@ function ChartTabAxis(props: FormEditProps) {
label="Width" label="Width"
invalid={ invalid={
!!( !!(
errors.commonAxisSettingsDto?.width && touched.commonAxisSettingsDto?.width errors.commonAxisSettingsDto?.width &&
touched.commonAxisSettingsDto?.width
) )
} }
errorMessage={errors.commonAxisSettingsDto?.width} errorMessage={errors.commonAxisSettingsDto?.width}
@ -453,7 +461,7 @@ function ChartTabAxis(props: FormEditProps) {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Common Axis Settings - Grid"> <Card className="my-2" header="Grid">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
@ -477,7 +485,11 @@ function ChartTabAxis(props: FormEditProps) {
} }
errorMessage={errors.commonAxisSettingsDto?.grid?.color} errorMessage={errors.commonAxisSettingsDto?.grid?.color}
> >
<Field type="text" name="commonAxisSettingsDto.grid.color" component={Input} /> <Field
type="text"
name="commonAxisSettingsDto.grid.color"
component={Input}
/>
</FormItem> </FormItem>
<FormItem <FormItem
@ -497,6 +509,7 @@ function ChartTabAxis(props: FormEditProps) {
/> />
</FormItem> </FormItem>
</Card> </Card>
</div>
</TabContent> </TabContent>
</Tabs> </Tabs>
<div className="mt-4"> <div className="mt-4">

View file

@ -318,7 +318,8 @@ function ChartTabCommonSettings(props: FormEditProps) {
</Card> </Card>
</TabContent> </TabContent>
<TabContent value="commonSettings_tooltip"> <TabContent value="commonSettings_tooltip">
<Card className="my-2"> <div className="grid grid-cols-1 lg:grid-cols-3 gap-3">
<Card className="my-2" header="General">
<FormItem <FormItem
label="Enabled" label="Enabled"
invalid={!!(errors.tooltipDto?.enabled && touched.tooltipDto?.enabled)} invalid={!!(errors.tooltipDto?.enabled && touched.tooltipDto?.enabled)}
@ -397,7 +398,9 @@ function ChartTabCommonSettings(props: FormEditProps) {
<FormItem <FormItem
label="Arrow Length" label="Arrow Length"
invalid={!!(errors.tooltipDto?.arrowLength && touched.tooltipDto?.arrowLength)} invalid={
!!(errors.tooltipDto?.arrowLength && touched.tooltipDto?.arrowLength)
}
errorMessage={errors.tooltipDto?.arrowLength} errorMessage={errors.tooltipDto?.arrowLength}
> >
<Field type="number" name="tooltipDto.arrowLength" component={Input} /> <Field type="number" name="tooltipDto.arrowLength" component={Input} />
@ -407,7 +410,8 @@ function ChartTabCommonSettings(props: FormEditProps) {
label="Padding Top/Bottom" label="Padding Top/Bottom"
invalid={ invalid={
!!( !!(
errors.tooltipDto?.paddingTopBottom && touched.tooltipDto?.paddingTopBottom errors.tooltipDto?.paddingTopBottom &&
touched.tooltipDto?.paddingTopBottom
) )
} }
errorMessage={errors.tooltipDto?.paddingTopBottom} errorMessage={errors.tooltipDto?.paddingTopBottom}
@ -419,7 +423,8 @@ function ChartTabCommonSettings(props: FormEditProps) {
label="Padding Left/Right" label="Padding Left/Right"
invalid={ invalid={
!!( !!(
errors.tooltipDto?.paddingLeftRight && touched.tooltipDto?.paddingLeftRight errors.tooltipDto?.paddingLeftRight &&
touched.tooltipDto?.paddingLeftRight
) )
} }
errorMessage={errors.tooltipDto?.paddingLeftRight} errorMessage={errors.tooltipDto?.paddingLeftRight}
@ -427,10 +432,13 @@ function ChartTabCommonSettings(props: FormEditProps) {
<Field type="number" name="tooltipDto.paddingLeftRight" component={Input} /> <Field type="number" name="tooltipDto.paddingLeftRight" component={Input} />
</FormItem> </FormItem>
</Card> </Card>
<div className="font-bold m-3">Tooltip Settings - Font</div>
<Card className="my-2" header="Font">
<FormItem <FormItem
label="Color" label="Color"
invalid={!!(errors.tooltipDto?.font?.color && touched.tooltipDto?.font?.color)} invalid={
!!(errors.tooltipDto?.font?.color && touched.tooltipDto?.font?.color)
}
errorMessage={errors.tooltipDto?.font?.color} errorMessage={errors.tooltipDto?.font?.color}
> >
<Field name="tooltipDto.font.color" component={Input} /> <Field name="tooltipDto.font.color" component={Input} />
@ -438,7 +446,9 @@ function ChartTabCommonSettings(props: FormEditProps) {
<FormItem <FormItem
label="Family" label="Family"
invalid={!!(errors.tooltipDto?.font?.family && touched.tooltipDto?.font?.family)} invalid={
!!(errors.tooltipDto?.font?.family && touched.tooltipDto?.font?.family)
}
errorMessage={errors.tooltipDto?.font?.family} errorMessage={errors.tooltipDto?.font?.family}
> >
<Field name="tooltipDto.font.family" component={Input} /> <Field name="tooltipDto.font.family" component={Input} />
@ -454,17 +464,22 @@ function ChartTabCommonSettings(props: FormEditProps) {
<FormItem <FormItem
label="Weight" label="Weight"
invalid={!!(errors.tooltipDto?.font?.weight && touched.tooltipDto?.font?.weight)} invalid={
!!(errors.tooltipDto?.font?.weight && touched.tooltipDto?.font?.weight)
}
errorMessage={errors.tooltipDto?.font?.weight} errorMessage={errors.tooltipDto?.font?.weight}
> >
<Field type="number" name="tooltipDto.font.weight" component={Input} /> <Field type="number" name="tooltipDto.font.weight" component={Input} />
</FormItem> </FormItem>
</Card>
<div className="font-bold m-3">Tooltip Settings - Border</div> <Card className="my-2" header="Border">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
!!(errors.tooltipDto?.border?.visible && touched.tooltipDto?.border?.visible) !!(
errors.tooltipDto?.border?.visible && touched.tooltipDto?.border?.visible
)
} }
errorMessage={errors.tooltipDto?.border?.visible as string} errorMessage={errors.tooltipDto?.border?.visible as string}
> >
@ -475,7 +490,8 @@ function ChartTabCommonSettings(props: FormEditProps) {
label="Dash Style" label="Dash Style"
invalid={ invalid={
!!( !!(
errors.tooltipDto?.border?.dashStyle && touched.tooltipDto?.border?.dashStyle errors.tooltipDto?.border?.dashStyle &&
touched.tooltipDto?.border?.dashStyle
) )
} }
errorMessage={errors.tooltipDto?.border?.dashStyle} errorMessage={errors.tooltipDto?.border?.dashStyle}
@ -516,8 +532,14 @@ function ChartTabCommonSettings(props: FormEditProps) {
} }
errorMessage={errors.tooltipDto?.border?.cornerRadius} errorMessage={errors.tooltipDto?.border?.cornerRadius}
> >
<Field type="number" name="tooltipDto.border.cornerRadius" component={Input} /> <Field
type="number"
name="tooltipDto.border.cornerRadius"
component={Input}
/>
</FormItem> </FormItem>
</Card>
</div>
</TabContent> </TabContent>
<TabContent value="commonSettings_margin"> <TabContent value="commonSettings_margin">
<Card className="my-2"> <Card className="my-2">

View file

@ -30,7 +30,8 @@ function ChartTabCrosshair(props: FormEditProps) {
{({ touched, errors, resetForm, isSubmitting, values }) => ( {({ touched, errors, resetForm, isSubmitting, values }) => (
<Form> <Form>
<FormContainer size="sm"> <FormContainer size="sm">
<Card className="my-2"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-3">
<Card className="my-2" header="Crosshair Options">
<FormItem <FormItem
label="Enabled" label="Enabled"
invalid={!!(errors.crosshairDto?.enabled && touched.crosshairDto?.enabled)} invalid={!!(errors.crosshairDto?.enabled && touched.crosshairDto?.enabled)}
@ -77,7 +78,7 @@ function ChartTabCrosshair(props: FormEditProps) {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Crosshair Options - Label"> <Card className="my-2" header="Label Options">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
@ -138,7 +139,7 @@ function ChartTabCrosshair(props: FormEditProps) {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Crosshair Options - Label - Font"> <Card className="my-2" header="Font Options">
<FormItem <FormItem
label="Color" label="Color"
invalid={ invalid={
@ -192,7 +193,7 @@ function ChartTabCrosshair(props: FormEditProps) {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Crosshair Options - Label - Horizontal Line"> <Card className="my-2" header="Label - Horizontal Line">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
@ -259,7 +260,7 @@ function ChartTabCrosshair(props: FormEditProps) {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Crosshair Options - Label - Vertical Line"> <Card className="my-2" header="Label - Vertical Line">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
@ -325,6 +326,7 @@ function ChartTabCrosshair(props: FormEditProps) {
<Field type="number" name="crosshairDto.verticalLine.width" component={Input} /> <Field type="number" name="crosshairDto.verticalLine.width" component={Input} />
</FormItem> </FormItem>
</Card> </Card>
</div>
<div className="mt-4"> <div className="mt-4">
<Button block variant="solid" loading={isSubmitting} type="submit"> <Button block variant="solid" loading={isSubmitting} type="submit">
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')} {isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}

View file

@ -27,7 +27,6 @@ function ChartTabExport(props: FormEditProps) {
{({ touched, errors, resetForm, isSubmitting, values }) => ( {({ touched, errors, resetForm, isSubmitting, values }) => (
<Form> <Form>
<FormContainer size="sm"> <FormContainer size="sm">
<Card className="my-2">
<FormItem <FormItem
label="Enabled" label="Enabled"
invalid={!!(errors.exportDto?.enabled && touched.exportDto?.enabled)} invalid={!!(errors.exportDto?.enabled && touched.exportDto?.enabled)}
@ -63,7 +62,6 @@ function ChartTabExport(props: FormEditProps) {
> >
<Field type="number" name="exportDto.margin" component={Input} /> <Field type="number" name="exportDto.margin" component={Input} />
</FormItem> </FormItem>
</Card>
<div className="mt-4"> <div className="mt-4">
<Button block variant="solid" loading={isSubmitting} type="submit"> <Button block variant="solid" loading={isSubmitting} type="submit">
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')} {isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}

View file

@ -45,13 +45,8 @@ function ChartTabLegend(props: FormEditProps) {
{({ touched, errors, resetForm, isSubmitting, values }) => ( {({ touched, errors, resetForm, isSubmitting, values }) => (
<Form> <Form>
<FormContainer size="sm"> <FormContainer size="sm">
<Tabs defaultValue="legendSettings_general"> <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
<TabList> <Card className="my-2" header="General">
<TabNav value="legendSettings_general">General</TabNav>
<TabNav value="legendSettings_border">Border</TabNav>
</TabList>
<TabContent value="legendSettings_general">
<Card className="my-2">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={!!(errors.legendDto?.visible && touched.legendDto?.visible)} invalid={!!(errors.legendDto?.visible && touched.legendDto?.visible)}
@ -119,7 +114,7 @@ function ChartTabLegend(props: FormEditProps) {
)} )}
</Field> </Field>
</FormItem> </FormItem>
<div className="flex gap-5">
<FormItem <FormItem
label="Row Count" label="Row Count"
invalid={!!(errors.legendDto?.rowCount && touched.legendDto?.rowCount)} invalid={!!(errors.legendDto?.rowCount && touched.legendDto?.rowCount)}
@ -135,10 +130,9 @@ function ChartTabLegend(props: FormEditProps) {
> >
<Field type="number" name="legendDto.columnCount" component={Input} /> <Field type="number" name="legendDto.columnCount" component={Input} />
</FormItem> </FormItem>
</div>
</Card> </Card>
</TabContent> <Card className="my-2" header="Border">
<TabContent value="legendSettings_border">
<Card className="my-2">
<FormItem <FormItem
label="Visible" label="Visible"
invalid={ invalid={
@ -151,9 +145,7 @@ function ChartTabLegend(props: FormEditProps) {
<FormItem <FormItem
label="Color" label="Color"
invalid={ invalid={!!(errors.legendDto?.border?.color && touched.legendDto?.border?.color)}
!!(errors.legendDto?.border?.color && touched.legendDto?.border?.color)
}
errorMessage={errors.legendDto?.border?.color} errorMessage={errors.legendDto?.border?.color}
> >
<Field name="legendDto.border.color" component={Input} /> <Field name="legendDto.border.color" component={Input} />
@ -162,9 +154,7 @@ function ChartTabLegend(props: FormEditProps) {
<FormItem <FormItem
label="Dash Style" label="Dash Style"
invalid={ invalid={
!!( !!(errors.legendDto?.border?.dashStyle && touched.legendDto?.border?.dashStyle)
errors.legendDto?.border?.dashStyle && touched.legendDto?.border?.dashStyle
)
} }
errorMessage={errors.legendDto?.border?.dashStyle} errorMessage={errors.legendDto?.border?.dashStyle}
> >
@ -186,9 +176,7 @@ function ChartTabLegend(props: FormEditProps) {
<FormItem <FormItem
label="Width" label="Width"
invalid={ invalid={!!(errors.legendDto?.border?.width && touched.legendDto?.border?.width)}
!!(errors.legendDto?.border?.width && touched.legendDto?.border?.width)
}
errorMessage={errors.legendDto?.border?.width} errorMessage={errors.legendDto?.border?.width}
> >
<Field type="number" name="legendDto.border.width" component={Input} /> <Field type="number" name="legendDto.border.width" component={Input} />
@ -207,8 +195,7 @@ function ChartTabLegend(props: FormEditProps) {
<Field type="number" name="legendDto.border.cornerRadius" component={Input} /> <Field type="number" name="legendDto.border.cornerRadius" component={Input} />
</FormItem> </FormItem>
</Card> </Card>
</TabContent> </div>
</Tabs>
<div className="mt-4"> <div className="mt-4">
<Button block variant="solid" loading={isSubmitting} type="submit"> <Button block variant="solid" loading={isSubmitting} type="submit">
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')} {isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}

View file

@ -29,12 +29,15 @@ const ChartTabZoomAndPan = (props: FormEditProps) => {
{({ touched, errors, resetForm, isSubmitting, values }) => ( {({ touched, errors, resetForm, isSubmitting, values }) => (
<Form> <Form>
<FormContainer size="sm"> <FormContainer size="sm">
<Card className="my-2"> <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
<Card className="my-2" header="General">
<div className="flex gap-5">
<FormItem <FormItem
label="Allow Mouse Wheel" label="Allow Mouse Wheel"
invalid={ invalid={
!!( !!(
errors.zoomAndPanDto?.allowMouseWheel && touched.zoomAndPanDto?.allowMouseWheel errors.zoomAndPanDto?.allowMouseWheel &&
touched.zoomAndPanDto?.allowMouseWheel
) )
} }
errorMessage={errors.zoomAndPanDto?.allowMouseWheel as string} errorMessage={errors.zoomAndPanDto?.allowMouseWheel as string}
@ -57,12 +60,14 @@ const ChartTabZoomAndPan = (props: FormEditProps) => {
<FormItem <FormItem
label="Drag To Zoom" label="Drag To Zoom"
invalid={!!(errors.zoomAndPanDto?.dragToZoom && touched.zoomAndPanDto?.dragToZoom)} invalid={
!!(errors.zoomAndPanDto?.dragToZoom && touched.zoomAndPanDto?.dragToZoom)
}
errorMessage={errors.zoomAndPanDto?.dragToZoom as string} errorMessage={errors.zoomAndPanDto?.dragToZoom as string}
> >
<Field name="zoomAndPanDto.dragToZoom" component={Checkbox} /> <Field name="zoomAndPanDto.dragToZoom" component={Checkbox} />
</FormItem> </FormItem>
</div>
<FormItem <FormItem
label="Argument Axis" label="Argument Axis"
invalid={ invalid={
@ -129,7 +134,7 @@ const ChartTabZoomAndPan = (props: FormEditProps) => {
</FormItem> </FormItem>
</Card> </Card>
<Card className="my-2" header="Zoom and Pan - DragBox Style"> <Card className="my-2" header="DragBox Style">
<FormItem <FormItem
label="Color" label="Color"
invalid={ invalid={
@ -153,9 +158,14 @@ const ChartTabZoomAndPan = (props: FormEditProps) => {
} }
errorMessage={errors.zoomAndPanDto?.dragBoxStyle?.opacity as string} errorMessage={errors.zoomAndPanDto?.dragBoxStyle?.opacity as string}
> >
<Field type="number" name="zoomAndPanDto.dragBoxStyle.opacity" component={Input} /> <Field
type="number"
name="zoomAndPanDto.dragBoxStyle.opacity"
component={Input}
/>
</FormItem> </FormItem>
</Card> </Card>
</div>
<div className="mt-4"> <div className="mt-4">
<Button block variant="solid" loading={isSubmitting} type="submit"> <Button block variant="solid" loading={isSubmitting} type="submit">
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')} {isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}

View file

@ -290,16 +290,16 @@ const FormEdit = () => {
{translate('::ListForms.ListFormEdit.TabChartLegend')} {translate('::ListForms.ListFormEdit.TabChartLegend')}
</TabNav> </TabNav>
)} )}
{visibleTabs.includes('exportSettings') && (
<TabNav value="exportSettings">
{translate('::ListForms.ListFormEdit.TabChartExport')}
</TabNav>
)}
{visibleTabs.includes('crosshairOptions') && ( {visibleTabs.includes('crosshairOptions') && (
<TabNav value="crosshairOptions"> <TabNav value="crosshairOptions">
{translate('::ListForms.ListFormEdit.TabChartCrosshair')} {translate('::ListForms.ListFormEdit.TabChartCrosshair')}
</TabNav> </TabNav>
)} )}
{visibleTabs.includes('exportSettings') && (
<TabNav value="exportSettings">
{translate('::ListForms.ListFormEdit.TabChartExport')}
</TabNav>
)}
</TabList> </TabList>
{/* <TabList className="flex-wrap border-b mb-2 bg-slate-50"> {/* <TabList className="flex-wrap border-b mb-2 bg-slate-50">

View file

@ -58,6 +58,20 @@ function FormTabColumns(props: FormEditProps) {
component={Checkbox} component={Checkbox}
/> />
</FormItem> </FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.SelectionColumnChooserEnabled')}
invalid={
errors.pivotOptionDto?.columnChooserEnabled &&
touched.pivotOptionDto?.columnChooserEnabled
}
errorMessage={errors.pivotOptionDto?.columnChooserEnabled}
>
<Field
name="pivotOptionDto.columnChooserEnabled"
placeholder={translate('::ListForms.ListFormEdit.SelectionColumnChooserEnabled')}
component={Checkbox}
/>
</FormItem>
<FormItem <FormItem
label={translate('::ListForms.ListFormEdit.ShowColumnFields')} label={translate('::ListForms.ListFormEdit.ShowColumnFields')}
invalid={ invalid={

View file

@ -15,7 +15,7 @@ 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, FieldProps, Form, Formik } from 'formik' import { Field, FieldProps, Form, Formik } from 'formik'
import { Dispatch, SetStateAction, useEffect, useState } from 'react' import { Dispatch, SetStateAction } from 'react'
import { boolean, number, object, string } from 'yup' import { boolean, number, object, string } from 'yup'
import { JsonRowDialogData } from './types' import { JsonRowDialogData } from './types'
import { import {
@ -149,11 +149,16 @@ function JsonRowOpDialogSeries({
visible: true, visible: true,
width: 2, width: 2,
label: { label: {
visible: false, visible: true,
backgroundColor: '#f05b41', backgroundColor: '#f05b41',
customizeText: '', customizeText: '',
format: '', format: 'decimal',
font: null, font: {
color: '#FFFFFF',
family: '"Segoe UI", "Helvetica Neue", "Trebuchet MS", Verdana, sans-serif',
size: 12,
weight: 400,
},
}, },
} }
} }
@ -409,6 +414,62 @@ function JsonRowOpDialogSeries({
> >
<Field type="text" name="label.customizeText" component={Input} /> <Field type="text" name="label.customizeText" component={Input} />
</FormItem> </FormItem>
<Card className="my-2" header="Font">
<FormItem
label="Color"
errorMessage={errors.label?.font?.color}
>
<Field name="label.font.color" component={Input} />
</FormItem>
<FormItem
label="Family"
invalid={
!!(
errors.label?.font?.family &&
touched.label?.font?.family
)
}
errorMessage={errors.label?.font?.family}
>
<Field name="label.font.family" component={Input} />
</FormItem>
<FormItem
label="Size"
invalid={
!!(
errors.label?.font?.size &&
touched.label?.font?.size
)
}
errorMessage={errors.label?.font?.size}
>
<Field
type="number"
name="label.font.size"
component={Input}
/>
</FormItem>
<FormItem
label="Weight"
invalid={
!!(
errors.label?.font?.weight &&
touched.label?.font?.weight
)
}
errorMessage={errors.label?.font?.weight}
>
<Field
type="number"
name="label.font.weight"
component={Input}
/>
</FormItem>
</Card>
</Card> </Card>
</div> </div>
<div className="text-right mt-4"> <div className="text-right mt-4">

View file

@ -33,7 +33,19 @@ const Chart = (props: ChartProps) => {
useEffect(() => { useEffect(() => {
if (!gridDto) return if (!gridDto) return
const dataSource = createSelectDataSource(gridDto.gridOptions, listFormCode, searchParams) console.log(
gridDto.gridOptions?.seriesDto?.map((s) => `${s.argumentField} asc false`).join(', '),
)
console.log(gridDto.gridOptions?.seriesDto?.map((s) => `${s.valueField} count`).join(', '))
const dataSource = createSelectDataSource(
gridDto.gridOptions,
listFormCode,
searchParams,
[],
gridDto.gridOptions?.seriesDto?.map((s) => `${s.argumentField} asc false`).join(', '),
gridDto.gridOptions?.seriesDto?.map((s) => `${s.valueField} count`).join(', '),
)
const options = { const options = {
dataSource: dataSource, dataSource: dataSource,
@ -62,8 +74,14 @@ const Chart = (props: ChartProps) => {
valueAxis: gridDto.gridOptions.valueAxisDto, valueAxis: gridDto.gridOptions.valueAxisDto,
tooltip: gridDto.gridOptions.tooltipDto, tooltip: gridDto.gridOptions.tooltipDto,
series:
gridDto.gridOptions.seriesDto?.length > 0
? gridDto.gridOptions.seriesDto.map((s) => ({
argumentField: 'key',
valueField: 'summary',
}))
: undefined,
panes: gridDto.gridOptions.panesDto?.length > 0 ? gridDto.gridOptions.panesDto : undefined, panes: gridDto.gridOptions.panesDto?.length > 0 ? gridDto.gridOptions.panesDto : undefined,
series: gridDto.gridOptions.seriesDto?.length > 0 ? gridDto.gridOptions.seriesDto : undefined,
commonSeriesSettings: gridDto.gridOptions.commonSeriesSettingsDto, commonSeriesSettings: gridDto.gridOptions.commonSeriesSettingsDto,
commonPaneSettings: gridDto.gridOptions.commonPaneSettingsDto, commonPaneSettings: gridDto.gridOptions.commonPaneSettingsDto,
commonAxisSettings: gridDto.gridOptions.commonAxisSettingsDto, commonAxisSettings: gridDto.gridOptions.commonAxisSettingsDto,

View file

@ -29,14 +29,19 @@ const List = () => {
const { states } = useStoreState((state) => state.base.lists) const { states } = useStoreState((state) => state.base.lists)
const { setStates } = useStoreActions((a) => a.base.lists) const { setStates } = useStoreActions((a) => a.base.lists)
useEffect(() => { // 🔹 Tekrar çağırılabilir metod
const initializeGridAsync = async () => { const refreshGridDto = async () => {
if (!listFormCode) return
try {
const response = await getList({ listFormCode }) const response = await getList({ listFormCode })
setGridDto(response.data) setGridDto(response.data)
} catch (error) {
console.error('GridDto refresh error:', error)
}
} }
initializeGridAsync() useEffect(() => {
.then(() => { refreshGridDto().then(() => {
//base içerisine kaydedilen state içerisinden bakılacak //base içerisine kaydedilen state içerisinden bakılacak
const listFormStates = states.find((a) => a.listFormCode === listFormCode) const listFormStates = states.find((a) => a.listFormCode === listFormCode)
if (listFormStates) { if (listFormStates) {
@ -45,9 +50,6 @@ const List = () => {
setViewMode(gridDto?.gridOptions?.layoutDto.defaultLayout || 'grid') setViewMode(gridDto?.gridOptions?.layoutDto.defaultLayout || 'grid')
} }
}) })
.catch((error) => {
console.error('Hata oluştu:', error)
})
}, [listFormCode]) }, [listFormCode])
if (!listFormCode) { if (!listFormCode) {
@ -109,6 +111,7 @@ const List = () => {
<FaTh className="w-4 h-4" /> <FaTh className="w-4 h-4" />
</Button> </Button>
)} )}
{gridDto?.gridOptions?.layoutDto.pivot && ( {gridDto?.gridOptions?.layoutDto.pivot && (
<Button <Button
size="xs" size="xs"
@ -145,6 +148,7 @@ const List = () => {
searchParams={searchParams} searchParams={searchParams}
isSubForm={false} isSubForm={false}
gridDto={gridDto} gridDto={gridDto}
refreshGridDto={refreshGridDto}
/> />
) : viewMode === 'card' ? ( ) : viewMode === 'card' ? (
<Card <Card

View file

@ -2,7 +2,6 @@
import Container from '@/components/shared/Container' import Container from '@/components/shared/Container'
import { DX_CLASSNAMES } from '@/constants/app.constant' import { DX_CLASSNAMES } from '@/constants/app.constant'
import { GridDto, ListFormCustomizationTypeEnum } from '@/proxy/form/models' import { GridDto, ListFormCustomizationTypeEnum } from '@/proxy/form/models'
import { getList } from '@/services/form.service'
import { import {
getListFormCustomization, getListFormCustomization,
postListFormCustomization, postListFormCustomization,
@ -34,21 +33,29 @@ import {
} from './Utils' } from './Utils'
import { useFilters } from './useFilters' import { useFilters } from './useFilters'
import WidgetGroup from '@/components/common/WidgetGroup' import WidgetGroup from '@/components/common/WidgetGroup'
import { Button } from '@/components/ui'
import { FaInfoCircle, FaSyncAlt, FaTrash, FaTrashAlt } from 'react-icons/fa'
import { usePermission } from '@/utils/hooks/usePermission'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { usePWA } from '@/utils/hooks/usePWA'
interface GridProps { interface PivotProps {
listFormCode: string listFormCode: string
searchParams?: URLSearchParams searchParams?: URLSearchParams
isSubForm?: boolean isSubForm?: boolean
level?: number level?: number
refreshData?: () => Promise<void> refreshData?: () => Promise<void>
gridDto?: GridDto gridDto?: GridDto
refreshGridDto: () => Promise<void>
} }
const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' // kullanici tanimli gridState ile islem gormus gridin paneline ait renk const statedGridPanelColor = 'rgba(50, 200, 200, 0.5)' // kullanici tanimli gridState ile islem gormus gridin paneline ait renk
const Pivot = (props: GridProps) => { const Pivot = (props: PivotProps) => {
const { listFormCode, searchParams, isSubForm, level, gridDto } = props const { listFormCode, searchParams, isSubForm, level, gridDto } = props
const { translate } = useLocalization() const { translate } = useLocalization()
const { checkPermission } = usePermission()
const isPwaMode = usePWA()
const gridRef = useRef<PivotGrid>() const gridRef = useRef<PivotGrid>()
const chartRef = useRef<Chart>(null) const chartRef = useRef<Chart>(null)
@ -104,6 +111,57 @@ const Pivot = (props: GridProps) => {
} }
} }
const clearPivotFilters = () => {
const grid = gridRef.current?.instance
if (!grid) return
const ds = grid.getDataSource()
if (ds) {
const fields = ds.fields()
fields.forEach((f: any) => {
f.filterValues = undefined
f.filterType = undefined
})
ds.reload()
}
}
const moveAllFieldsToFilterArea = () => {
const grid = gridRef.current?.instance
if (!grid) return
const ds = grid.getDataSource()
if (!ds) return
const fields = ds.fields()
fields.forEach((field) => {
field.area = 'filter' // tüm alanları filtre alanına taşı
field.areaIndex = undefined
})
ds.fields(fields)
ds.reload() // PivotGridi yeniden yükle
grid.repaint() // UI güncelle
}
const resetPivotGridState = async () => {
const grid = gridRef.current?.instance
if (grid) {
// kullaniciya ait kayitli grid state i sil customizationData boşalt silinsin.
await postListFormCustomization({
listFormCode: listFormCode,
customizationType: ListFormCustomizationTypeEnum.GridState,
filterName: `pivot-${gridRef.current?.instance.option('stateStoring')?.storageKey ?? ''}`,
customizationData: '',
})
await props.refreshGridDto()
clearPivotFilters()
moveAllFieldsToFilterArea()
}
}
const customSaveState = useCallback( const customSaveState = useCallback(
(state: any) => (state: any) =>
postListFormCustomization({ postListFormCustomization({
@ -249,7 +307,50 @@ const Pivot = (props: GridProps) => {
></Helmet> ></Helmet>
)} )}
{gridDto && columnData && ( {gridDto && columnData && (
<> <div className="p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 ">
<div className="flex justify-end items-center">
<div className="relative pb-1 flex gap-1 border-b-1">
<Button
size="xs"
variant={'default'}
className="text-sm"
onClick={clearPivotFilters}
title="Remove Filter"
>
<FaTrash className="w-3 h-3" />
</Button>
<Button
size="xs"
variant={'default'}
className="text-sm"
onClick={resetPivotGridState}
title="Reset Grid State"
>
<FaSyncAlt className="w-3 h-3" />
</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"
>
<FaInfoCircle className="w-3 h-3" />
</Button>
)}
</div>
</div>
{gridDto.gridOptions.pivotOptionDto.showChart && ( {gridDto.gridOptions.pivotOptionDto.showChart && (
<Chart ref={chartRef as any}> <Chart ref={chartRef as any}>
<Size height={gridDto.gridOptions.pivotOptionDto.chartHeight} /> <Size height={gridDto.gridOptions.pivotOptionDto.chartHeight} />
@ -260,6 +361,8 @@ const Pivot = (props: GridProps) => {
</Chart> </Chart>
)} )}
<div className="dx-datagrid-header-panel h-1"></div>
<PivotGrid <PivotGrid
ref={gridRef as any} ref={gridRef as any}
id={'Pivot-' + listFormCode} id={'Pivot-' + listFormCode}
@ -292,12 +395,12 @@ const Pivot = (props: GridProps) => {
showFilterFields={gridDto.gridOptions.pivotOptionDto.showFilterFields} showFilterFields={gridDto.gridOptions.pivotOptionDto.showFilterFields}
/> />
<FieldChooser <FieldChooser
enabled={gridDto.gridOptions.columnOptionDto.columnChooserEnabled} enabled={gridDto.gridOptions.pivotOptionDto.columnChooserEnabled}
height={500} height={500}
/> />
<Scrolling mode={gridDto.gridOptions.pagerOptionDto.scrollingMode} /> <Scrolling mode={gridDto.gridOptions.pagerOptionDto.scrollingMode} />
</PivotGrid> </PivotGrid>
</> </div>
)} )}
</Container> </Container>
</> </>

View file

@ -103,12 +103,6 @@ const useFilters = ({
const menus = [] const menus = []
menus.push({
text: translate('::ListForms.ListForm.Pivots'),
id: 'openPivotGrid',
icon: 'search',
})
// #region Save/Reset grid state and Filters // #region Save/Reset grid state and Filters
if (grdOpt.filterRowDto?.allowUserUiFilterSave || grdOpt.stateStoringDto?.enabled) { if (grdOpt.filterRowDto?.allowUserUiFilterSave || grdOpt.stateStoringDto?.enabled) {
//Kullanicinin filtre islemi yapmasina izin verilmis ise filtreleme menu elemanlarini ekle //Kullanicinin filtre islemi yapmasina izin verilmis ise filtreleme menu elemanlarini ekle
@ -126,7 +120,7 @@ const useFilters = ({
menus.push({ menus.push({
text: translate('::ListForms.ListForm.RemoveFilter'), text: translate('::ListForms.ListForm.RemoveFilter'),
id: 'clearFilter', id: 'clearFilter',
icon: 'clear', icon: 'close',
}) })
} }
@ -135,7 +129,7 @@ const useFilters = ({
menus.push({ menus.push({
text: translate('::ListForms.ListForm.ResetGridState'), text: translate('::ListForms.ListForm.ResetGridState'),
id: 'resetGridState', id: 'resetGridState',
icon: 'return', icon: 'refresh',
}) })
} }
@ -143,7 +137,7 @@ const useFilters = ({
menus.push({ menus.push({
text: translate('::ListForms.ListForm.Manage'), text: translate('::ListForms.ListForm.Manage'),
id: 'openManage', id: 'openManage',
icon: 'info', icon: 'preferences',
}) })
} }
@ -151,7 +145,7 @@ const useFilters = ({
menus.push({ menus.push({
text: translate('::ListForms.ListForm.ImportManager'), text: translate('::ListForms.ListForm.ImportManager'),
id: 'importManager', id: 'importManager',
icon: 'import', icon: 'upload',
}) })
} }
@ -183,8 +177,6 @@ const useFilters = ({
} else if (itemData.id === 'deleteFilter') { } else if (itemData.id === 'deleteFilter') {
// Kayitli bir filtreyi silmek icin ilgili ekrani ac // Kayitli bir filtreyi silmek icin ilgili ekrani ac
setIsDeleteModalOpen(true) setIsDeleteModalOpen(true)
} else if (itemData.id === 'openPivotGrid') {
navigate(ROUTES_ENUM.protected.admin.pivot.replace(':listFormCode', listFormCode))
} else if (itemData.id === 'openManage') { } else if (itemData.id === 'openManage') {
window.open( window.open(
ROUTES_ENUM.protected.saas.listFormManagement.edit.replace( ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(