ActivityLog düzenlemesi
This commit is contained in:
parent
a7e8d7995b
commit
cf6ded1105
3 changed files with 90 additions and 47 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
import AdaptableCard from '@/components/shared/AdaptableCard'
|
import AdaptableCard from '@/components/shared/AdaptableCard'
|
||||||
import Container from '@/components/shared/Container'
|
import Container from '@/components/shared/Container'
|
||||||
|
import Drawer from '@/components/ui/Drawer'
|
||||||
|
import Button from '@/components/ui/Button'
|
||||||
import NotificationChannels from '@/constants/notification-channel.enum'
|
import NotificationChannels from '@/constants/notification-channel.enum'
|
||||||
import { NotificationDto } from '@/proxy/notification/models'
|
import { NotificationDto } from '@/proxy/notification/models'
|
||||||
import { getList } from '@/services/notification.service'
|
import { getList } from '@/services/notification.service'
|
||||||
|
|
@ -9,13 +11,14 @@ import { Dictionary } from 'lodash'
|
||||||
import forOwn from 'lodash/forOwn'
|
import forOwn from 'lodash/forOwn'
|
||||||
import groupBy from 'lodash/groupBy'
|
import groupBy from 'lodash/groupBy'
|
||||||
import has from 'lodash/has'
|
import has from 'lodash/has'
|
||||||
import isEmpty from 'lodash/isEmpty'
|
|
||||||
import merge from 'lodash/merge'
|
import merge from 'lodash/merge'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import Log from './components/Log'
|
import Log from './components/Log'
|
||||||
import LogFilter from './components/LogFilter'
|
import LogFilter from './components/LogFilter'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { APP_NAME } from '@/constants/app.constant'
|
import { APP_NAME } from '@/constants/app.constant'
|
||||||
|
import { DIR_RTL } from '@/constants/theme.constant'
|
||||||
|
import { useStoreState } from '@/store'
|
||||||
|
|
||||||
const itemsPerPage = 10
|
const itemsPerPage = 10
|
||||||
|
|
||||||
|
|
@ -26,12 +29,13 @@ const ActivityLog = () => {
|
||||||
const [notifications, setNotifications] = useState<Dictionary<NotificationDto[]>>({})
|
const [notifications, setNotifications] = useState<Dictionary<NotificationDto[]>>({})
|
||||||
const [page, setPage] = useState(0)
|
const [page, setPage] = useState(0)
|
||||||
const [hasMore, setHasMore] = useState(false)
|
const [hasMore, setHasMore] = useState(false)
|
||||||
|
const [isFilterDrawerOpen, setIsFilterDrawerOpen] = useState(false)
|
||||||
|
const direction = useStoreState((state) => state.theme.direction)
|
||||||
const [filter, setFilter] = useState<string[]>([
|
const [filter, setFilter] = useState<string[]>([
|
||||||
NotificationChannels.Desktop,
|
NotificationChannels.Desktop,
|
||||||
NotificationChannels.Mail,
|
NotificationChannels.Mail,
|
||||||
NotificationChannels.Rocket,
|
NotificationChannels.Rocket,
|
||||||
NotificationChannels.Sms,
|
NotificationChannels.Sms,
|
||||||
NotificationChannels.Telegram,
|
|
||||||
NotificationChannels.UiActivity,
|
NotificationChannels.UiActivity,
|
||||||
NotificationChannels.UiToast,
|
NotificationChannels.UiToast,
|
||||||
NotificationChannels.WhatsApp,
|
NotificationChannels.WhatsApp,
|
||||||
|
|
@ -67,18 +71,16 @@ const ActivityLog = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isEmpty(notifications)) {
|
fetchData(page > 0)
|
||||||
fetchData()
|
}, [page, filter])
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
const handleFilterChange = (value: string[]) => {
|
||||||
fetchData(true)
|
setPage(0)
|
||||||
}, [page])
|
setNotifications({})
|
||||||
|
setHasMore(false)
|
||||||
useEffect(() => {
|
setFilter(value)
|
||||||
fetchData()
|
setIsFilterDrawerOpen(false)
|
||||||
}, [filter])
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
|
|
@ -88,19 +90,53 @@ const ActivityLog = () => {
|
||||||
defaultTitle={APP_NAME}
|
defaultTitle={APP_NAME}
|
||||||
></Helmet>
|
></Helmet>
|
||||||
|
|
||||||
<AdaptableCard>
|
<AdaptableCard className="overflow-hidden">
|
||||||
<div className="grid lg:grid-cols-5 gap-8">
|
<div className="w-full">
|
||||||
<div className="col-span-4">
|
<div className="mb-5 flex items-center justify-between gap-3">
|
||||||
<h3 className="mb-6">{translate('::Abp.Identity.ActivityLogs')}</h3>
|
<h3 className="text-xl font-semibold md:text-2xl">
|
||||||
<Log
|
{translate('::Abp.Identity.ActivityLogs')}
|
||||||
notifications={notifications}
|
</h3>
|
||||||
isLoading={loading}
|
<Button
|
||||||
onLoadMore={() => setPage(page + 1)}
|
className="lg:hidden"
|
||||||
loadable={hasMore}
|
size="sm"
|
||||||
></Log>
|
variant="twoTone"
|
||||||
|
onClick={() => setIsFilterDrawerOpen(true)}
|
||||||
|
>
|
||||||
|
{translate('::Abp.Identity.ActivityLogs.Filters')}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="grid grid-cols-1 gap-6 lg:grid-cols-[minmax(0,1fr)_340px]">
|
||||||
|
<div className="min-w-0 rounded-xl border border-gray-200 bg-white p-4 lg:p-6">
|
||||||
|
<Log
|
||||||
|
notifications={notifications}
|
||||||
|
isLoading={loading}
|
||||||
|
onLoadMore={() => setPage((prev) => prev + 1)}
|
||||||
|
loadable={hasMore}
|
||||||
|
></Log>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="hidden lg:block">
|
||||||
|
<LogFilter filter={filter} onFilterChange={handleFilterChange} useAffix />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<LogFilter filter={filter} onFilterChange={(value: string[]) => setFilter(value)} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Drawer
|
||||||
|
title={translate('::Abp.Identity.ActivityLogs.Filters')}
|
||||||
|
isOpen={isFilterDrawerOpen}
|
||||||
|
width={340}
|
||||||
|
placement={direction === DIR_RTL ? 'right' : 'left'}
|
||||||
|
onClose={() => setIsFilterDrawerOpen(false)}
|
||||||
|
onRequestClose={() => setIsFilterDrawerOpen(false)}
|
||||||
|
>
|
||||||
|
<LogFilter
|
||||||
|
filter={filter}
|
||||||
|
onFilterChange={handleFilterChange}
|
||||||
|
useAffix={false}
|
||||||
|
className="border-none p-0"
|
||||||
|
/>
|
||||||
|
</Drawer>
|
||||||
</AdaptableCard>
|
</AdaptableCard>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const Log = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Loading type="cover" loading={isLoading}>
|
<Loading type="cover" loading={isLoading}>
|
||||||
<div className="max-w-[900px]">
|
<div className="w-full">
|
||||||
{keys(notifications).map((group) => (
|
{keys(notifications).map((group) => (
|
||||||
<div key={group} className="mb-8">
|
<div key={group} className="mb-8">
|
||||||
<div className="mb-4 font-semibold uppercase">
|
<div className="mb-4 font-semibold uppercase">
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ const ticketCheckboxes = [
|
||||||
{ label: NotificationChannels.UiActivity, value: NotificationChannels.UiActivity },
|
{ label: NotificationChannels.UiActivity, value: NotificationChannels.UiActivity },
|
||||||
{ label: NotificationChannels.UiToast, value: NotificationChannels.UiToast },
|
{ label: NotificationChannels.UiToast, value: NotificationChannels.UiToast },
|
||||||
{ label: NotificationChannels.WhatsApp, value: NotificationChannels.WhatsApp },
|
{ label: NotificationChannels.WhatsApp, value: NotificationChannels.WhatsApp },
|
||||||
{ label: NotificationChannels.Telegram, value: NotificationChannels.Telegram },
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const CategoryTitle = ({ children, className }: CategoryTitleProps) => {
|
const CategoryTitle = ({ children, className }: CategoryTitleProps) => {
|
||||||
|
|
@ -34,35 +33,43 @@ const CategoryTitle = ({ children, className }: CategoryTitleProps) => {
|
||||||
const LogFilter = ({
|
const LogFilter = ({
|
||||||
filter,
|
filter,
|
||||||
onFilterChange,
|
onFilterChange,
|
||||||
|
useAffix = true,
|
||||||
|
className,
|
||||||
}: {
|
}: {
|
||||||
filter: string[]
|
filter: string[]
|
||||||
onFilterChange: (value: string[]) => void
|
onFilterChange: (value: string[]) => void
|
||||||
|
useAffix?: boolean
|
||||||
|
className?: string
|
||||||
}) => {
|
}) => {
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
return (
|
const content = (
|
||||||
<div>
|
<div className={classNames('rounded-xl border border-gray-200 bg-white p-4', className)}>
|
||||||
<Affix className="hidden lg:block" offset={80}>
|
<h5 className="mb-4 text-base font-semibold">{translate('::Abp.Identity.ActivityLogs.Filters')}</h5>
|
||||||
<h5 className="mb-4">{translate('::Abp.Identity.ActivityLogs.Filters')}</h5>
|
<Checkbox.Group
|
||||||
<Checkbox.Group
|
vertical
|
||||||
vertical
|
value={filter}
|
||||||
value={filter}
|
onChange={(value) => {
|
||||||
onChange={(value) => {
|
onFilterChange(value as string[])
|
||||||
onFilterChange(value as string[])
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<CategoryTitle className="mb-3 text-gray-500">
|
||||||
<CategoryTitle className="mb-3">
|
{translate('::Abp.Identity.ActivityLogs.Channels')}
|
||||||
{translate('::Abp.Identity.ActivityLogs.Channels')}
|
</CategoryTitle>
|
||||||
</CategoryTitle>
|
{ticketCheckboxes.map((checkbox) => (
|
||||||
{ticketCheckboxes.map((checkbox) => (
|
<Checkbox key={checkbox.value} className="mb-3" value={checkbox.value}>
|
||||||
<Checkbox key={checkbox.value} className="mb-4" value={checkbox.value}>
|
{checkbox.label}
|
||||||
{checkbox.label}
|
</Checkbox>
|
||||||
</Checkbox>
|
))}
|
||||||
))}
|
</Checkbox.Group>
|
||||||
</Checkbox.Group>
|
|
||||||
</Affix>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (useAffix) {
|
||||||
|
return <Affix offset={80}>{content}</Affix>
|
||||||
|
}
|
||||||
|
|
||||||
|
return content
|
||||||
}
|
}
|
||||||
|
|
||||||
export default LogFilter
|
export default LogFilter
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue