i18n ve Localization düzenlemesi

This commit is contained in:
Sedat ÖZTÜRK 2025-08-12 12:39:09 +03:00
parent 00eb20d55f
commit 012f507cd3
42 changed files with 1462 additions and 678 deletions

View file

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

1500
ui/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -44,7 +44,6 @@
"formik": "^2.4.6",
"framer-motion": "^11.15.0",
"history": "^5.3.0",
"i18next": "^23.7.11",
"jspdf": "^3.0.1",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
@ -57,7 +56,6 @@
"react-error-boundary": "^5.0.0",
"react-helmet": "^6.1.0",
"react-highlight-words": "^0.20.0",
"react-i18next": "^15.2.0",
"react-icons": "^5.4.0",
"react-modal": "^3.16.3",
"react-quill": "^2.0.0",

View file

@ -1,31 +1,31 @@
import { MenuDto } from "@/proxy/menus";
import { MenuDto } from '@/proxy/menus/models'
export interface MenuItem extends MenuDto {
children?: MenuItem[];
children?: MenuItem[]
}
export interface MenuApiResponse {
totalCount: number;
items: MenuItem[];
totalCount: number
items: MenuItem[]
}
export interface DragEndEvent {
active: {
id: string;
id: string
data: {
current: {
type: string;
item: MenuItem;
};
};
};
type: string
item: MenuItem
}
}
}
over: {
id: string;
id: string
data: {
current: {
type: string;
item?: MenuItem;
};
};
} | null;
type: string
item?: MenuItem
}
}
} | null
}

View file

@ -3,7 +3,6 @@ import Theme from '@/components/template/Theme'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { StoreProvider } from 'easy-peasy'
import { BrowserRouter } from 'react-router-dom'
import './locales'
import { store } from './store'
import { DynamicRoutesProvider } from './routes/dynamicRoutesContext'
import { ComponentProvider } from './contexts/ComponentContext'

View file

@ -14,9 +14,9 @@ import {
import { FileUploadArea } from './FileUploadArea'
import { ImportPreview } from './ImportPreview'
import { ImportProgress } from './ImportProgress'
import { GridDto } from '@/proxy/form'
import { ListFormImportDto, ListFormImportExecuteDto } from '@/proxy/imports/models'
import { ImportService } from '@/services/import.service'
import { GridDto } from '@/proxy/form/models'
interface ImportDashboardProps {
gridDto: GridDto
@ -97,17 +97,26 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
if (session.status !== 'failed') {
// Daha uzun süreli ve gerçekçi bir progression
setTimeout(async () => {
session = await importService.updateSession(session.id, { status: 'validating', listFormCode: gridDto.gridOptions.listFormCode || '' })
session = await importService.updateSession(session.id, {
status: 'validating',
listFormCode: gridDto.gridOptions.listFormCode || '',
})
setCurrentSession(session)
}, 1000) // 1 saniye sonra validating
setTimeout(async () => {
session = await importService.updateSession(session.id, { status: 'processing', listFormCode: gridDto.gridOptions.listFormCode || '' })
session = await importService.updateSession(session.id, {
status: 'processing',
listFormCode: gridDto.gridOptions.listFormCode || '',
})
setCurrentSession(session)
}, 2000) // 2 saniye sonra processing başlangıç
setTimeout(async () => {
session = await importService.updateSession(session.id, { status: 'uploaded', listFormCode: gridDto.gridOptions.listFormCode || '' })
session = await importService.updateSession(session.id, {
status: 'uploaded',
listFormCode: gridDto.gridOptions.listFormCode || '',
})
setCurrentSession(session)
}, 3000) // 3 saniye sonra uploaded
@ -199,7 +208,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
const getEditableColumns = () => {
return gridDto.columnFormats.filter(
(col) =>
(col: any) =>
col.visible &&
col.columnEditingDto.allowEditing &&
col.canCreate &&
@ -287,7 +296,7 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
{editableColumns.map((column) => (
{editableColumns.map((column: any) => (
<tr key={column.fieldName} className="hover:bg-slate-50">
<td className="px-2 py-2 font-medium text-slate-800">
{column.captionName || column.fieldName}
@ -308,7 +317,9 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
</span>
</td>
<td className="px-4 py-2">
{column.validationRuleDto.some((rule) => rule.type === 'required') ? (
{column.validationRuleDto.some(
(rule: any) => rule.type === 'required',
) ? (
<span className="text-red-500 font-medium">Yes</span>
) : (
<span className="text-slate-400">No</span>
@ -455,7 +466,9 @@ export const ImportDashboard: React.FC<ImportDashboardProps> = ({ gridDto }) =>
if (sessionExecutes[session.id]) {
setLoadingExecutes((prev) => new Set([...prev, session.id]))
try {
const executes = await importService.getListFormImportExecutes(session.id)
const executes = await importService.getListFormImportExecutes(
session.id,
)
setSessionExecutes((prev) => ({
...prev,
[session.id]: executes,

View file

@ -1,13 +1,17 @@
import React, { useState, useEffect, useRef } from 'react'
import { CheckCircle, AlertTriangle, Eye, Play, X } from 'lucide-react'
import { ListFormImportDto } from '@/proxy/imports/models'
import { GridDto } from '@/proxy/form'
import { GridDto } from '@/proxy/form/models'
import { ImportService } from '@/services/import.service'
interface ImportPreviewProps {
session: ListFormImportDto
gridDto: GridDto
onExecute: (sessionId: string, listFormCode: string, selectedRows?: number[]) => Promise<{ successCount?: number } | void>
onExecute: (
sessionId: string,
listFormCode: string,
selectedRows?: number[],
) => Promise<{ successCount?: number } | void>
loading: boolean
importService: ImportService
onPreviewLoaded?: () => void
@ -20,13 +24,15 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
loading,
importService,
onPreviewLoaded,
}) => {
const [previewData, setPreviewData] = useState<any>(null)
const [selectedRows, setSelectedRows] = useState<number[]>([])
const [selectAll, setSelectAll] = useState(false)
const [showSuccessMessage, setShowSuccessMessage] = useState(false)
const [lastExecutionResult, setLastExecutionResult] = useState<{ selectedCount: number; successCount: number } | null>(null)
const [lastExecutionResult, setLastExecutionResult] = useState<{
selectedCount: number
successCount: number
} | null>(null)
const hasCalledOnPreviewLoaded = useRef(false)
// Selection handlers
@ -173,9 +179,7 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
{/* Preview Data */}
{previewData && previewData.headers && previewData.headers.length > 0 ? (
<div className="p-3 border-b border-slate-200">
<h4 className="font-semibold text-slate-800 mb-4">
Data Preview
</h4>
<h4 className="font-semibold text-slate-800 mb-4">Data Preview</h4>
<div className="overflow-auto border border-slate-200 rounded-lg max-h-90">
<table className="w-full text-sm min-w-full">
@ -257,7 +261,8 @@ export const ImportPreview: React.FC<ImportPreviewProps> = ({
<div className="flex items-center space-x-2 text-green-700">
<CheckCircle className="w-5 h-5" />
<span className="font-medium">
Import completed successfully! {lastExecutionResult.successCount} of {lastExecutionResult.selectedCount} rows were imported.
Import completed successfully! {lastExecutionResult.successCount} of{' '}
{lastExecutionResult.selectedCount} rows were imported.
</span>
</div>
</div>

View file

@ -6,13 +6,13 @@ import type { ReactNode, ReactElement } from 'react'
import type { CommonProps } from '@/@types/common'
import { HiArrowLeft, HiCheck } from 'react-icons/hi'
import { Avatar, Select } from '@/components/ui'
import i18n, { dateLocales } from '@/locales'
import { useStoreActions, useStoreState } from '@/store'
import appConfig from '@/configs/app.config'
import dayjs from 'dayjs'
import { components } from 'react-select'
import { ROUTES_ENUM } from '@/routes/route.constant'
import { hasSubdomain } from '@/utils/subdomain'
import { dateLocales } from '@/constants/dateLocales.constant'
interface SimpleProps extends CommonProps {
content?: ReactNode
@ -38,7 +38,6 @@ const Simple = ({ children, content, ...rest }: SimpleProps) => {
const onLanguageSelect = (cultureName = appConfig.locale) => {
const dispatchLang = () => {
i18n.changeLanguage(cultureName)
setLang(cultureName)
}

View file

@ -7,10 +7,10 @@ import {
NAV_ITEM_TYPE_TITLE,
} from '@/constants/navigation.constant'
import { useStoreState } from '@/store'
import { useTranslation } from 'react-i18next'
import HorizontalMenuDropdownItem from './HorizontalMenuDropdownItem'
import HorizontalMenuItem from './HorizontalMenuItem'
import HorizontalMenuIcon from './HorizontalMenuIcon'
import { useLocalization } from '@/utils/hooks/useLocalization'
type HorizontalMenuContentProps = {
manuVariant: NavMode
@ -18,8 +18,6 @@ type HorizontalMenuContentProps = {
}
const HorizontalMenuContent = ({ manuVariant }: HorizontalMenuContentProps) => {
const { t } = useTranslation()
const { mainMenu: navigationConfig } = useStoreState((state) => state.abpConfig.menu)
return (
@ -45,7 +43,7 @@ const HorizontalMenuContent = ({ manuVariant }: HorizontalMenuContentProps) => {
title={
<div className="flex items-center">
<HorizontalMenuIcon icon={secondarySubNav.icon} />
<span>{t(secondarySubNav.translateKey, secondarySubNav.title)}</span>
<span>{secondarySubNav.title}</span>
</div>
}
>

View file

@ -1,7 +1,6 @@
import Dropdown from '@/components/ui/Dropdown'
import HorizontalMenuNavLink from './HorizontalMenuNavLink'
import classNames from 'classnames'
import { useTranslation } from 'react-i18next'
export type HorizontalMenuItemProps = {
nav: {
@ -15,36 +14,21 @@ export type HorizontalMenuItemProps = {
}
const HorizontalMenuDropdownItem = ({ nav }: HorizontalMenuItemProps) => {
const { title, translateKey, path, key, isExternalLink, icon } = nav
const { t } = useTranslation()
const itemTitle = t(translateKey, title)
const { title, path, key, isExternalLink, icon } = nav
return (
<Dropdown.Item
eventKey={key}
className={
classNames(
path
)
}
>
<Dropdown.Item eventKey={key} className={classNames(path)}>
{path ? (
<HorizontalMenuNavLink
path={path}
className={
classNames(
path
)
}
className={classNames(path)}
isExternalLink={isExternalLink}
icon={icon}
>
{itemTitle}
{title}
</HorizontalMenuNavLink>
) : (
<span>{itemTitle}</span>
<span>{title}</span>
)}
</Dropdown.Item>
)

View file

@ -1,7 +1,6 @@
import navigationIcon from '@/configs/navigation-icon.config'
import MenuItem from '@/components/ui/MenuItem'
import HorizontalMenuNavLink from './HorizontalMenuNavLink'
import { useTranslation } from 'react-i18next'
import type { NavMode } from '@/@types/theme'
export type HorizontalMenuItemProps = {
@ -17,16 +16,8 @@ export type HorizontalMenuItemProps = {
manuVariant: NavMode
}
const HorizontalMenuItem = ({
nav,
isLink,
manuVariant,
}: HorizontalMenuItemProps) => {
const { title, translateKey, icon, path, isExternalLink } = nav
const { t } = useTranslation()
const itemTitle = t(translateKey, title)
const HorizontalMenuItem = ({ nav, isLink, manuVariant }: HorizontalMenuItemProps) => {
const { title, icon, path, isExternalLink } = nav
const renderIcon = icon && <span className="text-2xl">{navigationIcon[icon]}</span>
@ -37,14 +28,14 @@ const HorizontalMenuItem = ({
<MenuItem variant={manuVariant}>
<span className="flex items-center gap-2">
{renderIcon}
{itemTitle}
{title}
</span>
</MenuItem>
</HorizontalMenuNavLink>
) : (
<MenuItem variant={manuVariant}>
{renderIcon}
<span>{itemTitle}</span>
<span>{title}</span>
</MenuItem>
)}
</>

View file

@ -5,13 +5,11 @@ import Spinner from '@/components/ui/Spinner'
import classNames from 'classnames'
import withHeaderItem from '@/utils/hoc/withHeaderItem'
import { useStoreState, useStoreActions } from '@/store'
import { dateLocales } from '@/locales'
import dayjs from 'dayjs'
// eslint-disable-next-line import/no-named-as-default
import i18n from 'i18next'
import { HiCheck } from 'react-icons/hi'
import type { CommonProps } from '@/@types/common'
import appConfig from '@/configs/app.config'
import { dateLocales } from '@/constants/dateLocales.constant'
const _LanguageSelector = ({ className }: CommonProps) => {
const [loading, setLoading] = useState(false)
@ -41,7 +39,6 @@ const _LanguageSelector = ({ className }: CommonProps) => {
setLoading(true)
const dispatchLang = () => {
i18n.changeLanguage(cultureName)
setLang(cultureName)
setLoading(false)
}

View file

@ -12,28 +12,21 @@ import StackedSideNavSecondary from './StackedSideNavSecondary'
import useResponsive from '@/utils/hooks/useResponsive'
import isEmpty from 'lodash/isEmpty'
import { useStoreState } from '@/store'
import { useTranslation } from 'react-i18next'
const stackedSideNavDefaultStyle = {
width: SPLITTED_SIDE_NAV_MINI_WIDTH,
}
const StackedSideNav = () => {
const { t } = useTranslation()
const [selectedMenu, setSelectedMenu] = useState<SelectedMenuItem>({})
const [activeKeys, setActiveKeys] = useState<string[]>([])
const themeColor = useStoreState((state) => state.theme.themeColor)
const primaryColorLevel = useStoreState(
(state) => state.theme.primaryColorLevel
)
const primaryColorLevel = useStoreState((state) => state.theme.primaryColorLevel)
const navMode = useStoreState((state) => state.theme.navMode)
const mode = useStoreState((state) => state.theme.mode)
const direction = useStoreState((state) => state.theme.direction)
const currentRouteKey = useStoreState(
(state) => state.base.common.currentRouteKey
)
const currentRouteKey = useStoreState((state) => state.base.common.currentRouteKey)
const userAuthority = useStoreState((state) => state.auth.user.authority)
const { larger } = useResponsive()
@ -77,10 +70,7 @@ const StackedSideNav = () => {
{larger.md && (
<div className={`stacked-side-nav`}>
<StackedSideNavMini
className={`stacked-side-nav-mini ${navColor(
'stacked-side-nav-mini',
navMode
)}`}
className={`stacked-side-nav-mini ${navColor('stacked-side-nav-mini', navMode)}`}
style={stackedSideNavDefaultStyle}
routeKey={currentRouteKey}
activeKeys={activeKeys}
@ -95,21 +85,16 @@ const StackedSideNav = () => {
className={`stacked-side-nav-secondary ${navColor(
'stacked-side-nav-secondary',
mode,
false
false,
)}`}
style={{
width: SPLITTED_SIDE_NAV_SECONDARY_WIDTH,
...(isEmpty(selectedMenu)
? stackedSideNavSecondaryDirStyle()
: {}),
...(isEmpty(selectedMenu) ? stackedSideNavSecondaryDirStyle() : {}),
}}
>
{!isEmpty(selectedMenu) && (
<StackedSideNavSecondary
title={t(
selectedMenu.translateKey as string,
selectedMenu.title as string
)}
title={selectedMenu.title as string}
menu={selectedMenu.menu}
routeKey={currentRouteKey}
navMode={NAV_MODE_TRANSPARENT}

View file

@ -4,7 +4,6 @@ import type { Direction } from '@/@types/theme'
import { PermissionCheck } from '@/components/shared'
import Dropdown from '@/components/ui/Dropdown'
import Menu from '@/components/ui/Menu'
import { Trans } from 'react-i18next'
import { Link } from 'react-router-dom'
import VerticalMenuIcon from './VerticalMenuIcon'
@ -33,9 +32,7 @@ const DefaultItem = ({ nav, onLinkClick }: DefaultItemProps) => {
label={
<>
<VerticalMenuIcon icon={nav.icon} />
<span>
<Trans i18nKey={nav.translateKey} defaults={nav.title} />
</span>
<span>{nav.title}</span>
</>
}
eventKey={nav.key}
@ -58,14 +55,10 @@ const DefaultItem = ({ nav, onLinkClick }: DefaultItemProps) => {
}
target={subNav.isExternalLink ? '_blank' : ''}
>
<span>
<Trans i18nKey={subNav.translateKey} defaults={subNav.title} />
</span>
<span>{nav.title}</span>
</Link>
) : (
<span>
<Trans i18nKey={subNav.translateKey} defaults={subNav.title} />
</span>
<span>{nav.title}</span>
)}
</MenuItem>
</PermissionCheck>
@ -105,14 +98,10 @@ const CollapsedItem = ({ nav, onLinkClick, direction }: CollapsedItemProps) => {
}
target={subNav.isExternalLink ? '_blank' : ''}
>
<span>
<Trans i18nKey={subNav.translateKey} defaults={subNav.title} />
</span>
<span>{subNav.title}</span>
</Link>
) : (
<span>
<Trans i18nKey={subNav.translateKey} defaults={subNav.title} />
</span>
<span>{subNav.title}</span>
)}
</Dropdown.Item>
</PermissionCheck>

View file

@ -10,7 +10,6 @@ import {
} from '@/constants/navigation.constant'
import useMenuActive from '@/utils/hooks/useMenuActive'
import { useEffect, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { Link, useLocation } from 'react-router-dom'
import VerticalCollapsedMenuItem from './VerticalCollapsedMenuItem'
import VerticalSingleMenuItem from './VerticalSingleMenuItem'
@ -42,9 +41,6 @@ const VerticalMenuContent = (props: VerticalMenuContentProps) => {
onMenuItemClick,
direction = themeConfig.direction,
} = props
const { t } = useTranslation()
const [defaultExpandedKeys, setDefaultExpandedKeys] = useState<string[]>([])
const [defaultActiveKeys, setDefaultActiveKeys] = useState<string[]>([])
@ -105,9 +101,7 @@ const VerticalMenuContent = (props: VerticalMenuContentProps) => {
label={
<>
<VerticalMenuIcon icon={nav.icon} />
<span>
<Trans i18nKey={nav.translateKey} defaults={nav.title} />
</span>
<span>{nav.title}</span>
</>
}
eventKey={nav.key}

View file

@ -2,7 +2,6 @@ import Tooltip from '@/components/ui/Tooltip'
import Menu from '@/components/ui/Menu'
import VerticalMenuIcon from './VerticalMenuIcon'
import { Link } from 'react-router-dom'
import { Trans, useTranslation } from 'react-i18next'
import type { CommonProps } from '@/@types/common'
import type { Direction } from '@/@types/theme'
import type { NavigationTree } from '@/@types/navigation'
@ -27,10 +26,8 @@ interface DefaultItemProps {
interface VerticalMenuItemProps extends CollapsedItemProps, DefaultItemProps {}
const CollapsedItem = ({ title, translateKey, children, direction }: CollapsedItemProps) => {
const { t } = useTranslation()
return (
<Tooltip title={t(translateKey) || title} placement={direction === 'rtl' ? 'left' : 'right'}>
<Tooltip title={title} placement={direction === 'rtl' ? 'left' : 'right'}>
{children}
</Tooltip>
)
@ -55,11 +52,7 @@ const DefaultItem = (props: DefaultItemProps) => {
target={nav.isExternalLink ? '_blank' : ''}
>
<VerticalMenuIcon icon={nav.icon} />
{!sideCollapsed && (
<span>
<Trans i18nKey={nav.translateKey} defaults={nav.title} />
</span>
)}
{!sideCollapsed && <span>{nav.title}</span>}
</Link>
</MenuItem>
</PermissionCheck>

View file

@ -1,24 +1,3 @@
// eslint-disable-next-line import/no-named-as-default
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'
import en from './lang/en.json'
import appConfig from '@/configs/app.config'
const resources = {
en: {
translation: en,
},
}
i18n.use(initReactI18next).init({
resources,
fallbackLng: appConfig.locale,
lng: appConfig.locale,
interpolation: {
escapeValue: false,
},
})
export const dateLocales: {
[key: string]: () => Promise<ILocale>
} = {
@ -40,5 +19,3 @@ export const dateLocales: {
tr: () => import('dayjs/locale/tr'),
zh: () => import('dayjs/locale/zh'),
}
export default i18n

View file

@ -1,4 +0,0 @@
import i18n from './locales'
export { dateLocales } from './locales'
export default i18n

View file

@ -1,20 +0,0 @@
{
"nav": {
"home": "Home",
"singleMenuItem": "Single menu item",
"collapseMenu": {
"collapseMenu": "Collapse menu item",
"item1": "Collapse menu item 1",
"item2": "Collapse menu item 2"
},
"groupMenu": {
"groupMenu": "Group menu",
"single": "Group single menu item",
"collapse": {
"collapse": "Group collapse menu",
"item1": "Group collapse menu item 1",
"item2": "Group collapse menu item 2"
}
}
}
}

View file

@ -1,5 +1,5 @@
import { AuditedEntityDto } from '@/proxy/abp'
import { PermissionCrudDto } from '@/proxy/form'
import { PermissionCrudDto } from '../form/models'
export interface BreakDto {
endValue: number

View file

@ -1,4 +1,4 @@
import { RouteDto } from '@/proxy/routes'
import { RouteDto } from '@/proxy/routes/models'
import { lazy } from 'react'
// Tüm view bileşenlerini import et (vite özel)
@ -27,11 +27,11 @@ export function loadComponent(componentPath: string) {
// React Router için uygun bir route tipi
export interface DynamicReactRoute {
key: string;
path: string;
getComponent: () => React.LazyExoticComponent<React.ComponentType<any>>;
routeType: string;
authority?: string[];
key: string
path: string
getComponent: () => React.LazyExoticComponent<React.ComponentType<any>>
routeType: string
authority?: string[]
}
// API'den gelen route objesini, React Router için uygun hale getirir
@ -42,5 +42,5 @@ export function mapDynamicRoutes(routes: RouteDto[]): DynamicReactRoute[] {
getComponent: () => loadComponent(route.componentPath),
routeType: route.routeType,
authority: route.authority,
}));
}))
}

View file

@ -1,4 +1,4 @@
import { RouteDto } from '@/proxy/routes'
import { RouteDto } from '@/proxy/routes/models'
import React, { createContext, useContext, useEffect, useState } from 'react'
import { useStoreState } from '@/store/store'

View file

@ -1,7 +1,7 @@
import { AxiosError } from 'axios'
import { SignUpCredential, SignUpResponse } from '../@types/auth'
import apiService from './api.service'
import { ProfileDto, UpdateProfileDto } from '../proxy/account'
import { ProfileDto, UpdateProfileDto } from '@/proxy/account/models'
export const register = (data: SignUpCredential) =>
apiService.fetchData<SignUpResponse>({

View file

@ -1,6 +1,6 @@
import { ListResultDto } from '../../proxy'
import { ListFormCustomizationRequestDto } from '../../proxy/admin/list-form-customization/models'
import { ListFormCustomizationDto } from '../../proxy/form'
import { ListFormCustomizationDto } from '../../proxy/form/models'
import apiService from '../api.service'
export const getListFormCustomizations = (input: ListFormCustomizationRequestDto) =>

View file

@ -1,5 +1,5 @@
import { ListFormJsonRowDto, ListFormWizardDto } from '../../proxy/admin/list-form/models'
import { FieldsDefaultValueDto, GridOptionsEditDto } from '../../proxy/form'
import { FieldsDefaultValueDto, GridOptionsEditDto } from '../../proxy/form/models'
import apiService from '../api.service'
export const postListFormWizard = (input: ListFormWizardDto) =>

View file

@ -1,5 +1,5 @@
import { AiDto } from '@/proxy/ai/models'
import { PagedAndSortedResultRequestDto, PagedResultDto } from '../proxy'
import { AiDto } from '../proxy/ai'
import apiService, { Config } from './api.service'
export class AiService {

View file

@ -1,6 +1,6 @@
import { AxiosError, Method } from 'axios'
import { URLSearchParams } from 'url'
import { GridDto } from '../proxy/form'
import { GridDto } from '../proxy/form/models'
import apiService from './api.service'
export const getList = (data: Record<string, string>) => {

View file

@ -1,4 +1,3 @@
import { ListResultDto } from '../proxy'
import {
GetPermissionListResultDto,
IdentityRoleDto,
@ -7,7 +6,8 @@ import {
UpdatePermissionsDto,
UserClaimModel,
UserInfoViewModel,
} from '../proxy/admin'
} from '@/proxy/admin/models'
import { ListResultDto } from '../proxy'
import { AuditLogDto } from '../proxy/auditLog/audit-log'
import apiService from './api.service'

View file

@ -1,4 +1,4 @@
import { GridDto } from '@/proxy/form'
import { GridDto } from '@/proxy/form/models'
import {
ImportPreviewData,
ListFormImportDto,
@ -177,7 +177,10 @@ ${headers
}
})
await this.updateSession(sessionId, { totalRows: rows.length, listFormCode: gridDto?.gridOptions.listFormCode || '' })
await this.updateSession(sessionId, {
totalRows: rows.length,
listFormCode: gridDto?.gridOptions.listFormCode || '',
})
return {
sessionId,

View file

@ -2,7 +2,7 @@ import {
ListFormCustomizationDto,
ListFormCustomizationForUserDto,
ListFormCustomizationTypeEnum,
} from '../proxy/form'
} from '../proxy/form/models'
import apiService from './api.service'
export const getListFormCustomization = (

View file

@ -1,5 +1,5 @@
import { IdentityRoleDto, IdentityUserDto } from '@/proxy/admin/models'
import { ListResultDto, PagedResultDto } from '../proxy'
import { IdentityRoleDto, IdentityUserDto } from '../proxy/admin'
import {
CreateUpdateOrganizationUnitDto,
OrganizationUnitDto,

View file

@ -1,4 +1,4 @@
import { RouteDto } from '@/proxy/routes'
import { RouteDto } from '@/proxy/routes/models'
import apiService, { Config } from '@/services/api.service'
export class RouteService {

View file

@ -1,6 +1,6 @@
import { AxiosError } from 'axios'
import { MainGroupedSettingDto } from '../proxy/settings'
import apiService from './api.service'
import { MainGroupedSettingDto } from '@/proxy/settings/models'
export const getList = () =>
apiService.fetchData<MainGroupedSettingDto[]>({

View file

@ -1,35 +1,24 @@
// scripts/tenant.ts
import axios from 'axios'
import https from 'https'
export type TenantDto = { name: string }
export type PagedResultDto<T> = { totalCount: number; items: T[] }
if (process.env.NODE_ENV === 'development') {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
}
export async function fetchTenantNames(apiUrl: string): Promise<string[]> {
try {
const url = `${apiUrl.replace(/\/$/, '')}/api/app/platform-tenant?skipCount=0&maxResultCount=1000`
const isLocalHttps = /^https:\/\/localhost(:\d+)?/i.test(apiUrl)
const response = await fetch(url, {
const response = await axios.get<PagedResultDto<TenantDto>>(url, {
headers: {
Accept: 'application/json',
'X-Requested-With': 'XMLHttpRequest',
},
httpsAgent: isLocalHttps ? new https.Agent({ rejectUnauthorized: false }) : undefined,
})
if (!response.ok) {
console.error('[vite] Tenant API hatası:', response.status, response.statusText)
return []
}
const data = (await response.json()) as PagedResultDto<TenantDto>
return (data.items ?? [])
.map((t) =>
String(t?.name || '')
.trim()
.toLowerCase(),
)
.filter(Boolean)
return (response.data.items ?? []).map((t: TenantDto) => t.name.trim().toLowerCase())
} catch (e) {
console.error('[vite] Tenant listesi alınamadı:', e)
return []

View file

@ -1,10 +1,7 @@
import { useEffect } from 'react'
// eslint-disable-next-line import/no-named-as-default
import i18n from 'i18next'
import dayjs from 'dayjs'
import { dateLocales } from '@/locales'
import { useStoreState } from '@/store'
import { locale } from 'devextreme/localization'
import { dateLocales } from '@/constants/dateLocales.constant'
function useLocale() {
const cultureName = useStoreState((state) => state.locale.currentLang)
@ -14,10 +11,6 @@ function useLocale() {
)?.twoLetterISOLanguageName
useEffect(() => {
if (cultureName !== i18n.language) {
i18n.changeLanguage(cultureName)
locale(twoLetterISOLanguageName ?? cultureName)
}
if (cultureName && twoLetterISOLanguageName && dateLocales[twoLetterISOLanguageName]) {
dateLocales[twoLetterISOLanguageName]().then(() => {
dayjs.locale(cultureName)

View file

@ -1,5 +1,10 @@
import { ListFormEditTabs } from '@/proxy/admin/list-form/models'
import { CommandColumnDto, EditingFormDto, FieldsDefaultValueDto, SubFormDto } from '@/proxy/form'
import {
CommandColumnDto,
EditingFormDto,
FieldsDefaultValueDto,
SubFormDto,
} from '@/proxy/form/models'
import { ExtractNestedValues } from '@/utils/extractNestedValues'
export type JsonRowOperation = 'create' | 'update' | 'delete'

View file

@ -6,11 +6,11 @@ import { useEffect, useState } from 'react'
import { MdBarChart, MdList } from 'react-icons/md'
import { useLocation, useNavigate } from 'react-router-dom'
import Grid from '../list/Grid'
import Chart from '../chart/Chart'
import { GridDto, SubFormDto, SubFormTabTypeEnum } from '@/proxy/form/models'
import FormEdit from './FormEdit'
import FormNew from './FormNew'
import FormView from './FormView'
import Chart from '../chart/Chart'
import { GridDto, SubFormDto, SubFormTabTypeEnum } from '@/proxy/form/models'
const SubForms = (props: {
gridDto: GridDto

View file

@ -1,4 +1,4 @@
import { GridBoxOptionsDto } from '@/proxy/form'
import { GridBoxOptionsDto } from '@/proxy/form/models'
import { GridColumnData } from '@/views/list/GridColumnData'
import { Button } from 'devextreme-react/button'
import DataGrid from 'devextreme-react/data-grid'

View file

@ -1,4 +1,4 @@
import { TagBoxOptionsDto } from '@/proxy/form'
import { TagBoxOptionsDto } from '@/proxy/form/models'
import { GridColumnData } from '@/views/list/GridColumnData'
import TagBox from 'devextreme-react/tag-box'
import { ApplyValueMode } from 'devextreme/common'

View file

@ -2,7 +2,7 @@ import { FormItemComponent, SimpleItem } from 'devextreme/ui/form'
import { GridColumnData } from '../list/GridColumnData'
import { Overwrite } from '../../utils/types'
import { GridBoxOptionsDto, PlatformEditorTypes, TagBoxOptionsDto } from '../../proxy/form/models'
import { Meta } from 'easy-peasy'
import { Meta } from '@/@types/routes'
export type EditorType2 = FormItemComponent | PlatformEditorTypes.dxGridBox
export type SimpleItemWithColData = Overwrite<

View file

@ -402,8 +402,7 @@ export function PostManagement({
setPostToDelete(null)
}
}}
>
</ConfirmDialog>
></ConfirmDialog>
)}
</div>
)

3
ui/src/views/index.ts Normal file
View file

@ -0,0 +1,3 @@
import Views from './Views'
export default Views