fix dropdown.

This commit is contained in:
Simon Larsen 2022-08-01 10:37:14 +01:00
parent ad440d470e
commit 6d85a2aa8c
No known key found for this signature in database
GPG Key ID: AB45983AA9C81CDE
16 changed files with 117 additions and 21 deletions

View File

@ -42,6 +42,7 @@ export default class ApiKey extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'projectId',
type: TableColumnType.Entity,
modelType: Project
})
@ManyToOne(
(_type: string) => {
@ -119,6 +120,7 @@ export default class ApiKey extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'createdByUserId',
type: TableColumnType.Entity,
modelType: User
})
@ManyToOne(
(_type: string) => {

View File

@ -74,6 +74,7 @@ export default class APIKeyPermission extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'apiKeyId',
type: TableColumnType.Entity,
modelType: ApiKey
})
@ManyToOne(
(_type: string) => {
@ -105,6 +106,7 @@ export default class APIKeyPermission extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'projectId',
type: TableColumnType.Entity,
modelType: Project
})
@ManyToOne(
(_type: string) => {
@ -176,6 +178,7 @@ export default class APIKeyPermission extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'createdByUserId',
type: TableColumnType.Entity,
modelType: User
})
@ManyToOne(
(_type: string) => {
@ -292,7 +295,7 @@ export default class APIKeyPermission extends BaseModel {
Permission.CanEditProjectApiKey,
],
})
@TableColumn({ required: false, type: TableColumnType.Array })
@TableColumn({ required: false, type: TableColumnType.EntityArray, modelType: Label })
@ManyToMany(() => {
return Label;
})

View File

