Codex 5.6 Sol Genel Optimizasyon
This commit is contained in:
parent
e7be51a1be
commit
0ff184fcdf
47 changed files with 595 additions and 331 deletions
|
|
@ -13938,6 +13938,12 @@
|
|||
"en": "Api URL",
|
||||
"tr": "Api URL"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "OpenUrl",
|
||||
"en": "Open URL",
|
||||
"tr": "URL'yi Aç"
|
||||
},
|
||||
{
|
||||
"resourceName": "Platform",
|
||||
"key": "App.Listform.ListformField.ApplicationName",
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@
|
|||
{
|
||||
"name": "DynamicEntityComponent",
|
||||
"routePath": "/admin/dynamic-entity",
|
||||
"code": "import React, { useEffect, useState } from \"react\";\nimport axios from \"axios\";\n\ninterface DynamicEntityComponentProps {\n title: string;\n}\n\nconst api = axios.create({\n baseURL: \"https://localhost:44344\",\n});\n\nconst DynamicEntityComponent: React.FC<DynamicEntityComponentProps> = ({ title }) => {\n const [data, setData] = useState<Array<{ id: string; name: string }>>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n const res = await api.get(`/api/app/crudendpoint/${title}`);\n const raw = Array.isArray(res.data) ? res.data : res.data?.items ?? [];\n\n const filtered = raw.map((item: any) => ({\n id: item.Id ?? item.id,\n name: item.Name ?? item.name,\n }));\n\n setData(filtered);\n } catch (err: any) {\n setError(err.message || \"Failed to fetch data\");\n } finally {\n setLoading(false);\n }\n };\n\n if (title) fetchData();\n }, [title]);\n\n if (loading) return <div>Loading...</div>;\n if (error) return <div className=\"text-red-600 dark:text-red-400\">Error: {error}</div>;\n if (!data.length) return <div>No records found</div>;\n\n const headers = [\"id\", \"name\", \"actions\"];\n\n return (\n <div className=\"overflow-auto\">\n <table className=\"min-w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 shadow-sm rounded-lg\">\n <thead className=\"bg-slate-100 dark:bg-slate-800\">\n <tr>\n {headers.map((key) => (\n <th\n key={key}\n className=\"text-left px-4 py-2 border-b border-slate-200 dark:border-slate-700 text-sm font-medium text-slate-700 dark:text-slate-200\"\n >\n {key === \"actions\" ? \"Actions\" : key}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.map((item, rowIndex) => (\n <tr key={rowIndex} className=\"hover:bg-slate-50 dark:hover:bg-slate-800\">\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800 text-sm text-slate-800 dark:text-slate-100\">\n {item.id}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800 text-sm text-slate-800 dark:text-slate-100\">\n {item.name}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800\">\n <button\n type=\"button\"\n onClick={() => alert(item.name)}\n className=\"bg-blue-600 hover:bg-blue-700 dark:bg-blue-800 dark:hover:bg-blue-900 text-white text-sm px-3 py-1 rounded-lg shadow-sm transition\"\n >\n Show Name\n </button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n};\n\nexport default DynamicEntityComponent;",
|
||||
"code": "import React, { useEffect, useState } from \"react\";\nimport axios from \"axios\";\n\ninterface DynamicEntityComponentProps {\n title: string;\n}\n\nconst api = axios.create({\n baseURL: \"https://localhost:44344\",\n});\n\nconst DynamicEntityComponent: React.FC<DynamicEntityComponentProps> = ({ title }) => {\n const [data, setData] = useState<Array<{ id: string; name: string }>>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const fetchData = async () => {\n setLoading(true);\n setError(null);\n\n try {\n const res = await api.get(`/api/app/crudendpoint/${title}`);\n const raw = Array.isArray(res.data) ? res.data : res.data?.items ?? [];\n\n const filtered = raw.map((item: any) => ({\n id: item.Id ?? item.id,\n name: item.Name ?? item.name,\n }));\n\n setData(filtered);\n } catch (err: any) {\n setError(err.message || \"Failed to fetch data\");\n } finally {\n setLoading(false);\n }\n };\n\n if (title) fetchData();\n }, [title]);\n\n if (loading) return <div>Loading...</div>;\n if (error) return <div className=\"text-red-600 dark:text-red-400\">Error: {error}</div>;\n if (!data.length) return <div>No records found</div>;\n\n const headers = [\"id\", \"name\", \"actions\"];\n\n return (\n <div className=\"overflow-auto\">\n <table className=\"min-w-full bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 shadow-sm rounded-lg\">\n <thead className=\"bg-slate-100 dark:bg-slate-800\">\n <tr>\n {headers.map((key) => (\n <th\n key={key}\n className=\"text-left px-4 py-2 border-b border-slate-200 dark:border-slate-700 text-sm font-medium text-slate-700 dark:text-slate-200\"\n >\n {key === \"actions\" ? \"Actions\" : key}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {data.map((item, rowIndex) => (\n <tr key={item.id ?? rowIndex} className=\"hover:bg-slate-50 dark:hover:bg-slate-800\">\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800 text-sm text-slate-800 dark:text-slate-100\">\n {item.id}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800 text-sm text-slate-800 dark:text-slate-100\">\n {item.name}\n </td>\n <td className=\"px-4 py-2 border-b border-slate-100 dark:border-slate-800\">\n <Button\n type=\"button\"\n color=\"blue-500\"\n onClick={() => alert(item.name)}\n shape=\"round\"\n size=\"xs\"\n variant=\"solid\"\n id=\"c_mrix4c1a_qrybhk\"\n >\n Show Name\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n};\n\nexport default DynamicEntityComponent;",
|
||||
"props": null,
|
||||
"description": null,
|
||||
"isActive": true,
|
||||
|
|
@ -363,9 +363,7 @@
|
|||
"props": null,
|
||||
"description": null,
|
||||
"isActive": true,
|
||||
"dependencies": [
|
||||
"DynamicEntityComponent"
|
||||
]
|
||||
"dependencies": ["DynamicEntityComponent"]
|
||||
}
|
||||
],
|
||||
"Abouts": [
|
||||
|
|
@ -1807,9 +1805,7 @@
|
|||
{
|
||||
"postContent": "CI/CD pipeline güncellememiz tamamlandı! Deployment süremiz %40 azaldı. Otomasyonun gücü 💪",
|
||||
"type": "video",
|
||||
"urls": [
|
||||
"https://www.w3schools.com/html/mov_bbb.mp4"
|
||||
]
|
||||
"urls": ["https://www.w3schools.com/html/mov_bbb.mp4"]
|
||||
}
|
||||
],
|
||||
"SocialPollOptions": [
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"commit": "351eddf",
|
||||
"commit": "e7be51a",
|
||||
"releases": [
|
||||
{
|
||||
"version": "1.1.06",
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import { BrowserRouter } from 'react-router-dom'
|
|||
import { store } from './store'
|
||||
import { DynamicRoutesProvider } from './routes/dynamicRoutesContext'
|
||||
import { ComponentProvider } from './contexts/ComponentContext'
|
||||
import { registerServiceWorker } from './views/version/swRegistration'
|
||||
import { useEffect } from 'react'
|
||||
import DevExtremeBoundary from './components/devExtreme/DevExtremeBoundary'
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
|
|
@ -20,7 +20,11 @@ const queryClient = new QueryClient({
|
|||
|
||||
function App() {
|
||||
useEffect(() => {
|
||||
registerServiceWorker()
|
||||
void import('./views/version/swRegistration')
|
||||
.then(({ registerServiceWorker }) => registerServiceWorker())
|
||||
.catch((error: unknown) => {
|
||||
console.warn('Service worker could not be registered.', error)
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
|
@ -29,9 +33,11 @@ function App() {
|
|||
<DynamicRoutesProvider>
|
||||
<ComponentProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Theme>
|
||||
<Layout />
|
||||
</Theme>
|
||||
<DevExtremeBoundary>
|
||||
<Theme>
|
||||
<Layout />
|
||||
</Theme>
|
||||
</DevExtremeBoundary>
|
||||
</QueryClientProvider>
|
||||
</ComponentProvider>
|
||||
</DynamicRoutesProvider>
|
||||
|
|
|
|||
56
ui/src/components/devExtreme/DevExtremeBoundary.tsx
Normal file
56
ui/src/components/devExtreme/DevExtremeBoundary.tsx
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import Loading from '@/components/shared/Loading'
|
||||
import { useStoreState } from '@/store'
|
||||
import { useEffect, useState, type ReactNode } from 'react'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { configureDevExtreme } from './devExtremeConfig'
|
||||
|
||||
interface DevExtremeBoundaryProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const DevExtremeBoundary = ({ children }: DevExtremeBoundaryProps) => {
|
||||
const { pathname } = useLocation()
|
||||
const cultureName = useStoreState((state) => state.locale.currentLang) || 'en'
|
||||
const [configuredCulture, setConfiguredCulture] = useState<string>()
|
||||
const [error, setError] = useState<Error>()
|
||||
const requiresDevExtreme = pathname.startsWith('/admin')
|
||||
|
||||
useEffect(() => {
|
||||
if (!requiresDevExtreme || configuredCulture === cultureName) return
|
||||
|
||||
let cancelled = false
|
||||
setError(undefined)
|
||||
|
||||
void configureDevExtreme(cultureName)
|
||||
.then(() => {
|
||||
if (!cancelled) setConfiguredCulture(cultureName)
|
||||
})
|
||||
.catch((reason: unknown) => {
|
||||
if (!cancelled) {
|
||||
setError(reason instanceof Error ? reason : new Error(String(reason)))
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [configuredCulture, cultureName, requiresDevExtreme])
|
||||
|
||||
if (!requiresDevExtreme) return children
|
||||
|
||||
if (error) {
|
||||
return <div className="p-4 text-red-600">DevExtreme yüklenemedi: {error.message}</div>
|
||||
}
|
||||
|
||||
if (configuredCulture !== cultureName) {
|
||||
return (
|
||||
<div className="flex flex-auto flex-col h-[100vh]">
|
||||
<Loading loading />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return children
|
||||
}
|
||||
|
||||
export default DevExtremeBoundary
|
||||
31
ui/src/components/devExtreme/devExtremeConfig.ts
Normal file
31
ui/src/components/devExtreme/devExtremeConfig.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
let devExtremeModulesPromise:
|
||||
| Promise<{
|
||||
config: typeof import('devextreme/core/config').default
|
||||
locale: typeof import('devextreme/localization').locale
|
||||
licenseKey: string
|
||||
}>
|
||||
| undefined
|
||||
|
||||
const loadDevExtremeModules = () => {
|
||||
devExtremeModulesPromise ??= Promise.all([
|
||||
import('devextreme/core/config'),
|
||||
import('devextreme/localization'),
|
||||
import('@/devextreme-license'),
|
||||
]).then(([configModule, localizationModule, licenseModule]) => ({
|
||||
config: configModule.default,
|
||||
locale: localizationModule.locale,
|
||||
licenseKey: licenseModule.licenseKey,
|
||||
}))
|
||||
|
||||
return devExtremeModulesPromise
|
||||
}
|
||||
|
||||
export const configureDevExtreme = async (cultureName: string) => {
|
||||
const { config, locale, licenseKey } = await loadDevExtremeModules()
|
||||
|
||||
config({
|
||||
licenseKey,
|
||||
defaultCurrency: cultureName.startsWith('tr') ? 'TRY' : 'USD',
|
||||
})
|
||||
locale(cultureName)
|
||||
}
|
||||
|
|
@ -1,16 +1,18 @@
|
|||
import Header from '@/components/template/Header'
|
||||
import MobileNav from '@/components/template/MobileNav'
|
||||
import Notification from '@/components/template/Notification'
|
||||
import SideNav from '@/components/template/SideNav'
|
||||
import SideNavToggle from '@/components/template/SideNavToggle'
|
||||
import SidePanel from '@/components/template/SidePanel'
|
||||
import UserDropdown from '@/components/template/UserDropdown'
|
||||
import { useStoreState } from '@/store'
|
||||
import LanguageSelector from '../template/LanguageSelector'
|
||||
import MessengerWidget from '../template/MessengerWidget'
|
||||
import Search from '../template/Search'
|
||||
import StackedSideNav from '../template/StackedSideNav'
|
||||
import AiAssistant from '../template/AiAssistant'
|
||||
import {
|
||||
DeferredAiAssistant,
|
||||
DeferredMessengerWidget,
|
||||
DeferredNotification,
|
||||
DeferredSearch,
|
||||
DeferredSidePanel,
|
||||
} from '../template/DeferredShellActions'
|
||||
import { DynamicRouter } from '@/routes/dynamicRouter'
|
||||
|
||||
const HeaderActionsStart = () => {
|
||||
|
|
@ -18,7 +20,7 @@ const HeaderActionsStart = () => {
|
|||
<>
|
||||
<MobileNav />
|
||||
<SideNavToggle />
|
||||
<Search />
|
||||
<DeferredSearch />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -26,11 +28,11 @@ const HeaderActionsStart = () => {
|
|||
const HeaderActionsEnd = () => {
|
||||
return (
|
||||
<>
|
||||
<AiAssistant />
|
||||
<Notification />
|
||||
<MessengerWidget />
|
||||
<DeferredAiAssistant />
|
||||
<DeferredNotification />
|
||||
<DeferredMessengerWidget />
|
||||
<LanguageSelector />
|
||||
<SidePanel className="hidden" />
|
||||
<DeferredSidePanel />
|
||||
<UserDropdown hoverable={false} />
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
import Header from '@/components/template/Header'
|
||||
import SidePanel from '@/components/template/SidePanel'
|
||||
import UserDropdown from '@/components/template/UserDropdown'
|
||||
import HeaderLogo from '@/components/template/HeaderLogo'
|
||||
import SecondaryHeader from '@/components/template/SecondaryHeader'
|
||||
import Notification from '@/components/template/Notification'
|
||||
import MobileNav from '@/components/template/MobileNav'
|
||||
import View from '@/views/Views'
|
||||
import Search from '@/components/template/Search'
|
||||
import LanguageSelector from '../template/LanguageSelector'
|
||||
import MessengerWidget from '../template/MessengerWidget'
|
||||
import AiAssistant from '../template/AiAssistant'
|
||||
import {
|
||||
DeferredAiAssistant,
|
||||
DeferredMessengerWidget,
|
||||
DeferredNotification,
|
||||
DeferredSearch,
|
||||
DeferredSidePanel,
|
||||
} from '../template/DeferredShellActions'
|
||||
|
||||
const HeaderActionsStart = () => {
|
||||
return (
|
||||
|
|
@ -23,12 +25,12 @@ const HeaderActionsStart = () => {
|
|||
const HeaderActionsEnd = () => {
|
||||
return (
|
||||
<>
|
||||
<AiAssistant />
|
||||
<Search />
|
||||
<Notification />
|
||||
<MessengerWidget />
|
||||
<DeferredAiAssistant />
|
||||
<DeferredSearch />
|
||||
<DeferredNotification />
|
||||
<DeferredMessengerWidget />
|
||||
<LanguageSelector />
|
||||
<SidePanel className="hidden" />
|
||||
<DeferredSidePanel />
|
||||
<UserDropdown hoverable={false} />
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useMemo, lazy, Suspense } from 'react'
|
||||
import { Component, useMemo, lazy, Suspense, type ErrorInfo, type ReactNode } from 'react'
|
||||
import Loading from '@/components/shared/Loading'
|
||||
import { useStoreState } from '@/store'
|
||||
import {
|
||||
|
|
@ -36,6 +36,45 @@ const layouts = {
|
|||
const AuthLayout = lazy(() => import('./AuthLayout'))
|
||||
const PublicLayout = lazy(() => import('./PublicLayout'))
|
||||
|
||||
class LayoutChunkErrorBoundary extends Component<
|
||||
{ children: ReactNode },
|
||||
{ failed: boolean }
|
||||
> {
|
||||
state = { failed: false }
|
||||
|
||||
static getDerivedStateFromError() {
|
||||
return { failed: true }
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
||||
console.error('Application layout could not be loaded.', error, errorInfo)
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.failed) {
|
||||
return (
|
||||
<div className="flex min-h-screen items-center justify-center p-6">
|
||||
<div className="max-w-md text-center">
|
||||
<h1 className="mb-2 text-lg font-semibold">Uygulama kabuğu yüklenemedi</h1>
|
||||
<p className="mb-4 text-sm text-gray-500">
|
||||
Bağlantınızı kontrol edip uygulamayı yeniden yükleyin.
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
className="rounded bg-indigo-600 px-4 py-2 text-sm font-medium text-white"
|
||||
onClick={() => window.location.reload()}
|
||||
>
|
||||
Yeniden yükle
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return this.props.children
|
||||
}
|
||||
}
|
||||
|
||||
const Layout = () => {
|
||||
const location = useLocation()
|
||||
const layoutType = useStoreState((s) => s.theme.layout.type) as LayoutType
|
||||
|
|
@ -94,15 +133,17 @@ const Layout = () => {
|
|||
}
|
||||
|
||||
return (
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="flex flex-auto flex-col h-[100vh]">
|
||||
<Loading loading />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<AppLayout />
|
||||
</Suspense>
|
||||
<LayoutChunkErrorBoundary>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="flex flex-auto flex-col h-[100vh]">
|
||||
<Loading loading />
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<AppLayout />
|
||||
</Suspense>
|
||||
</LayoutChunkErrorBoundary>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,26 @@
|
|||
import Header from '@/components/template/Header'
|
||||
import MobileNav from '@/components/template/MobileNav'
|
||||
import Notification from '@/components/template/Notification'
|
||||
import Search from '@/components/template/Search'
|
||||
import SideNav from '@/components/template/SideNav'
|
||||
import SideNavToggle from '@/components/template/SideNavToggle'
|
||||
import SidePanel from '@/components/template/SidePanel'
|
||||
import UserDropdown from '@/components/template/UserDropdown'
|
||||
import View from '@/views/Views'
|
||||
import LanguageSelector from '../template/LanguageSelector'
|
||||
import MessengerWidget from '../template/MessengerWidget'
|
||||
import { useStoreState } from '@/store'
|
||||
import StackedSideNav from '../template/StackedSideNav'
|
||||
import AiAssistant from '../template/AiAssistant'
|
||||
import {
|
||||
DeferredAiAssistant,
|
||||
DeferredMessengerWidget,
|
||||
DeferredNotification,
|
||||
DeferredSearch,
|
||||
DeferredSidePanel,
|
||||
} from '../template/DeferredShellActions'
|
||||
|
||||
const HeaderActionsStart = () => {
|
||||
return (
|
||||
<>
|
||||
<MobileNav />
|
||||
<SideNavToggle />
|
||||
<Search />
|
||||
<DeferredSearch />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -26,11 +28,11 @@ const HeaderActionsStart = () => {
|
|||
const HeaderActionsEnd = () => {
|
||||
return (
|
||||
<>
|
||||
<AiAssistant />
|
||||
<Notification />
|
||||
<MessengerWidget />
|
||||
<DeferredAiAssistant />
|
||||
<DeferredNotification />
|
||||
<DeferredMessengerWidget />
|
||||
<LanguageSelector />
|
||||
<SidePanel className="hidden" />
|
||||
<DeferredSidePanel />
|
||||
<UserDropdown hoverable={false} />
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
import Header from '@/components/template/Header'
|
||||
import SidePanel from '@/components/template/SidePanel'
|
||||
import UserDropdown from '@/components/template/UserDropdown'
|
||||
import HeaderLogo from '@/components/template/HeaderLogo'
|
||||
import MobileNav from '@/components/template/MobileNav'
|
||||
import HorizontalNav from '@/components/template/HorizontalNav'
|
||||
import View from '@/views/Views'
|
||||
import Notification from '@/components/template/Notification'
|
||||
import Search from '@/components/template/Search'
|
||||
import LanguageSelector from '../template/LanguageSelector'
|
||||
import MessengerWidget from '../template/MessengerWidget'
|
||||
import AiAssistant from '../template/AiAssistant'
|
||||
import {
|
||||
DeferredAiAssistant,
|
||||
DeferredMessengerWidget,
|
||||
DeferredNotification,
|
||||
DeferredSearch,
|
||||
DeferredSidePanel,
|
||||
} from '../template/DeferredShellActions'
|
||||
|
||||
const HeaderActionsStart = () => {
|
||||
return (
|
||||
|
|
@ -23,12 +25,12 @@ const HeaderActionsStart = () => {
|
|||
const HeaderActionsEnd = () => {
|
||||
return (
|
||||
<>
|
||||
<Search />
|
||||
<AiAssistant />
|
||||
<Notification />
|
||||
<MessengerWidget />
|
||||
<DeferredSearch />
|
||||
<DeferredAiAssistant />
|
||||
<DeferredNotification />
|
||||
<DeferredMessengerWidget />
|
||||
<LanguageSelector />
|
||||
<SidePanel className="hidden" />
|
||||
<DeferredSidePanel />
|
||||
<UserDropdown hoverable={false} />
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
import Header from '@/components/template/Header'
|
||||
import SidePanel from '@/components/template/SidePanel'
|
||||
import UserDropdown from '@/components/template/UserDropdown'
|
||||
import MobileNav from '@/components/template/MobileNav'
|
||||
import StackedSideNav from '@/components/template/StackedSideNav'
|
||||
import View from '@/views/Views'
|
||||
import Search from '@/components/template/Search'
|
||||
import Notification from '@/components/template/Notification'
|
||||
import LanguageSelector from '../template/LanguageSelector'
|
||||
import MessengerWidget from '../template/MessengerWidget'
|
||||
import AiAssistant from '../template/AiAssistant'
|
||||
import {
|
||||
DeferredAiAssistant,
|
||||
DeferredMessengerWidget,
|
||||
DeferredNotification,
|
||||
DeferredSearch,
|
||||
DeferredSidePanel,
|
||||
} from '../template/DeferredShellActions'
|
||||
|
||||
const HeaderActionsStart = () => {
|
||||
return (
|
||||
<>
|
||||
<MobileNav />
|
||||
<Search />
|
||||
<DeferredSearch />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -22,11 +24,11 @@ const HeaderActionsStart = () => {
|
|||
const HeaderActionsEnd = () => {
|
||||
return (
|
||||
<>
|
||||
<AiAssistant />
|
||||
<Notification />
|
||||
<MessengerWidget />
|
||||
<DeferredAiAssistant />
|
||||
<DeferredNotification />
|
||||
<DeferredMessengerWidget />
|
||||
<LanguageSelector />
|
||||
<SidePanel className="hidden" />
|
||||
<DeferredSidePanel />
|
||||
<UserDropdown hoverable={false} />
|
||||
</>
|
||||
)
|
||||
|
|
|
|||
72
ui/src/components/template/DeferredShellActions.tsx
Normal file
72
ui/src/components/template/DeferredShellActions.tsx
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import React, { Component, lazy, Suspense, type ErrorInfo, type ReactNode } from 'react'
|
||||
|
||||
const Search = lazy(() => import('./Search'))
|
||||
const AiAssistant = lazy(() => import('./AiAssistant'))
|
||||
const Notification = lazy(() => import('./Notification'))
|
||||
const MessengerWidget = lazy(() => import('./MessengerWidget'))
|
||||
const SidePanel = lazy(() => import('./SidePanel'))
|
||||
|
||||
interface OptionalShellActionBoundaryProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
interface OptionalShellActionBoundaryState {
|
||||
failed: boolean
|
||||
}
|
||||
|
||||
class OptionalShellActionBoundary extends Component<
|
||||
OptionalShellActionBoundaryProps,
|
||||
OptionalShellActionBoundaryState
|
||||
> {
|
||||
state: OptionalShellActionBoundaryState = { failed: false }
|
||||
|
||||
static getDerivedStateFromError(): OptionalShellActionBoundaryState {
|
||||
return { failed: true }
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
||||
console.error('Optional shell action could not be loaded.', error, errorInfo)
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.state.failed ? null : this.props.children
|
||||
}
|
||||
}
|
||||
|
||||
const ActionFallback = () => <span aria-hidden className="inline-block h-9 w-9" />
|
||||
|
||||
const DeferredAction = ({ children }: { children: ReactNode }) => (
|
||||
<OptionalShellActionBoundary>
|
||||
<Suspense fallback={<ActionFallback />}>{children}</Suspense>
|
||||
</OptionalShellActionBoundary>
|
||||
)
|
||||
|
||||
export const DeferredSearch = () => (
|
||||
<DeferredAction>
|
||||
<Search />
|
||||
</DeferredAction>
|
||||
)
|
||||
|
||||
export const DeferredAiAssistant = () => (
|
||||
<DeferredAction>
|
||||
<AiAssistant />
|
||||
</DeferredAction>
|
||||
)
|
||||
|
||||
export const DeferredNotification = () => (
|
||||
<DeferredAction>
|
||||
<Notification />
|
||||
</DeferredAction>
|
||||
)
|
||||
|
||||
export const DeferredMessengerWidget = () => (
|
||||
<DeferredAction>
|
||||
<MessengerWidget />
|
||||
</DeferredAction>
|
||||
)
|
||||
|
||||
export const DeferredSidePanel = () => (
|
||||
<DeferredAction>
|
||||
<SidePanel className="hidden" />
|
||||
</DeferredAction>
|
||||
)
|
||||
|
|
@ -1,52 +1,11 @@
|
|||
import {
|
||||
import type {
|
||||
CreateUpdateCustomComponentDto,
|
||||
CustomComponent,
|
||||
CustomComponentDto,
|
||||
} from '@/proxy/developerKit/models'
|
||||
import { developerKitService } from '@/services/developerKit.service'
|
||||
import { useStoreState } from '@/store/store'
|
||||
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'
|
||||
import {
|
||||
Alert,
|
||||
Avatar,
|
||||
Badge,
|
||||
Button,
|
||||
Calendar,
|
||||
Card,
|
||||
Checkbox,
|
||||
ConfigProvider,
|
||||
DatePicker,
|
||||
Dialog,
|
||||
Drawer,
|
||||
Dropdown,
|
||||
FormItem,
|
||||
FormContainer,
|
||||
Input,
|
||||
InputGroup,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Notification,
|
||||
Pagination,
|
||||
Progress,
|
||||
Radio,
|
||||
RangeCalendar,
|
||||
ScrollBar,
|
||||
Segment,
|
||||
Select,
|
||||
Skeleton,
|
||||
Spinner,
|
||||
Steps,
|
||||
Switcher,
|
||||
Table,
|
||||
Tabs,
|
||||
Tag,
|
||||
TimeInput,
|
||||
Timeline,
|
||||
toast,
|
||||
Tooltip,
|
||||
Upload,
|
||||
} from '../components/ui'
|
||||
import axios from 'axios'
|
||||
import React, { createContext, useContext, useState, useEffect, useCallback, useMemo } from 'react'
|
||||
|
||||
interface ComponentProps {
|
||||
[key: string]: unknown
|
||||
|
|
@ -75,6 +34,39 @@ interface ComponentContextType {
|
|||
|
||||
const ComponentContext = createContext<ComponentContextType | undefined>(undefined)
|
||||
|
||||
const HelloWorldComponent: React.ComponentType<unknown> = () =>
|
||||
React.createElement('div', { className: 'p-6 bg-blue-50 rounded-lg' }, [
|
||||
React.createElement(
|
||||
'h1',
|
||||
{ key: 'title', className: 'text-2xl font-bold text-blue-900 mb-4' },
|
||||
'Hello World!',
|
||||
),
|
||||
React.createElement(
|
||||
'p',
|
||||
{ key: 'description', className: 'text-blue-700' },
|
||||
'Bu manuel kayıtlı bir komponent!',
|
||||
),
|
||||
])
|
||||
|
||||
const TestListComponent: React.ComponentType<unknown> = () =>
|
||||
React.createElement('div', { className: 'p-6 bg-green-50 rounded-lg' }, [
|
||||
React.createElement(
|
||||
'h1',
|
||||
{ key: 'title', className: 'text-2xl font-bold text-green-900 mb-4' },
|
||||
'Test List',
|
||||
),
|
||||
React.createElement(
|
||||
'p',
|
||||
{ key: 'description', className: 'text-green-700' },
|
||||
'Bu da test için kayıtlı komponent!',
|
||||
),
|
||||
])
|
||||
|
||||
const defaultRegisteredComponents: Record<string, React.ComponentType<unknown>> = {
|
||||
HelloWorld: HelloWorldComponent,
|
||||
TestList: TestListComponent,
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export const useComponents = () => {
|
||||
const context = useContext(ComponentContext)
|
||||
|
|
@ -89,16 +81,13 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
const [components, setComponents] = useState<CustomComponent[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
const [registeredComponents, setRegisteredComponents] = useState<
|
||||
Record<string, React.ComponentType<unknown>>
|
||||
>({})
|
||||
const [registeredComponents, setRegisteredComponents] = useState(defaultRegisteredComponents)
|
||||
const [compiledComponents, setCompiledComponents] = useState<
|
||||
Record<string, React.ComponentType<ComponentProps>>
|
||||
>({})
|
||||
|
||||
const refreshComponents = async () => {
|
||||
const refreshComponents = useCallback(async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
||||
const customComponents = extraProperties?.customComponents as CustomComponentDto[]
|
||||
|
|
@ -107,16 +96,14 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
setError(err instanceof Error ? err.message : 'Failed to fetch components')
|
||||
console.error('Failed to fetch components:', err)
|
||||
setComponents([])
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
}, [extraProperties])
|
||||
|
||||
useEffect(() => {
|
||||
refreshComponents()
|
||||
}, [extraProperties])
|
||||
}, [refreshComponents])
|
||||
|
||||
const addComponent = async (componentData: CreateUpdateCustomComponentDto) => {
|
||||
const addComponent = useCallback(async (componentData: CreateUpdateCustomComponentDto) => {
|
||||
try {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
|
@ -128,9 +115,12 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
const updateComponent = async (id: string, componentData: CreateUpdateCustomComponentDto) => {
|
||||
const updateComponent = useCallback(async (
|
||||
id: string,
|
||||
componentData: CreateUpdateCustomComponentDto,
|
||||
) => {
|
||||
try {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
|
@ -144,9 +134,9 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
const deleteComponent = async (id: string) => {
|
||||
const deleteComponent = useCallback(async (id: string) => {
|
||||
try {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
|
|
@ -158,78 +148,36 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
const getComponent = (id: string) => {
|
||||
return components?.find((comp) => comp.id === id)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const getComponentByName = (name: string) => {
|
||||
return components?.find((comp) => comp.name === name)
|
||||
}
|
||||
const componentsById = useMemo(
|
||||
() => new Map(components.map((component) => [component.id, component])),
|
||||
[components],
|
||||
)
|
||||
const componentsByName = useMemo(
|
||||
() => new Map(components.map((component) => [component.name, component])),
|
||||
[components],
|
||||
)
|
||||
const activeComponentsByName = useMemo(
|
||||
() => new Map(components.filter((component) => component.isActive).map((component) => [component.name, component])),
|
||||
[components],
|
||||
)
|
||||
|
||||
const registerComponent = (name: string, component: React.ComponentType<unknown>) => {
|
||||
setRegisteredComponents((prev) => ({
|
||||
...prev,
|
||||
[name]: component,
|
||||
}))
|
||||
}
|
||||
const getComponent = useCallback((id: string) => componentsById.get(id), [componentsById])
|
||||
|
||||
// Register some default components on mount
|
||||
useEffect(() => {
|
||||
// Example components for testing
|
||||
const HelloWorldComponent: React.ComponentType<unknown> = () => {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{
|
||||
className: 'p-6 bg-blue-50 rounded-lg',
|
||||
},
|
||||
[
|
||||
React.createElement(
|
||||
'h1',
|
||||
{
|
||||
className: 'text-2xl font-bold text-blue-900 mb-4',
|
||||
},
|
||||
'Hello World!',
|
||||
),
|
||||
React.createElement(
|
||||
'p',
|
||||
{
|
||||
className: 'text-blue-700',
|
||||
},
|
||||
'Bu manuel kayıtlı bir komponent!',
|
||||
),
|
||||
],
|
||||
const getComponentByName = useCallback(
|
||||
(name: string) => componentsByName.get(name),
|
||||
[componentsByName],
|
||||
)
|
||||
|
||||
const registerComponent = useCallback(
|
||||
(name: string, component: React.ComponentType<unknown>) => {
|
||||
setRegisteredComponents((previous) =>
|
||||
previous[name] === component ? previous : { ...previous, [name]: component },
|
||||
)
|
||||
}
|
||||
|
||||
const TestListComponent: React.ComponentType<unknown> = () => {
|
||||
return React.createElement(
|
||||
'div',
|
||||
{
|
||||
className: 'p-6 bg-green-50 rounded-lg',
|
||||
},
|
||||
[
|
||||
React.createElement(
|
||||
'h1',
|
||||
{
|
||||
className: 'text-2xl font-bold text-green-900 mb-4',
|
||||
},
|
||||
'Test List',
|
||||
),
|
||||
React.createElement(
|
||||
'p',
|
||||
{
|
||||
className: 'text-green-700',
|
||||
},
|
||||
'Bu da test için kayıtlı komponent!',
|
||||
),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
registerComponent('HelloWorld', HelloWorldComponent)
|
||||
registerComponent('TestList', TestListComponent)
|
||||
}, []) // Empty dependency array - only run once
|
||||
},
|
||||
[],
|
||||
)
|
||||
|
||||
// Component compilation functions (moved from ComponentRegistryProvider)
|
||||
const extractComponentInfo = useCallback((code: string, defaultName = '') => {
|
||||
|
|
@ -259,7 +207,10 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
|
||||
// Compile components when they change
|
||||
useEffect(() => {
|
||||
if (!components || !components?.length) return
|
||||
if (!components.length) {
|
||||
setCompiledComponents({})
|
||||
return
|
||||
}
|
||||
|
||||
let cancelled = false
|
||||
|
||||
|
|
@ -332,9 +283,54 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
|
||||
// Babel is several megabytes and is only needed when an active runtime
|
||||
// component exists. Keep it out of the application startup bundle.
|
||||
const Babel = await import('@babel/standalone')
|
||||
const [Babel, ui, { default: axios }] = await Promise.all([
|
||||
import('@babel/standalone'),
|
||||
import('../components/ui'),
|
||||
import('axios'),
|
||||
])
|
||||
if (cancelled) return
|
||||
|
||||
const {
|
||||
Alert,
|
||||
Avatar,
|
||||
Badge,
|
||||
Button,
|
||||
Calendar,
|
||||
Card,
|
||||
Checkbox,
|
||||
ConfigProvider,
|
||||
DatePicker,
|
||||
Dialog,
|
||||
Drawer,
|
||||
Dropdown,
|
||||
FormItem,
|
||||
FormContainer,
|
||||
Input,
|
||||
InputGroup,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Notification,
|
||||
Pagination,
|
||||
Progress,
|
||||
Radio,
|
||||
RangeCalendar,
|
||||
ScrollBar,
|
||||
Segment,
|
||||
Select,
|
||||
Skeleton,
|
||||
Spinner,
|
||||
Steps,
|
||||
Switcher,
|
||||
Table,
|
||||
Tabs,
|
||||
Tag,
|
||||
TimeInput,
|
||||
Timeline,
|
||||
toast,
|
||||
Tooltip,
|
||||
Upload,
|
||||
} = ui
|
||||
|
||||
const compiledBundle = Babel.transform(bundledCode, {
|
||||
presets: ['react', 'typescript'],
|
||||
filename: 'components-bundle.tsx',
|
||||
|
|
@ -453,7 +449,7 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
return <Component {...props} />
|
||||
}
|
||||
|
||||
const component = components.find((c) => c.name === name && c.isActive)
|
||||
const component = activeComponentsByName.get(name)
|
||||
if (!component) {
|
||||
console.error(`Component not found: ${name}`)
|
||||
return (
|
||||
|
|
@ -465,7 +461,7 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
|
||||
return null
|
||||
},
|
||||
[components, compiledComponents],
|
||||
[activeComponentsByName, compiledComponents],
|
||||
)
|
||||
|
||||
const compileAndRender = useCallback((code: string) => {
|
||||
|
|
@ -476,43 +472,63 @@ export const ComponentProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
|||
|
||||
const isComponentRegistered = useCallback(
|
||||
(name: string) => {
|
||||
return components.some((c) => c.name === name && c.isActive) || !!compiledComponents[name]
|
||||
return activeComponentsByName.has(name) || !!compiledComponents[name]
|
||||
},
|
||||
[components, compiledComponents],
|
||||
[activeComponentsByName, compiledComponents],
|
||||
)
|
||||
|
||||
const getRegisteredComponents = useCallback(() => {
|
||||
const dbComponents = components?.filter((c) => c.isActive).map((c) => c.name) || []
|
||||
const dbComponents = [...activeComponentsByName.keys()]
|
||||
const compiledNames = Object.keys(compiledComponents)
|
||||
return [...new Set([...dbComponents, ...compiledNames])]
|
||||
}, [components, compiledComponents])
|
||||
}, [activeComponentsByName, compiledComponents])
|
||||
|
||||
const getComponentCode = useCallback(
|
||||
(name: string) => {
|
||||
const component = components.find((c) => c.name === name)
|
||||
const component = componentsByName.get(name)
|
||||
return component ? component.code : null
|
||||
},
|
||||
[components],
|
||||
[componentsByName],
|
||||
)
|
||||
|
||||
const value = {
|
||||
components,
|
||||
loading,
|
||||
error,
|
||||
addComponent,
|
||||
updateComponent,
|
||||
deleteComponent,
|
||||
getComponent,
|
||||
getComponentByName,
|
||||
refreshComponents,
|
||||
registeredComponents,
|
||||
registerComponent,
|
||||
renderComponent,
|
||||
compileAndRender,
|
||||
isComponentRegistered,
|
||||
getRegisteredComponents,
|
||||
getComponentCode,
|
||||
}
|
||||
const value = useMemo<ComponentContextType>(
|
||||
() => ({
|
||||
components,
|
||||
loading,
|
||||
error,
|
||||
addComponent,
|
||||
updateComponent,
|
||||
deleteComponent,
|
||||
getComponent,
|
||||
getComponentByName,
|
||||
refreshComponents,
|
||||
registeredComponents,
|
||||
registerComponent,
|
||||
renderComponent,
|
||||
compileAndRender,
|
||||
isComponentRegistered,
|
||||
getRegisteredComponents,
|
||||
getComponentCode,
|
||||
}),
|
||||
[
|
||||
components,
|
||||
loading,
|
||||
error,
|
||||
addComponent,
|
||||
updateComponent,
|
||||
deleteComponent,
|
||||
getComponent,
|
||||
getComponentByName,
|
||||
refreshComponents,
|
||||
registeredComponents,
|
||||
registerComponent,
|
||||
renderComponent,
|
||||
compileAndRender,
|
||||
isComponentRegistered,
|
||||
getRegisteredComponents,
|
||||
getComponentCode,
|
||||
],
|
||||
)
|
||||
|
||||
return <ComponentContext.Provider value={value}>{children}</ComponentContext.Provider>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,38 @@
|
|||
/* eslint-disable import/default */
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import App from './App'
|
||||
import './index.css'
|
||||
import { UiEvalService } from './services/UiEvalService'
|
||||
|
||||
import config from 'devextreme/core/config'
|
||||
import { licenseKey } from './devextreme-license'
|
||||
type UiEvalServiceModule = typeof import('./services/UiEvalService')
|
||||
|
||||
// Lisansı uygulama başlamadan önce kaydediyoruz
|
||||
config({ licenseKey })
|
||||
let uiEvalServicePromise: Promise<UiEvalServiceModule> | undefined
|
||||
const loadUiEvalService = () =>
|
||||
(uiEvalServicePromise ??= import('./services/UiEvalService'))
|
||||
|
||||
const lazyUiEvalService = new Proxy<Record<string, (...args: unknown[]) => void>>(
|
||||
{},
|
||||
{
|
||||
get: (_, methodName) => {
|
||||
if (typeof methodName !== 'string') return undefined
|
||||
|
||||
return (...args: unknown[]) => {
|
||||
void loadUiEvalService()
|
||||
.then(({ UiEvalService }) => {
|
||||
const serviceMethod = Reflect.get(UiEvalService, methodName)
|
||||
if (typeof serviceMethod === 'function') {
|
||||
Reflect.apply(serviceMethod, UiEvalService, args)
|
||||
}
|
||||
})
|
||||
.catch((error: unknown) => {
|
||||
console.error(`UiEvalService.${methodName} could not be loaded.`, error)
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
const globalWithUiEval = globalThis as typeof globalThis & {
|
||||
UiEvalService?: typeof lazyUiEvalService
|
||||
}
|
||||
globalWithUiEval.UiEvalService ??= lazyUiEvalService
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />)
|
||||
|
||||
UiEvalService.Init()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import { Gantt } from 'devextreme-react'
|
||||
|
||||
export const extraFilterControlTypeOptions = [
|
||||
{ value: 'Select', label: 'Select' },
|
||||
{ value: 'TextBox', label: 'TextBox' },
|
||||
|
|
@ -175,4 +173,4 @@ export const tooltipFormatListOptions = [
|
|||
{ value: 'thousands', label: 'Thousands' },
|
||||
{ value: 'trillions', label: 'Trillions' },
|
||||
{ value: 'year', label: 'Year' },
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import {
|
||||
import type {
|
||||
HorizontalAlignment,
|
||||
ScrollMode,
|
||||
SelectAllMode,
|
||||
type SingleMultipleOrNone,
|
||||
SingleMultipleOrNone,
|
||||
} from 'devextreme/common'
|
||||
import {
|
||||
import type {
|
||||
ApplyFilterMode,
|
||||
ColumnChooserMode,
|
||||
ColumnResizeMode,
|
||||
|
|
@ -15,7 +15,7 @@ import {
|
|||
StartEditAction,
|
||||
StateStoreType,
|
||||
} from 'devextreme/ui/data_grid_types'
|
||||
import { FormItemComponent } from 'devextreme/ui/form'
|
||||
import type { FormItemComponent } from 'devextreme/ui/form'
|
||||
import { AuditedEntityDto } from '../abp'
|
||||
import { EditorType2, RowMode } from '../../views/form/types'
|
||||
import {
|
||||
|
|
@ -42,9 +42,9 @@ import {
|
|||
ChartZoomAndPanDto,
|
||||
} from '../admin/charts/models'
|
||||
import { ListViewLayoutType } from '@/views/admin/listForm/edit/types'
|
||||
import { SeriesType } from 'devextreme/common/charts'
|
||||
import { PagerDisplayMode } from 'devextreme/common/grids'
|
||||
import { GanttScaleType } from 'devextreme/ui/gantt'
|
||||
import type { SeriesType } from 'devextreme/common/charts'
|
||||
import type { PagerDisplayMode } from 'devextreme/common/grids'
|
||||
import type { GanttScaleType } from 'devextreme/ui/gantt'
|
||||
|
||||
//1
|
||||
export interface SelectListItem {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,25 @@
|
|||
import React, { lazy } from 'react'
|
||||
import { RouteDto } from '@/proxy/routes/models'
|
||||
import { CustomComponent } from '@/proxy/developerKit/models'
|
||||
import type { RouteDto } from '@/proxy/routes/models'
|
||||
import type { CustomComponent } from '@/proxy/developerKit/models'
|
||||
|
||||
// Tüm view bileşenlerini import et (vite özel)
|
||||
// shared klasörü hariç, çünkü bu bileşenler genellikle başka yerlerde statik import ediliyor
|
||||
const modules = import.meta.glob(['../views/**/*.tsx', '!../views/shared/**/*.tsx'])
|
||||
|
||||
const lazyComponentCache = new Map<string, React.LazyExoticComponent<React.ComponentType<any>>>()
|
||||
// Only physical modules are safe to cache. Runtime components depend on the
|
||||
// latest ComponentContext render function and must not retain an old closure.
|
||||
const physicalComponentCache = new Map<
|
||||
string,
|
||||
React.LazyExoticComponent<React.ComponentType<any>>
|
||||
>()
|
||||
|
||||
// Fiziksel komponent yükleme (mevcut mantık)
|
||||
function loadPhysicalComponent(componentPath: string) {
|
||||
const cleanedPath = componentPath.replace(/^@\//, '')
|
||||
const fullPath = `../${cleanedPath}.tsx`
|
||||
|
||||
if (lazyComponentCache.has(fullPath)) {
|
||||
return lazyComponentCache.get(fullPath)!
|
||||
if (physicalComponentCache.has(fullPath)) {
|
||||
return physicalComponentCache.get(fullPath)!
|
||||
}
|
||||
|
||||
const loader = modules[fullPath]
|
||||
|
|
@ -24,7 +29,7 @@ function loadPhysicalComponent(componentPath: string) {
|
|||
}
|
||||
|
||||
const LazyComponent = lazy(loader as () => Promise<{ default: React.ComponentType<any> }>)
|
||||
lazyComponentCache.set(fullPath, LazyComponent)
|
||||
physicalComponentCache.set(fullPath, LazyComponent)
|
||||
return LazyComponent
|
||||
}
|
||||
|
||||
|
|
@ -35,12 +40,6 @@ function loadDynamicComponent(
|
|||
renderComponent?: (name: string, props?: any) => React.ReactNode,
|
||||
isComponentRegistered?: (name: string) => boolean,
|
||||
) {
|
||||
|
||||
if (lazyComponentCache.has(componentPath)) {
|
||||
// console.log(`Dynamic component loaded from cache: ${componentName}`)
|
||||
return lazyComponentCache.get(componentPath)!
|
||||
}
|
||||
|
||||
// Önce manuel registered komponentleri kontrol et
|
||||
let DynamicComponent = registeredComponents[componentPath]
|
||||
|
||||
|
|
@ -61,13 +60,10 @@ function loadDynamicComponent(
|
|||
throw new Error(`Dynamic component not found: ${componentPath}`)
|
||||
}
|
||||
|
||||
// console.log(`Dynamic component loaded: ${componentPath}`)
|
||||
// Dinamik komponent için lazy wrapper oluştur
|
||||
const LazyComponent = lazy(() =>
|
||||
Promise.resolve({ default: DynamicComponent as React.ComponentType<any> }),
|
||||
)
|
||||
lazyComponentCache.set(componentPath, LazyComponent)
|
||||
return LazyComponent
|
||||
// Do not put this wrapper in a module-level cache. renderComponent changes
|
||||
// after the asynchronous database bundle compilation finishes. Caching this
|
||||
// function would keep the pre-compilation closure and render an empty page.
|
||||
return DynamicComponent as React.ComponentType<any>
|
||||
}
|
||||
|
||||
export function loadComponent(
|
||||
|
|
@ -103,7 +99,7 @@ export interface DynamicReactRoute {
|
|||
registeredComponents?: Record<string, React.ComponentType<unknown>>,
|
||||
renderComponent?: (name: string, props?: any) => React.ReactNode,
|
||||
isComponentRegistered?: (name: string) => boolean,
|
||||
) => React.LazyExoticComponent<React.ComponentType<any>>
|
||||
) => React.ComponentType<any>
|
||||
routeType: string
|
||||
authority?: string[]
|
||||
componentType: string
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export const updateSent = (notificationId: string, isSent: boolean) =>
|
|||
})
|
||||
|
||||
export const updateReadMany = (notificationIds: string[], isRead: boolean) =>
|
||||
apiService.fetchData<number>({
|
||||
apiService.fetchData<number, string[]>({
|
||||
method: 'PUT',
|
||||
url: `/api/app/notification/read-many`,
|
||||
params: { isRead },
|
||||
|
|
@ -45,7 +45,7 @@ export const updateReadMany = (notificationIds: string[], isRead: boolean) =>
|
|||
})
|
||||
|
||||
export const updateSentMany = (notificationIds: string[], isSent: boolean) =>
|
||||
apiService.fetchData<number>({
|
||||
apiService.fetchData<number, string[]>({
|
||||
method: 'PUT',
|
||||
url: `/api/app/notification/sent-many`,
|
||||
params: { isSent },
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ import { useEffect } from 'react'
|
|||
import dayjs from 'dayjs'
|
||||
import utc from 'dayjs/plugin/utc'
|
||||
import timezone from 'dayjs/plugin/timezone'
|
||||
import { locale as dxLocale } from 'devextreme/localization'
|
||||
import config from 'devextreme/core/config'
|
||||
import { useStoreState } from '@/store'
|
||||
import { dateLocales } from '@/constants/dateLocales.constant'
|
||||
|
||||
|
|
@ -26,14 +24,6 @@ function useLocale() {
|
|||
dayjs.locale(cultureName)
|
||||
dayjs.tz.setDefault(timeZone)
|
||||
|
||||
// ✅ DevExtreme locale ayarı
|
||||
dxLocale(cultureName)
|
||||
|
||||
// ✅ Para birimi
|
||||
config({
|
||||
defaultCurrency: cultureName.startsWith('tr') ? 'TRY' : 'USD',
|
||||
})
|
||||
|
||||
// console.info(`🌍 Locale: ${cultureName}, TZ: ${timeZone}`)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||
import { useStoreState } from '@/store'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { ColumnChooserMode, ColumnResizeMode } from 'devextreme/common/grids'
|
||||
import type { ColumnChooserMode, ColumnResizeMode } from 'devextreme/common/grids'
|
||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||
import * as Yup from 'yup'
|
||||
import { FormEditProps } from './FormEdit'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Button, Card, Checkbox, FormContainer, FormItem, Input, Select } from '
|
|||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||
import { useStoreState } from '@/store'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import {
|
||||
import type {
|
||||
GridsEditMode,
|
||||
GridsEditRefreshMode,
|
||||
NewRowPosition,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||
import { useStoreState } from '@/store'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { ApplyFilterMode } from 'devextreme/common/grids'
|
||||
import type { ApplyFilterMode } from 'devextreme/common/grids'
|
||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||
import * as Yup from 'yup'
|
||||
import { FormEditProps } from './FormEdit'
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import { useCallback, useEffect, useState } from 'react'
|
|||
import { getListFormFields } from '@/services/admin/list-form-field.service'
|
||||
import groupBy from 'lodash/groupBy'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { GanttScaleType } from 'devextreme/ui/gantt'
|
||||
import type { GanttScaleType } from 'devextreme/ui/gantt'
|
||||
import { gantScaleOptions } from './options'
|
||||
|
||||
const validationSchema = Yup.object().shape({})
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { Button, Checkbox, FormContainer, FormItem, Input, Select } from '@/comp
|
|||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||
import { useStoreState } from '@/store'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { ScrollMode } from 'devextreme/common'
|
||||
import { PagerDisplayMode } from 'devextreme/common/grids'
|
||||
import type { ScrollMode } from 'devextreme/common'
|
||||
import type { PagerDisplayMode } from 'devextreme/common/grids'
|
||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||
import * as Yup from 'yup'
|
||||
import { FormEditProps } from './FormEdit'
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { Button, Checkbox, FormContainer, FormItem, Select } from '@/components/
|
|||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||
import { useStoreState } from '@/store'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { SelectAllMode, SingleMultipleOrNone } from 'devextreme/common'
|
||||
import { SelectionColumnDisplayMode } from 'devextreme/common/grids'
|
||||
import type { SelectAllMode, SingleMultipleOrNone } from 'devextreme/common'
|
||||
import type { SelectionColumnDisplayMode } from 'devextreme/common/grids'
|
||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||
import * as Yup from 'yup'
|
||||
import { FormEditProps } from './FormEdit'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Button, Checkbox, FormContainer, FormItem, Input, Select } from '@/comp
|
|||
import { ListFormEditTabs } from '@/proxy/admin/list-form/options'
|
||||
import { useStoreState } from '@/store'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { StateStoreType } from 'devextreme/common/grids'
|
||||
import type { StateStoreType } from 'devextreme/common/grids'
|
||||
import { Field, FieldProps, Form, Formik } from 'formik'
|
||||
import * as Yup from 'yup'
|
||||
import { FormEditProps } from './FormEdit'
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ function ComponentCodeLayout() {
|
|||
try {
|
||||
const componentData = {
|
||||
name: name.trim(),
|
||||
routePath: id ? (getComponent(id)?.routePath ?? '') : '',
|
||||
dependencies: JSON.stringify(dependencies), // Serialize dependencies to JSON string
|
||||
code: code.trim(),
|
||||
isActive,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
FaEyeSlash,
|
||||
FaFilter,
|
||||
FaCalendarAlt,
|
||||
FaExternalLinkAlt,
|
||||
} from 'react-icons/fa'
|
||||
import Widget from '@/components/common/Widget'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
|
|
@ -65,6 +66,11 @@ const ComponentManager: React.FC = () => {
|
|||
}
|
||||
}
|
||||
|
||||
const handleOpenRoute = (routePath: string) => {
|
||||
const normalizedPath = routePath.startsWith('/') ? routePath : `/${routePath}`
|
||||
navigate(normalizedPath)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<Helmet
|
||||
|
|
@ -241,6 +247,17 @@ const ComponentManager: React.FC = () => {
|
|||
</Button>
|
||||
</div>
|
||||
<div className="flex items-center gap-1">
|
||||
<Button
|
||||
type="button"
|
||||
variant="solid"
|
||||
shape="circle"
|
||||
color="gray-600"
|
||||
disabled={!component.isActive || !component.routePath?.trim()}
|
||||
title={translate('::OpenUrl')}
|
||||
onClick={() => handleOpenRoute(component.routePath)}
|
||||
>
|
||||
<FaExternalLinkAlt className="w-3 h-3" />
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="solid"
|
||||
|
|
@ -255,7 +272,7 @@ const ComponentManager: React.FC = () => {
|
|||
'_blank',
|
||||
)
|
||||
}
|
||||
title={translate('::App.DeveloperKit.Component.Edit')}
|
||||
title={translate('::Edit')}
|
||||
>
|
||||
<FaRegEdit className="w-3 h-3" />
|
||||
</Button>
|
||||
|
|
@ -272,7 +289,7 @@ const ComponentManager: React.FC = () => {
|
|||
),
|
||||
)
|
||||
}
|
||||
title={translate('::App.DeveloperKit.Component.View')}
|
||||
title={translate('::App.Platform.View')}
|
||||
>
|
||||
<FaEye className="w-3 h-3" />
|
||||
</Button>
|
||||
|
|
@ -282,7 +299,7 @@ const ComponentManager: React.FC = () => {
|
|||
shape="circle"
|
||||
color="red-600"
|
||||
onClick={() => handleDelete(component.id)}
|
||||
title={translate('::App.DeveloperKit.Component.Delete')}
|
||||
title={translate('::Delete')}
|
||||
>
|
||||
<FaTrashAlt className="w-3 h-3" />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ import '@/utils/registerDevExtremeEditors'
|
|||
import { executeEditorScript } from '@/utils/editorScriptRuntime'
|
||||
import {
|
||||
Form as FormDx,
|
||||
FormRef,
|
||||
type FormRef,
|
||||
GroupItem as GroupItemDx,
|
||||
SimpleItem as SimpleItemDx,
|
||||
} from 'devextreme-react/form'
|
||||
import { FieldDataChangedEvent, GroupItem } from 'devextreme/ui/form'
|
||||
import type { FieldDataChangedEvent, GroupItem } from 'devextreme/ui/form'
|
||||
import { Dispatch, RefObject, useEffect, useRef, useState } from 'react'
|
||||
import { GridBoxEditorComponent } from './editors/GridBoxEditorComponent'
|
||||
import { ImageUploadEditorComponent } from './editors/ImageUploadEditorComponent'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Container, Loading } from '@/components/shared'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { DataType } from 'devextreme/common'
|
||||
import { SimpleItem } from 'devextreme/ui/form'
|
||||
import type { DataType } from 'devextreme/common'
|
||||
import type { SimpleItem } from 'devextreme/ui/form'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { useParams, useSearchParams } from 'react-router-dom'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { FormItemComponent, SimpleItem } from 'devextreme/ui/form'
|
||||
import type { FormItemComponent, SimpleItem } from 'devextreme/ui/form'
|
||||
import { Overwrite } from '../../utils/types'
|
||||
import {
|
||||
ColumnFormatDto,
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ import { Notification, toast } from '@/components/ui'
|
|||
import { getList } from '@/services/form.service'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { usePermission } from '@/utils/hooks/usePermission'
|
||||
import { FormRef } from 'devextreme-react/form'
|
||||
import type { FormRef } from 'devextreme-react/form'
|
||||
import { captionize } from 'devextreme/core/utils/inflector'
|
||||
import CustomStore from 'devextreme/data/custom_store'
|
||||
import { GroupItem } from 'devextreme/ui/form'
|
||||
import type { GroupItem } from 'devextreme/ui/form'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom'
|
||||
import { GridColumnData } from '../list/GridColumnData'
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Gantt, {
|
|||
ContextMenu,
|
||||
Editing,
|
||||
FilterRow,
|
||||
GanttRef,
|
||||
type GanttRef,
|
||||
HeaderFilter,
|
||||
Item,
|
||||
Sorting,
|
||||
|
|
@ -24,7 +24,7 @@ import { layoutTypes } from '../admin/listForm/edit/types'
|
|||
import WidgetGroup from '@/components/ui/Widget/WidgetGroup'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { usePWA } from '@/utils/hooks/usePWA'
|
||||
import { GanttScaleType } from 'devextreme/ui/gantt'
|
||||
import type { GanttScaleType } from 'devextreme/ui/gantt'
|
||||
import { useListFormColumns } from './useListFormColumns'
|
||||
import CustomStore from 'devextreme/data/custom_store'
|
||||
import { GridColumnData } from './GridColumnData'
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ import { Template } from 'devextreme-react/core/template'
|
|||
import DataGrid, {
|
||||
ColumnChooser,
|
||||
ColumnFixing,
|
||||
DataGridRef,
|
||||
DataGridTypes,
|
||||
type DataGridRef,
|
||||
type DataGridTypes,
|
||||
Editing,
|
||||
Export,
|
||||
FilterPanel,
|
||||
|
|
@ -38,7 +38,7 @@ import DataGrid, {
|
|||
TotalItem,
|
||||
} from 'devextreme-react/data-grid'
|
||||
import { Item } from 'devextreme-react/toolbar'
|
||||
import { DataType } from 'devextreme/common'
|
||||
import type { DataType } from 'devextreme/common'
|
||||
import { captionize } from 'devextreme/core/utils/inflector'
|
||||
import CustomStore from 'devextreme/data/custom_store'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataGridTypes } from 'devextreme-react/data-grid'
|
||||
import type { DataGridTypes } from 'devextreme-react/data-grid'
|
||||
import {
|
||||
ColumnFormatDto,
|
||||
GridBoxOptionsDto,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import {
|
|||
deleteListFormCustomization,
|
||||
postListFormCustomization,
|
||||
} from '@/services/list-form-customization.service'
|
||||
import { DataGridRef } from 'devextreme-react/data-grid'
|
||||
import type { DataGridRef } from 'devextreme-react/data-grid'
|
||||
import { Dispatch, MutableRefObject, SetStateAction, useState } from 'react'
|
||||
import CreatableSelect from 'react-select/creatable'
|
||||
import { ISelectBoxData } from './useFilters'
|
||||
|
|
|
|||
|
|
@ -3,20 +3,25 @@ import { APP_NAME, DX_CLASSNAMES } from '@/constants/app.constant'
|
|||
import { GridDto, ListFormCustomizationTypeEnum } from '@/proxy/form/models'
|
||||
import { postListFormCustomization } from '@/services/list-form-customization.service'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import Chart, { ChartRef, CommonSeriesSettings, Size, Tooltip } from 'devextreme-react/chart'
|
||||
import Chart, {
|
||||
type ChartRef,
|
||||
CommonSeriesSettings,
|
||||
Size,
|
||||
Tooltip,
|
||||
} from 'devextreme-react/chart'
|
||||
import PivotGrid, {
|
||||
Export,
|
||||
FieldChooser,
|
||||
FieldPanel,
|
||||
HeaderFilter,
|
||||
LoadPanel,
|
||||
PivotGridRef,
|
||||
PivotGridTypes,
|
||||
type PivotGridRef,
|
||||
type PivotGridTypes,
|
||||
Scrolling,
|
||||
Search,
|
||||
} from 'devextreme-react/pivot-grid'
|
||||
import CustomStore from 'devextreme/data/custom_store'
|
||||
import { Field } from 'devextreme/ui/pivot_grid/data_source'
|
||||
import type { Field } from 'devextreme/ui/pivot_grid/data_source'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { GridColumnData } from './GridColumnData'
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import Scheduler, {
|
|||
Editing,
|
||||
Item,
|
||||
Resource,
|
||||
SchedulerRef,
|
||||
type SchedulerRef,
|
||||
Toolbar,
|
||||
View,
|
||||
} from 'devextreme-react/scheduler'
|
||||
|
|
@ -31,7 +31,7 @@ import { Loading } from '@/components/shared'
|
|||
import { usePermission } from '@/utils/hooks/usePermission'
|
||||
import { RowMode, SimpleItemWithColData } from '../form/types'
|
||||
import { captionize } from 'devextreme/core/utils/inflector'
|
||||
import { AppointmentFormOpeningEvent } from 'devextreme/ui/scheduler'
|
||||
import type { AppointmentFormOpeningEvent } from 'devextreme/ui/scheduler'
|
||||
|
||||
interface SchedulerViewProps {
|
||||
listFormCode: string
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ import TreeListDx, {
|
|||
Selection,
|
||||
Sorting,
|
||||
Toolbar,
|
||||
TreeListRef,
|
||||
TreeListTypes,
|
||||
type TreeListRef,
|
||||
type TreeListTypes,
|
||||
} from 'devextreme-react/tree-list'
|
||||
import { Item } from 'devextreme-react/toolbar'
|
||||
import CustomStore from 'devextreme/data/custom_store'
|
||||
|
|
@ -60,7 +60,7 @@ import { layoutTypes } from '../admin/listForm/edit/types'
|
|||
import { useListFormCustomDataSource } from './useListFormCustomDataSource'
|
||||
import { useListFormColumns } from './useListFormColumns'
|
||||
import { orderListToolbarItems } from './toolbarOrder'
|
||||
import { DataType } from 'devextreme/common'
|
||||
import type { DataType } from 'devextreme/common'
|
||||
import { useStoreState } from '@/store/store'
|
||||
import SubForms from '../form/SubForms'
|
||||
import { ImportDashboard } from '@/components/importManager/ImportDashboard'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { DataType } from 'devextreme/common'
|
||||
import { PivotGridDataType } from 'devextreme/ui/pivot_grid/data_source'
|
||||
import type { DataType } from 'devextreme/common'
|
||||
import type { PivotGridDataType } from 'devextreme/ui/pivot_grid/data_source'
|
||||
import { MULTIVALUE_DELIMITER } from '../../constants/app.constant'
|
||||
import { ChartSeriesDto } from '@/proxy/admin/charts/models'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ToolbarItem } from 'devextreme/ui/data_grid_types'
|
||||
import type { ToolbarItem } from 'devextreme/ui/data_grid_types'
|
||||
|
||||
const orderedToolbarItemNames = [
|
||||
'searchPanel',
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ import {
|
|||
} from '@/proxy/form/models'
|
||||
import { getListFormCustomization } from '@/services/list-form-customization.service'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { DataGridRef } from 'devextreme-react/data-grid'
|
||||
import { PivotGridRef } from 'devextreme-react/pivot-grid'
|
||||
import { TreeListRef } from 'devextreme-react/tree-list'
|
||||
import { ToolbarItem } from 'devextreme/ui/data_grid_types'
|
||||
import type { DataGridRef } from 'devextreme-react/data-grid'
|
||||
import type { PivotGridRef } from 'devextreme-react/pivot-grid'
|
||||
import type { TreeListRef } from 'devextreme-react/tree-list'
|
||||
import type { ToolbarItem } from 'devextreme/ui/data_grid_types'
|
||||
import dxDataGrid from 'devextreme/ui/data_grid'
|
||||
import dxPivotGrid from 'devextreme/ui/pivot_grid'
|
||||
import dxTreeList from 'devextreme/ui/tree_list'
|
||||
|
|
@ -19,7 +19,7 @@ import { setGridPanelColor } from './Utils'
|
|||
import { usePermission } from '@/utils/hooks/usePermission'
|
||||
import { usePWA } from '@/utils/hooks/usePWA'
|
||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||
import { GanttRef } from 'devextreme-react/cjs/gantt'
|
||||
import type { GanttRef } from 'devextreme-react/cjs/gantt'
|
||||
import { useStoreState } from '@/store'
|
||||
import { MULTIVALUE_DELIMITER } from '@/constants/app.constant'
|
||||
import { createReportQueryString } from '../report/reportRouteParams'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { DataGridTypes } from 'devextreme-react/data-grid'
|
||||
import { DataType, HorizontalEdge, SortOrder, ValidationRule } from 'devextreme/common'
|
||||
import type { DataGridTypes } from 'devextreme-react/data-grid'
|
||||
import type { DataType, HorizontalEdge, SortOrder, ValidationRule } from 'devextreme/common'
|
||||
import CustomStore from 'devextreme/data/custom_store'
|
||||
import { SelectedFilterOperation } from 'devextreme/ui/data_grid'
|
||||
import type { SelectedFilterOperation } from 'devextreme/ui/data_grid'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { usePermission } from '@/utils/hooks/usePermission'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { DataGridRef } from 'devextreme-react/data-grid'
|
||||
import { PivotGridRef } from 'devextreme-react/pivot-grid'
|
||||
import type { DataGridRef } from 'devextreme-react/data-grid'
|
||||
import type { PivotGridRef } from 'devextreme-react/pivot-grid'
|
||||
import CustomStore from 'devextreme/data/custom_store'
|
||||
import { MutableRefObject, useCallback } from 'react'
|
||||
import { layoutTypes, ListViewLayoutType } from '@/views/admin/listForm/edit/types'
|
||||
|
|
@ -8,10 +8,10 @@ import { GridOptionsDto } from '@/proxy/form/models'
|
|||
import { GridColumnData } from './GridColumnData'
|
||||
import { dynamicFetch } from '@/services/form.service'
|
||||
import { MULTIVALUE_DELIMITER } from '@/constants/app.constant'
|
||||
import { TreeListRef } from 'devextreme-react/cjs/tree-list'
|
||||
import { GanttRef } from 'devextreme-react/cjs/gantt'
|
||||
import { SchedulerRef } from 'devextreme-react/cjs/scheduler'
|
||||
import { CardViewRef, CardViewTypes } from 'devextreme-react/cjs/card-view'
|
||||
import type { TreeListRef } from 'devextreme-react/cjs/tree-list'
|
||||
import type { GanttRef } from 'devextreme-react/cjs/gantt'
|
||||
import type { SchedulerRef } from 'devextreme-react/cjs/scheduler'
|
||||
import type { CardViewRef, CardViewTypes } from 'devextreme-react/cjs/card-view'
|
||||
|
||||
const filteredGridPanelColor = 'rgba(10, 200, 10, 0.5)' // kullanici tanimli filtre ile filtrelenmis gridin paneline ait renk
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { GridDto, UiCommandButtonPositionTypeEnum, WorkflowDto } from '@/proxy/f
|
|||
import { dynamicFetch } from '@/services/form.service'
|
||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||
import { usePermission } from '@/utils/hooks/usePermission'
|
||||
import { DataGridTypes } from 'devextreme-react/data-grid'
|
||||
import { ToolbarItem } from 'devextreme/ui/data_grid_types'
|
||||
import type { DataGridTypes } from 'devextreme-react/data-grid'
|
||||
import type { ToolbarItem } from 'devextreme/ui/data_grid_types'
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { ReactNode } from 'react'
|
||||
import { useDialogContext } from '../shared/DialogContext'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import Button from 'devextreme-react/button'
|
||||
import DataGrid, { DataGridRef } from 'devextreme-react/data-grid'
|
||||
import DataGrid, { type DataGridRef } from 'devextreme-react/data-grid'
|
||||
import DropDownBox from 'devextreme-react/drop-down-box'
|
||||
import { ReactElement, useRef } from 'react'
|
||||
import { GridBoxOptionsDto } from '@/proxy/form/models'
|
||||
|
|
|
|||
Loading…
Reference in a new issue