feat: client, instructor, tenant join relationship
This commit is contained in:
parent
5d03b2c414
commit
553ca30d12
31
src/collections/InstructorClientTenantRelations/index.ts
Normal file
31
src/collections/InstructorClientTenantRelations/index.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { CollectionConfig } from "payload";
|
||||
|
||||
export const InstructorClientTenantRelations: CollectionConfig = {
|
||||
slug: 'instructorClientTenantRelations',
|
||||
fields: [
|
||||
{
|
||||
name: 'displayName',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'instructor',
|
||||
type: 'relationship',
|
||||
relationTo: 'users',
|
||||
hasMany: false,
|
||||
},
|
||||
{
|
||||
name: 'client',
|
||||
type: 'relationship',
|
||||
relationTo: 'users',
|
||||
hasMany: false,
|
||||
},
|
||||
{
|
||||
name: 'tenant',
|
||||
type: 'relationship',
|
||||
relationTo: 'tenants',
|
||||
hasMany: false,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default InstructorClientTenantRelations
|
||||
@ -17,6 +17,8 @@ export const readAccess: Access<User> = ({ req, id }) => {
|
||||
}
|
||||
|
||||
const superAdmin = isSuperAdmin(req.user)
|
||||
if (superAdmin) return true;
|
||||
|
||||
const selectedTenant = getTenantFromCookie(
|
||||
req.headers,
|
||||
getCollectionIDType({ payload: req.payload, collectionSlug: 'tenants' }),
|
||||
@ -35,10 +37,6 @@ export const readAccess: Access<User> = ({ req, id }) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (superAdmin) {
|
||||
return true
|
||||
}
|
||||
|
||||
return {
|
||||
or: [
|
||||
{
|
||||
|
||||
@ -28,7 +28,7 @@ const defaultTenantArrayField = tenantsArrayField({
|
||||
{
|
||||
name: 'roles',
|
||||
type: 'select',
|
||||
defaultValue: ['tenant-viewer'],
|
||||
defaultValue: ['tenant-client'],
|
||||
hasMany: true,
|
||||
options: ['tenant-admin', 'tenant-client', 'tenant-instructor'],
|
||||
required: true,
|
||||
@ -76,12 +76,6 @@ export const Users: CollectionConfig = {
|
||||
},
|
||||
index: true,
|
||||
},
|
||||
{
|
||||
name: 'accessLevel',
|
||||
type: 'number',
|
||||
max: UserAccessLevel.FULL_ACCESS,
|
||||
defaultValue: UserAccessLevel.GUEST,
|
||||
},
|
||||
{
|
||||
...defaultTenantArrayField,
|
||||
admin: {
|
||||
@ -89,6 +83,18 @@ export const Users: CollectionConfig = {
|
||||
position: 'sidebar',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'clients',
|
||||
type: 'join',
|
||||
collection: 'instructorClientTenantRelations',
|
||||
on: 'instructor',
|
||||
admin: {
|
||||
condition: (data) => {
|
||||
const tenantRoles = data.tenants?.flatMap((t: any) => t.roles)
|
||||
return tenantRoles.includes('tenant-instructor')
|
||||
}
|
||||
},
|
||||
}
|
||||
],
|
||||
timestamps: true,
|
||||
hooks: {
|
||||
|
||||
@ -86,6 +86,7 @@ export interface Config {
|
||||
habbits: Habbit;
|
||||
habbitEntries: HabbitEntry;
|
||||
schedules: Schedule;
|
||||
instructorClientTenantRelations: InstructorClientTenantRelation;
|
||||
redirects: Redirect;
|
||||
forms: Form;
|
||||
'form-submissions': FormSubmission;
|
||||
@ -95,7 +96,11 @@ export interface Config {
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
};
|
||||
collectionsJoins: {};
|
||||
collectionsJoins: {
|
||||
users: {
|
||||
clients: 'instructorClientTenantRelations';
|
||||
};
|
||||
};
|
||||
collectionsSelect: {
|
||||
pages: PagesSelect<false> | PagesSelect<true>;
|
||||
posts: PostsSelect<false> | PostsSelect<true>;
|
||||
@ -116,6 +121,7 @@ export interface Config {
|
||||
habbits: HabbitsSelect<false> | HabbitsSelect<true>;
|
||||
habbitEntries: HabbitEntriesSelect<false> | HabbitEntriesSelect<true>;
|
||||
schedules: SchedulesSelect<false> | SchedulesSelect<true>;
|
||||
instructorClientTenantRelations: InstructorClientTenantRelationsSelect<false> | InstructorClientTenantRelationsSelect<true>;
|
||||
redirects: RedirectsSelect<false> | RedirectsSelect<true>;
|
||||
forms: FormsSelect<false> | FormsSelect<true>;
|
||||
'form-submissions': FormSubmissionsSelect<false> | FormSubmissionsSelect<true>;
|
||||
@ -426,7 +432,6 @@ export interface User {
|
||||
id: number;
|
||||
roles?: ('full-access' | 'super-admin' | 'user' | 'guest')[] | null;
|
||||
username?: string | null;
|
||||
accessLevel?: number | null;
|
||||
tenants?:
|
||||
| {
|
||||
tenant: number | Tenant;
|
||||
@ -434,6 +439,11 @@ export interface User {
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
clients?: {
|
||||
docs?: (number | InstructorClientTenantRelation)[];
|
||||
hasNextPage?: boolean;
|
||||
totalDocs?: number;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
email: string;
|
||||
@ -445,6 +455,19 @@ export interface User {
|
||||
lockUntil?: string | null;
|
||||
password?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "instructorClientTenantRelations".
|
||||
*/
|
||||
export interface InstructorClientTenantRelation {
|
||||
id: number;
|
||||
displayName?: string | null;
|
||||
instructor?: (number | null) | User;
|
||||
client?: (number | null) | User;
|
||||
tenant?: (number | null) | Tenant;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "CallToActionBlock".
|
||||
@ -1434,6 +1457,10 @@ export interface PayloadLockedDocument {
|
||||
relationTo: 'schedules';
|
||||
value: number | Schedule;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'instructorClientTenantRelations';
|
||||
value: number | InstructorClientTenantRelation;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'redirects';
|
||||
value: number | Redirect;
|
||||
@ -1783,7 +1810,6 @@ export interface CategoriesSelect<T extends boolean = true> {
|
||||
export interface UsersSelect<T extends boolean = true> {
|
||||
roles?: T;
|
||||
username?: T;
|
||||
accessLevel?: T;
|
||||
tenants?:
|
||||
| T
|
||||
| {
|
||||
@ -1791,6 +1817,7 @@ export interface UsersSelect<T extends boolean = true> {
|
||||
roles?: T;
|
||||
id?: T;
|
||||
};
|
||||
clients?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
email?: T;
|
||||
@ -2030,6 +2057,18 @@ export interface SchedulesSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "instructorClientTenantRelations_select".
|
||||
*/
|
||||
export interface InstructorClientTenantRelationsSelect<T extends boolean = true> {
|
||||
displayName?: T;
|
||||
instructor?: T;
|
||||
client?: T;
|
||||
tenant?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "redirects_select".
|
||||
|
||||
@ -24,6 +24,7 @@ import { HabbitCategories } from './collections/Habbits/HabbitCategories'
|
||||
import { Habbits } from './collections/Habbits/Habbits'
|
||||
import { HabbitEntries } from './collections/Habbits/HabbitEntry'
|
||||
import { Schedules } from './collections/Schedules'
|
||||
import InstructorClientTenantRelations from './collections/InstructorClientTenantRelations'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
@ -72,7 +73,7 @@ export default buildConfig({
|
||||
connectionString: process.env.DATABASE_URI || '',
|
||||
},
|
||||
}),
|
||||
collections: [Pages, Posts, Media, Categories, Users, Tenants, Exercises, ExerciseTypes, MuscleGroups, Equipments, Workouts, WorkoutTypes, Ingredients, MealItems, Meals, HabbitCategories, Habbits, HabbitEntries, Schedules],
|
||||
collections: [Pages, Posts, Media, Categories, Users, Tenants, Exercises, ExerciseTypes, MuscleGroups, Equipments, Workouts, WorkoutTypes, Ingredients, MealItems, Meals, HabbitCategories, Habbits, HabbitEntries, Schedules, InstructorClientTenantRelations],
|
||||
cors: [getServerSideURL()].filter(Boolean),
|
||||
globals: [Header, Footer],
|
||||
plugins: [
|
||||
|
||||
@ -14,7 +14,6 @@ import { beforeSyncWithSearch } from '@/search/beforeSync'
|
||||
|
||||
import { Config, Page, Post, User } from '@/payload-types'
|
||||
import { getServerSideURL } from '@/utilities/getURL'
|
||||
import { UserAccessLevel } from '@/collections/Users'
|
||||
import { isSuperAdmin } from '@/access/isSuperAdmin'
|
||||
import { getUserTenantIDs } from '@/utilities/getUserTenantIds'
|
||||
|
||||
@ -117,7 +116,7 @@ export const plugins: Plugin[] = [
|
||||
tenantsArrayField: {
|
||||
includeDefaultField: false,
|
||||
},
|
||||
userHasAccessToAllTenants: (user: User) => (user.accessLevel || 0) >= UserAccessLevel.SUPER_ADMIN,
|
||||
userHasAccessToAllTenants: (user: User) => isSuperAdmin(user),
|
||||
tenantField: {
|
||||
access: {
|
||||
read: () => true,
|
||||
@ -127,7 +126,6 @@ export const plugins: Plugin[] = [
|
||||
}
|
||||
return getUserTenantIDs(req.user).length > 0
|
||||
},
|
||||
create: () => true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user