From e2c46487cd7ada9dd7419dfacadc404c8b1a75e8 Mon Sep 17 00:00:00 2001 From: LeticiadelaOsa Date: Fri, 12 Jan 2024 21:07:30 +0100 Subject: [PATCH 1/4] Add selects to edit-relation --- .../components/field-tree.business.tsx | 6 +-- .../components/field-tree.component.tsx | 6 +-- .../table-pk-picker.component.tsx | 8 ++-- .../table-pk-picker/table-pk-picker.model.ts | 4 +- .../edit-realtion/edit-relation.business.ts | 42 ++++++++++++++++++- .../edit-realtion/edit-relation.component.tsx | 35 +++++++++++++++- src/pods/edit-realtion/edit-relation.pod.tsx | 15 ++++++- 7 files changed, 99 insertions(+), 17 deletions(-) diff --git a/src/common/components/table-pk-picker/components/field-tree.business.tsx b/src/common/components/table-pk-picker/components/field-tree.business.tsx index 64ae4f06..6a87d472 100644 --- a/src/common/components/table-pk-picker/components/field-tree.business.tsx +++ b/src/common/components/table-pk-picker/components/field-tree.business.tsx @@ -1,12 +1,12 @@ import { Tick } from '../../icons/tick-icon.component'; -import { OptionVm } from '../table-pk-picker.model'; +import { PkOptionVm } from '../table-pk-picker.model'; import classes from '../table-pk-picker.component.module.css'; export const generateOptions = ( name: string, - options: OptionVm[], + options: PkOptionVm[], parentPath: string, - handleSelectPKField: (option: OptionVm, parentPath: string) => void, + handleSelectPKField: (option: PkOptionVm, parentPath: string) => void, selectedPKField?: string ): JSX.Element[] => { return options.map(option => ( diff --git a/src/common/components/table-pk-picker/components/field-tree.component.tsx b/src/common/components/table-pk-picker/components/field-tree.component.tsx index 71844c10..627b18d9 100644 --- a/src/common/components/table-pk-picker/components/field-tree.component.tsx +++ b/src/common/components/table-pk-picker/components/field-tree.component.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { OptionVm } from '../table-pk-picker.model'; +import { PkOptionVm } from '../table-pk-picker.model'; import classes from '../table-pk-picker.component.module.css'; import { generateOptions } from './field-tree.business'; interface Props { name: string; - options: OptionVm[]; + options: PkOptionVm[]; optionsListVisible: boolean; - handleOptionClick: (option: OptionVm, parentPath: string) => void; + handleOptionClick: (option: PkOptionVm, parentPath: string) => void; selectedPKField?: string; } diff --git a/src/common/components/table-pk-picker/table-pk-picker.component.tsx b/src/common/components/table-pk-picker/table-pk-picker.component.tsx index e6ca78f7..451a8950 100644 --- a/src/common/components/table-pk-picker/table-pk-picker.component.tsx +++ b/src/common/components/table-pk-picker/table-pk-picker.component.tsx @@ -2,17 +2,17 @@ import React from 'react'; import classes from './table-pk-picker.component.module.css'; import { FieldTree } from './components/field-tree.component'; import { ExpandDown } from '../icons/expand-down-icon.component'; -import { OptionVm } from './table-pk-picker.model'; +import { PkOptionVm } from './table-pk-picker.model'; import { GUID } from '@/core/model'; import { SELECT_AN_PK_OPTION } from './table-pk-picker.const'; interface Props { name: string; - options: OptionVm[]; + options: PkOptionVm[]; label?: string; selectedKeyFieldId?: GUID; selectTitle?: string; - onKeySelected: (field: OptionVm) => void; + onKeySelected: (field: PkOptionVm) => void; } export const TablePkPicker: React.FC = props => { @@ -30,7 +30,7 @@ export const TablePkPicker: React.FC = props => { const [currentSelectedKeyFieldId, setCurrentSelectedKeyFieldId] = React.useState(selectedKeyFieldId); - const handleOptionClick = (option: OptionVm, parentPath: string) => { + const handleOptionClick = (option: PkOptionVm, parentPath: string) => { setCurrentSelectedKeyFieldId(option.id); const currentPath = parentPath ? `${parentPath} > ${option.label}` diff --git a/src/common/components/table-pk-picker/table-pk-picker.model.ts b/src/common/components/table-pk-picker/table-pk-picker.model.ts index e452d684..b85c621b 100644 --- a/src/common/components/table-pk-picker/table-pk-picker.model.ts +++ b/src/common/components/table-pk-picker/table-pk-picker.model.ts @@ -1,7 +1,7 @@ import { GUID } from '@/core/model'; -export interface OptionVm { +export interface PkOptionVm { id: GUID; label: string; - children?: OptionVm[]; + children?: PkOptionVm[]; } diff --git a/src/pods/edit-realtion/edit-relation.business.ts b/src/pods/edit-realtion/edit-relation.business.ts index eb614dac..5b6c0974 100644 --- a/src/pods/edit-realtion/edit-relation.business.ts +++ b/src/pods/edit-realtion/edit-relation.business.ts @@ -1,5 +1,10 @@ -import { DropdownOptionVm } from '@/common/components'; -import { DatabaseSchemaVm } from '@/core/providers/canvas-schema'; +import { DropdownOptionVm, PkOptionVm } from '@/common/components'; +import { GUID } from '@/core/model'; +import { + DatabaseSchemaVm, + FieldVm, + TableVm, +} from '@/core/providers/canvas-schema'; export const mapRelationsTipeToDropdonwVm = (): DropdownOptionVm[] => [ { id: '1', label: '1:1' }, @@ -16,3 +21,36 @@ export const mapTablesToDropdonwVm = ( canvasSchema.tables.map( (table): DropdownOptionVm => ({ id: table.id, label: table.tableName }) ); + +const returnTablefromCanvasShema = ( + id: GUID, + canvasSchema: DatabaseSchemaVm +): TableVm => { + const table = canvasSchema.tables.find(table => table.id === id); + if (!table) { + throw Error(`Table with id ${id} does not exist`); + } + return table; +}; + +const returnOptionsFromTable = (fields: FieldVm[]): PkOptionVm[] => + fields.map((field): PkOptionVm => { + if (field.children && field.children.length > 0) { + return { + id: field.id, + label: field.name, + children: returnOptionsFromTable(field.children), + }; + } + return { id: field.id, label: field.name }; + }); + +export const mapTablesFieldsToPkOptionVm = ( + id: GUID, + canvasSchema: DatabaseSchemaVm +): PkOptionVm[] => { + const table = returnTablefromCanvasShema(id, canvasSchema); + const options = returnOptionsFromTable(table.fields); + + return options; +}; diff --git a/src/pods/edit-realtion/edit-relation.component.tsx b/src/pods/edit-realtion/edit-relation.component.tsx index 6dfc029f..30b3f143 100644 --- a/src/pods/edit-realtion/edit-relation.component.tsx +++ b/src/pods/edit-realtion/edit-relation.component.tsx @@ -1,17 +1,26 @@ import React from 'react'; import { Dropdown, DropdownOptionVm } from '@/common/components/dropdown'; import { RelationType, RelationVm } from '@/core/providers/canvas-schema'; +import { PkOptionVm, TablePkPicker } from '@/common/components'; interface Props { relationsTypeOptions: DropdownOptionVm[]; tablesNameOptions: DropdownOptionVm[]; + fieldsTableOrigin: PkOptionVm[]; + fieldsTableDestination: PkOptionVm[]; relation: RelationVm; setRelation: (relation: RelationVm) => void; } export const EditRelationComponent: React.FC = props => { - const { relationsTypeOptions, tablesNameOptions, relation, setRelation } = - props; + const { + relationsTypeOptions, + tablesNameOptions, + relation, + setRelation, + fieldsTableDestination, + fieldsTableOrigin, + } = props; return ( <> @@ -33,6 +42,17 @@ export const EditRelationComponent: React.FC = props => { } selectTitle="Select origin table" > + {relation.fromTableId && ( + + setRelation({ ...relation, fromFieldId: field.id }) + } + selectTitle="Select origin field" + > + )} = props => { } selectTitle="Select destination table" > + {relation.toTableId && ( + + setRelation({ ...relation, toFieldId: field.id }) + } + selectTitle="Select destination field" + > + )} ); }; diff --git a/src/pods/edit-realtion/edit-relation.pod.tsx b/src/pods/edit-realtion/edit-relation.pod.tsx index 59d88c5a..20107e94 100644 --- a/src/pods/edit-realtion/edit-relation.pod.tsx +++ b/src/pods/edit-realtion/edit-relation.pod.tsx @@ -1,8 +1,9 @@ import React from 'react'; import { DatabaseSchemaVm, RelationVm } from '@/core/providers/canvas-schema'; -import { DropdownOptionVm } from '@/common/components'; +import { DropdownOptionVm, PkOptionVm } from '@/common/components'; import { mapRelationsTipeToDropdonwVm, + mapTablesFieldsToPkOptionVm, mapTablesToDropdonwVm, } from './edit-relation.business'; import { EditRelationComponent } from './edit-relation.component'; @@ -30,6 +31,16 @@ export const EditRelationPod: React.FC = props => { const tablesNameOptions: DropdownOptionVm[] = mapTablesToDropdonwVm(canvasSchema); + const fieldsTableOrigin: PkOptionVm[] = mapTablesFieldsToPkOptionVm( + relation.fromTableId || '1', + canvasSchema + ); + + const fieldsTableDestination: PkOptionVm[] = mapTablesFieldsToPkOptionVm( + relation.toTableId || '1', + canvasSchema + ); + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); @@ -44,6 +55,8 @@ export const EditRelationPod: React.FC = props => { From 22f3b3c454edf4c789ceffeac9a6d7aee1b803be Mon Sep 17 00:00:00 2001 From: LeticiadelaOsa Date: Mon, 15 Jan 2024 11:09:16 +0100 Subject: [PATCH 2/4] Problem --- src/pods/edit-realtion/edit-relation.business.ts | 7 +++++++ src/pods/edit-realtion/edit-relation.pod.tsx | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/pods/edit-realtion/edit-relation.business.ts b/src/pods/edit-realtion/edit-relation.business.ts index 5b6c0974..cc3763e1 100644 --- a/src/pods/edit-realtion/edit-relation.business.ts +++ b/src/pods/edit-realtion/edit-relation.business.ts @@ -45,10 +45,17 @@ const returnOptionsFromTable = (fields: FieldVm[]): PkOptionVm[] => return { id: field.id, label: field.name }; }); +const emptyFields: FieldVm[] = [ + { id: '', name: '', type: 'string', PK: false }, +]; + export const mapTablesFieldsToPkOptionVm = ( id: GUID, canvasSchema: DatabaseSchemaVm ): PkOptionVm[] => { + if (!id) { + return returnOptionsFromTable(emptyFields); + } const table = returnTablefromCanvasShema(id, canvasSchema); const options = returnOptionsFromTable(table.fields); diff --git a/src/pods/edit-realtion/edit-relation.pod.tsx b/src/pods/edit-realtion/edit-relation.pod.tsx index 20107e94..b5c13ca6 100644 --- a/src/pods/edit-realtion/edit-relation.pod.tsx +++ b/src/pods/edit-realtion/edit-relation.pod.tsx @@ -31,13 +31,14 @@ export const EditRelationPod: React.FC = props => { const tablesNameOptions: DropdownOptionVm[] = mapTablesToDropdonwVm(canvasSchema); + //The problem is that these two functions should below not be called until the other fields are not selected, + // but as I can't do that, I have to initialise the fields with an emptyFields if the id is undefined. const fieldsTableOrigin: PkOptionVm[] = mapTablesFieldsToPkOptionVm( - relation.fromTableId || '1', + relation.fromTableId, canvasSchema ); - const fieldsTableDestination: PkOptionVm[] = mapTablesFieldsToPkOptionVm( - relation.toTableId || '1', + relation.toTableId, canvasSchema ); From 1c46a8e0216f9a5bd3918b0ec23a467a7830e3bc Mon Sep 17 00:00:00 2001 From: LeticiadelaOsa Date: Mon, 15 Jan 2024 17:43:19 +0100 Subject: [PATCH 3/4] delete comments --- src/pods/edit-realtion/edit-relation.pod.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pods/edit-realtion/edit-relation.pod.tsx b/src/pods/edit-realtion/edit-relation.pod.tsx index b5c13ca6..7c6776d1 100644 --- a/src/pods/edit-realtion/edit-relation.pod.tsx +++ b/src/pods/edit-realtion/edit-relation.pod.tsx @@ -31,8 +31,6 @@ export const EditRelationPod: React.FC = props => { const tablesNameOptions: DropdownOptionVm[] = mapTablesToDropdonwVm(canvasSchema); - //The problem is that these two functions should below not be called until the other fields are not selected, - // but as I can't do that, I have to initialise the fields with an emptyFields if the id is undefined. const fieldsTableOrigin: PkOptionVm[] = mapTablesFieldsToPkOptionVm( relation.fromTableId, canvasSchema From a9338e754d68ec7358f4859bb7efc662d8ba676b Mon Sep 17 00:00:00 2001 From: LeticiadelaOsa Date: Mon, 15 Jan 2024 19:46:36 +0100 Subject: [PATCH 4/4] Add TODOS --- .../table-pk-picker/components/field-tree.business.tsx | 3 +++ src/pods/edit-realtion/edit-relation.business.ts | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/common/components/table-pk-picker/components/field-tree.business.tsx b/src/common/components/table-pk-picker/components/field-tree.business.tsx index 6a87d472..cbfbfce3 100644 --- a/src/common/components/table-pk-picker/components/field-tree.business.tsx +++ b/src/common/components/table-pk-picker/components/field-tree.business.tsx @@ -2,6 +2,9 @@ import { Tick } from '../../icons/tick-icon.component'; import { PkOptionVm } from '../table-pk-picker.model'; import classes from '../table-pk-picker.component.module.css'; +// TODO: +// #116 Add unit test support to fieldTreeBusiness +//https://github.com/Lemoncode/mongo-modeler/issues/116 export const generateOptions = ( name: string, options: PkOptionVm[], diff --git a/src/pods/edit-realtion/edit-relation.business.ts b/src/pods/edit-realtion/edit-relation.business.ts index cc3763e1..c556ddd0 100644 --- a/src/pods/edit-realtion/edit-relation.business.ts +++ b/src/pods/edit-realtion/edit-relation.business.ts @@ -13,8 +13,13 @@ export const mapRelationsTipeToDropdonwVm = (): DropdownOptionVm[] => [ ]; // TODO: -// #91 +// #91 Disable toolbar add relation button when there are no relations //https://github.com/Lemoncode/mongo-modeler/issues/91 + +// TODO: +// #118 Add unit tests to edit relation business +//https://github.com/Lemoncode/mongo-modeler/issues/118 + export const mapTablesToDropdonwVm = ( canvasSchema: DatabaseSchemaVm ): DropdownOptionVm[] =>