mirror of
https://github.com/kremalicious/umami.git
synced 2024-06-30 21:51:59 +02:00
Breakdown feature for insights report.
This commit is contained in:
parent
5e1111db5d
commit
f48720c915
|
@ -162,6 +162,13 @@ export const labels = defineMessages({
|
||||||
totalRecords: { id: 'labels.total-records', defaultMessage: 'Total records' },
|
totalRecords: { id: 'labels.total-records', defaultMessage: 'Total records' },
|
||||||
insights: { id: 'label.insights', defaultMessage: 'Insights' },
|
insights: { id: 'label.insights', defaultMessage: 'Insights' },
|
||||||
dropoff: { id: 'label.dropoff', defaultMessage: 'Dropoff' },
|
dropoff: { id: 'label.dropoff', defaultMessage: 'Dropoff' },
|
||||||
|
referrer: { id: 'label.referrer', defaultMessage: 'Referrer' },
|
||||||
|
country: { id: 'label.country', defaultMessage: 'Country' },
|
||||||
|
region: { id: 'label.region', defaultMessage: 'Region' },
|
||||||
|
city: { id: 'label.city', defaultMessage: 'City' },
|
||||||
|
browser: { id: 'label.browser', defaultMessage: 'Browser' },
|
||||||
|
device: { id: 'label.device', defaultMessage: 'Device' },
|
||||||
|
pageTitle: { id: 'label.pageTitle', defaultMessage: 'Page title' },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const messages = defineMessages({
|
export const messages = defineMessages({
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import FunnelReport from './funnel/FunnelReport';
|
import FunnelReport from './funnel/FunnelReport';
|
||||||
import EventDataReport from './event-data/EventDataReport';
|
import EventDataReport from './event-data/EventDataReport';
|
||||||
|
import InsightsReport from './insights/InsightsReport';
|
||||||
|
|
||||||
const reports = {
|
const reports = {
|
||||||
funnel: FunnelReport,
|
funnel: FunnelReport,
|
||||||
'event-data': EventDataReport,
|
'event-data': EventDataReport,
|
||||||
|
insights: InsightsReport,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ReportDetails({ reportId, reportType }) {
|
export default function ReportDetails({ reportId, reportType }) {
|
||||||
|
|
|
@ -11,20 +11,6 @@ import PopupForm from '../PopupForm';
|
||||||
import FilterSelectForm from '../FilterSelectForm';
|
import FilterSelectForm from '../FilterSelectForm';
|
||||||
import FieldSelectForm from '../FieldSelectForm';
|
import FieldSelectForm from '../FieldSelectForm';
|
||||||
|
|
||||||
const fieldOptions = [
|
|
||||||
{ name: 'url', type: 'string' },
|
|
||||||
{ name: 'title', type: 'string' },
|
|
||||||
{ name: 'referrer', type: 'string' },
|
|
||||||
{ name: 'query', type: 'string' },
|
|
||||||
{ name: 'browser', type: 'string' },
|
|
||||||
{ name: 'os', type: 'string' },
|
|
||||||
{ name: 'device', type: 'string' },
|
|
||||||
{ name: 'country', type: 'string' },
|
|
||||||
{ name: 'region', type: 'string' },
|
|
||||||
{ name: 'city', type: 'string' },
|
|
||||||
{ name: 'language', type: 'string' },
|
|
||||||
];
|
|
||||||
|
|
||||||
export function InsightsParameters() {
|
export function InsightsParameters() {
|
||||||
const { report, runReport, updateReport, isRunning } = useContext(ReportContext);
|
const { report, runReport, updateReport, isRunning } = useContext(ReportContext);
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
|
@ -33,9 +19,23 @@ export function InsightsParameters() {
|
||||||
const { websiteId, dateRange, filters, groups } = parameters || {};
|
const { websiteId, dateRange, filters, groups } = parameters || {};
|
||||||
const queryEnabled = websiteId && dateRange && (filters?.length || groups?.length);
|
const queryEnabled = websiteId && dateRange && (filters?.length || groups?.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) },
|
||||||
|
];
|
||||||
|
|
||||||
const parameterGroups = [
|
const parameterGroups = [
|
||||||
{ label: formatMessage(labels.filters), group: REPORT_PARAMETERS.filters },
|
|
||||||
{ label: formatMessage(labels.breakdown), group: REPORT_PARAMETERS.groups },
|
{ label: formatMessage(labels.breakdown), group: REPORT_PARAMETERS.groups },
|
||||||
|
{ label: formatMessage(labels.filters), group: REPORT_PARAMETERS.filters },
|
||||||
];
|
];
|
||||||
|
|
||||||
const parameterData = {
|
const parameterData = {
|
||||||
|
@ -71,12 +71,12 @@ export function InsightsParameters() {
|
||||||
{(close, element) => {
|
{(close, element) => {
|
||||||
return (
|
return (
|
||||||
<PopupForm element={element} onClose={close}>
|
<PopupForm element={element} onClose={close}>
|
||||||
{group === REPORT_PARAMETERS.filters && (
|
|
||||||
<FilterSelectForm fields={fieldOptions} onSelect={handleAdd.bind(null, group)} />
|
|
||||||
)}
|
|
||||||
{group === REPORT_PARAMETERS.groups && (
|
{group === REPORT_PARAMETERS.groups && (
|
||||||
<FieldSelectForm fields={fieldOptions} onSelect={handleAdd.bind(null, group)} />
|
<FieldSelectForm fields={fieldOptions} onSelect={handleAdd.bind(null, group)} />
|
||||||
)}
|
)}
|
||||||
|
{group === REPORT_PARAMETERS.filters && (
|
||||||
|
<FilterSelectForm fields={fieldOptions} onSelect={handleAdd.bind(null, group)} />
|
||||||
|
)}
|
||||||
</PopupForm>
|
</PopupForm>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
@ -95,19 +95,19 @@ export function InsightsParameters() {
|
||||||
items={parameterData[group]}
|
items={parameterData[group]}
|
||||||
onRemove={index => handleRemove(group, index)}
|
onRemove={index => handleRemove(group, index)}
|
||||||
>
|
>
|
||||||
{({ name, value }) => {
|
{({ value, label }) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.parameter}>
|
<div className={styles.parameter}>
|
||||||
{group === REPORT_PARAMETERS.filters && (
|
|
||||||
<>
|
|
||||||
<div>{name}</div>
|
|
||||||
<div className={styles.op}>{value[0]}</div>
|
|
||||||
<div>{value[1]}</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{group === REPORT_PARAMETERS.groups && (
|
{group === REPORT_PARAMETERS.groups && (
|
||||||
<>
|
<>
|
||||||
<div>{name}</div>
|
<div>{label}</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{group === REPORT_PARAMETERS.filters && (
|
||||||
|
<>
|
||||||
|
<div>{label}</div>
|
||||||
|
<div className={styles.op}>{value[0]}</div>
|
||||||
|
<div>{value[1]}</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,14 +6,15 @@ import { ReportContext } from '../Report';
|
||||||
export function InsightsTable() {
|
export function InsightsTable() {
|
||||||
const { report } = useContext(ReportContext);
|
const { report } = useContext(ReportContext);
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { fields = [] } = report?.parameters || {};
|
const { groups = [] } = report?.parameters || {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GridTable data={report?.data || []}>
|
<GridTable data={report?.data || []}>
|
||||||
{fields.map(({ name }) => {
|
{groups.map(({ name, label }) => {
|
||||||
return <GridColumn key={name} name={name} label={name} />;
|
return <GridColumn key={name} name={name} label={label} />;
|
||||||
})}
|
})}
|
||||||
<GridColumn name="total" label={formatMessage(labels.total)} />
|
<GridColumn name="views" label={formatMessage(labels.views)} width="100px" />
|
||||||
|
<GridColumn name="visitors" label={formatMessage(labels.visitors)} width="100px" />
|
||||||
</GridTable>
|
</GridTable>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ export interface InsightsRequestBody {
|
||||||
};
|
};
|
||||||
fields: { name: string; type: string; value: string }[];
|
fields: { name: string; type: string; value: string }[];
|
||||||
filters: string[];
|
filters: string[];
|
||||||
groups: string[];
|
groups: { name: string; type: string }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async (
|
export default async (
|
||||||
|
@ -27,24 +27,19 @@ export default async (
|
||||||
const {
|
const {
|
||||||
websiteId,
|
websiteId,
|
||||||
dateRange: { startDate, endDate },
|
dateRange: { startDate, endDate },
|
||||||
fields,
|
|
||||||
filters,
|
|
||||||
groups,
|
groups,
|
||||||
|
filters,
|
||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
if (!(await canViewWebsite(req.auth, websiteId))) {
|
if (!(await canViewWebsite(req.auth, websiteId))) {
|
||||||
return unauthorized(res);
|
return unauthorized(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await getInsights(
|
const data = await getInsights(websiteId, groups, {
|
||||||
websiteId,
|
...filters,
|
||||||
{
|
startDate: new Date(startDate),
|
||||||
...filters,
|
endDate: new Date(endDate),
|
||||||
startDate: new Date(startDate),
|
});
|
||||||
endDate: new Date(endDate),
|
|
||||||
},
|
|
||||||
groups,
|
|
||||||
);
|
|
||||||
|
|
||||||
return ok(res, data);
|
return ok(res, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { EVENT_TYPE } from 'lib/constants';
|
||||||
import { QueryFilters } from 'lib/types';
|
import { QueryFilters } from 'lib/types';
|
||||||
|
|
||||||
export async function getInsights(
|
export async function getInsights(
|
||||||
...args: [websiteId: string, filters: QueryFilters, groups: { name: string; type: string }[]]
|
...args: [websiteId: string, groups: { name: string; type: string }[], filters: QueryFilters]
|
||||||
) {
|
) {
|
||||||
return runQuery({
|
return runQuery({
|
||||||
[PRISMA]: () => relationalQuery(...args),
|
[PRISMA]: () => relationalQuery(...args),
|
||||||
|
@ -15,8 +15,8 @@ export async function getInsights(
|
||||||
|
|
||||||
async function relationalQuery(
|
async function relationalQuery(
|
||||||
websiteId: string,
|
websiteId: string,
|
||||||
filters: QueryFilters,
|
|
||||||
groups: { name: string; type: string }[],
|
groups: { name: string; type: string }[],
|
||||||
|
filters: QueryFilters,
|
||||||
): Promise<
|
): Promise<
|
||||||
{
|
{
|
||||||
x: string;
|
x: string;
|
||||||
|
@ -48,8 +48,8 @@ async function relationalQuery(
|
||||||
|
|
||||||
async function clickhouseQuery(
|
async function clickhouseQuery(
|
||||||
websiteId: string,
|
websiteId: string,
|
||||||
filters: QueryFilters,
|
|
||||||
groups: { name: string; type: string }[],
|
groups: { name: string; type: string }[],
|
||||||
|
filters: QueryFilters,
|
||||||
): Promise<
|
): Promise<
|
||||||
{
|
{
|
||||||
x: string;
|
x: string;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user