Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
# Conflicts:
#	components/settings/WebsiteSettings.js
#	pages/api/websites/[id]/index.js
  • Loading branch information
mikecao committed Oct 12, 2022
2 parents 5e2d23f + 9a90d2e commit 8627782
Show file tree
Hide file tree
Showing 23 changed files with 147 additions and 97 deletions.
8 changes: 4 additions & 4 deletions components/pages/WebsiteList.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function WebsiteList({ websites, showCharts, limit }) {
const ordered = useMemo(
() =>
websites
.map(website => ({ ...website, order: websiteOrder.indexOf(website.id) || 0 }))
.map(website => ({ ...website, order: websiteOrder.indexOf(website.websiteUuid) || 0 }))
.sort(firstBy('order')),
[websites, websiteOrder],
);
Expand All @@ -46,11 +46,11 @@ export default function WebsiteList({ websites, showCharts, limit }) {

return (
<div>
{ordered.map(({ id, name, domain }, index) =>
{ordered.map(({ websiteUuid, name, domain }, index) =>
index < limit ? (
<div key={id} className={styles.website}>
<div key={websiteUuid} className={styles.website}>
<WebsiteChart
websiteId={id}
websiteId={websiteUuid}
title={name}
domain={domain}
showChart={showCharts}
Expand Down
28 changes: 16 additions & 12 deletions components/settings/WebsiteSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function WebsiteSettings() {
icon={<LinkIcon />}
size="small"
tooltip={<FormattedMessage id="message.get-share-url" defaultMessage="Get share URL" />}
tooltipId={`button-share-${row.id}`}
tooltipId={`button-share-${row.websiteUuid}`}
onClick={() => setShowUrl(row)}
/>
)}
Expand All @@ -56,42 +56,46 @@ export default function WebsiteSettings() {
tooltip={
<FormattedMessage id="message.get-tracking-code" defaultMessage="Get tracking code" />
}
tooltipId={`button-code-${row.id}`}
tooltipId={`button-code-${row.websiteUuid}`}
onClick={() => setShowCode(row)}
/>
<Button
icon={<Pen />}
size="small"
tooltip={<FormattedMessage id="label.edit" defaultMessage="Edit" />}
tooltipId={`button-edit-${row.id}`}
tooltipId={`button-edit-${row.websiteUuid}`}
onClick={() => setEditWebsite(row)}
/>
<Button
icon={<Reset />}
size="small"
tooltip={<FormattedMessage id="label.reset" defaultMessage="Reset" />}
tooltipId={`button-reset-${row.id}`}
tooltipId={`button-reset-${row.websiteUuid}`}
onClick={() => setResetWebsite(row)}
/>
<Button
icon={<Trash />}
size="small"
tooltip={<FormattedMessage id="label.delete" defaultMessage="Delete" />}
tooltipId={`button-delete-${row.id}`}
tooltipId={`button-delete-${row.websiteUuid}`}
onClick={() => setDeleteWebsite(row)}
/>
</ButtonLayout>
);

const DetailsLink = ({ id, name, domain }) => (
<Link className={styles.detailLink} href="/websites/[...id]" as={`/websites/${id}/${name}`}>
const DetailsLink = ({ websiteUuid, name, domain }) => (
<Link
className={styles.detailLink}
href="/websites/[...id]"
as={`/websites/${websiteUuid}/${name}`}
>
<Favicon domain={domain} />
<OverflowText tooltipId={`${id}-name`}>{name}</OverflowText>
<OverflowText tooltipId={`${websiteUuid}-name`}>{name}</OverflowText>
</Link>
);

const Domain = ({ domain, id }) => (
<OverflowText tooltipId={`${id}-domain`}>{domain}</OverflowText>
const Domain = ({ domain, websiteUuid }) => (
<OverflowText tooltipId={`${websiteUuid}-domain`}>{domain}</OverflowText>
);

const adminColumns = [
Expand Down Expand Up @@ -199,7 +203,7 @@ export default function WebsiteSettings() {
title={<FormattedMessage id="label.reset-website" defaultMessage="Reset statistics" />}
>
<ResetForm
values={{ type: 'websites', id: resetWebsite.id, name: resetWebsite.name }}
values={{ type: 'websites', id: resetWebsite.websiteUuid, name: resetWebsite.name }}
onSave={handleSave}
onClose={handleClose}
/>
Expand All @@ -210,7 +214,7 @@ export default function WebsiteSettings() {
title={<FormattedMessage id="label.delete-website" defaultMessage="Delete website" />}
>
<DeleteForm
values={{ type: 'websites', id: deleteWebsite.id, name: deleteWebsite.name }}
values={{ type: 'websites', id: deleteWebsite.websiteUuid, name: deleteWebsite.name }}
onSave={handleSave}
onClose={handleClose}
/>
Expand Down
20 changes: 10 additions & 10 deletions db/clickhouse/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ SET allow_experimental_object_type = 1;
-- Create Event
CREATE TABLE event
(
website_id UInt32,
session_uuid UUID,
event_uuid Nullable(UUID),
website_id UUID,
session_id UUID,
event_id Nullable(UUID),
--session
hostname LowCardinality(String),
browser LowCardinality(String),
Expand All @@ -23,13 +23,13 @@ CREATE TABLE event
created_at DateTime('UTC')
)
engine = MergeTree
ORDER BY (website_id, session_uuid, created_at)
ORDER BY (website_id, session_id, created_at)
SETTINGS index_granularity = 8192;

CREATE TABLE event_queue (
website_id UInt32,
session_uuid UUID,
event_uuid Nullable(UUID),
website_id UUID,
session_id UUID,
event_id Nullable(UUID),
url String,
referrer String,
hostname LowCardinality(String),
Expand All @@ -44,7 +44,7 @@ CREATE TABLE event_queue (
created_at DateTime('UTC')
)
ENGINE = Kafka
SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input broker list
SETTINGS kafka_broker_list = 'dev-01.umami.dev:9092,dev-01.umami.dev:9093,dev-01.umami.dev:9094', -- input broker list
kafka_topic_list = 'event',
kafka_group_name = 'event_consumer_group',
kafka_format = 'JSONEachRow',
Expand All @@ -53,8 +53,8 @@ SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input bro

CREATE MATERIALIZED VIEW event_queue_mv TO event AS
SELECT website_id,
session_uuid,
event_uuid,
session_id,
event_id,
url,
referrer,
hostname,
Expand Down
5 changes: 5 additions & 0 deletions lib/clickhouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ function getDateFormat(date) {
return `'${dateFormat(date, 'UTC:yyyy-mm-dd HH:MM:ss')}'`;
}

function getCommaSeparatedStringFormat(data) {
return data.map(a => `'${a}'`).join(',');
}

function getBetweenDates(field, start_at, end_at) {
return `${field} between ${getDateFormat(start_at)}
and ${getDateFormat(end_at)}`;
Expand Down Expand Up @@ -180,6 +184,7 @@ export default {
getDateStringQuery,
getDateQuery,
getDateFormat,
getCommaSeparatedStringFormat,
getBetweenDates,
getFilterQuery,
parseFilters,
Expand Down
4 changes: 1 addition & 3 deletions pages/api/websites/[id]/active.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ export default async (req, res) => {
return unauthorized(res);
}

const { id } = req.query;

const websiteId = +id;
const { id: websiteId } = req.query;

const result = await getActiveVisitors(websiteId);

Expand Down
4 changes: 1 addition & 3 deletions pages/api/websites/[id]/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ export default async (req, res) => {
return unauthorized(res);
}

const { id, start_at, end_at, unit, tz, url, event_name } = req.query;
const { id: websiteId, start_at, end_at, unit, tz, url, event_name } = req.query;

if (!moment.tz.zone(tz) || !unitTypes.includes(unit)) {
return badRequest(res);
}

const websiteId = +id;
const startDate = new Date(+start_at);
const endDate = new Date(+end_at);

Expand Down
25 changes: 10 additions & 15 deletions pages/api/websites/[id]/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
import { methodNotAllowed, ok, unauthorized, getRandomChars } from 'next-basics';
import { deleteWebsite, getAccount, getWebsite, updateWebsite } from 'queries';
import { allowQuery } from 'lib/auth';
import { useAuth, useCors } from 'lib/middleware';
import { validate } from 'uuid';
import { getRandomChars, methodNotAllowed, ok, unauthorized } from 'next-basics';
import { deleteWebsite, getAccount, getWebsite, getWebsiteByUuid, updateWebsite } from 'queries';

export default async (req, res) => {
await useAuth(req, res);

const { isAdmin, userId, accountUuid } = req.auth;

const { id } = req.query;

const websiteId = +id;
const where = validate(id) ? { websiteUuid: id } : { id: +id };
const { id: websiteId } = req.query;

if (req.method === 'GET') {
await useCors(req, res);
Expand All @@ -21,24 +13,27 @@ export default async (req, res) => {
return unauthorized(res);
}

const website = await getWebsite(where);
const website = await getWebsiteByUuid(websiteId);

return ok(res, website);
}

if (req.method === 'POST') {
await useAuth(req, res);

const { isAdmin: currentUserIsAdmin, userId: currentUserId, accountUuid } = req.auth;
const { name, domain, owner, enable_share_url } = req.body;
let account;

if (accountUuid) {
account = await getAccount({ accountUuid });
}

const website = await getWebsite(where);
const website = await getWebsite(websiteId);

const shareId = enable_share_url ? website.shareId || getRandomChars(8) : null;

if (website.userId !== userId && !isAdmin) {
if (website.userId !== currentUserId && !currentUserIsAdmin) {
return unauthorized(res);
}

Expand All @@ -49,7 +44,7 @@ export default async (req, res) => {
shareId: shareId,
userId: account ? account.id : +owner,
},
where,
{ websiteUuid: websiteId },
);

return ok(res);
Expand Down
22 changes: 16 additions & 6 deletions pages/api/websites/[id]/metrics.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { getPageviewMetrics, getSessionMetrics, getWebsiteById } from 'queries';
import { ok, methodNotAllowed, unauthorized, badRequest } from 'next-basics';
import { allowQuery } from 'lib/auth';
import { useCors } from 'lib/middleware';
import { FILTER_IGNORED } from 'lib/constants';
import { useCors } from 'lib/middleware';
import { badRequest, methodNotAllowed, ok, unauthorized } from 'next-basics';
import { getPageviewMetrics, getSessionMetrics, getWebsiteByUuid } from 'queries';

const sessionColumns = ['browser', 'os', 'device', 'screen', 'country', 'language'];
const pageviewColumns = ['url', 'referrer', 'query'];
Expand Down Expand Up @@ -41,9 +41,19 @@ export default async (req, res) => {
return unauthorized(res);
}

const { id, type, start_at, end_at, url, referrer, os, browser, device, country } = req.query;
const {
id: websiteId,
type,
start_at,
end_at,
url,
referrer,
os,
browser,
device,
country,
} = req.query;

const websiteId = +id;
const startDate = new Date(+start_at);
const endDate = new Date(+end_at);

Expand Down Expand Up @@ -83,7 +93,7 @@ export default async (req, res) => {
let domain;

if (type === 'referrer') {
const website = await getWebsiteById(websiteId);
const website = await getWebsiteByUuid(websiteId);

if (!website) {
return badRequest(res);
Expand Down
16 changes: 13 additions & 3 deletions pages/api/websites/[id]/pageviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,20 @@ export default async (req, res) => {
return unauthorized(res);
}

const { id, start_at, end_at, unit, tz, url, referrer, os, browser, device, country } =
req.query;
const {
id: websiteId,
start_at,
end_at,
unit,
tz,
url,
referrer,
os,
browser,
device,
country,
} = req.query;

const websiteId = +id;
const startDate = new Date(+start_at);
const endDate = new Date(+end_at);

Expand Down
3 changes: 1 addition & 2 deletions pages/api/websites/[id]/reset.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { allowQuery } from 'lib/auth';

export default async (req, res) => {
const { id } = req.query;
const websiteId = +id;
const { id: websiteId } = req.query;

if (req.method === 'POST') {
if (!(await allowQuery(req))) {
Expand Down
13 changes: 11 additions & 2 deletions pages/api/websites/[id]/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@ export default async (req, res) => {
return unauthorized(res);
}

const { website_id, start_at, end_at, url, referrer, os, browser, device, country } = req.query;
const {
id: websiteId,
start_at,
end_at,
url,
referrer,
os,
browser,
device,
country,
} = req.query;

const websiteId = +website_id;
const startDate = new Date(+start_at);
const endDate = new Date(+end_at);

Expand Down
14 changes: 7 additions & 7 deletions queries/admin/website/deleteWebsite.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import prisma from 'lib/prisma';
import redis, { DELETED } from 'lib/redis';
import { getWebsiteById } from 'queries';
import { getWebsiteByUuid } from 'queries';

export async function deleteWebsite(websiteId) {
const { client, transaction } = prisma;

const { websiteUuid } = await getWebsiteById(websiteId);
const { websiteUuid } = await getWebsiteByUuid(websiteId);

return transaction([
client.pageview.deleteMany({
where: { session: { website: { id: websiteId } } },
where: { session: { website: { websiteUuid: websiteId } } },
}),
client.eventData.deleteMany({
where: { event: { session: { website: { id: websiteId } } } },
where: { event: { session: { website: { websiteUuid: websiteId } } } },
}),
client.event.deleteMany({
where: { session: { website: { id: websiteId } } },
where: { session: { website: { websiteUuid: websiteId } } },
}),
client.session.deleteMany({
where: { website: { id: websiteId } },
where: { website: { websiteUuid: websiteId } },
}),
client.website.delete({
where: { id: websiteId },
where: { websiteUuid: websiteId },
}),
]).then(async res => {
if (redis.client) {
Expand Down
Loading

0 comments on commit 8627782

Please sign in to comment.