From 310c1cea84bb1be4a242dd2d81ea77fe75599372 Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 22 Jun 2025 13:14:00 +0300 Subject: [PATCH 1/7] record preview, related records: fix links when primary key is a foreign key --- .../db-table-row-view.component.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts index f2338a8c8..713bdc676 100644 --- a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts +++ b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts @@ -146,16 +146,20 @@ export class DbTableRowViewComponent implements OnInit, OnDestroy { const tableRecords = { rows: formattedRows, links: res.rows.map(row => { - let params = {}; - Object.keys(res.primaryColumns).forEach((key) => { - params[res.primaryColumns[key].column_name] = row[res.primaryColumns[key].column_name]; - }); - - return params; + return res.primaryColumns.reduce((keys, column) => { + if (res.foreignKeys.map(foreignKey => foreignKey.column_name).includes(column.column_name)) { + const referencedColumnNameOfForeignKey = foreignKeyMap[column.column_name]; + keys[column.column_name] = row[column.column_name][referencedColumnNameOfForeignKey]; + } else { + keys[column.column_name] = row[column.column_name]; + } + return keys; + }, {}) }), identityColumn, fieldsOrder } + this.referencedRecords[table.table_name] = tableRecords; }); }); From 12a365d9aa3d990231d41afefdad3ec27529e6a0 Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 22 Jun 2025 13:27:57 +0300 Subject: [PATCH 2/7] edit row, related records: delete legacy links as now related records are buttons --- .../db-table-row-edit/db-table-row-edit.component.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts index 6144653cc..07a075bd2 100644 --- a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts +++ b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts @@ -368,13 +368,6 @@ export class DbTableRowEditComponent implements OnInit { const tableRecords = { rawRows: res.rows, formattedRows, - links: res.rows.map(row => { - let params = {}; - Object.keys(res.primaryColumns).forEach((key) => { - params[res.primaryColumns[key].column_name] = row[res.primaryColumns[key].column_name]; - }); - return params; - }), identityColumn, fieldsOrder, foreignKeys: res.foreignKeys From 6ac33e6dc66976f9b741544128a39485e9dc8d3b Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 22 Jun 2025 13:41:55 +0300 Subject: [PATCH 3/7] record preview: fix link to a record in case when primary key is a foreign key --- .../db-table-row-view.component.html | 2 +- .../db-table-row-view.component.ts | 27 ++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html index ca6cfeba4..28a656b19 100644 --- a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html +++ b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html @@ -12,7 +12,7 @@

Preview

create diff --git a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts index 713bdc676..b094dc115 100644 --- a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts +++ b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts @@ -201,12 +201,33 @@ export class DbTableRowViewComponent implements OnInit, OnDestroy { return this.selectedRow.widgetsList.includes(columnName); } - getDedicatedPageLink() { + getDedicatedPageLinkParams() { if (this.selectedRow) { - const params = new URLSearchParams(); + const params = {}; for (const key in this.selectedRow.primaryKeys) { if (this.selectedRow.primaryKeys.hasOwnProperty(key)) { - params.append(key, this.selectedRow.primaryKeys[key]); + if (this.selectedRow.foreignKeysList.includes(key)) { + const referencedColumnName = this.selectedRow.foreignKeys[key].referenced_column_name; + params[key] = this.selectedRow.record[key][referencedColumnName]; + } + else { + params[key] = this.selectedRow.primaryKeys[key]; + } + + } + } + return params; + }; + return {}; + } + + getDedicatedPageLink() { + if (this.selectedRow) { + const paramsObj = this.getDedicatedPageLinkParams(); + const params = new URLSearchParams(); + for (const key in paramsObj) { + if (paramsObj.hasOwnProperty(key)) { + params.set(key, paramsObj[key]); } } return `${location.origin}${this.selectedRow.link}?${params.toString()}`; From 6527b30d471ac31cac8f369f77eedf2ee48fe4fe Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 22 Jun 2025 13:49:55 +0300 Subject: [PATCH 4/7] record view: close record view on redirects to other pages --- .../db-table-row-view/db-table-row-view.component.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html index 28a656b19..a820188e6 100644 --- a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html +++ b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html @@ -39,13 +39,15 @@

Preview

Absent
+ matTooltip="Set up records view" + (click)="handleClose()"> settings + matTooltip="Open records in table view" + (click)="handleClose()"> open_in_new @@ -82,7 +84,8 @@

Preview

+ class="row-preview-sidebar__field-value row-preview-sidebar__field-value_foreign-key" + (click)="handleClose()"> {{getForeignKeyValue(column.title)}} edit From 73fd5e0939fcc9d3735df17dde2dccb46183b9c3 Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 22 Jun 2025 14:27:07 +0300 Subject: [PATCH 5/7] edit page, related records: human readable names for record field names --- .../db-table-row-edit.component.css | 12 ++++++ .../db-table-row-edit.component.html | 8 ++-- .../db-table-row-edit.component.ts | 41 ++++++++++++++++--- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.css b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.css index 052e0b692..a3e072d8d 100644 --- a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.css +++ b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.css @@ -132,6 +132,18 @@ padding: 0 8px 16px; } +.related-record__fields { + margin-left: -4px; +} + +.related-record__field { + margin-left: 8px; +} + +.related-record__fieldName { + margin-right: 4px; +} + .widget { display: grid; grid-template-columns: 0 1fr 36px; diff --git a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.html b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.html index d63127e60..f53dc6a1c 100644 --- a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.html +++ b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.html @@ -91,10 +91,10 @@

{{ referencedRecords[referencedTable.table_name].formattedRows[i][referencedRecords[referencedTable.table_name].identityColumn] }} - - - {{field_name}}: - {{ referencedRecords[referencedTable.table_name].formattedRows[i][field_name] }} + + + {{field.displayName}}: + {{ referencedRecords[referencedTable.table_name].formattedRows[i][field.fieldName] }}; diff --git a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts index 07a075bd2..8432e7171 100644 --- a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts +++ b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts @@ -41,7 +41,7 @@ import { TablesService } from 'src/app/services/tables.service'; import { Title } from '@angular/platform-browser'; import { formatFieldValue } from 'src/app/lib/format-field-value'; import { getTableTypes } from 'src/app/lib/setup-table-row-structure'; -import { normalizeTableName } from '../../lib/normalize'; +import { normalizeTableName, normalizeFieldName } from 'src/app/lib/normalize'; @Component({ selector: 'app-db-table-row-edit', @@ -346,23 +346,52 @@ export class DbTableRowEditComponent implements OnInit { if (res.identity_column && res.list_fields.length) { identityColumn = res.identity_column; - fieldsOrder = res.list_fields.filter((field: string) => field !== res.identity_column).slice(0, 3); + fieldsOrder = res.list_fields + .filter((field: string) => field !== res.identity_column) + .slice(0, 3) + .map((field: string) => { + return { + fieldName: field, + displayName: this.relatedRecordsProperties[table.table_name].widgets[field]?.name || normalizeFieldName(field), + }; + }); } if (res.identity_column && !res.list_fields.length) { identityColumn = res.identity_column; - fieldsOrder = res.structure.filter((field: TableField) => field.column_name !== res.identity_column).map((field: TableField) => field.column_name).slice(0, 3); + fieldsOrder = res.structure + .filter((field: TableField) => field.column_name !== res.identity_column) + .slice(0, 3) + .map((field: TableField) => { + return { + fieldName: field.column_name, + displayName: this.relatedRecordsProperties[table.table_name].widgets[field.column_name]?.name || normalizeFieldName(field.column_name), + } + }) } if (!res.identity_column && res.list_fields.length) { identityColumn = res.list_fields[0]; - fieldsOrder = res.list_fields.slice(1, 4); + fieldsOrder = res.list_fields + .slice(1, 4) + .map((field: string) => { + return { + fieldName: field, + displayName: this.relatedRecordsProperties[table.table_name].widgets[field]?.name || normalizeFieldName(field), + }; + }); } if (!res.identity_column && !res.list_fields.length) { identityColumn = res.structure[0].column_name; - console.log(identityColumn); - fieldsOrder = res.structure.slice(1, 4).map((field: TableField) => field.column_name); + fieldsOrder = res.structure + .slice(1, 4) + .map((field: TableField) => { + return { + fieldName: field.column_name, + displayName: this.relatedRecordsProperties[table.table_name].widgets[field.column_name]?.name || normalizeFieldName(field.column_name), + } + }) } const tableRecords = { From a89f74693fc02ebb7d0857924d40f77dcaf934e1 Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 22 Jun 2025 15:31:11 +0300 Subject: [PATCH 6/7] related records: show field name if it is not identity field --- .../db-table-row-view.component.html | 9 +++++- .../db-table-row-view.component.ts | 28 +++++++++++++++++-- .../db-table-row-edit.component.html | 5 +++- .../db-table-row-edit.component.ts | 25 ++++++++++++++--- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html index a820188e6..685e965f4 100644 --- a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html +++ b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html @@ -58,7 +58,14 @@

Preview

[routerLink]="['/dashboard', selectedRow.connectionID, referencedTable.table_name, 'entry']" [queryParams]="referencedRecords[referencedTable.table_name]?.links[i]" (click)="handleClose()"> - {{row[referencedRecords[referencedTable.table_name].identityColumn]}} + + + + {{referencedRecords[referencedTable.table_name].identityColumn.displayName}}:  + + {{ row[referencedRecords[referencedTable.table_name].identityColumn.name] }} + + {{field_name}}: diff --git a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts index b094dc115..45f417307 100644 --- a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts +++ b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts @@ -107,6 +107,11 @@ export class DbTableRowViewComponent implements OnInit, OnDestroy { foreignKeyMap[fk.column_name] = fk.referenced_column_name; } + const tableWidgetsNameMap = Object.keys(res.widgets).reduce((acc, key) => { + acc[key] = res.widgets[key].name; + return acc; + }, {}); + // Format each row const formattedRows = res.rows.map(row => { const formattedRow = {}; @@ -124,21 +129,38 @@ export class DbTableRowViewComponent implements OnInit, OnDestroy { if (res.identity_column && res.list_fields.length) { identityColumn = res.identity_column; + identityColumn = { + isSet: true, + name: res.identity_column, + displayName: tableWidgetsNameMap[res.identity_column] || normalizeFieldName(res.identity_column) + }; fieldsOrder = res.list_fields.filter((field: string) => field !== res.identity_column).slice(0, 3); } if (res.identity_column && !res.list_fields.length) { - identityColumn = res.identity_column; + identityColumn = { + isSet: true, + name: res.identity_column, + displayName: tableWidgetsNameMap[res.identity_column] || normalizeFieldName(res.identity_column) + }; fieldsOrder = res.structure.filter((field: TableField) => field.column_name !== res.identity_column).map((field: TableField) => field.column_name).slice(0, 3); } if (!res.identity_column && res.list_fields.length) { - identityColumn = res.list_fields[0]; + identityColumn = { + isSet: false, + name: res.list_fields[0], + displayName: tableWidgetsNameMap[res.list_fields[0]] || normalizeFieldName(res.list_fields[0]) + }; fieldsOrder = res.list_fields.slice(1, 4); } if (!res.identity_column && !res.list_fields.length) { - identityColumn = res.structure[0].column_name; + identityColumn = { + isSet: false, + name: res.structure[0].column_name, + displayName: tableWidgetsNameMap[res.structure[0].column_name] || normalizeFieldName(res.structure[0].column_name) + }; console.log(identityColumn); fieldsOrder = res.structure.slice(1, 4).map((field: TableField) => field.column_name); } diff --git a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.html b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.html index f53dc6a1c..1123b6281 100644 --- a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.html +++ b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.html @@ -89,7 +89,10 @@

- {{ referencedRecords[referencedTable.table_name].formattedRows[i][referencedRecords[referencedTable.table_name].identityColumn] }} + + {{referencedRecords[referencedTable.table_name].identityColumn.displayName}}:  + + {{ referencedRecords[referencedTable.table_name].formattedRows[i][referencedRecords[referencedTable.table_name].identityColumn.name] }} diff --git a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts index 8432e7171..cc50c48a1 100644 --- a/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts +++ b/frontend/src/app/components/db-table-row-edit/db-table-row-edit.component.ts @@ -42,6 +42,7 @@ import { Title } from '@angular/platform-browser'; import { formatFieldValue } from 'src/app/lib/format-field-value'; import { getTableTypes } from 'src/app/lib/setup-table-row-structure'; import { normalizeTableName, normalizeFieldName } from 'src/app/lib/normalize'; +import { isSet } from 'lodash'; @Component({ selector: 'app-db-table-row-edit', @@ -345,7 +346,11 @@ export class DbTableRowEditComponent implements OnInit { }) if (res.identity_column && res.list_fields.length) { - identityColumn = res.identity_column; + identityColumn = { + isSet: true, + name: res.identity_column, + displayName: this.relatedRecordsProperties[table.table_name].widgets[res.identity_column]?.name || normalizeFieldName(res.identity_column) + }; fieldsOrder = res.list_fields .filter((field: string) => field !== res.identity_column) .slice(0, 3) @@ -358,7 +363,11 @@ export class DbTableRowEditComponent implements OnInit { } if (res.identity_column && !res.list_fields.length) { - identityColumn = res.identity_column; + identityColumn = { + isSet: true, + name: res.identity_column, + displayName: this.relatedRecordsProperties[table.table_name].widgets[res.identity_column]?.name || normalizeFieldName(res.identity_column) + }; fieldsOrder = res.structure .filter((field: TableField) => field.column_name !== res.identity_column) .slice(0, 3) @@ -371,7 +380,11 @@ export class DbTableRowEditComponent implements OnInit { } if (!res.identity_column && res.list_fields.length) { - identityColumn = res.list_fields[0]; + identityColumn = { + isSet: false, + name: res.list_fields[0], + displayName: this.relatedRecordsProperties[table.table_name].widgets[res.list_fields[0]]?.name || normalizeFieldName(res.list_fields[0]) + }; fieldsOrder = res.list_fields .slice(1, 4) .map((field: string) => { @@ -383,7 +396,11 @@ export class DbTableRowEditComponent implements OnInit { } if (!res.identity_column && !res.list_fields.length) { - identityColumn = res.structure[0].column_name; + identityColumn = { + isSet: false, + name: res.structure[0].column_name, + displayName: this.relatedRecordsProperties[table.table_name].widgets[res.structure[0].column_name]?.name || normalizeFieldName(res.structure[0].column_name) + }; fieldsOrder = res.structure .slice(1, 4) .map((field: TableField) => { From 9b6c7e33ad111633e758b182bfcf48a8afdc1021 Mon Sep 17 00:00:00 2001 From: Lyubov Voloshko Date: Sun, 22 Jun 2025 15:43:52 +0300 Subject: [PATCH 7/7] record preview, related recors: normalized and names from widgets for fields names --- .../db-table-row-view.component.html | 10 ++-- .../db-table-row-view.component.ts | 47 +++++++++++++++---- frontend/src/app/consts/acronyms.ts | 2 - 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html index 685e965f4..b8e7f95f3 100644 --- a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html +++ b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.html @@ -59,17 +59,17 @@

Preview

[queryParams]="referencedRecords[referencedTable.table_name]?.links[i]" (click)="handleClose()"> - + {{referencedRecords[referencedTable.table_name].identityColumn.displayName}}:  - {{ row[referencedRecords[referencedTable.table_name].identityColumn.name] }} + {{ row[referencedRecords[referencedTable.table_name].identityColumn.fieldName] }} - - {{field_name}}: - {{ row[field_name]}} + + {{field.displayName}}: + {{ row[field.fieldName] || '—' }}; diff --git a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts index 45f417307..f574953e9 100644 --- a/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts +++ b/frontend/src/app/components/dashboard/db-table-row-view/db-table-row-view.component.ts @@ -128,41 +128,70 @@ export class DbTableRowViewComponent implements OnInit, OnDestroy { }) if (res.identity_column && res.list_fields.length) { - identityColumn = res.identity_column; identityColumn = { isSet: true, - name: res.identity_column, + fieldName: res.identity_column, displayName: tableWidgetsNameMap[res.identity_column] || normalizeFieldName(res.identity_column) }; - fieldsOrder = res.list_fields.filter((field: string) => field !== res.identity_column).slice(0, 3); + fieldsOrder = res.list_fields + .filter((field: string) => field !== res.identity_column) + .slice(0, 3) + .map((field: string) => { + return { + fieldName: field, + displayName: tableWidgetsNameMap[field] || normalizeFieldName(field) + }; + }); } if (res.identity_column && !res.list_fields.length) { identityColumn = { isSet: true, - name: res.identity_column, + fieldName: res.identity_column, displayName: tableWidgetsNameMap[res.identity_column] || normalizeFieldName(res.identity_column) }; - fieldsOrder = res.structure.filter((field: TableField) => field.column_name !== res.identity_column).map((field: TableField) => field.column_name).slice(0, 3); + fieldsOrder = res.structure + .filter((field: TableField) => field.column_name !== res.identity_column) + .slice(0, 3) + .map((field: TableField) => { + return { + fieldName: field.column_name, + displayName: tableWidgetsNameMap[field.column_name] || normalizeFieldName(field.column_name) + }; + }); } if (!res.identity_column && res.list_fields.length) { identityColumn = { isSet: false, - name: res.list_fields[0], + fieldName: res.list_fields[0], displayName: tableWidgetsNameMap[res.list_fields[0]] || normalizeFieldName(res.list_fields[0]) }; - fieldsOrder = res.list_fields.slice(1, 4); + fieldsOrder = res.list_fields + .slice(1, 4) + .map((field: string) => { + return { + fieldName: field, + displayName: tableWidgetsNameMap[field] || normalizeFieldName(field) + }; + }); } if (!res.identity_column && !res.list_fields.length) { identityColumn = { isSet: false, - name: res.structure[0].column_name, + fieldName: res.structure[0].column_name, displayName: tableWidgetsNameMap[res.structure[0].column_name] || normalizeFieldName(res.structure[0].column_name) }; console.log(identityColumn); - fieldsOrder = res.structure.slice(1, 4).map((field: TableField) => field.column_name); + fieldsOrder = res.structure + .slice(1, 4) + .map((field: TableField) => { + return { + fieldName: field.column_name, + displayName: tableWidgetsNameMap[field.column_name] || normalizeFieldName(field.column_name) + }; + }); } const tableRecords = { diff --git a/frontend/src/app/consts/acronyms.ts b/frontend/src/app/consts/acronyms.ts index 1ef21b423..b4e113a5a 100644 --- a/frontend/src/app/consts/acronyms.ts +++ b/frontend/src/app/consts/acronyms.ts @@ -4232,7 +4232,6 @@ export default [ 'PEN', 'PEO', 'PEPFAR', -'PER', 'perl', 'PES', 'PEST', @@ -5069,7 +5068,6 @@ export default [ 'TNO', 'TNT', 'to', -'TO', 'TOA', 'TOAD', 'TOBS',