@ -269,6 +269,11 @@ export default class BaseModel extends BaseEntity {
return Boolean(getTableColumn(this, columnName).isDefaultValueColumn);
}
public isEntityColumn(columnName: string): boolean {
const tableColumnType: TableColumnMetadata = getTableColumn(this, columnName);
return Boolean(tableColumnType.type === TableColumnType.Entity || tableColumnType.type === TableColumnType.EntityArray);
}
public toJSON(): JSONObject {
const json: JSONObject = this.toJSONObject();
return JSONFunctions.serialize(json);

View File

@ -34,6 +34,7 @@ export default class EmailVerificationToken extends BaseModel {
manyToOneRelationColumn: 'userId',
required: true,
type: TableColumnType.Entity,
modelType: User
})
@ManyToOne(
(_type: string) => {

View File

@ -48,6 +48,7 @@ export default class Label extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'projectId',
type: TableColumnType.Entity,
modelType: Project
})
@ManyToOne(
(_type: string) => {
@ -146,6 +147,7 @@ export default class Label extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'createdByUserId',
type: TableColumnType.Entity,
modelType: Project
})
@ManyToOne(
(_type: string) => {

View File

@ -143,7 +143,7 @@ export default class Probe extends BaseModel {
read: [Permission.ProjectMember, Permission.Public],
update: [],
})
@TableColumn({ type: TableColumnType.Entity, required: false })
@TableColumn({ type: TableColumnType.Entity, required: false, modelType: Project })
@ManyToOne(
(_type: string) => {
return Project;
@ -177,7 +177,7 @@ export default class Probe extends BaseModel {
read: [],
update: [],
})
@TableColumn({ type: TableColumnType.Entity })
@TableColumn({ type: TableColumnType.Entity, modelType: User })
@ManyToOne(
(_type: string) => {
return User;

View File

@ -119,6 +119,7 @@ export default class Model extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'createdByUserId',
type: TableColumnType.Entity,
modelType: User
})
@ManyToOne(
(_type: string) => {

View File

@ -12,7 +12,7 @@ import TableColumnType from '../Types/Database/TableColumnType';
name: 'ProjectAPIKey',
})
export default class ProjectAPIKey extends BaseModel {
@TableColumn({ type: TableColumnType.Entity })
@TableColumn({ type: TableColumnType.Entity, modelType: Project })
@ManyToOne(
(_type: string) => {
return Project;
@ -36,7 +36,7 @@ export default class ProjectAPIKey extends BaseModel {
})
public projectId?: ObjectID;
@TableColumn({ type: TableColumnType.Entity })
@TableColumn({ type: TableColumnType.Entity, modelType: User })
@ManyToOne(
(_type: string) => {
return User;
@ -60,7 +60,7 @@ export default class ProjectAPIKey extends BaseModel {
})
public deletedByUserId?: ObjectID;
@TableColumn({ type: TableColumnType.Entity })
@TableColumn({ type: TableColumnType.Entity, modelType: User })
@ManyToOne(
(_type: string) => {
return User;

View File

@ -60,6 +60,7 @@ export default class Team extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'projectId',
type: TableColumnType.Entity,
modelType: Project
})
@ManyToOne(
(_type: string) => {
@ -159,6 +160,7 @@ export default class Team extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'createdByUserId',
type: TableColumnType.Entity,
modelType: Project
})
@ManyToOne(
(_type: string) => {

View File

@ -63,6 +63,7 @@ export default class TeamMember extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'teamId',
type: TableColumnType.Entity,
modelType: Team
})
@ManyToOne(
(_type: string) => {
@ -116,6 +117,7 @@ export default class TeamMember extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'projectId',
type: TableColumnType.Entity,
modelType: Project
})
@ManyToOne(
(_type: string) => {
@ -169,6 +171,7 @@ export default class TeamMember extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'userId',
type: TableColumnType.Entity,
modelType: User
})
@ManyToOne(
(_type: string) => {
@ -213,6 +216,7 @@ export default class TeamMember extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'createdByUserId',
type: TableColumnType.Entity,
modelType: User
})
@ManyToOne(
(_type: string) => {

View File

@ -71,6 +71,7 @@ export default class TeamPermission extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'teamId',
type: TableColumnType.Entity,
modelType: Team
})
@ManyToOne(
(_type: string) => {
@ -102,6 +103,7 @@ export default class TeamPermission extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'projectId',
type: TableColumnType.Entity,
modelType: Project
})
@ManyToOne(
(_type: string) => {
@ -173,6 +175,7 @@ export default class TeamPermission extends BaseModel {
@TableColumn({
manyToOneRelationColumn: 'createdByUserId',
type: TableColumnType.Entity,
modelType: User
})
@ManyToOne(
(_type: string) => {

View File

@ -17,6 +17,7 @@ export interface TableColumnMetadata {
encrypted?: boolean;
manyToOneRelationColumn?: string;
type: TableColumnType;
modelType?: { new (): BaseModel }
}
export default (props: TableColumnMetadata): ReflectionMetadataType => {

View File

@ -24,6 +24,7 @@ enum ColumnType {
Number,
BigNumber,
Entity,
EntityArray
}
export default ColumnType;

View File

@ -46,6 +46,9 @@ import QueryHelper from '../Types/Database/QueryHelper';
import { getUniqueColumnsBy } from 'Common/Types/Database/UniqueColumnBy';
import Search from 'Common/Types/Database/Search';
import Typeof from 'Common/Types/Typeof';
import TableColumns from 'Common/Types/Database/Columns';
import TableColumnType from 'Common/Types/Database/TableColumnType';
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
enum DatabaseRequestType {
Create = 'create',
@ -302,6 +305,45 @@ class DatabaseService<TBaseModel extends BaseModel> {
return createBy;
}
private serializeCreate(data: TBaseModel | QueryDeepPartialEntity<TBaseModel>): TBaseModel | QueryDeepPartialEntity<TBaseModel> {
const columns: TableColumns = this.model.getTableColumns();
for (const columnName of columns.columns) {
if (this.model.isEntityColumn(columnName)) {
const tableColumnMetadata = this.model.getTableColumnMetadata(columnName);
if (data && tableColumnMetadata.modelType && (data as any)[columnName] && tableColumnMetadata.type === TableColumnType.Entity && (typeof (data as any)[columnName] === "string" || (data as any)[columnName] instanceof ObjectID)) {
(data as any)[columnName] = new tableColumnMetadata.modelType();
(data as any)[columnName]._id = (data as any)[columnName].toString();
}
if (data
&& Array.isArray((data as any)[columnName])
&& (data as any)[columnName].length > 0
&& tableColumnMetadata.modelType
&& (data as any)[columnName]
&& tableColumnMetadata.type === TableColumnType.EntityArray
) {
const itemsArray: Array<BaseModel> = [];
for (const item of (data as any)[columnName]) {
if (typeof (data as any)[columnName] === "string" || (data as any)[columnName] instanceof ObjectID) {
const basemodelItem = new tableColumnMetadata.modelType();
basemodelItem._id = (data as any)[columnName].toString();
itemsArray.push(basemodelItem);
} else {
itemsArray.push(item);
}
}
(data as any)[columnName] = itemsArray;
}
}
}
return data;
}
public async create(createBy: CreateBy<TBaseModel>): Promise<TBaseModel> {
let _createdBy: CreateBy<TBaseModel> = await this._onBeforeCreate(
createBy
@ -329,6 +371,10 @@ class DatabaseService<TBaseModel extends BaseModel> {
// check uniqueColumns by:
createBy = await this.checkUniqueColumnBy(createBy);
// serialize.
createBy.data = (await this.serializeCreate(createBy.data) as TBaseModel);
try {
createBy.data = await this.getRepository().save(createBy.data);
await this.onCreateSuccess(createBy);
@ -1027,11 +1073,12 @@ class DatabaseService<TBaseModel extends BaseModel> {
beforeUpdateBy = this.asUpdateByByPermissions(beforeUpdateBy);
debugger;
const numberOfDocsAffected: number =
(
await this.getRepository().update(
beforeUpdateBy.query as any,
beforeUpdateBy.data
this.serializeQuery(beforeUpdateBy.query as any) as any,
this.serializeCreate(beforeUpdateBy.data) as QueryDeepPartialEntity<TBaseModel>
)
).affected || 0;

View File

@ -6,7 +6,7 @@ import React, {
useState,
} from 'react';
type DropdownValue = string | number;
export type DropdownValue = string | number;
export interface DropdownOption {
value: DropdownValue;
@ -19,7 +19,7 @@ export interface ComponentProps {
onClick?: undefined | (() => void);
placeholder?: undefined | string;
className?: undefined | string;
onChange?: undefined | ((value: DropdownValue) => void);
onChange?: undefined | ((value: DropdownValue | Array<DropdownValue>) => void);
value?: DropdownOption | undefined;
onFocus?: (() => void) | undefined;
onBlur?: (() => void) | undefined;
@ -29,8 +29,8 @@ export interface ComponentProps {
const Dropdown: FunctionComponent<ComponentProps> = (
props: ComponentProps
): ReactElement => {
const [value, setValue] = useState<DropdownOption | null>(null);
const [selectedValue, setSelectedValue] = useState<DropdownOption | null>(null);
const [value, setValue] = useState<DropdownOption | Array<DropdownOption> | null>(null);
const [selectedValue, setSelectedValue] = useState<DropdownOption | Array<DropdownOption> | null>(null);
useEffect(() => {
if (props.initialValue) {
@ -57,17 +57,36 @@ const Dropdown: FunctionComponent<ComponentProps> = (
useEffect(() => {
const selectedValues: Array<DropdownOption> = props.options.filter(
(item: DropdownOption) => {
return item.value === value?.value;
if (Array.isArray(value)) {
return value.map((v) => {
return v.value
}).includes(item.value);
} else {
return item.value === value?.value;
}
}
);
let selectedValue: DropdownOption | null = null;
if (selectedValues.length > 0) {
if (selectedValues.length > 0 && !props.isMultiSelect) {
selectedValue = selectedValues[0] || null;
}
setSelectedValue(selectedValue);
setSelectedValue(props.isMultiSelect ? selectedValues : selectedValue);
if (value) {
if (Array.isArray(value)) {
props.onChange &&
props.onChange((value as Array<DropdownOption>).map((i: DropdownOption) => {
return i.value;
}));
} else {
props.onChange &&
props.onChange((value as DropdownOption).value);
}
}
}, [value]);
@ -92,10 +111,15 @@ const Dropdown: FunctionComponent<ComponentProps> = (
options={props.options as any}
onChange={(option: any | null) => {
if (option) {
const value: DropdownOption = (option as DropdownOption)
setValue(value);
props.onChange &&
props.onChange((option as DropdownOption).value);
if (props.isMultiSelect) {
const value: Array<DropdownOption> = (option as Array<DropdownOption>)
setValue(value);
} else {
const value: DropdownOption = (option as DropdownOption)
setValue(value);
}
}
}}
/>

View File

@ -22,7 +22,7 @@ import Alert, { AlertType } from '../Alerts/Alert';
import ColorPicker from './Fields/ColorPicker';
import Color from 'Common/Types/Color';
import TextArea from './Fields/TextArea';
import Dropdown from '../Dropdown/Dropdown';
import Dropdown, { DropdownValue } from '../Dropdown/Dropdown';
import OneUptimeDate from 'Common/Types/Date';
export const DefaultValidateFunction: Function = (
@ -155,7 +155,7 @@ const BasicForm: Function = <T extends Object>(
return (
<Dropdown
onChange={async (
value: string | number
value: DropdownValue | Array<DropdownValue>
) => {
await form.setFieldValue(
fieldName,