Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Mike Cao 2023-07-07 20:39:56 -07:00
commit f9d09c8b54
17 changed files with 108 additions and 69 deletions

View File

@ -15,6 +15,7 @@ export const labels = defineMessages({
password: { id: 'label.password', defaultMessage: 'Password' },
role: { id: 'label.role', defaultMessage: 'Role' },
user: { id: 'label.user', defaultMessage: 'User' },
viewOnly: { id: 'label.view-only', defaultMessage: 'View only' },
admin: { id: 'label.admin', defaultMessage: 'Administrator' },
confirm: { id: 'label.confirm', defaultMessage: 'Confirm' },
details: { id: 'label.details', defaultMessage: 'Details' },

View File

@ -7,6 +7,7 @@ import PasswordChangeButton from './PasswordChangeButton';
import useUser from 'hooks/useUser';
import useMessages from 'hooks/useMessages';
import useConfig from 'hooks/useConfig';
import { ROLES } from 'lib/constants';
export function ProfileDetails() {
const { user } = useUser();
@ -19,12 +20,24 @@ export function ProfileDetails() {
const { username, role } = user;
const renderRole = value => {
if (value === ROLES.user) {
return formatMessage(labels.user);
}
if (value === ROLES.admin) {
return formatMessage(labels.admin);
}
if (value === ROLES.viewOnly) {
return formatMessage(labels.viewOnly);
}
return formatMessage(labels.unknown);
};
return (
<Form>
<FormRow label={formatMessage(labels.username)}>{username}</FormRow>
<FormRow label={formatMessage(labels.role)}>
{formatMessage(labels[role] || labels.unknown)}
</FormRow>
<FormRow label={formatMessage(labels.role)}>{renderRole(role)}</FormRow>
{!cloudMode && (
<FormRow label={formatMessage(labels.password)}>
<PasswordChangeButton />

View File

@ -9,8 +9,11 @@ import Icons from 'components/icons';
import TeamJoinForm from './TeamJoinForm';
import useApi from 'hooks/useApi';
import useMessages from 'hooks/useMessages';
import { ROLES } from 'lib/constants';
import useUser from 'hooks/useUser';
export default function TeamsList() {
const { user } = useUser();
const { formatMessage, labels, messages } = useMessages();
const [update, setUpdate] = useState(0);
const { get, useQuery } = useApi();
@ -48,17 +51,21 @@ export default function TeamsList() {
);
const createButton = (
<ModalTrigger>
<Button variant="primary">
<Icon>
<Icons.Plus />
</Icon>
<Text>{formatMessage(labels.createTeam)}</Text>
</Button>
<Modal title={formatMessage(labels.createTeam)}>
{close => <TeamAddForm onSave={handleSave} onClose={close} />}
</Modal>
</ModalTrigger>
<>
{user.role !== ROLES.viewOnly && (
<ModalTrigger>
<Button variant="primary">
<Icon>
<Icons.Plus />
</Icon>
<Text>{formatMessage(labels.createTeam)}</Text>
</Button>
<Modal title={formatMessage(labels.createTeam)}>
{close => <TeamAddForm onSave={handleSave} onClose={close} />}
</Modal>
</ModalTrigger>
)}
</>
);
return (

View File

@ -35,6 +35,9 @@ export function UserAddForm({ onSave, onClose }) {
if (value === ROLES.admin) {
return formatMessage(labels.admin);
}
if (value === ROLES.viewOnly) {
return formatMessage(labels.viewOnly);
}
};
return (
@ -52,6 +55,7 @@ export function UserAddForm({ onSave, onClose }) {
<FormRow label={formatMessage(labels.role)}>
<FormInput name="role" rules={{ required: formatMessage(labels.required) }}>
<Dropdown renderValue={renderValue}>
<Item key={ROLES.viewOnly}>{formatMessage(labels.viewOnly)}</Item>
<Item key={ROLES.user}>{formatMessage(labels.user)}</Item>
<Item key={ROLES.admin}>{formatMessage(labels.admin)}</Item>
</Dropdown>

View File

@ -35,6 +35,9 @@ export function UserEditForm({ userId, data, onSave }) {
if (value === ROLES.admin) {
return formatMessage(labels.admin);
}
if (value === ROLES.viewOnly) {
return formatMessage(labels.viewOnly);
}
};
return (
@ -57,6 +60,7 @@ export function UserEditForm({ userId, data, onSave }) {
<FormRow label={formatMessage(labels.role)}>
<FormInput name="role" rules={{ required: formatMessage(labels.required) }}>
<Dropdown renderValue={renderValue}>
<Item key={ROLES.viewOnly}>{formatMessage(labels.viewOnly)}</Item>
<Item key={ROLES.user}>{formatMessage(labels.user)}</Item>
<Item key={ROLES.admin}>{formatMessage(labels.admin)}</Item>
</Dropdown>

View File

@ -7,6 +7,7 @@ import WebsitesTable from 'components/pages/settings/websites/WebsitesTable';
import useApi from 'hooks/useApi';
import useUser from 'hooks/useUser';
import useMessages from 'hooks/useMessages';
import { ROLES } from 'lib/constants';
export function WebsitesList() {
const { formatMessage, labels, messages } = useMessages();
@ -26,17 +27,21 @@ export function WebsitesList() {
};
const addButton = (
<ModalTrigger>
<Button variant="primary">
<Icon>
<Icons.Plus />
</Icon>
<Text>{formatMessage(labels.addWebsite)}</Text>
</Button>
<Modal title={formatMessage(labels.addWebsite)}>
{close => <WebsiteAddForm onSave={handleSave} onClose={close} />}
</Modal>
</ModalTrigger>
<>
{user.role !== ROLES.viewOnly && (
<ModalTrigger>
<Button variant="primary">
<Icon>
<Icons.Plus />
</Icon>
<Text>{formatMessage(labels.addWebsite)}</Text>
</Button>
<Modal title={formatMessage(labels.addWebsite)}>
{close => <WebsiteAddForm onSave={handleSave} onClose={close} />}
</Modal>
</ModalTrigger>
)}
</>
);
return (

View File

@ -1,4 +1,9 @@
-- edit event_data values
ALTER TABLE "event_data" RENAME COLUMN "event_date_value" TO "date_value";
ALTER TABLE "event_data" RENAME COLUMN "event_numeric_value" TO "numeric_value";
ALTER TABLE "event_data" RENAME COLUMN "event_numeric_value" TO "number_value";
ALTER TABLE "event_data" RENAME COLUMN "event_string_value" TO "string_value";
ALTER TABLE "event_data" RENAME COLUMN "event_data_type" TO "data_type";
ALTER TABLE "event_data" RENAME COLUMN "event_data_type" TO "data_type";
-- add job_id
ALTER TABLE "website_event" ADD COLUMN "job_id" UUID AFTER "created_at";
ALTER TABLE "event_data" ADD COLUMN "job_id" UUID AFTER "created_at";

View File

@ -1,2 +0,0 @@
ALTER TABLE "website_event" ADD COLUMN "job_id" UUID AFTER "created_at";
ALTER TABLE "event_data" ADD COLUMN "job_id" UUID AFTER "created_at";

View File

@ -119,7 +119,7 @@ CREATE TABLE umami.event_data
event_name String,
event_key String,
string_value Nullable(String),
numeric_value Nullable(Decimal64(4)), --922337203685477.5625
number_value Nullable(Decimal64(4)), --922337203685477.5625
date_value Nullable(DateTime('UTC')),
data_type UInt32,
created_at DateTime('UTC'),
@ -137,7 +137,7 @@ CREATE TABLE umami.event_data_queue (
event_name String,
event_key String,
string_value Nullable(String),
numeric_value Nullable(Decimal64(4)), --922337203685477.5625
number_value Nullable(Decimal64(4)), --922337203685477.5625
date_value Nullable(DateTime('UTC')),
data_type UInt32,
created_at DateTime('UTC'),
@ -161,7 +161,7 @@ SELECT website_id,
event_name,
event_key,
string_value,
numeric_value,
number_value,
date_value,
data_type,
created_at

View File

@ -15,7 +15,7 @@
ALTER TABLE `event_data` RENAME COLUMN `event_data_type` TO `data_type`;
ALTER TABLE `event_data` RENAME COLUMN `event_date_value` TO `date_value`;
ALTER TABLE `event_data` RENAME COLUMN `event_id` TO `event_data_id`;
ALTER TABLE `event_data` RENAME COLUMN `event_numeric_value` TO `numeric_value`;
ALTER TABLE `event_data` RENAME COLUMN `event_numeric_value` TO `number_value`;
ALTER TABLE `event_data` RENAME COLUMN `event_string_value` TO `string_value`;
-- CreateTable
@ -24,10 +24,10 @@ CREATE TABLE `session_data` (
`website_id` VARCHAR(36) NOT NULL,
`session_id` VARCHAR(36) NOT NULL,
`event_key` VARCHAR(500) NOT NULL,
`event_string_value` VARCHAR(500) NULL,
`event_numeric_value` DECIMAL(19, 4) NULL,
`event_date_value` TIMESTAMP(0) NULL,
`event_data_type` INTEGER UNSIGNED NOT NULL,
`string_value` VARCHAR(500) NULL,
`number_value` DECIMAL(19, 4) NULL,
`date_value` TIMESTAMP(0) NULL,
`data_type` INTEGER UNSIGNED NOT NULL,
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
INDEX `session_data_created_at_idx`(`created_at`),

View File

@ -101,7 +101,7 @@ model EventData {
websiteId String @map("website_id") @db.VarChar(36)
eventKey String @map("event_key") @db.VarChar(500)
stringValue String? @map("string_value") @db.VarChar(500)
numericValue Decimal? @map("numeric_value") @db.Decimal(19, 4)
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
dateValue DateTime? @map("date_value") @db.Timestamp(0)
dataType Int @map("data_type") @db.UnsignedInt
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
@ -117,15 +117,15 @@ model EventData {
}
model SessionData {
id String @id() @map("session_data_id") @db.VarChar(36)
websiteId String @map("website_id") @db.VarChar(36)
sessionId String @map("session_id") @db.VarChar(36)
eventKey String @map("event_key") @db.VarChar(500)
eventStringValue String? @map("event_string_value") @db.VarChar(500)
eventNumericValue Decimal? @map("event_numeric_value") @db.Decimal(19, 4)
eventDateValue DateTime? @map("event_date_value") @db.Timestamp(0)
eventDataType Int @map("event_data_type") @db.UnsignedInt
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
id String @id() @map("session_data_id") @db.VarChar(36)
websiteId String @map("website_id") @db.VarChar(36)
sessionId String @map("session_id") @db.VarChar(36)
eventKey String @map("event_key") @db.VarChar(500)
stringValue String? @map("string_value") @db.VarChar(500)
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
dateValue DateTime? @map("date_value") @db.Timestamp(0)
dataType Int @map("data_type") @db.UnsignedInt
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamp(0)
website Website @relation(fields: [websiteId], references: [id])
session Session @relation(fields: [sessionId], references: [id])

View File

@ -2,7 +2,7 @@
ALTER TABLE "event_data" RENAME COLUMN "event_data_type" TO "data_type";
ALTER TABLE "event_data" RENAME COLUMN "event_date_value" TO "date_value";
ALTER TABLE "event_data" RENAME COLUMN "event_id" TO "event_data_id";
ALTER TABLE "event_data" RENAME COLUMN "event_numeric_value" TO "numeric_value";
ALTER TABLE "event_data" RENAME COLUMN "event_numeric_value" TO "number_value";
ALTER TABLE "event_data" RENAME COLUMN "event_string_value" TO "string_value";
-- CreateTable
@ -12,7 +12,7 @@ CREATE TABLE "session_data" (
"session_id" UUID NOT NULL,
"session_key" VARCHAR(500) NOT NULL,
"string_value" VARCHAR(500),
"numeric_value" DECIMAL(19,4),
"number_value" DECIMAL(19,4),
"date_value" TIMESTAMPTZ(6),
"data_type" INTEGER NOT NULL,
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,

View File

@ -101,7 +101,7 @@ model EventData {
websiteEventId String @map("website_event_id") @db.Uuid
eventKey String @map("event_key") @db.VarChar(500)
stringValue String? @map("string_value") @db.VarChar(500)
numericValue Decimal? @map("numeric_value") @db.Decimal(19, 4)
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
dateValue DateTime? @map("date_value") @db.Timestamptz(6)
dataType Int @map("data_type") @db.Integer
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
@ -116,16 +116,16 @@ model EventData {
}
model SessionData {
id String @id() @map("session_data_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid
sessionId String @map("session_id") @db.Uuid
sessionKey String @map("session_key") @db.VarChar(500)
stringValue String? @map("string_value") @db.VarChar(500)
numericValue Decimal? @map("numeric_value") @db.Decimal(19, 4)
dateValue DateTime? @map("date_value") @db.Timestamptz(6)
dataType Int @map("data_type") @db.Integer
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
deletedAt DateTime? @default(now()) @map("deleted_at") @db.Timestamptz(6)
id String @id() @map("session_data_id") @db.Uuid
websiteId String @map("website_id") @db.Uuid
sessionId String @map("session_id") @db.Uuid
sessionKey String @map("session_key") @db.VarChar(500)
stringValue String? @map("string_value") @db.VarChar(500)
numberValue Decimal? @map("number_value") @db.Decimal(19, 4)
dateValue DateTime? @map("date_value") @db.Timestamptz(6)
dataType Int @map("data_type") @db.Integer
createdAt DateTime? @default(now()) @map("created_at") @db.Timestamptz(6)
deletedAt DateTime? @default(now()) @map("deleted_at") @db.Timestamptz(6)
website Website @relation(fields: [websiteId], references: [id])
session Session @relation(fields: [sessionId], references: [id])

View File

@ -82,17 +82,17 @@ function getEventDataFilterQuery(
switch (type) {
case 'number':
ac.push(`and event_numeric_value = {eventValue${i}:UInt64})`);
ac.push(`and number_value = {eventValue${i}:UInt64})`);
break;
case 'string':
ac.push(`and event_string_value = {eventValue${i}:String})`);
ac.push(`and string_value = {eventValue${i}:String})`);
break;
case 'boolean':
ac.push(`and event_string_value = {eventValue${i}:String})`);
ac.push(`and string_value = {eventValue${i}:String})`);
value = cv ? 'true' : 'false';
break;
case 'date':
ac.push(`and event_date_value = {eventValue${i}:DateTime('UTC')})`);
ac.push(`and date_value = {eventValue${i}:DateTime('UTC')})`);
break;
}

View File

@ -92,6 +92,7 @@ export const KAFKA_TOPIC = {
export const ROLES = {
admin: 'admin',
user: 'user',
viewOnly: 'view-only',
teamOwner: 'team-owner',
teamMember: 'team-member',
} as const;
@ -114,6 +115,7 @@ export const ROLE_PERMISSIONS = {
PERMISSIONS.websiteDelete,
PERMISSIONS.teamCreate,
],
[ROLES.viewOnly]: [],
[ROLES.teamOwner]: [PERMISSIONS.teamUpdate, PERMISSIONS.teamDelete],
[ROLES.teamMember]: [],
} as const;

View File

@ -94,20 +94,20 @@ function getEventDataFilterQuery(
switch (type) {
case 'number':
ac.push(`and event_numeric_value = $${params.length + 1})`);
ac.push(`and number_value = $${params.length + 1})`);
params.push(value);
break;
case 'string':
ac.push(`and event_string_value = $${params.length + 1})`);
ac.push(`and string_value = $${params.length + 1})`);
params.push(decodeURIComponent(cv.eventValue as string));
break;
case 'boolean':
ac.push(`and event_string_value = $${params.length + 1})`);
ac.push(`and string_value = $${params.length + 1})`);
params.push(decodeURIComponent(cv.eventValue as string));
value = cv ? 'true' : 'false';
break;
case 'date':
ac.push(`and event_date_value = $${params.length + 1})`);
ac.push(`and date_value = $${params.length + 1})`);
params.push(cv.eventValue);
break;
}

View File

@ -81,7 +81,7 @@ async function clickhouseQuery(data: {
a.dynamicDataType === DATA_TYPE.array
? a.value
: null,
numeric_value: a.dynamicDataType === DATA_TYPE.number ? a.value : null,
number_value: a.dynamicDataType === DATA_TYPE.number ? a.value : null,
date_value: a.dynamicDataType === DATA_TYPE.date ? getDateFormat(a.value) : null,
data_type: a.dynamicDataType,
created_at: createdAt,