Wizard Düzenlemeleri
This commit is contained in:
parent
4b2fceb404
commit
85b498a477
17 changed files with 440 additions and 205 deletions
|
|
@ -4,6 +4,6 @@ namespace Sozsoft.Platform.ListForms;
|
||||||
|
|
||||||
public interface IListFormWizardAppService
|
public interface IListFormWizardAppService
|
||||||
{
|
{
|
||||||
Task Create(WizardCreateInputDto input);
|
Task Create(ListFormWizardDto input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,15 @@ using System.Data;
|
||||||
|
|
||||||
namespace Sozsoft.Platform.ListForms;
|
namespace Sozsoft.Platform.ListForms;
|
||||||
|
|
||||||
public class WizardCreateInputDto
|
public class ListFormWizardDto
|
||||||
{
|
{
|
||||||
|
public string WizardName { get; set; }
|
||||||
public string ListFormCode { get; set; }
|
public string ListFormCode { get; set; }
|
||||||
public string MenuCode { get; set; }
|
public string MenuCode { get; set; }
|
||||||
|
|
||||||
|
public bool IsTenant { get; set; }
|
||||||
|
public bool IsBranch { get; set; }
|
||||||
|
|
||||||
public string LanguageTextMenuEn { get; set; }
|
public string LanguageTextMenuEn { get; set; }
|
||||||
public string LanguageTextMenuTr { get; set; }
|
public string LanguageTextMenuTr { get; set; }
|
||||||
public string LanguageTextTitleEn { get; set; }
|
public string LanguageTextTitleEn { get; set; }
|
||||||
|
|
@ -22,5 +22,8 @@ public class MenuDto : FullAuditedEntityDto<Guid>
|
||||||
public string UserId { get; set; } // External kullanici id (orn: ali.akman. ihtiyaca gore guid veya int de olabilir)
|
public string UserId { get; set; } // External kullanici id (orn: ali.akman. ihtiyaca gore guid veya int de olabilir)
|
||||||
public string RoleId { get; set; } // External role id (orn: ihracat)
|
public string RoleId { get; set; } // External role id (orn: ihracat)
|
||||||
public string CultureName { get; set; } // Bu tanim hangi dil icin "en", "tr"
|
public string CultureName { get; set; } // Bu tanim hangi dil icin "en", "tr"
|
||||||
|
|
||||||
|
public string MenuTextTr { get; set; }
|
||||||
|
public string MenuTextEn { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ using Volo.Abp.PermissionManagement;
|
||||||
using Volo.Abp.Uow;
|
using Volo.Abp.Uow;
|
||||||
using static Sozsoft.Platform.PlatformConsts;
|
using static Sozsoft.Platform.PlatformConsts;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using Sozsoft.Platform.Data.Seeds;
|
|
||||||
|
|
||||||
namespace Sozsoft.Platform.ListForms;
|
namespace Sozsoft.Platform.ListForms;
|
||||||
|
|
||||||
|
|
@ -49,17 +48,19 @@ public class ListFormWizardAppService(
|
||||||
private readonly string cultureNameDefault = PlatformConsts.DefaultLanguage;
|
private readonly string cultureNameDefault = PlatformConsts.DefaultLanguage;
|
||||||
|
|
||||||
[UnitOfWork]
|
[UnitOfWork]
|
||||||
public async Task Create(WizardCreateInputDto input)
|
public async Task Create(ListFormWizardDto input)
|
||||||
{
|
{
|
||||||
var listFormCode = input.ListFormCode;
|
var wizardName = input.WizardName.Trim();
|
||||||
var nameLangKey = PlatformConsts.Wizard.WizardKey(listFormCode);
|
var titleLangKey = PlatformConsts.Wizard.WizardKeyTitle(wizardName);
|
||||||
var titleLangKey = PlatformConsts.Wizard.WizardKeyTitle(listFormCode);
|
var nameLangKey = PlatformConsts.Wizard.WizardKey(wizardName);
|
||||||
var code = PlatformConsts.Wizard.WizardKey(listFormCode);
|
var descLangKey = PlatformConsts.Wizard.WizardKeyDesc(wizardName);
|
||||||
|
|
||||||
|
var code = PlatformConsts.Wizard.WizardKey(wizardName);
|
||||||
|
|
||||||
//Dil - Language Keys
|
//Dil - Language Keys
|
||||||
await CreateLangKey(nameLangKey, input.LanguageTextMenuEn, input.LanguageTextMenuTr);
|
await CreateLangKey(nameLangKey, input.LanguageTextMenuEn, input.LanguageTextMenuTr);
|
||||||
await CreateLangKey(titleLangKey, input.LanguageTextTitleEn, input.LanguageTextTitleTr);
|
await CreateLangKey(titleLangKey, input.LanguageTextTitleEn, input.LanguageTextTitleTr);
|
||||||
await CreateLangKey(PlatformConsts.Wizard.WizardKeyDesc(listFormCode), input.LanguageTextDescEn, input.LanguageTextDescTr);
|
await CreateLangKey(descLangKey, input.LanguageTextDescEn, input.LanguageTextDescTr);
|
||||||
|
|
||||||
//Permission Group
|
//Permission Group
|
||||||
var groupName = input.PermissionGroupName ?? PlatformConsts.AppName;
|
var groupName = input.PermissionGroupName ?? PlatformConsts.AppName;
|
||||||
|
|
@ -78,23 +79,23 @@ public class ListFormWizardAppService(
|
||||||
var permRead = existingPerms.FirstOrDefault(a => a.Name == code) ??
|
var permRead = existingPerms.FirstOrDefault(a => a.Name == code) ??
|
||||||
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, code, null, nameLangKey, true, MultiTenancySides.Both), autoSave: false);
|
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, code, null, nameLangKey, true, MultiTenancySides.Both), autoSave: false);
|
||||||
|
|
||||||
var permCreate = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermCreate(listFormCode)) ??
|
var permCreate = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermCreate(wizardName)) ??
|
||||||
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermCreate(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyCreate, true, MultiTenancySides.Both), autoSave: false);
|
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermCreate(wizardName), permRead.Name, PlatformConsts.Wizard.LangKeyCreate, true, MultiTenancySides.Both), autoSave: false);
|
||||||
|
|
||||||
var permUpdate = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermUpdate(listFormCode)) ??
|
var permUpdate = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermUpdate(wizardName)) ??
|
||||||
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermUpdate(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyUpdate, true, MultiTenancySides.Both), autoSave: false);
|
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermUpdate(wizardName), permRead.Name, PlatformConsts.Wizard.LangKeyUpdate, true, MultiTenancySides.Both), autoSave: false);
|
||||||
|
|
||||||
var permDelete = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermDelete(listFormCode)) ??
|
var permDelete = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermDelete(wizardName)) ??
|
||||||
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermDelete(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyDelete, true, MultiTenancySides.Both), autoSave: false);
|
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermDelete(wizardName), permRead.Name, PlatformConsts.Wizard.LangKeyDelete, true, MultiTenancySides.Both), autoSave: false);
|
||||||
|
|
||||||
var permExport = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermExport(listFormCode)) ??
|
var permExport = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermExport(wizardName)) ??
|
||||||
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermExport(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyExport, true, MultiTenancySides.Both), autoSave: false);
|
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermExport(wizardName), permRead.Name, PlatformConsts.Wizard.LangKeyExport, true, MultiTenancySides.Both), autoSave: false);
|
||||||
|
|
||||||
var permImport = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermImport(listFormCode)) ??
|
var permImport = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermImport(wizardName)) ??
|
||||||
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermImport(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyImport, true, MultiTenancySides.Both), autoSave: false);
|
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermImport(wizardName), permRead.Name, PlatformConsts.Wizard.LangKeyImport, true, MultiTenancySides.Both), autoSave: false);
|
||||||
|
|
||||||
var PermNote = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermNote(listFormCode)) ??
|
var permNote = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermNote(wizardName)) ??
|
||||||
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermNote(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyNote, true, MultiTenancySides.Both), autoSave: false);
|
await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermNote(wizardName), permRead.Name, PlatformConsts.Wizard.LangKeyNote, true, MultiTenancySides.Both), autoSave: false);
|
||||||
|
|
||||||
// Permission Grants - Bulk Insert
|
// Permission Grants - Bulk Insert
|
||||||
var adminUserName = PlatformConsts.AbpIdentity.User.AdminEmailDefaultValue;
|
var adminUserName = PlatformConsts.AbpIdentity.User.AdminEmailDefaultValue;
|
||||||
|
|
@ -108,6 +109,8 @@ public class ListFormWizardAppService(
|
||||||
new PermissionGrant(Guid.NewGuid(), permUpdate.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
new PermissionGrant(Guid.NewGuid(), permUpdate.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
||||||
new PermissionGrant(Guid.NewGuid(), permDelete.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
new PermissionGrant(Guid.NewGuid(), permDelete.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
||||||
new PermissionGrant(Guid.NewGuid(), permExport.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
new PermissionGrant(Guid.NewGuid(), permExport.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
||||||
|
new PermissionGrant(Guid.NewGuid(), permImport.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
||||||
|
new PermissionGrant(Guid.NewGuid(), permNote.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName),
|
||||||
], autoSave: false);
|
], autoSave: false);
|
||||||
|
|
||||||
//Menu Parent
|
//Menu Parent
|
||||||
|
|
@ -115,11 +118,11 @@ public class ListFormWizardAppService(
|
||||||
var menuParent = await AsyncExecuter.FirstOrDefaultAsync(menuQueryable.Where(a => a.Code == input.MenuParentCode));
|
var menuParent = await AsyncExecuter.FirstOrDefaultAsync(menuQueryable.Where(a => a.Code == input.MenuParentCode));
|
||||||
if (menuParent == null)
|
if (menuParent == null)
|
||||||
{
|
{
|
||||||
await CreateLangKey(PlatformConsts.Wizard.WizardKeyParent(listFormCode), input.LanguageTextMenuParentEn, input.LanguageTextMenuParentTr);
|
await CreateLangKey(PlatformConsts.Wizard.WizardKeyParent(wizardName), input.LanguageTextMenuParentEn, input.LanguageTextMenuParentTr);
|
||||||
menuParent = await repoMenu.InsertAsync(new Menu
|
menuParent = await repoMenu.InsertAsync(new Menu
|
||||||
{
|
{
|
||||||
Code = input.MenuParentCode,
|
Code = input.MenuParentCode,
|
||||||
DisplayName = PlatformConsts.Wizard.WizardKeyParent(listFormCode),
|
DisplayName = PlatformConsts.Wizard.WizardKeyParent(wizardName),
|
||||||
IsDisabled = false,
|
IsDisabled = false,
|
||||||
}, autoSave: false);
|
}, autoSave: false);
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +139,7 @@ public class ListFormWizardAppService(
|
||||||
Target = null,
|
Target = null,
|
||||||
ElementId = null,
|
ElementId = null,
|
||||||
CssClass = null,
|
CssClass = null,
|
||||||
Url = PlatformConsts.Wizard.MenuUrl(listFormCode),
|
Url = PlatformConsts.Wizard.MenuUrl(code),
|
||||||
RequiredPermissionName = permRead.Name
|
RequiredPermissionName = permRead.Name
|
||||||
}, autoSave: false);
|
}, autoSave: false);
|
||||||
|
|
||||||
|
|
@ -187,14 +190,14 @@ public class ListFormWizardAppService(
|
||||||
ShowNote = true,
|
ShowNote = true,
|
||||||
LayoutJson = Wizard.DefaultLayoutJson(),
|
LayoutJson = Wizard.DefaultLayoutJson(),
|
||||||
CultureName = LanguageCodes.En,
|
CultureName = LanguageCodes.En,
|
||||||
ListFormCode = listFormCode,
|
ListFormCode = input.ListFormCode,
|
||||||
Name = nameLangKey,
|
Name = nameLangKey,
|
||||||
Title = titleLangKey,
|
Title = titleLangKey,
|
||||||
|
Description = descLangKey,
|
||||||
DataSourceCode = input.DataSourceCode,
|
DataSourceCode = input.DataSourceCode,
|
||||||
IsTenant = false,
|
IsTenant = input.IsTenant,
|
||||||
IsBranch = false,
|
IsBranch = input.IsBranch,
|
||||||
IsOrganizationUnit = false,
|
IsOrganizationUnit = false,
|
||||||
Description = Wizard.WizardKeyDesc(listFormCode),
|
|
||||||
SelectCommandType = input.SelectCommandType,
|
SelectCommandType = input.SelectCommandType,
|
||||||
SelectCommand = input.SelectCommand,
|
SelectCommand = input.SelectCommand,
|
||||||
KeyFieldName = input.KeyFieldName,
|
KeyFieldName = input.KeyFieldName,
|
||||||
|
|
@ -207,11 +210,11 @@ public class ListFormWizardAppService(
|
||||||
GroupPanelJson = JsonSerializer.Serialize(new { Visible = false }),
|
GroupPanelJson = JsonSerializer.Serialize(new { Visible = false }),
|
||||||
SelectionJson = Wizard.DefaultSelectionSingleJson,
|
SelectionJson = Wizard.DefaultSelectionSingleJson,
|
||||||
ColumnOptionJson = Wizard.DefaultColumnOptionJson(),
|
ColumnOptionJson = Wizard.DefaultColumnOptionJson(),
|
||||||
PermissionJson = Wizard.DefaultPermissionJson(listFormCode),
|
PermissionJson = Wizard.DefaultPermissionJson(code),
|
||||||
DeleteCommand = Wizard.DefaultDeleteCommand(nameof(TableNameEnum.Country)),
|
DeleteCommand = Wizard.DefaultDeleteCommand(nameof(TableNameEnum.Country)),
|
||||||
DeleteFieldsDefaultValueJson = Wizard.DefaultDeleteFieldsDefaultValueJson(),
|
DeleteFieldsDefaultValueJson = Wizard.DefaultDeleteFieldsDefaultValueJson(input.KeyFieldDbSourceType),
|
||||||
PagerOptionJson = Wizard.DefaultPagerOptionJson,
|
PagerOptionJson = Wizard.DefaultPagerOptionJson,
|
||||||
EditingOptionJson = Wizard.DefaultEditingOptionJson(listFormCode, 600, 500, true, true, true, true, false),
|
EditingOptionJson = Wizard.DefaultEditingOptionJson(titleLangKey, 600, 500, true, true, true, true, false),
|
||||||
EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null,
|
EditingFormJson = editingFormDtos.Count > 0 ? JsonSerializer.Serialize(editingFormDtos) : null,
|
||||||
}, autoSave: true);
|
}, autoSave: true);
|
||||||
|
|
||||||
|
|
@ -224,7 +227,7 @@ public class ListFormWizardAppService(
|
||||||
fieldOrder++;
|
fieldOrder++;
|
||||||
await repoListFormField.InsertAsync(new ListFormField
|
await repoListFormField.InsertAsync(new ListFormField
|
||||||
{
|
{
|
||||||
ListFormCode = listFormCode,
|
ListFormCode = input.ListFormCode,
|
||||||
FieldName = item.DataField,
|
FieldName = item.DataField,
|
||||||
CaptionName = item.DataField,
|
CaptionName = item.DataField,
|
||||||
Visible = true,
|
Visible = true,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ using Volo.Abp.Domain.Repositories;
|
||||||
using Volo.Abp.PermissionManagement;
|
using Volo.Abp.PermissionManagement;
|
||||||
using Volo.Abp.TenantManagement;
|
using Volo.Abp.TenantManagement;
|
||||||
using static Sozsoft.Platform.Data.Seeds.SeedConsts;
|
using static Sozsoft.Platform.Data.Seeds.SeedConsts;
|
||||||
|
using Sozsoft.Languages;
|
||||||
|
|
||||||
namespace Sozsoft.Platform.Menus;
|
namespace Sozsoft.Platform.Menus;
|
||||||
|
|
||||||
|
|
@ -26,18 +27,21 @@ public class MenuAppService : CrudAppService<
|
||||||
{
|
{
|
||||||
private readonly IRepository<Menu, Guid> _menuRepository;
|
private readonly IRepository<Menu, Guid> _menuRepository;
|
||||||
private readonly IRepository<LanguageKey, Guid> _repositoryKey;
|
private readonly IRepository<LanguageKey, Guid> _repositoryKey;
|
||||||
|
private readonly IRepository<LanguageText, Guid> _repositoryText;
|
||||||
private readonly ITenantRepository _tenantRepository;
|
private readonly ITenantRepository _tenantRepository;
|
||||||
private readonly IPermissionDefinitionRecordRepository _permissionRepository;
|
private readonly IPermissionDefinitionRecordRepository _permissionRepository;
|
||||||
|
|
||||||
public MenuAppService(
|
public MenuAppService(
|
||||||
IRepository<Menu, Guid> menuRepository,
|
IRepository<Menu, Guid> menuRepository,
|
||||||
IRepository<LanguageKey, Guid> languageKeyRepository,
|
IRepository<LanguageKey, Guid> languageKeyRepository,
|
||||||
|
IRepository<LanguageText, Guid> languageTextRepository,
|
||||||
ITenantRepository tenantRepository,
|
ITenantRepository tenantRepository,
|
||||||
IPermissionDefinitionRecordRepository permissionRepository
|
IPermissionDefinitionRecordRepository permissionRepository
|
||||||
) : base(menuRepository)
|
) : base(menuRepository)
|
||||||
{
|
{
|
||||||
_menuRepository = menuRepository;
|
_menuRepository = menuRepository;
|
||||||
_repositoryKey = languageKeyRepository;
|
_repositoryKey = languageKeyRepository;
|
||||||
|
_repositoryText = languageTextRepository;
|
||||||
_tenantRepository = tenantRepository;
|
_tenantRepository = tenantRepository;
|
||||||
_permissionRepository = permissionRepository;
|
_permissionRepository = permissionRepository;
|
||||||
|
|
||||||
|
|
@ -244,4 +248,68 @@ public class MenuAppService : CrudAppService<
|
||||||
|
|
||||||
return entityDtos;
|
return entityDtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<MenuDto> CreateWithLanguageKeyTextAsync(MenuDto input)
|
||||||
|
{
|
||||||
|
await CheckCreatePolicyAsync();
|
||||||
|
|
||||||
|
//Dil Key oluşturuluyor.
|
||||||
|
var keyExists = await _repositoryKey.AnyAsync(
|
||||||
|
a => a.Key == input.Code &&
|
||||||
|
a.ResourceName == PlatformConsts.AppName);
|
||||||
|
if (!keyExists)
|
||||||
|
{
|
||||||
|
await _repositoryKey.InsertAsync(new LanguageKey
|
||||||
|
{
|
||||||
|
Key = input.Code,
|
||||||
|
ResourceName = PlatformConsts.AppName
|
||||||
|
}, autoSave: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// English text oluşturuluyor veya güncelleniyor.
|
||||||
|
var existingEnText = await _repositoryText.FirstOrDefaultAsync(
|
||||||
|
a => a.CultureName == "en" &&
|
||||||
|
a.Key == input.Code &&
|
||||||
|
a.ResourceName == PlatformConsts.AppName);
|
||||||
|
|
||||||
|
if (existingEnText != null)
|
||||||
|
{
|
||||||
|
existingEnText.Value = input.MenuTextEn;
|
||||||
|
await _repositoryText.UpdateAsync(existingEnText);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _repositoryText.InsertAsync(new LanguageText
|
||||||
|
{
|
||||||
|
Key = input.Code,
|
||||||
|
CultureName = "en",
|
||||||
|
Value = input.MenuTextEn,
|
||||||
|
ResourceName = PlatformConsts.AppName
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Türkçe text oluşturuluyor veya güncelleniyor.
|
||||||
|
var existingTrText = await _repositoryText.FirstOrDefaultAsync(
|
||||||
|
a => a.CultureName == "tr" &&
|
||||||
|
a.Key == input.Code &&
|
||||||
|
a.ResourceName == PlatformConsts.AppName);
|
||||||
|
|
||||||
|
if (existingTrText != null)
|
||||||
|
{
|
||||||
|
existingTrText.Value = input.MenuTextTr;
|
||||||
|
await _repositoryText.UpdateAsync(existingTrText);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await _repositoryText.InsertAsync(new LanguageText
|
||||||
|
{
|
||||||
|
Key = input.Code,
|
||||||
|
CultureName = "tr",
|
||||||
|
Value = input.MenuTextTr,
|
||||||
|
ResourceName = PlatformConsts.AppName
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return await base.CreateAsync(input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -450,7 +450,7 @@
|
||||||
"code": "Abp.Mailing.DefaultFromDisplayName",
|
"code": "Abp.Mailing.DefaultFromDisplayName",
|
||||||
"nameKey": "Abp.Mailing.DefaultFromDisplayName",
|
"nameKey": "Abp.Mailing.DefaultFromDisplayName",
|
||||||
"descriptionKey": "Abp.Mailing.DefaultFromDisplayName.Description",
|
"descriptionKey": "Abp.Mailing.DefaultFromDisplayName.Description",
|
||||||
"defaultValue": "Sozsoft",
|
"defaultValue": "Sözsoft",
|
||||||
"isVisibleToClients": false,
|
"isVisibleToClients": false,
|
||||||
"providers": "T|G|D",
|
"providers": "T|G|D",
|
||||||
"isInherited": false,
|
"isInherited": false,
|
||||||
|
|
|
||||||
|
|
@ -407,7 +407,7 @@ public static class PlatformConsts
|
||||||
|
|
||||||
public static class Wizard
|
public static class Wizard
|
||||||
{
|
{
|
||||||
public static string WizardKey(string code) => $"{Prefix.App}.{AppName}.{code}";
|
public static string WizardKey(string code) => $"{Prefix.App}.Wizard.{code}";
|
||||||
public static string WizardKeyTitle(string code) => $"{WizardKey(code)}.Title";
|
public static string WizardKeyTitle(string code) => $"{WizardKey(code)}.Title";
|
||||||
public static string WizardKeyDesc(string code) => $"{WizardKey(code)}.Desc";
|
public static string WizardKeyDesc(string code) => $"{WizardKey(code)}.Desc";
|
||||||
public static string WizardKeyParent(string code) => $"{WizardKey(code)}.Parent";
|
public static string WizardKeyParent(string code) => $"{WizardKey(code)}.Parent";
|
||||||
|
|
@ -418,12 +418,12 @@ public static class PlatformConsts
|
||||||
public static string PermExport(string code) => $"{WizardKey(code)}.Export";
|
public static string PermExport(string code) => $"{WizardKey(code)}.Export";
|
||||||
public static string PermImport(string code) => $"{WizardKey(code)}.Import";
|
public static string PermImport(string code) => $"{WizardKey(code)}.Import";
|
||||||
public static string PermNote(string code) => $"{WizardKey(code)}.Note";
|
public static string PermNote(string code) => $"{WizardKey(code)}.Note";
|
||||||
public static string LangKeyCreate => $"{Prefix.App}.Create";
|
public static string LangKeyCreate => "Create";
|
||||||
public static string LangKeyUpdate => $"{Prefix.App}.Update";
|
public static string LangKeyUpdate => "Update";
|
||||||
public static string LangKeyDelete => $"{Prefix.App}.Delete";
|
public static string LangKeyDelete => "Delete";
|
||||||
public static string LangKeyExport => $"{Prefix.App}.Export";
|
public static string LangKeyExport => "Export";
|
||||||
public static string LangKeyImport => $"{Prefix.App}.Import";
|
public static string LangKeyImport => "Import";
|
||||||
public static string LangKeyNote => $"{Prefix.App}.Note";
|
public static string LangKeyNote => "Note";
|
||||||
|
|
||||||
public static string MenuUrl(string code) => $"/admin/list/{code}";
|
public static string MenuUrl(string code) => $"/admin/list/{code}";
|
||||||
public static string MenuIcon => "FcList";
|
public static string MenuIcon => "FcList";
|
||||||
|
|
@ -494,8 +494,8 @@ public static class PlatformConsts
|
||||||
{
|
{
|
||||||
return JsonSerializer.Serialize(new[]
|
return JsonSerializer.Serialize(new[]
|
||||||
{
|
{
|
||||||
new { FieldName = "DeleterId", FieldDbType = DbType.Guid.ToString(), Value = "@USERID", CustomValueType = FieldCustomValueTypeEnum.CustomKey },
|
new { FieldName = "DeleterId", FieldDbType = DbType.Guid, Value = "@USERID", CustomValueType = FieldCustomValueTypeEnum.CustomKey },
|
||||||
new { FieldName = "Id", FieldDbType = dbType.ToString(), Value = "@ID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
|
new { FieldName = "Id", FieldDbType = dbType, Value = "@ID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -401,7 +401,7 @@ const PublicLayout = () => {
|
||||||
<div className="border-t border-gray-800 mt-12 pt-8">
|
<div className="border-t border-gray-800 mt-12 pt-8">
|
||||||
<div className="flex flex-col md:flex-row justify-between items-center">
|
<div className="flex flex-col md:flex-row justify-between items-center">
|
||||||
<p className="text-gray-400 text-sm">
|
<p className="text-gray-400 text-sm">
|
||||||
© {currentYear} Sozsoft Platform. {translate('::Public.footer.copyright')}
|
© {currentYear} Sözsoft Platform. {translate('::Public.footer.copyright')}
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-4 md:mt-0">
|
<div className="mt-4 md:mt-0">
|
||||||
<ul className="flex space-x-6 text-sm">
|
<ul className="flex space-x-6 text-sm">
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,11 @@ export interface ListFormWizardColumnGroupDto {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ListFormWizardDto {
|
export interface ListFormWizardDto {
|
||||||
|
wizardName: string
|
||||||
listFormCode: string
|
listFormCode: string
|
||||||
menuCode: string
|
menuCode: string
|
||||||
|
isTenant: boolean
|
||||||
|
isBranch: boolean
|
||||||
languageTextMenuEn: string
|
languageTextMenuEn: string
|
||||||
languageTextMenuTr: string
|
languageTextMenuTr: string
|
||||||
languageTextTitleEn: string
|
languageTextTitleEn: string
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,6 @@ export interface MenuDto extends FullAuditedEntityDto<string> {
|
||||||
cultureName?: string
|
cultureName?: string
|
||||||
group?: string
|
group?: string
|
||||||
shortName?: string
|
shortName?: string
|
||||||
|
menuTextTr?: string
|
||||||
|
menuTextEn?: string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,16 @@ export class MenuService {
|
||||||
{ apiName: this.apiName },
|
{ apiName: this.apiName },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
createWithLanguageKeyText = (input: MenuDto) =>
|
||||||
|
apiService.fetchData<MenuDto, MenuDto>(
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
url: '/api/app/menu/with-language-key-text',
|
||||||
|
data: input,
|
||||||
|
},
|
||||||
|
{ apiName: this.apiName },
|
||||||
|
)
|
||||||
|
|
||||||
delete = (id: string) =>
|
delete = (id: string) =>
|
||||||
apiService.fetchData<void>(
|
apiService.fetchData<void>(
|
||||||
{
|
{
|
||||||
|
|
@ -51,7 +61,7 @@ export class MenuService {
|
||||||
params: {
|
params: {
|
||||||
sorting: input.sorting,
|
sorting: input.sorting,
|
||||||
skipCount: input.skipCount,
|
skipCount: input.skipCount,
|
||||||
maxResultCount: input.maxResultCount
|
maxResultCount: input.maxResultCount,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ apiName: this.apiName },
|
{ apiName: this.apiName },
|
||||||
|
|
@ -80,11 +90,9 @@ export class MenuService {
|
||||||
export const getMenus = async (skipCount = 0, maxResultCount = 1000, sorting = 'order') => {
|
export const getMenus = async (skipCount = 0, maxResultCount = 1000, sorting = 'order') => {
|
||||||
const menuService = new MenuService()
|
const menuService = new MenuService()
|
||||||
|
|
||||||
return await menuService.getList(
|
return await menuService.getList({
|
||||||
{
|
|
||||||
sorting,
|
sorting,
|
||||||
skipCount,
|
skipCount,
|
||||||
maxResultCount,
|
maxResultCount,
|
||||||
}
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,15 @@ import WizardStep3, { WizardGroup } from './WizardStep3'
|
||||||
import WizardStep4 from './WizardStep4'
|
import WizardStep4 from './WizardStep4'
|
||||||
import { Container } from '@/components/shared'
|
import { Container } from '@/components/shared'
|
||||||
import { sqlDataTypeToDbType } from './edit/options'
|
import { sqlDataTypeToDbType } from './edit/options'
|
||||||
|
import { useStoreActions } from '@/store/store'
|
||||||
|
|
||||||
// ─── Formik initial values & validation ──────────────────────────────────────
|
// ─── Formik initial values & validation ──────────────────────────────────────
|
||||||
const initialValues: ListFormWizardDto = {
|
const initialValues: ListFormWizardDto = {
|
||||||
|
wizardName: '',
|
||||||
listFormCode: '',
|
listFormCode: '',
|
||||||
menuCode: '',
|
menuCode: '',
|
||||||
|
isTenant: false,
|
||||||
|
isBranch: false,
|
||||||
languageTextMenuEn: '',
|
languageTextMenuEn: '',
|
||||||
languageTextMenuTr: '',
|
languageTextMenuTr: '',
|
||||||
languageTextTitleEn: '',
|
languageTextTitleEn: '',
|
||||||
|
|
@ -53,6 +57,7 @@ const initialValues: ListFormWizardDto = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const step1ValidationSchema = Yup.object().shape({
|
const step1ValidationSchema = Yup.object().shape({
|
||||||
|
wizardName: Yup.string().required(),
|
||||||
menuCode: Yup.string().required(),
|
menuCode: Yup.string().required(),
|
||||||
permissionGroupName: Yup.string().required(),
|
permissionGroupName: Yup.string().required(),
|
||||||
menuParentCode: Yup.string().required(),
|
menuParentCode: Yup.string().required(),
|
||||||
|
|
@ -62,16 +67,18 @@ const step1ValidationSchema = Yup.object().shape({
|
||||||
|
|
||||||
const step2ValidationSchema = Yup.object().shape({
|
const step2ValidationSchema = Yup.object().shape({
|
||||||
listFormCode: Yup.string().required(),
|
listFormCode: Yup.string().required(),
|
||||||
languageTextTitleEn: Yup.string(),
|
languageTextTitleEn: Yup.string().required(),
|
||||||
languageTextTitleTr: Yup.string(),
|
languageTextTitleTr: Yup.string().required(),
|
||||||
languageTextDescEn: Yup.string(),
|
languageTextDescEn: Yup.string().required(),
|
||||||
languageTextDescTr: Yup.string(),
|
languageTextDescTr: Yup.string().required(),
|
||||||
dataSourceCode: Yup.string().required(),
|
dataSourceCode: Yup.string().required(),
|
||||||
dataSourceConnectionString: Yup.string(),
|
dataSourceConnectionString: Yup.string(),
|
||||||
selectCommandType: Yup.string().required(),
|
selectCommandType: Yup.string().required(),
|
||||||
selectCommand: Yup.string().required(),
|
selectCommand: Yup.string().required(),
|
||||||
keyFieldName: Yup.string().required(),
|
keyFieldName: Yup.string().required(),
|
||||||
keyFieldDbSourceType: Yup.string().required(),
|
keyFieldDbSourceType: Yup.number().required(),
|
||||||
|
isTenant: Yup.boolean(),
|
||||||
|
isBranch: Yup.boolean(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const listFormValidationSchema = step1ValidationSchema.concat(step2ValidationSchema)
|
const listFormValidationSchema = step1ValidationSchema.concat(step2ValidationSchema)
|
||||||
|
|
@ -80,7 +87,6 @@ const listFormValidationSchema = step1ValidationSchema.concat(step2ValidationSch
|
||||||
|
|
||||||
const Wizard = () => {
|
const Wizard = () => {
|
||||||
const [currentStep, setCurrentStep] = useState(0)
|
const [currentStep, setCurrentStep] = useState(0)
|
||||||
const [wizardName, setWizardName] = useState('')
|
|
||||||
|
|
||||||
// ── Data Source ──
|
// ── Data Source ──
|
||||||
const [isLoadingDataSource, setIsLoadingDataSource] = useState(false)
|
const [isLoadingDataSource, setIsLoadingDataSource] = useState(false)
|
||||||
|
|
@ -214,12 +220,12 @@ const Wizard = () => {
|
||||||
|
|
||||||
// Auto-derive listFormCode from wizardName
|
// Auto-derive listFormCode from wizardName
|
||||||
const deriveListFormCode = (name: string) => {
|
const deriveListFormCode = (name: string) => {
|
||||||
const sanitized = name.replace(/[^a-zA-Z0-9]/g, '')
|
const sanitized = name.replace(/\s/g, '')
|
||||||
return sanitized ? `App.${sanitized}` : ''
|
return sanitized ? `App.Wizard.${sanitized}` : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleWizardNameChange = (name: string) => {
|
const handleWizardNameChange = (name: string) => {
|
||||||
setWizardName(name)
|
formikRef.current?.setFieldValue('wizardName', name)
|
||||||
const derived = deriveListFormCode(name)
|
const derived = deriveListFormCode(name)
|
||||||
formikRef.current?.setFieldValue('listFormCode', derived)
|
formikRef.current?.setFieldValue('listFormCode', derived)
|
||||||
formikRef.current?.setFieldValue('menuCode', derived)
|
formikRef.current?.setFieldValue('menuCode', derived)
|
||||||
|
|
@ -274,11 +280,12 @@ const Wizard = () => {
|
||||||
await formikRef.current.setTouched({ ...formikRef.current.touched, ...touchedStep1 })
|
await formikRef.current.setTouched({ ...formikRef.current.touched, ...touchedStep1 })
|
||||||
|
|
||||||
// Also require wizardName
|
// Also require wizardName
|
||||||
if (!wizardName.trim() || hasStep1Errors) return
|
if (hasStep1Errors) return
|
||||||
setCurrentStep(1)
|
setCurrentStep(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBack = () => setCurrentStep(0)
|
const handleBack = () => setCurrentStep(0)
|
||||||
|
const { getConfig } = useStoreActions((a) => a.abpConfig)
|
||||||
|
|
||||||
const handleNext2 = async () => {
|
const handleNext2 = async () => {
|
||||||
if (!formikRef.current) return
|
if (!formikRef.current) return
|
||||||
|
|
@ -322,13 +329,10 @@ const Wizard = () => {
|
||||||
</Notification>,
|
</Notification>,
|
||||||
{ placement: 'top-end' },
|
{ placement: 'top-end' },
|
||||||
)
|
)
|
||||||
|
getConfig(true)
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate(
|
navigate(ROUTES_ENUM.protected.admin.list.replace(':listFormCode', values.listFormCode))
|
||||||
ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(
|
|
||||||
':listFormCode',
|
|
||||||
values.listFormCode,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}, 1500)
|
}, 1500)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -368,14 +372,13 @@ const Wizard = () => {
|
||||||
{ placement: 'top-end' },
|
{ placement: 'top-end' },
|
||||||
)
|
)
|
||||||
setSubmitting(false)
|
setSubmitting(false)
|
||||||
|
getConfig(true)
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate(
|
navigate(
|
||||||
ROUTES_ENUM.protected.saas.listFormManagement.edit.replace(
|
ROUTES_ENUM.protected.admin.list.replace(':listFormCode', values.listFormCode),
|
||||||
':listFormCode',
|
|
||||||
values.listFormCode,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}, 500)
|
}, 1500)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
toast.push(<Notification title={error.message} type="danger" />, {
|
toast.push(<Notification title={error.message} type="danger" />, {
|
||||||
placement: 'top-end',
|
placement: 'top-end',
|
||||||
|
|
@ -385,14 +388,16 @@ const Wizard = () => {
|
||||||
>
|
>
|
||||||
{({ touched, errors, isSubmitting, values }) => (
|
{({ touched, errors, isSubmitting, values }) => (
|
||||||
<Form>
|
<Form>
|
||||||
<FormContainer size={currentStep === 2 ? undefined : currentStep === 3 ? undefined : 'sm'}>
|
<FormContainer
|
||||||
|
size={currentStep === 2 ? undefined : currentStep === 3 ? undefined : 'sm'}
|
||||||
|
>
|
||||||
{/* ─── Step 1: Basic Info ─────────────────────────────── */}
|
{/* ─── Step 1: Basic Info ─────────────────────────────── */}
|
||||||
{currentStep === 0 && (
|
{currentStep === 0 && (
|
||||||
<WizardStep1
|
<WizardStep1
|
||||||
values={values}
|
values={values}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
touched={touched}
|
touched={touched}
|
||||||
wizardName={wizardName}
|
wizardName={values.wizardName}
|
||||||
onWizardNameChange={handleWizardNameChange}
|
onWizardNameChange={handleWizardNameChange}
|
||||||
rawMenuItems={rawMenuItems}
|
rawMenuItems={rawMenuItems}
|
||||||
menuTree={menuTree}
|
menuTree={menuTree}
|
||||||
|
|
@ -453,7 +458,7 @@ const Wizard = () => {
|
||||||
{currentStep === 3 && (
|
{currentStep === 3 && (
|
||||||
<WizardStep4
|
<WizardStep4
|
||||||
values={values}
|
values={values}
|
||||||
wizardName={wizardName}
|
wizardName={values.wizardName}
|
||||||
selectedColumns={selectedColumns}
|
selectedColumns={selectedColumns}
|
||||||
selectCommandColumns={selectCommandColumns}
|
selectCommandColumns={selectCommandColumns}
|
||||||
groups={editingGroups}
|
groups={editingGroups}
|
||||||
|
|
|
||||||
|
|
@ -348,7 +348,7 @@ function MenuTreeInline({
|
||||||
<div
|
<div
|
||||||
className={`rounded-lg border ${invalid ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'} bg-white dark:bg-gray-800 overflow-hidden`}
|
className={`rounded-lg border ${invalid ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'} bg-white dark:bg-gray-800 overflow-hidden`}
|
||||||
>
|
>
|
||||||
<div className="h-72 overflow-y-auto py-1">
|
<div className="h-96 overflow-y-auto py-1">
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="px-4 py-3 text-sm text-gray-400">Loading…</div>
|
<div className="px-4 py-3 text-sm text-gray-400">Loading…</div>
|
||||||
) : enrichedNodes.length === 0 ? (
|
) : enrichedNodes.length === 0 ? (
|
||||||
|
|
@ -498,8 +498,10 @@ function MenuAddDialog({
|
||||||
onSaved,
|
onSaved,
|
||||||
}: MenuAddDialogProps) {
|
}: MenuAddDialogProps) {
|
||||||
const [form, setForm] = useState({
|
const [form, setForm] = useState({
|
||||||
|
name: '',
|
||||||
code: '',
|
code: '',
|
||||||
displayName: '',
|
menuTextEn: '',
|
||||||
|
menuTextTr: '',
|
||||||
parentCode: initialParentCode,
|
parentCode: initialParentCode,
|
||||||
icon: '',
|
icon: '',
|
||||||
shortName: '',
|
shortName: '',
|
||||||
|
|
@ -510,8 +512,10 @@ function MenuAddDialog({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen)
|
if (isOpen)
|
||||||
setForm({
|
setForm({
|
||||||
|
name: '',
|
||||||
code: '',
|
code: '',
|
||||||
displayName: '',
|
menuTextEn: '',
|
||||||
|
menuTextTr: '',
|
||||||
parentCode: initialParentCode,
|
parentCode: initialParentCode,
|
||||||
icon: '',
|
icon: '',
|
||||||
shortName: '',
|
shortName: '',
|
||||||
|
|
@ -520,18 +524,22 @@ function MenuAddDialog({
|
||||||
}, [isOpen, initialParentCode, initialOrder])
|
}, [isOpen, initialParentCode, initialOrder])
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
if (!form.code.trim() || !form.displayName.trim()) return
|
if (!form.code.trim() || !form.menuTextEn.trim()) return
|
||||||
setSaving(true)
|
setSaving(true)
|
||||||
try {
|
try {
|
||||||
await menuService.create({
|
// Menü oluşturuluyor
|
||||||
|
await menuService.createWithLanguageKeyText({
|
||||||
code: form.code.trim(),
|
code: form.code.trim(),
|
||||||
displayName: form.displayName.trim(),
|
displayName: form.code.trim(),
|
||||||
parentCode: form.parentCode.trim() || undefined,
|
parentCode: form.parentCode.trim() || undefined,
|
||||||
icon: form.icon || undefined,
|
icon: form.icon || undefined,
|
||||||
shortName: form.shortName.trim() || undefined,
|
shortName: form.shortName.trim() || undefined,
|
||||||
order: form.order,
|
order: form.order,
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
|
menuTextTr: form.menuTextTr.trim(),
|
||||||
|
menuTextEn: form.menuTextEn.trim(),
|
||||||
} as MenuDto)
|
} as MenuDto)
|
||||||
|
|
||||||
onSaved()
|
onSaved()
|
||||||
onClose()
|
onClose()
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
|
|
@ -544,74 +552,125 @@ function MenuAddDialog({
|
||||||
// suppress unused warning — rawItems kept for future use
|
// suppress unused warning — rawItems kept for future use
|
||||||
void rawItems
|
void rawItems
|
||||||
|
|
||||||
|
const fieldCls =
|
||||||
|
'h-11 px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 outline-none focus:border-indigo-400 w-full'
|
||||||
|
const disabledCls =
|
||||||
|
'h-11 px-3 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 text-sm text-gray-400 dark:text-gray-500 cursor-not-allowed w-full'
|
||||||
|
const labelCls = 'text-xs font-medium text-gray-500 dark:text-gray-400 mb-1'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog isOpen={isOpen} onClose={onClose} onRequestClose={onClose} width={520}>
|
<Dialog isOpen={isOpen} onClose={onClose} onRequestClose={onClose} width={680}>
|
||||||
<div className="flex flex-col gap-4 p-4">
|
<div className="flex flex-col gap-5 p-5">
|
||||||
|
{/* Header */}
|
||||||
|
<div className="flex items-center gap-2 pb-1 border-b border-gray-100 dark:border-gray-700">
|
||||||
|
<FaPlus className="text-green-500 text-sm" />
|
||||||
<h5 className="text-base font-semibold text-gray-800 dark:text-gray-100">Yeni Menü Ekle</h5>
|
<h5 className="text-base font-semibold text-gray-800 dark:text-gray-100">Yeni Menü Ekle</h5>
|
||||||
<div className="flex flex-col gap-3">
|
</div>
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<label className="text-sm font-medium text-gray-600 dark:text-gray-300">
|
{/* Row 1 — Name | Code */}
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<label className={labelCls}>
|
||||||
|
Name <span className="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
autoFocus
|
||||||
|
value={form.name}
|
||||||
|
onChange={(e) =>
|
||||||
|
setForm((p) => ({
|
||||||
|
...p,
|
||||||
|
name: e.target.value.replace(/\s+/g, ''),
|
||||||
|
code: `App.Wizard.${e.target.value.replace(/\s+/g, '')}`,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
placeholder="MyMenu"
|
||||||
|
className={fieldCls}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<label className={labelCls}>
|
||||||
Code <span className="text-red-500">*</span>
|
Code <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
value={form.code}
|
value={form.code}
|
||||||
onChange={(e) => setForm((p) => ({ ...p, code: e.target.value }))}
|
disabled
|
||||||
placeholder="App.MyMenu"
|
placeholder="App.Wizard.MyMenu"
|
||||||
className="h-11 px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 outline-none focus:border-indigo-400"
|
className={disabledCls}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-1">
|
</div>
|
||||||
<label className="text-sm font-medium text-gray-600 dark:text-gray-300">
|
|
||||||
Display Name <span className="text-red-500">*</span>
|
{/* Row 3 — Icon (full width) */}
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<label className={labelCls}>
|
||||||
|
Icon <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
|
||||||
value={form.displayName}
|
|
||||||
onChange={(e) => setForm((p) => ({ ...p, displayName: e.target.value }))}
|
|
||||||
placeholder="My Menu"
|
|
||||||
className="h-11 px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 outline-none focus:border-indigo-400"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<label className="text-sm font-medium text-gray-600 dark:text-gray-300">Icon</label>
|
|
||||||
<IconPickerField
|
<IconPickerField
|
||||||
value={form.icon}
|
value={form.icon}
|
||||||
onChange={(key) => setForm((p) => ({ ...p, icon: key }))}
|
onChange={(key) => setForm((p) => ({ ...p, icon: key }))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
<label className="text-sm font-medium text-gray-600 dark:text-gray-300">
|
{/* Row 2 — Display Name EN | Display Name TR */}
|
||||||
Menu Parent
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<label className={labelCls}>
|
||||||
|
Display Name (English) <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
|
<input
|
||||||
|
value={form.menuTextEn}
|
||||||
|
onChange={(e) => setForm((p) => ({ ...p, menuTextEn: e.target.value }))}
|
||||||
|
placeholder="My Menu"
|
||||||
|
className={fieldCls}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<label className={labelCls}>
|
||||||
|
Display Name (Turkish) <span className="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
value={form.menuTextTr}
|
||||||
|
onChange={(e) => setForm((p) => ({ ...p, menuTextTr: e.target.value }))}
|
||||||
|
placeholder="Menüm"
|
||||||
|
className={fieldCls}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Row 4 — Menu Parent | Order */}
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<label className={labelCls}>Menu Parent</label>
|
||||||
<input
|
<input
|
||||||
disabled
|
disabled
|
||||||
value={form.parentCode || '(Ana Menü)'}
|
value={form.parentCode || '(Ana Menü)'}
|
||||||
className="h-11 px-3 py-2 rounded-lg border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-700 text-sm text-gray-400 dark:text-gray-500 cursor-not-allowed"
|
className={disabledCls}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col">
|
||||||
<label className="text-sm font-medium text-gray-600 dark:text-gray-300">
|
<label className={labelCls}>Sıra (Order)</label>
|
||||||
Sıra (Order)
|
|
||||||
</label>
|
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
value={form.order}
|
value={form.order}
|
||||||
onChange={(e) => setForm((p) => ({ ...p, order: Number(e.target.value) }))}
|
onChange={(e) => setForm((p) => ({ ...p, order: Number(e.target.value) }))}
|
||||||
className="h-11 px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 outline-none focus:border-indigo-400"
|
className={fieldCls}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-1">
|
</div>
|
||||||
<label className="text-sm font-medium text-gray-600 dark:text-gray-300">
|
|
||||||
Short Name
|
{/* Row 5 — Short Name (full width) */}
|
||||||
</label>
|
<div className="flex flex-col">
|
||||||
|
<label className={labelCls}>Short Name</label>
|
||||||
<input
|
<input
|
||||||
value={form.shortName}
|
value={form.shortName}
|
||||||
onChange={(e) => setForm((p) => ({ ...p, shortName: e.target.value }))}
|
onChange={(e) => setForm((p) => ({ ...p, shortName: e.target.value }))}
|
||||||
placeholder="My Menu (short)"
|
placeholder="My Menu (short)"
|
||||||
className="h-11 px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm text-gray-700 dark:text-gray-200 outline-none focus:border-indigo-400"
|
className={fieldCls}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div className="flex justify-end gap-2 pt-2">
|
{/* Footer */}
|
||||||
|
<div className="flex justify-end gap-2 pt-1 border-t border-gray-100 dark:border-gray-700">
|
||||||
<Button size="sm" variant="plain" onClick={onClose}>
|
<Button size="sm" variant="plain" onClick={onClose}>
|
||||||
İptal
|
İptal
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -619,7 +678,12 @@ function MenuAddDialog({
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
loading={saving}
|
loading={saving}
|
||||||
disabled={!form.code.trim() || !form.displayName.trim()}
|
disabled={
|
||||||
|
!form.code.trim() ||
|
||||||
|
!form.menuTextEn.trim() ||
|
||||||
|
!form.menuTextTr.trim() ||
|
||||||
|
!form.icon.trim()
|
||||||
|
}
|
||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
>
|
>
|
||||||
Kaydet
|
Kaydet
|
||||||
|
|
@ -698,7 +762,7 @@ const WizardStep1 = ({
|
||||||
placeholder="e.g. Routes, Products, Orders"
|
placeholder="e.g. Routes, Products, Orders"
|
||||||
value={wizardName}
|
value={wizardName}
|
||||||
autoFocus
|
autoFocus
|
||||||
onChange={(e) => onWizardNameChange(e.target.value)}
|
onChange={(e) => onWizardNameChange(e.target.value.replace(/\s/g, ''))}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
|
@ -785,14 +849,33 @@ const WizardStep1 = ({
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
name="menuCode"
|
name="menuCode"
|
||||||
placeholder="e.g. App.Routes, App.Products, App.Orders"
|
placeholder="e.g. App.Wizard.Routes, App.Wizard.Products, App.Wizard.Orders"
|
||||||
component={Input}
|
component={Input}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
{/* Menu Icon */}
|
||||||
|
<FormItem
|
||||||
|
label="Menu Icon"
|
||||||
|
asterisk={true}
|
||||||
|
invalid={!!(errors.menuIcon && touched.menuIcon)}
|
||||||
|
errorMessage={errors.menuIcon}
|
||||||
|
>
|
||||||
|
<Field name="menuIcon">
|
||||||
|
{({ field, form }: FieldProps<string>) => (
|
||||||
|
<IconPickerField
|
||||||
|
value={field.value}
|
||||||
|
onChange={(key) => form.setFieldValue(field.name, key)}
|
||||||
|
invalid={!!(errors.menuIcon && touched.menuIcon)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Field>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
{/* Menu Text (En) */}
|
{/* Menu Text (En) */}
|
||||||
<FormItem
|
<FormItem
|
||||||
label="Menu Text (En)"
|
label="Display Name (English)"
|
||||||
asterisk={true}
|
asterisk={true}
|
||||||
invalid={!!(errors.languageTextMenuEn && touched.languageTextMenuEn)}
|
invalid={!!(errors.languageTextMenuEn && touched.languageTextMenuEn)}
|
||||||
errorMessage={errors.languageTextMenuEn}
|
errorMessage={errors.languageTextMenuEn}
|
||||||
|
|
@ -808,7 +891,7 @@ const WizardStep1 = ({
|
||||||
|
|
||||||
{/* Menu Text (Tr) */}
|
{/* Menu Text (Tr) */}
|
||||||
<FormItem
|
<FormItem
|
||||||
label="Menu Text (Tr)"
|
label="Display Name (Turkish)"
|
||||||
asterisk={true}
|
asterisk={true}
|
||||||
invalid={!!(errors.languageTextMenuTr && touched.languageTextMenuTr)}
|
invalid={!!(errors.languageTextMenuTr && touched.languageTextMenuTr)}
|
||||||
errorMessage={errors.languageTextMenuTr}
|
errorMessage={errors.languageTextMenuTr}
|
||||||
|
|
@ -867,7 +950,13 @@ const WizardStep1 = ({
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Button variant="solid" type="button" icon={<FaArrowRight />} disabled={!step1CanGo} onClick={onNext}>
|
<Button
|
||||||
|
variant="solid"
|
||||||
|
type="button"
|
||||||
|
icon={<FaArrowRight />}
|
||||||
|
disabled={!step1CanGo}
|
||||||
|
onClick={onNext}
|
||||||
|
>
|
||||||
{translate('::Next') || 'Next'}
|
{translate('::Next') || 'Next'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Button, FormItem, Input, Select } from '@/components/ui'
|
import { Button, Checkbox, FormItem, Input, Select } from '@/components/ui'
|
||||||
import { ListFormWizardDto } from '@/proxy/admin/list-form/models'
|
import { ListFormWizardDto } from '@/proxy/admin/list-form/models'
|
||||||
import { SelectCommandTypeEnum } from '@/proxy/form/models'
|
import { SelectCommandTypeEnum } from '@/proxy/form/models'
|
||||||
import type { DatabaseColumnDto, SqlObjectExplorerDto } from '@/proxy/sql-query-manager/models'
|
import type { DatabaseColumnDto, SqlObjectExplorerDto } from '@/proxy/sql-query-manager/models'
|
||||||
|
|
@ -66,6 +66,10 @@ const WizardStep2 = ({
|
||||||
!values.dataSourceCode && 'Veri Kaynağı',
|
!values.dataSourceCode && 'Veri Kaynağı',
|
||||||
!values.selectCommand && 'Select Command',
|
!values.selectCommand && 'Select Command',
|
||||||
!values.keyFieldName && 'Key Field',
|
!values.keyFieldName && 'Key Field',
|
||||||
|
!values.languageTextDescEn && 'Description Text (En)',
|
||||||
|
!values.languageTextDescTr && 'Description Text (Tr)',
|
||||||
|
!values.languageTextTitleEn && 'Title Text (En)',
|
||||||
|
!values.languageTextTitleTr && 'Title Text (Tr)',
|
||||||
selectedColumns.size === 0 && 'Sütun seçimi',
|
selectedColumns.size === 0 && 'Sütun seçimi',
|
||||||
].filter(Boolean) as string[]
|
].filter(Boolean) as string[]
|
||||||
const step2CanGo = step2Missing.length === 0
|
const step2CanGo = step2Missing.length === 0
|
||||||
|
|
@ -89,8 +93,9 @@ const WizardStep2 = ({
|
||||||
type="text"
|
type="text"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
name="listFormCode"
|
name="listFormCode"
|
||||||
placeholder="e.g. App.Soutes"
|
placeholder="e.g. App.Wizard.Routes"
|
||||||
component={Input}
|
component={Input}
|
||||||
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
|
@ -145,66 +150,10 @@ const WizardStep2 = ({
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label="Title Text (En)"
|
|
||||||
invalid={!!(errors.languageTextTitleEn && touched.languageTextTitleEn)}
|
|
||||||
errorMessage={errors.languageTextTitleEn}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
autoComplete="off"
|
|
||||||
name="languageTextTitleEn"
|
|
||||||
placeholder="English Title Text"
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label="Title Text (Tr)"
|
|
||||||
invalid={!!(errors.languageTextTitleTr && touched.languageTextTitleTr)}
|
|
||||||
errorMessage={errors.languageTextTitleTr}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
autoComplete="off"
|
|
||||||
name="languageTextTitleTr"
|
|
||||||
placeholder="Turkish Title Text"
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label="Description Text (En)"
|
|
||||||
invalid={!!(errors.languageTextDescEn && touched.languageTextDescEn)}
|
|
||||||
errorMessage={errors.languageTextDescEn}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
autoComplete="off"
|
|
||||||
name="languageTextDescEn"
|
|
||||||
placeholder="English Description Text"
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
|
|
||||||
<FormItem
|
|
||||||
label="Description Text (Tr)"
|
|
||||||
invalid={!!(errors.languageTextDescTr && touched.languageTextDescTr)}
|
|
||||||
errorMessage={errors.languageTextDescTr}
|
|
||||||
>
|
|
||||||
<Field
|
|
||||||
type="text"
|
|
||||||
autoComplete="off"
|
|
||||||
name="languageTextDescTr"
|
|
||||||
placeholder="Turkish Description Text"
|
|
||||||
component={Input}
|
|
||||||
/>
|
|
||||||
</FormItem>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Select Command + Key Field Name */}
|
{/* Select Command + Key Field Name */}
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-6">
|
||||||
<FormItem
|
<FormItem
|
||||||
label="Select Command"
|
label="Select Command"
|
||||||
invalid={!!(errors.selectCommand && touched.selectCommand)}
|
invalid={!!(errors.selectCommand && touched.selectCommand)}
|
||||||
|
|
@ -268,7 +217,6 @@ const WizardStep2 = ({
|
||||||
: []
|
: []
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
componentAs={CreatableSelect}
|
|
||||||
field={field}
|
field={field}
|
||||||
form={form}
|
form={form}
|
||||||
isClearable
|
isClearable
|
||||||
|
|
@ -361,6 +309,94 @@ const WizardStep2 = ({
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label="Is Tenant?"
|
||||||
|
invalid={!!(errors.isTenant && touched.isTenant)}
|
||||||
|
errorMessage={errors.isTenant}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="checkbox"
|
||||||
|
autoComplete="off"
|
||||||
|
name="isTenant"
|
||||||
|
component={Checkbox}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label="Is Branch?"
|
||||||
|
invalid={!!(errors.isBranch && touched.isBranch)}
|
||||||
|
errorMessage={errors.isBranch}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="checkbox"
|
||||||
|
autoComplete="off"
|
||||||
|
name="isBranch"
|
||||||
|
component={Checkbox}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-6">
|
||||||
|
<FormItem
|
||||||
|
label="Title Text (English)"
|
||||||
|
asterisk={true}
|
||||||
|
invalid={!!(errors.languageTextTitleEn && touched.languageTextTitleEn)}
|
||||||
|
errorMessage={errors.languageTextTitleEn}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
autoComplete="off"
|
||||||
|
name="languageTextTitleEn"
|
||||||
|
placeholder="English Title Text"
|
||||||
|
component={Input}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label="Title Text (Turkish)"
|
||||||
|
asterisk={true}
|
||||||
|
invalid={!!(errors.languageTextTitleTr && touched.languageTextTitleTr)}
|
||||||
|
errorMessage={errors.languageTextTitleTr}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
autoComplete="off"
|
||||||
|
name="languageTextTitleTr"
|
||||||
|
placeholder="Turkish Title Text"
|
||||||
|
component={Input}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label="Description Text (English)"
|
||||||
|
asterisk={true}
|
||||||
|
invalid={!!(errors.languageTextDescEn && touched.languageTextDescEn)}
|
||||||
|
errorMessage={errors.languageTextDescEn}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
autoComplete="off"
|
||||||
|
name="languageTextDescEn"
|
||||||
|
placeholder="English Description Text"
|
||||||
|
component={Input}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
<FormItem
|
||||||
|
label="Description Text (Turkish)"
|
||||||
|
asterisk={true}
|
||||||
|
invalid={!!(errors.languageTextDescTr && touched.languageTextDescTr)}
|
||||||
|
errorMessage={errors.languageTextDescTr}
|
||||||
|
>
|
||||||
|
<Field
|
||||||
|
type="text"
|
||||||
|
autoComplete="off"
|
||||||
|
name="languageTextDescTr"
|
||||||
|
placeholder="Turkish Description Text"
|
||||||
|
component={Input}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Column Selection Panel */}
|
{/* Column Selection Panel */}
|
||||||
|
|
|
||||||
|
|
@ -751,17 +751,17 @@ const WizardStep3 = ({
|
||||||
{/* ── Fixed Footer ─────────────────────────────────────────────────── */}
|
{/* ── Fixed Footer ─────────────────────────────────────────────────── */}
|
||||||
<div className="fixed bottom-0 left-0 right-0 z-10 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700 px-6 py-0 h-16 flex items-center">
|
<div className="fixed bottom-0 left-0 right-0 z-10 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700 px-6 py-0 h-16 flex items-center">
|
||||||
<div className="flex items-center gap-3 w-full">
|
<div className="flex items-center gap-3 w-full">
|
||||||
<Button variant="default" type="button" icon={<FaCode />} onClick={() => setIsHelperOpen(true)}>
|
<Button size='sm' variant="default" type="button" icon={<FaArrowLeft />} onClick={onBack}>
|
||||||
{translate('::Helper Codes') || 'Helper Codes'}
|
|
||||||
</Button>
|
|
||||||
<Button variant="default" type="button" icon={<FaArrowLeft />} onClick={onBack}>
|
|
||||||
{translate('::Back') || 'Back'}
|
{translate('::Back') || 'Back'}
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button size='sm' variant="default" type="button" icon={<FaCode />} onClick={() => setIsHelperOpen(true)}>
|
||||||
|
{translate('::Helper Codes') || 'Helper Codes'}
|
||||||
|
</Button>
|
||||||
<div className="flex-1 flex items-center justify-end gap-3">
|
<div className="flex-1 flex items-center justify-end gap-3">
|
||||||
{!canProceed && (
|
{!canProceed && (
|
||||||
<span className="text-xs text-amber-600 dark:text-amber-400 font-medium">⚠ {validationMsg}</span>
|
<span className="text-xs text-amber-600 dark:text-amber-400 font-medium">⚠ {validationMsg}</span>
|
||||||
)}
|
)}
|
||||||
<Button variant="solid" type="button" icon={<FaArrowRight />} disabled={!canProceed} onClick={onNext}>
|
<Button size='sm' variant="solid" type="button" icon={<FaArrowRight />} disabled={!canProceed} onClick={onNext}>
|
||||||
{translate('::Next') || 'Next'}
|
{translate('::Next') || 'Next'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import {
|
||||||
FaRocket,
|
FaRocket,
|
||||||
FaSpinner,
|
FaSpinner,
|
||||||
} from 'react-icons/fa'
|
} from 'react-icons/fa'
|
||||||
import { selectCommandTypeOptions } from './edit/options'
|
import { dbSourceTypeOptions, selectCommandTypeOptions } from './edit/options'
|
||||||
|
|
||||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -230,7 +230,13 @@ const WizardStep4 = ({
|
||||||
/>
|
/>
|
||||||
<Row label="Select Command" value={values.selectCommand} />
|
<Row label="Select Command" value={values.selectCommand} />
|
||||||
<Row label="Key Field" value={values.keyFieldName} />
|
<Row label="Key Field" value={values.keyFieldName} />
|
||||||
<Row label="Key Field Tipi" value={String(values.keyFieldDbSourceType)} />
|
<Row
|
||||||
|
label="Key Field Tipi"
|
||||||
|
value={
|
||||||
|
dbSourceTypeOptions.find((o: any) => o.value === values.keyFieldDbSourceType)
|
||||||
|
?.label ?? String(values.keyFieldDbSourceType)
|
||||||
|
}
|
||||||
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -384,11 +390,19 @@ const WizardStep4 = ({
|
||||||
{/* ── Fixed Footer ─────────────────────────────────────────────── */}
|
{/* ── Fixed Footer ─────────────────────────────────────────────── */}
|
||||||
<div className="fixed bottom-0 left-0 right-0 z-10 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700 px-6 py-0 h-16 flex items-center">
|
<div className="fixed bottom-0 left-0 right-0 z-10 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-700 px-6 py-0 h-16 flex items-center">
|
||||||
<div className="flex items-center gap-3 w-full">
|
<div className="flex items-center gap-3 w-full">
|
||||||
<Button variant="default" type="button" icon={<FaArrowLeft />} onClick={onBack} disabled={isDeploying}>
|
<Button
|
||||||
|
size='sm'
|
||||||
|
variant="default"
|
||||||
|
type="button"
|
||||||
|
icon={<FaArrowLeft />}
|
||||||
|
onClick={onBack}
|
||||||
|
disabled={isDeploying}
|
||||||
|
>
|
||||||
{translate('::Back') || 'Back'}
|
{translate('::Back') || 'Back'}
|
||||||
</Button>
|
</Button>
|
||||||
<div className="flex-1 flex items-center justify-end">
|
<div className="flex-1 flex items-center justify-end">
|
||||||
<Button
|
<Button
|
||||||
|
size='sm'
|
||||||
variant="solid"
|
variant="solid"
|
||||||
type="button"
|
type="button"
|
||||||
icon={<FaRocket />}
|
icon={<FaRocket />}
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,8 @@ export default defineConfig(async ({ mode }) => {
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|
||||||
manifest: {
|
manifest: {
|
||||||
name: 'Sozsoft Platform',
|
name: 'Sözsoft Platform',
|
||||||
short_name: 'Sozsoft Platform',
|
short_name: 'Sözsoft Platform',
|
||||||
theme_color: '#FF99C8',
|
theme_color: '#FF99C8',
|
||||||
background_color: '#f0e7db',
|
background_color: '#f0e7db',
|
||||||
display: 'standalone',
|
display: 'standalone',
|
||||||
|
|
@ -112,7 +112,7 @@ export default defineConfig(async ({ mode }) => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
categories: ['business', 'productivity'],
|
categories: ['business', 'productivity'],
|
||||||
description: 'Sozsoft Platform Application',
|
description: 'Sözsoft Platform Application',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue