refactor: update role's position and add status page edit check
This commit is contained in:
parent
824d5cd14e
commit
bb83f4b56d
@ -1,24 +1,28 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useParams } from 'react-router';
|
import { useParams } from 'react-router';
|
||||||
import { trpc } from '../api/trpc';
|
import { trpc } from '../api/trpc';
|
||||||
import { Empty } from 'antd';
|
import { Button, Empty } from 'antd';
|
||||||
import { MonitorHealthBar } from '../components/monitor/MonitorHealthBar';
|
import { MonitorHealthBar } from '../components/monitor/MonitorHealthBar';
|
||||||
import { useUserStore } from '../store/user';
|
import { useUserInfo } from '../store/user';
|
||||||
|
import { ROLES } from '../../shared';
|
||||||
|
|
||||||
export const StatusPage: React.FC = React.memo(() => {
|
export const StatusPage: React.FC = React.memo(() => {
|
||||||
const { slug } = useParams<{ slug: string }>();
|
const { slug } = useParams<{ slug: string }>();
|
||||||
useUserStore();
|
|
||||||
|
|
||||||
const { data: info } = trpc.monitor.getPageInfo.useQuery({
|
const { data: info } = trpc.monitor.getPageInfo.useQuery({
|
||||||
slug: slug!,
|
slug: slug!,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const allowEdit = useAllowEdit(info?.workspaceId);
|
||||||
|
|
||||||
const monitorList = info?.monitorList ?? [];
|
const monitorList = info?.monitorList ?? [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-4/5 mx-auto py-8 ">
|
<div className="w-4/5 mx-auto py-8 ">
|
||||||
<div className="text-2xl mb-4">{info?.title}</div>
|
<div className="text-2xl mb-4">{info?.title}</div>
|
||||||
|
|
||||||
|
<div>{allowEdit && <Button type="primary">Edit</Button>}</div>
|
||||||
|
|
||||||
<div className="text-lg mb-2">Services</div>
|
<div className="text-lg mb-2">Services</div>
|
||||||
|
|
||||||
{info && (
|
{info && (
|
||||||
@ -44,3 +48,19 @@ export const StatusPage: React.FC = React.memo(() => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
StatusPage.displayName = 'StatusPage';
|
StatusPage.displayName = 'StatusPage';
|
||||||
|
|
||||||
|
function useAllowEdit(workspaceId?: string): boolean {
|
||||||
|
const userInfo = useUserInfo();
|
||||||
|
|
||||||
|
const { data: role } = trpc.workspace.getUserWorkspaceRole.useQuery(
|
||||||
|
{
|
||||||
|
workspaceId: workspaceId!,
|
||||||
|
userId: userInfo?.id!,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
enabled: !!userInfo?.id && !!workspaceId,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return role === ROLES.owner;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Handler } from 'express';
|
import { Handler } from 'express';
|
||||||
import { getWorkspaceUser } from '../model/workspace';
|
import { getWorkspaceUser } from '../model/workspace';
|
||||||
import { ROLES } from '../utils/const';
|
import { ROLES } from '../../shared';
|
||||||
|
|
||||||
export function workspacePermission(roles: ROLES[] = []): Handler {
|
export function workspacePermission(roles: ROLES[] = []): Handler {
|
||||||
return async (req, res, next) => {
|
return async (req, res, next) => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { prisma } from './_client';
|
import { prisma } from './_client';
|
||||||
import bcryptjs from 'bcryptjs';
|
import bcryptjs from 'bcryptjs';
|
||||||
import { ROLES, SYSTEM_ROLES } from '../utils/const';
|
import { ROLES, SYSTEM_ROLES } from '../../shared';
|
||||||
import { jwtVerify } from '../middleware/auth';
|
import { jwtVerify } from '../middleware/auth';
|
||||||
import { TRPCError } from '@trpc/server';
|
import { TRPCError } from '@trpc/server';
|
||||||
import { Prisma } from '@prisma/client';
|
import { Prisma } from '@prisma/client';
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
import { body, validate } from '../middleware/validate';
|
import { body, validate } from '../middleware/validate';
|
||||||
import * as yup from 'yup';
|
import * as yup from 'yup';
|
||||||
import { COLLECTION_TYPE, HOSTNAME_REGEX } from '../utils/const';
|
import { COLLECTION_TYPE } from '../utils/const';
|
||||||
import {
|
import {
|
||||||
findSession,
|
findSession,
|
||||||
saveWebsiteEvent,
|
saveWebsiteEvent,
|
||||||
saveWebsiteSessionData,
|
saveWebsiteSessionData,
|
||||||
} from '../model/website';
|
} from '../model/website';
|
||||||
import { createToken } from '../utils/common';
|
import { createToken } from '../utils/common';
|
||||||
|
import { hostnameRegex } from '../../shared';
|
||||||
|
|
||||||
export const websiteRouter = Router();
|
export const websiteRouter = Router();
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ websiteRouter.post(
|
|||||||
.object()
|
.object()
|
||||||
.shape({
|
.shape({
|
||||||
data: yup.object(),
|
data: yup.object(),
|
||||||
hostname: yup.string().matches(HOSTNAME_REGEX).max(100),
|
hostname: yup.string().matches(hostnameRegex).max(100),
|
||||||
language: yup.string().max(35),
|
language: yup.string().max(35),
|
||||||
referrer: yup.string().max(500),
|
referrer: yup.string().max(500),
|
||||||
screen: yup.string().max(11),
|
screen: yup.string().max(11),
|
||||||
|
@ -12,8 +12,8 @@ import {
|
|||||||
getWorkspaceWebsiteStats,
|
getWorkspaceWebsiteStats,
|
||||||
} from '../model/workspace';
|
} from '../model/workspace';
|
||||||
import { parseDateRange } from '../utils/common';
|
import { parseDateRange } from '../utils/common';
|
||||||
import { ROLES } from '../utils/const';
|
|
||||||
import { QueryFilters } from '../utils/prisma';
|
import { QueryFilters } from '../utils/prisma';
|
||||||
|
import { ROLES } from '../../shared';
|
||||||
|
|
||||||
export const workspaceRouter = Router();
|
export const workspaceRouter = Router();
|
||||||
|
|
||||||
|
@ -1,10 +1,32 @@
|
|||||||
import { router, workspaceOwnerProcedure } from '../trpc';
|
import { publicProcedure, router, workspaceOwnerProcedure } from '../trpc';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { prisma } from '../../model/_client';
|
import { prisma } from '../../model/_client';
|
||||||
import { workspaceDashboardLayoutSchema } from '../../model/_schema';
|
import { workspaceDashboardLayoutSchema } from '../../model/_schema';
|
||||||
import { Prisma } from '@prisma/client';
|
import { Prisma } from '@prisma/client';
|
||||||
|
|
||||||
export const workspaceRouter = router({
|
export const workspaceRouter = router({
|
||||||
|
getUserWorkspaceRole: publicProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
userId: z.string(),
|
||||||
|
workspaceId: z.string(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.output(z.string().nullable())
|
||||||
|
.query(async ({ input }) => {
|
||||||
|
const { userId, workspaceId } = input;
|
||||||
|
|
||||||
|
const relation = await prisma.workspacesOnUsers.findUnique({
|
||||||
|
where: {
|
||||||
|
userId_workspaceId: {
|
||||||
|
workspaceId,
|
||||||
|
userId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return relation?.role ?? null;
|
||||||
|
}),
|
||||||
updateDashboardOrder: workspaceOwnerProcedure
|
updateDashboardOrder: workspaceOwnerProcedure
|
||||||
.input(
|
.input(
|
||||||
z.object({
|
z.object({
|
||||||
|
@ -3,7 +3,7 @@ import _ from 'lodash';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { jwtVerify } from '../middleware/auth';
|
import { jwtVerify } from '../middleware/auth';
|
||||||
import { getWorkspaceUser } from '../model/workspace';
|
import { getWorkspaceUser } from '../model/workspace';
|
||||||
import { ROLES, SYSTEM_ROLES } from '../utils/const';
|
import { ROLES, SYSTEM_ROLES } from '../../shared';
|
||||||
import type { IncomingMessage } from 'http';
|
import type { IncomingMessage } from 'http';
|
||||||
import { OpenApiMeta } from 'trpc-openapi';
|
import { OpenApiMeta } from 'trpc-openapi';
|
||||||
|
|
||||||
|
@ -1,16 +1,3 @@
|
|||||||
export enum SYSTEM_ROLES {
|
|
||||||
admin = 'admin',
|
|
||||||
user = 'user',
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum ROLES {
|
|
||||||
owner = 'owner',
|
|
||||||
readOnly = 'readOnly',
|
|
||||||
}
|
|
||||||
|
|
||||||
export const HOSTNAME_REGEX =
|
|
||||||
/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/;
|
|
||||||
|
|
||||||
export const COLLECTION_TYPE = {
|
export const COLLECTION_TYPE = {
|
||||||
event: 'event',
|
event: 'event',
|
||||||
identify: 'identify',
|
identify: 'identify',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import puppeteer from 'puppeteer';
|
import puppeteer from 'puppeteer';
|
||||||
import { jwtSign } from '../../middleware/auth';
|
import { jwtSign } from '../../middleware/auth';
|
||||||
import { SYSTEM_ROLES } from '../const';
|
import { SYSTEM_ROLES } from '../../../shared';
|
||||||
import { settings } from '../settings';
|
import { settings } from '../settings';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
export * from './date';
|
export * from './date';
|
||||||
export * from './server';
|
export * from './server';
|
||||||
export * from './regex';
|
export * from './regex';
|
||||||
|
export * from './role';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export const hostnameRegex =
|
export const hostnameRegex =
|
||||||
/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/;
|
/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/;
|
||||||
|
|
||||||
export const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
export const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
||||||
|
9
src/shared/role.ts
Normal file
9
src/shared/role.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export enum SYSTEM_ROLES {
|
||||||
|
admin = 'admin',
|
||||||
|
user = 'user',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum ROLES {
|
||||||
|
owner = 'owner',
|
||||||
|
readOnly = 'readOnly',
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user