diff --git a/components/pages/reports/FieldSelectForm.js b/components/pages/reports/FieldSelectForm.js index 69f399bb..30fd193d 100644 --- a/components/pages/reports/FieldSelectForm.js +++ b/components/pages/reports/FieldSelectForm.js @@ -2,14 +2,14 @@ import { Menu, Item, Form, FormRow } from 'react-basics'; import { useMessages } from 'hooks'; import styles from './FieldSelectForm.module.css'; -export default function FieldSelectForm({ fields, onSelect }) { +export default function FieldSelectForm({ items, onSelect }) { const { formatMessage, labels } = useMessages(); return (
- onSelect(fields[key])}> - {fields.map(({ label, name, type }, index) => { + onSelect(items[key])}> + {items.map(({ name, label, type }, index) => { return (
{label || name}
diff --git a/components/pages/reports/FilterSelectForm.js b/components/pages/reports/FilterSelectForm.js index 0dc107b0..29493b08 100644 --- a/components/pages/reports/FilterSelectForm.js +++ b/components/pages/reports/FilterSelectForm.js @@ -2,11 +2,11 @@ import { useState } from 'react'; import FieldSelectForm from './FieldSelectForm'; import FieldFilterForm from './FieldFilterForm'; -export default function FilterSelectForm({ fields, onSelect }) { +export default function FilterSelectForm({ items, onSelect }) { const [field, setField] = useState(); if (!field) { - return ; + return ; } return ; diff --git a/components/pages/reports/insights/InsightsParameters.js b/components/pages/reports/insights/InsightsParameters.js index 5d7e1fca..4ec60a9a 100644 --- a/components/pages/reports/insights/InsightsParameters.js +++ b/components/pages/reports/insights/InsightsParameters.js @@ -2,7 +2,6 @@ import { useContext, useRef } from 'react'; import { useMessages } from 'hooks'; import { Form, FormRow, FormButtons, SubmitButton, PopupTrigger, Icon, Popup } from 'react-basics'; import { ReportContext } from 'components/pages/reports/Report'; -import { REPORT_PARAMETERS } from 'lib/constants'; import Icons from 'components/icons'; import BaseParameters from '../BaseParameters'; import ParameterList from '../ParameterList'; @@ -16,52 +15,52 @@ export function InsightsParameters() { const { formatMessage, labels } = useMessages(); const ref = useRef(null); const { parameters } = report || {}; - const { websiteId, dateRange, filters, groups } = parameters || {}; - const queryEnabled = websiteId && dateRange && (filters?.length || groups?.length); + const { websiteId, dateRange, fields, filters } = parameters || {}; + const queryEnabled = websiteId && dateRange && (fields?.length || filters?.length); const fieldOptions = [ - { name: 'url_path', type: 'string', label: formatMessage(labels.url) }, - { name: 'page_title', type: 'string', label: formatMessage(labels.pageTitle) }, - { name: 'referrer_domain', type: 'string', label: formatMessage(labels.referrer) }, - { name: 'url_query', type: 'string', label: formatMessage(labels.query) }, - { name: 'browser', type: 'string', label: formatMessage(labels.browser) }, - { name: 'os', type: 'string', label: formatMessage(labels.os) }, - { name: 'device', type: 'string', label: formatMessage(labels.device) }, - { name: 'country', type: 'string', label: formatMessage(labels.country) }, - { name: 'region', type: 'string', label: formatMessage(labels.region) }, - { name: 'city', type: 'string', label: formatMessage(labels.city) }, - { name: 'language', type: 'string', label: formatMessage(labels.language) }, + { name: 'url_path', label: formatMessage(labels.url) }, + { name: 'page_title', label: formatMessage(labels.pageTitle) }, + { name: 'referrer_domain', label: formatMessage(labels.referrer) }, + { name: 'url_query', label: formatMessage(labels.query) }, + { name: 'browser', label: formatMessage(labels.browser) }, + { name: 'os', label: formatMessage(labels.os) }, + { name: 'device', label: formatMessage(labels.device) }, + { name: 'country', label: formatMessage(labels.country) }, + { name: 'region', label: formatMessage(labels.region) }, + { name: 'city', label: formatMessage(labels.city) }, + { name: 'language', label: formatMessage(labels.language) }, ]; const parameterGroups = [ - { label: formatMessage(labels.breakdown), group: REPORT_PARAMETERS.groups }, - { label: formatMessage(labels.filters), group: REPORT_PARAMETERS.filters }, + { id: 'fields', label: formatMessage(labels.fields) }, + { id: 'filters', label: formatMessage(labels.filters) }, ]; const parameterData = { + fields, filters, - groups, }; const handleSubmit = values => { runReport(values); }; - const handleAdd = (group, value) => { - const data = parameterData[group]; + const handleAdd = (id, value) => { + const data = parameterData[id]; if (!data.find(({ name }) => name === value.name)) { - updateReport({ parameters: { [group]: data.concat(value) } }); + updateReport({ parameters: { [id]: data.concat(value) } }); } }; - const handleRemove = (group, index) => { - const data = [...parameterData[group]]; + const handleRemove = (id, index) => { + const data = [...parameterData[id]]; data.splice(index, 1); - updateReport({ parameters: { [group]: data } }); + updateReport({ parameters: { [id]: data } }); }; - const AddButton = ({ group }) => { + const AddButton = ({ id }) => { return ( @@ -71,11 +70,11 @@ export function InsightsParameters() { {(close, element) => { return ( - {group === REPORT_PARAMETERS.groups && ( - + {id === 'fields' && ( + )} - {group === REPORT_PARAMETERS.filters && ( - + {id === 'filters' && ( + )} ); @@ -88,22 +87,19 @@ export function InsightsParameters() { return ( - {parameterGroups.map(({ label, group }) => { + {parameterGroups.map(({ id, label }) => { return ( - }> - handleRemove(group, index)} - > + }> + handleRemove(id, index)}> {({ value, label }) => { return (
- {group === REPORT_PARAMETERS.groups && ( + {id === 'fields' && ( <>
{label}
)} - {group === REPORT_PARAMETERS.filters && ( + {id === 'filters' && ( <>
{label}
{value[0]}
diff --git a/components/pages/reports/insights/InsightsTable.js b/components/pages/reports/insights/InsightsTable.js index 24960254..0d5298e4 100644 --- a/components/pages/reports/insights/InsightsTable.js +++ b/components/pages/reports/insights/InsightsTable.js @@ -1,29 +1,42 @@ -import { useContext } from 'react'; +import { useContext, useEffect, useState } from 'react'; import { GridTable, GridColumn } from 'react-basics'; import { useFormat, useMessages } from 'hooks'; import { ReportContext } from '../Report'; +import EmptyPlaceholder from 'components/common/EmptyPlaceholder'; export function InsightsTable() { + const [fields, setFields] = useState(); const { report } = useContext(ReportContext); const { formatMessage, labels } = useMessages(); - const { groups = [] } = report?.parameters || {}; const { formatValue } = useFormat(); + useEffect( + () => { + setFields(report?.parameters?.fields); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [report?.data], + ); + + if (!fields) { + return ; + } + return ( - {groups.map(({ name, label }) => { + {fields.map(({ name, label }) => { return ( {row => formatValue(row[name], name)} ); })} - - {row => row.views.toLocaleString()} - {row => row.visitors.toLocaleString()} + + {row => row.views.toLocaleString()} + ); } diff --git a/pages/api/reports/insights.ts b/pages/api/reports/insights.ts index 44f72063..decb1f81 100644 --- a/pages/api/reports/insights.ts +++ b/pages/api/reports/insights.ts @@ -27,7 +27,7 @@ export default async ( const { websiteId, dateRange: { startDate, endDate }, - groups, + fields, filters, } = req.body; @@ -35,7 +35,7 @@ export default async ( return unauthorized(res); } - const data = await getInsights(websiteId, groups, { + const data = await getInsights(websiteId, fields, { ...filters, startDate: new Date(startDate), endDate: new Date(endDate), diff --git a/queries/analytics/reports/getInsights.ts b/queries/analytics/reports/getInsights.ts index b7c8777d..4c47052b 100644 --- a/queries/analytics/reports/getInsights.ts +++ b/queries/analytics/reports/getInsights.ts @@ -5,7 +5,7 @@ import { EVENT_TYPE } from 'lib/constants'; import { QueryFilters } from 'lib/types'; export async function getInsights( - ...args: [websiteId: string, groups: { name: string; type: string }[], filters: QueryFilters] + ...args: [websiteId: string, fields: { name: string; type?: string }[], filters: QueryFilters] ) { return runQuery({ [PRISMA]: () => relationalQuery(...args), @@ -15,7 +15,7 @@ export async function getInsights( async function relationalQuery( websiteId: string, - groups: { name: string; type: string }[], + fields: { name: string; type?: string }[], filters: QueryFilters, ): Promise< { @@ -49,7 +49,7 @@ async function relationalQuery( async function clickhouseQuery( websiteId: string, - groups: { name: string; type: string }[], + fields: { name: string; type?: string }[], filters: QueryFilters, ): Promise< { @@ -66,14 +66,14 @@ async function clickhouseQuery( return rawQuery( ` select - ${parseFields(groups)} + ${parseFields(fields)} from website_event where website_id = {websiteId:UUID} and created_at between {startDate:DateTime} and {endDate:DateTime} and event_type = {eventType:UInt32} ${filterQuery} - group by ${groups.map(({ name }) => name).join(',')} - order by 1 desc + group by ${fields.map(({ name }) => name).join(',')} + order by 1 desc, 2 desc limit 500 `, params,