5899 display a banner to alert users which need to reconnect their account (#6301)
Closes #5899 <img width="1280" alt="Index - banner" src="https://github.com/twentyhq/twenty/assets/71827178/313cf20d-eb34-496a-8c7c-7589fbd55954"> --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import { Field, ObjectType } from '@nestjs/graphql';
|
||||
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
@ -12,12 +13,17 @@ import {
|
||||
Unique,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
export enum KeyValuePairType {
|
||||
USER_VAR = 'USER_VAR',
|
||||
FEATURE_FLAG = 'FEATURE_FLAG',
|
||||
SYSTEM_VAR = 'SYSTEM_VAR',
|
||||
}
|
||||
|
||||
@Entity({ name: 'keyValuePair', schema: 'core' })
|
||||
@ObjectType('KeyValuePair')
|
||||
@Unique('IndexOnKeyUserIdWorkspaceIdUnique', ['key', 'userId', 'workspaceId'])
|
||||
@ -41,7 +47,7 @@ export class KeyValuePair {
|
||||
user: Relation<User>;
|
||||
|
||||
@Column({ nullable: true })
|
||||
userId: string;
|
||||
userId: string | null;
|
||||
|
||||
@ManyToOne(() => Workspace, (workspace) => workspace.keyValuePairs, {
|
||||
onDelete: 'CASCADE',
|
||||
@ -50,15 +56,28 @@ export class KeyValuePair {
|
||||
workspace: Relation<Workspace>;
|
||||
|
||||
@Column({ nullable: true })
|
||||
workspaceId: string;
|
||||
workspaceId: string | null;
|
||||
|
||||
@Field(() => String)
|
||||
@Column({ nullable: false, type: 'text' })
|
||||
key: string;
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
@Column({ nullable: true, type: 'text' })
|
||||
value: string;
|
||||
@Field(() => JSON, { nullable: true })
|
||||
@Column('jsonb', { nullable: true })
|
||||
value: JSON;
|
||||
|
||||
@Field(() => String)
|
||||
@Column({ nullable: false, type: 'text' })
|
||||
textValueDeprecated: string;
|
||||
|
||||
@Field(() => KeyValuePairType)
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: Object.values(KeyValuePairType),
|
||||
nullable: false,
|
||||
default: KeyValuePairType.USER_VAR,
|
||||
})
|
||||
type: KeyValuePairType;
|
||||
|
||||
@CreateDateColumn({ type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
@ -1,59 +1,79 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { BadRequestException } from '@nestjs/common';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
import { IsNull, Repository } from 'typeorm';
|
||||
|
||||
import { KeyValuePair } from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
|
||||
import {
|
||||
KeyValuePair,
|
||||
KeyValuePairType,
|
||||
} from 'src/engine/core-modules/key-value-pair/key-value-pair.entity';
|
||||
|
||||
export class KeyValuePairService<TYPE> {
|
||||
export class KeyValuePairService<
|
||||
KeyValueTypesMap extends Record<string, any> = Record<string, any>,
|
||||
> {
|
||||
constructor(
|
||||
@InjectRepository(KeyValuePair, 'core')
|
||||
private readonly keyValuePairRepository: Repository<KeyValuePair>,
|
||||
) {}
|
||||
|
||||
async get<K extends keyof TYPE>({
|
||||
async get<K extends keyof KeyValueTypesMap>({
|
||||
userId,
|
||||
workspaceId,
|
||||
type,
|
||||
key,
|
||||
}: {
|
||||
userId?: string;
|
||||
workspaceId?: string;
|
||||
key: K;
|
||||
}): Promise<TYPE[K] | undefined> {
|
||||
return (
|
||||
await this.keyValuePairRepository.findOne({
|
||||
where: {
|
||||
userId,
|
||||
workspaceId,
|
||||
key: key as string,
|
||||
},
|
||||
})
|
||||
)?.value as TYPE[K] | undefined;
|
||||
userId?: string | null;
|
||||
workspaceId?: string | null;
|
||||
type: KeyValuePairType;
|
||||
key?: Extract<K, string>;
|
||||
}): Promise<Array<KeyValueTypesMap[K]>> {
|
||||
const keyValuePairs = (await this.keyValuePairRepository.find({
|
||||
where: {
|
||||
...(userId === undefined
|
||||
? {}
|
||||
: userId === null
|
||||
? { userId: IsNull() }
|
||||
: { userId }),
|
||||
...(workspaceId === undefined
|
||||
? {}
|
||||
: workspaceId === null
|
||||
? { workspaceId: IsNull() }
|
||||
: { workspaceId }),
|
||||
...(key === undefined ? {} : { key }),
|
||||
type,
|
||||
},
|
||||
})) as Array<KeyValueTypesMap[K]>;
|
||||
|
||||
return keyValuePairs.map((keyValuePair) => ({
|
||||
...keyValuePair,
|
||||
value: keyValuePair.value ?? keyValuePair.textValueDeprecated,
|
||||
}));
|
||||
}
|
||||
|
||||
async set<K extends keyof TYPE>({
|
||||
async set<K extends keyof KeyValueTypesMap>({
|
||||
userId,
|
||||
workspaceId,
|
||||
key,
|
||||
value,
|
||||
type,
|
||||
}: {
|
||||
userId?: string;
|
||||
workspaceId?: string;
|
||||
key: K;
|
||||
value: TYPE[K];
|
||||
userId?: string | null;
|
||||
workspaceId?: string | null;
|
||||
key: Extract<K, string>;
|
||||
value: KeyValueTypesMap[K];
|
||||
type: KeyValuePairType;
|
||||
}) {
|
||||
if (!userId && !workspaceId) {
|
||||
throw new BadRequestException('userId and workspaceId are undefined');
|
||||
}
|
||||
const upsertData = {
|
||||
userId,
|
||||
workspaceId,
|
||||
key: key as string,
|
||||
value: value as string,
|
||||
key,
|
||||
value,
|
||||
type,
|
||||
};
|
||||
|
||||
const conflictPaths = Object.keys(upsertData).filter(
|
||||
(key) => key !== 'value' && upsertData[key] !== undefined,
|
||||
(key) =>
|
||||
['userId', 'workspaceId', 'key'].includes(key) &&
|
||||
upsertData[key] !== undefined,
|
||||
);
|
||||
|
||||
const indexPredicate = !userId
|
||||
@ -67,4 +87,31 @@ export class KeyValuePairService<TYPE> {
|
||||
indexPredicate,
|
||||
});
|
||||
}
|
||||
|
||||
async delete({
|
||||
userId,
|
||||
workspaceId,
|
||||
type,
|
||||
key,
|
||||
}: {
|
||||
userId?: string | null;
|
||||
workspaceId?: string | null;
|
||||
type: KeyValuePairType;
|
||||
key: Extract<keyof KeyValueTypesMap, string>;
|
||||
}) {
|
||||
await this.keyValuePairRepository.delete({
|
||||
...(userId === undefined
|
||||
? {}
|
||||
: userId === null
|
||||
? { userId: IsNull() }
|
||||
: { userId }),
|
||||
...(workspaceId === undefined
|
||||
? {}
|
||||
: workspaceId === null
|
||||
? { workspaceId: IsNull() }
|
||||
: { workspaceId }),
|
||||
type,
|
||||
key,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user