From 6d43cb23dd3203a9d39db8172bc432e1f8ea1359 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Sun, 13 Aug 2023 16:42:11 -0700 Subject: [PATCH 1/7] Remove case sensitivity on search. --- queries/admin/report.ts | 6 ++++++ queries/admin/team.ts | 3 ++- queries/admin/user.ts | 1 + queries/admin/website.ts | 4 ++-- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/queries/admin/report.ts b/queries/admin/report.ts index d2523f82..7ca2f2b2 100644 --- a/queries/admin/report.ts +++ b/queries/admin/report.ts @@ -41,6 +41,7 @@ export async function getReports( filterType === REPORT_FILTER_TYPES.name) && { name: { startsWith: filter, + mode: 'insensitive', }, }), }, @@ -49,6 +50,7 @@ export async function getReports( filterType === REPORT_FILTER_TYPES.description) && { description: { startsWith: filter, + mode: 'insensitive', }, }), }, @@ -57,6 +59,7 @@ export async function getReports( filterType === REPORT_FILTER_TYPES.type) && { type: { startsWith: filter, + mode: 'insensitive', }, }), }, @@ -66,6 +69,7 @@ export async function getReports( user: { username: { startsWith: filter, + mode: 'insensitive', }, }, }), @@ -76,6 +80,7 @@ export async function getReports( website: { name: { startsWith: filter, + mode: 'insensitive', }, }, }), @@ -86,6 +91,7 @@ export async function getReports( website: { domain: { startsWith: filter, + mode: 'insensitive', }, }, }), diff --git a/queries/admin/team.ts b/queries/admin/team.ts index 3294c029..71ea634a 100644 --- a/queries/admin/team.ts +++ b/queries/admin/team.ts @@ -97,7 +97,7 @@ export async function getTeams( OR: [ { ...((filterType === TEAM_FILTER_TYPES.all || filterType === TEAM_FILTER_TYPES.name) && { - name: { startsWith: filter }, + name: { startsWith: filter, mode: 'insensitive' }, }), }, { @@ -109,6 +109,7 @@ export async function getTeams( user: { username: { startsWith: filter, + mode: 'insensitive', }, }, }, diff --git a/queries/admin/user.ts b/queries/admin/user.ts index f4be4751..3aece6d1 100644 --- a/queries/admin/user.ts +++ b/queries/admin/user.ts @@ -57,6 +57,7 @@ export async function getUsers( filterType === USER_FILTER_TYPES.username) && { username: { startsWith: filter, + mode: 'insensitive', }, }), }, diff --git a/queries/admin/website.ts b/queries/admin/website.ts index 721b0662..a55db814 100644 --- a/queries/admin/website.ts +++ b/queries/admin/website.ts @@ -36,13 +36,13 @@ export async function getWebsites( { ...((filterType === WEBSITE_FILTER_TYPES.all || filterType === WEBSITE_FILTER_TYPES.name) && { - name: { startsWith: filter }, + name: { startsWith: filter, mode: 'insensitive' }, }), }, { ...((filterType === WEBSITE_FILTER_TYPES.all || filterType === WEBSITE_FILTER_TYPES.domain) && { - domain: { startsWith: filter }, + domain: { startsWith: filter, mode: 'insensitive' }, }), }, ], From f7eeaa622b39c7a75f18465cd12bf5fbb0d8cd62 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Sun, 13 Aug 2023 22:21:49 -0700 Subject: [PATCH 2/7] Add website/reports to top nav. --- components/layout/NavBar.js | 2 + components/messages.js | 3 + components/pages/reports/ReportsPage.js | 36 +++++++- components/pages/reports/ReportsTable.js | 12 +++ .../pages/settings/websites/WebsitesList.js | 9 +- .../pages/settings/websites/WebsitesTable.js | 17 +++- .../pages/websites/WebsiteReportsPage.js | 12 +-- components/pages/websites/WebsitesPage.js | 67 ++++++++++++++ hooks/index.js | 1 + hooks/useReports.js | 6 +- hooks/useWebsiteReports.js | 38 ++++++++ lib/types.ts | 2 + pages/api/reports/index.ts | 10 +- pages/api/users/[id]/websites.ts | 3 +- pages/api/websites/[id]/reports.ts | 38 ++++++++ pages/reports/index.js | 13 +++ pages/websites/index.js | 13 +++ queries/admin/report.ts | 54 ++++++++++- queries/admin/website.ts | 91 ++++++++++++------- 19 files changed, 361 insertions(+), 66 deletions(-) create mode 100644 components/pages/websites/WebsitesPage.js create mode 100644 hooks/useWebsiteReports.js create mode 100644 pages/api/websites/[id]/reports.ts create mode 100644 pages/reports/index.js create mode 100644 pages/websites/index.js diff --git a/components/layout/NavBar.js b/components/layout/NavBar.js index 97eaa46c..e896b404 100644 --- a/components/layout/NavBar.js +++ b/components/layout/NavBar.js @@ -18,6 +18,8 @@ export function NavBar() { const links = [ { label: formatMessage(labels.dashboard), url: '/dashboard' }, + { label: formatMessage(labels.websites), url: '/websites' }, + { label: formatMessage(labels.reports), url: '/reports' }, !cloudMode && { label: formatMessage(labels.settings), url: '/settings' }, ].filter(n => n); diff --git a/components/messages.js b/components/messages.js index f47513e8..c0024810 100644 --- a/components/messages.js +++ b/components/messages.js @@ -21,6 +21,8 @@ export const labels = defineMessages({ details: { id: 'label.details', defaultMessage: 'Details' }, website: { id: 'label.website', defaultMessage: 'Website' }, websites: { id: 'label.websites', defaultMessage: 'Websites' }, + myWebsites: { id: 'label.my-websites', defaultMessage: 'My Websites' }, + teamWebsites: { id: 'label.team-websites', defaultMessage: 'Team Websites' }, created: { id: 'label.created', defaultMessage: 'Created' }, edit: { id: 'label.edit', defaultMessage: 'Edit' }, name: { id: 'label.name', defaultMessage: 'Name' }, @@ -28,6 +30,7 @@ export const labels = defineMessages({ accessCode: { id: 'label.access-code', defaultMessage: 'Access code' }, teamId: { id: 'label.team-id', defaultMessage: 'Team ID' }, team: { id: 'label.team', defaultMessage: 'Team' }, + teamName: { id: 'label.team-name', defaultMessage: 'Team Name' }, regenerate: { id: 'label.regenerate', defaultMessage: 'Regenerate' }, remove: { id: 'label.remove', defaultMessage: 'Remove' }, join: { id: 'label.join', defaultMessage: 'Join' }, diff --git a/components/pages/reports/ReportsPage.js b/components/pages/reports/ReportsPage.js index 470e1b08..d63fc77f 100644 --- a/components/pages/reports/ReportsPage.js +++ b/components/pages/reports/ReportsPage.js @@ -1,13 +1,24 @@ +import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; import Page from 'components/layout/Page'; import PageHeader from 'components/layout/PageHeader'; -import Link from 'next/link'; -import { Button, Icon, Icons, Text } from 'react-basics'; import { useMessages, useReports } from 'hooks'; +import Link from 'next/link'; +import { Button, Flexbox, Icon, Icons, Text } from 'react-basics'; import ReportsTable from './ReportsTable'; export function ReportsPage() { - const { formatMessage, labels } = useMessages(); - const { reports, error, isLoading } = useReports(); + const { formatMessage, labels, messages } = useMessages(); + const { + reports, + error, + isLoading, + filter, + handleFilterChange, + handlePageChange, + handlePageSizeChange, + } = useReports(); + + const hasData = (reports && reports?.data.length !== 0) || filter; return ( @@ -21,7 +32,22 @@ export function ReportsPage() { - + + {hasData && ( + + )} + {!hasData && ( + + )} ); } diff --git a/components/pages/reports/ReportsTable.js b/components/pages/reports/ReportsTable.js index 529f5359..e59e4069 100644 --- a/components/pages/reports/ReportsTable.js +++ b/components/pages/reports/ReportsTable.js @@ -12,14 +12,23 @@ export function ReportsTable({ onFilterChange, onPageChange, onPageSizeChange, + showDomain, }) { const [report, setReport] = useState(null); const { formatMessage, labels } = useMessages(); + const domainColumn = [ + { + name: 'domain', + label: formatMessage(labels.domain), + }, + ]; + const columns = [ { name: 'name', label: formatMessage(labels.name) }, { name: 'description', label: formatMessage(labels.description) }, { name: 'type', label: formatMessage(labels.type) }, + ...(showDomain ? domainColumn : []), { name: 'action', label: ' ' }, ]; @@ -41,6 +50,9 @@ export function ReportsTable({ > {row => { const { id } = row; + if (showDomain) { + row.domain = row.website.domain; + } return ( diff --git a/components/pages/settings/websites/WebsitesList.js b/components/pages/settings/websites/WebsitesList.js index 310b481f..f99b2d6e 100644 --- a/components/pages/settings/websites/WebsitesList.js +++ b/components/pages/settings/websites/WebsitesList.js @@ -10,19 +10,21 @@ import useMessages from 'hooks/useMessages'; import { ROLES } from 'lib/constants'; import useApiFilter from 'hooks/useApiFilter'; -export function WebsitesList() { +export function WebsitesList({ showTeam, showHeader = true, includeTeams, onlyTeams, fetch }) { const { formatMessage, labels, messages } = useMessages(); const { user } = useUser(); const { filter, page, pageSize, handleFilterChange, handlePageChange, handlePageSizeChange } = useApiFilter(); const { get, useQuery } = useApi(); const { data, isLoading, error, refetch } = useQuery( - ['websites', user?.id, filter, page, pageSize], + ['websites', fetch, user?.id, filter, page, pageSize, includeTeams, onlyTeams], () => get(`/users/${user?.id}/websites`, { filter, page, pageSize, + includeTeams, + onlyTeams, }), { enabled: !!user }, ); @@ -54,10 +56,11 @@ export function WebsitesList() { return ( - {addButton} + {showHeader && {addButton}} {hasData && ( {row => { - const { id } = row; + const { + id, + teamWebsite, + user: { username }, + } = row; + if (showTeam) { + row.teamName = teamWebsite[0]?.team.name; + row.owner = username; + } return ( <> diff --git a/components/pages/websites/WebsiteReportsPage.js b/components/pages/websites/WebsiteReportsPage.js index beb9bc4f..85a002e6 100644 --- a/components/pages/websites/WebsiteReportsPage.js +++ b/components/pages/websites/WebsiteReportsPage.js @@ -1,7 +1,7 @@ import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; import Page from 'components/layout/Page'; import ReportsTable from 'components/pages/reports/ReportsTable'; -import { useMessages, useReports } from 'hooks'; +import { useMessages, useWebsiteReports } from 'hooks'; import Link from 'next/link'; import { Button, Flexbox, Icon, Icons, Text } from 'react-basics'; import WebsiteHeader from './WebsiteHeader'; @@ -17,9 +17,9 @@ export function WebsiteReportsPage({ websiteId }) { handleFilterChange, handlePageChange, handlePageSizeChange, - } = useReports(websiteId); + } = useWebsiteReports(websiteId); - const hasData = reports && reports.data.length !== 0; + const hasData = (reports && reports.data.length !== 0) || filter; const handleDelete = async id => { await deleteReport(id); @@ -48,11 +48,7 @@ export function WebsiteReportsPage({ websiteId }) { filterValue={filter} /> )} - {!hasData && ( - - {/* {addButton} */} - - )} + {!hasData && } ); } diff --git a/components/pages/websites/WebsitesPage.js b/components/pages/websites/WebsitesPage.js new file mode 100644 index 00000000..4fdd025d --- /dev/null +++ b/components/pages/websites/WebsitesPage.js @@ -0,0 +1,67 @@ +import Page from 'components/layout/Page'; +import PageHeader from 'components/layout/PageHeader'; +import WebsiteAddForm from 'components/pages/settings/websites/WebsiteAddForm'; +import WebsiteList from 'components/pages/settings/websites/WebsitesList'; +import { useMessages } from 'hooks'; +import useUser from 'hooks/useUser'; +import { ROLES } from 'lib/constants'; +import { useState } from 'react'; +import { + Button, + Icon, + Icons, + Item, + Modal, + ModalTrigger, + Tabs, + Text, + useToasts, +} from 'react-basics'; + +export function WebsitesPage() { + const { formatMessage, labels, messages } = useMessages(); + const [tab, setTab] = useState('my-websites'); + const [fetch, setFetch] = useState(1); + const { user } = useUser(); + const { showToast } = useToasts(); + + const handleSave = async () => { + setFetch(fetch + 1); + showToast({ message: formatMessage(messages.saved), variant: 'success' }); + }; + + const addButton = ( + <> + {user.role !== ROLES.viewOnly && ( + + + + {close => } + + + )} + + ); + + return ( + + {addButton} + + {formatMessage(labels.myWebsites)} + {formatMessage(labels.teamWebsites)} + + + {tab === 'my-websites' && } + {tab === 'team-webaites' && ( + + )} + + ); +} + +export default WebsitesPage; diff --git a/hooks/index.js b/hooks/index.js index 004260b0..2596ba57 100644 --- a/hooks/index.js +++ b/hooks/index.js @@ -20,3 +20,4 @@ export * from './useTheme'; export * from './useTimezone'; export * from './useUser'; export * from './useWebsite'; +export * from './useWebsiteReports'; diff --git a/hooks/useReports.js b/hooks/useReports.js index 57d76492..932fa6dc 100644 --- a/hooks/useReports.js +++ b/hooks/useReports.js @@ -2,15 +2,15 @@ import { useState } from 'react'; import useApi from './useApi'; import useApiFilter from 'hooks/useApiFilter'; -export function useReports(websiteId) { +export function useReports() { const [modified, setModified] = useState(Date.now()); const { get, useQuery, del, useMutation } = useApi(); const { mutate } = useMutation(reportId => del(`/reports/${reportId}`)); const { filter, page, pageSize, handleFilterChange, handlePageChange, handlePageSizeChange } = useApiFilter(); const { data, error, isLoading } = useQuery( - ['reports:website', { websiteId, modified, filter, page, pageSize }], - () => get(`/reports`, { websiteId, filter, page, pageSize }), + ['reports', { modified, filter, page, pageSize }], + () => get(`/reports`, { filter, page, pageSize }), ); const deleteReport = id => { diff --git a/hooks/useWebsiteReports.js b/hooks/useWebsiteReports.js new file mode 100644 index 00000000..3b7ec415 --- /dev/null +++ b/hooks/useWebsiteReports.js @@ -0,0 +1,38 @@ +import { useState } from 'react'; +import useApi from './useApi'; +import useApiFilter from 'hooks/useApiFilter'; + +export function useWebsiteReports(websiteId) { + const [modified, setModified] = useState(Date.now()); + const { get, useQuery, del, useMutation } = useApi(); + const { mutate } = useMutation(reportId => del(`/reports/${reportId}`)); + const { filter, page, pageSize, handleFilterChange, handlePageChange, handlePageSizeChange } = + useApiFilter(); + const { data, error, isLoading } = useQuery( + ['reports:website', { websiteId, modified, filter, page, pageSize }], + () => get(`/websites/${websiteId}/reports`, { websiteId, filter, page, pageSize }), + ); + + const deleteReport = id => { + mutate(id, { + onSuccess: () => { + setModified(Date.now()); + }, + }); + }; + + return { + reports: data, + error, + isLoading, + deleteReport, + filter, + page, + pageSize, + handleFilterChange, + handlePageChange, + handlePageSizeChange, + }; +} + +export default useWebsiteReports; diff --git a/lib/types.ts b/lib/types.ts index 5a25169a..65bef8fb 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -27,6 +27,7 @@ export interface WebsiteSearchFilter extends SearchFilter { @@ -40,6 +41,7 @@ export interface TeamSearchFilter extends SearchFilter { export interface ReportSearchFilter extends SearchFilter { userId?: string; websiteId?: string; + includeTeams?: boolean; } export interface SearchFilter { diff --git a/pages/api/reports/index.ts b/pages/api/reports/index.ts index 8c6825f1..db83e6ed 100644 --- a/pages/api/reports/index.ts +++ b/pages/api/reports/index.ts @@ -4,7 +4,7 @@ import { useAuth, useCors } from 'lib/middleware'; import { NextApiRequestQueryBody, ReportSearchFilterType, SearchFilter } from 'lib/types'; import { NextApiResponse } from 'next'; import { methodNotAllowed, ok, unauthorized } from 'next-basics'; -import { createReport, getReportsByWebsiteId } from 'queries'; +import { createReport, getReportsByUserId, getReportsByWebsiteId } from 'queries'; export interface ReportsRequestQuery extends SearchFilter {} @@ -26,20 +26,14 @@ export default async ( await useCors(req, res); await useAuth(req, res); - const { websiteId } = req.query; - const { user: { id: userId }, } = req.auth; if (req.method === 'GET') { - if (!(websiteId && (await canViewWebsite(req.auth, websiteId)))) { - return unauthorized(res); - } - const { page, filter, pageSize } = req.query; - const data = await getReportsByWebsiteId(websiteId, { + const data = await getReportsByUserId(userId, { page, filter, pageSize: +pageSize || null, diff --git a/pages/api/users/[id]/websites.ts b/pages/api/users/[id]/websites.ts index 72d793d1..0e9231f7 100644 --- a/pages/api/users/[id]/websites.ts +++ b/pages/api/users/[id]/websites.ts @@ -21,7 +21,7 @@ export default async ( await useAuth(req, res); const { user } = req.auth; - const { id: userId, page, filter, pageSize, includeTeams } = req.query; + const { id: userId, page, filter, pageSize, includeTeams, onlyTeams } = req.query; if (req.method === 'GET') { if (!user.isAdmin && user.id !== userId) { @@ -33,6 +33,7 @@ export default async ( filter, pageSize: +pageSize || null, includeTeams, + onlyTeams, }); return ok(res, websites); diff --git a/pages/api/websites/[id]/reports.ts b/pages/api/websites/[id]/reports.ts new file mode 100644 index 00000000..60c6f714 --- /dev/null +++ b/pages/api/websites/[id]/reports.ts @@ -0,0 +1,38 @@ +import { canViewWebsite } from 'lib/auth'; +import { useAuth, useCors } from 'lib/middleware'; +import { NextApiRequestQueryBody, ReportSearchFilterType, SearchFilter } from 'lib/types'; +import { NextApiResponse } from 'next'; +import { methodNotAllowed, ok, unauthorized } from 'next-basics'; +import { getReportsByWebsiteId } from 'queries'; + +export interface ReportsRequestQuery extends SearchFilter { + id: string; +} + +export default async ( + req: NextApiRequestQueryBody, + res: NextApiResponse, +) => { + await useCors(req, res); + await useAuth(req, res); + + const { id: websiteId } = req.query; + + if (req.method === 'GET') { + if (!(websiteId && (await canViewWebsite(req.auth, websiteId)))) { + return unauthorized(res); + } + + const { page, filter, pageSize } = req.query; + + const data = await getReportsByWebsiteId(websiteId, { + page, + filter, + pageSize: +pageSize || null, + }); + + return ok(res, data); + } + + return methodNotAllowed(res); +}; diff --git a/pages/reports/index.js b/pages/reports/index.js new file mode 100644 index 00000000..ff3b4e86 --- /dev/null +++ b/pages/reports/index.js @@ -0,0 +1,13 @@ +import AppLayout from 'components/layout/AppLayout'; +import ReportsPage from 'components/pages/reports/ReportsPage'; +import { useMessages } from 'hooks'; + +export default function () { + const { formatMessage, labels } = useMessages(); + + return ( + + + + ); +} diff --git a/pages/websites/index.js b/pages/websites/index.js new file mode 100644 index 00000000..42a327bc --- /dev/null +++ b/pages/websites/index.js @@ -0,0 +1,13 @@ +import AppLayout from 'components/layout/AppLayout'; +import WebsitesPage from 'components/pages/websites/WebsitesPage'; +import useMessages from 'hooks/useMessages'; + +export default function () { + const { formatMessage, labels } = useMessages(); + + return ( + + + + ); +} diff --git a/queries/admin/report.ts b/queries/admin/report.ts index 7ca2f2b2..3c50c2cb 100644 --- a/queries/admin/report.ts +++ b/queries/admin/report.ts @@ -28,13 +28,45 @@ export async function deleteReport(reportId: string): Promise { export async function getReports( ReportSearchFilter: ReportSearchFilter, + options?: { include?: Prisma.ReportInclude }, ): Promise> { - const { userId, websiteId, filter, filterType = REPORT_FILTER_TYPES.all } = ReportSearchFilter; + const { + userId, + websiteId, + includeTeams, + filter, + filterType = REPORT_FILTER_TYPES.all, + } = ReportSearchFilter; + const where: Prisma.ReportWhereInput = { ...(userId && { userId: userId }), ...(websiteId && { websiteId: websiteId }), - ...(filter && { - AND: { + AND: [ + { + OR: [ + { + ...(userId && { userId: userId }), + }, + { + ...(includeTeams && { + website: { + teamWebsite: { + some: { + team: { + teamUser: { + some: { + userId, + }, + }, + }, + }, + }, + }, + }), + }, + ], + }, + { OR: [ { ...((filterType === REPORT_FILTER_TYPES.all || @@ -98,7 +130,7 @@ export async function getReports( }, ], }, - }), + ], }; const [pageFilters, getParameters] = prisma.getPageFilters(ReportSearchFilter); @@ -106,6 +138,7 @@ export async function getReports( const reports = await prisma.client.report.findMany({ where, ...pageFilters, + ...(options?.include && { include: options.include }), }); const count = await prisma.client.report.count({ where, @@ -122,7 +155,18 @@ export async function getReportsByUserId( userId: string, filter: SearchFilter, ): Promise> { - return getReports({ userId, ...filter }); + return getReports( + { userId, ...filter }, + { + include: { + website: { + select: { + domain: true, + }, + }, + }, + }, + ); } export async function getReportsByWebsiteId( diff --git a/queries/admin/website.ts b/queries/admin/website.ts index a55db814..d7b98b45 100644 --- a/queries/admin/website.ts +++ b/queries/admin/website.ts @@ -26,29 +26,11 @@ export async function getWebsites( userId, teamId, includeTeams, + onlyTeams, filter, filterType = WEBSITE_FILTER_TYPES.all, } = WebsiteSearchFilter; - const filterQuery = { - AND: { - OR: [ - { - ...((filterType === WEBSITE_FILTER_TYPES.all || - filterType === WEBSITE_FILTER_TYPES.name) && { - name: { startsWith: filter, mode: 'insensitive' }, - }), - }, - { - ...((filterType === WEBSITE_FILTER_TYPES.all || - filterType === WEBSITE_FILTER_TYPES.domain) && { - domain: { startsWith: filter, mode: 'insensitive' }, - }), - }, - ], - }, - }; - const where: Prisma.WebsiteWhereInput = { ...(teamId && { teamWebsite: { @@ -61,28 +43,53 @@ export async function getWebsites( { OR: [ { - ...(userId && { - userId, - }), + ...(userId && + !onlyTeams && { + userId, + }), }, { - ...(includeTeams && { - teamWebsite: { - some: { - team: { - teamUser: { - some: { - userId, + ...((includeTeams || onlyTeams) && { + AND: [ + { + teamWebsite: { + some: { + team: { + teamUser: { + some: { + userId, + }, + }, }, }, }, }, - }, + { + userId: { + not: userId, + }, + }, + ], + }), + }, + ], + }, + { + OR: [ + { + ...((filterType === WEBSITE_FILTER_TYPES.all || + filterType === WEBSITE_FILTER_TYPES.name) && { + name: { startsWith: filter, mode: 'insensitive' }, + }), + }, + { + ...((filterType === WEBSITE_FILTER_TYPES.all || + filterType === WEBSITE_FILTER_TYPES.domain) && { + domain: { startsWith: filter, mode: 'insensitive' }, }), }, ], }, - { ...(filter && filterQuery) }, ], }; @@ -108,7 +115,27 @@ export async function getWebsitesByUserId( userId: string, filter?: WebsiteSearchFilter, ): Promise> { - return getWebsites({ userId, ...filter }); + return getWebsites( + { userId, ...filter }, + { + include: { + teamWebsite: { + include: { + team: { + select: { + name: true, + }, + }, + }, + }, + user: { + select: { + username: true, + }, + }, + }, + }, + ); } export async function getWebsitesByTeamId( From 96d74783e06ed5bedb79588f404421409392c5d2 Mon Sep 17 00:00:00 2001 From: Brian Cao Date: Sun, 13 Aug 2023 22:32:25 -0700 Subject: [PATCH 3/7] Edit button states. --- components/pages/reports/ReportsTable.js | 17 ++++++++++++----- queries/admin/report.ts | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/components/pages/reports/ReportsTable.js b/components/pages/reports/ReportsTable.js index e59e4069..39a35c96 100644 --- a/components/pages/reports/ReportsTable.js +++ b/components/pages/reports/ReportsTable.js @@ -1,9 +1,10 @@ -import { useState } from 'react'; -import { Flexbox, Icon, Icons, Text, Button, Modal } from 'react-basics'; +import ConfirmDeleteForm from 'components/common/ConfirmDeleteForm'; import LinkButton from 'components/common/LinkButton'; import SettingsTable from 'components/common/SettingsTable'; -import ConfirmDeleteForm from 'components/common/ConfirmDeleteForm'; import { useMessages } from 'hooks'; +import useUser from 'hooks/useUser'; +import { useState } from 'react'; +import { Button, Flexbox, Icon, Icons, Modal, Text } from 'react-basics'; export function ReportsTable({ data = [], @@ -16,6 +17,7 @@ export function ReportsTable({ }) { const [report, setReport] = useState(null); const { formatMessage, labels } = useMessages(); + const { user } = useUser(); const domainColumn = [ { @@ -49,14 +51,19 @@ export function ReportsTable({ filterValue={filterValue} > {row => { - const { id } = row; + const { + id, + userId: reportOwnerId, + website: { domain, userId: websiteOwnerId }, + } = row; if (showDomain) { - row.domain = row.website.domain; + row.domain = domain; } return ( {formatMessage(labels.view)} + {!showDomain || user.id === reportOwnerId || user.id === websiteOwnerId} - + {(!showTeam || ownerId === user.id) && ( + + + + )}