Notification UiToast, UiActivity, Desktop düzenlemesi

Fazla Console.Log kaldırıldı.
This commit is contained in:
Sedat ÖZTÜRK 2026-05-11 15:19:27 +03:00
parent 8feab2184a
commit 524a88274b
21 changed files with 73 additions and 70 deletions

View file

@ -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 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";
public const string UiToast = "UiToast";
public const string WhatsApp = "WhatsApp";
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";
}

View file

@ -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,

View file

@ -90,12 +90,6 @@ const PropertyPanel: React.FC<PropertyPanelProps> = ({
// 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<PropertyPanelProps> = ({
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<PropertyPanelProps> = ({
// Apply property and event changes together
if (Object.keys(allUpdates).length > 0) {
console.log("🔧 PropertyPanel: Applying combined updates:", allUpdates);
onPropertiesChange(selectedComponent.id, allUpdates);
}

View file

@ -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 <Avatar shape="circle" src={AVATAR_URL(creatorId, tenantId)} />
@ -75,16 +75,20 @@ const _Notification = ({ className }: { className?: string }) => {
const [noResult, setNoResult] = useState(false)
const [loading, setLoading] = useState(false)
const [toastNotificationList, setToastNotificationList] = useState<string[]>([])
const toastNotificationInterval = useRef<NodeJS.Timer>()
const [desktopNotificationList, setDesktopNotificationList] = useState<string[]>([])
const desktopNotificationInterval = useRef<NodeJS.Timer>()
const toastNotificationList = useRef<string[]>([])
const toastNotificationInterval = useRef<ReturnType<typeof setInterval>>()
const desktopNotificationList = useRef<string[]>([])
const desktopNotificationInterval = useRef<ReturnType<typeof setInterval>>()
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(
<Notify
type="success"
duration={0}
closable={true}
onClose={async () => {
await updateRead(notification.id, true)
}}
>
{notification.message}
</Notify>,
@ -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(() => {
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 (
<Tooltip title={translate('::App.Notifications')}>

View file

@ -6,7 +6,7 @@ const NotificationChannels = {
UiActivity: 'UiActivity',
UiToast: 'UiToast',
WhatsApp: 'WhatsApp',
Telegram: 'Telegram',
// Telegram: 'Telegram',
}
export const NotificationChannelColors: Record<string, string> = {
@ -17,7 +17,7 @@ export const NotificationChannelColors: Record<string, string> = {
UiActivity: 'bg-lime-600',
UiToast: 'bg-emerald-800',
WhatsApp: 'bg-cyan-600',
Telegram: 'bg-purple-900',
// Telegram: 'bg-purple-900',
}
export default NotificationChannels

View file

@ -26,5 +26,6 @@ export interface NotificationRuleDto {
export declare class NotificationFilterRequestDto extends PagedAndSortedResultRequestDto {
channels?: string[]
isRead?: boolean
isSent?: boolean
isListRequest: boolean
}

View file

@ -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...')
}

View file

@ -132,7 +132,6 @@ class DynamicServiceService {
* Kodu test et (compile)
*/
async testCompile(data: TestCompileDto): Promise<CompileResult> {
console.log('DynamicServiceService.testCompile called with data:', data)
const response = await apiService.fetchData<CompileResult>({
url: `${this.baseUrl}/test-compile`,
method: 'POST',

View file

@ -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)
}

View file

@ -36,7 +36,6 @@ export type Injections = typeof injections
const reduxStateSyncConfig: ReduxStateSyncConfig = {
predicate: (action) => {
// console.log({ action })
const blacklist = [
'persist/FLUSH',
'persist/REHYDRATE',

View file

@ -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);

View file

@ -42,7 +42,7 @@ export const useExamTimer = ({
}, []);
useEffect(() => {
let interval: NodeJS.Timeout;
let interval: ReturnType<typeof setInterval>;
if (isRunning && !isPaused && timeRemaining > 0) {
interval = setInterval(() => {

View file

@ -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)

View file

@ -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) => ({

View file

@ -324,8 +324,6 @@ const FileItem = forwardRef<HTMLDivElement, FileItemProps>((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 (
<div className="w-full h-full bg-gray-100 dark:bg-gray-700 rounded flex items-center justify-center overflow-hidden">
{!imageError ? (

View file

@ -93,7 +93,7 @@ const FileUploadModal = forwardRef<HTMLDivElement, FileUploadModalProps>((props,
// Upload files one by one
for (const fileData of filesToUpload) {
let progressInterval: NodeJS.Timeout | null = null
let progressInterval: ReturnType<typeof setInterval> | null = null;
try {
// Set status to uploading

View file

@ -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) => ({

View file

@ -91,7 +91,6 @@ function RolesPermission({
const filteredData = { ...data, groups: filteredGroups }
console.log('Filtered permissions by tenant group:', tenantGroup, filteredData)
setPermissionList(filteredData)
}

View file

@ -39,7 +39,7 @@ const LocationPicker: React.FC<LocationPickerProps> = ({ onSelect, onClose }) =>
const searchInputRef = useRef<HTMLInputElement>(null)
const autocompleteServiceRef = useRef<any>(null)
const placesServiceRef = useRef<any>(null)
const debounceTimerRef = useRef<NodeJS.Timeout>()
const debounceTimerRef = useRef<ReturnType<typeof setTimeout>>()
const scriptLoadedRef = useRef(false)
// Google Maps SDK'yı yükle

View file

@ -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)

View file

@ -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)