From 524a88274b8f1059b0f07d51466759cf9ff54fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96ZT=C3=9CRK?= <76204082+iamsedatozturk@users.noreply.github.com> Date: Mon, 11 May 2026 15:19:27 +0300 Subject: [PATCH] =?UTF-8?q?Notification=20UiToast,=20UiActivity,=20Desktop?= =?UTF-8?q?=20d=C3=BCzenlemesi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fazla Console.Log kaldırıldı. --- .../Enums/NotificationChannels.cs | 15 ++-- .../Seeds/ListFormSeeder_Saas.cs | 6 +- .../components/codeLayout/PropertyPanel.tsx | 14 ---- ui/src/components/template/Notification.tsx | 79 +++++++++++++------ ui/src/constants/notification-channel.enum.ts | 4 +- ui/src/proxy/notification/models.ts | 1 + ui/src/routes/dynamicRouteLoader.tsx | 4 - ui/src/services/dynamicService.service.ts | 1 - ui/src/services/fileManagement.service.ts | 1 - ui/src/store/store.ts | 1 - ui/src/utils/hooks/useCoordinator.ts | 1 - ui/src/utils/hooks/useExamTimer.ts | 2 +- ui/src/utils/hooks/useReports.ts | 2 - ui/src/views/admin/files/FileManager.tsx | 1 - .../views/admin/files/components/FileItem.tsx | 2 - .../files/components/FileUploadModal.tsx | 2 +- .../listForm/edit/form-fields/FormFields.tsx | 1 - .../admin/role-management/RolesPermission.tsx | 1 - .../intranet/SocialWall/LocationPicker.tsx | 2 +- ui/src/views/public/Payment.tsx | 2 - ui/src/views/settings/Settings.tsx | 1 - 21 files changed, 73 insertions(+), 70 deletions(-) diff --git a/api/modules/Sozsoft.Notifications/Sozsoft.Notifications.Domain.Shared/Enums/NotificationChannels.cs b/api/modules/Sozsoft.Notifications/Sozsoft.Notifications.Domain.Shared/Enums/NotificationChannels.cs index be25b6f..78dcaf5 100644 --- a/api/modules/Sozsoft.Notifications/Sozsoft.Notifications.Domain.Shared/Enums/NotificationChannels.cs +++ b/api/modules/Sozsoft.Notifications/Sozsoft.Notifications.Domain.Shared/Enums/NotificationChannels.cs @@ -2,13 +2,12 @@ public static class NotificationChannels { - public const string Sms = "Sms"; - public const string Mail = "Mail"; - public const string Rocket = "Rocket"; - public const string Desktop = "Desktop"; - public const string UiActivity = "UiActivity"; - public const string UiToast = "UiToast"; - public const string WhatsApp = "WhatsApp"; + public const string Sms = "Sms"; //SMS (ABP Sms + Posta Guvercini) + public const string Mail = "Mail"; //Email (ABP Emailing + Amazon SES) + public const string Rocket = "Rocket"; //Rocket.Chat (HTTP API) + public const string Desktop = "Desktop"; + public const string UiActivity = "UiActivity"; //UI Activity (ABP UI Activity) + public const string UiToast = "UiToast"; //UI Toast (ABP UI Toast) Ayarlar/Sistem/Bildirimler/Chrome açık olması gerekiyor. + public const string WhatsApp = "WhatsApp"; //WhatsApp (HTTP API, template-based) // public const string Telegram = "Telegram"; } - diff --git a/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs b/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs index 9783979..d216de5 100644 --- a/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs +++ b/api/src/Sozsoft.Platform.DbMigrator/Seeds/ListFormSeeder_Saas.cs @@ -4453,12 +4453,12 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency LookupQuery = JsonSerializer.Serialize(new LookupDataDto[] { new () { Key="Sms",Name="Sms" }, new () { Key="Mail",Name="Mail" }, + new () { Key="WhatsApp",Name="WhatsApp" }, new () { Key="Rocket",Name="Rocket" }, - new () { Key="Desktop",Name="Desktop" }, new () { Key="UiActivity",Name="UiActivity" }, new () { Key="UiToast",Name="UiToast" }, - new () { Key="WhatsApp",Name="WhatsApp" }, - new () { Key="Telegram",Name="Telegram" }, + new () { Key="Desktop",Name="Desktop" }, + // new () { Key="Telegram",Name="Telegram" }, }), }), ColumnCustomizationJson = DefaultColumnCustomizationJson, diff --git a/ui/src/components/codeLayout/PropertyPanel.tsx b/ui/src/components/codeLayout/PropertyPanel.tsx index 0fc39de..84a620e 100644 --- a/ui/src/components/codeLayout/PropertyPanel.tsx +++ b/ui/src/components/codeLayout/PropertyPanel.tsx @@ -90,12 +90,6 @@ const PropertyPanel: React.FC = ({ // hooks.add("useEffect"); // } - console.log( - "🪝 Active hooks detected:", - Array.from(hooks), - "for component:", - selectedComponent.id - ); setActiveHooks(hooks); } }, [selectedComponent, currentCode]); @@ -131,13 +125,6 @@ const PropertyPanel: React.FC = ({ const handleApplyPropChanges = () => { if (!selectedComponent) return; - console.log("🔄 PropertyPanel: Applying changes:", { - properties: pendingProperties, - events: pendingEvents, - hooks: pendingHooks, - selectedComponentId: selectedComponent.id, - }); - // Combine all changes into a single update object const allUpdates = { ...pendingProperties, @@ -146,7 +133,6 @@ const PropertyPanel: React.FC = ({ // Apply property and event changes together if (Object.keys(allUpdates).length > 0) { - console.log("🔧 PropertyPanel: Applying combined updates:", allUpdates); onPropertiesChange(selectedComponent.id, allUpdates); } diff --git a/ui/src/components/template/Notification.tsx b/ui/src/components/template/Notification.tsx index e747e4b..6a223b8 100644 --- a/ui/src/components/template/Notification.tsx +++ b/ui/src/components/template/Notification.tsx @@ -37,7 +37,7 @@ type NotificationList = { } const notificationHeight = 'h-72' -const notificationInterval = 120000 +const notificationInterval = 120000 // 2 minutes const notificationTypeAvatar = (creatorId: string, tenantId?: string) => { return @@ -75,16 +75,20 @@ const _Notification = ({ className }: { className?: string }) => { const [noResult, setNoResult] = useState(false) const [loading, setLoading] = useState(false) - const [toastNotificationList, setToastNotificationList] = useState([]) - const toastNotificationInterval = useRef() - const [desktopNotificationList, setDesktopNotificationList] = useState([]) - const desktopNotificationInterval = useRef() + const toastNotificationList = useRef([]) + const toastNotificationInterval = useRef>() + const desktopNotificationList = useRef([]) + const desktopNotificationInterval = useRef>() const { bgTheme } = useThemeClass() const { larger } = useResponsive() const direction = useStoreState((state) => state.theme.direction) const tabHasFocus = useStoreState((a) => a.base.common.tabHasFocus) + const tabHasFocusRef = useRef(tabHasFocus) + useEffect(() => { + tabHasFocusRef.current = tabHasFocus + }, [tabHasFocus]) const getReactNotificationCount = useCallback(async () => { const resp = await getList({ @@ -175,22 +179,23 @@ const _Notification = ({ className }: { className?: string }) => { const resp = await getList({ channels: [NotificationChannels.UiToast], isListRequest: false, + isSent: false, maxResultCount: 1000, }) const items = resp.data.items ?? [] const newNotificationList = items.filter( - (a) => !toastNotificationList.includes(a.id) && !a.isSent, + (a) => !toastNotificationList.current.includes(a.id) && !a.isSent, ) - setToastNotificationList(newNotificationList.map((a) => a.id)) + toastNotificationList.current = [ + ...toastNotificationList.current, + ...newNotificationList.map((a) => a.id), + ] for (const notification of newNotificationList) { toast.push( { - await updateRead(notification.id, true) - }} > {notification.message} , @@ -200,13 +205,16 @@ const _Notification = ({ className }: { className?: string }) => { ) await updateSent(notification.id, true) + await updateRead(notification.id, true) } - setToastNotificationList([]) } useEffect(() => { + if (tabHasFocusRef.current) { + getToastNotifications() + } toastNotificationInterval.current = setInterval(async () => { - if (tabHasFocus) { + if (tabHasFocusRef.current) { await getToastNotifications() } }, notificationInterval) @@ -214,41 +222,68 @@ const _Notification = ({ className }: { className?: string }) => { return () => { clearInterval(toastNotificationInterval.current) } - }, [toastNotificationList, tabHasFocus]) + }, []) //Desktop const getDesktopNotifications = async () => { + if (!('Notification' in window) || window.Notification.permission !== 'granted') return + const resp = await getList({ channels: [NotificationChannels.Desktop], isListRequest: false, + isSent: false, maxResultCount: 1000, }) const items = resp.data.items ?? [] const newNotificationList = items.filter( - (a) => !desktopNotificationList.includes(a.id) && !a.isSent, + (a) => !desktopNotificationList.current.includes(a.id) && !a.isSent, ) - setDesktopNotificationList(newNotificationList.map((a) => a.id)) + desktopNotificationList.current = [ + ...desktopNotificationList.current, + ...newNotificationList.map((a) => a.id), + ] for (const notification of newNotificationList) { - var options = { + const title = notification.notificationType || 'Bildirim' + const options = { body: notification.message, dir: 'ltr', + requireInteraction: true, } as NotificationOptions - new window.Notification(notification.notificationType, options) + + if ('serviceWorker' in navigator && navigator.serviceWorker.controller) { + const reg = await navigator.serviceWorker.ready + await reg.showNotification(title, options) + } else { + new window.Notification(title, options) + } await updateSent(notification.id, true) + await updateRead(notification.id, true) } - setDesktopNotificationList([]) } useEffect(() => { - desktopNotificationInterval.current = setInterval(async () => { - await getDesktopNotifications() - }, notificationInterval) + const startDesktopNotifications = async () => { + if (!('Notification' in window)) return + + if (window.Notification.permission === 'default') { + await window.Notification.requestPermission() + } + + if (window.Notification.permission === 'granted') { + await getDesktopNotifications() + desktopNotificationInterval.current = setInterval(async () => { + await getDesktopNotifications() + }, notificationInterval) + } + } + + startDesktopNotifications() return () => { clearInterval(desktopNotificationInterval.current) } - }, [desktopNotificationList]) + }, []) return ( diff --git a/ui/src/constants/notification-channel.enum.ts b/ui/src/constants/notification-channel.enum.ts index 527dcf5..b3ceb9f 100644 --- a/ui/src/constants/notification-channel.enum.ts +++ b/ui/src/constants/notification-channel.enum.ts @@ -6,7 +6,7 @@ const NotificationChannels = { UiActivity: 'UiActivity', UiToast: 'UiToast', WhatsApp: 'WhatsApp', - Telegram: 'Telegram', + // Telegram: 'Telegram', } export const NotificationChannelColors: Record = { @@ -17,7 +17,7 @@ export const NotificationChannelColors: Record = { UiActivity: 'bg-lime-600', UiToast: 'bg-emerald-800', WhatsApp: 'bg-cyan-600', - Telegram: 'bg-purple-900', + // Telegram: 'bg-purple-900', } export default NotificationChannels diff --git a/ui/src/proxy/notification/models.ts b/ui/src/proxy/notification/models.ts index e032003..3d54d7b 100644 --- a/ui/src/proxy/notification/models.ts +++ b/ui/src/proxy/notification/models.ts @@ -26,5 +26,6 @@ export interface NotificationRuleDto { export declare class NotificationFilterRequestDto extends PagedAndSortedResultRequestDto { channels?: string[] isRead?: boolean + isSent?: boolean isListRequest: boolean } diff --git a/ui/src/routes/dynamicRouteLoader.tsx b/ui/src/routes/dynamicRouteLoader.tsx index 2c31490..b5caeac 100644 --- a/ui/src/routes/dynamicRouteLoader.tsx +++ b/ui/src/routes/dynamicRouteLoader.tsx @@ -60,14 +60,10 @@ function loadDynamicComponent( // Eğer manuel registered'da yoksa, database compiled komponentleri kontrol et if (!DynamicComponent && isComponentRegistered && renderComponent && isComponentRegistered(componentName)) { - // console.log(`Database component found: ${componentName}`) - // Database komponentini wrapper ile kullan DynamicComponent = (props: any) => renderComponent(componentName, props) as React.ReactElement } if (!DynamicComponent) { - console.error(`Dynamic component not found: ${componentName}`) - console.log('Available registered components:', Object.keys(registeredComponents)) if (isComponentRegistered) { console.log('Database component registry available - checking...') } diff --git a/ui/src/services/dynamicService.service.ts b/ui/src/services/dynamicService.service.ts index 144c40b..63096d1 100644 --- a/ui/src/services/dynamicService.service.ts +++ b/ui/src/services/dynamicService.service.ts @@ -132,7 +132,6 @@ class DynamicServiceService { * Kodu test et (compile) */ async testCompile(data: TestCompileDto): Promise { - console.log('DynamicServiceService.testCompile called with data:', data) const response = await apiService.fetchData({ url: `${this.baseUrl}/test-compile`, method: 'POST', diff --git a/ui/src/services/fileManagement.service.ts b/ui/src/services/fileManagement.service.ts index f149a00..219aa2e 100644 --- a/ui/src/services/fileManagement.service.ts +++ b/ui/src/services/fileManagement.service.ts @@ -62,7 +62,6 @@ class FileManagementService { // Upload a file directly with FormData (NoteModal pattern) async uploadFileDirectly(formData: FormData, tenantId?: string): Promise<{ data: FileItem }> { try { - console.log('Uploading file directly with FormData') if (tenantId) { formData.append('tenantId', tenantId) } diff --git a/ui/src/store/store.ts b/ui/src/store/store.ts index 7121973..0a1a3fb 100644 --- a/ui/src/store/store.ts +++ b/ui/src/store/store.ts @@ -36,7 +36,6 @@ export type Injections = typeof injections const reduxStateSyncConfig: ReduxStateSyncConfig = { predicate: (action) => { - // console.log({ action }) const blacklist = [ 'persist/FLUSH', 'persist/REHYDRATE', diff --git a/ui/src/utils/hooks/useCoordinator.ts b/ui/src/utils/hooks/useCoordinator.ts index 40d12b7..6e81823 100644 --- a/ui/src/utils/hooks/useCoordinator.ts +++ b/ui/src/utils/hooks/useCoordinator.ts @@ -93,7 +93,6 @@ export function useCoordinator() { }; const handleExamComplete = (session: ExamSession) => { - console.log("Exam completed:", session); alert("Assessment completed successfully!"); setCurrentPath("/admin/dashboard"); setCurrentExam(null); diff --git a/ui/src/utils/hooks/useExamTimer.ts b/ui/src/utils/hooks/useExamTimer.ts index dd71e06..60e6988 100644 --- a/ui/src/utils/hooks/useExamTimer.ts +++ b/ui/src/utils/hooks/useExamTimer.ts @@ -42,7 +42,7 @@ export const useExamTimer = ({ }, []); useEffect(() => { - let interval: NodeJS.Timeout; + let interval: ReturnType; if (isRunning && !isPaused && timeRemaining > 0) { interval = setInterval(() => { diff --git a/ui/src/utils/hooks/useReports.ts b/ui/src/utils/hooks/useReports.ts index 5be2fce..2fefe12 100644 --- a/ui/src/utils/hooks/useReports.ts +++ b/ui/src/utils/hooks/useReports.ts @@ -92,8 +92,6 @@ export const useReports = () => { const currentTemplateResponse = await reportsService.getTemplateById(id) const currentTemplate = currentTemplateResponse.data as ReportTemplateDto - console.log('Current Template:', currentTemplate) - const updatedTemplate = { ...currentTemplate, ...updates } await reportsService.updateTemplate(id, updatedTemplate) diff --git a/ui/src/views/admin/files/FileManager.tsx b/ui/src/views/admin/files/FileManager.tsx index ee06de1..fdc362c 100644 --- a/ui/src/views/admin/files/FileManager.tsx +++ b/ui/src/views/admin/files/FileManager.tsx @@ -164,7 +164,6 @@ const FileManager = () => { } const response = await fileManagementService.getFolderPath(folderId, selectedTenant?.id) - // console.log('Breadcrumb response for folderId:', folderId, response) const pathItems: BreadcrumbItem[] = [ { name: 'Files', path: '', id: undefined }, ...response.data.path.map((item) => ({ diff --git a/ui/src/views/admin/files/components/FileItem.tsx b/ui/src/views/admin/files/components/FileItem.tsx index aef54e8..f86f543 100644 --- a/ui/src/views/admin/files/components/FileItem.tsx +++ b/ui/src/views/admin/files/components/FileItem.tsx @@ -324,8 +324,6 @@ const FileItem = forwardRef((props, ref) => { const ImagePreview = ({ src, alt }: { src: string; alt: string }) => { const [imageError, setImageError] = useState(false) - console.log('Rendering ImagePreview with src:', src) // Debug için - return (
{!imageError ? ( diff --git a/ui/src/views/admin/files/components/FileUploadModal.tsx b/ui/src/views/admin/files/components/FileUploadModal.tsx index 8976dde..39d4b82 100644 --- a/ui/src/views/admin/files/components/FileUploadModal.tsx +++ b/ui/src/views/admin/files/components/FileUploadModal.tsx @@ -93,7 +93,7 @@ const FileUploadModal = forwardRef((props, // Upload files one by one for (const fileData of filesToUpload) { - let progressInterval: NodeJS.Timeout | null = null + let progressInterval: ReturnType | null = null; try { // Set status to uploading diff --git a/ui/src/views/admin/listForm/edit/form-fields/FormFields.tsx b/ui/src/views/admin/listForm/edit/form-fields/FormFields.tsx index d0632b0..9659ca8 100644 --- a/ui/src/views/admin/listForm/edit/form-fields/FormFields.tsx +++ b/ui/src/views/admin/listForm/edit/form-fields/FormFields.tsx @@ -226,7 +226,6 @@ function FormFields({ }) setNull(resp?.data?.items) setFields(resp?.data?.items) - console.log('getFields', resp?.data?.items) if (resp.data?.items) { setFieldList( resp?.data?.items.map((f: ColumnFormatEditDto) => ({ diff --git a/ui/src/views/admin/role-management/RolesPermission.tsx b/ui/src/views/admin/role-management/RolesPermission.tsx index a09a639..c0b36c6 100644 --- a/ui/src/views/admin/role-management/RolesPermission.tsx +++ b/ui/src/views/admin/role-management/RolesPermission.tsx @@ -91,7 +91,6 @@ function RolesPermission({ const filteredData = { ...data, groups: filteredGroups } - console.log('Filtered permissions by tenant group:', tenantGroup, filteredData) setPermissionList(filteredData) } diff --git a/ui/src/views/intranet/SocialWall/LocationPicker.tsx b/ui/src/views/intranet/SocialWall/LocationPicker.tsx index ed51212..bdbf0b5 100644 --- a/ui/src/views/intranet/SocialWall/LocationPicker.tsx +++ b/ui/src/views/intranet/SocialWall/LocationPicker.tsx @@ -39,7 +39,7 @@ const LocationPicker: React.FC = ({ onSelect, onClose }) => const searchInputRef = useRef(null) const autocompleteServiceRef = useRef(null) const placesServiceRef = useRef(null) - const debounceTimerRef = useRef() + const debounceTimerRef = useRef>() const scriptLoadedRef = useRef(false) // Google Maps SDK'yı yükle diff --git a/ui/src/views/public/Payment.tsx b/ui/src/views/public/Payment.tsx index 8d8ce48..1a66d53 100644 --- a/ui/src/views/public/Payment.tsx +++ b/ui/src/views/public/Payment.tsx @@ -83,8 +83,6 @@ const Payment: React.FC = () => { }, } as OrderDto - console.log('Order data:', orderData) - const orderService = new OrderService() const result = await orderService.createOrder(orderData) diff --git a/ui/src/views/settings/Settings.tsx b/ui/src/views/settings/Settings.tsx index a452bab..252f55c 100644 --- a/ui/src/views/settings/Settings.tsx +++ b/ui/src/views/settings/Settings.tsx @@ -65,7 +65,6 @@ const Settings = () => { values.App_SiteManagement_Theme_Style.includes('.dark') ? 'dark' : 'light', ) } - console.log(values) const resp = await updateSettingValues(values) if (resp.status === 204) { await fetchData(activeGroupName)