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..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 @@ -1,12 +1,15 @@ 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'; +// TODO: +// #116 Add unit test support to fieldTreeBusiness +//https://github.com/Lemoncode/mongo-modeler/issues/116 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..c556ddd0 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' }, @@ -8,11 +13,56 @@ 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[] => 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 }; + }); + +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); + + 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..7c6776d1 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,15 @@ export const EditRelationPod: React.FC = props => { const tablesNameOptions: DropdownOptionVm[] = mapTablesToDropdonwVm(canvasSchema); + const fieldsTableOrigin: PkOptionVm[] = mapTablesFieldsToPkOptionVm( + relation.fromTableId, + canvasSchema + ); + const fieldsTableDestination: PkOptionVm[] = mapTablesFieldsToPkOptionVm( + relation.toTableId, + canvasSchema + ); + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); @@ -44,6 +54,8 @@ export const EditRelationPod: React.FC = props => {