mirror of
https://github.com/umami-software/umami.git
synced 2025-12-08 05:12:36 +01:00
commit
b6e543801c
469 changed files with 7191 additions and 7464 deletions
|
|
@ -13,13 +13,6 @@
|
||||||
"ecmaVersion": 11,
|
"ecmaVersion": 11,
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"settings": {
|
|
||||||
"import/resolver": {
|
|
||||||
"node": {
|
|
||||||
"moduleDirectory": ["node_modules", "src/"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"extends": [
|
"extends": [
|
||||||
"plugin:@typescript-eslint/recommended",
|
"plugin:@typescript-eslint/recommended",
|
||||||
"eslint:recommended",
|
"eslint:recommended",
|
||||||
|
|
|
||||||
13
Dockerfile
13
Dockerfile
|
|
@ -1,5 +1,5 @@
|
||||||
# Install dependencies only when needed
|
# Install dependencies only when needed
|
||||||
FROM node:18-alpine AS deps
|
FROM node:22-alpine AS deps
|
||||||
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||||
RUN apk add --no-cache libc6-compat
|
RUN apk add --no-cache libc6-compat
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
@ -9,7 +9,7 @@ RUN yarn config set network-timeout 300000
|
||||||
RUN yarn install --frozen-lockfile
|
RUN yarn install --frozen-lockfile
|
||||||
|
|
||||||
# Rebuild the source code only when needed
|
# Rebuild the source code only when needed
|
||||||
FROM node:18-alpine AS builder
|
FROM node:22-alpine AS builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
@ -26,18 +26,21 @@ ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
RUN yarn build-docker
|
RUN yarn build-docker
|
||||||
|
|
||||||
# Production image, copy all the files and run next
|
# Production image, copy all the files and run next
|
||||||
FROM node:18-alpine AS runner
|
FROM node:22-alpine AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
ARG NODE_OPTIONS
|
||||||
|
|
||||||
ENV NODE_ENV production
|
ENV NODE_ENV production
|
||||||
ENV NEXT_TELEMETRY_DISABLED 1
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
|
ENV NODE_OPTIONS $NODE_OPTIONS
|
||||||
|
|
||||||
RUN addgroup --system --gid 1001 nodejs
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
RUN adduser --system --uid 1001 nextjs
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
RUN set -x \
|
RUN set -x \
|
||||||
&& apk add --no-cache curl openssl \
|
&& apk add --no-cache curl \
|
||||||
&& yarn add npm-run-all dotenv semver prisma@5.17.0
|
&& yarn add npm-run-all dotenv semver prisma@6.1.0
|
||||||
|
|
||||||
# You only need to copy next.config.js if you are NOT using the default configuration
|
# You only need to copy next.config.js if you are NOT using the default configuration
|
||||||
COPY --from=builder /app/next.config.js .
|
COPY --from=builder /app/next.config.js .
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
binaryTargets = ["native", "linux-musl-openssl-3.0.x", "linux-musl-arm64-openssl-3.0.x"]
|
binaryTargets = ["native"]
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
binaryTargets = ["native", "linux-musl-openssl-3.0.x", "linux-musl-arm64-openssl-3.0.x"]
|
binaryTargets = ["native"]
|
||||||
}
|
}
|
||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
|
|
|
||||||
1
next-env.d.ts
vendored
1
next-env.d.ts
vendored
|
|
@ -1,6 +1,5 @@
|
||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
/// <reference types="next/navigation-types/compat/navigation" />
|
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
require('dotenv').config();
|
require('dotenv').config();
|
||||||
const path = require('path');
|
|
||||||
const pkg = require('./package.json');
|
const pkg = require('./package.json');
|
||||||
|
|
||||||
const TRACKER_SCRIPT = '/script.js';
|
const TRACKER_SCRIPT = '/script.js';
|
||||||
|
|
@ -9,6 +8,7 @@ const basePath = process.env.BASE_PATH;
|
||||||
const collectApiEndpoint = process.env.COLLECT_API_ENDPOINT;
|
const collectApiEndpoint = process.env.COLLECT_API_ENDPOINT;
|
||||||
const cloudMode = process.env.CLOUD_MODE;
|
const cloudMode = process.env.CLOUD_MODE;
|
||||||
const cloudUrl = process.env.CLOUD_URL;
|
const cloudUrl = process.env.CLOUD_URL;
|
||||||
|
const corsMaxAge = process.env.CORS_MAX_AGE;
|
||||||
const defaultLocale = process.env.DEFAULT_LOCALE;
|
const defaultLocale = process.env.DEFAULT_LOCALE;
|
||||||
const disableLogin = process.env.DISABLE_LOGIN;
|
const disableLogin = process.env.DISABLE_LOGIN;
|
||||||
const disableUI = process.env.DISABLE_UI;
|
const disableUI = process.env.DISABLE_UI;
|
||||||
|
|
@ -60,6 +60,15 @@ const trackerHeaders = [
|
||||||
];
|
];
|
||||||
|
|
||||||
const headers = [
|
const headers = [
|
||||||
|
{
|
||||||
|
source: '/api/:path*',
|
||||||
|
headers: [
|
||||||
|
{ key: 'Access-Control-Allow-Origin', value: '*' },
|
||||||
|
{ key: 'Access-Control-Allow-Headers', value: '*' },
|
||||||
|
{ key: 'Access-Control-Allow-Methods', value: 'GET, DELETE, POST, PUT' },
|
||||||
|
{ key: 'Access-Control-Max-Age', value: corsMaxAge || '86400' },
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
source: '/:path*',
|
source: '/:path*',
|
||||||
headers: defaultHeaders,
|
headers: defaultHeaders,
|
||||||
|
|
@ -169,27 +178,22 @@ const config = {
|
||||||
typescript: {
|
typescript: {
|
||||||
ignoreBuildErrors: true,
|
ignoreBuildErrors: true,
|
||||||
},
|
},
|
||||||
|
experimental: {
|
||||||
|
turbo: {
|
||||||
|
rules: {
|
||||||
|
'*.svg': {
|
||||||
|
loaders: ['@svgr/webpack'],
|
||||||
|
as: '*.js',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
webpack(config) {
|
webpack(config) {
|
||||||
const fileLoaderRule = config.module.rules.find(rule => rule.test?.test?.('.svg'));
|
config.module.rules.push({
|
||||||
|
test: /\.svg$/,
|
||||||
config.module.rules.push(
|
issuer: /\.(js|ts)x?$/,
|
||||||
{
|
use: ['@svgr/webpack'],
|
||||||
...fileLoaderRule,
|
});
|
||||||
test: /\.svg$/i,
|
|
||||||
resourceQuery: /url/,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.svg$/i,
|
|
||||||
issuer: fileLoaderRule.issuer,
|
|
||||||
resourceQuery: { not: [...fileLoaderRule.resourceQuery.not, /url/] },
|
|
||||||
use: ['@svgr/webpack'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
fileLoaderRule.exclude = /\.svg$/i;
|
|
||||||
|
|
||||||
config.resolve.alias['public'] = path.resolve('./public');
|
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
async headers() {
|
async headers() {
|
||||||
|
|
|
||||||
39
package.json
39
package.json
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "umami",
|
"name": "umami",
|
||||||
"version": "2.15.1",
|
"version": "2.16.0",
|
||||||
"description": "A simple, fast, privacy-focused alternative to Google Analytics.",
|
"description": "A simple, fast, privacy-focused alternative to Google Analytics.",
|
||||||
"author": "Umami Software, Inc. <hello@umami.is>",
|
"author": "Umami Software, Inc. <hello@umami.is>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
"url": "https://github.com/umami-software/umami.git"
|
"url": "https://github.com/umami-software/umami.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev -p 3000",
|
"dev": "next dev -p 3000 --turbo",
|
||||||
"build": "npm-run-all check-env build-db check-db build-tracker build-geo build-app",
|
"build": "npm-run-all check-env build-db check-db build-tracker build-geo build-app",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"build-docker": "npm-run-all build-db build-tracker build-geo build-app",
|
"build-docker": "npm-run-all build-db build-tracker build-geo build-app",
|
||||||
|
|
@ -63,21 +63,20 @@
|
||||||
"cacheDirectories": [
|
"cacheDirectories": [
|
||||||
".next/cache"
|
".next/cache"
|
||||||
],
|
],
|
||||||
"resolutions": {
|
|
||||||
"jackspeak": "2.1.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clickhouse/client": "^1.4.1",
|
"@clickhouse/client": "^1.10.1",
|
||||||
"@date-fns/utc": "^1.2.0",
|
"@date-fns/utc": "^1.2.0",
|
||||||
"@dicebear/collection": "^9.2.1",
|
"@dicebear/collection": "^9.2.1",
|
||||||
"@dicebear/core": "^9.2.1",
|
"@dicebear/core": "^9.2.1",
|
||||||
"@fontsource/inter": "^4.5.15",
|
"@fontsource/inter": "^4.5.15",
|
||||||
"@prisma/client": "5.22.0",
|
"@hello-pangea/dnd": "^17.0.0",
|
||||||
"@prisma/extension-read-replicas": "^0.3.0",
|
"@prisma/client": "6.1.0",
|
||||||
|
"@prisma/extension-read-replicas": "^0.4.0",
|
||||||
"@react-spring/web": "^9.7.3",
|
"@react-spring/web": "^9.7.3",
|
||||||
"@tanstack/react-query": "^5.28.6",
|
"@tanstack/react-query": "^5.28.6",
|
||||||
"@umami/prisma-client": "^0.14.0",
|
"@umami/prisma-client": "^0.14.0",
|
||||||
"@umami/redis-client": "^0.24.0",
|
"@umami/redis-client": "^0.26.0",
|
||||||
|
"bcryptjs": "^2.4.3",
|
||||||
"chalk": "^4.1.1",
|
"chalk": "^4.1.1",
|
||||||
"chart.js": "^4.4.2",
|
"chart.js": "^4.4.2",
|
||||||
"chartjs-adapter-date-fns": "^3.0.0",
|
"chartjs-adapter-date-fns": "^3.0.0",
|
||||||
|
|
@ -99,17 +98,17 @@
|
||||||
"is-docker": "^3.0.0",
|
"is-docker": "^3.0.0",
|
||||||
"is-localhost-ip": "^1.4.0",
|
"is-localhost-ip": "^1.4.0",
|
||||||
"isbot": "^5.1.16",
|
"isbot": "^5.1.16",
|
||||||
|
"jsonwebtoken": "^9.0.2",
|
||||||
"kafkajs": "^2.1.0",
|
"kafkajs": "^2.1.0",
|
||||||
"maxmind": "^4.3.6",
|
"maxmind": "^4.3.24",
|
||||||
"md5": "^2.3.0",
|
"md5": "^2.3.0",
|
||||||
"next": "15.0.4",
|
"next": "15.0.4",
|
||||||
"next-basics": "^0.39.0",
|
|
||||||
"node-fetch": "^3.2.8",
|
"node-fetch": "^3.2.8",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prisma": "5.22.0",
|
"prisma": "6.1.0",
|
||||||
|
"pure-rand": "^6.1.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-basics": "^0.125.0",
|
"react-basics": "^0.126.0",
|
||||||
"react-beautiful-dnd": "^13.1.0",
|
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-error-boundary": "^4.0.4",
|
"react-error-boundary": "^4.0.4",
|
||||||
"react-intl": "^6.5.5",
|
"react-intl": "^6.5.5",
|
||||||
|
|
@ -118,9 +117,10 @@
|
||||||
"react-window": "^1.8.6",
|
"react-window": "^1.8.6",
|
||||||
"request-ip": "^3.3.0",
|
"request-ip": "^3.3.0",
|
||||||
"semver": "^7.5.4",
|
"semver": "^7.5.4",
|
||||||
|
"serialize-error": "^12.0.0",
|
||||||
"thenby": "^1.3.4",
|
"thenby": "^1.3.4",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
"yup": "^0.32.11",
|
"zod": "^3.24.1",
|
||||||
"zustand": "^4.5.5"
|
"zustand": "^4.5.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
@ -135,15 +135,16 @@
|
||||||
"@svgr/webpack": "^8.1.0",
|
"@svgr/webpack": "^8.1.0",
|
||||||
"@types/cypress": "^1.1.3",
|
"@types/cypress": "^1.1.3",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/node": "^20.9.0",
|
"@types/node": "^22.13.4",
|
||||||
"@types/react": "^18.2.41",
|
"@types/react": "^19.0.8",
|
||||||
"@types/react-dom": "^18.2.17",
|
"@types/react-dom": "^19.0.2",
|
||||||
|
"@types/react-intl": "^3.0.0",
|
||||||
"@types/react-window": "^1.8.8",
|
"@types/react-window": "^1.8.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
||||||
"@typescript-eslint/parser": "^6.7.3",
|
"@typescript-eslint/parser": "^6.7.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"cypress": "^13.6.6",
|
"cypress": "^13.6.6",
|
||||||
"esbuild": "^0.17.17",
|
"esbuild": "^0.25.0",
|
||||||
"eslint": "^8.33.0",
|
"eslint": "^8.33.0",
|
||||||
"eslint-config-next": "^14.0.4",
|
"eslint-config-next": "^14.0.4",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -2,7 +2,7 @@
|
||||||
"label.access-code": [
|
"label.access-code": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "Access code"
|
"value": "पहुंच कोड"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"label.actions": [
|
"label.actions": [
|
||||||
|
|
@ -14,19 +14,19 @@
|
||||||
"label.activity": [
|
"label.activity": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "Activity log"
|
"value": "गतिविधि लॉग"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"label.add": [
|
"label.add": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "Add"
|
"value": "जोडो"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"label.add-description": [
|
"label.add-description": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "Add description"
|
"value": "विवरण लिखें"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"label.add-member": [
|
"label.add-member": [
|
||||||
|
|
@ -1006,7 +1006,7 @@
|
||||||
"label.reports": [
|
"label.reports": [
|
||||||
{
|
{
|
||||||
"type": 0,
|
"type": 0,
|
||||||
"value": "Reports"
|
"value": "प्रतिवेदन"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"label.required": [
|
"label.required": [
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,8 @@ const customResolver = resolve({
|
||||||
|
|
||||||
const aliasConfig = {
|
const aliasConfig = {
|
||||||
entries: [
|
entries: [
|
||||||
{ find: /^app/, replacement: path.resolve('./src/app') },
|
{ find: /^@/, replacement: path.resolve('./src/') },
|
||||||
{ find: /^components/, replacement: path.resolve('./src/components') },
|
|
||||||
{ find: /^hooks/, replacement: path.resolve('./src/hooks') },
|
|
||||||
{ find: /^lib/, replacement: path.resolve('./src/lib') },
|
|
||||||
{ find: /^store/, replacement: path.resolve('./src/store') },
|
|
||||||
{ find: /^public/, replacement: path.resolve('./public') },
|
{ find: /^public/, replacement: path.resolve('./public') },
|
||||||
{ find: /^assets/, replacement: path.resolve('./src/assets') },
|
|
||||||
],
|
],
|
||||||
customResolver,
|
customResolver,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
/* eslint-disable no-console */
|
|
||||||
require('dotenv').config();
|
|
||||||
const { hashPassword } = require('next-basics');
|
|
||||||
const chalk = require('chalk');
|
|
||||||
const prompts = require('prompts');
|
|
||||||
const { PrismaClient } = require('@prisma/client');
|
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
|
||||||
|
|
||||||
const runQuery = async query => {
|
|
||||||
return query.catch(e => {
|
|
||||||
throw e;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const updateUserByUsername = (username, data) => {
|
|
||||||
return runQuery(
|
|
||||||
prisma.user.update({
|
|
||||||
where: {
|
|
||||||
username,
|
|
||||||
},
|
|
||||||
data,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const changePassword = async (username, newPassword) => {
|
|
||||||
const password = hashPassword(newPassword);
|
|
||||||
return updateUserByUsername(username, { password });
|
|
||||||
};
|
|
||||||
|
|
||||||
const getUsernameAndPassword = async () => {
|
|
||||||
let [username, password] = process.argv.slice(2);
|
|
||||||
if (username && password) {
|
|
||||||
return { username, password };
|
|
||||||
}
|
|
||||||
|
|
||||||
const questions = [];
|
|
||||||
if (!username) {
|
|
||||||
questions.push({
|
|
||||||
type: 'text',
|
|
||||||
name: 'username',
|
|
||||||
message: 'Enter user to change password',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!password) {
|
|
||||||
questions.push(
|
|
||||||
{
|
|
||||||
type: 'password',
|
|
||||||
name: 'password',
|
|
||||||
message: 'Enter new password',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'password',
|
|
||||||
name: 'confirmation',
|
|
||||||
message: 'Confirm new password',
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const answers = await prompts(questions);
|
|
||||||
if (answers.password !== answers.confirmation) {
|
|
||||||
throw new Error(`Passwords don't match`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
username: username || answers.username,
|
|
||||||
password: answers.password,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
(async () => {
|
|
||||||
let username, password;
|
|
||||||
|
|
||||||
try {
|
|
||||||
({ username, password } = await getUsernameAndPassword());
|
|
||||||
} catch (error) {
|
|
||||||
console.log(chalk.redBright(error.message));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await changePassword(username, password);
|
|
||||||
console.log('Password changed for user', chalk.greenBright(username));
|
|
||||||
} catch (error) {
|
|
||||||
if (error.meta.cause.includes('Record to update not found')) {
|
|
||||||
console.log('User not found:', chalk.redBright(username));
|
|
||||||
} else {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prisma.$disconnect();
|
|
||||||
})();
|
|
||||||
|
|
@ -23,5 +23,5 @@ if (!process.env.SKIP_DB_CHECK && !process.env.DATABASE_TYPE) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.env.CLOUD_MODE) {
|
if (process.env.CLOUD_MODE) {
|
||||||
checkMissing(['CLOUD_URL', 'KAFKA_BROKER', 'KAFKA_URL', 'REDIS_URL']);
|
checkMissing(['CLOUD_URL', 'KAFKA_BROKER', 'KAFKA_URL', 'REDIS_URL', 'KAFKA_SASL_MECHANISM']);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import { Loading } from 'react-basics';
|
import { Loading } from 'react-basics';
|
||||||
import Script from 'next/script';
|
import Script from 'next/script';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
import { useLogin, useConfig } from 'components/hooks';
|
import { useLogin, useConfig } from '@/components/hooks';
|
||||||
import UpdateNotice from './UpdateNotice';
|
import UpdateNotice from './UpdateNotice';
|
||||||
|
|
||||||
export function App({ children }) {
|
export function App({ children }) {
|
||||||
|
|
@ -22,6 +22,10 @@ export function App({ children }) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.uiDisabled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
import { useEffect } from 'react';
|
||||||
import { Icon, Text } from 'react-basics';
|
import { Icon, Text } from 'react-basics';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import HamburgerButton from 'components/common/HamburgerButton';
|
import HamburgerButton from '@/components/common/HamburgerButton';
|
||||||
import ThemeButton from 'components/input/ThemeButton';
|
import ThemeButton from '@/components/input/ThemeButton';
|
||||||
import LanguageButton from 'components/input/LanguageButton';
|
import LanguageButton from '@/components/input/LanguageButton';
|
||||||
import ProfileButton from 'components/input/ProfileButton';
|
import ProfileButton from '@/components/input/ProfileButton';
|
||||||
import TeamsButton from 'components/input/TeamsButton';
|
import TeamsButton from '@/components/input/TeamsButton';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { useMessages, useNavigation, useTeamUrl } from 'components/hooks';
|
import { useMessages, useNavigation, useTeamUrl } from '@/components/hooks';
|
||||||
|
import { getItem, setItem } from '@/lib/storage';
|
||||||
import styles from './NavBar.module.css';
|
import styles from './NavBar.module.css';
|
||||||
import { useEffect } from 'react';
|
|
||||||
import { getItem, setItem } from 'next-basics';
|
|
||||||
|
|
||||||
export function NavBar() {
|
export function NavBar() {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { useEffect, useCallback, useState } from 'react';
|
import { useEffect, useCallback, useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { Button } from 'react-basics';
|
import { Button } from 'react-basics';
|
||||||
import { setItem } from 'next-basics';
|
import { setItem } from '@/lib/storage';
|
||||||
import useStore, { checkVersion } from 'store/version';
|
import useStore, { checkVersion } from '@/store/version';
|
||||||
import { REPO_URL, VERSION_CHECK } from 'lib/constants';
|
import { REPO_URL, VERSION_CHECK } from '@/lib/constants';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
import styles from './UpdateNotice.module.css';
|
import styles from './UpdateNotice.module.css';
|
||||||
|
|
||||||
|
|
@ -14,6 +14,7 @@ export function UpdateNotice({ user, config }) {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const [dismissed, setDismissed] = useState(checked);
|
const [dismissed, setDismissed] = useState(checked);
|
||||||
const allowUpdate =
|
const allowUpdate =
|
||||||
|
process.env.NODE_ENV === 'production' &&
|
||||||
user?.isAdmin &&
|
user?.isAdmin &&
|
||||||
!config?.updatesDisabled &&
|
!config?.updatesDisabled &&
|
||||||
!pathname.includes('/share/') &&
|
!pathname.includes('/share/') &&
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { Button } from 'react-basics';
|
import { Button } from 'react-basics';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import Script from 'next/script';
|
import Script from 'next/script';
|
||||||
import WebsiteSelect from 'components/input/WebsiteSelect';
|
import WebsiteSelect from '@/components/input/WebsiteSelect';
|
||||||
import Page from 'components/layout/Page';
|
import Page from '@/components/layout/Page';
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from '@/components/layout/PageHeader';
|
||||||
import EventsChart from 'components/metrics/EventsChart';
|
import EventsChart from '@/components/metrics/EventsChart';
|
||||||
import WebsiteChart from '../websites/[websiteId]/WebsiteChart';
|
import WebsiteChart from '../websites/[websiteId]/WebsiteChart';
|
||||||
import { useApi, useNavigation } from 'components/hooks';
|
import { useApi, useNavigation } from '@/components/hooks';
|
||||||
import styles from './TestConsole.module.css';
|
import styles from './TestConsole.module.css';
|
||||||
|
|
||||||
export function TestConsole({ websiteId }: { websiteId: string }) {
|
export function TestConsole({ websiteId }: { websiteId: string }) {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { useState, useMemo, useEffect } from 'react';
|
import { useState, useMemo, useEffect } from 'react';
|
||||||
import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd';
|
import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Button, Loading, Toggle, SearchField } from 'react-basics';
|
import { Button, Loading, Toggle, SearchField } from 'react-basics';
|
||||||
import { firstBy } from 'thenby';
|
import { firstBy } from 'thenby';
|
||||||
import useDashboard, { saveDashboard } from 'store/dashboard';
|
import useDashboard, { saveDashboard } from '@/store/dashboard';
|
||||||
import { useMessages, useWebsites } from 'components/hooks';
|
import { useMessages, useWebsites } from '@/components/hooks';
|
||||||
import styles from './DashboardEdit.module.css';
|
import styles from './DashboardEdit.module.css';
|
||||||
|
|
||||||
const DRAG_ID = 'dashboard-website-ordering';
|
const DRAG_ID = 'dashboard-website-ordering';
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { Icon, Icons, Loading, Text } from 'react-basics';
|
import { Icon, Icons, Loading, Text } from 'react-basics';
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from '@/components/layout/PageHeader';
|
||||||
import Pager from 'components/common/Pager';
|
import Pager from '@/components/common/Pager';
|
||||||
import WebsiteChartList from '../websites/[websiteId]/WebsiteChartList';
|
import WebsiteChartList from '../websites/[websiteId]/WebsiteChartList';
|
||||||
import DashboardSettingsButton from 'app/(main)/dashboard/DashboardSettingsButton';
|
import DashboardSettingsButton from '@/app/(main)/dashboard/DashboardSettingsButton';
|
||||||
import DashboardEdit from 'app/(main)/dashboard/DashboardEdit';
|
import DashboardEdit from '@/app/(main)/dashboard/DashboardEdit';
|
||||||
import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
|
import EmptyPlaceholder from '@/components/common/EmptyPlaceholder';
|
||||||
import { useMessages, useLocale, useTeamUrl, useWebsites } from 'components/hooks';
|
import { useMessages, useLocale, useTeamUrl, useWebsites } from '@/components/hooks';
|
||||||
import useDashboard from 'store/dashboard';
|
import useDashboard from '@/store/dashboard';
|
||||||
import LinkButton from 'components/common/LinkButton';
|
import LinkButton from '@/components/common/LinkButton';
|
||||||
|
|
||||||
export function DashboardPage() {
|
export function DashboardPage() {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { TooltipPopup, Icon, Text, Flexbox, Button } from 'react-basics';
|
import { TooltipPopup, Icon, Text, Flexbox, Button } from 'react-basics';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { saveDashboard } from 'store/dashboard';
|
import { saveDashboard } from '@/store/dashboard';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
|
|
||||||
export function DashboardSettingsButton() {
|
export function DashboardSettingsButton() {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,10 @@
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import NavBar from './NavBar';
|
import NavBar from './NavBar';
|
||||||
import Page from 'components/layout/Page';
|
import Page from '@/components/layout/Page';
|
||||||
import styles from './layout.module.css';
|
import styles from './layout.module.css';
|
||||||
|
|
||||||
export default function ({ children }) {
|
export default async function ({ children }) {
|
||||||
if (process.env.DISABLE_UI) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<App>
|
<App>
|
||||||
<main className={styles.layout}>
|
<main className={styles.layout}>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import DateFilter from 'components/input/DateFilter';
|
import DateFilter from '@/components/input/DateFilter';
|
||||||
import { Button, Flexbox } from 'react-basics';
|
import { Button, Flexbox } from 'react-basics';
|
||||||
import { useDateRange, useMessages } from 'components/hooks';
|
import { useDateRange, useMessages } from '@/components/hooks';
|
||||||
import { DEFAULT_DATE_RANGE } from 'lib/constants';
|
import { DEFAULT_DATE_RANGE } from '@/lib/constants';
|
||||||
import { DateRange } from 'lib/types';
|
import { DateRange } from '@/lib/types';
|
||||||
import styles from './DateRangeSetting.module.css';
|
import styles from './DateRangeSetting.module.css';
|
||||||
|
|
||||||
export function DateRangeSetting() {
|
export function DateRangeSetting() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Button, Dropdown, Item, Flexbox } from 'react-basics';
|
import { Button, Dropdown, Item, Flexbox } from 'react-basics';
|
||||||
import { useLocale, useMessages } from 'components/hooks';
|
import { useLocale, useMessages } from '@/components/hooks';
|
||||||
import { DEFAULT_LOCALE } from 'lib/constants';
|
import { DEFAULT_LOCALE } from '@/lib/constants';
|
||||||
import { languages } from 'lib/lang';
|
import { languages } from '@/lib/lang';
|
||||||
import styles from './LanguageSetting.module.css';
|
import styles from './LanguageSetting.module.css';
|
||||||
|
|
||||||
export function LanguageSetting() {
|
export function LanguageSetting() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Button, Icon, Text, useToasts, ModalTrigger, Modal } from 'react-basics';
|
import { Button, Icon, Text, useToasts, ModalTrigger, Modal } from 'react-basics';
|
||||||
import PasswordEditForm from 'app/(main)/profile/PasswordEditForm';
|
import PasswordEditForm from '@/app/(main)/profile/PasswordEditForm';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
|
|
||||||
export function PasswordChangeButton() {
|
export function PasswordChangeButton() {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import { Form, FormRow, FormInput, FormButtons, PasswordField, Button } from 'react-basics';
|
import { Form, FormRow, FormInput, FormButtons, PasswordField, Button } from 'react-basics';
|
||||||
import { useApi, useMessages } from 'components/hooks';
|
import { useApi, useMessages } from '@/components/hooks';
|
||||||
|
|
||||||
export function PasswordEditForm({ onSave, onClose }) {
|
export function PasswordEditForm({ onSave, onClose }) {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from '@/components/layout/PageHeader';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
|
|
||||||
export function ProfileHeader() {
|
export function ProfileHeader() {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { Form, FormRow } from 'react-basics';
|
import { Form, FormRow } from 'react-basics';
|
||||||
import TimezoneSetting from 'app/(main)/profile/TimezoneSetting';
|
import TimezoneSetting from '@/app/(main)/profile/TimezoneSetting';
|
||||||
import DateRangeSetting from 'app/(main)/profile/DateRangeSetting';
|
import DateRangeSetting from '@/app/(main)/profile/DateRangeSetting';
|
||||||
import LanguageSetting from 'app/(main)/profile/LanguageSetting';
|
import LanguageSetting from '@/app/(main)/profile/LanguageSetting';
|
||||||
import ThemeSetting from 'app/(main)/profile/ThemeSetting';
|
import ThemeSetting from '@/app/(main)/profile/ThemeSetting';
|
||||||
import PasswordChangeButton from './PasswordChangeButton';
|
import PasswordChangeButton from './PasswordChangeButton';
|
||||||
import { useLogin, useMessages } from 'components/hooks';
|
import { useLogin, useMessages } from '@/components/hooks';
|
||||||
import { ROLES } from 'lib/constants';
|
import { ROLES } from '@/lib/constants';
|
||||||
|
|
||||||
export function ProfileSettings() {
|
export function ProfileSettings() {
|
||||||
const { user } = useLogin();
|
const { user } = useLogin();
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Button, Icon } from 'react-basics';
|
import { Button, Icon } from 'react-basics';
|
||||||
import { useTheme } from 'components/hooks';
|
import { useTheme } from '@/components/hooks';
|
||||||
import Sun from 'assets/sun.svg';
|
import Sun from '@/assets/sun.svg';
|
||||||
import Moon from 'assets/moon.svg';
|
import Moon from '@/assets/moon.svg';
|
||||||
import styles from './ThemeSetting.module.css';
|
import styles from './ThemeSetting.module.css';
|
||||||
|
|
||||||
export function ThemeSetting() {
|
export function ThemeSetting() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Dropdown, Item, Button, Flexbox } from 'react-basics';
|
import { Dropdown, Item, Button, Flexbox } from 'react-basics';
|
||||||
import { useTimezone, useMessages } from 'components/hooks';
|
import { useTimezone, useMessages } from '@/components/hooks';
|
||||||
import { getTimezone } from 'lib/date';
|
import { getTimezone } from '@/lib/date';
|
||||||
import styles from './TimezoneSetting.module.css';
|
import styles from './TimezoneSetting.module.css';
|
||||||
|
|
||||||
const timezones = Intl.supportedValuesOf('timeZone');
|
const timezones = Intl.supportedValuesOf('timeZone');
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
|
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
|
||||||
import { useApi, useMessages, useModified } from 'components/hooks';
|
import { useApi, useMessages, useModified } from '@/components/hooks';
|
||||||
import ConfirmationForm from 'components/common/ConfirmationForm';
|
import ConfirmationForm from '@/components/common/ConfirmationForm';
|
||||||
|
|
||||||
export function ReportDeleteButton({
|
export function ReportDeleteButton({
|
||||||
reportId,
|
reportId,
|
||||||
|
|
@ -11,7 +11,7 @@ export function ReportDeleteButton({
|
||||||
reportName: string;
|
reportName: string;
|
||||||
onDelete?: () => void;
|
onDelete?: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels, messages, FormattedMessage } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
const { del, useMutation } = useApi();
|
const { del, useMutation } = useApi();
|
||||||
const { mutate, isPending, error } = useMutation({
|
const { mutate, isPending, error } = useMutation({
|
||||||
mutationFn: reportId => del(`/reports/${reportId}`),
|
mutationFn: reportId => del(`/reports/${reportId}`),
|
||||||
|
|
@ -39,12 +39,7 @@ export function ReportDeleteButton({
|
||||||
<Modal title={formatMessage(labels.deleteReport)}>
|
<Modal title={formatMessage(labels.deleteReport)}>
|
||||||
{(close: () => void) => (
|
{(close: () => void) => (
|
||||||
<ConfirmationForm
|
<ConfirmationForm
|
||||||
message={
|
message={formatMessage(messages.confirmDelete, { target: <b>{reportName}</b> })}
|
||||||
<FormattedMessage
|
|
||||||
{...messages.confirmDelete}
|
|
||||||
values={{ target: <b>{reportName}</b> }}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
isLoading={isPending}
|
isLoading={isPending}
|
||||||
error={error}
|
error={error}
|
||||||
onConfirm={handleConfirm.bind(null, close)}
|
onConfirm={handleConfirm.bind(null, close)}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { useReports } from 'components/hooks';
|
import { useReports } from '@/components/hooks';
|
||||||
import ReportsTable from './ReportsTable';
|
import ReportsTable from './ReportsTable';
|
||||||
import DataTable from 'components/common/DataTable';
|
import DataTable from '@/components/common/DataTable';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
export default function ReportsDataTable({
|
export default function ReportsDataTable({
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from '@/components/layout/PageHeader';
|
||||||
import { Icon, Icons, Text } from 'react-basics';
|
import { Icon, Icons, Text } from 'react-basics';
|
||||||
import { useLogin, useMessages, useTeamUrl } from 'components/hooks';
|
import { useLogin, useMessages, useTeamUrl } from '@/components/hooks';
|
||||||
import LinkButton from 'components/common/LinkButton';
|
import LinkButton from '@/components/common/LinkButton';
|
||||||
import { ROLES } from 'lib/constants';
|
import { ROLES } from '@/lib/constants';
|
||||||
|
|
||||||
export function ReportsHeader() {
|
export function ReportsHeader() {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
import ReportsHeader from './ReportsHeader';
|
import ReportsHeader from './ReportsHeader';
|
||||||
import ReportsDataTable from './ReportsDataTable';
|
import ReportsDataTable from './ReportsDataTable';
|
||||||
import { useTeamUrl } from 'components/hooks';
|
import { useTeamUrl } from '@/components/hooks';
|
||||||
|
|
||||||
export default function ReportsPage() {
|
export default function ReportsPage() {
|
||||||
const { teamId } = useTeamUrl();
|
const { teamId } = useTeamUrl();
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { GridColumn, GridTable, Icon, Icons, Text } from 'react-basics';
|
import { GridColumn, GridTable, Icon, Icons, Text } from 'react-basics';
|
||||||
import LinkButton from 'components/common/LinkButton';
|
import LinkButton from '@/components/common/LinkButton';
|
||||||
import { useMessages, useLogin, useTeamUrl } from 'components/hooks';
|
import { useMessages, useLogin, useTeamUrl } from '@/components/hooks';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from '@/lib/constants';
|
||||||
import ReportDeleteButton from './ReportDeleteButton';
|
import ReportDeleteButton from './ReportDeleteButton';
|
||||||
|
|
||||||
export function ReportsTable({ data = [], showDomain }: { data: any[]; showDomain?: boolean }) {
|
export function ReportsTable({ data = [], showDomain }: { data: any[]; showDomain?: boolean }) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { FormRow } from 'react-basics';
|
import { FormRow } from 'react-basics';
|
||||||
import { parseDateRange } from 'lib/date';
|
import { parseDateRange } from '@/lib/date';
|
||||||
import DateFilter from 'components/input/DateFilter';
|
import DateFilter from '@/components/input/DateFilter';
|
||||||
import WebsiteSelect from 'components/input/WebsiteSelect';
|
import WebsiteSelect from '@/components/input/WebsiteSelect';
|
||||||
import { useMessages, useTeamUrl, useWebsite } from 'components/hooks';
|
import { useMessages, useTeamUrl, useWebsite } from '@/components/hooks';
|
||||||
import { ReportContext } from './Report';
|
import { ReportContext } from './Report';
|
||||||
import styles from './BaseParameters.module.css';
|
import styles from './BaseParameters.module.css';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { REPORT_PARAMETERS } from 'lib/constants';
|
import { REPORT_PARAMETERS } from '@/lib/constants';
|
||||||
import PopupForm from './PopupForm';
|
import PopupForm from './PopupForm';
|
||||||
import FieldSelectForm from './FieldSelectForm';
|
import FieldSelectForm from './FieldSelectForm';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Form, FormRow, Menu, Item } from 'react-basics';
|
import { Form, FormRow, Menu, Item } from 'react-basics';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
|
|
||||||
export default function FieldAggregateForm({
|
export default function FieldAggregateForm({
|
||||||
name,
|
name,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useFilters, useFormat, useLocale, useMessages, useWebsiteValues } from 'components/hooks';
|
|
||||||
import { OPERATORS } from 'lib/constants';
|
|
||||||
import { isEqualsOperator } from 'lib/params';
|
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
|
import { useFilters, useFormat, useMessages, useWebsiteValues } from '@/components/hooks';
|
||||||
|
import { OPERATORS } from '@/lib/constants';
|
||||||
|
import { isEqualsOperator } from '@/lib/params';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Dropdown,
|
Dropdown,
|
||||||
|
|
@ -55,7 +55,6 @@ export default function FieldFilterEditForm({
|
||||||
const [selected, setSelected] = useState(isEquals ? value : '');
|
const [selected, setSelected] = useState(isEquals ? value : '');
|
||||||
const { filters } = useFilters();
|
const { filters } = useFilters();
|
||||||
const { formatValue } = useFormat();
|
const { formatValue } = useFormat();
|
||||||
const { locale } = useLocale();
|
|
||||||
const isDisabled = !operator || (isEquals && !selected) || (!isEquals && !value);
|
const isDisabled = !operator || (isEquals && !selected) || (!isEquals && !value);
|
||||||
const {
|
const {
|
||||||
data: values = [],
|
data: values = [],
|
||||||
|
|
@ -80,29 +79,17 @@ export default function FieldFilterEditForm({
|
||||||
};
|
};
|
||||||
|
|
||||||
const formattedValues = useMemo(() => {
|
const formattedValues = useMemo(() => {
|
||||||
if (!values) {
|
return values.reduce((obj: { [x: string]: string }, { value }: { value: string }) => {
|
||||||
return {};
|
obj[value] = formatValue(value, name);
|
||||||
}
|
|
||||||
const formatted = {};
|
|
||||||
const format = (val: string) => {
|
|
||||||
formatted[val] = formatValue(val, name);
|
|
||||||
return formatted[val];
|
|
||||||
};
|
|
||||||
|
|
||||||
if (values?.length !== 1) {
|
return obj;
|
||||||
const { compare } = new Intl.Collator(locale, { numeric: true });
|
}, {});
|
||||||
values.sort((a, b) => compare(formatted[a] ?? format(a), formatted[b] ?? format(b)));
|
}, [formatValue, name, values]);
|
||||||
} else {
|
|
||||||
format(values[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return formatted;
|
|
||||||
}, [formatValue, locale, name, values]);
|
|
||||||
|
|
||||||
const filteredValues = useMemo(() => {
|
const filteredValues = useMemo(() => {
|
||||||
return value
|
return value
|
||||||
? values.filter((n: string | number) =>
|
? values.filter((n: string | number) =>
|
||||||
formattedValues[n].toLowerCase().includes(value.toLowerCase()),
|
formattedValues[n]?.toLowerCase()?.includes(value.toLowerCase()),
|
||||||
)
|
)
|
||||||
: values;
|
: values;
|
||||||
}, [value, formattedValues]);
|
}, [value, formattedValues]);
|
||||||
|
|
@ -226,7 +213,7 @@ const ResultsMenu = ({ values, type, isLoading, onSelect }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu className={styles.menu} variant="popup" onSelect={onSelect}>
|
<Menu className={styles.menu} variant="popup" onSelect={onSelect}>
|
||||||
{values?.map((value: any) => {
|
{values?.map(({ value }) => {
|
||||||
return <Item key={value}>{formatValue(value, type)}</Item>;
|
return <Item key={value}>{formatValue(value, type)}</Item>;
|
||||||
})}
|
})}
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useFields, useMessages } from 'components/hooks';
|
import { useFields, useMessages } from '@/components/hooks';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { Button, FormRow, Icon, Popup, PopupTrigger } from 'react-basics';
|
import { Button, FormRow, Icon, Popup, PopupTrigger } from 'react-basics';
|
||||||
import FieldSelectForm from '../[reportId]/FieldSelectForm';
|
import FieldSelectForm from '../[reportId]/FieldSelectForm';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Menu, Item, Form, FormRow } from 'react-basics';
|
import { Menu, Item, Form, FormRow } from 'react-basics';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import styles from './FieldSelectForm.module.css';
|
import styles from './FieldSelectForm.module.css';
|
||||||
import { Key } from 'react';
|
import { Key } from 'react';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useMessages, useFormat, useFilters, useFields } from 'components/hooks';
|
import { useMessages, useFormat, useFilters, useFields } from '@/components/hooks';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { Button, FormRow, Icon, Popup, PopupTrigger } from 'react-basics';
|
import { Button, FormRow, Icon, Popup, PopupTrigger } from 'react-basics';
|
||||||
import FilterSelectForm from '../[reportId]/FilterSelectForm';
|
import FilterSelectForm from '../[reportId]/FilterSelectForm';
|
||||||
import ParameterList from '../[reportId]/ParameterList';
|
import ParameterList from '../[reportId]/ParameterList';
|
||||||
import PopupForm from '../[reportId]/PopupForm';
|
import PopupForm from '../[reportId]/PopupForm';
|
||||||
import { ReportContext } from './Report';
|
import { ReportContext } from './Report';
|
||||||
import FieldFilterEditForm from '../[reportId]/FieldFilterEditForm';
|
import FieldFilterEditForm from '../[reportId]/FieldFilterEditForm';
|
||||||
import { isSearchOperator } from 'lib/params';
|
import { isSearchOperator } from '@/lib/params';
|
||||||
import styles from './FilterParameters.module.css';
|
import styles from './FilterParameters.module.css';
|
||||||
|
|
||||||
export function FilterParameters() {
|
export function FilterParameters() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { Icon } from 'react-basics';
|
import { Icon } from 'react-basics';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import Empty from 'components/common/Empty';
|
import Empty from '@/components/common/Empty';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import styles from './ParameterList.module.css';
|
import styles from './ParameterList.module.css';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { createContext, ReactNode } from 'react';
|
import { createContext, ReactNode } from 'react';
|
||||||
import { Loading } from 'react-basics';
|
import { Loading } from 'react-basics';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useReport } from 'components/hooks';
|
import { useReport } from '@/components/hooks';
|
||||||
import styles from './Report.module.css';
|
import styles from './Report.module.css';
|
||||||
|
|
||||||
export const ReportContext = createContext(null);
|
export const ReportContext = createContext(null);
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { Icon, LoadingButton, InlineEditField, useToasts } from 'react-basics';
|
import { Icon, LoadingButton, InlineEditField, useToasts } from 'react-basics';
|
||||||
import { useMessages, useApi, useNavigation, useTeamUrl } from 'components/hooks';
|
import { useMessages, useApi, useNavigation, useTeamUrl } from '@/components/hooks';
|
||||||
import { ReportContext } from './Report';
|
import { ReportContext } from './Report';
|
||||||
import styles from './ReportHeader.module.css';
|
import styles from './ReportHeader.module.css';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from '@/lib/constants';
|
||||||
import Breadcrumb from 'components/common/Breadcrumb';
|
import Breadcrumb from '@/components/common/Breadcrumb';
|
||||||
|
|
||||||
export function ReportHeader({ icon }) {
|
export function ReportHeader({ icon }) {
|
||||||
const { report, updateReport } = useContext(ReportContext);
|
const { report, updateReport } = useContext(ReportContext);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { useReport } from 'components/hooks';
|
import { useReport } from '@/components/hooks';
|
||||||
import EventDataReport from '../event-data/EventDataReport';
|
import EventDataReport from '../event-data/EventDataReport';
|
||||||
import FunnelReport from '../funnel/FunnelReport';
|
import FunnelReport from '../funnel/FunnelReport';
|
||||||
import GoalReport from '../goals/GoalsReport';
|
import GoalReport from '../goals/GoalsReport';
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import Funnel from 'assets/funnel.svg';
|
import Funnel from '@/assets/funnel.svg';
|
||||||
import Money from 'assets/money.svg';
|
import Money from '@/assets/money.svg';
|
||||||
import Lightbulb from 'assets/lightbulb.svg';
|
import Lightbulb from '@/assets/lightbulb.svg';
|
||||||
import Magnet from 'assets/magnet.svg';
|
import Magnet from '@/assets/magnet.svg';
|
||||||
import Path from 'assets/path.svg';
|
import Path from '@/assets/path.svg';
|
||||||
import Tag from 'assets/tag.svg';
|
import Tag from '@/assets/tag.svg';
|
||||||
import Target from 'assets/target.svg';
|
import Target from '@/assets/target.svg';
|
||||||
import { useMessages, useTeamUrl } from 'components/hooks';
|
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from '@/components/layout/PageHeader';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { Button, Icon, Icons, Text } from 'react-basics';
|
import { Button, Icon, Icons, Text } from 'react-basics';
|
||||||
import styles from './ReportTemplates.module.css';
|
import styles from './ReportTemplates.module.css';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { Form, FormRow, FormButtons, SubmitButton, PopupTrigger, Icon, Popup } from 'react-basics';
|
import { Form, FormRow, FormButtons, SubmitButton, PopupTrigger, Icon, Popup } from 'react-basics';
|
||||||
import Empty from 'components/common/Empty';
|
import Empty from '@/components/common/Empty';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { useApi, useMessages } from 'components/hooks';
|
import { useApi, useMessages } from '@/components/hooks';
|
||||||
import { DATA_TYPES, REPORT_PARAMETERS } from 'lib/constants';
|
import { DATA_TYPES, REPORT_PARAMETERS } from '@/lib/constants';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import FieldAddForm from '../[reportId]/FieldAddForm';
|
import FieldAddForm from '../[reportId]/FieldAddForm';
|
||||||
import ParameterList from '../[reportId]/ParameterList';
|
import ParameterList from '../[reportId]/ParameterList';
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import ReportMenu from '../[reportId]/ReportMenu';
|
||||||
import ReportBody from '../[reportId]/ReportBody';
|
import ReportBody from '../[reportId]/ReportBody';
|
||||||
import EventDataParameters from './EventDataParameters';
|
import EventDataParameters from './EventDataParameters';
|
||||||
import EventDataTable from './EventDataTable';
|
import EventDataTable from './EventDataTable';
|
||||||
import Nodes from 'assets/nodes.svg';
|
import Nodes from '@/assets/nodes.svg';
|
||||||
|
|
||||||
const defaultParameters = {
|
const defaultParameters = {
|
||||||
type: 'event-data',
|
type: 'event-data',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { GridTable, GridColumn } from 'react-basics';
|
import { GridTable, GridColumn } from 'react-basics';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
|
|
||||||
export function EventDataTable() {
|
export function EventDataTable() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import { formatLongNumber } from 'lib/format';
|
import { formatLongNumber } from '@/lib/format';
|
||||||
import styles from './FunnelChart.module.css';
|
import styles from './FunnelChart.module.css';
|
||||||
|
|
||||||
export interface FunnelChartProps {
|
export interface FunnelChartProps {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import {
|
import {
|
||||||
Icon,
|
Icon,
|
||||||
Form,
|
Form,
|
||||||
|
|
@ -12,7 +12,7 @@ import {
|
||||||
TextField,
|
TextField,
|
||||||
Button,
|
Button,
|
||||||
} from 'react-basics';
|
} from 'react-basics';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import FunnelStepAddForm from './FunnelStepAddForm';
|
import FunnelStepAddForm from './FunnelStepAddForm';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import BaseParameters from '../[reportId]/BaseParameters';
|
import BaseParameters from '../[reportId]/BaseParameters';
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import Report from '../[reportId]/Report';
|
||||||
import ReportHeader from '../[reportId]/ReportHeader';
|
import ReportHeader from '../[reportId]/ReportHeader';
|
||||||
import ReportMenu from '../[reportId]/ReportMenu';
|
import ReportMenu from '../[reportId]/ReportMenu';
|
||||||
import ReportBody from '../[reportId]/ReportBody';
|
import ReportBody from '../[reportId]/ReportBody';
|
||||||
import Funnel from 'assets/funnel.svg';
|
import Funnel from '@/assets/funnel.svg';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from '@/lib/constants';
|
||||||
|
|
||||||
const defaultParameters = {
|
const defaultParameters = {
|
||||||
type: REPORT_TYPES.funnel,
|
type: REPORT_TYPES.funnel,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { Button, FormRow, TextField, Flexbox, Dropdown, Item } from 'react-basics';
|
import { Button, FormRow, TextField, Flexbox, Dropdown, Item } from 'react-basics';
|
||||||
import styles from './FunnelStepAddForm.module.css';
|
import styles from './FunnelStepAddForm.module.css';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Button, Dropdown, Flexbox, FormRow, Item, TextField } from 'react-basics';
|
import { Button, Dropdown, Flexbox, FormRow, Item, TextField } from 'react-basics';
|
||||||
import styles from './GoalsAddForm.module.css';
|
import styles from './GoalsAddForm.module.css';
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import { formatLongNumber } from 'lib/format';
|
import { formatLongNumber } from '@/lib/format';
|
||||||
import styles from './GoalsChart.module.css';
|
import styles from './GoalsChart.module.css';
|
||||||
|
|
||||||
export function GoalsChart({ className }: { className?: string; isLoading?: boolean }) {
|
export function GoalsChart({ className }: { className?: string; isLoading?: boolean }) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { formatNumber } from 'lib/format';
|
import { formatNumber } from '@/lib/format';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import Report from '../[reportId]/Report';
|
||||||
import ReportHeader from '../[reportId]/ReportHeader';
|
import ReportHeader from '../[reportId]/ReportHeader';
|
||||||
import ReportMenu from '../[reportId]/ReportMenu';
|
import ReportMenu from '../[reportId]/ReportMenu';
|
||||||
import ReportBody from '../[reportId]/ReportBody';
|
import ReportBody from '../[reportId]/ReportBody';
|
||||||
import Target from 'assets/target.svg';
|
import Target from '@/assets/target.svg';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from '@/lib/constants';
|
||||||
|
|
||||||
const defaultParameters = {
|
const defaultParameters = {
|
||||||
type: REPORT_TYPES.goals,
|
type: REPORT_TYPES.goals,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { Form, FormButtons, SubmitButton } from 'react-basics';
|
import { Form, FormButtons, SubmitButton } from 'react-basics';
|
||||||
import BaseParameters from '../[reportId]/BaseParameters';
|
import BaseParameters from '../[reportId]/BaseParameters';
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import ReportMenu from '../[reportId]/ReportMenu';
|
||||||
import ReportBody from '../[reportId]/ReportBody';
|
import ReportBody from '../[reportId]/ReportBody';
|
||||||
import InsightsParameters from './InsightsParameters';
|
import InsightsParameters from './InsightsParameters';
|
||||||
import InsightsTable from './InsightsTable';
|
import InsightsTable from './InsightsTable';
|
||||||
import Lightbulb from 'assets/lightbulb.svg';
|
import Lightbulb from '@/assets/lightbulb.svg';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from '@/lib/constants';
|
||||||
|
|
||||||
const defaultParameters = {
|
const defaultParameters = {
|
||||||
type: REPORT_TYPES.insights,
|
type: REPORT_TYPES.insights,
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useContext, useEffect, useState } from 'react';
|
import { useContext, useEffect, useState } from 'react';
|
||||||
import { GridTable, GridColumn } from 'react-basics';
|
import { GridTable, GridColumn } from 'react-basics';
|
||||||
import { useFormat, useMessages } from 'components/hooks';
|
import { useFormat, useMessages } from '@/components/hooks';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
|
import EmptyPlaceholder from '@/components/common/EmptyPlaceholder';
|
||||||
import { formatShortTime } from 'lib/format';
|
import { formatShortTime } from '@/lib/format';
|
||||||
|
|
||||||
export function InsightsTable() {
|
export function InsightsTable() {
|
||||||
const [fields, setFields] = useState([]);
|
const [fields, setFields] = useState([]);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import {
|
import {
|
||||||
Dropdown,
|
Dropdown,
|
||||||
Form,
|
Form,
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import ReportMenu from '../[reportId]/ReportMenu';
|
||||||
import ReportBody from '../[reportId]/ReportBody';
|
import ReportBody from '../[reportId]/ReportBody';
|
||||||
import JourneyParameters from './JourneyParameters';
|
import JourneyParameters from './JourneyParameters';
|
||||||
import JourneyView from './JourneyView';
|
import JourneyView from './JourneyView';
|
||||||
import Path from 'assets/path.svg';
|
import Path from '@/assets/path.svg';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from '@/lib/constants';
|
||||||
|
|
||||||
const defaultParameters = {
|
const defaultParameters = {
|
||||||
type: REPORT_TYPES.journey,
|
type: REPORT_TYPES.journey,
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ import { useContext, useMemo, useState } from 'react';
|
||||||
import { TextOverflow, TooltipPopup } from 'react-basics';
|
import { TextOverflow, TooltipPopup } from 'react-basics';
|
||||||
import { firstBy } from 'thenby';
|
import { firstBy } from 'thenby';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useEscapeKey, useMessages } from 'components/hooks';
|
import { useEscapeKey, useMessages } from '@/components/hooks';
|
||||||
import { objectToArray } from 'lib/data';
|
import { objectToArray } from '@/lib/data';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import styles from './JourneyView.module.css';
|
import styles from './JourneyView.module.css';
|
||||||
import { formatLongNumber } from 'lib/format';
|
import { formatLongNumber } from '@/lib/format';
|
||||||
|
|
||||||
const NODE_HEIGHT = 60;
|
const NODE_HEIGHT = 60;
|
||||||
const NODE_GAP = 10;
|
const NODE_GAP = 10;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { Form, FormButtons, FormRow, SubmitButton } from 'react-basics';
|
import { Form, FormButtons, FormRow, SubmitButton } from 'react-basics';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import { MonthSelect } from 'components/input/MonthSelect';
|
import { MonthSelect } from '@/components/input/MonthSelect';
|
||||||
import BaseParameters from '../[reportId]/BaseParameters';
|
import BaseParameters from '../[reportId]/BaseParameters';
|
||||||
import { parseDateRange } from 'lib/date';
|
import { parseDateRange } from '@/lib/date';
|
||||||
|
|
||||||
export function RetentionParameters() {
|
export function RetentionParameters() {
|
||||||
const { report, runReport, isRunning, updateReport } = useContext(ReportContext);
|
const { report, runReport, isRunning, updateReport } = useContext(ReportContext);
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ import Report from '../[reportId]/Report';
|
||||||
import ReportHeader from '../[reportId]/ReportHeader';
|
import ReportHeader from '../[reportId]/ReportHeader';
|
||||||
import ReportMenu from '../[reportId]/ReportMenu';
|
import ReportMenu from '../[reportId]/ReportMenu';
|
||||||
import ReportBody from '../[reportId]/ReportBody';
|
import ReportBody from '../[reportId]/ReportBody';
|
||||||
import Magnet from 'assets/magnet.svg';
|
import Magnet from '@/assets/magnet.svg';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from '@/lib/constants';
|
||||||
import { parseDateRange } from 'lib/date';
|
import { parseDateRange } from '@/lib/date';
|
||||||
import { endOfMonth, startOfMonth } from 'date-fns';
|
import { endOfMonth, startOfMonth } from 'date-fns';
|
||||||
|
|
||||||
const defaultParameters = {
|
const defaultParameters = {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
|
import EmptyPlaceholder from '@/components/common/EmptyPlaceholder';
|
||||||
import { useMessages, useLocale } from 'components/hooks';
|
import { useMessages, useLocale } from '@/components/hooks';
|
||||||
import { formatDate } from 'lib/date';
|
import { formatDate } from '@/lib/date';
|
||||||
import styles from './RetentionTable.module.css';
|
import styles from './RetentionTable.module.css';
|
||||||
|
|
||||||
const DAYS = [1, 2, 3, 4, 5, 6, 7, 14, 21, 28];
|
const DAYS = [1, 2, 3, 4, 5, 6, 7, 14, 21, 28];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import useRevenueValues from 'components/hooks/queries/useRevenueValues';
|
import useRevenueValues from '@/components/hooks/queries/useRevenueValues';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { Dropdown, Form, FormButtons, FormInput, FormRow, Item, SubmitButton } from 'react-basics';
|
import { Dropdown, Form, FormButtons, FormInput, FormRow, Item, SubmitButton } from 'react-basics';
|
||||||
import BaseParameters from '../[reportId]/BaseParameters';
|
import BaseParameters from '../[reportId]/BaseParameters';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import Money from 'assets/money.svg';
|
import Money from '@/assets/money.svg';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from '@/lib/constants';
|
||||||
import Report from '../[reportId]/Report';
|
import Report from '../[reportId]/Report';
|
||||||
import ReportBody from '../[reportId]/ReportBody';
|
import ReportBody from '../[reportId]/ReportBody';
|
||||||
import ReportHeader from '../[reportId]/ReportHeader';
|
import ReportHeader from '../[reportId]/ReportHeader';
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import EmptyPlaceholder from 'components/common/EmptyPlaceholder';
|
import EmptyPlaceholder from '@/components/common/EmptyPlaceholder';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { GridColumn, GridTable } from 'react-basics';
|
import { GridColumn, GridTable } from 'react-basics';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import { formatLongCurrency } from 'lib/format';
|
import { formatLongCurrency } from '@/lib/format';
|
||||||
|
|
||||||
export function RevenueTable() {
|
export function RevenueTable() {
|
||||||
const { report } = useContext(ReportContext);
|
const { report } = useContext(ReportContext);
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { colord } from 'colord';
|
import { colord } from 'colord';
|
||||||
import BarChart from 'components/charts/BarChart';
|
import BarChart from '@/components/charts/BarChart';
|
||||||
import PieChart from 'components/charts/PieChart';
|
import PieChart from '@/components/charts/PieChart';
|
||||||
import TypeIcon from 'components/common/TypeIcon';
|
import TypeIcon from '@/components/common/TypeIcon';
|
||||||
import { useCountryNames, useLocale, useMessages } from 'components/hooks';
|
import { useCountryNames, useLocale, useMessages } from '@/components/hooks';
|
||||||
import { GridRow } from 'components/layout/Grid';
|
import { GridRow } from '@/components/layout/Grid';
|
||||||
import ListTable from 'components/metrics/ListTable';
|
import ListTable from '@/components/metrics/ListTable';
|
||||||
import MetricCard from 'components/metrics/MetricCard';
|
import MetricCard from '@/components/metrics/MetricCard';
|
||||||
import MetricsBar from 'components/metrics/MetricsBar';
|
import MetricsBar from '@/components/metrics/MetricsBar';
|
||||||
import { renderDateLabels } from 'lib/charts';
|
import { renderDateLabels } from '@/lib/charts';
|
||||||
import { CHART_COLORS } from 'lib/constants';
|
import { CHART_COLORS } from '@/lib/constants';
|
||||||
import { formatLongCurrency, formatLongNumber } from 'lib/format';
|
import { formatLongCurrency, formatLongNumber } from '@/lib/format';
|
||||||
import { useCallback, useContext, useMemo } from 'react';
|
import { useCallback, useContext, useMemo } from 'react';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import RevenueTable from './RevenueTable';
|
import RevenueTable from './RevenueTable';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import { Form, FormButtons, SubmitButton } from 'react-basics';
|
import { Form, FormButtons, SubmitButton } from 'react-basics';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import BaseParameters from '../[reportId]/BaseParameters';
|
import BaseParameters from '../[reportId]/BaseParameters';
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import ReportMenu from '../[reportId]/ReportMenu';
|
||||||
import ReportBody from '../[reportId]/ReportBody';
|
import ReportBody from '../[reportId]/ReportBody';
|
||||||
import UTMParameters from './UTMParameters';
|
import UTMParameters from './UTMParameters';
|
||||||
import UTMView from './UTMView';
|
import UTMView from './UTMView';
|
||||||
import Tag from 'assets/tag.svg';
|
import Tag from '@/assets/tag.svg';
|
||||||
import { REPORT_TYPES } from 'lib/constants';
|
import { REPORT_TYPES } from '@/lib/constants';
|
||||||
|
|
||||||
const defaultParameters = {
|
const defaultParameters = {
|
||||||
type: REPORT_TYPES.utm,
|
type: REPORT_TYPES.utm,
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { firstBy } from 'thenby';
|
import { firstBy } from 'thenby';
|
||||||
import { ReportContext } from '../[reportId]/Report';
|
import { ReportContext } from '../[reportId]/Report';
|
||||||
import { CHART_COLORS, UTM_PARAMS } from 'lib/constants';
|
import { CHART_COLORS, UTM_PARAMS } from '@/lib/constants';
|
||||||
import PieChart from 'components/charts/PieChart';
|
import PieChart from '@/components/charts/PieChart';
|
||||||
import ListTable from 'components/metrics/ListTable';
|
import ListTable from '@/components/metrics/ListTable';
|
||||||
import styles from './UTMView.module.css';
|
import styles from './UTMView.module.css';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
|
|
||||||
function toArray(data: { [key: string]: number } = {}) {
|
function toArray(data: { [key: string]: number } = {}) {
|
||||||
return Object.keys(data)
|
return Object.keys(data)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { useLogin, useMessages } from 'components/hooks';
|
import { useLogin, useMessages } from '@/components/hooks';
|
||||||
import MenuLayout from 'components/layout/MenuLayout';
|
import MenuLayout from '@/components/layout/MenuLayout';
|
||||||
|
|
||||||
export default function SettingsLayout({ children }: { children: ReactNode }) {
|
export default function SettingsLayout({ children }: { children: ReactNode }) {
|
||||||
const { user } = useLogin();
|
const { user } = useLogin();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useApi, useMessages } from 'components/hooks';
|
import { useApi, useMessages } from '@/components/hooks';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Form,
|
Form,
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ import {
|
||||||
Button,
|
Button,
|
||||||
SubmitButton,
|
SubmitButton,
|
||||||
} from 'react-basics';
|
} from 'react-basics';
|
||||||
import { useApi, useMessages, useModified } from 'components/hooks';
|
import { useApi, useMessages, useModified } from '@/components/hooks';
|
||||||
|
|
||||||
export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
|
export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose: () => void }) {
|
||||||
const { formatMessage, labels, getMessage } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
const { post, useMutation } = useApi();
|
const { post, useMutation } = useApi();
|
||||||
const { mutate, error } = useMutation({ mutationFn: (data: any) => post('/teams/join', data) });
|
const { mutate, error } = useMutation({ mutationFn: (data: any) => post('/teams/join', data) });
|
||||||
const ref = useRef(null);
|
const ref = useRef(null);
|
||||||
|
|
@ -28,7 +28,7 @@ export function TeamJoinForm({ onSave, onClose }: { onSave: () => void; onClose:
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form ref={ref} onSubmit={handleSubmit} error={error && getMessage(error)}>
|
<Form ref={ref} onSubmit={handleSubmit} error={error}>
|
||||||
<FormRow label={formatMessage(labels.accessCode)}>
|
<FormRow label={formatMessage(labels.accessCode)}>
|
||||||
<FormInput name="accessCode" rules={{ required: formatMessage(labels.required) }}>
|
<FormInput name="accessCode" rules={{ required: formatMessage(labels.required) }}>
|
||||||
<TextField autoComplete="off" />
|
<TextField autoComplete="off" />
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useLocale, useLogin, useMessages, useModified } from 'components/hooks';
|
import { useLocale, useLogin, useMessages, useModified } from '@/components/hooks';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
|
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
|
||||||
import TeamDeleteForm from './TeamLeaveForm';
|
import TeamDeleteForm from './TeamLeaveForm';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useApi, useMessages, useModified } from 'components/hooks';
|
import { useApi, useMessages, useModified } from '@/components/hooks';
|
||||||
import ConfirmationForm from 'components/common/ConfirmationForm';
|
import ConfirmationForm from '@/components/common/ConfirmationForm';
|
||||||
|
|
||||||
export function TeamLeaveForm({
|
export function TeamLeaveForm({
|
||||||
teamId,
|
teamId,
|
||||||
|
|
@ -14,7 +14,7 @@ export function TeamLeaveForm({
|
||||||
onSave: () => void;
|
onSave: () => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage, labels, messages, FormattedMessage } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
const { del, useMutation } = useApi();
|
const { del, useMutation } = useApi();
|
||||||
const { mutate, error, isPending } = useMutation({
|
const { mutate, error, isPending } = useMutation({
|
||||||
mutationFn: () => del(`/teams/${teamId}/users/${userId}`),
|
mutationFn: () => del(`/teams/${teamId}/users/${userId}`),
|
||||||
|
|
@ -34,9 +34,7 @@ export function TeamLeaveForm({
|
||||||
return (
|
return (
|
||||||
<ConfirmationForm
|
<ConfirmationForm
|
||||||
buttonLabel={formatMessage(labels.leave)}
|
buttonLabel={formatMessage(labels.leave)}
|
||||||
message={
|
message={formatMessage(messages.confirmLeave, { target: <b>{teamName}</b> })}
|
||||||
<FormattedMessage {...messages.confirmLeave} values={{ target: <b>{teamName}</b> }} />
|
|
||||||
}
|
|
||||||
onConfirm={handleConfirm}
|
onConfirm={handleConfirm}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
isLoading={isPending}
|
isLoading={isPending}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics';
|
import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { useMessages, useModified } from 'components/hooks';
|
import { useMessages, useModified } from '@/components/hooks';
|
||||||
import TeamAddForm from './TeamAddForm';
|
import TeamAddForm from './TeamAddForm';
|
||||||
import { messages } from 'components/messages';
|
import { messages } from '@/components/messages';
|
||||||
|
|
||||||
export function TeamsAddButton({ onSave }: { onSave?: () => void }) {
|
export function TeamsAddButton({ onSave }: { onSave?: () => void }) {
|
||||||
const { formatMessage, labels } = useMessages();
|
const { formatMessage, labels } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import DataTable from 'components/common/DataTable';
|
import DataTable from '@/components/common/DataTable';
|
||||||
import TeamsTable from 'app/(main)/settings/teams/TeamsTable';
|
import TeamsTable from '@/app/(main)/settings/teams/TeamsTable';
|
||||||
import { useLogin, useTeams } from 'components/hooks';
|
import { useLogin, useTeams } from '@/components/hooks';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
export function TeamsDataTable({
|
export function TeamsDataTable({
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Flexbox } from 'react-basics';
|
import { Flexbox } from 'react-basics';
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from '@/components/layout/PageHeader';
|
||||||
import { ROLES } from 'lib/constants';
|
import { ROLES } from '@/lib/constants';
|
||||||
import { useLogin, useMessages } from 'components/hooks';
|
import { useLogin, useMessages } from '@/components/hooks';
|
||||||
import TeamsJoinButton from './TeamsJoinButton';
|
import TeamsJoinButton from './TeamsJoinButton';
|
||||||
import TeamsAddButton from './TeamsAddButton';
|
import TeamsAddButton from './TeamsAddButton';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics';
|
import { Button, Icon, Modal, ModalTrigger, Text, useToasts } from 'react-basics';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { useMessages, useModified } from 'components/hooks';
|
import { useMessages, useModified } from '@/components/hooks';
|
||||||
import TeamJoinForm from './TeamJoinForm';
|
import TeamJoinForm from './TeamJoinForm';
|
||||||
|
|
||||||
export function TeamsJoinButton() {
|
export function TeamsJoinButton() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { GridColumn, GridTable, Icon, Text } from 'react-basics';
|
import { GridColumn, GridTable, Icon, Text } from 'react-basics';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import { ROLES } from 'lib/constants';
|
import { ROLES } from '@/lib/constants';
|
||||||
import LinkButton from 'components/common/LinkButton';
|
import LinkButton from '@/components/common/LinkButton';
|
||||||
|
|
||||||
export function TeamsTable({
|
export function TeamsTable({
|
||||||
data = [],
|
data = [],
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Button, Icon, Text, Modal, Icons, ModalTrigger, useToasts } from 'react-basics';
|
import { Button, Icon, Text, Modal, Icons, ModalTrigger, useToasts } from 'react-basics';
|
||||||
import UserAddForm from './UserAddForm';
|
import UserAddForm from './UserAddForm';
|
||||||
import { useMessages, useModified } from 'components/hooks';
|
import { useMessages, useModified } from '@/components/hooks';
|
||||||
|
|
||||||
export function UserAddButton({ onSave }: { onSave?: () => void }) {
|
export function UserAddButton({ onSave }: { onSave?: () => void }) {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import {
|
||||||
SubmitButton,
|
SubmitButton,
|
||||||
Button,
|
Button,
|
||||||
} from 'react-basics';
|
} from 'react-basics';
|
||||||
import { useApi, useMessages } from 'components/hooks';
|
import { useApi, useMessages } from '@/components/hooks';
|
||||||
import { ROLES } from 'lib/constants';
|
import { ROLES } from '@/lib/constants';
|
||||||
|
|
||||||
export function UserAddForm({ onSave, onClose }) {
|
export function UserAddForm({ onSave, onClose }) {
|
||||||
const { post, useMutation } = useApi();
|
const { post, useMutation } = useApi();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
|
import { Button, Icon, Icons, Modal, ModalTrigger, Text } from 'react-basics';
|
||||||
import { useMessages, useLogin } from 'components/hooks';
|
import { useMessages, useLogin } from '@/components/hooks';
|
||||||
import UserDeleteForm from './UserDeleteForm';
|
import UserDeleteForm from './UserDeleteForm';
|
||||||
|
|
||||||
export function UserDeleteButton({
|
export function UserDeleteButton({
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import { useApi, useMessages, useModified } from 'components/hooks';
|
import { useApi, useMessages, useModified } from '@/components/hooks';
|
||||||
import ConfirmationForm from 'components/common/ConfirmationForm';
|
import ConfirmationForm from '@/components/common/ConfirmationForm';
|
||||||
|
|
||||||
export function UserDeleteForm({ userId, username, onSave, onClose }) {
|
export function UserDeleteForm({ userId, username, onSave, onClose }) {
|
||||||
const { FormattedMessage, messages, labels, formatMessage } = useMessages();
|
const { messages, labels, formatMessage } = useMessages();
|
||||||
const { del, useMutation } = useApi();
|
const { del, useMutation } = useApi();
|
||||||
const { mutate, error, isPending } = useMutation({ mutationFn: () => del(`/users/${userId}`) });
|
const { mutate, error, isPending } = useMutation({ mutationFn: () => del(`/users/${userId}`) });
|
||||||
const { touch } = useModified();
|
const { touch } = useModified();
|
||||||
|
|
@ -19,9 +19,7 @@ export function UserDeleteForm({ userId, username, onSave, onClose }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfirmationForm
|
<ConfirmationForm
|
||||||
message={
|
message={formatMessage(messages.confirmDelete, { target: <b>{username}</b> })}
|
||||||
<FormattedMessage {...messages.confirmDelete} values={{ target: <b>{username}</b> }} />
|
|
||||||
}
|
|
||||||
onConfirm={handleConfirm}
|
onConfirm={handleConfirm}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
buttonLabel={formatMessage(labels.delete)}
|
buttonLabel={formatMessage(labels.delete)}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import DataTable from 'components/common/DataTable';
|
import DataTable from '@/components/common/DataTable';
|
||||||
import { useUsers } from 'components/hooks';
|
import { useUsers } from '@/components/hooks';
|
||||||
import UsersTable from './UsersTable';
|
import UsersTable from './UsersTable';
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from '@/components/layout/PageHeader';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import UserAddButton from './UserAddButton';
|
import UserAddButton from './UserAddButton';
|
||||||
|
|
||||||
export function UsersHeader({ onAdd }: { onAdd?: () => void }) {
|
export function UsersHeader({ onAdd }: { onAdd?: () => void }) {
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { Text, Icon, Icons, GridTable, GridColumn } from 'react-basics';
|
import { Text, Icon, Icons, GridTable, GridColumn } from 'react-basics';
|
||||||
import { formatDistance } from 'date-fns';
|
import { formatDistance } from 'date-fns';
|
||||||
import { ROLES } from 'lib/constants';
|
import { ROLES } from '@/lib/constants';
|
||||||
import { useMessages, useLocale } from 'components/hooks';
|
import { useMessages, useLocale } from '@/components/hooks';
|
||||||
import UserDeleteButton from './UserDeleteButton';
|
import UserDeleteButton from './UserDeleteButton';
|
||||||
import LinkButton from 'components/common/LinkButton';
|
import LinkButton from '@/components/common/LinkButton';
|
||||||
|
|
||||||
export function UsersTable({
|
export function UsersTable({
|
||||||
data = [],
|
data = [],
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import {
|
||||||
SubmitButton,
|
SubmitButton,
|
||||||
PasswordField,
|
PasswordField,
|
||||||
} from 'react-basics';
|
} from 'react-basics';
|
||||||
import { useApi, useLogin, useMessages } from 'components/hooks';
|
import { useApi, useLogin, useMessages } from '@/components/hooks';
|
||||||
import { ROLES } from 'lib/constants';
|
import { ROLES } from '@/lib/constants';
|
||||||
import { useContext, useRef } from 'react';
|
import { useContext, useRef } from 'react';
|
||||||
import { UserContext } from './UserProvider';
|
import { UserContext } from './UserProvider';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { createContext, ReactNode, useEffect } from 'react';
|
import { createContext, ReactNode, useEffect } from 'react';
|
||||||
import { useModified, useUser } from 'components/hooks';
|
import { useModified, useUser } from '@/components/hooks';
|
||||||
import { Loading } from 'react-basics';
|
import { Loading } from 'react-basics';
|
||||||
|
|
||||||
export const UserContext = createContext(null);
|
export const UserContext = createContext(null);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { Key, useContext, useState } from 'react';
|
import { Key, useContext, useState } from 'react';
|
||||||
import { Item, Tabs, useToasts } from 'react-basics';
|
import { Item, Tabs, useToasts } from 'react-basics';
|
||||||
import Icons from 'components/icons';
|
import Icons from '@/components/icons';
|
||||||
import UserEditForm from './UserEditForm';
|
import UserEditForm from './UserEditForm';
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from '@/components/layout/PageHeader';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import UserWebsites from './UserWebsites';
|
import UserWebsites from './UserWebsites';
|
||||||
import { UserContext } from './UserProvider';
|
import { UserContext } from './UserProvider';
|
||||||
import Breadcrumb from 'components/common/Breadcrumb';
|
import Breadcrumb from '@/components/common/Breadcrumb';
|
||||||
|
|
||||||
export function UserSettings({ userId }: { userId: string }) {
|
export function UserSettings({ userId }: { userId: string }) {
|
||||||
const { formatMessage, labels, messages } = useMessages();
|
const { formatMessage, labels, messages } = useMessages();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import WebsitesTable from 'app/(main)/settings/websites/WebsitesTable';
|
import WebsitesTable from '@/app/(main)/settings/websites/WebsitesTable';
|
||||||
import DataTable from 'components/common/DataTable';
|
import DataTable from '@/components/common/DataTable';
|
||||||
import { useWebsites } from 'components/hooks';
|
import { useWebsites } from '@/components/hooks';
|
||||||
|
|
||||||
export function UserWebsites({ userId }) {
|
export function UserWebsites({ userId }) {
|
||||||
const queryResult = useWebsites({ userId });
|
const queryResult = useWebsites({ userId });
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useMessages, useModified } from 'components/hooks';
|
import { useMessages, useModified } from '@/components/hooks';
|
||||||
import { Button, Icon, Icons, Modal, ModalTrigger, Text, useToasts } from 'react-basics';
|
import { Button, Icon, Icons, Modal, ModalTrigger, Text, useToasts } from 'react-basics';
|
||||||
import WebsiteAddForm from './WebsiteAddForm';
|
import WebsiteAddForm from './WebsiteAddForm';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ import {
|
||||||
Button,
|
Button,
|
||||||
SubmitButton,
|
SubmitButton,
|
||||||
} from 'react-basics';
|
} from 'react-basics';
|
||||||
import { useApi } from 'components/hooks';
|
import { useApi } from '@/components/hooks';
|
||||||
import { DOMAIN_REGEX } from 'lib/constants';
|
import { DOMAIN_REGEX } from '@/lib/constants';
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
|
|
||||||
export function WebsiteAddForm({
|
export function WebsiteAddForm({
|
||||||
teamId,
|
teamId,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import WebsitesTable from 'app/(main)/settings/websites/WebsitesTable';
|
import WebsitesTable from '@/app/(main)/settings/websites/WebsitesTable';
|
||||||
import DataTable from 'components/common/DataTable';
|
import DataTable from '@/components/common/DataTable';
|
||||||
import { useWebsites } from 'components/hooks';
|
import { useWebsites } from '@/components/hooks';
|
||||||
|
|
||||||
export function WebsitesDataTable({
|
export function WebsitesDataTable({
|
||||||
teamId,
|
teamId,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useMessages } from 'components/hooks';
|
import { useMessages } from '@/components/hooks';
|
||||||
import PageHeader from 'components/layout/PageHeader';
|
import PageHeader from '@/components/layout/PageHeader';
|
||||||
import WebsiteAddButton from './WebsiteAddButton';
|
import WebsiteAddButton from './WebsiteAddButton';
|
||||||
|
|
||||||
export interface WebsitesHeaderProps {
|
export interface WebsitesHeaderProps {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
'use client';
|
'use client';
|
||||||
import { useLogin } from 'components/hooks';
|
import { useLogin } from '@/components/hooks';
|
||||||
import WebsitesDataTable from './WebsitesDataTable';
|
import WebsitesDataTable from './WebsitesDataTable';
|
||||||
import WebsitesHeader from './WebsitesHeader';
|
import WebsitesHeader from './WebsitesHeader';
|
||||||
import { ROLES } from 'lib/constants';
|
import { ROLES } from '@/lib/constants';
|
||||||
|
|
||||||
export default function WebsitesSettingsPage({ teamId }: { teamId: string }) {
|
export default function WebsitesSettingsPage({ teamId }: { teamId: string }) {
|
||||||
const { user } = useLogin();
|
const { user } = useLogin();
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import { Text, Icon, Icons, GridTable, GridColumn } from 'react-basics';
|
import { Text, Icon, Icons, GridTable, GridColumn } from 'react-basics';
|
||||||
import { useMessages, useTeamUrl } from 'components/hooks';
|
import { useMessages, useTeamUrl } from '@/components/hooks';
|
||||||
import LinkButton from 'components/common/LinkButton';
|
import LinkButton from '@/components/common/LinkButton';
|
||||||
|
|
||||||
export interface WebsitesTableProps {
|
export interface WebsitesTableProps {
|
||||||
data: any[];
|
data: any[];
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue