Tree ile Gantt birbirinden ayrıldı

This commit is contained in:
Sedat ÖZTÜRK 2025-12-02 12:56:11 +03:00
parent 5a4244dee3
commit 0681eb9479
17 changed files with 630 additions and 332 deletions

View file

@ -0,0 +1,62 @@
namespace Erp.Platform.ListForms;
/// <summary>
/// TreeList için özel ayarları içerir
/// </summary>
public class GanttOptionDto
{
/// <summary>
/// Parent kaydı belirten field adı (örn: "Id")
/// </summary>
public string KeyExpr { get; set; }
/// <summary>
/// Parent kaydı belirten field adı (örn: "parentId")
/// </summary>
public string ParentIdExpr { get; set; }
/// <summary>
/// Alt kayıtların olup olmadığını belirten field adı (opsiyonel)
/// </summary>
public string HasItemsExpr { get; set; }
/// <summary>
/// Root (en üst) seviyedeki kayıtların parent değeri (genelde null veya 0)
/// </summary>
public object RootValue { get; set; } = null;
/// <summary>
/// Başlangıçta açık olacak node'ların ID'leri
/// </summary>
public object[] ExpandedRowKeys { get; set; } = [];
/// <summary>
/// Tüm node'ları başlangıçta açık göster
/// </summary>
public bool AutoExpandAll { get; set; } = false;
/// <summary>
/// Alt kayıtlar seçildiğinde parent kayıtları da seç (recursive selection)
/// </summary>
public bool RecursiveSelection { get; set; } = false;
/// <summary>
/// Başlık alanı (örn: "Title")
/// </summary>
public string TitleExpr { get; set; }
/// <summary>
/// Başlangıç Tarihi ifadesi (örn: "0001-01-01")
/// </summary>
public string StartExpr { get; set; }
/// <summary>
/// Bitiş Tarihi ifadesi (örn: "9999-12-31")
/// </summary>
public string EndExpr { get; set; }
/// <summary>
/// İlerleme ifadesi (örn: "%50")
/// </summary>
public string ProgressExpr { get; set; }
}

View file

@ -164,6 +164,19 @@ public class GridOptionsDto : AuditedEntityDto<Guid>
set { TreeOptionJson = JsonSerializer.Serialize(value); }
}
[JsonIgnore]
public string GanttOptionJson { get; set; }
public GanttOptionDto GanttOptionDto
{
get
{
if (!string.IsNullOrEmpty(GanttOptionJson))
return JsonSerializer.Deserialize<GanttOptionDto>(GanttOptionJson);
return new GanttOptionDto();
}
set { GanttOptionJson = JsonSerializer.Serialize(value); }
}
[JsonIgnore]
public string PagerOptionJson { get; set; }
public GridPagerOptionDto PagerOptionDto

View file

@ -47,6 +47,7 @@ public class ListFormEditTabs
public const string ColumnForm = "column";
public const string PivotForm = "pivot";
public const string TreeForm = "tree";
public const string GanttForm = "gantt";
public const string PagerForm = "pager";
public const string StateForm = "state";
public const string SubFormJsonRow = "subForm";

View file

@ -151,6 +151,10 @@ public class ListFormsAppService : CrudAppService<
{
item.TreeOptionJson = JsonSerializer.Serialize(input.TreeOptionDto);
}
else if (input.EditType == ListFormEditTabs.GanttForm)
{
item.GanttOptionJson = JsonSerializer.Serialize(input.GanttOptionDto);
}
else if (input.EditType == ListFormEditTabs.PagerForm)
{
item.PageSize = input.PageSize;

View file

@ -3592,8 +3592,14 @@
{
"resourceName": "Platform",
"key": "ListForms.ListFormEdit.TabTree",
"en": "Tree & Gantt",
"tr": "Ağaç & Gantt"
"en": "Tree",
"tr": "Ağaç"
},
{
"resourceName": "Platform",
"key": "ListForms.ListFormEdit.TabGantt",
"en": "Gantt",
"tr": "Gantt"
},
{
"resourceName": "Platform",

View file

@ -2103,7 +2103,7 @@ public class ListFormSeeder_Project : IDataSeedContributor, ITransientDependency
SelectionJson = DefaultSelectionSingleJson,
ColumnOptionJson = DefaultColumnOptionJson,
PermissionJson = DefaultPermissionJson(listFormName),
TreeOptionJson = JsonSerializer.Serialize(new TreeOptionDto
GanttOptionJson = JsonSerializer.Serialize(new GanttOptionDto
{
KeyExpr = "Id",
ParentIdExpr = "ParentId",

View file

@ -33,7 +33,8 @@ public class ListForm : FullAuditedEntity<Guid>
public string DefaultFilter { get; set; } // Her sorgunun sonuna eklenecek default WHERE condition
public string ColumnOptionJson { get; set; }
public string PivotOptionJson { get; set; }
public string TreeOptionJson { get; set; }
public string TreeOptionJson { get; set; } // Tree yapisi ile ilgili ayarlar
public string GanttOptionJson { get; set; } // Gantt yapisi ile ilgili ayarlar
public string FilterRowJson { get; set; } // Filtre ayarlari, Json olarak tutulur, donus sinifi FilterRowDto
public string RowJson { get; set; } // Row ayarları, Json olarak tutulur, donus sinifi FilterRowDto
public string HeaderFilterJson { get; set; } // Header filtreleme ayarlari, Json olarak tutulur

View file

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Erp.Platform.Migrations
{
[DbContext(typeof(PlatformDbContext))]
[Migration("20251201104936_Initial")]
[Migration("20251202094339_Initial")]
partial class Initial
{
/// <inheritdoc />
@ -6173,6 +6173,9 @@ namespace Erp.Platform.Migrations
b.Property<bool>("FullHeight")
.HasColumnType("bit");
b.Property<string>("GanttOptionJson")
.HasColumnType("nvarchar(max)");
b.Property<string>("GroupPanelJson")
.HasColumnType("text");

View file

@ -2246,6 +2246,7 @@ namespace Erp.Platform.Migrations
ColumnOptionJson = table.Column<string>(type: "text", nullable: true),
PivotOptionJson = table.Column<string>(type: "text", nullable: true),
TreeOptionJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
GanttOptionJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
FilterRowJson = table.Column<string>(type: "text", nullable: true),
RowJson = table.Column<string>(type: "nvarchar(max)", nullable: true),
HeaderFilterJson = table.Column<string>(type: "text", nullable: true),

View file

@ -6170,6 +6170,9 @@ namespace Erp.Platform.Migrations
b.Property<bool>("FullHeight")
.HasColumnType("bit");
b.Property<string>("GanttOptionJson")
.HasColumnType("nvarchar(max)");
b.Property<string>("GroupPanelJson")
.HasColumnType("text");

View file

@ -42,6 +42,7 @@ export const ListFormEditTabs = {
ColumnForm: 'column',
PivotForm: 'pivot',
TreeForm: 'tree',
GanttForm: 'gantt',
PagerForm: 'pager',
StateForm: 'state',
SubForm: 'subForm',
@ -90,6 +91,7 @@ export const tabVisibilityConfig: Record<string, string[]> = {
'columns',
'pivots',
'tree',
'gantt',
'pager',
'state',
'extrafilter',

View file

@ -386,6 +386,16 @@ export interface TreeOptionDto {
expandedRowKeys?: any[]
autoExpandAll?: boolean
recursiveSelection?: boolean
}
export interface GanttOptionDto {
keyExpr?: string
parentIdExpr?: string
hasItemsExpr?: string
rootValue?: any
expandedRowKeys?: any[]
autoExpandAll?: boolean
recursiveSelection?: boolean
titleExpr?: string
startExpr?: string
endExpr?: string
@ -490,6 +500,8 @@ export interface GridOptionsDto extends AuditedEntityDto<string> {
pivotOptionDto: GridPivotOptionDto
treeOptionJson?: string
treeOptionDto: TreeOptionDto
ganttOptionJson?: string
ganttOptionDto: GanttOptionDto
pagerOptionJson?: string
pagerOptionDto: GridPagerOptionDto
editingOptionJson?: string

View file

@ -36,7 +36,7 @@ import FormTabWidgets from './FormTabWidgets'
import FormTabExtraFilters from './FormTabExtraFilters'
import FormTabEditForm from './FormTabEditForm'
import FormTabPivots from './FormTabPivots'
import FormTabTreeGantt from './FormTabTreeGantt'
import FormTabTree from './FormTabTree'
import ChartTabAnimation from './ChartTabAnimation'
import ChartTabAnnotations from './ChartTabAnnotations'
import ChartTabZoomAndPan from './ChartTabZoomAndPan'
@ -50,6 +50,7 @@ import ChartTabPanes from './ChartTabPanes'
import { tabVisibilityConfig } from '@/proxy/admin/list-form/options'
import FormTabSorting from './FormTabSorting'
import FormTabRow from './FormTabRow'
import FormTabGantt from './FormTabGantt'
export interface FormEditProps {
onSubmit: (
@ -236,6 +237,9 @@ const FormEdit = () => {
{visibleTabs.includes('tree') && (
<TabNav value="tree">{translate('::ListForms.ListFormEdit.TabTree')}</TabNav>
)}
{visibleTabs.includes('gantt') && (
<TabNav value="gantt">{translate('::ListForms.ListFormEdit.TabGantt')}</TabNav>
)}
{visibleTabs.includes('pager') && (
<TabNav value="pager">{translate('::ListForms.ListFormEdit.TabPaging')}</TabNav>
)}
@ -360,7 +364,10 @@ const FormEdit = () => {
<FormTabPivots onSubmit={onSubmit} />
</TabContent>
<TabContent value="tree" className="px-2">
<FormTabTreeGantt onSubmit={onSubmit} />
<FormTabTree onSubmit={onSubmit} />
</TabContent>
<TabContent value="gantt" className="px-2">
<FormTabGantt onSubmit={onSubmit} />
</TabContent>
<TabContent value="pager" className="px-2">
<FormTabPager onSubmit={onSubmit} />

View file

@ -0,0 +1,300 @@
import {
Button,
Notification,
Checkbox,
FormContainer,
FormItem,
Input,
Select,
toast,
Card,
} from '@/components/ui'
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
import { useStoreState } from '@/store'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Field, FieldProps, Form, Formik } from 'formik'
import * as Yup from 'yup'
import { FormEditProps } from './FormEdit'
import { SelectBoxOption } from '@/types/shared'
import { useEffect, useState } from 'react'
import { getListFormFields } from '@/services/admin/list-form-field.service'
import { groupBy } from 'lodash'
import { useParams } from 'react-router-dom'
const validationSchema = Yup.object().shape({})
function FormTabGantt(props: FormEditProps) {
const { listFormCode } = useParams()
const { translate } = useLocalization()
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
const getFields = async () => {
if (!listFormCode) {
return
}
try {
const resp = await getListFormFields({
listFormCode,
sorting: 'ListOrderNo',
maxResultCount: 1000,
})
if (resp.data?.items) {
const fieldNames = groupBy(resp?.data?.items, 'fieldName')
setFieldList(
Object.keys(fieldNames).map((a) => ({
value: a,
label: a,
})),
)
}
} catch (error: any) {
toast.push(
<Notification type="danger" duration={2000}>
Alanlar getirilemedi
{error.toString()}
</Notification>,
{
placement: 'top-end',
},
)
}
}
useEffect(() => {
getFields()
}, [listFormCode])
const listFormValues = useStoreState((s) => s.admin.lists.values)
if (!listFormValues) {
return null
}
return (
<Formik
initialValues={listFormValues}
validationSchema={validationSchema}
onSubmit={async (values, formikHelpers) => {
await props.onSubmit(ListFormEditTabs.GanttForm, values, formikHelpers)
}}
>
{({ touched, errors, isSubmitting, values }) => (
<Form>
<FormContainer size="sm">
<FormItem
label={translate('::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName')}
invalid={errors.ganttOptionDto?.keyExpr && touched.ganttOptionDto?.keyExpr}
errorMessage={errors.ganttOptionDto?.keyExpr}
>
<Field
type="text"
name="ganttOptionDto.keyExpr"
placeholder={translate('::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.ganttOptionDto.keyExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.ParentIdExpr')}
invalid={errors.ganttOptionDto?.parentIdExpr && touched.ganttOptionDto?.parentIdExpr}
errorMessage={errors.ganttOptionDto?.parentIdExpr}
>
<Field
type="text"
name="ganttOptionDto.parentIdExpr"
placeholder={translate('::ListForms.ListFormEdit.ParentIdExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.ganttOptionDto.parentIdExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.HasItemsExpr')}
invalid={errors.ganttOptionDto?.hasItemsExpr && touched.ganttOptionDto?.hasItemsExpr}
errorMessage={errors.ganttOptionDto?.hasItemsExpr}
>
<Field
type="text"
autoComplete="off"
name="ganttOptionDto.hasItemsExpr"
placeholder={translate('::ListForms.ListFormEdit.HasItemsExpr')}
component={Input}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.RootValue')}
invalid={!!(errors.ganttOptionDto?.rootValue && touched.ganttOptionDto?.rootValue)}
errorMessage={errors.ganttOptionDto?.rootValue as string}
>
<Field
type="text"
autoComplete="off"
name="ganttOptionDto.rootValue"
placeholder={translate('::ListForms.ListFormEdit.RootValue')}
component={Input}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.AutoExpandAll')}
invalid={
errors.ganttOptionDto?.autoExpandAll && touched.ganttOptionDto?.autoExpandAll
}
errorMessage={errors.ganttOptionDto?.autoExpandAll}
>
<Field
name="ganttOptionDto.autoExpandAll"
placeholder={translate('::ListForms.ListFormEdit.AutoExpandAll')}
component={Checkbox}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.RecursiveSelection')}
invalid={
errors.ganttOptionDto?.recursiveSelection &&
touched.ganttOptionDto?.recursiveSelection
}
errorMessage={errors.ganttOptionDto?.recursiveSelection}
>
<Field
name="ganttOptionDto.recursiveSelection"
placeholder={translate('::ListForms.ListFormEdit.RecursiveSelection')}
component={Checkbox}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.TitleExpr')}
invalid={errors.ganttOptionDto?.titleExpr && touched.ganttOptionDto?.titleExpr}
errorMessage={errors.ganttOptionDto?.titleExpr}
>
<Field
type="text"
name="ganttOptionDto.titleExpr"
placeholder={translate('::ListForms.ListFormEdit.TitleExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.ganttOptionDto.titleExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.StartExpr')}
invalid={errors.ganttOptionDto?.startExpr && touched.ganttOptionDto?.startExpr}
errorMessage={errors.ganttOptionDto?.startExpr}
>
<Field
type="text"
name="ganttOptionDto.startExpr"
placeholder={translate('::ListForms.ListFormEdit.StartExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.ganttOptionDto.startExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.EndExpr')}
invalid={errors.ganttOptionDto?.endExpr && touched.ganttOptionDto?.endExpr}
errorMessage={errors.ganttOptionDto?.endExpr}
>
<Field
type="text"
name="ganttOptionDto.endExpr"
placeholder={translate('::ListForms.ListFormEdit.EndExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.ganttOptionDto.endExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.ProgressExpr')}
invalid={errors.ganttOptionDto?.progressExpr && touched.ganttOptionDto?.progressExpr}
errorMessage={errors.ganttOptionDto?.progressExpr}
>
<Field
type="text"
name="ganttOptionDto.progressExpr"
placeholder={translate('::ListForms.ListFormEdit.ProgressExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.ganttOptionDto.progressExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<Button block variant="solid" loading={isSubmitting} type="submit" className="my-2">
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
</Button>
</FormContainer>
</Form>
)}
</Formik>
)
}
export default FormTabGantt

View file

@ -0,0 +1,198 @@
import {
Button,
Notification,
Checkbox,
FormContainer,
FormItem,
Input,
Select,
toast,
Card,
} from '@/components/ui'
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
import { useStoreState } from '@/store'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Field, FieldProps, Form, Formik } from 'formik'
import * as Yup from 'yup'
import { FormEditProps } from './FormEdit'
import { SelectBoxOption } from '@/types/shared'
import { useEffect, useState } from 'react'
import { getListFormFields } from '@/services/admin/list-form-field.service'
import { groupBy } from 'lodash'
import { useParams } from 'react-router-dom'
const validationSchema = Yup.object().shape({})
function FormTabTree(props: FormEditProps) {
const { listFormCode } = useParams()
const { translate } = useLocalization()
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
const getFields = async () => {
if (!listFormCode) {
return
}
try {
const resp = await getListFormFields({
listFormCode,
sorting: 'ListOrderNo',
maxResultCount: 1000,
})
if (resp.data?.items) {
const fieldNames = groupBy(resp?.data?.items, 'fieldName')
setFieldList(
Object.keys(fieldNames).map((a) => ({
value: a,
label: a,
})),
)
}
} catch (error: any) {
toast.push(
<Notification type="danger" duration={2000}>
Alanlar getirilemedi
{error.toString()}
</Notification>,
{
placement: 'top-end',
},
)
}
}
useEffect(() => {
getFields()
}, [listFormCode])
const listFormValues = useStoreState((s) => s.admin.lists.values)
if (!listFormValues) {
return null
}
return (
<Formik
initialValues={listFormValues}
validationSchema={validationSchema}
onSubmit={async (values, formikHelpers) => {
await props.onSubmit(ListFormEditTabs.TreeForm, values, formikHelpers)
}}
>
{({ touched, errors, isSubmitting, values }) => (
<Form>
<FormContainer size="sm">
<FormItem
label={translate('::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName')}
invalid={errors.treeOptionDto?.keyExpr && touched.treeOptionDto?.keyExpr}
errorMessage={errors.treeOptionDto?.keyExpr}
>
<Field
type="text"
name="treeOptionDto.keyExpr"
placeholder={translate('::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.treeOptionDto.keyExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.ParentIdExpr')}
invalid={errors.treeOptionDto?.parentIdExpr && touched.treeOptionDto?.parentIdExpr}
errorMessage={errors.treeOptionDto?.parentIdExpr}
>
<Field
type="text"
name="treeOptionDto.parentIdExpr"
placeholder={translate('::ListForms.ListFormEdit.ParentIdExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.treeOptionDto.parentIdExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.HasItemsExpr')}
invalid={errors.treeOptionDto?.hasItemsExpr && touched.treeOptionDto?.hasItemsExpr}
errorMessage={errors.treeOptionDto?.hasItemsExpr}
>
<Field
type="text"
autoComplete="off"
name="treeOptionDto.hasItemsExpr"
placeholder={translate('::ListForms.ListFormEdit.HasItemsExpr')}
component={Input}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.RootValue')}
invalid={!!(errors.treeOptionDto?.rootValue && touched.treeOptionDto?.rootValue)}
errorMessage={errors.treeOptionDto?.rootValue as string}
>
<Field
type="text"
autoComplete="off"
name="treeOptionDto.rootValue"
placeholder={translate('::ListForms.ListFormEdit.RootValue')}
component={Input}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.AutoExpandAll')}
invalid={errors.treeOptionDto?.autoExpandAll && touched.treeOptionDto?.autoExpandAll}
errorMessage={errors.treeOptionDto?.autoExpandAll}
>
<Field
name="treeOptionDto.autoExpandAll"
placeholder={translate('::ListForms.ListFormEdit.AutoExpandAll')}
component={Checkbox}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.RecursiveSelection')}
invalid={
errors.treeOptionDto?.recursiveSelection &&
touched.treeOptionDto?.recursiveSelection
}
errorMessage={errors.treeOptionDto?.recursiveSelection}
>
<Field
name="treeOptionDto.recursiveSelection"
placeholder={translate('::ListForms.ListFormEdit.RecursiveSelection')}
component={Checkbox}
/>
</FormItem>
<Button block variant="solid" loading={isSubmitting} type="submit" className="my-2">
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
</Button>
</FormContainer>
</Form>
)}
</Formik>
)
}
export default FormTabTree

View file

@ -1,315 +0,0 @@
import { Container } from '@/components/shared'
import {
Button,
Notification,
Checkbox,
FormContainer,
FormItem,
Input,
Select,
toast,
Card,
} from '@/components/ui'
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
import { useStoreState } from '@/store'
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Field, FieldProps, Form, Formik } from 'formik'
import * as Yup from 'yup'
import { FormEditProps } from './FormEdit'
import { SelectBoxOption } from '@/types/shared'
import { useEffect, useState } from 'react'
import { getListFormFields } from '@/services/admin/list-form-field.service'
import { groupBy } from 'lodash'
import { useParams } from 'react-router-dom'
const validationSchema = Yup.object().shape({})
function FormTabTreeGantt(props: FormEditProps) {
const { listFormCode } = useParams()
const { translate } = useLocalization()
const [fieldList, setFieldList] = useState<SelectBoxOption[]>([])
const getFields = async () => {
if (!listFormCode) {
return
}
try {
const resp = await getListFormFields({
listFormCode,
sorting: 'ListOrderNo',
maxResultCount: 1000,
})
if (resp.data?.items) {
const fieldNames = groupBy(resp?.data?.items, 'fieldName')
setFieldList(
Object.keys(fieldNames).map((a) => ({
value: a,
label: a,
})),
)
}
} catch (error: any) {
toast.push(
<Notification type="danger" duration={2000}>
Alanlar getirilemedi
{error.toString()}
</Notification>,
{
placement: 'top-end',
},
)
}
}
useEffect(() => {
getFields()
}, [listFormCode])
const listFormValues = useStoreState((s) => s.admin.lists.values)
if (!listFormValues) {
return null
}
return (
<Formik
initialValues={listFormValues}
validationSchema={validationSchema}
onSubmit={async (values, formikHelpers) => {
await props.onSubmit(ListFormEditTabs.TreeForm, values, formikHelpers)
}}
>
{({ touched, errors, isSubmitting, values }) => (
<Form>
<FormContainer size="sm">
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
<Card className="my-2" header="Tree Options">
<FormItem
label={translate('::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName')}
invalid={errors.treeOptionDto?.keyExpr && touched.treeOptionDto?.keyExpr}
errorMessage={errors.treeOptionDto?.keyExpr}
>
<Field
type="text"
name="treeOptionDto.keyExpr"
placeholder={translate(
'::ListForms.ListFormEdit.DatabaseDataSourceKeyFieldName',
)}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.treeOptionDto.keyExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.ParentIdExpr')}
invalid={
errors.treeOptionDto?.parentIdExpr && touched.treeOptionDto?.parentIdExpr
}
errorMessage={errors.treeOptionDto?.parentIdExpr}
>
<Field
type="text"
name="treeOptionDto.parentIdExpr"
placeholder={translate('::ListForms.ListFormEdit.ParentIdExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.treeOptionDto.parentIdExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.HasItemsExpr')}
invalid={
errors.treeOptionDto?.hasItemsExpr && touched.treeOptionDto?.hasItemsExpr
}
errorMessage={errors.treeOptionDto?.hasItemsExpr}
>
<Field
type="text"
autoComplete="off"
name="treeOptionDto.hasItemsExpr"
placeholder={translate('::ListForms.ListFormEdit.HasItemsExpr')}
component={Input}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.RootValue')}
invalid={!!(errors.treeOptionDto?.rootValue && touched.treeOptionDto?.rootValue)}
errorMessage={errors.treeOptionDto?.rootValue as string}
>
<Field
type="text"
autoComplete="off"
name="treeOptionDto.rootValue"
placeholder={translate('::ListForms.ListFormEdit.RootValue')}
component={Input}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.AutoExpandAll')}
invalid={
errors.treeOptionDto?.autoExpandAll && touched.treeOptionDto?.autoExpandAll
}
errorMessage={errors.treeOptionDto?.autoExpandAll}
>
<Field
name="treeOptionDto.autoExpandAll"
placeholder={translate('::ListForms.ListFormEdit.AutoExpandAll')}
component={Checkbox}
/>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.RecursiveSelection')}
invalid={
errors.treeOptionDto?.recursiveSelection &&
touched.treeOptionDto?.recursiveSelection
}
errorMessage={errors.treeOptionDto?.recursiveSelection}
>
<Field
name="treeOptionDto.recursiveSelection"
placeholder={translate('::ListForms.ListFormEdit.RecursiveSelection')}
component={Checkbox}
/>
</FormItem>
</Card>
<Card className="my-2" header="Gantt Options">
<FormItem
label={translate('::ListForms.ListFormEdit.TitleExpr')}
invalid={errors.treeOptionDto?.titleExpr && touched.treeOptionDto?.titleExpr}
errorMessage={errors.treeOptionDto?.titleExpr}
>
<Field
type="text"
name="treeOptionDto.titleExpr"
placeholder={translate('::ListForms.ListFormEdit.TitleExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.treeOptionDto.titleExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.StartExpr')}
invalid={errors.treeOptionDto?.startExpr && touched.treeOptionDto?.startExpr}
errorMessage={errors.treeOptionDto?.startExpr}
>
<Field
type="text"
name="treeOptionDto.startExpr"
placeholder={translate('::ListForms.ListFormEdit.StartExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.treeOptionDto.startExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.EndExpr')}
invalid={errors.treeOptionDto?.endExpr && touched.treeOptionDto?.endExpr}
errorMessage={errors.treeOptionDto?.endExpr}
>
<Field
type="text"
name="treeOptionDto.endExpr"
placeholder={translate('::ListForms.ListFormEdit.EndExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.treeOptionDto.endExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
<FormItem
label={translate('::ListForms.ListFormEdit.ProgressExpr')}
invalid={
errors.treeOptionDto?.progressExpr && touched.treeOptionDto?.progressExpr
}
errorMessage={errors.treeOptionDto?.progressExpr}
>
<Field
type="text"
name="treeOptionDto.progressExpr"
placeholder={translate('::ListForms.ListFormEdit.ProgressExpr')}
>
{({ field, form }: FieldProps<SelectBoxOption>) => (
<Select
field={field}
form={form}
isClearable={true}
options={fieldList}
value={fieldList?.filter(
(option) => option.value === values.treeOptionDto.progressExpr,
)}
onChange={(option) => form.setFieldValue(field.name, option?.value)}
/>
)}
</Field>
</FormItem>
</Card>
</div>
<Button block variant="solid" loading={isSubmitting} type="submit" className="my-2">
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
</Button>
</FormContainer>
</Form>
)}
</Formik>
)
}
export default FormTabTreeGantt

View file

@ -216,10 +216,10 @@ const GanttView = (props: GanttViewProps) => {
taskListWidth={500}
scaleType={scaleType}
rootValue={
gridDto.gridOptions.treeOptionDto?.rootValue === '' ||
gridDto.gridOptions.treeOptionDto?.rootValue === undefined
gridDto.gridOptions.ganttOptionDto?.rootValue === '' ||
gridDto.gridOptions.ganttOptionDto?.rootValue === undefined
? null
: gridDto.gridOptions.treeOptionDto?.rootValue
: gridDto.gridOptions.ganttOptionDto?.rootValue
}
height={
gridDto.gridOptions.height > 0
@ -231,12 +231,12 @@ const GanttView = (props: GanttViewProps) => {
>
<Tasks
dataSource={ganttDataSource}
keyExpr={gridDto.gridOptions.treeOptionDto?.keyExpr}
parentIdExpr={gridDto.gridOptions.treeOptionDto?.parentIdExpr}
titleExpr={gridDto.gridOptions.treeOptionDto?.titleExpr}
startExpr={gridDto.gridOptions.treeOptionDto?.startExpr}
endExpr={gridDto.gridOptions.treeOptionDto?.endExpr}
progressExpr={gridDto.gridOptions.treeOptionDto?.progressExpr}
keyExpr={gridDto.gridOptions.ganttOptionDto?.keyExpr}
parentIdExpr={gridDto.gridOptions.ganttOptionDto?.parentIdExpr}
titleExpr={gridDto.gridOptions.ganttOptionDto?.titleExpr}
startExpr={gridDto.gridOptions.ganttOptionDto?.startExpr}
endExpr={gridDto.gridOptions.ganttOptionDto?.endExpr}
progressExpr={gridDto.gridOptions.ganttOptionDto?.progressExpr}
/>
<Toolbar>