Intranet üzerinde Widgets yapısı dinamik hale getirildi
This commit is contained in:
parent
0941b9143b
commit
7a0839a3f6
34 changed files with 1181 additions and 208 deletions
|
|
@ -798,7 +798,7 @@ içindedir; oradaki kontroller yalnızca butonları gizler, asıl kontrol AppSer
|
||||||
| Aktivite ve denetim kaydı | `/admin/activityLog`, `/admin/changeLog` | Kullanıcı hareketleri ve ABP audit log detayı. |
|
| Aktivite ve denetim kaydı | `/admin/activityLog`, `/admin/changeLog` | Kullanıcı hareketleri ve ABP audit log detayı. |
|
||||||
| Bildirimler | `/admin/profile/notification-settings`, bildirim ekranları | Kanal tercihleri ve bildirim oluşturma. |
|
| Bildirimler | `/admin/profile/notification-settings`, bildirim ekranları | Kanal tercihleri ve bildirim oluşturma. |
|
||||||
| Forum | `/admin/forum`, `/admin/forumManagement` | Forum kullanımı ve yönetimi. |
|
| Forum | `/admin/forum`, `/admin/forumManagement` | Forum kullanımı ve yönetimi. |
|
||||||
| Intranet | Intranet dashboard ve widget'ları | Duyuru, anket, sosyal duvar, etkinlik. |
|
| Intranet | Intranet dashboard ve widget'ları | Duyuru, anket, sosyal duvar, etkinlik. Hangi widget'ın hangi kolonda, hangi sırada ve hangi yetkiyle yayınlandığı `Adm_T_IntranetWidget` kaydından gelir (`TenantData.json` → `Widgets`). |
|
||||||
| Video oda | `/admin/videoroom/*` | Oda listesi, detay, planlama, katılımcı ve ekran paylaşımı. |
|
| Video oda | `/admin/videoroom/*` | Oda listesi, detay, planlama, katılımcı ve ekran paylaşımı. |
|
||||||
| Raporlar | `/admin/reports/:report/view|design/...` | DevExpress rapor görüntüleyici ve tasarımcı. |
|
| Raporlar | `/admin/reports/:report/view|design/...` | DevExpress rapor görüntüleyici ve tasarımcı. |
|
||||||
| AI asistanı | `/admin/ai` | n8n webhook üzerinden sohbet arayüzü. |
|
| AI asistanı | `/admin/ai` | n8n webhook üzerinden sohbet arayüzü. |
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,7 @@ public class IntranetDashboardDto
|
||||||
public List<FileItemDto> Documents { get; set; } = [];
|
public List<FileItemDto> Documents { get; set; } = [];
|
||||||
public List<AnnouncementDto> Announcements { get; set; } = [];
|
public List<AnnouncementDto> Announcements { get; set; } = [];
|
||||||
public List<SurveyDto> Surveys { get; set; } = [];
|
public List<SurveyDto> Surveys { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>Dashboard'da yayinlanan widget'lar; sira ve kolon bilgisi kayittan gelir.</summary>
|
||||||
|
public List<IntranetWidgetDto> Widgets { get; set; } = [];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
using Sozsoft.Platform.Enums;
|
||||||
|
|
||||||
|
namespace Sozsoft.Platform.Intranet;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dashboard'da yayinlanacak widget tanimi. Hangi widget'in nerede, hangi sirada ve hangi
|
||||||
|
/// yetkiyle gorunecegi bu kayittan gelir; koddaki kayit yalnizca render fonksiyonunu tasir.
|
||||||
|
/// </summary>
|
||||||
|
public class IntranetWidgetDto
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Builtin widget'ta koddaki kayit anahtari, Custom widget'ta tekil kod.</summary>
|
||||||
|
public string Code { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string LabelKey { get; set; }
|
||||||
|
|
||||||
|
public IntranetWidgetSourceType SourceType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Custom widget'in CustomComponent adi.</summary>
|
||||||
|
public string ComponentName { get; set; }
|
||||||
|
|
||||||
|
public string PermissionName { get; set; }
|
||||||
|
|
||||||
|
public IntranetWidgetColumn Column { get; set; }
|
||||||
|
|
||||||
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Custom widget'a gecilecek prop'lar; JSON nesnesi.</summary>
|
||||||
|
public string Props { get; set; }
|
||||||
|
}
|
||||||
|
|
@ -85,6 +85,16 @@ public static class LookupQueryValues
|
||||||
$"\"{FullNameTable(TableNameEnum.LanguageText)}\".\"CultureName\" = 'tr' " +
|
$"\"{FullNameTable(TableNameEnum.LanguageText)}\".\"CultureName\" = 'tr' " +
|
||||||
$"ORDER BY \"{FullNameTable(TableNameEnum.LanguageKey)}\".\"Key\";";
|
$"ORDER BY \"{FullNameTable(TableNameEnum.LanguageKey)}\".\"Key\";";
|
||||||
|
|
||||||
|
public static string CustomComponentValues =
|
||||||
|
$"SELECT " +
|
||||||
|
$"\"Name\" AS \"Key\", " +
|
||||||
|
$"\"Name\" AS \"Name\" " +
|
||||||
|
$"FROM \"{FullNameTable(TableNameEnum.CustomComponent)}\" " +
|
||||||
|
$"WHERE " +
|
||||||
|
$"\"IsActive\" = 'true' " +
|
||||||
|
$"AND \"IsDeleted\" = 'false' " +
|
||||||
|
$"ORDER BY \"Name\";";
|
||||||
|
|
||||||
public static string CountryValues =
|
public static string CountryValues =
|
||||||
$"SELECT " +
|
$"SELECT " +
|
||||||
$"\"Id\" AS \"Key\", " +
|
$"\"Id\" AS \"Key\", " +
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ public class IntranetAppService : PlatformAppService, IIntranetAppService
|
||||||
private readonly IRepository<Department, Guid> _departmentRepository;
|
private readonly IRepository<Department, Guid> _departmentRepository;
|
||||||
private readonly IRepository<JobPosition, Guid> _jobPositionRepository;
|
private readonly IRepository<JobPosition, Guid> _jobPositionRepository;
|
||||||
private readonly IRepository<Announcement, Guid> _announcementRepository;
|
private readonly IRepository<Announcement, Guid> _announcementRepository;
|
||||||
|
private readonly IRepository<IntranetWidget, Guid> _intranetWidgetRepository;
|
||||||
private readonly IRepository<Survey, Guid> _surveyRepository;
|
private readonly IRepository<Survey, Guid> _surveyRepository;
|
||||||
private readonly IRepository<SurveyResponse, Guid> _surveyResponseRepository;
|
private readonly IRepository<SurveyResponse, Guid> _surveyResponseRepository;
|
||||||
private readonly IRepository<SurveyAnswer, Guid> _surveyAnswerRepository;
|
private readonly IRepository<SurveyAnswer, Guid> _surveyAnswerRepository;
|
||||||
|
|
@ -60,6 +61,7 @@ public class IntranetAppService : PlatformAppService, IIntranetAppService
|
||||||
IRepository<Department, Guid> departmentRepository,
|
IRepository<Department, Guid> departmentRepository,
|
||||||
IRepository<JobPosition, Guid> jobPositionRepository,
|
IRepository<JobPosition, Guid> jobPositionRepository,
|
||||||
IRepository<Announcement, Guid> announcementRepository,
|
IRepository<Announcement, Guid> announcementRepository,
|
||||||
|
IRepository<IntranetWidget, Guid> intranetWidgetRepository,
|
||||||
IRepository<Survey, Guid> surveyRepository,
|
IRepository<Survey, Guid> surveyRepository,
|
||||||
IRepository<SurveyResponse, Guid> surveyResponseRepository,
|
IRepository<SurveyResponse, Guid> surveyResponseRepository,
|
||||||
IRepository<SurveyAnswer, Guid> surveyAnswerRepository,
|
IRepository<SurveyAnswer, Guid> surveyAnswerRepository,
|
||||||
|
|
@ -83,6 +85,7 @@ public class IntranetAppService : PlatformAppService, IIntranetAppService
|
||||||
_departmentRepository = departmentRepository;
|
_departmentRepository = departmentRepository;
|
||||||
_jobPositionRepository = jobPositionRepository;
|
_jobPositionRepository = jobPositionRepository;
|
||||||
_announcementRepository = announcementRepository;
|
_announcementRepository = announcementRepository;
|
||||||
|
_intranetWidgetRepository = intranetWidgetRepository;
|
||||||
_surveyRepository = surveyRepository;
|
_surveyRepository = surveyRepository;
|
||||||
_surveyResponseRepository = surveyResponseRepository;
|
_surveyResponseRepository = surveyResponseRepository;
|
||||||
_surveyAnswerRepository = surveyAnswerRepository;
|
_surveyAnswerRepository = surveyAnswerRepository;
|
||||||
|
|
@ -107,9 +110,45 @@ public class IntranetAppService : PlatformAppService, IIntranetAppService
|
||||||
Announcements = await GetAnnouncementsAsync(), //3
|
Announcements = await GetAnnouncementsAsync(), //3
|
||||||
Surveys = await GetSurveysAsync(), //4
|
Surveys = await GetSurveysAsync(), //4
|
||||||
Events = await GetUpcomingEventsAsync(), //5
|
Events = await GetUpcomingEventsAsync(), //5
|
||||||
|
Widgets = await GetWidgetsAsync(), //6
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Aktif widget'lari sirali dondurur. Yetkisi olmayan widget sunucuda elenir; boylece
|
||||||
|
/// istemciye yalnizca gorulebilecek widget'lar gider.
|
||||||
|
/// </summary>
|
||||||
|
private async Task<List<IntranetWidgetDto>> GetWidgetsAsync()
|
||||||
|
{
|
||||||
|
var widgets = await _intranetWidgetRepository.GetListAsync(x => x.IsActive);
|
||||||
|
|
||||||
|
var result = new List<IntranetWidgetDto>();
|
||||||
|
foreach (var widget in widgets.OrderBy(x => x.Order).ThenBy(x => x.Code))
|
||||||
|
{
|
||||||
|
if (!widget.PermissionName.IsNullOrWhiteSpace() &&
|
||||||
|
!await AuthorizationService.IsGrantedAsync(widget.PermissionName))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Add(new IntranetWidgetDto
|
||||||
|
{
|
||||||
|
Id = widget.Id,
|
||||||
|
Code = widget.Code,
|
||||||
|
Name = widget.Name,
|
||||||
|
LabelKey = widget.LabelKey,
|
||||||
|
SourceType = widget.SourceType,
|
||||||
|
ComponentName = widget.ComponentName,
|
||||||
|
PermissionName = widget.PermissionName,
|
||||||
|
Column = widget.Column,
|
||||||
|
Order = widget.Order,
|
||||||
|
Props = widget.Props
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private Task<(Dictionary<Guid, string> DepartmentDict, Dictionary<Guid, JobPosition> JobPositionDict)> GetUserLookupDictionariesAsync()
|
private Task<(Dictionary<Guid, string> DepartmentDict, Dictionary<Guid, JobPosition> JobPositionDict)> GetUserLookupDictionariesAsync()
|
||||||
{
|
{
|
||||||
return _userLookupDictionariesTask ??= LoadUserLookupDictionariesAsync();
|
return _userLookupDictionariesTask ??= LoadUserLookupDictionariesAsync();
|
||||||
|
|
|
||||||
|
|
@ -17196,18 +17196,6 @@
|
||||||
"en": "Select at least one operation or turn generation off",
|
"en": "Select at least one operation or turn generation off",
|
||||||
"tr": "En az bir operasyon seçin ya da üretimi kapatın"
|
"tr": "En az bir operasyon seçin ya da üretimi kapatın"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "App.SqlQueryManager.ExistingCrudEndpoints",
|
|
||||||
"en": "Existing CRUD endpoints",
|
|
||||||
"tr": "Kayıtlı CRUD endpoint'leri"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"resourceName": "Platform",
|
|
||||||
"key": "App.SqlQueryManager.ExistingCrudEndpointsHint",
|
|
||||||
"en": "This table already has generated endpoints; deploying again regenerates them with the operations selected below.",
|
|
||||||
"tr": "Bu tablo için endpoint'ler daha önce üretilmiş; tekrar deploy edildiğinde aşağıda seçilen operasyonlarla yeniden üretilir."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"resourceName": "Platform",
|
"resourceName": "Platform",
|
||||||
"key": "App.SqlQueryManager.CrudEndpointsInactiveNote",
|
"key": "App.SqlQueryManager.CrudEndpointsInactiveNote",
|
||||||
|
|
@ -27737,6 +27725,78 @@
|
||||||
"key": "App.Agenda.Description",
|
"key": "App.Agenda.Description",
|
||||||
"en": "Agenda — the calendar screen. Table: Adm_T_Agenda · tenant scope · scheduler (calendar) layout.\nUsage: this screen is the reference for the scheduler layout. A recurring appointment request needs no code — the recurrence is expressed in the RecurrenceRule field.\nFields:\n• Text, Description → the title and the detail of the appointment\n• StartDate, EndDate → the start and end moments; the calendar places the record over them\n• AllDay → an all day record; the hour information is ignored\n• RecurrenceRule → the recurrence rule in iCalendar format, e.g. FREQ=WEEKLY;BYDAY=MO,WE. Written by the calendar's own repeat dialog\n• RecurrenceException → the excluded occurrences of the series; when a single occurrence is cancelled its date is added here rather than breaking the series\n• UserName → the owner of the record\nCaution: the calendar view is opened through the LayoutJson and SchedulerOptionJson of the list screen — there is no separate calendar route. When a recurring record is edited, decide whether the change applies to the whole series or to one occurrence; changing the rule shifts the past occurrences as well.",
|
"en": "Agenda — the calendar screen. Table: Adm_T_Agenda · tenant scope · scheduler (calendar) layout.\nUsage: this screen is the reference for the scheduler layout. A recurring appointment request needs no code — the recurrence is expressed in the RecurrenceRule field.\nFields:\n• Text, Description → the title and the detail of the appointment\n• StartDate, EndDate → the start and end moments; the calendar places the record over them\n• AllDay → an all day record; the hour information is ignored\n• RecurrenceRule → the recurrence rule in iCalendar format, e.g. FREQ=WEEKLY;BYDAY=MO,WE. Written by the calendar's own repeat dialog\n• RecurrenceException → the excluded occurrences of the series; when a single occurrence is cancelled its date is added here rather than breaking the series\n• UserName → the owner of the record\nCaution: the calendar view is opened through the LayoutJson and SchedulerOptionJson of the list screen — there is no separate calendar route. When a recurring record is edited, decide whether the change applies to the whole series or to one occurrence; changing the rule shifts the past occurrences as well.",
|
||||||
"tr": "Ajanda — takvim ekranı. Tablo: Adm_T_Agenda · tenant kapsamlı · scheduler (takvim) düzeni.\nKullanım: bu ekran scheduler düzeninin referansıdır. Tekrarlayan randevu talebi kod gerektirmez — tekrar bilgisi RecurrenceRule alanında ifade edilir.\nAlanlar:\n• Text, Description → randevunun başlığı ve ayrıntısı\n• StartDate, EndDate → başlangıç ve bitiş anları; takvim kaydı bunlara göre yerleştirir\n• AllDay → tüm gün süren kayıt; saat bilgisi dikkate alınmaz\n• RecurrenceRule → iCalendar biçiminde tekrar kuralı, örn. FREQ=WEEKLY;BYDAY=MO,WE. Takvimin kendi tekrar diyaloğu tarafından yazılır\n• RecurrenceException → serinin hariç tutulan tekrarları; tek bir tekrar iptal edildiğinde seri bozulmaz, tarihi buraya eklenir\n• UserName → kaydın sahibi\nDikkat: takvim görünümü liste ekranının LayoutJson ve SchedulerOptionJson tanımlarıyla açılır — ayrı bir takvim rotası yoktur. Tekrarlayan kayıt düzenlenirken değişikliğin tüm seriye mi tek tekrara mı uygulanacağına karar ver; kuralı değiştirmek geçmiş tekrarları da kaydırır."
|
"tr": "Ajanda — takvim ekranı. Tablo: Adm_T_Agenda · tenant kapsamlı · scheduler (takvim) düzeni.\nKullanım: bu ekran scheduler düzeninin referansıdır. Tekrarlayan randevu talebi kod gerektirmez — tekrar bilgisi RecurrenceRule alanında ifade edilir.\nAlanlar:\n• Text, Description → randevunun başlığı ve ayrıntısı\n• StartDate, EndDate → başlangıç ve bitiş anları; takvim kaydı bunlara göre yerleştirir\n• AllDay → tüm gün süren kayıt; saat bilgisi dikkate alınmaz\n• RecurrenceRule → iCalendar biçiminde tekrar kuralı, örn. FREQ=WEEKLY;BYDAY=MO,WE. Takvimin kendi tekrar diyaloğu tarafından yazılır\n• RecurrenceException → serinin hariç tutulan tekrarları; tek bir tekrar iptal edildiğinde seri bozulmaz, tarihi buraya eklenir\n• UserName → kaydın sahibi\nDikkat: takvim görünümü liste ekranının LayoutJson ve SchedulerOptionJson tanımlarıyla açılır — ayrı bir takvim rotası yoktur. Tekrarlayan kayıt düzenlenirken değişikliğin tüm seriye mi tek tekrara mı uygulanacağına karar ver; kuralı değiştirmek geçmiş tekrarları da kaydırır."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"en": "Intranet Widgets",
|
||||||
|
"tr": "Intranet Widget'ları"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.DeveloperKit.IntranetWidgets.Description",
|
||||||
|
"en": "Intranet Widgets — the widgets published on the intranet dashboard. Table: Adm_T_IntranetWidget · tenant scope (IsTenant = true) · list screen.\nUsage: which widget appears on the dashboard, in which column, in which order and with which permission is decided here. A widget coded into the application is published by adding a record whose Code matches the code registration; a component produced in the Component Manager is published by choosing it in ComponentName.\nFields:\n• Code → the unique key of the widget; for a builtin widget it is the registration key in the code\n• Name → the name shown on this screen\n• SourceType → Builtin (coded into the application) or Custom (a custom component)\n• ComponentName → the custom component to render; only for SourceType = Custom\n• Column, Order → where on the dashboard and in which order it is placed\n• LabelKey → the language key of the title shown on the dashboard\n• PermissionName → the permission required to see the widget; a widget left empty is open to every logged in user\n• Props → the props passed to the custom component, as a JSON object\n• IsActive → an inactive widget is not sent to the dashboard\nCaution: the Code of a builtin widget must match the registration in the code; a record with no counterpart renders nothing. The user's own layout (design mode) is kept per user — Reset returns to the order defined here.",
|
||||||
|
"tr": "Intranet Widget'ları — intranet dashboard'ında yayınlanan widget'lar. Tablo: Adm_T_IntranetWidget · tenant kapsamlı (IsTenant = true) · liste ekranı.\nKullanım: dashboard'da hangi widget'ın, hangi kolonda, hangi sırada ve hangi yetkiyle görüneceği buradan belirlenir. Uygulamaya kodlanmış bir widget, Code alanı koddaki kayıtla eşleşen bir satır eklenerek yayınlanır; Component Manager'da üretilmiş bir bileşen ise ComponentName alanından seçilerek yayınlanır.\nAlanlar:\n• Code → widget'ın tekil anahtarı; builtin widget'ta koddaki kayıt anahtarıdır\n• Name → bu ekranda görünen ad\n• SourceType → Builtin (uygulamaya kodlanmış) veya Custom (özel bileşen)\n• ComponentName → basılacak özel bileşen; yalnızca SourceType = Custom için\n• Column, Order → dashboard'da hangi kolona ve hangi sıraya yerleşeceği\n• LabelKey → dashboard'da gösterilen başlığın dil anahtarı\n• PermissionName → widget'ı görmek için gereken yetki; boş bırakılan widget oturum açmış herkese açıktır\n• Props → özel bileşene geçilecek prop'lar; JSON nesnesi\n• IsActive → pasif widget dashboard'a gönderilmez\nDikkat: builtin widget'ın Code değeri koddaki kayıtla birebir aynı olmalıdır; karşılığı olmayan kayıt hiçbir şey basmaz. Kullanıcının kendi yerleşimi (tasarım modu) kullanıcı bazında tutulur — Reset buradaki sıraya döner."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Code",
|
||||||
|
"en": "Code",
|
||||||
|
"tr": "Kod"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.LabelKey",
|
||||||
|
"en": "Label Key",
|
||||||
|
"tr": "Başlık Anahtarı"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.SourceType",
|
||||||
|
"en": "Source Type",
|
||||||
|
"tr": "Kaynak Türü"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.ComponentName",
|
||||||
|
"en": "Component",
|
||||||
|
"tr": "Bileşen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.PermissionName",
|
||||||
|
"en": "Permission",
|
||||||
|
"tr": "Yetki"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.Listform.ListformField.Props",
|
||||||
|
"en": "Props",
|
||||||
|
"tr": "Prop’lar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.StaticLookup.Builtin",
|
||||||
|
"en": "Builtin",
|
||||||
|
"tr": "Yerleşik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.StaticLookup.Left",
|
||||||
|
"en": "Left",
|
||||||
|
"tr": "Sol"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.StaticLookup.Center",
|
||||||
|
"en": "Center",
|
||||||
|
"tr": "Orta"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"resourceName": "Platform",
|
||||||
|
"key": "App.StaticLookup.Right",
|
||||||
|
"en": "Right",
|
||||||
|
"tr": "Sağ"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6480,5 +6480,5 @@ public class ListFormSeeder_Administration : IDataSeedContributor, ITransientDep
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10096,5 +10096,312 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region IntranetWidget
|
||||||
|
listFormName = AppCodes.DeveloperKits.IntranetWidgets;
|
||||||
|
if (!await _listFormRepository.AnyAsync(a => a.ListFormCode == listFormName))
|
||||||
|
{
|
||||||
|
var listForm = await _listFormRepository.InsertAsync(
|
||||||
|
new ListForm()
|
||||||
|
{
|
||||||
|
ListFormType = ListFormTypeEnum.List,
|
||||||
|
PageSize = 10,
|
||||||
|
ExportJson = DefaultExportJson,
|
||||||
|
IsSubForm = false,
|
||||||
|
ShowNote = false,
|
||||||
|
LayoutJson = DefaultLayoutJson(),
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
ListFormCode = listFormName,
|
||||||
|
Name = listFormName,
|
||||||
|
Title = listFormName,
|
||||||
|
DataSourceCode = SeedConsts.DataSources.DefaultCode,
|
||||||
|
IsTenant = true,
|
||||||
|
IsBranch = false,
|
||||||
|
IsOrganizationUnit = false,
|
||||||
|
Description = $"{listFormName}.Description",
|
||||||
|
SelectCommandType = SelectCommandTypeEnum.Table,
|
||||||
|
SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.IntranetWidget)),
|
||||||
|
KeyFieldName = "Id",
|
||||||
|
KeyFieldDbSourceType = DbType.Guid,
|
||||||
|
DefaultFilter = DefaultFilterJson,
|
||||||
|
SortMode = GridOptions.SortModeMultiple,
|
||||||
|
FilterRowJson = DefaultFilterRowJson(),
|
||||||
|
HeaderFilterJson = DefaultHeaderFilterJson(),
|
||||||
|
SearchPanelJson = DefaultSearchPanelJson(),
|
||||||
|
GroupPanelJson = DefaultGroupPanelJson(),
|
||||||
|
SelectionJson = DefaultSelectionSingleJson,
|
||||||
|
ColumnOptionJson = DefaultColumnOptionJson(),
|
||||||
|
PermissionJson = DefaultPermissionJson(listFormName),
|
||||||
|
DeleteCommand = DefaultDeleteCommand(nameof(TableNameEnum.IntranetWidget)),
|
||||||
|
DeleteFieldsDefaultValueJson = DefaultDeleteFieldsDefaultValueJson(),
|
||||||
|
PagerOptionJson = DefaultPagerOptionJson,
|
||||||
|
InsertFieldsDefaultValueJson = DefaultInsertFieldsDefaultValueJson(),
|
||||||
|
EditingOptionJson = DefaultEditingOptionJson(listFormName, 850, 560, true, true, true, true, false),
|
||||||
|
FormFieldsDefaultValueJson = JsonSerializer.Serialize(new FieldsDefaultValue[] {
|
||||||
|
new() { FieldName = "IsActive", FieldDbType = DbType.Boolean, Value = "true", CustomValueType = FieldCustomValueTypeEnum.Value }
|
||||||
|
}),
|
||||||
|
EditingFormJson = JsonSerializer.Serialize(new List<EditingFormDto>
|
||||||
|
{
|
||||||
|
new() { Order = 1, ColCount = 2, ColSpan = 2, ItemType = "group" },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
#region IntranetWidget Fields
|
||||||
|
await _listFormFieldRepository.InsertManyAsync([
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Guid,
|
||||||
|
FieldName = "Id",
|
||||||
|
CaptionName = "App.Listform.ListformField.Id",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 1,
|
||||||
|
Visible = false,
|
||||||
|
IsActive = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "Code",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 1,
|
||||||
|
EditorType2 = EditorTypes.dxTextBox,
|
||||||
|
ColSpan = 1,
|
||||||
|
CaptionName = "App.Listform.ListformField.Code",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 2,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
AllowSearch = true,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "Name",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 2,
|
||||||
|
EditorType2 = EditorTypes.dxTextBox,
|
||||||
|
ColSpan = 1,
|
||||||
|
CaptionName = "App.Listform.ListformField.Name",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 3,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
AllowSearch = true,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Int32,
|
||||||
|
FieldName = "SourceType",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 3,
|
||||||
|
EditorType2 = EditorTypes.dxSelectBox,
|
||||||
|
ColSpan = 1,
|
||||||
|
CaptionName = "App.Listform.ListformField.SourceType",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 4,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
AllowSearch = true,
|
||||||
|
LookupJson = JsonSerializer.Serialize(new LookupDto
|
||||||
|
{
|
||||||
|
DataSourceType = UiLookupDataSourceTypeEnum.StaticData,
|
||||||
|
DisplayExpr = "name",
|
||||||
|
ValueExpr = "key",
|
||||||
|
LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] {
|
||||||
|
new () { Key = (int)IntranetWidgetSourceType.Builtin, Name = "App.StaticLookup.Builtin" },
|
||||||
|
new () { Key = (int)IntranetWidgetSourceType.Custom, Name = "App.StaticLookup.Custom" },
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "ComponentName",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 4,
|
||||||
|
EditorType2 = EditorTypes.dxSelectBox,
|
||||||
|
ColSpan = 1,
|
||||||
|
EditorOptions = EditorOptions.ShowClearButton(),
|
||||||
|
CaptionName = "App.Listform.ListformField.ComponentName",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 5,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
AllowSearch = true,
|
||||||
|
LookupJson = JsonSerializer.Serialize(new LookupDto
|
||||||
|
{
|
||||||
|
DataSourceType = UiLookupDataSourceTypeEnum.Query,
|
||||||
|
DisplayExpr = "Name",
|
||||||
|
ValueExpr = "Key",
|
||||||
|
LookupQuery = LookupQueryValues.CustomComponentValues,
|
||||||
|
}),
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Int32,
|
||||||
|
FieldName = "Column",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 5,
|
||||||
|
EditorType2 = EditorTypes.dxSelectBox,
|
||||||
|
ColSpan = 1,
|
||||||
|
CaptionName = "App.Listform.ListformField.Column",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 6,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
AllowSearch = true,
|
||||||
|
SortIndex = 1,
|
||||||
|
SortDirection = GridColumnOptions.SortOrderAsc,
|
||||||
|
LookupJson = JsonSerializer.Serialize(new LookupDto
|
||||||
|
{
|
||||||
|
DataSourceType = UiLookupDataSourceTypeEnum.StaticData,
|
||||||
|
DisplayExpr = "name",
|
||||||
|
ValueExpr = "key",
|
||||||
|
LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] {
|
||||||
|
new () { Key = (int)IntranetWidgetColumn.Left, Name = "App.StaticLookup.Left" },
|
||||||
|
new () { Key = (int)IntranetWidgetColumn.Center, Name = "App.StaticLookup.Center" },
|
||||||
|
new () { Key = (int)IntranetWidgetColumn.Right, Name = "App.StaticLookup.Right" },
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Int32,
|
||||||
|
FieldName = "Order",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 6,
|
||||||
|
EditorType2 = EditorTypes.dxNumberBox,
|
||||||
|
ColSpan = 1,
|
||||||
|
EditorOptions = EditorOptions.Number(0),
|
||||||
|
CaptionName = "App.Listform.ListformField.Order",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 7,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
AllowSearch = true,
|
||||||
|
SortIndex = 2,
|
||||||
|
SortDirection = GridColumnOptions.SortOrderAsc,
|
||||||
|
ValidationRuleJson = DefaultValidationRuleRequiredJson,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "LabelKey",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 7,
|
||||||
|
EditorType2 = EditorTypes.dxTextBox,
|
||||||
|
ColSpan = 1,
|
||||||
|
CaptionName = "App.Listform.ListformField.LabelKey",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 8,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "PermissionName",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 8,
|
||||||
|
EditorType2 = EditorTypes.dxSelectBox,
|
||||||
|
ColSpan = 1,
|
||||||
|
EditorOptions = EditorOptions.ShowClearButton(),
|
||||||
|
CaptionName = "App.Listform.ListformField.PermissionName",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 9,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
AllowSearch = true,
|
||||||
|
LookupJson = JsonSerializer.Serialize(new LookupDto
|
||||||
|
{
|
||||||
|
DataSourceType = UiLookupDataSourceTypeEnum.Query,
|
||||||
|
DisplayExpr = "Name",
|
||||||
|
ValueExpr = "Key",
|
||||||
|
LookupQuery = LookupQueryValues.PermissionNameValues,
|
||||||
|
}),
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.Boolean,
|
||||||
|
FieldName = "IsActive",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 9,
|
||||||
|
EditorType2 = EditorTypes.dxCheckBox,
|
||||||
|
ColSpan = 1,
|
||||||
|
CaptionName = "App.Listform.ListformField.IsActive",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 10,
|
||||||
|
Visible = true,
|
||||||
|
IsActive = true,
|
||||||
|
AllowSearch = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
},
|
||||||
|
new() {
|
||||||
|
ListFormCode = listForm.ListFormCode,
|
||||||
|
CultureName = LanguageCodes.En,
|
||||||
|
SourceDbType = DbType.String,
|
||||||
|
FieldName = "Props",
|
||||||
|
EditGroupOrderNo = 1,
|
||||||
|
EditOrderNo = 10,
|
||||||
|
EditorType2 = EditorTypes.dxTextArea,
|
||||||
|
ColSpan = 2,
|
||||||
|
EditorOptions = EditorOptions.Multiline(120),
|
||||||
|
CaptionName = "App.Listform.ListformField.Props",
|
||||||
|
Width = 0,
|
||||||
|
ListOrderNo = 11,
|
||||||
|
Visible = false,
|
||||||
|
IsActive = true,
|
||||||
|
ColumnCustomizationJson = DefaultColumnCustomizationJson,
|
||||||
|
PermissionJson = DefaultFieldPermissionJson(listForm.Name),
|
||||||
|
PivotSettingsJson = DefaultPivotSettingsJson
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -984,6 +984,17 @@
|
||||||
"IsDisabled": false,
|
"IsDisabled": false,
|
||||||
"ModuleId": "Sas"
|
"ModuleId": "Sas"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ParentCode": "App.DeveloperKit",
|
||||||
|
"Code": "App.Files",
|
||||||
|
"DisplayName": "App.Files",
|
||||||
|
"Order": 2,
|
||||||
|
"Url": "/admin/files",
|
||||||
|
"Icon": "FcFolder",
|
||||||
|
"RequiredPermissionName": "App.Files",
|
||||||
|
"IsDisabled": false,
|
||||||
|
"ModuleId": "Sas"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ParentCode": "App.DeveloperKit",
|
"ParentCode": "App.DeveloperKit",
|
||||||
"Code": "App.DeveloperKit.CustomEndpoints",
|
"Code": "App.DeveloperKit.CustomEndpoints",
|
||||||
|
|
@ -1028,11 +1039,22 @@
|
||||||
"IsDisabled": false,
|
"IsDisabled": false,
|
||||||
"ModuleId": "Sas"
|
"ModuleId": "Sas"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ParentCode": "App.DeveloperKit",
|
||||||
|
"Code": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"DisplayName": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"Order": 7,
|
||||||
|
"Url": "/admin/list/App.DeveloperKit.IntranetWidgets",
|
||||||
|
"Icon": "FcAdvertising",
|
||||||
|
"RequiredPermissionName": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"IsDisabled": false,
|
||||||
|
"ModuleId": "Sas"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ParentCode": "App.DeveloperKit",
|
"ParentCode": "App.DeveloperKit",
|
||||||
"Code": "App.Listforms.WizardManager",
|
"Code": "App.Listforms.WizardManager",
|
||||||
"DisplayName": "App.Listforms.WizardManager",
|
"DisplayName": "App.Listforms.WizardManager",
|
||||||
"Order": 6,
|
"Order": 8,
|
||||||
"Url": "/admin/listform/wizardManager",
|
"Url": "/admin/listform/wizardManager",
|
||||||
"Icon": "FcFlashAuto",
|
"Icon": "FcFlashAuto",
|
||||||
"RequiredPermissionName": "App.Listforms.Wizard",
|
"RequiredPermissionName": "App.Listforms.Wizard",
|
||||||
|
|
@ -1413,22 +1435,11 @@
|
||||||
"IsDisabled": false,
|
"IsDisabled": false,
|
||||||
"ModuleId": "Adm"
|
"ModuleId": "Adm"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ParentCode": "App.Administration",
|
|
||||||
"Code": "App.Files",
|
|
||||||
"DisplayName": "App.Files",
|
|
||||||
"Order": 11,
|
|
||||||
"Url": "/admin/files",
|
|
||||||
"Icon": "FcFolder",
|
|
||||||
"RequiredPermissionName": "App.Files",
|
|
||||||
"IsDisabled": false,
|
|
||||||
"ModuleId": "Adm"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ParentCode": "App.Administration",
|
"ParentCode": "App.Administration",
|
||||||
"Code": "App.Forum",
|
"Code": "App.Forum",
|
||||||
"DisplayName": "App.Forum",
|
"DisplayName": "App.Forum",
|
||||||
"Order": 12,
|
"Order": 11,
|
||||||
"Url": "/admin/forum",
|
"Url": "/admin/forum",
|
||||||
"Icon": "FcLink",
|
"Icon": "FcLink",
|
||||||
"RequiredPermissionName": "App.ForumManagement.Publish",
|
"RequiredPermissionName": "App.ForumManagement.Publish",
|
||||||
|
|
|
||||||
|
|
@ -2262,6 +2262,51 @@
|
||||||
"MultiTenancySide": 2,
|
"MultiTenancySide": 2,
|
||||||
"Modules": "Sas|Adm"
|
"Modules": "Sas|Adm"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Files",
|
||||||
|
"ParentName": null,
|
||||||
|
"DisplayName": "App.Files",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Files.Create",
|
||||||
|
"ParentName": "App.Files",
|
||||||
|
"DisplayName": "App.Platform.Create",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Files.Update",
|
||||||
|
"ParentName": "App.Files",
|
||||||
|
"DisplayName": "App.Platform.Update",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Files.Delete",
|
||||||
|
"ParentName": "App.Files",
|
||||||
|
"DisplayName": "App.Platform.Delete",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Administration",
|
||||||
|
"Name": "App.Files.Widget",
|
||||||
|
"ParentName": "App.Files",
|
||||||
|
"DisplayName": "App.Platform.Widget",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Saas",
|
"GroupName": "App.Saas",
|
||||||
"Name": "App.DeveloperKit.CustomEndpoints",
|
"Name": "App.DeveloperKit.CustomEndpoints",
|
||||||
|
|
@ -2460,6 +2505,60 @@
|
||||||
"MultiTenancySide": 2,
|
"MultiTenancySide": 2,
|
||||||
"Modules": "Sas|Adm"
|
"Modules": "Sas|Adm"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Saas",
|
||||||
|
"Name": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"ParentName": "App.DeveloperKit",
|
||||||
|
"DisplayName": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Saas",
|
||||||
|
"Name": "App.DeveloperKit.IntranetWidgets.Create",
|
||||||
|
"ParentName": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"DisplayName": "App.Platform.Create",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Saas",
|
||||||
|
"Name": "App.DeveloperKit.IntranetWidgets.Update",
|
||||||
|
"ParentName": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"DisplayName": "App.Platform.Update",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Saas",
|
||||||
|
"Name": "App.DeveloperKit.IntranetWidgets.Delete",
|
||||||
|
"ParentName": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"DisplayName": "App.Platform.Delete",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Saas",
|
||||||
|
"Name": "App.DeveloperKit.IntranetWidgets.Export",
|
||||||
|
"ParentName": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"DisplayName": "Export",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.Saas",
|
||||||
|
"Name": "App.DeveloperKit.IntranetWidgets.Import",
|
||||||
|
"ParentName": "App.DeveloperKit.IntranetWidgets",
|
||||||
|
"DisplayName": "Import",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 2,
|
||||||
|
"Modules": "Sas|Adm"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Saas",
|
"GroupName": "App.Saas",
|
||||||
"Name": "App.Listforms.Listform",
|
"Name": "App.Listforms.Listform",
|
||||||
|
|
@ -4935,51 +5034,6 @@
|
||||||
"MultiTenancySide": 3,
|
"MultiTenancySide": 3,
|
||||||
"Modules": "Sas|Adm"
|
"Modules": "Sas|Adm"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"GroupName": "App.Administration",
|
|
||||||
"Name": "App.Files",
|
|
||||||
"ParentName": null,
|
|
||||||
"DisplayName": "App.Files",
|
|
||||||
"IsEnabled": true,
|
|
||||||
"MultiTenancySide": 3,
|
|
||||||
"Modules": "Sas|Adm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"GroupName": "App.Administration",
|
|
||||||
"Name": "App.Files.Create",
|
|
||||||
"ParentName": "App.Files",
|
|
||||||
"DisplayName": "App.Platform.Create",
|
|
||||||
"IsEnabled": true,
|
|
||||||
"MultiTenancySide": 3,
|
|
||||||
"Modules": "Sas|Adm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"GroupName": "App.Administration",
|
|
||||||
"Name": "App.Files.Update",
|
|
||||||
"ParentName": "App.Files",
|
|
||||||
"DisplayName": "App.Platform.Update",
|
|
||||||
"IsEnabled": true,
|
|
||||||
"MultiTenancySide": 3,
|
|
||||||
"Modules": "Sas|Adm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"GroupName": "App.Administration",
|
|
||||||
"Name": "App.Files.Delete",
|
|
||||||
"ParentName": "App.Files",
|
|
||||||
"DisplayName": "App.Platform.Delete",
|
|
||||||
"IsEnabled": true,
|
|
||||||
"MultiTenancySide": 3,
|
|
||||||
"Modules": "Sas|Adm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"GroupName": "App.Administration",
|
|
||||||
"Name": "App.Files.Widget",
|
|
||||||
"ParentName": "App.Files",
|
|
||||||
"DisplayName": "App.Platform.Widget",
|
|
||||||
"IsEnabled": true,
|
|
||||||
"MultiTenancySide": 3,
|
|
||||||
"Modules": "Sas|Adm"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"GroupName": "App.Administration",
|
"GroupName": "App.Administration",
|
||||||
"Name": "App.ForumManagement.Publish",
|
"Name": "App.ForumManagement.Publish",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
namespace Sozsoft.Platform.Enums;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Intranet dashboard widget'inin nereden render edildigini belirler.
|
||||||
|
/// </summary>
|
||||||
|
public enum IntranetWidgetSourceType
|
||||||
|
{
|
||||||
|
/// <summary>Uygulama icine kodlanmis widget; <c>Code</c> alani koddaki kayit anahtaridir.</summary>
|
||||||
|
Builtin = 0,
|
||||||
|
|
||||||
|
/// <summary>DeveloperKit'te uretilmis bir CustomComponent; <c>ComponentName</c> alani ile eslesir.</summary>
|
||||||
|
Custom = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Dashboard'daki üç kolondan hangisinde yayinlanacagi.</summary>
|
||||||
|
public enum IntranetWidgetColumn
|
||||||
|
{
|
||||||
|
Left = 0,
|
||||||
|
Center = 1,
|
||||||
|
Right = 2,
|
||||||
|
}
|
||||||
|
|
@ -88,6 +88,7 @@ public enum TableNameEnum
|
||||||
Event,
|
Event,
|
||||||
EventPhoto,
|
EventPhoto,
|
||||||
EventComment,
|
EventComment,
|
||||||
|
IntranetWidget,
|
||||||
MessengerConversation,
|
MessengerConversation,
|
||||||
MessengerConversationMessage,
|
MessengerConversationMessage,
|
||||||
Videoroom,
|
Videoroom,
|
||||||
|
|
|
||||||
|
|
@ -476,6 +476,9 @@ public static class PlatformConsts
|
||||||
|
|
||||||
public const string CustomEndpoints = Default + ".CustomEndpoints";
|
public const string CustomEndpoints = Default + ".CustomEndpoints";
|
||||||
|
|
||||||
|
/// <summary>Intranet dashboard'inda yayinlanan widget tanimlarinin ListForm ekrani.</summary>
|
||||||
|
public const string IntranetWidgets = Default + ".IntranetWidgets";
|
||||||
|
|
||||||
// Coarse gate for calling a dynamic endpoint through the dispatcher.
|
// Coarse gate for calling a dynamic endpoint through the dispatcher.
|
||||||
// The per endpoint User/Role/Global rules are checked on top of this.
|
// The per endpoint User/Role/Global rules are checked on top of this.
|
||||||
// Named Put/Remove because Update/Delete already gate editing the
|
// Named Put/Remove because Update/Delete already gate editing the
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ public static class TableNameResolver
|
||||||
{ nameof(TableNameEnum.Event), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
{ nameof(TableNameEnum.Event), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
||||||
{ nameof(TableNameEnum.EventPhoto), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
{ nameof(TableNameEnum.EventPhoto), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
||||||
{ nameof(TableNameEnum.EventComment), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
{ nameof(TableNameEnum.EventComment), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
||||||
|
{ nameof(TableNameEnum.IntranetWidget), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
||||||
{ nameof(TableNameEnum.MessengerConversation), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
{ nameof(TableNameEnum.MessengerConversation), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
||||||
{ nameof(TableNameEnum.MessengerConversationMessage), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
{ nameof(TableNameEnum.MessengerConversationMessage), (TablePrefix.TenantByName, MenuPrefix.Administration) },
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -471,6 +471,7 @@ public static class SeedConsts
|
||||||
public const string Default = Prefix.App + ".DeveloperKit";
|
public const string Default = Prefix.App + ".DeveloperKit";
|
||||||
|
|
||||||
public const string CustomEndpoints = Default + ".CustomEndpoints";
|
public const string CustomEndpoints = Default + ".CustomEndpoints";
|
||||||
|
public const string IntranetWidgets = Default + ".IntranetWidgets";
|
||||||
}
|
}
|
||||||
|
|
||||||
public const string Forum = Prefix.App + ".Forum";
|
public const string Forum = Prefix.App + ".Forum";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
using Sozsoft.Platform.Enums;
|
||||||
|
using Volo.Abp.Domain.Entities.Auditing;
|
||||||
|
using Volo.Abp.MultiTenancy;
|
||||||
|
|
||||||
|
namespace Sozsoft.Platform.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Intranet dashboard'inda yayinlanan widget tanimi. Widget'in kendisi ya uygulamaya kodlanmistir
|
||||||
|
/// (<see cref="IntranetWidgetSourceType.Builtin"/>, <see cref="Code"/> koddaki kayit anahtaridir)
|
||||||
|
/// ya da DeveloperKit'te uretilmis bir CustomComponent'tir
|
||||||
|
/// (<see cref="IntranetWidgetSourceType.Custom"/>, <see cref="ComponentName"/> ile eslesir).
|
||||||
|
/// Kolon, sira, yetki ve gorunurluk bu kayittan gelir; kodda tutulmaz.
|
||||||
|
/// </summary>
|
||||||
|
public class IntranetWidget : FullAuditedEntity<Guid>, IMultiTenant
|
||||||
|
{
|
||||||
|
public Guid? TenantId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Widget'in tenant icinde tekil anahtari; Builtin widget'larda koddaki kayit anahtaridir.</summary>
|
||||||
|
public string Code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Yonetim ekranlarinda gorunen ad.</summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Dashboard'da gosterilen basligin dil anahtari.</summary>
|
||||||
|
public string LabelKey { get; set; }
|
||||||
|
|
||||||
|
public IntranetWidgetSourceType SourceType { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Custom widget'in CustomComponent adi; Builtin widget'ta bostur.</summary>
|
||||||
|
public string ComponentName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Widget'i gormek icin gereken yetki kodu; bos ise herkese aciktir.</summary>
|
||||||
|
public string PermissionName { get; set; }
|
||||||
|
|
||||||
|
public IntranetWidgetColumn Column { get; set; }
|
||||||
|
|
||||||
|
public int Order { get; set; }
|
||||||
|
|
||||||
|
/// <summary>Custom widget'a gecilecek prop'lar; JSON nesnesi olarak tutulur.</summary>
|
||||||
|
public string Props { get; set; }
|
||||||
|
|
||||||
|
public bool IsActive { get; set; } = true;
|
||||||
|
}
|
||||||
|
|
@ -126,6 +126,8 @@ public class PlatformDbContext :
|
||||||
public DbSet<MessengerConversation> MessengerConversations { get; set; }
|
public DbSet<MessengerConversation> MessengerConversations { get; set; }
|
||||||
public DbSet<MessengerConversationMessage> MessengerConversationMessages { get; set; }
|
public DbSet<MessengerConversationMessage> MessengerConversationMessages { get; set; }
|
||||||
|
|
||||||
|
public DbSet<IntranetWidget> IntranetWidgets { get; set; }
|
||||||
|
|
||||||
public DbSet<Announcement> Announcements { get; set; }
|
public DbSet<Announcement> Announcements { get; set; }
|
||||||
public DbSet<AnnouncementComment> AnnouncementComments { get; set; }
|
public DbSet<AnnouncementComment> AnnouncementComments { get; set; }
|
||||||
public DbSet<AnnouncementLike> AnnouncementLikes { get; set; }
|
public DbSet<AnnouncementLike> AnnouncementLikes { get; set; }
|
||||||
|
|
@ -1201,6 +1203,22 @@ public class PlatformDbContext :
|
||||||
b.HasIndex(x => new { x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
|
b.HasIndex(x => new { x.Name }).IsUnique().HasFilter("[IsDeleted] = 0");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
builder.Entity<IntranetWidget>(b =>
|
||||||
|
{
|
||||||
|
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.IntranetWidget)), Prefix.DbSchema);
|
||||||
|
b.ConfigureByConvention();
|
||||||
|
|
||||||
|
b.Property(x => x.Code).IsRequired().HasMaxLength(64);
|
||||||
|
b.Property(x => x.Name).IsRequired().HasMaxLength(128);
|
||||||
|
b.Property(x => x.LabelKey).HasMaxLength(256);
|
||||||
|
b.Property(x => x.ComponentName).HasMaxLength(256);
|
||||||
|
b.Property(x => x.PermissionName).HasMaxLength(256);
|
||||||
|
b.Property(x => x.Props).HasColumnType("nvarchar(max)");
|
||||||
|
b.Property(x => x.IsActive).HasDefaultValue(true);
|
||||||
|
|
||||||
|
b.HasIndex(x => new { x.TenantId, x.Code }).IsUnique().HasFilter("[IsDeleted] = 0");
|
||||||
|
});
|
||||||
|
|
||||||
builder.Entity<Announcement>(b =>
|
builder.Entity<Announcement>(b =>
|
||||||
{
|
{
|
||||||
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.Announcement)), Prefix.DbSchema);
|
b.ToTable(TableNameResolver.GetFullTableName(nameof(TableNameEnum.Announcement)), Prefix.DbSchema);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
|
||||||
namespace Sozsoft.Platform.Migrations
|
namespace Sozsoft.Platform.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(PlatformDbContext))]
|
[DbContext(typeof(PlatformDbContext))]
|
||||||
[Migration("20260901075908_Initial")]
|
[Migration("20260903062758_Initial")]
|
||||||
partial class Initial
|
partial class Initial
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -3105,6 +3105,93 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.ToTable("Sas_H_InstallmentOption", (string)null);
|
b.ToTable("Sas_H_InstallmentOption", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Sozsoft.Platform.Entities.IntranetWidget", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
|
b.Property<string>("Code")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("nvarchar(64)");
|
||||||
|
|
||||||
|
b.Property<int>("Column")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("ComponentName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("datetime2")
|
||||||
|
.HasColumnName("CreationTime");
|
||||||
|
|
||||||
|
b.Property<Guid?>("CreatorId")
|
||||||
|
.HasColumnType("uniqueidentifier")
|
||||||
|
.HasColumnName("CreatorId");
|
||||||
|
|
||||||
|
b.Property<Guid?>("DeleterId")
|
||||||
|
.HasColumnType("uniqueidentifier")
|
||||||
|
.HasColumnName("DeleterId");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("DeletionTime")
|
||||||
|
.HasColumnType("datetime2")
|
||||||
|
.HasColumnName("DeletionTime");
|
||||||
|
|
||||||
|
b.Property<bool>("IsActive")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(true);
|
||||||
|
|
||||||
|
b.Property<bool>("IsDeleted")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(false)
|
||||||
|
.HasColumnName("IsDeleted");
|
||||||
|
|
||||||
|
b.Property<string>("LabelKey")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastModificationTime")
|
||||||
|
.HasColumnType("datetime2")
|
||||||
|
.HasColumnName("LastModificationTime");
|
||||||
|
|
||||||
|
b.Property<Guid?>("LastModifierId")
|
||||||
|
.HasColumnType("uniqueidentifier")
|
||||||
|
.HasColumnName("LastModifierId");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
||||||
|
b.Property<int>("Order")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("PermissionName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<string>("Props")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int>("SourceType")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<Guid?>("TenantId")
|
||||||
|
.HasColumnType("uniqueidentifier")
|
||||||
|
.HasColumnName("TenantId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("TenantId", "Code")
|
||||||
|
.IsUnique()
|
||||||
|
.HasFilter("[IsDeleted] = 0");
|
||||||
|
|
||||||
|
b.ToTable("Adm_T_IntranetWidget", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Sozsoft.Platform.Entities.IpRestriction", b =>
|
modelBuilder.Entity("Sozsoft.Platform.Entities.IpRestriction", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
|
|
@ -601,6 +601,35 @@ namespace Sozsoft.Platform.Migrations
|
||||||
table.PrimaryKey("PK_Adm_T_EventType", x => x.Id);
|
table.PrimaryKey("PK_Adm_T_EventType", x => x.Id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Adm_T_IntranetWidget",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||||
|
TenantId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
|
Code = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: false),
|
||||||
|
Name = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: false),
|
||||||
|
LabelKey = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
||||||
|
SourceType = table.Column<int>(type: "int", nullable: false),
|
||||||
|
ComponentName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
||||||
|
PermissionName = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
|
||||||
|
Column = table.Column<int>(type: "int", nullable: false),
|
||||||
|
Order = table.Column<int>(type: "int", nullable: false),
|
||||||
|
Props = table.Column<string>(type: "nvarchar(max)", nullable: true),
|
||||||
|
IsActive = table.Column<bool>(type: "bit", nullable: false, defaultValue: true),
|
||||||
|
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||||
|
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
|
LastModificationTime = table.Column<DateTime>(type: "datetime2", nullable: true),
|
||||||
|
LastModifierId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
|
IsDeleted = table.Column<bool>(type: "bit", nullable: false, defaultValue: false),
|
||||||
|
DeleterId = table.Column<Guid>(type: "uniqueidentifier", nullable: true),
|
||||||
|
DeletionTime = table.Column<DateTime>(type: "datetime2", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Adm_T_IntranetWidget", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "Adm_T_IpRestriction",
|
name: "Adm_T_IpRestriction",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
|
|
@ -3838,6 +3867,13 @@ namespace Sozsoft.Platform.Migrations
|
||||||
unique: true,
|
unique: true,
|
||||||
filter: "[IsDeleted] = 0");
|
filter: "[IsDeleted] = 0");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Adm_T_IntranetWidget_TenantId_Code",
|
||||||
|
table: "Adm_T_IntranetWidget",
|
||||||
|
columns: new[] { "TenantId", "Code" },
|
||||||
|
unique: true,
|
||||||
|
filter: "[IsDeleted] = 0");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_Adm_T_IpRestriction_TenantId_ResourceType_ResourceId_IP",
|
name: "IX_Adm_T_IpRestriction_TenantId_ResourceType_ResourceId_IP",
|
||||||
table: "Adm_T_IpRestriction",
|
table: "Adm_T_IpRestriction",
|
||||||
|
|
@ -4465,6 +4501,9 @@ namespace Sozsoft.Platform.Migrations
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Adm_T_EventLike");
|
name: "Adm_T_EventLike");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Adm_T_IntranetWidget");
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "Adm_T_IpRestriction");
|
name: "Adm_T_IpRestriction");
|
||||||
|
|
||||||
|
|
@ -3102,6 +3102,93 @@ namespace Sozsoft.Platform.Migrations
|
||||||
b.ToTable("Sas_H_InstallmentOption", (string)null);
|
b.ToTable("Sas_H_InstallmentOption", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Sozsoft.Platform.Entities.IntranetWidget", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("Id")
|
||||||
|
.HasColumnType("uniqueidentifier");
|
||||||
|
|
||||||
|
b.Property<string>("Code")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("nvarchar(64)");
|
||||||
|
|
||||||
|
b.Property<int>("Column")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("ComponentName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationTime")
|
||||||
|
.HasColumnType("datetime2")
|
||||||
|
.HasColumnName("CreationTime");
|
||||||
|
|
||||||
|
b.Property<Guid?>("CreatorId")
|
||||||
|
.HasColumnType("uniqueidentifier")
|
||||||
|
.HasColumnName("CreatorId");
|
||||||
|
|
||||||
|
b.Property<Guid?>("DeleterId")
|
||||||
|
.HasColumnType("uniqueidentifier")
|
||||||
|
.HasColumnName("DeleterId");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("DeletionTime")
|
||||||
|
.HasColumnType("datetime2")
|
||||||
|
.HasColumnName("DeletionTime");
|
||||||
|
|
||||||
|
b.Property<bool>("IsActive")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(true);
|
||||||
|
|
||||||
|
b.Property<bool>("IsDeleted")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bit")
|
||||||
|
.HasDefaultValue(false)
|
||||||
|
.HasColumnName("IsDeleted");
|
||||||
|
|
||||||
|
b.Property<string>("LabelKey")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("LastModificationTime")
|
||||||
|
.HasColumnType("datetime2")
|
||||||
|
.HasColumnName("LastModificationTime");
|
||||||
|
|
||||||
|
b.Property<Guid?>("LastModifierId")
|
||||||
|
.HasColumnType("uniqueidentifier")
|
||||||
|
.HasColumnName("LastModifierId");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(128)
|
||||||
|
.HasColumnType("nvarchar(128)");
|
||||||
|
|
||||||
|
b.Property<int>("Order")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("PermissionName")
|
||||||
|
.HasMaxLength(256)
|
||||||
|
.HasColumnType("nvarchar(256)");
|
||||||
|
|
||||||
|
b.Property<string>("Props")
|
||||||
|
.HasColumnType("nvarchar(max)");
|
||||||
|
|
||||||
|
b.Property<int>("SourceType")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<Guid?>("TenantId")
|
||||||
|
.HasColumnType("uniqueidentifier")
|
||||||
|
.HasColumnName("TenantId");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("TenantId", "Code")
|
||||||
|
.IsUnique()
|
||||||
|
.HasFilter("[IsDeleted] = 0");
|
||||||
|
|
||||||
|
b.ToTable("Adm_T_IntranetWidget", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("Sozsoft.Platform.Entities.IpRestriction", b =>
|
modelBuilder.Entity("Sozsoft.Platform.Entities.IpRestriction", b =>
|
||||||
{
|
{
|
||||||
b.Property<Guid>("Id")
|
b.Property<Guid>("Id")
|
||||||
|
|
|
||||||
|
|
@ -2239,5 +2239,91 @@
|
||||||
"FormatTemplate": "{Prefix}-{yyyy}{MM}{dd}-{Number}",
|
"FormatTemplate": "{Prefix}-{yyyy}{MM}{dd}-{Number}",
|
||||||
"ResetPeriod": "Daily"
|
"ResetPeriod": "Daily"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"Widgets": [
|
||||||
|
{
|
||||||
|
"Code": "today-birthdays",
|
||||||
|
"Name": "Today Birthdays",
|
||||||
|
"LabelKey": "::App.DashboardWidget.Birthdays",
|
||||||
|
"SourceType": "Builtin",
|
||||||
|
"ComponentName": "",
|
||||||
|
"PermissionName": "AbpIdentity.Users.Widget",
|
||||||
|
"Column": "Left",
|
||||||
|
"Order": 10,
|
||||||
|
"Props": "",
|
||||||
|
"IsActive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Code": "documents",
|
||||||
|
"Name": "Recent Documents",
|
||||||
|
"LabelKey": "::App.DashboardWidget.Documents",
|
||||||
|
"SourceType": "Builtin",
|
||||||
|
"ComponentName": "",
|
||||||
|
"PermissionName": "App.Files.Widget",
|
||||||
|
"Column": "Left",
|
||||||
|
"Order": 20,
|
||||||
|
"Props": "",
|
||||||
|
"IsActive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Code": "active-surveys",
|
||||||
|
"Name": "Active Surveys",
|
||||||
|
"LabelKey": "::App.DashboardWidget.Surveys",
|
||||||
|
"SourceType": "Builtin",
|
||||||
|
"ComponentName": "",
|
||||||
|
"PermissionName": "App.Intranet.Survey.Widget",
|
||||||
|
"Column": "Left",
|
||||||
|
"Order": 30,
|
||||||
|
"Props": "",
|
||||||
|
"IsActive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Code": "social-wall",
|
||||||
|
"Name": "Social Wall",
|
||||||
|
"LabelKey": "::App.DashboardWidget.SocialWall",
|
||||||
|
"SourceType": "Builtin",
|
||||||
|
"ComponentName": "",
|
||||||
|
"PermissionName": "App.Intranet.SocialPost.Widget",
|
||||||
|
"Column": "Center",
|
||||||
|
"Order": 40,
|
||||||
|
"Props": "",
|
||||||
|
"IsActive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Code": "announcements",
|
||||||
|
"Name": "Announcements",
|
||||||
|
"LabelKey": "::App.Intranet.Announcement",
|
||||||
|
"SourceType": "Builtin",
|
||||||
|
"ComponentName": "",
|
||||||
|
"PermissionName": "App.Intranet.Announcement.Widget",
|
||||||
|
"Column": "Right",
|
||||||
|
"Order": 50,
|
||||||
|
"Props": "",
|
||||||
|
"IsActive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Code": "upcoming-events",
|
||||||
|
"Name": "Upcoming Events",
|
||||||
|
"LabelKey": "::App.DashboardWidget.Events",
|
||||||
|
"SourceType": "Builtin",
|
||||||
|
"ComponentName": "",
|
||||||
|
"PermissionName": "App.Intranet.Events.Event.Widget",
|
||||||
|
"Column": "Right",
|
||||||
|
"Order": 60,
|
||||||
|
"Props": "",
|
||||||
|
"IsActive": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Code": "role-list",
|
||||||
|
"Name": "Role List",
|
||||||
|
"LabelKey": "::AbpIdentity.Roles",
|
||||||
|
"SourceType": "Custom",
|
||||||
|
"ComponentName": "RoleComponent",
|
||||||
|
"PermissionName": "AbpIdentity.Roles",
|
||||||
|
"Column": "Center",
|
||||||
|
"Order": 20,
|
||||||
|
"Props": "",
|
||||||
|
"IsActive": true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ public class TenantSeederDto
|
||||||
public List<EventSeedDto> Events { get; set; }
|
public List<EventSeedDto> Events { get; set; }
|
||||||
public List<EventPhotoSeedDto> EventPhotos { get; set; }
|
public List<EventPhotoSeedDto> EventPhotos { get; set; }
|
||||||
public List<EventCommentSeedDto> EventComments { get; set; }
|
public List<EventCommentSeedDto> EventComments { get; set; }
|
||||||
|
public List<IntranetWidgetSeedDto> Widgets { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SequenceSeedDto
|
public class SequenceSeedDto
|
||||||
|
|
@ -195,6 +196,20 @@ public class SurveyQuestionOptionSeedDto
|
||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class IntranetWidgetSeedDto
|
||||||
|
{
|
||||||
|
public string Code { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string LabelKey { get; set; }
|
||||||
|
public IntranetWidgetSourceType SourceType { get; set; }
|
||||||
|
public string ComponentName { get; set; }
|
||||||
|
public string PermissionName { get; set; }
|
||||||
|
public IntranetWidgetColumn Column { get; set; }
|
||||||
|
public int Order { get; set; }
|
||||||
|
public string Props { get; set; }
|
||||||
|
public bool IsActive { get; set; } = true;
|
||||||
|
}
|
||||||
|
|
||||||
public class AnnouncementSeedDto
|
public class AnnouncementSeedDto
|
||||||
{
|
{
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
|
@ -487,6 +502,7 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
private readonly IRepository<Department, Guid> _departmentRepository;
|
private readonly IRepository<Department, Guid> _departmentRepository;
|
||||||
private readonly IRepository<JobPosition, Guid> _jobPositionRepository;
|
private readonly IRepository<JobPosition, Guid> _jobPositionRepository;
|
||||||
private readonly IRepository<Announcement, Guid> _announcementRepository;
|
private readonly IRepository<Announcement, Guid> _announcementRepository;
|
||||||
|
private readonly IRepository<IntranetWidget, Guid> _intranetWidgetRepository;
|
||||||
private readonly IRepository<Survey, Guid> _surveyRepository;
|
private readonly IRepository<Survey, Guid> _surveyRepository;
|
||||||
private readonly IRepository<SurveyQuestion, Guid> _surveyQuestionRepository;
|
private readonly IRepository<SurveyQuestion, Guid> _surveyQuestionRepository;
|
||||||
private readonly IRepository<SurveyQuestionOption, Guid> _surveyQuestionOptionRepository;
|
private readonly IRepository<SurveyQuestionOption, Guid> _surveyQuestionOptionRepository;
|
||||||
|
|
@ -531,6 +547,7 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
IRepository<JobPosition, Guid> jobPositionRepository,
|
IRepository<JobPosition, Guid> jobPositionRepository,
|
||||||
|
|
||||||
IRepository<Announcement, Guid> announcementRepository,
|
IRepository<Announcement, Guid> announcementRepository,
|
||||||
|
IRepository<IntranetWidget, Guid> intranetWidgetRepository,
|
||||||
IRepository<Survey, Guid> surveyRepository,
|
IRepository<Survey, Guid> surveyRepository,
|
||||||
IRepository<SurveyQuestion, Guid> surveyQuestionRepository,
|
IRepository<SurveyQuestion, Guid> surveyQuestionRepository,
|
||||||
IRepository<SurveyQuestionOption, Guid> surveyQuestionOptionRepository,
|
IRepository<SurveyQuestionOption, Guid> surveyQuestionOptionRepository,
|
||||||
|
|
@ -572,6 +589,7 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
_departmentRepository = departmentRepository;
|
_departmentRepository = departmentRepository;
|
||||||
_jobPositionRepository = jobPositionRepository;
|
_jobPositionRepository = jobPositionRepository;
|
||||||
_announcementRepository = announcementRepository;
|
_announcementRepository = announcementRepository;
|
||||||
|
_intranetWidgetRepository = intranetWidgetRepository;
|
||||||
_surveyRepository = surveyRepository;
|
_surveyRepository = surveyRepository;
|
||||||
_surveyQuestionRepository = surveyQuestionRepository;
|
_surveyQuestionRepository = surveyQuestionRepository;
|
||||||
_surveyQuestionOptionRepository = surveyQuestionOptionRepository;
|
_surveyQuestionOptionRepository = surveyQuestionOptionRepository;
|
||||||
|
|
@ -1006,6 +1024,26 @@ public class TenantDataSeeder : IDataSeedContributor, ITransientDependency
|
||||||
}, autoSave: true);
|
}, autoSave: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var item in items.Widgets)
|
||||||
|
{
|
||||||
|
if (await _intranetWidgetRepository.AnyAsync(x => x.Code == item.Code))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
await _intranetWidgetRepository.InsertAsync(new IntranetWidget
|
||||||
|
{
|
||||||
|
Code = item.Code,
|
||||||
|
Name = item.Name,
|
||||||
|
LabelKey = item.LabelKey,
|
||||||
|
SourceType = item.SourceType,
|
||||||
|
ComponentName = item.ComponentName,
|
||||||
|
PermissionName = item.PermissionName,
|
||||||
|
Column = item.Column,
|
||||||
|
Order = item.Order,
|
||||||
|
Props = item.Props,
|
||||||
|
IsActive = item.IsActive
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var item in items.Announcements)
|
foreach (var item in items.Announcements)
|
||||||
{
|
{
|
||||||
var exists = await _announcementRepository.AnyAsync(x => x.Title == item.Title);
|
var exists = await _announcementRepository.AnyAsync(x => x.Title == item.Title);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -7,6 +7,25 @@ export interface IntranetDashboardDto {
|
||||||
announcements: AnnouncementDto[]
|
announcements: AnnouncementDto[]
|
||||||
surveys: SurveyDto[]
|
surveys: SurveyDto[]
|
||||||
socialPosts: SocialPostDto[]
|
socialPosts: SocialPostDto[]
|
||||||
|
widgets: IntranetWidgetDto[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dashboard'da yayınlanan widget tanımı; kolon, sıra ve yetki veritabanından gelir.
|
||||||
|
export type IntranetWidgetSourceType = 0 | 1 // 0: Builtin (koda gömülü), 1: Custom (CustomComponent)
|
||||||
|
|
||||||
|
export type IntranetWidgetColumn = 0 | 1 | 2 // 0: left, 1: center, 2: right
|
||||||
|
|
||||||
|
export interface IntranetWidgetDto {
|
||||||
|
id: string
|
||||||
|
code: string
|
||||||
|
name: string
|
||||||
|
labelKey: string
|
||||||
|
sourceType: IntranetWidgetSourceType
|
||||||
|
componentName: string
|
||||||
|
permissionName: string
|
||||||
|
column: IntranetWidgetColumn
|
||||||
|
order: number
|
||||||
|
props: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Etkinlik
|
// Etkinlik
|
||||||
|
|
|
||||||
|
|
@ -781,7 +781,7 @@ const SqlObjectExplorer = ({
|
||||||
closeCtx()
|
closeCtx()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{ctxNode!.folder === 'views' && <FaEye className="text-purple-500" />}
|
{ctxNode!.folder === 'views' && <FaEye className="text-blue-500" />}
|
||||||
{ctxNode!.folder === 'procedures' && <FaCog className="text-green-600" />}
|
{ctxNode!.folder === 'procedures' && <FaCog className="text-green-600" />}
|
||||||
{ctxNode!.folder === 'functions' && <FaCode className="text-orange-500" />}
|
{ctxNode!.folder === 'functions' && <FaCode className="text-orange-500" />}
|
||||||
View Definition
|
View Definition
|
||||||
|
|
|
||||||
|
|
@ -24,14 +24,11 @@ import {
|
||||||
FaTasks,
|
FaTasks,
|
||||||
FaChartBar,
|
FaChartBar,
|
||||||
FaRegCalendarAlt,
|
FaRegCalendarAlt,
|
||||||
FaToggleOn,
|
|
||||||
FaToggleOff,
|
|
||||||
} from 'react-icons/fa'
|
} from 'react-icons/fa'
|
||||||
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
import { sqlObjectManagerService } from '@/services/sql-query-manager.service'
|
||||||
import { getMenus } from '@/services/menu.service'
|
import { getMenus } from '@/services/menu.service'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
import { CascadeBehavior, SqlTableRelation, RelationshipType } from '@/proxy/developerKit/models'
|
import { CascadeBehavior, SqlTableRelation, RelationshipType } from '@/proxy/developerKit/models'
|
||||||
import type { CrudEndpoint } from '@/proxy/developerKit/models'
|
|
||||||
import { useNavigationIcons } from '@/proxy/menus/navigation-icon.config'
|
import { useNavigationIcons } from '@/proxy/menus/navigation-icon.config'
|
||||||
import { MenuItem } from '@/proxy/menus/menu'
|
import { MenuItem } from '@/proxy/menus/menu'
|
||||||
import {
|
import {
|
||||||
|
|
@ -48,7 +45,6 @@ import {
|
||||||
CRUD_ENDPOINT_PERMISSION,
|
CRUD_ENDPOINT_PERMISSION,
|
||||||
CRUD_OPERATION_TYPES,
|
CRUD_OPERATION_TYPES,
|
||||||
type CrudOperationType,
|
type CrudOperationType,
|
||||||
METHOD_COLOR,
|
|
||||||
getErrorMessage,
|
getErrorMessage,
|
||||||
getOperationMeta,
|
getOperationMeta,
|
||||||
toEntityName,
|
toEntityName,
|
||||||
|
|
@ -1338,7 +1334,6 @@ const SqlTableDesignerDialog = ({
|
||||||
...CRUD_OPERATION_TYPES,
|
...CRUD_OPERATION_TYPES,
|
||||||
])
|
])
|
||||||
/** Duzenlenen tablonun kayitli endpoint'leri; adim mevcut durumu gosterir. */
|
/** Duzenlenen tablonun kayitli endpoint'leri; adim mevcut durumu gosterir. */
|
||||||
const [existingCrudEndpoints, setExistingCrudEndpoints] = useState<CrudEndpoint[]>([])
|
|
||||||
const [crudLoading, setCrudLoading] = useState(false)
|
const [crudLoading, setCrudLoading] = useState(false)
|
||||||
const [columns, setColumns] = useState<ColumnDefinition[]>([createEmptyColumn()])
|
const [columns, setColumns] = useState<ColumnDefinition[]>([createEmptyColumn()])
|
||||||
const [originalColumns, setOriginalColumns] = useState<ColumnDefinition[]>([])
|
const [originalColumns, setOriginalColumns] = useState<ColumnDefinition[]>([])
|
||||||
|
|
@ -1431,7 +1426,6 @@ const SqlTableDesignerDialog = ({
|
||||||
developerKitService
|
developerKitService
|
||||||
.getEndpointsByEntity(toEntityName(initialTableData.tableName))
|
.getEndpointsByEntity(toEntityName(initialTableData.tableName))
|
||||||
.then((endpoints) => {
|
.then((endpoints) => {
|
||||||
setExistingCrudEndpoints(endpoints)
|
|
||||||
if (endpoints.length === 0) return
|
if (endpoints.length === 0) return
|
||||||
setGenerateCrud(true)
|
setGenerateCrud(true)
|
||||||
const active = endpoints
|
const active = endpoints
|
||||||
|
|
@ -1439,7 +1433,7 @@ const SqlTableDesignerDialog = ({
|
||||||
.map((e) => e.operationType as CrudOperationType)
|
.map((e) => e.operationType as CrudOperationType)
|
||||||
setCrudOperations(CRUD_OPERATION_TYPES.filter((op) => active.includes(op)))
|
setCrudOperations(CRUD_OPERATION_TYPES.filter((op) => active.includes(op)))
|
||||||
})
|
})
|
||||||
.catch(() => setExistingCrudEndpoints([]))
|
.catch(() => {})
|
||||||
.finally(() => setCrudLoading(false))
|
.finally(() => setCrudLoading(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2151,7 +2145,6 @@ const SqlTableDesignerDialog = ({
|
||||||
setTemplatesOpen(false)
|
setTemplatesOpen(false)
|
||||||
setGenerateCrud(false)
|
setGenerateCrud(false)
|
||||||
setCrudOperations([...CRUD_OPERATION_TYPES])
|
setCrudOperations([...CRUD_OPERATION_TYPES])
|
||||||
setExistingCrudEndpoints([])
|
|
||||||
onClose()
|
onClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3373,39 +3366,6 @@ const SqlTableDesignerDialog = ({
|
||||||
<p className="mb-0 text-xs text-gray-400">{translate('::App.Platform.Loading')}</p>
|
<p className="mb-0 text-xs text-gray-400">{translate('::App.Platform.Loading')}</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{existingCrudEndpoints.length > 0 && (
|
|
||||||
<div className="rounded-lg border border-blue-200 bg-blue-50 p-3 dark:border-blue-900 dark:bg-blue-900/20">
|
|
||||||
<span className="block text-sm font-medium">
|
|
||||||
{translate('::App.SqlQueryManager.ExistingCrudEndpoints')}
|
|
||||||
</span>
|
|
||||||
<span className="mb-2 block text-xs text-gray-500 dark:text-gray-400">
|
|
||||||
{translate('::App.SqlQueryManager.ExistingCrudEndpointsHint')}
|
|
||||||
</span>
|
|
||||||
<div className="flex flex-col gap-1">
|
|
||||||
{existingCrudEndpoints.map((endpoint) => (
|
|
||||||
<div key={endpoint.id} className="flex items-center gap-2 text-xs">
|
|
||||||
<span
|
|
||||||
className={`rounded border px-1.5 py-0.5 font-mono ${
|
|
||||||
METHOD_COLOR[endpoint.method] ||
|
|
||||||
'border-gray-200 bg-gray-100 text-gray-700 dark:border-gray-700 dark:bg-gray-700 dark:text-gray-200'
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{endpoint.method}
|
|
||||||
</span>
|
|
||||||
<span className="font-mono text-gray-600 dark:text-gray-300">{endpoint.path}</span>
|
|
||||||
<span className="ml-auto">
|
|
||||||
{endpoint.isActive ? (
|
|
||||||
<FaToggleOn className="text-base text-green-500" />
|
|
||||||
) : (
|
|
||||||
<FaToggleOff className="text-base text-gray-300 dark:text-gray-600" />
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<label className="flex items-start gap-3 cursor-pointer rounded-lg border p-3 dark:border-gray-700">
|
<label className="flex items-start gap-3 cursor-pointer rounded-lg border p-3 dark:border-gray-700">
|
||||||
<Checkbox checked={generateCrud} onChange={(checked) => setGenerateCrud(checked)} />
|
<Checkbox checked={generateCrud} onChange={(checked) => setGenerateCrud(checked)} />
|
||||||
<span>
|
<span>
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import {
|
||||||
AnnouncementDto,
|
AnnouncementDto,
|
||||||
EventDto,
|
EventDto,
|
||||||
IntranetDashboardDto,
|
IntranetDashboardDto,
|
||||||
|
IntranetWidgetDto,
|
||||||
SurveyAnswerDto,
|
SurveyAnswerDto,
|
||||||
SurveyDto,
|
SurveyDto,
|
||||||
} from '@/proxy/intranet/models'
|
} from '@/proxy/intranet/models'
|
||||||
|
|
@ -25,7 +26,12 @@ import { currentLocalDate } from '@/utils/dateUtils'
|
||||||
import { useStoreActions, useStoreState } from '@/store/store'
|
import { useStoreActions, useStoreState } from '@/store/store'
|
||||||
import Button from '@/components/ui/Button'
|
import Button from '@/components/ui/Button'
|
||||||
import { LuX } from 'react-icons/lu'
|
import { LuX } from 'react-icons/lu'
|
||||||
import type { DashboardWidgetColumn, DashboardWidgetDefinition } from './dashboardWidget'
|
import { useComponents } from '@/contexts/ComponentContext'
|
||||||
|
import type {
|
||||||
|
DashboardWidgetColumn,
|
||||||
|
DashboardWidgetContext,
|
||||||
|
DashboardWidgetDefinition,
|
||||||
|
} from './dashboardWidget'
|
||||||
|
|
||||||
dayjs.extend(relativeTime)
|
dayjs.extend(relativeTime)
|
||||||
dayjs.extend(isBetween)
|
dayjs.extend(isBetween)
|
||||||
|
|
@ -33,16 +39,34 @@ dayjs.extend(localizedFormat)
|
||||||
|
|
||||||
const dashboardColumns: DashboardWidgetColumn[] = ['left', 'center', 'right']
|
const dashboardColumns: DashboardWidgetColumn[] = ['left', 'center', 'right']
|
||||||
|
|
||||||
|
// IntranetWidget.Column enum sırası ile aynı: 0 = Left, 1 = Center, 2 = Right
|
||||||
|
const widgetColumns: DashboardWidgetColumn[] = ['left', 'center', 'right']
|
||||||
|
|
||||||
type DashboardWidgetModule = { dashboardWidget?: DashboardWidgetDefinition }
|
type DashboardWidgetModule = { dashboardWidget?: DashboardWidgetDefinition }
|
||||||
|
|
||||||
const dashboardWidgets = Object.values(
|
// Koda gömülü widget'ların render tablosu. Hangisinin nerede, hangi sırada ve hangi yetkiyle
|
||||||
import.meta.glob<DashboardWidgetModule>(['./widgets/*.tsx', './SocialWall/index.tsx'], {
|
// yayınlandığı IntranetWidget kaydından gelir; buradaki kayıt yalnızca `code` ile eşleşir.
|
||||||
eager: true,
|
const builtinWidgets = new Map(
|
||||||
}),
|
Object.values(
|
||||||
|
import.meta.glob<DashboardWidgetModule>(['./widgets/*.tsx', './SocialWall/index.tsx'], {
|
||||||
|
eager: true,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.map((module) => module.dashboardWidget)
|
||||||
|
.filter((widget): widget is DashboardWidgetDefinition => Boolean(widget))
|
||||||
|
.map((widget) => [widget.id, widget] as const),
|
||||||
)
|
)
|
||||||
.map((module) => module.dashboardWidget)
|
|
||||||
.filter((widget): widget is DashboardWidgetDefinition => Boolean(widget))
|
// Custom widget'ın prop'ları kayıtta JSON metni olarak durur; bozuk içerik widget'ı düşürmemeli.
|
||||||
.sort((left, right) => left.order - right.order)
|
const parseWidgetProps = (props: string): Record<string, unknown> => {
|
||||||
|
if (!props) return {}
|
||||||
|
try {
|
||||||
|
const parsed = JSON.parse(props)
|
||||||
|
return parsed && typeof parsed === 'object' ? (parsed as Record<string, unknown>) : {}
|
||||||
|
} catch {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const layoutPresets = [
|
const layoutPresets = [
|
||||||
{
|
{
|
||||||
|
|
@ -82,6 +106,7 @@ const columnSpanClasses: Record<number, string> = {
|
||||||
|
|
||||||
const IntranetDashboard: React.FC = () => {
|
const IntranetDashboard: React.FC = () => {
|
||||||
const { checkPermission } = usePermission()
|
const { checkPermission } = usePermission()
|
||||||
|
const { renderComponent, getComponentByName, compiling: componentsCompiling } = useComponents()
|
||||||
const [selectedAnnouncement, setSelectedAnnouncement] = useState<AnnouncementDto | null>(null)
|
const [selectedAnnouncement, setSelectedAnnouncement] = useState<AnnouncementDto | null>(null)
|
||||||
const [selectedEvent, setSelectedEvent] = useState<EventDto | null>(null)
|
const [selectedEvent, setSelectedEvent] = useState<EventDto | null>(null)
|
||||||
const [selectedSurvey, setSelectedSurvey] = useState<SurveyDto | null>(null)
|
const [selectedSurvey, setSelectedSurvey] = useState<SurveyDto | null>(null)
|
||||||
|
|
@ -182,7 +207,38 @@ const IntranetDashboard: React.FC = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const grantedPolicies = useStoreState((state) => state.abpConfig?.config?.auth.grantedPolicies)
|
// Sunucu yetkisiz widget'ı zaten elemiştir; istemcideki kontrol yetkiyi ikinci katmanda da uygular.
|
||||||
|
const widgets = (intranetDashboard?.widgets || []).filter(
|
||||||
|
(widget) => !widget.permissionName || checkPermission(widget.permissionName),
|
||||||
|
)
|
||||||
|
|
||||||
|
const findWidget = (code: string) => widgets.find((widget) => widget.code === code)
|
||||||
|
|
||||||
|
// Yeni tanımlanan widget kolonun sonuna değil, kayıttaki sırasının gerektirdiği yere girer.
|
||||||
|
const insertByOrder = (columnCodes: string[], widget: IntranetWidgetDto) => {
|
||||||
|
const index = columnCodes.findIndex((code) => {
|
||||||
|
const placed = findWidget(code)
|
||||||
|
return placed !== undefined && placed.order > widget.order
|
||||||
|
})
|
||||||
|
|
||||||
|
if (index === -1) columnCodes.push(widget.code)
|
||||||
|
else columnCodes.splice(index, 0, widget.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
const assignedCodes = new Set(dashboardColumns.flatMap((column) => widgetOrder[column] || []))
|
||||||
|
|
||||||
|
// Gösterilecek liste kayıtlardan türetilir; kullanıcının sürükleyerek kaydettiği sıra korunur,
|
||||||
|
// kaydında yeri olmayan yeni widget kendi kolonunda sıra numarasının gerektirdiği yere girer.
|
||||||
|
// Böylece yeni tanımlanan bir widget, store güncellenmeden de ekranda görünür.
|
||||||
|
const columnWidgetCodes = (column: DashboardWidgetColumn) => {
|
||||||
|
const codes = [...new Set(widgetOrder[column] || [])].filter((code) => findWidget(code))
|
||||||
|
|
||||||
|
widgets
|
||||||
|
.filter((widget) => widgetColumns[widget.column] === column && !assignedCodes.has(widget.code))
|
||||||
|
.forEach((widget) => insertByOrder(codes, widget))
|
||||||
|
|
||||||
|
return codes
|
||||||
|
}
|
||||||
|
|
||||||
const initializeDefaultOrder = () => {
|
const initializeDefaultOrder = () => {
|
||||||
const defaultOrder: Record<DashboardWidgetColumn, string[]> = {
|
const defaultOrder: Record<DashboardWidgetColumn, string[]> = {
|
||||||
|
|
@ -190,37 +246,22 @@ const IntranetDashboard: React.FC = () => {
|
||||||
center: [],
|
center: [],
|
||||||
right: [],
|
right: [],
|
||||||
}
|
}
|
||||||
dashboardWidgets.forEach((widget) => {
|
widgets.forEach((widget) => {
|
||||||
if (checkPermission(widget.permission)) defaultOrder[widget.column].push(widget.id)
|
defaultOrder[widgetColumns[widget.column]].push(widget.code)
|
||||||
})
|
})
|
||||||
setWidgetOrder(defaultOrder)
|
setWidgetOrder(defaultOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Türetilen liste sürükle-bırakın üzerine yazacağı sıradır; kayıtlar geldiğinde saklanır.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!grantedPolicies) return
|
if (!intranetDashboard) return
|
||||||
|
|
||||||
const hasSavedOrder = dashboardColumns.some((column) => widgetOrder[column].length > 0)
|
setWidgetOrder({
|
||||||
if (!hasSavedOrder) {
|
left: columnWidgetCodes('left'),
|
||||||
initializeDefaultOrder()
|
center: columnWidgetCodes('center'),
|
||||||
return
|
right: columnWidgetCodes('right'),
|
||||||
}
|
|
||||||
|
|
||||||
// Kayıtlı sıralamayı tekilleştir ve henüz yerleştirilmemiş widget'ları ekle
|
|
||||||
const order: Record<DashboardWidgetColumn, string[]> = {
|
|
||||||
left: [...new Set(widgetOrder.left || [])],
|
|
||||||
center: [...new Set(widgetOrder.center || [])],
|
|
||||||
right: [...new Set(widgetOrder.right || [])],
|
|
||||||
}
|
|
||||||
|
|
||||||
const allAssigned = new Set([...order.left, ...order.center, ...order.right])
|
|
||||||
dashboardWidgets.forEach((widget) => {
|
|
||||||
if (!allAssigned.has(widget.id) && checkPermission(widget.permission)) {
|
|
||||||
order[widget.column].push(widget.id)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
}, [intranetDashboard])
|
||||||
setWidgetOrder(order)
|
|
||||||
}, [grantedPolicies])
|
|
||||||
|
|
||||||
const setWidgetVisibility = (widgetId: string, visible: boolean) => {
|
const setWidgetVisibility = (widgetId: string, visible: boolean) => {
|
||||||
const next = visible
|
const next = visible
|
||||||
|
|
@ -231,9 +272,7 @@ const IntranetDashboard: React.FC = () => {
|
||||||
|
|
||||||
const activeLayout =
|
const activeLayout =
|
||||||
layoutPresets.find((layout) => layout.id === selectedLayout) || layoutPresets[0]
|
layoutPresets.find((layout) => layout.id === selectedLayout) || layoutPresets[0]
|
||||||
const hiddenWidgets = dashboardWidgets.filter(
|
const hiddenWidgets = widgets.filter((widget) => hiddenWidgetIds.includes(widget.code))
|
||||||
(widget) => hiddenWidgetIds.includes(widget.id) && checkPermission(widget.permission),
|
|
||||||
)
|
|
||||||
|
|
||||||
const handleDragStart = (e: React.DragEvent, widgetId: string) => {
|
const handleDragStart = (e: React.DragEvent, widgetId: string) => {
|
||||||
setDragState({ draggedId: widgetId, targetColumn: null, targetIndex: null })
|
setDragState({ draggedId: widgetId, targetColumn: null, targetIndex: null })
|
||||||
|
|
@ -310,23 +349,62 @@ const IntranetDashboard: React.FC = () => {
|
||||||
|
|
||||||
const handleColumnDrop = (e: React.DragEvent<HTMLDivElement>, column: DashboardWidgetColumn) => {
|
const handleColumnDrop = (e: React.DragEvent<HTMLDivElement>, column: DashboardWidgetColumn) => {
|
||||||
if (!isDesignMode) return
|
if (!isDesignMode) return
|
||||||
handleDrop(e, column, widgetOrder[column].length)
|
handleDrop(e, column, columnWidgetCodes(column).length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Başlık anahtarı dil anahtarı listesinden seçildiğinde "::" öneki olmadan kaydedilir;
|
||||||
|
// anahtarı olmayan widget'ta kayıttaki ad gösterilir.
|
||||||
|
const widgetLabel = (widget: IntranetWidgetDto) =>
|
||||||
|
widget.labelKey
|
||||||
|
? translate(widget.labelKey.includes('::') ? widget.labelKey : `::${widget.labelKey}`)
|
||||||
|
: widget.name
|
||||||
|
|
||||||
|
const widgetContext: DashboardWidgetContext = {
|
||||||
|
dashboard: intranetDashboard,
|
||||||
|
openAnnouncement: setSelectedAnnouncement,
|
||||||
|
openEvent: setSelectedEvent,
|
||||||
|
takeSurvey: handleTakeSurvey,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget'ın neden basılamadığı sessizce yutulmamalı; kayıt varken boş kalan bir kolon
|
||||||
|
// yapılandırma hatasını gizler.
|
||||||
|
const renderWidgetNotice = (message: string) => (
|
||||||
|
<div className="rounded-lg border border-dashed border-gray-300 bg-white p-4 text-sm text-gray-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400">
|
||||||
|
{message}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
// Builtin widget koddaki kayıttan, custom widget DeveloperKit'te üretilmiş bileşenden basılır.
|
||||||
|
const renderWidgetContent = (widget: IntranetWidgetDto) => {
|
||||||
|
if (widget.sourceType === 1) {
|
||||||
|
if (!widget.componentName) {
|
||||||
|
return renderWidgetNotice(`${widget.name}: ComponentName tanımlı değil`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getComponentByName(widget.componentName)) {
|
||||||
|
return renderWidgetNotice(
|
||||||
|
componentsCompiling
|
||||||
|
? `${widget.componentName} yükleniyor…`
|
||||||
|
: `${widget.componentName} bulunamadı veya pasif`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderComponent(widget.componentName, parseWidgetProps(widget.props))
|
||||||
|
}
|
||||||
|
|
||||||
|
const builtin = builtinWidgets.get(widget.code)
|
||||||
|
if (!builtin) {
|
||||||
|
return renderWidgetNotice(`${widget.code}: koda kayıtlı bir widget yok`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return builtin.render(widgetContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderWidgets = (column: DashboardWidgetColumn) => {
|
const renderWidgets = (column: DashboardWidgetColumn) => {
|
||||||
const columnWidgets = widgetOrder[column] || []
|
return columnWidgetCodes(column)
|
||||||
|
|
||||||
const uniqueWidgets = [...new Set(columnWidgets)]
|
|
||||||
|
|
||||||
return uniqueWidgets
|
|
||||||
.map((widgetId, index) => {
|
.map((widgetId, index) => {
|
||||||
const metadata = dashboardWidgets.find((w) => w.id === widgetId)
|
const widget = findWidget(widgetId)
|
||||||
if (
|
if (!widget || hiddenWidgetIds.includes(widgetId)) return null
|
||||||
!metadata ||
|
|
||||||
!checkPermission(metadata.permission) ||
|
|
||||||
hiddenWidgetIds.includes(widgetId)
|
|
||||||
)
|
|
||||||
return null
|
|
||||||
|
|
||||||
const isDragging = dragState.draggedId === widgetId
|
const isDragging = dragState.draggedId === widgetId
|
||||||
const isDropTarget = dragState.targetColumn === column && dragState.targetIndex === index
|
const isDropTarget = dragState.targetColumn === column && dragState.targetIndex === index
|
||||||
|
|
@ -417,7 +495,7 @@ const IntranetDashboard: React.FC = () => {
|
||||||
type="button"
|
type="button"
|
||||||
className="absolute right-2 top-2 z-20 flex h-7 w-7 items-center justify-center rounded-full bg-white text-gray-500 shadow-sm dark:bg-gray-800 dark:text-gray-300"
|
className="absolute right-2 top-2 z-20 flex h-7 w-7 items-center justify-center rounded-full bg-white text-gray-500 shadow-sm dark:bg-gray-800 dark:text-gray-300"
|
||||||
title={translate('::App.Dashboard.HideWidget')}
|
title={translate('::App.Dashboard.HideWidget')}
|
||||||
aria-label={`${translate('::App.Dashboard.HideWidget')}: ${translate(metadata.labelKey)}`}
|
aria-label={`${translate('::App.Dashboard.HideWidget')}: ${widgetLabel(widget)}`}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
onMouseDown={(e) => e.stopPropagation()}
|
onMouseDown={(e) => e.stopPropagation()}
|
||||||
onDragStart={(e) => e.stopPropagation()}
|
onDragStart={(e) => e.stopPropagation()}
|
||||||
|
|
@ -447,12 +525,7 @@ const IntranetDashboard: React.FC = () => {
|
||||||
<div
|
<div
|
||||||
className={`${isDesignMode ? 'p-1.5' : ''} transition-all duration-500 ease-out`}
|
className={`${isDesignMode ? 'p-1.5' : ''} transition-all duration-500 ease-out`}
|
||||||
>
|
>
|
||||||
{metadata.render({
|
{renderWidgetContent(widget)}
|
||||||
dashboard: intranetDashboard,
|
|
||||||
openAnnouncement: setSelectedAnnouncement,
|
|
||||||
openEvent: setSelectedEvent,
|
|
||||||
takeSurvey: handleTakeSurvey,
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -555,15 +628,15 @@ const IntranetDashboard: React.FC = () => {
|
||||||
</span>
|
</span>
|
||||||
{hiddenWidgets.map((widget) => (
|
{hiddenWidgets.map((widget) => (
|
||||||
<Button
|
<Button
|
||||||
key={widget.id}
|
key={widget.code}
|
||||||
type="button"
|
type="button"
|
||||||
variant="plain"
|
variant="plain"
|
||||||
shape="none"
|
shape="none"
|
||||||
className="!h-8 !rounded-md !bg-emerald-50 !px-2 text-xs text-emerald-700 hover:!bg-emerald-100 dark:!bg-emerald-950 dark:text-emerald-300"
|
className="!h-8 !rounded-md !bg-emerald-50 !px-2 text-xs text-emerald-700 hover:!bg-emerald-100 dark:!bg-emerald-950 dark:text-emerald-300"
|
||||||
onClick={() => setWidgetVisibility(widget.id, true)}
|
onClick={() => setWidgetVisibility(widget.code, true)}
|
||||||
title={translate('::App.Dashboard.ShowWidget')}
|
title={translate('::App.Dashboard.ShowWidget')}
|
||||||
>
|
>
|
||||||
+ {translate(widget.labelKey)}
|
+ {widgetLabel(widget)}
|
||||||
</Button>
|
</Button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -572,7 +645,7 @@ const IntranetDashboard: React.FC = () => {
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-12">
|
<div className="grid grid-cols-1 lg:grid-cols-12">
|
||||||
{dashboardColumns.map((column, index) => {
|
{dashboardColumns.map((column, index) => {
|
||||||
const isEmptyDropTarget =
|
const isEmptyDropTarget =
|
||||||
isDesignMode && dragState.targetColumn === column && widgetOrder[column].length === 0
|
isDesignMode && dragState.targetColumn === column && columnWidgetCodes(column).length === 0
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ const SocialWall: React.FC = () => {
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto px-4">
|
<div className="mx-auto">
|
||||||
{/* Filter Tabs */}
|
{/* Filter Tabs */}
|
||||||
<div className="flex gap-4 mb-6 border-b border-gray-200 dark:border-gray-700">
|
<div className="flex gap-4 mb-6 border-b border-gray-200 dark:border-gray-700">
|
||||||
{renderTab('all', '::App.SocialWall.AllPosts')}
|
{renderTab('all', '::App.SocialWall.AllPosts')}
|
||||||
|
|
@ -242,10 +242,6 @@ const SocialWall: React.FC = () => {
|
||||||
|
|
||||||
export const dashboardWidget: DashboardWidgetDefinition = {
|
export const dashboardWidget: DashboardWidgetDefinition = {
|
||||||
id: 'social-wall',
|
id: 'social-wall',
|
||||||
permission: 'App.Intranet.SocialPost.Widget',
|
|
||||||
column: 'center',
|
|
||||||
labelKey: '::App.DashboardWidget.SocialWall',
|
|
||||||
order: 40,
|
|
||||||
render: () => <SocialWall />,
|
render: () => <SocialWall />,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,12 @@ export interface DashboardWidgetContext {
|
||||||
takeSurvey: (survey: SurveyDto) => void
|
takeSurvey: (survey: SurveyDto) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uygulamaya kodlanmış widget'ın kayıt girişi. Yalnızca render sorumluluğunu taşır:
|
||||||
|
* kolon, sıra, başlık, yetki ve yayında olup olmadığı IntranetWidget kaydından gelir.
|
||||||
|
* `id`, kaydın `Code` alanıyla eşleşmelidir.
|
||||||
|
*/
|
||||||
export interface DashboardWidgetDefinition {
|
export interface DashboardWidgetDefinition {
|
||||||
id: string
|
id: string
|
||||||
permission: string
|
|
||||||
column: DashboardWidgetColumn
|
|
||||||
labelKey: string
|
|
||||||
order: number
|
|
||||||
render: (context: DashboardWidgetContext) => ReactNode
|
render: (context: DashboardWidgetContext) => ReactNode
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -130,10 +130,6 @@ const Announcements: React.FC<AnnouncementsProps> = ({ announcements, onAnnounce
|
||||||
|
|
||||||
export const dashboardWidget: DashboardWidgetDefinition = {
|
export const dashboardWidget: DashboardWidgetDefinition = {
|
||||||
id: 'announcements',
|
id: 'announcements',
|
||||||
permission: 'App.Intranet.Announcement.Widget',
|
|
||||||
column: 'right',
|
|
||||||
labelKey: '::App.Intranet.Announcement',
|
|
||||||
order: 50,
|
|
||||||
render: ({ dashboard, openAnnouncement }) => (
|
render: ({ dashboard, openAnnouncement }) => (
|
||||||
<Announcements
|
<Announcements
|
||||||
announcements={dashboard?.announcements || []}
|
announcements={dashboard?.announcements || []}
|
||||||
|
|
|
||||||
|
|
@ -114,10 +114,6 @@ const Events: React.FC<EventsProps> = ({ events, onEventClick }) => {
|
||||||
|
|
||||||
export const dashboardWidget: DashboardWidgetDefinition = {
|
export const dashboardWidget: DashboardWidgetDefinition = {
|
||||||
id: 'upcoming-events',
|
id: 'upcoming-events',
|
||||||
permission: 'App.Intranet.Events.Event.Widget',
|
|
||||||
column: 'right',
|
|
||||||
labelKey: '::App.DashboardWidget.Events',
|
|
||||||
order: 60,
|
|
||||||
render: ({ dashboard, openEvent }) => (
|
render: ({ dashboard, openEvent }) => (
|
||||||
<Events events={dashboard?.events || []} onEventClick={openEvent} />
|
<Events events={dashboard?.events || []} onEventClick={openEvent} />
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -97,10 +97,6 @@ const RecentDocuments: React.FC<{ documents: DocumentDto[] }> = ({ documents })
|
||||||
|
|
||||||
export const dashboardWidget: DashboardWidgetDefinition = {
|
export const dashboardWidget: DashboardWidgetDefinition = {
|
||||||
id: 'documents',
|
id: 'documents',
|
||||||
permission: 'App.Files.Widget',
|
|
||||||
column: 'left',
|
|
||||||
labelKey: '::App.DashboardWidget.Documents',
|
|
||||||
order: 20,
|
|
||||||
render: ({ dashboard }) => <RecentDocuments documents={dashboard?.documents || []} />,
|
render: ({ dashboard }) => <RecentDocuments documents={dashboard?.documents || []} />,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,10 +195,6 @@ const Surveys: React.FC<SurveysProps> = ({ surveys, onTakeSurvey }) => {
|
||||||
|
|
||||||
export const dashboardWidget: DashboardWidgetDefinition = {
|
export const dashboardWidget: DashboardWidgetDefinition = {
|
||||||
id: 'active-surveys',
|
id: 'active-surveys',
|
||||||
permission: 'App.Intranet.Survey.Widget',
|
|
||||||
column: 'left',
|
|
||||||
labelKey: '::App.DashboardWidget.Surveys',
|
|
||||||
order: 30,
|
|
||||||
render: ({ dashboard, takeSurvey }) => (
|
render: ({ dashboard, takeSurvey }) => (
|
||||||
<Surveys surveys={dashboard?.surveys || []} onTakeSurvey={takeSurvey} />
|
<Surveys surveys={dashboard?.surveys || []} onTakeSurvey={takeSurvey} />
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,6 @@ const TodayBirthdays: React.FC<{ employees: UserInfoViewModel[] }> = ({ employee
|
||||||
|
|
||||||
export const dashboardWidget: DashboardWidgetDefinition = {
|
export const dashboardWidget: DashboardWidgetDefinition = {
|
||||||
id: 'today-birthdays',
|
id: 'today-birthdays',
|
||||||
permission: 'AbpIdentity.Users.Widget',
|
|
||||||
column: 'left',
|
|
||||||
labelKey: '::App.DashboardWidget.Birthdays',
|
|
||||||
order: 10,
|
|
||||||
render: ({ dashboard }) => <TodayBirthdays employees={dashboard?.birthdays || []} />,
|
render: ({ dashboard }) => <TodayBirthdays employees={dashboard?.birthdays || []} />,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue