Tenant bazında Localization düzenlemesi
This commit is contained in:
parent
768dfdfd16
commit
bab93daf10
9 changed files with 150 additions and 19 deletions
|
|
@ -9,9 +9,9 @@
|
||||||
"code": "Abp.Localization.DefaultLanguage",
|
"code": "Abp.Localization.DefaultLanguage",
|
||||||
"nameKey": "Abp.Localization.DefaultLanguage",
|
"nameKey": "Abp.Localization.DefaultLanguage",
|
||||||
"descriptionKey": "Abp.Localization.DefaultLanguage.Description",
|
"descriptionKey": "Abp.Localization.DefaultLanguage.Description",
|
||||||
"defaultValue": "en",
|
"defaultValue": "tr",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": ["G", "D"],
|
"providers": ["T", "G", "D"],
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
"isEncrypted": false,
|
"isEncrypted": false,
|
||||||
"mainGroupKey": "App.SiteManagement",
|
"mainGroupKey": "App.SiteManagement",
|
||||||
|
|
@ -40,12 +40,12 @@
|
||||||
"order": 1
|
"order": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"code": "Abp.Localization.Timezone",
|
"code": "Abp.Timing.TimeZone",
|
||||||
"nameKey": "Abp.Localization.Timezone",
|
"nameKey": "Abp.Timing.TimeZone",
|
||||||
"descriptionKey": "Abp.Localization.Timezone.Description",
|
"descriptionKey": "Abp.Timing.TimeZone.Description",
|
||||||
"defaultValue": "UTC",
|
"defaultValue": "Turkey Standard Time",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": ["G", "D"],
|
"providers": ["T", "G", "D"],
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
"isEncrypted": false,
|
"isEncrypted": false,
|
||||||
"mainGroupKey": "App.SiteManagement",
|
"mainGroupKey": "App.SiteManagement",
|
||||||
|
|
@ -3607,6 +3607,12 @@
|
||||||
"en": "Timezone",
|
"en": "Timezone",
|
||||||
"tr": "Saat Dilimi"
|
"tr": "Saat Dilimi"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "Abp.Timing.TimeZone",
|
||||||
|
"en": "Timezone",
|
||||||
|
"tr": "Saat Dilimi"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "Abp.Localization.Timezone.Description",
|
"key": "Abp.Localization.Timezone.Description",
|
||||||
|
|
@ -5813,13 +5819,13 @@
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.EditingForm",
|
"key": "ListForms.ListFormEdit.EditingForm",
|
||||||
"en": "Form",
|
"en": "Form",
|
||||||
"tr": "Dışarıdan Tıklandığında Gizle"
|
"tr": "Form"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "ListForms.ListFormEdit.EditingFormFormFields",
|
"key": "ListForms.ListFormEdit.EditingFormFormFields",
|
||||||
"en": "Editing Form Fields",
|
"en": "Editing Form Fields",
|
||||||
"tr": "Form"
|
"tr": "Düzenleme Form Alanları"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
|
|
|
||||||
|
|
@ -39113,7 +39113,7 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency
|
||||||
RoleId = null,
|
RoleId = null,
|
||||||
UserId = null,
|
UserId = null,
|
||||||
CultureName = LanguageCodes.En,
|
CultureName = LanguageCodes.En,
|
||||||
SourceDbType = DbType.Date,
|
SourceDbType = DbType.DateTime,
|
||||||
FieldName = "StartDate",
|
FieldName = "StartDate",
|
||||||
Width = 100,
|
Width = 100,
|
||||||
ListOrderNo = 5,
|
ListOrderNo = 5,
|
||||||
|
|
@ -39147,7 +39147,7 @@ public class ListFormsSeeder : IDataSeedContributor, ITransientDependency
|
||||||
RoleId = null,
|
RoleId = null,
|
||||||
UserId = null,
|
UserId = null,
|
||||||
CultureName = LanguageCodes.En,
|
CultureName = LanguageCodes.En,
|
||||||
SourceDbType = DbType.Date,
|
SourceDbType = DbType.DateTime,
|
||||||
FieldName = "EndDate",
|
FieldName = "EndDate",
|
||||||
Width = 100,
|
Width = 100,
|
||||||
ListOrderNo = 6,
|
ListOrderNo = 6,
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ public static class PlatformConsts
|
||||||
public static string TimeSpanOptions = "{\"type\":\"time\",\"pickerType\":\"list\",\"displayFormat\":\"HH:mm\",\"dateSerializationFormat\":\"yyyy-MM-ddTHH:mm:ss\",\"interval\":30,\"width\":\"100%\"}";
|
public static string TimeSpanOptions = "{\"type\":\"time\",\"pickerType\":\"list\",\"displayFormat\":\"HH:mm\",\"dateSerializationFormat\":\"yyyy-MM-ddTHH:mm:ss\",\"interval\":30,\"width\":\"100%\"}";
|
||||||
public static string NumberStandartFormat = "{ \"format\": \",##0.###\" }";
|
public static string NumberStandartFormat = "{ \"format\": \",##0.###\" }";
|
||||||
public static string NumberPercentFormat = "{ \"format\": \"#0.##'%'\" }";
|
public static string NumberPercentFormat = "{ \"format\": \"#0.##'%'\" }";
|
||||||
|
public static string DateFormat = "{ \"format\": \"dd/MM/yyyy\", \"displayFormat\" : \"dd/MM/yyyy\" }";
|
||||||
|
public static string DateTimeFormat = "{ \"format\": \"dd/MM/yyyy HH:mm\", \"displayFormat\" : \"dd/MM/yyyy HH:mm\" }";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EditorScriptValues
|
public static class EditorScriptValues
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,9 @@ public class PlatformDomainModule : AbpModule
|
||||||
//context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>());
|
//context.Services.Replace(ServiceDescriptor.Singleton<IEmailSender, NullEmailSender>());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Configure<AbpClockOptions>(options =>
|
// Configure<AbpClockOptions>(options =>
|
||||||
{
|
// {
|
||||||
options.Kind = DateTimeKind.Utc;
|
// options.Kind = DateTimeKind.Utc;
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ using Kurs.Platform.Classrooms;
|
||||||
using Kurs.Platform.EntityFrameworkCore;
|
using Kurs.Platform.EntityFrameworkCore;
|
||||||
using Kurs.Platform.Extensions;
|
using Kurs.Platform.Extensions;
|
||||||
using Kurs.Platform.Identity;
|
using Kurs.Platform.Identity;
|
||||||
|
using Kurs.Platform.Localization;
|
||||||
using Kurs.Settings;
|
using Kurs.Settings;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Cors;
|
using Microsoft.AspNetCore.Cors;
|
||||||
|
|
@ -47,6 +48,7 @@ using Volo.Abp.Identity;
|
||||||
using Volo.Abp.Modularity;
|
using Volo.Abp.Modularity;
|
||||||
using Volo.Abp.Security.Claims;
|
using Volo.Abp.Security.Claims;
|
||||||
using Volo.Abp.Swashbuckle;
|
using Volo.Abp.Swashbuckle;
|
||||||
|
using Volo.Abp.Timing;
|
||||||
using Volo.Abp.UI.Navigation.Urls;
|
using Volo.Abp.UI.Navigation.Urls;
|
||||||
using Volo.Abp.VirtualFileSystem;
|
using Volo.Abp.VirtualFileSystem;
|
||||||
using static Kurs.Platform.PlatformConsts;
|
using static Kurs.Platform.PlatformConsts;
|
||||||
|
|
@ -101,6 +103,11 @@ public class PlatformHttpApiHostModule : AbpModule
|
||||||
{
|
{
|
||||||
var configuration = context.Services.GetConfiguration();
|
var configuration = context.Services.GetConfiguration();
|
||||||
|
|
||||||
|
//Tenant bazında lokalizasyon ayarları için
|
||||||
|
//TenantLocalization Middleware kaydı
|
||||||
|
context.Services.AddTransient<TenantLocalizationMiddleware>();
|
||||||
|
context.Services.AddTransient<TenantLocalizationInitializer>();
|
||||||
|
|
||||||
ConfigureAuthentication(context);
|
ConfigureAuthentication(context);
|
||||||
ConfigureBundles();
|
ConfigureBundles();
|
||||||
ConfigureUrls(configuration);
|
ConfigureUrls(configuration);
|
||||||
|
|
@ -391,6 +398,7 @@ public class PlatformHttpApiHostModule : AbpModule
|
||||||
if (PlatformConsts.IsMultiTenant)
|
if (PlatformConsts.IsMultiTenant)
|
||||||
{
|
{
|
||||||
app.UseMultiTenancy();
|
app.UseMultiTenancy();
|
||||||
|
app.UseMiddleware<TenantLocalizationMiddleware>();
|
||||||
}
|
}
|
||||||
|
|
||||||
app.UseUnitOfWork();
|
app.UseUnitOfWork();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Volo.Abp.DependencyInjection;
|
||||||
|
using Volo.Abp.Settings;
|
||||||
|
using Volo.Abp.Timing;
|
||||||
|
using Volo.Abp.MultiTenancy;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
|
namespace Kurs.Platform.Localization
|
||||||
|
{
|
||||||
|
public class TenantLocalizationInitializer : ITransientDependency
|
||||||
|
{
|
||||||
|
private readonly ISettingProvider _settingProvider;
|
||||||
|
private readonly ICurrentTenant _currentTenant;
|
||||||
|
private readonly IOptions<AbpClockOptions> _clockOptions;
|
||||||
|
|
||||||
|
public TenantLocalizationInitializer(
|
||||||
|
ISettingProvider settingProvider,
|
||||||
|
ICurrentTenant currentTenant,
|
||||||
|
IOptions<AbpClockOptions> clockOptions)
|
||||||
|
{
|
||||||
|
_settingProvider = settingProvider;
|
||||||
|
_currentTenant = currentTenant;
|
||||||
|
_clockOptions = clockOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ApplyTenantSettingsAsync()
|
||||||
|
{
|
||||||
|
// Dil ayarı
|
||||||
|
var lang = await _settingProvider.GetOrNullAsync("Abp.Localization.DefaultLanguage") ?? "en";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var culture = new CultureInfo(lang);
|
||||||
|
CultureInfo.DefaultThreadCurrentCulture = culture;
|
||||||
|
CultureInfo.DefaultThreadCurrentUICulture = culture;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
|
||||||
|
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Saat tipi (UTC / Local)
|
||||||
|
var timeZoneId = await _settingProvider.GetOrNullAsync("Abp.Timing.TimeZone") ?? "UTC";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
|
||||||
|
_clockOptions.Value.Kind = tz.Id.Contains("UTC", StringComparison.OrdinalIgnoreCase)
|
||||||
|
? DateTimeKind.Utc
|
||||||
|
: DateTimeKind.Local;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
_clockOptions.Value.Kind = DateTimeKind.Utc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kurs.Platform.Localization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
public class TenantLocalizationMiddleware : IMiddleware
|
||||||
|
{
|
||||||
|
private readonly TenantLocalizationInitializer _initializer;
|
||||||
|
|
||||||
|
public TenantLocalizationMiddleware(TenantLocalizationInitializer initializer)
|
||||||
|
{
|
||||||
|
_initializer = initializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||||||
|
{
|
||||||
|
await _initializer.ApplyTenantSettingsAsync();
|
||||||
|
await next(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -55,7 +55,7 @@ const cellTemplateMultiValue = (
|
||||||
>
|
>
|
||||||
${v}
|
${v}
|
||||||
</div>
|
</div>
|
||||||
`
|
`,
|
||||||
)
|
)
|
||||||
.join('')
|
.join('')
|
||||||
|
|
||||||
|
|
@ -64,7 +64,6 @@ const cellTemplateMultiValue = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function calculateFilterExpressionMultiValue(
|
function calculateFilterExpressionMultiValue(
|
||||||
this: DataGridTypes.Column,
|
this: DataGridTypes.Column,
|
||||||
filterValue: any,
|
filterValue: any,
|
||||||
|
|
@ -392,7 +391,24 @@ const useListFormColumns = ({
|
||||||
|
|
||||||
column.alignment = colData.alignment
|
column.alignment = colData.alignment
|
||||||
column.format = colData.format
|
column.format = colData.format
|
||||||
column.editorOptions = { ...(colData.editorOptions as IFormatProps) }
|
|
||||||
|
let editorOptions: any = {}
|
||||||
|
if (colData.editorOptions) {
|
||||||
|
try {
|
||||||
|
editorOptions =
|
||||||
|
typeof colData.editorOptions === 'string'
|
||||||
|
? JSON.parse(colData.editorOptions)
|
||||||
|
: colData.editorOptions
|
||||||
|
} catch {
|
||||||
|
editorOptions = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
column.editorOptions = { ...editorOptions }
|
||||||
|
|
||||||
|
if (column.editorOptions.displayFormat) {
|
||||||
|
column.format = column.editorOptions.displayFormat
|
||||||
|
}
|
||||||
|
|
||||||
// columnCustomizationDto
|
// columnCustomizationDto
|
||||||
column.fixed = colData.columnCustomizationDto?.fixed
|
column.fixed = colData.columnCustomizationDto?.fixed
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,43 @@
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import dayjs from 'dayjs'
|
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 { useStoreState } from '@/store'
|
||||||
import { dateLocales } from '@/constants/dateLocales.constant'
|
import { dateLocales } from '@/constants/dateLocales.constant'
|
||||||
|
|
||||||
|
dayjs.extend(utc)
|
||||||
|
dayjs.extend(timezone)
|
||||||
|
|
||||||
function useLocale() {
|
function useLocale() {
|
||||||
const cultureName = useStoreState((state) => state.locale.currentLang)
|
const cultureName = useStoreState((state) => state.locale.currentLang)
|
||||||
const languageList = useStoreState((state) => state.abpConfig.config?.localization.languages)
|
const languageList = useStoreState((state) => state.abpConfig.config?.localization.languages)
|
||||||
|
const abpConfig = useStoreState((state) => state.abpConfig.config)
|
||||||
const twoLetterISOLanguageName = languageList?.find(
|
const twoLetterISOLanguageName = languageList?.find(
|
||||||
(lang) => lang.cultureName === cultureName,
|
(lang) => lang.cultureName === cultureName,
|
||||||
)?.twoLetterISOLanguageName
|
)?.twoLetterISOLanguageName
|
||||||
|
|
||||||
|
const timeZone = abpConfig?.timing?.timeZone?.iana?.timeZoneName ?? 'UTC'
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (cultureName && twoLetterISOLanguageName && dateLocales[twoLetterISOLanguageName]) {
|
if (cultureName && twoLetterISOLanguageName && dateLocales[twoLetterISOLanguageName]) {
|
||||||
dateLocales[twoLetterISOLanguageName]().then(() => {
|
dateLocales[twoLetterISOLanguageName]().then(() => {
|
||||||
dayjs.locale(cultureName)
|
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}`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [cultureName, twoLetterISOLanguageName])
|
}, [cultureName, twoLetterISOLanguageName, timeZone])
|
||||||
|
|
||||||
return cultureName
|
return cultureName
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue