File Management ve ListFormSeeder

This commit is contained in:
Sedat ÖZTÜRK 2026-03-11 09:20:13 +03:00
parent 96b61e7801
commit dfc63617f8
6 changed files with 219 additions and 201 deletions

View file

@ -551,7 +551,7 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
};
}
[HttpDelete("api/app/file-management/items/{id}/item/{tenantId}")]
[HttpDelete("api/app/file-management/{id}/item/{tenantId}")]
public async Task DeleteItemAsync(string id, string? tenantId = null)
{
// Check if this is a protected system folder

View file

@ -7958,7 +7958,7 @@
},
{
"resourceName": "Platform",
"key": "Public.services.web.features.Api",
"key": "Public.services.web.features.api",
"tr": "Api Geliştirme",
"en": "Api Development"
},

View file

@ -84,7 +84,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(AbpIdentity.PermissionGroups.Create, AbpIdentity.PermissionGroups.Default, AbpIdentity.PermissionGroups.Update, AbpIdentity.PermissionGroups.Delete, AbpIdentity.PermissionGroups.Export, AbpIdentity.PermissionGroups.Import, AbpIdentity.PermissionGroups.Note),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 350, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 350, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
{
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items =
@ -206,7 +206,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(AbpIdentity.Permissions.Create, listFormName, AbpIdentity.Permissions.Update, AbpIdentity.Permissions.Delete, AbpIdentity.Permissions.Export, AbpIdentity.Permissions.Import, AbpIdentity.Permissions.Note),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 350, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 500, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
{
new() {
@ -433,7 +433,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(listFormName),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 500, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
{
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items =[
@ -788,7 +788,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
PermissionJson = DefaultPermissionJson(PlatformConsts.IdentityPermissions.Users.Create, listFormName, PlatformConsts.IdentityPermissions.Users.Update, PlatformConsts.IdentityPermissions.Users.Delete, PlatformConsts.IdentityPermissions.Users.Export, PlatformConsts.IdentityPermissions.Users.Import, PlatformConsts.IdentityPermissions.Users.Note),
DeleteCommand = $"UPDATE \"AbpUsers\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id",
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 400, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 450, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new () { Order=1,ColCount=1,ColSpan=1,ItemType="group",Items=[
new EditingFormItemDto { Order=1, DataField="Email", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
@ -1052,7 +1052,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
DeleteCommand = $"UPDATE \"{FullNameTable(TableNameEnum.IpRestriction)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id",
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new() {
Order=1, ColCount=1, ColSpan=1, ItemType="group", Items=
@ -1393,7 +1393,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(listFormName),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() {
@ -1523,7 +1523,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.ReportTemplate)),
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 900, 500, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 900, 600, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
{
new() {
@ -1532,8 +1532,8 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
new EditingFormItemDto { Order = 1, DataField = "Name", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 2, DataField = "Description", ColSpan = 1, EditorType2 = EditorTypes.dxTextArea },
new EditingFormItemDto { Order = 3, DataField = "CategoryId", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox },
new EditingFormItemDto { Order = 4, DataField = "HtmlContent", ColSpan = 1, EditorType2 = EditorTypes.dxHtmlEditor, EditorOptions = EditorOptionValues.HtmlEditorOptions },
new EditingFormItemDto { Order = 5, DataField = "Status", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox },
new EditingFormItemDto { Order = 4, DataField = "Status", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox },
new EditingFormItemDto { Order = 5, DataField = "HtmlContent", ColSpan = 1, EditorType2 = EditorTypes.dxHtmlEditor, EditorOptions = EditorOptionValues.HtmlEditorOptions },
]}
}),
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(),
@ -1721,7 +1721,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(DbType.String),
PagerOptionJson = DefaultPagerOptionJson,
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(DbType.String),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 400, 150, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 400, 200, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() {
@ -1815,7 +1815,7 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(DbType.String),
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(DbType.String),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 600, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new() {
Order = 1, ColCount = 2, ColSpan = 2, ItemType = "group",

View file

@ -591,7 +591,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(listFormName),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 500, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 600, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
{
new() { Order=1, ColCount=2, ColSpan=1, ItemType="group", Items =
@ -615,9 +615,9 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new EditingFormItemDto { Order=4, DataField = "Township", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
new EditingFormItemDto { Order=5, DataField = "Address1", ColSpan=2, IsRequired=false, EditorType2=EditorTypes.dxTextArea },
new EditingFormItemDto { Order=6, DataField = "Address2", ColSpan=2, IsRequired=false, EditorType2=EditorTypes.dxTextArea },
new EditingFormItemDto { Order=7, DataField = "Email", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=8, DataField = "Website", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=9, DataField = "PostalCode", ColSpan=1, IsRequired=false, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=7, DataField = "PostalCode", ColSpan=1, IsRequired=false, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=8, DataField = "Email", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order=9, DataField = "Website", ColSpan=1, IsRequired=true, EditorType2=EditorTypes.dxTextBox },
]
}
}),
@ -1057,7 +1057,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
new() { FieldName = "Id", FieldDbType = DbType.Int32, Value = "@ID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
}),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 450, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
{
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items = [
@ -1217,7 +1217,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
new() { FieldName = "Id", FieldDbType = DbType.Int32, Value = "@ID", CustomValueType = FieldCustomValueTypeEnum.CustomKey }
}),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 450, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>()
{
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items = [
@ -1711,7 +1711,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.Country)),
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 500, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 550, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() {
@ -1907,7 +1907,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.City)),
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() {
@ -2043,7 +2043,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.District)),
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() {
@ -2188,7 +2188,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
Name = listFormName,
Title = listFormName,
DataSourceCode = SeedConsts.DataSources.DefaultCode,
IsTenant = true,
IsTenant = false,
IsBranch = false,
IsOrganizationUnit = false,
Description = listFormName,
@ -2294,7 +2294,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
Name = listFormName,
Title = listFormName,
DataSourceCode = SeedConsts.DataSources.DefaultCode,
IsTenant = true,
IsTenant = false,
IsBranch = false,
IsOrganizationUnit = false,
Description = listFormName,
@ -2497,7 +2497,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
Name = listFormName,
Title = listFormName,
DataSourceCode = SeedConsts.DataSources.DefaultCode,
IsTenant = true,
IsTenant = false,
IsBranch = false,
IsOrganizationUnit = false,
Description = listFormName,
@ -2615,7 +2615,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
Name = listFormName,
Title = listFormName,
DataSourceCode = SeedConsts.DataSources.DefaultCode,
IsTenant = true,
IsTenant = false,
IsBranch = false,
IsOrganizationUnit = false,
Description = listFormName,
@ -2761,7 +2761,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
Name = listFormName,
Title = listFormName,
DataSourceCode = SeedConsts.DataSources.DefaultCode,
IsTenant = true,
IsTenant = false,
IsBranch = false,
IsOrganizationUnit = false,
Description = listFormName,
@ -2890,7 +2890,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 600, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items= [
new() { Order=1, ColCount=2, ColSpan=1, ItemType="group", Items= [
new EditingFormItemDto { Order = 1, DataField = "MainGroupKey", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxAutocomplete, EditorOptions=EditorOptionValues.ShowClearButton },
new EditingFormItemDto { Order = 2, DataField = "SubGroupKey", ColSpan = 1, EditorType2=EditorTypes.dxAutocomplete, EditorOptions=EditorOptionValues.ShowClearButton },
new EditingFormItemDto { Order = 3, DataField = "Code", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
@ -3615,7 +3615,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = $"UPDATE \"{FullNameTable(TableNameEnum.DataSource)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id",
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 600, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 500, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items=
[
@ -3752,9 +3752,9 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PermissionJson = DefaultPermissionJson(listFormName),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 500, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 950, 650, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items=[
new() { Order=1, ColCount=3, ColSpan=1, ItemType="group", Items=[
new EditingFormItemDto { Order = 1, DataField = "CultureName", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
new EditingFormItemDto { Order = 2, DataField = "Name", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 3, DataField = "ListFormCode", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
@ -3775,11 +3775,11 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new EditingFormItemDto { Order = 18, DataField = "IsSubForm", ColSpan = 1, EditorType2=EditorTypes.dxCheckBox },
]},
new() {
Order=2,ColCount=1,ColSpan=2,ItemType="group", Items= [
new EditingFormItemDto { Order = 1, DataField = "PermissionJson:C", ColSpan = 2, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 2, DataField = "PermissionJson:R", ColSpan = 2, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 3, DataField = "PermissionJson:U", ColSpan = 2, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 4, DataField = "PermissionJson:D", ColSpan = 2, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
Order=2,ColCount=2,ColSpan=1,ItemType="group", Items= [
new EditingFormItemDto { Order = 1, DataField = "PermissionJson:C", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 2, DataField = "PermissionJson:R", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 3, DataField = "PermissionJson:U", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 4, DataField = "PermissionJson:D", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
]}
}),
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(),
@ -3824,7 +3824,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "CultureName",
CaptionName = "App.Listform.ListformField.CultureName",
CaptionName = "App.Listform.ListformField.CultureName",
Width = 90,
ListOrderNo = 1,
Visible = true,
@ -3843,8 +3843,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "Name",
CaptionName = "App.Listform.ListformField.Name",
Width = 180,
CaptionName = "App.Listform.ListformField.Name",
Width = 200,
ListOrderNo = 2,
Visible = true,
IsActive = true,
@ -3860,8 +3860,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "Description",
CaptionName = "App.Listform.ListformField.Description",
Width = 180,
CaptionName = "App.Listform.ListformField.Description",
Width = 250,
ListOrderNo = 3,
Visible = true,
IsActive = true,
@ -3876,8 +3876,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "ListFormCode",
CaptionName = "App.Listform.ListformField.ListFormCode",
Width = 120,
CaptionName = "App.Listform.ListformField.ListFormCode",
Width = 200,
ListOrderNo = 4,
Visible = true,
IsActive = true,
@ -3895,7 +3895,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "ListFormType",
CaptionName = "App.Listform.ListformField.ListFormType",
CaptionName = "App.Listform.ListformField.ListFormType",
Width = 75,
ListOrderNo = 5,
Visible = true,
@ -3922,7 +3922,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.Int32,
FieldName = "SelectCommandType",
CaptionName = "App.Listform.ListformField.SelectCommandType",
CaptionName = "App.Listform.ListformField.SelectCommandType",
Width = 150,
ListOrderNo = 6,
Visible = true,
@ -3951,8 +3951,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "SelectCommand",
CaptionName = "App.Listform.ListformField.SelectCommand",
Width = 150,
CaptionName = "App.Listform.ListformField.SelectCommand",
Width = 200,
ListOrderNo = 7,
Visible = true,
IsActive = true,
@ -3968,7 +3968,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "TableName",
CaptionName = "App.Listform.ListformField.TableName",
CaptionName = "App.Listform.ListformField.TableName",
Width = 100,
ListOrderNo = 8,
Visible = true,
@ -3984,7 +3984,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "KeyFieldName",
CaptionName = "App.Listform.ListformField.KeyFieldName",
CaptionName = "App.Listform.ListformField.KeyFieldName",
Width = 120,
ListOrderNo = 9,
Visible = true,
@ -4001,7 +4001,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.Int32,
FieldName = "KeyFieldDbSourceType",
CaptionName = "App.Listform.ListformField.KeyFieldDbSourceType",
CaptionName = "App.Listform.ListformField.KeyFieldDbSourceType",
Width = 100,
ListOrderNo = 10,
Visible = true,
@ -4052,8 +4052,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "Title",
CaptionName = "App.Listform.ListformField.Title",
Width = 150,
CaptionName = "App.Listform.ListformField.Title",
Width = 250,
ListOrderNo = 11,
Visible = true,
IsActive = true,
@ -4068,7 +4068,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "SortMode",
CaptionName = "App.Listform.ListformField.SortMode",
CaptionName = "App.Listform.ListformField.SortMode",
Width = 100,
ListOrderNo = 12,
Visible = true,
@ -4094,7 +4094,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.Boolean,
FieldName = "IsTenant",
CaptionName = "App.Listform.ListformField.IsTenant",
CaptionName = "App.Listform.ListformField.IsTenant",
Width = 85,
ListOrderNo = 13,
Visible = true,
@ -4110,7 +4110,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.Boolean,
FieldName = "IsOrganizationUnit",
CaptionName = "App.Listform.ListformField.IsOrganizationUnit",
CaptionName = "App.Listform.ListformField.IsOrganizationUnit",
Width = 85,
ListOrderNo = 14,
Visible = true,
@ -4126,7 +4126,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.Boolean,
FieldName = "IsSubForm",
CaptionName = "App.Listform.ListformField.IsSubForm",
CaptionName = "App.Listform.ListformField.IsSubForm",
Width = 85,
ListOrderNo = 15,
Visible = true,
@ -4142,8 +4142,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "PermissionJson",
CaptionName = "App.Listform.ListformField.PermissionJson",
Width = 250,
CaptionName = "App.Listform.ListformField.PermissionJson",
Width = 700,
ListOrderNo = 16,
Visible = true,
IsActive = true,
@ -4158,8 +4158,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "DeleteServiceAddress",
CaptionName = "App.Listform.ListformField.DeleteServiceAddress",
Width = 120,
CaptionName = "App.Listform.ListformField.DeleteServiceAddress",
Width = 150,
ListOrderNo = 17,
Visible = true,
IsActive = true,
@ -4174,8 +4174,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "InsertServiceAddress",
CaptionName = "App.Listform.ListformField.InsertServiceAddress",
Width = 120,
CaptionName = "App.Listform.ListformField.InsertServiceAddress",
Width = 150,
ListOrderNo = 18,
Visible = true,
IsActive = true,
@ -4190,8 +4190,8 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
CultureName = LanguageCodes.En,
SourceDbType = DbType.String,
FieldName = "UpdateServiceAddress",
CaptionName = "App.Listform.ListformField.UpdateServiceAddress",
Width = 120,
CaptionName = "App.Listform.ListformField.UpdateServiceAddress",
Width = 150,
ListOrderNo = 19,
Visible = true,
IsActive = true,
@ -4243,7 +4243,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = $"UPDATE \"{FullNameTable(TableNameEnum.NotificationRule)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id",
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 500, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items=[
new EditingFormItemDto { Order = 1, DataField = "NotificationType", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
@ -4484,7 +4484,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = $"UPDATE \"{FullNameTable(TableNameEnum.Notification)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id",
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 700, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 500, true, true, true, true, false),
}
);
@ -4711,9 +4711,9 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = $"UPDATE \"{FullNameTable(TableNameEnum.BackgroundWorker)}\" SET \"DeleterId\"=@DeleterId, \"DeletionTime\"=CURRENT_TIMESTAMP, \"IsDeleted\"='true' WHERE \"Id\"=@Id",
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 650, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 550, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group",Items=[
new() { Order=1, ColCount=2, ColSpan=1, ItemType="group",Items=[
new EditingFormItemDto { Order = 1, DataField = "Name", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 2, DataField = "Cron", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 3, DataField = "WorkerType", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
@ -4722,9 +4722,9 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new EditingFormItemDto { Order = 6, DataField = "IsActive", ColSpan = 1, EditorType2=EditorTypes.dxCheckBox },
]
},
new() { Order=2,ColCount=1,ColSpan=2,ItemType="group",Items= [
new EditingFormItemDto { Order = 1, DataField = "Options:MailType", ColSpan = 2, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 2, DataField = "Options:MailSubject", ColSpan = 2, EditorType2=EditorTypes.dxTextBox },
new() { Order=2,ColCount=2,ColSpan=1,ItemType="group",Items= [
new EditingFormItemDto { Order = 1, DataField = "Options:MailType", ColSpan = 1, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 2, DataField = "Options:MailSubject", ColSpan = 1, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 3, DataField = "Options:MailTemplate", ColSpan = 2, EditorType2=EditorTypes.dxTextArea, EditorOptions="{\"height\":200}" },
new EditingFormItemDto { Order = 4, DataField = "Options:Tablo", ColSpan = 2, EditorType2=EditorTypes.dxTextBox },
]}
@ -4931,7 +4931,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new EditingFormItemDto { Order = 2, DataField = "Path", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 3, DataField = "ComponentPath", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 4, DataField = "RouteType", ColSpan = 1, IsRequired = true, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton },
new EditingFormItemDto { Order = 5, DataField = "Authority", ColSpan = 1, EditorType2 = EditorTypes.dxAutocomplete }
new EditingFormItemDto { Order = 5, DataField = "Authority", ColSpan = 1, EditorType2 = EditorTypes.dxSelectBox, EditorOptions=EditorOptionValues.ShowClearButton }
]
}
}),
@ -5104,9 +5104,9 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
TreeOptionJson = DefaultTreeOptionJson("Code", "ParentCode", true),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 450, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 550, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>() {
new() { Order=1, ColCount=1, ColSpan=1, ItemType="group", Items=
new() { Order=1, ColCount=2, ColSpan=1, ItemType="group", Items=
[
new EditingFormItemDto { Order = 1, DataField = "Code", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxTextBox },
new EditingFormItemDto { Order = 2, DataField = "DisplayName", ColSpan = 1, IsRequired = true, EditorType2=EditorTypes.dxAutocomplete, EditorOptions=EditorOptionValues.ShowClearButton },
@ -5691,7 +5691,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
SourceDbType = DbType.String,
FieldName = "StatsJson",
CaptionName = "App.Listform.ListformField.StatsJson",
Width = 400,
Width = 700,
ListOrderNo = 2,
Visible = true,
IsActive = true,
@ -5779,7 +5779,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(listFormName),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 400, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() { Order = 1, ColCount = 1, ColSpan = 1, ItemType = "group", Items =
@ -5970,7 +5970,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.Product)),
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 400, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 500, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() { Order = 1, ColCount = 1, ColSpan = 1, ItemType = "group", Items =
@ -6203,7 +6203,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(listFormName),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() { Order = 1, ColCount = 1, ColSpan = 1, ItemType = "group", Items =
@ -6337,7 +6337,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(listFormName),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 300, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 350, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() { Order = 1, ColCount = 1, ColSpan = 1, ItemType = "group", Items =
@ -6955,7 +6955,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.BlogCategory)),
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 400, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 600, 450, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() { Order = 1, ColCount = 1, ColSpan = 1, ItemType = "group", Items =
@ -7515,7 +7515,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(listFormName),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 400, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 500, 500, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() {
@ -7747,7 +7747,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
ColumnOptionJson = DefaultColumnOptionJson(),
PermissionJson = DefaultPermissionJson(listFormName),
PagerOptionJson = DefaultPagerOptionJson,
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 600, true, true, true, true, false),
EditingOptionJson = DefaultEditingOptionJson(listFormName, 800, 700, true, true, true, true, false),
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
{
new() {

View file

@ -1,4 +1,4 @@
import { useState, useEffect, useCallback } from 'react'
import { useState, useEffect, useCallback, useRef } from 'react'
import { Helmet } from 'react-helmet'
import { Button, Input, Select, toast, Notification, Spinner } from '@/components/ui'
import {
@ -70,7 +70,11 @@ const FileManager = () => {
// Tenant state
const [tenants, setTenants] = useState<TenantDto[]>([])
const [tenantsLoading, setTenantsLoading] = useState(false)
const [selectedTenant, setSelectedTenant] = useState<{ id: string; name: string } | undefined>(undefined)
const [selectedTenant, setSelectedTenant] = useState<{ id: string; name: string } | undefined>(
undefined,
)
// Tracks mid-flight tenant change so the fetch effect doesn't fire with a stale folderId
const pendingTenantChange = useRef(false)
// Loading states
const [uploading, setUploading] = useState(false)
@ -97,76 +101,91 @@ const FileManager = () => {
// Reset navigation when tenant changes
useEffect(() => {
pendingTenantChange.current = true
setCurrentFolderId(undefined)
setSelectedItems([])
setBreadcrumbItems([{ name: 'Files', path: '', id: undefined }])
}, [selectedTenant])
// Fetch items from API
const fetchItems = useCallback(async (folderId?: string) => {
try {
setLoading(true)
const response = await fileManagementService.getItems(folderId, selectedTenant?.id)
// Backend returns GetFilesDto which has Items property
const items = response.data.items || []
// Manual protection for system folders
const protectedItems = items.map((item) => {
const isSystemFolder = ['avatar', 'import', 'note'].includes(item.name.toLowerCase())
return {
...item,
isReadOnly: item.isReadOnly || isSystemFolder,
}
})
const fetchItems = useCallback(
async (folderId?: string) => {
try {
setLoading(true)
const response = await fileManagementService.getItems(folderId, selectedTenant?.id)
// Backend returns GetFilesDto which has Items property
const items = response.data.items || []
// Manual protection for system folders
const protectedItems = items.map((item) => {
const isSystemFolder = ['avatar', 'import', 'note'].includes(item.name.toLowerCase())
return {
...item,
isReadOnly: item.isReadOnly || isSystemFolder,
}
})
// console.log('Fetched items:', protectedItems)
// console.log(
// 'Protected folders check:',
// protectedItems.filter((item) => item.isReadOnly),
// )
// console.log(
// 'Folders with childCount:',
// protectedItems.filter((item) => item.type === 'folder').map(item => ({
// name: item.name,
// childCount: item.childCount,
// hasChildCount: 'childCount' in item,
// type: typeof item.childCount
// }))
// )
setItems(protectedItems)
} catch (error) {
console.error('Failed to fetch items:', error)
toast.push(<Notification type="danger">Failed to load files and folders</Notification>)
} finally {
setLoading(false)
}
}, [selectedTenant])
// console.log('Fetched items:', protectedItems)
// console.log(
// 'Protected folders check:',
// protectedItems.filter((item) => item.isReadOnly),
// )
// console.log(
// 'Folders with childCount:',
// protectedItems.filter((item) => item.type === 'folder').map(item => ({
// name: item.name,
// childCount: item.childCount,
// hasChildCount: 'childCount' in item,
// type: typeof item.childCount
// }))
// )
setItems(protectedItems)
} catch (error) {
console.error('Failed to fetch items:', error)
toast.push(<Notification type="danger">Failed to load files and folders</Notification>)
} finally {
setLoading(false)
}
},
[selectedTenant],
)
// Fetch breadcrumb path
const fetchBreadcrumb = useCallback(async (folderId?: string) => {
try {
if (!folderId) {
setBreadcrumbItems([{ name: 'Files', path: '', id: undefined }])
return
}
const fetchBreadcrumb = useCallback(
async (folderId?: string) => {
try {
if (!folderId) {
setBreadcrumbItems([{ name: 'Files', path: '', id: undefined }])
return
}
const response = await fileManagementService.getFolderPath(folderId, selectedTenant?.id)
// console.log('Breadcrumb response for folderId:', folderId, response)
const pathItems: BreadcrumbItem[] = [
{ name: 'Files', path: '', id: undefined },
...response.data.path.map((item) => ({
name: item.name,
path: item.id,
id: item.id,
})),
]
setBreadcrumbItems(pathItems)
} catch (error) {
console.error('Failed to fetch breadcrumb:', error)
}
}, [selectedTenant])
const response = await fileManagementService.getFolderPath(folderId, selectedTenant?.id)
// console.log('Breadcrumb response for folderId:', folderId, response)
const pathItems: BreadcrumbItem[] = [
{ name: 'Files', path: '', id: undefined },
...response.data.path.map((item) => ({
name: item.name,
path: item.id,
id: item.id,
})),
]
setBreadcrumbItems(pathItems)
} catch (error) {
console.error('Failed to fetch breadcrumb:', error)
}
},
[selectedTenant],
)
// Initial load
useEffect(() => {
if (pendingTenantChange.current) {
pendingTenantChange.current = false
if (currentFolderId !== undefined) {
// The reset effect already called setCurrentFolderId(undefined);
// wait for that state update to re-trigger this effect at root.
return
}
}
fetchItems(currentFolderId)
fetchBreadcrumb(currentFolderId)
}, [currentFolderId, fetchItems, fetchBreadcrumb])
@ -241,7 +260,7 @@ const FileManager = () => {
event.preventDefault()
event.stopPropagation()
}
// Clear any text selection that might have occurred
if (window.getSelection) {
const selection = window.getSelection()
@ -249,7 +268,7 @@ const FileManager = () => {
selection.removeAllRanges()
}
}
if (item.type === 'folder') {
setCurrentFolderId(item.id)
setSelectedItems([])
@ -285,10 +304,13 @@ const FileManager = () => {
const handleCreateFolder = async (name: string) => {
try {
setCreating(true)
await fileManagementService.createFolder({
name,
parentId: currentFolderId,
}, selectedTenant?.id)
await fileManagementService.createFolder(
{
name,
parentId: currentFolderId,
},
selectedTenant?.id,
)
await fetchItems(currentFolderId)
toast.push(<Notification type="success">Folder created successfully</Notification>)
} catch (error) {
@ -305,10 +327,13 @@ const FileManager = () => {
try {
setRenaming(true)
await fileManagementService.renameItem({
id: itemToRename.id,
newName,
}, selectedTenant?.id)
await fileManagementService.renameItem(
{
id: itemToRename.id,
newName,
},
selectedTenant?.id,
)
await fetchItems(currentFolderId)
toast.push(<Notification type="success">Item renamed successfully</Notification>)
} catch (error) {
@ -491,7 +516,7 @@ const FileManager = () => {
const response = await fileManagementService.getItems(folderId, selectedTenant?.id)
const items = response.data.items || []
// Check if folder contains any files (not just other folders)
return items.some(item => item.type === 'file')
return items.some((item) => item.type === 'file')
} catch (error) {
console.error('Error checking folder contents:', error)
return false
@ -515,7 +540,7 @@ const FileManager = () => {
}
// Filter out folders that contain files
const finalDeletableItems = deletableItems.filter(item => {
const finalDeletableItems = deletableItems.filter((item) => {
if (item.type === 'folder') {
return !foldersWithFiles.includes(item.name)
}
@ -535,8 +560,8 @@ const FileManager = () => {
if (foldersWithFiles.length > 0) {
toast.push(
<Notification title="Security Warning" type="warning">
{foldersWithFiles.length} folder(s) containing files cannot be deleted for security reasons:{' '}
{foldersWithFiles.join(', ')}
{foldersWithFiles.length} folder(s) containing files cannot be deleted for security
reasons: {foldersWithFiles.join(', ')}
</Notification>,
)
}
@ -710,40 +735,38 @@ const FileManager = () => {
{/* Enhanced Unified Toolbar */}
<div className="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-3 sm:p-4 mb-4 mt-2">
{/* Main Toolbar Row */}
<div className="flex flex-col lg:flex-row lg:items-center justify-between gap-3 sm:gap-4">
{/* Left Section - Primary Actions */}
<div className="flex items-center gap-2 flex-wrap min-w-0">
{/* Tenant Selector Row */}
<div className="flex items-center gap-2">
<FaBuilding className="text-gray-500 flex-shrink-0" />
<Select
size="xs"
isLoading={tenantsLoading}
options={[
{ value: '', label: 'Host' },
...tenants.map((t) => ({ value: t.id ?? '', label: t.name ?? '' })),
]}
value={{
value: selectedTenant ? selectedTenant.id : '',
label: selectedTenant ? selectedTenant.name : 'Host',
}}
onChange={(option) => {
if (option && 'value' in option) {
const val = option.value as string
if (!val) {
setSelectedTenant(undefined)
} else {
const found = tenants.find((t) => t.id === val)
if (found) setSelectedTenant({ id: found.id!, name: found.name ?? '' })
}
}
}}
/>
</div>
<div className="flex items-center gap-2">
<FaBuilding className="text-gray-500 flex-shrink-0" />
<Select
size="xs"
isLoading={tenantsLoading}
options={[
{ value: '', label: 'Host' },
...tenants.map((t) => ({ value: t.id ?? '', label: t.name ?? '' })),
]}
value={{
value: selectedTenant ? selectedTenant.id : '',
label: selectedTenant ? selectedTenant.name : 'Host',
}}
onChange={(option) => {
if (option && 'value' in option) {
const val = option.value as string
if (!val) {
setSelectedTenant(undefined)
} else {
const found = tenants.find((t) => t.id === val)
if (found) setSelectedTenant({ id: found.id!, name: found.name ?? '' })
}
}
}}
/>
</div>
{/* File Operations */}
{/* Navigation */}
<Button
@ -825,8 +848,7 @@ const FileManager = () => {
disabled={selectedItems.length !== 1}
className="text-gray-600 hover:text-blue-600 flex-shrink-0"
title="Rename selected item"
>
</Button>
></Button>
<Button
variant="plain"
@ -855,8 +877,7 @@ const FileManager = () => {
}
className="text-gray-600 hover:text-green-600 flex-shrink-0"
title="Download selected file"
>
</Button>
></Button>
<Button
variant="plain"

View file

@ -315,18 +315,18 @@ export function ForumView({
</button>
)}
<nav className="flex items-center space-x-2 text-sm text-gray-500">
<button
onClick={() => handleBreadcrumbClick('forum')}
className={`transition-colors ${
viewState === 'categories'
? 'text-gray-900 font-medium cursor-default'
: 'hover:text-blue-600 cursor-pointer'
}`}
>
<h2 className="text-2xl font-bold text-gray-900">Forum</h2>
</button>
{selectedCategory && (
<>
<button
onClick={() => handleBreadcrumbClick('forum')}
className={`transition-colors ${
viewState === 'categories'
? 'text-gray-900 font-medium cursor-default'
: 'hover:text-blue-600 cursor-pointer'
}`}
>
<div className="text-sm font-medium text-gray-900">Forum</div>
</button>
<span>/</span>
<button
onClick={() => handleBreadcrumbClick('category')}
@ -379,9 +379,6 @@ export function ForumView({
<span className="text-gray-500">
{translate('::App.Forum.TopicManagement.Searchtopics')}
</span>
<kbd className="hidden sm:inline-block px-2 py-1 text-xs font-semibold text-gray-500 bg-gray-100 border border-gray-200 rounded">
K
</kbd>
</button>
<button