Grid, Tree, Chart, Pivot Toolbar style

This commit is contained in:
Sedat ÖZTÜRK 2026-06-18 17:03:22 +03:00
parent 866d9f1e85
commit 76621b24d8
8 changed files with 349 additions and 206 deletions

View file

@ -113,6 +113,140 @@ div.dialog-after-open > div.dialog-content.maximized {
padding: 0 0 !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel {
min-height: 37px;
background-color: transparent !important;
}
.dark .dx-datagrid-header-panel.pivot-toolbar-panel {
background-color: #202020 !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel .button,
.dx-datagrid-header-panel.pivot-toolbar-panel .dx-button,
.dx-datagrid-header-panel.pivot-toolbar-panel button {
background-color: transparent !important;
border-color: transparent !important;
border-radius: 0 !important;
padding: 0 !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel .relative.flex {
gap: 4px !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel > .dx-toolbar {
width: 100% !important;
background-color: transparent !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel > .dx-toolbar .dx-toolbar-items-container {
min-height: 28px !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel > .dx-toolbar .dx-toolbar-before {
width: auto !important;
max-width: none !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel > .dx-toolbar .dx-toolbar-after {
width: auto !important;
max-width: none !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel > .dx-toolbar .dx-toolbar-after .dx-toolbar-item {
padding-inline: 2px !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel > .dx-toolbar .dx-button-content {
padding-block: 4px !important;
padding-inline: 6px !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel .chart-toolbar-search {
width: 160px;
height: 32px;
padding: 6px 12px 6px 34px;
border: 0 !important;
border-bottom: 1px solid #d1d5db !important;
border-radius: 0 !important;
background-color: #fff;
}
.dark .dx-datagrid-header-panel.pivot-toolbar-panel .chart-toolbar-search {
background-color: #2d2d2d !important;
border-bottom-color: #6b7280 !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel > .dx-toolbar .dx-toolbar-menu-container .dx-button {
border-radius: 50% !important;
}
.dark
.dx-datagrid-header-panel.pivot-toolbar-panel
> .dx-toolbar
.dx-toolbar-menu-container
.dx-button {
background-color: #343440 !important;
border-color: #343440 !important;
}
.dark
.dx-datagrid-header-panel.pivot-toolbar-panel
> .dx-toolbar
.dx-toolbar-menu-container
.dx-button:hover {
background-color: #424250 !important;
border-color: #424250 !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel
> .dx-toolbar
.dx-toolbar-menu-container
.dx-button-content {
padding: 4px !important;
}
.dark .dx-datagrid-header-panel.pivot-toolbar-panel .button,
.dark .dx-datagrid-header-panel.pivot-toolbar-panel .dx-button,
.dark .dx-datagrid-header-panel.pivot-toolbar-panel button {
background-color: transparent !important;
border-color: transparent !important;
color: #fff !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel .dx-button-text {
text-transform: none !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel .button:hover,
.dx-datagrid-header-panel.pivot-toolbar-panel .dx-button:hover,
.dx-datagrid-header-panel.pivot-toolbar-panel button:hover {
background-color: #dedede !important;
}
.dark .dx-datagrid-header-panel.pivot-toolbar-panel .button:hover,
.dark .dx-datagrid-header-panel.pivot-toolbar-panel .dx-button:hover,
.dark .dx-datagrid-header-panel.pivot-toolbar-panel button:hover {
background-color: #2d2d2d !important;
}
.dx-datagrid-header-panel.pivot-toolbar-panel,
.dx-datagrid-header-panel.pivot-toolbar-panel .dx-button,
.dx-datagrid-header-panel.pivot-toolbar-panel .dx-button-text,
.dx-datagrid-header-panel.pivot-toolbar-panel svg {
color: #000 !important;
}
.dark .dx-datagrid-header-panel.pivot-toolbar-panel,
.dark .dx-datagrid-header-panel.pivot-toolbar-panel .button,
.dark .dx-datagrid-header-panel.pivot-toolbar-panel .dx-button,
.dark .dx-datagrid-header-panel.pivot-toolbar-panel .dx-button-text,
.dark .dx-datagrid-header-panel.pivot-toolbar-panel button,
.dark .dx-datagrid-header-panel.pivot-toolbar-panel svg {
color: #fff !important;
}
.dx-datagrid-header-panel > .dx-toolbar .dx-toolbar-before,
.dx-treelist-header-panel > .dx-toolbar .dx-toolbar-before {
width: 50% !important;

View file

@ -9,10 +9,10 @@ import { Helmet } from 'react-helmet'
import { useParams, useSearchParams } from 'react-router-dom'
import { GridDto } from '@/proxy/form/models'
import { usePermission } from '@/utils/hooks/usePermission'
import { Button, toast, Notification } from '@/components/ui'
import { toast, Notification } from '@/components/ui'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { usePWA } from '@/utils/hooks/usePWA'
import { FaCog, FaCrosshairs, FaSearch, FaSyncAlt } from 'react-icons/fa'
import { FaSearch } from 'react-icons/fa'
import { buildSeriesDto } from './Utils'
import { ChartSeriesDto } from '@/proxy/admin/charts/models'
import { SelectBoxOption } from '@/types/shared'
@ -29,6 +29,7 @@ import {
} from '@/services/admin/list-form.service'
import { layoutTypes } from '../admin/listForm/edit/types'
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
import Toolbar, { Item } from 'devextreme-react/toolbar'
interface ChartProps extends CommonProps, Meta {
id: string
@ -327,82 +328,95 @@ const Chart = (props: ChartProps) => {
></Helmet>
)}
{_listFormCode && chartOptions && (
<div className="p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 h-full relative">
<div className="flex justify-end items-center h-full">
<div className="relative pb-1 flex gap-1 border-b-1">
<FaSearch className="absolute left-2 top-1/2 -translate-y-1/2 text-gray-400 text-sm" />
<input
type="text"
placeholder={translate('::App.Search')}
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
onFilter(e.currentTarget.value)
setPrevValue(e.currentTarget.value.trim()) // Enter ile tetiklenirse güncelle
}
}}
onBlur={(e) => {
const newValue = e.currentTarget.value.trim()
<div className="p-1">
<div className="dx-datagrid-header-panel pivot-toolbar-panel text-black dark:text-white">
<Toolbar width="100%">
<Item
location="before"
locateInMenu="never"
render={() => (
<div className="relative flex items-center">
<FaSearch className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-sm" />
<input
type="text"
placeholder={translate('::App.Search')}
value={searchText}
onChange={(e) => setSearchText(e.target.value)}
onKeyDown={(e) => {
if (e.key === 'Enter') {
onFilter(e.currentTarget.value)
setPrevValue(e.currentTarget.value.trim()) // Enter ile tetiklenirse güncelle
}
}}
onBlur={(e) => {
const newValue = e.currentTarget.value.trim()
// 1. Değer değişmemişse => hiçbir şey yapma
if (newValue === prevValue) return
// 1. Değer değişmemişse => hiçbir şey yapma
if (newValue === prevValue) return
// 2. Yeni değer boş, ama eskiden değer vardı => filtre temizle
// 3. Yeni değer dolu ve eskisinden farklı => filtre uygula
onFilter(newValue)
setPrevValue(newValue)
}}
className="p-1 pl-6 pr-2 border border-1 outline-none text-xs text-gray-700 dark:text-gray-200 placeholder-gray-400 rounded"
// 2. Yeni değer boş, ama eskiden değer vardı => filtre temizle
// 3. Yeni değer dolu ve eskisinden farklı => filtre uygula
onFilter(newValue)
setPrevValue(newValue)
}}
className="chart-toolbar-search outline-none text-xs text-gray-700 placeholder-gray-400 dark:text-gray-200 dark:placeholder-gray-400"
/>
</div>
)}
/>
<Button
size="sm"
variant={'default'}
icon={<FaSyncAlt className="w-3 h-3" />}
className="text-sm flex items-center gap-1"
onClick={async () => {
setInitialized(false)
await refreshGridDto?.()
<Item
location="after"
widget="dxButton"
locateInMenu="auto"
showText="always"
options={{
icon: 'refresh',
text: translate('::App.Platform.Refresh'),
hint: translate('::App.Platform.Refresh'),
onClick: async () => {
setInitialized(false)
await refreshGridDto?.()
},
}}
title={translate('::App.Platform.Refresh')}
>
{translate('::App.Platform.Refresh')}
</Button>
<Button
size="sm"
icon={<FaCrosshairs className="w-3 h-3" />}
variant="default"
className="text-sm flex items-center gap-1"
onClick={() => setOpenDrawer(true)}
title={translate('::ListForms.ListFormEdit.TabChartSeries')}
>
{translate('::ListForms.ListFormEdit.TabChartSeries')}
</Button>
/>
<Item
location="after"
widget="dxButton"
locateInMenu="auto"
showText="always"
options={{
icon: 'chart',
text: translate('::ListForms.ListFormEdit.TabChartSeries'),
hint: translate('::ListForms.ListFormEdit.TabChartSeries'),
onClick: () => setOpenDrawer(true),
}}
/>
{checkPermission(gridDto?.gridOptions.permissionDto.u) && (
<Button
size="sm"
icon={<FaCog className="w-3 h-3" />}
variant={'default'}
className="text-sm"
onClick={() => {
window.open(
ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(
':listFormCode',
listFormCode,
),
isPwaMode ? '_self' : '_blank',
)
<Item
location="after"
widget="dxButton"
locateInMenu="auto"
showText="always"
options={{
icon: 'preferences',
text: translate('::ListForms.ListForm.Manage'),
hint: translate('::ListForms.ListForm.Manage'),
onClick: () => {
window.open(
ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(
':listFormCode',
listFormCode,
),
isPwaMode ? '_self' : '_blank',
)
},
}}
title={translate('::ListForms.ListForm.Manage')}
></Button>
/>
)}
</div>
</Toolbar>
</div>
<div
className={`transition-all duration-300 ${openDrawer ? 'mr-[500px]' : 'mr-0'}`}
style={{ width: openDrawer ? 'calc(100% - 500px)' : '100%' }}
>
<div className="border border-gray-200 dark:border-gray-600">
<DxChart key={'DxChart' + _listFormCode} {...chartOptions}></DxChart>
</div>

View file

@ -90,7 +90,7 @@ const ChartDrawer = ({
<>
{/* Drawer */}
<div
className={`fixed right-0 top-0 h-full w-[500px] bg-white shadow-2xl z-50 transform transition-transform duration-300 border-l-2 border-gray-300 ${
className={`fixed right-0 top-0 h-full w-[500px] bg-white text-gray-900 shadow-2xl z-50 transform transition-transform duration-300 border-l-2 border-gray-300 dark:bg-gray-900 dark:text-gray-100 dark:border-gray-700 ${
open ? 'translate-x-0' : 'translate-x-full'
}`}
>
@ -139,8 +139,8 @@ const ChartDrawer = ({
return (
<Form className="flex flex-col h-full">
{/* Header */}
<div className="flex items-center justify-between p-4 border-b bg-gray-50">
<h2 className="text-lg font-semibold flex items-center gap-2">
<div className="flex items-center justify-between p-4 border-b border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-800">
<h2 className="text-lg font-semibold flex items-center gap-2 text-gray-900 dark:text-gray-100">
<span>📊</span>
{translate('::App.Platform.ChartDrawer.ChartSeries')}
</h2>
@ -155,7 +155,7 @@ const ChartDrawer = ({
<FormContainer size="sm" className="flex flex-col flex-1 overflow-hidden">
{/* Add Series Button */}
<div className="p-3 border-b">
<div className="p-3 border-b border-gray-200 dark:border-gray-700">
<Button
size="sm"
block
@ -180,11 +180,11 @@ const ChartDrawer = ({
{values.series.map((series, index) => (
<div
key={index}
className="border rounded-lg p-3 bg-gray-50 hover:bg-gray-100 transition-colors"
className="border border-gray-200 rounded-lg p-3 bg-gray-50 hover:bg-gray-100 transition-colors dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700"
>
{/* Header */}
<div className="flex items-center justify-between mb-3">
<span className="font-semibold text-sm">
<span className="font-semibold text-sm text-gray-900 dark:text-gray-100">
{translate('::App.Platform.ChartDrawer.Series')} #{index + 1}
</span>
<Button
@ -192,7 +192,7 @@ const ChartDrawer = ({
size="xs"
variant="plain"
icon={<FaMinus />}
className="border-0 text-red-500 hover:bg-red-100"
className="border-0 text-red-500 hover:bg-red-100 dark:text-red-400 dark:hover:bg-red-900/30"
onClick={() => {
remove(index)
}}
@ -201,7 +201,7 @@ const ChartDrawer = ({
{/* Chart Type Selector */}
<div className="mb-3">
<label className="text-xs font-medium mb-1 block">
<label className="text-xs font-medium mb-1 block text-gray-700 dark:text-gray-300">
{translate('::App.Platform.ChartDrawer.ChartType')}
</label>
<Field name={`series[${index}].type`}>
@ -214,7 +214,7 @@ const ChartDrawer = ({
selectedSeriesIndex === index ? -1 : index,
)
}
className="w-full px-3 py-2 text-left border rounded hover:bg-white flex items-center gap-2 transition-colors"
className="w-full px-3 py-2 text-left border border-gray-300 rounded bg-white hover:bg-gray-50 flex items-center gap-2 transition-colors dark:border-gray-600 dark:bg-gray-900 dark:hover:bg-gray-800"
>
<span className="text-xl">
{chartSeriesTypeOptions.find(
@ -228,7 +228,7 @@ const ChartDrawer = ({
</span>
</Button>
{selectedSeriesIndex === index && (
<div className="absolute z-50 mt-1 w-full bg-white border rounded-lg shadow-xl p-2">
<div className="absolute z-50 mt-1 w-full bg-white border border-gray-200 rounded-lg shadow-xl p-2 dark:bg-gray-900 dark:border-gray-700">
<div className="grid grid-cols-2 gap-2">
{chartSeriesTypeOptions.map((chartType) => (
<Button
@ -238,10 +238,10 @@ const ChartDrawer = ({
form.setFieldValue(field.name, chartType.label)
setSelectedSeriesIndex(-1)
}}
className={`p-2 rounded-lg hover:bg-blue-50 flex items-center gap-2 transition-all ${
className={`p-2 rounded-lg hover:bg-blue-50 flex items-center gap-2 transition-all dark:hover:bg-blue-900/30 ${
field.value === chartType.label
? 'bg-blue-100 ring-2 ring-blue-400'
: 'bg-gray-50'
? 'bg-blue-100 ring-2 ring-blue-400 dark:bg-blue-900/40 dark:ring-blue-500'
: 'bg-gray-50 dark:bg-gray-800'
}`}
>
<span className="text-xl">{chartType.icon}</span>
@ -260,7 +260,7 @@ const ChartDrawer = ({
{/* Name */}
<div className="mb-3">
<label className="text-xs font-medium mb-1 block">
<label className="text-xs font-medium mb-1 block text-gray-700 dark:text-gray-300">
{translate('::App.Listform.ListformField.Name')}
</label>
<Field
@ -274,7 +274,7 @@ const ChartDrawer = ({
{/* Argument Field */}
<div className="mb-3">
<label className="text-xs font-medium mb-1 block">
<label className="text-xs font-medium mb-1 block text-gray-700 dark:text-gray-300">
{translate('::App.Platform.ChartDrawer.ArgumentField')}
</label>
<Field name={`series[${index}].argumentField`}>
@ -300,7 +300,7 @@ const ChartDrawer = ({
{/* Value Field */}
<div className="mb-3">
<label className="text-xs font-medium mb-1 block">
<label className="text-xs font-medium mb-1 block text-gray-700 dark:text-gray-300">
{translate('::App.Platform.ChartDrawer.ValueField')}
</label>
<Field name={`series[${index}].valueField`}>
@ -326,7 +326,7 @@ const ChartDrawer = ({
{/* Summary Type */}
<div className="mb-3">
<label className="text-xs font-medium mb-1 block">
<label className="text-xs font-medium mb-1 block text-gray-700 dark:text-gray-300">
{translate('::App.Platform.ChartDrawer.SummaryType')}
</label>
<Field name={`series[${index}].summaryType`}>
@ -354,7 +354,7 @@ const ChartDrawer = ({
</div>
{/* Footer */}
<div className="p-4 border-t bg-gray-50 flex gap-2">
<div className="p-4 border-t border-gray-200 bg-gray-50 flex gap-2 dark:border-gray-700 dark:bg-gray-800">
<Button type="button" variant="plain" onClick={onClose} className="flex-1">
{translate('::Cancel')}
</Button>

View file

@ -187,7 +187,7 @@ const GanttView = (props: GanttViewProps) => {
return (
<>
<div ref={widgetGroupRef}>
<div ref={widgetGroupRef} className={(gridDto?.widgets?.length ?? 0) > 0 ? 'mt-2' : ''}>
<WidgetGroup widgetGroups={gridDto?.widgets ?? []} />
</div>

View file

@ -1402,7 +1402,7 @@ const Grid = (props: GridProps) => {
return (
<>
<div ref={widgetGroupRef} className="mt-2">
<div ref={widgetGroupRef} className={(gridDto?.widgets?.length ?? 0) > 0 ? 'mt-2' : ''}>
<WidgetGroup widgetGroups={gridDto?.widgets ?? []} />
</div>
@ -1556,9 +1556,7 @@ const Grid = (props: GridProps) => {
popup={{
deferRendering: true,
animation: {},
wrapperAttr: useMobileEditPopup
? { class: 'mobile-edit-popup' }
: undefined,
wrapperAttr: useMobileEditPopup ? { class: 'mobile-edit-popup' } : undefined,
title:
(mode === 'new' ? '✚ ' : '🖊️ ') +
translate('::' + gridDto.gridOptions.editingOptionDto?.popup?.title),
@ -1568,9 +1566,10 @@ const Grid = (props: GridProps) => {
width: useMobileEditPopup
? '100%'
: gridDto.gridOptions.editingOptionDto?.popup?.width,
height: useMobileEditPopup && isPopupFullScreen
? '100%'
: gridDto.gridOptions.editingOptionDto?.popup?.height,
height:
useMobileEditPopup && isPopupFullScreen
? '100%'
: gridDto.gridOptions.editingOptionDto?.popup?.height,
position: useMobileEditPopup
? {
my: 'top center',

View file

@ -32,8 +32,7 @@ import {
} from './Utils'
import { useFilters } from './useFilters'
import WidgetGroup from '@/components/common/WidgetGroup'
import { Button, Dropdown, Notification, toast } from '@/components/ui'
import { FaCaretDown, FaCog, FaSave, FaTimes, FaUndo } from 'react-icons/fa'
import { Notification, toast } from '@/components/ui'
import { usePermission } from '@/utils/hooks/usePermission'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { usePWA } from '@/utils/hooks/usePWA'
@ -42,6 +41,7 @@ import { useListFormCustomDataSource } from './useListFormCustomDataSource'
import { useListFormColumns } from './useListFormColumns'
import { useStoreState } from '@/store'
import Checkbox from '@/components/ui/Checkbox'
import Toolbar, { Item } from 'devextreme-react/toolbar'
interface PivotProps {
listFormCode: string
@ -263,6 +263,44 @@ const Pivot = (props: PivotProps) => {
})
}, [listFormCode, storageKey])
const savePivotGridState = useCallback(() => {
const instance = gridRef.current?.instance()
if (!instance) {
return
}
const ds = instance.getDataSource()
if (!ds || typeof ds.state !== 'function') {
return
}
const currentState = ds.state()
customSaveState(currentState)
.then(() => {
toast.push(
<Notification type="success" duration={2000}>
{translate('::ListForms.ListForm.GridStateSaved')}
</Notification>,
{ placement: 'top-end' },
)
})
.catch(() => {
toast.push(
<Notification type="danger" duration={2500}>
{translate('::ListForms.ListForm.GridStateSaveError')}
</Notification>,
{ placement: 'top-end' },
)
})
}, [customSaveState, translate])
const openFormManager = useCallback(() => {
window.open(
ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(':listFormCode', listFormCode),
isPwaMode ? '_self' : '_blank',
)
}, [isPwaMode, listFormCode])
useEffect(() => {
refListFormCode.current = listFormCode
}, [listFormCode])
@ -420,112 +458,72 @@ const Pivot = (props: PivotProps) => {
></Helmet>
)}
{gridDto && columnData && (
<div className="p-1 bg-white dark:bg-neutral-800 dark:border-neutral-700 ">
<div className="flex justify-end items-center text-black">
<div className="relative flex gap-1">
<label className="flex items-center gap-1 text-xs cursor-pointer dark:text-white">
<span>{translate('::ListForms.ListFormEdit.ShowChart')}</span>
<Checkbox checked={showChart} onChange={(checked) => setShowChart(checked)} />
</label>
<div className="dx-menu">
<Dropdown
placement="bottom-end"
renderTitle={
<Button
size="sm"
variant={'plain'}
icon={<FaCaretDown className="ml-2 w-2 h-3" />}
className="text-sm flex items-center gap-1 border-0"
title="Menu"
>
<i className="dx-icon dx-icon-overflow" style={{ fontSize: '17px' }}></i>
<span className="text-black dark:text-white" style={{ fontSize: '13px' }}>
{translate('::ListForms.ListForm.GridMenu')}
</span>
</Button>
}
>
<Dropdown.Item
eventKey="removeFilter"
onClick={clearPivotFilters}
className="px-2"
>
<span className="flex items-center gap-2">
<FaTimes className="w-3 h-3" />
<span>{translate('::ListForms.ListForm.RemoveFilter')}</span>
<div className="p-1">
<div className="dx-datagrid-header-panel pivot-toolbar-panel text-black">
<Toolbar width="100%">
<Item
location="before"
locateInMenu="never"
render={() => (
<label className="flex items-center gap-1 text-xs cursor-pointer">
<span className="font-medium">
{translate('::ListForms.ListFormEdit.ShowChart')}
</span>
</Dropdown.Item>
<Dropdown.Item
eventKey="saveGridState"
onClick={() => {
const instance = gridRef.current?.instance()
if (instance) {
const ds = instance.getDataSource()
if (ds && typeof ds.state === 'function') {
const currentState = ds.state()
customSaveState(currentState)
.then(() => {
toast.push(
<Notification type="success" duration={2000}>
{translate('::ListForms.ListForm.GridStateSaved')}
</Notification>,
{ placement: 'top-end' },
)
})
.catch(() => {
toast.push(
<Notification type="danger" duration={2500}>
{translate('::ListForms.ListForm.GridStateSaveError')}
</Notification>,
{ placement: 'top-end' },
)
})
}
}
}}
className="px-2"
>
<span className="flex items-center gap-2">
<FaSave className="w-3 h-3" />
<span>{translate('::ListForms.ListForm.SaveGridState')}</span>
</span>
</Dropdown.Item>
<Dropdown.Item
eventKey="resetGridState"
onClick={resetPivotGridState}
className="px-2"
>
<span className="flex items-center gap-2">
<FaUndo className="w-3 h-3" />
<span>{translate('::ListForms.ListForm.ResetGridState')}</span>
</span>
</Dropdown.Item>
{checkPermission(gridDto?.gridOptions.permissionDto.u) && (
<Dropdown.Item
eventKey="formManager"
onClick={() => {
window.open(
ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(
':listFormCode',
listFormCode,
),
isPwaMode ? '_self' : '_blank',
)
}}
className="px-2"
>
<span className="flex items-center gap-2">
<FaCog className="w-3 h-3" />
<span>{translate('::ListForms.ListForm.Manage')}</span>
</span>
</Dropdown.Item>
)}
</Dropdown>
</div>
</div>
<Checkbox checked={showChart} onChange={(checked) => setShowChart(checked)} />
</label>
)}
/>
<Item
location="after"
widget="dxButton"
locateInMenu="auto"
showText="always"
options={{
icon: 'clear',
text: translate('::ListForms.ListForm.RemoveFilter'),
hint: translate('::ListForms.ListForm.RemoveFilter'),
onClick: clearPivotFilters,
}}
/>
<Item
location="after"
widget="dxButton"
locateInMenu="auto"
showText="always"
options={{
icon: 'save',
text: translate('::ListForms.ListForm.SaveGridState'),
hint: translate('::ListForms.ListForm.SaveGridState'),
onClick: savePivotGridState,
}}
/>
<Item
location="after"
widget="dxButton"
locateInMenu="auto"
showText="always"
options={{
icon: 'undo',
text: translate('::ListForms.ListForm.ResetGridState'),
hint: translate('::ListForms.ListForm.ResetGridState'),
onClick: resetPivotGridState,
}}
/>
{checkPermission(gridDto?.gridOptions.permissionDto.u) && (
<Item
location="after"
widget="dxButton"
locateInMenu="auto"
showText="always"
options={{
icon: 'preferences',
text: translate('::ListForms.ListForm.Manage'),
hint: translate('::ListForms.ListForm.Manage'),
onClick: openFormManager,
}}
/>
)}
</Toolbar>
</div>
{showChart && (
<Chart ref={chartRef as any}>
@ -537,8 +535,6 @@ const Pivot = (props: PivotProps) => {
</Chart>
)}
<div className="dx-datagrid-header-panel h-1"></div>
<PivotGrid
ref={gridRef as any}
id={'Pivot-' + listFormCode}

View file

@ -523,7 +523,7 @@ const SchedulerView = (props: SchedulerViewProps) => {
return (
<>
<div ref={widgetGroupRef}>
<div ref={widgetGroupRef} className={(gridDto?.widgets?.length ?? 0) > 0 ? 'mt-2' : ''}>
<WidgetGroup widgetGroups={gridDto?.widgets ?? []} />
</div>

View file

@ -1060,7 +1060,7 @@ const Tree = (props: TreeProps) => {
return (
<>
<div ref={widgetGroupRef}>
<div ref={widgetGroupRef} className={(gridDto?.widgets?.length ?? 0) > 0 ? 'mt-2' : ''}>
<WidgetGroup widgetGroups={gridDto?.widgets ?? []} />
</div>