Skip to content
Merged

Fixes #1436

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,14 @@
}
}

.table-list-sidenav-container ::ng-deep .mat-drawer-inner-container,
.side-bar_collapsed ::ng-deep .mat-drawer-inner-container {
overflow-y: auto !important;
overflow-x: hidden !important;
}

.table-list-sidenav-container ::ng-deep .mat-drawer:not(.mat-drawer-opened):not(.mat-drawer-animating) .mat-drawer-inner-container {
display: initial;
display: block;

Copilot AI Nov 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The change from display: initial; to display: block; may have unintended side effects. The initial value resets the display property to its default based on the element type, while block explicitly forces block-level display. Verify that this change doesn't break the layout for elements that should naturally be inline or have other display values.

Suggested change
display: block;
display: initial;

Copilot uses AI. Check for mistakes.
}

.mat-list-item {
Expand Down Expand Up @@ -105,6 +111,7 @@
.table-preview {
display: flex;
overflow-x: hidden;
height: calc(100vh - 44px);
}

.table-preview-content {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@

@media (width <= 600px) {
.row-preview-sidebar_open {
width: 0;
position: fixed;
top: 44px;
bottom: 0;
left: 0;
min-height: initial;
max-height: initial;
width: calc(100vw - 24px);
z-index: 2;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@
}
}

.settings-fields__subheading {
margin-top: -4px !important;
margin-bottom: 0 !important;
}

@media (prefers-color-scheme: dark) {
.settings-fields__subheading {
color: rgba(255,255,255,0.64);
}
}

@media (prefers-color-scheme: light) {
.settings-fields__subheading {
color: rgba(0,0,0,0.64);
}
}

.settings-table-display {
display: flex;
align-items: center;
Expand Down Expand Up @@ -94,13 +111,25 @@
top: -12px;
left: 8px;
display: inline-block;
background: #fff;
color: rgba(0, 0, 0, 0.6);
font-size: 0.75em;
padding: 4px;
z-index: 1;
}

@media (prefers-color-scheme: dark) {
.order__title {
background: transparent;
color: rgba(255, 255, 255, 0.6);
}
}

@media (prefers-color-scheme: light) {
.order__title {
background: #fff;
color: rgba(0, 0, 0, 0.6);
}
}

.order-item {
background: var(--mat-expansion-container-background-color);
color: var(--mat-expansion-container-text-color);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ <h2 class="mat-heading-2 settings-fields__heading">Table view</h2>
</mat-form-field>

<h2 class="mat-heading-2" style="margin-bottom: -4px; margin-top: 12px">"Edit row" behavior</h2>
<p class="mat-body-1" style="margin-top: -16px; margin-bottom: 0; color: rgba(0,0,0,0.64)">You can edit a row by clicking on the "pencil" icon on the right.</p>
<p class="mat-body-1 settings-fields__subheading">You can edit a row by clicking on the "pencil" icon on the right.</p>
<mat-form-field appearance="outline">
<mat-label>Searchable foreign key columns</mat-label>
<mat-select multiple
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,3 @@ tr.mat-row:hover {
padding: 8px 0;
width: 100%;
}

.hidden {
display: none;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ <h2 class="mat-h2 table-name">{{ displayName }}</h2>
{{action.title}}
</button>
</ng-container>
<button mat-button *ngIf="tableData && tableData.isExportAllowed"
(click)="exportData()">
Export to CSV
</button>
<button mat-button *ngIf="tableData && tableData.permissions && tableData.permissions.delete && tableData.canDelete"
(click)="handleActions({title: 'Delete rows', type: 'multiple', require_confirmation: true})">
Delete
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -522,4 +522,62 @@ export class DbTableViewComponent implements OnInit {
console.log('table view fiers filterSelected:', $event)
this.applyFilter.emit($event);
}

exportData() {
console.log('export data');
console.log(this.selection.selected);
Comment on lines +527 to +528

Copilot AI Nov 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two console.log statements (lines 527-528) that should be removed before merging to production. Debug logging statements should not be committed to the codebase.

Suggested change
console.log('export data');
console.log(this.selection.selected);

Copilot uses AI. Check for mistakes.

// Helper function to convert value to CSV-safe string
const convertToCSVValue = (value: any): string => {
// Handle null and undefined
if (value === null || value === undefined) {
return '';
}

// Handle nested objects and arrays - convert to JSON string
if (typeof value === 'object') {
try {
// Convert object/array to JSON string
value = JSON.stringify(value);
} catch (e) {
// Handle circular references or other JSON stringify errors
value = '[Object]';
}
}

// Convert to string if not already
const stringValue = String(value);

// Check if value needs to be quoted (contains comma, double quote, or newline)
if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n') || stringValue.includes('\r')) {
// Escape double quotes by doubling them and wrap in quotes
return `"${stringValue.replace(/"/g, '""')}"`;
}

return stringValue;
};

const header = Object.keys(this.selection.selected[0]);
Comment on lines +526 to +560

Copilot AI Nov 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exportData() method doesn't handle the case when selection.selected is empty. If no rows are selected, accessing this.selection.selected[0] at line 560 will throw an error. Consider adding a guard condition at the beginning of the method to check if any rows are selected before proceeding with the export.

Copilot uses AI. Check for mistakes.

// Create CSV rows with proper handling of nested objects
const csv = this.selection.selected.map((row) =>
header
.map((fieldName) => convertToCSVValue(row[fieldName]))
.join(',')
);

// Add header row
csv.unshift(header.map(h => convertToCSVValue(h)).join(','));
const csvArray = csv.join('\r\n');

const a = document.createElement('a');
const blob = new Blob([csvArray], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);

a.href = url;
a.download = 'myFile.csv';

Copilot AI Nov 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filename 'myFile.csv' is hardcoded. Consider using a more descriptive filename that includes the table name and timestamp, such as ${this.tableName}_export_${Date.now()}.csv to make exported files more identifiable and prevent overwriting.

Suggested change
a.download = 'myFile.csv';
const tableName = this.tableName ? this.tableName : 'table';
a.download = `${tableName}_export_${Date.now()}.csv`;

Copilot uses AI. Check for mistakes.
a.click();
window.URL.revokeObjectURL(url);
a.remove();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
align-items: center;
height: 100%;
min-height: calc(100vh - 120px); /* Adjust based on header height */
position: relative;
}

.collapsed-top-section {
Expand All @@ -39,14 +40,20 @@
flex: 1;
justify-content: flex-start;
padding-top: 8px;
overflow-y: auto;
width: 100%;
}

.collapsed-bottom-section {
display: flex;
flex-direction: column;
align-items: center;
margin-top: auto;
padding-bottom: 8px;
position: sticky;
bottom: 0;
background-color: #ffffff;
padding: 8px 0;
width: 100%;
z-index: 10;
}

.collapsed-folders {
Expand Down Expand Up @@ -209,6 +216,15 @@

/* Dark theme adaptations */
@media (prefers-color-scheme: dark) {
.collapsed-tables-list {
background: #303030;
border: 1px solid #424242;
}

.collapsed-bottom-section {
background-color: #303030;
}

.collapsed-folder-item {
background-color: transparent;
color: #ffffff;
Expand Down Expand Up @@ -422,7 +438,8 @@
.tables-list {
width: 100%;
box-sizing: border-box;
min-height: 0;
/* min-height: 0; */

Copilot AI Nov 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSS property min-height: 0; is commented out at line 441. If this property is no longer needed, the comment should be removed entirely. If it's temporarily disabled for testing, consider adding an explanatory comment about why it's commented out and when it should be restored.

Suggested change
/* min-height: 0; */

Copilot uses AI. Check for mistakes.
height: calc(100vh - 100px); /* Adjust based on header height */
}

.tables-list ::ng-deep .table-list-item .mat-list-item-content {
Expand Down Expand Up @@ -463,16 +480,25 @@
}

.folder-header.expanded {
background-color: #212121;
color: #ffffff;
background-color: #212121 !important;
color: #ffffff !important;
}

.folder-header.expanded .folder-icon {
color: #ffffff;
.folder-header .folder-icon {
color: #ffffff !important;
}

/* .folder-header.expanded .folder-name, */

Copilot AI Nov 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a commented-out CSS selector /* .folder-header.expanded .folder-name, */ at line 491. This commented code should either be removed if it's no longer needed, or uncommented if it's still required for the expanded folder state. Leaving commented code in the codebase without explanation can cause confusion.

Suggested change
/* .folder-header.expanded .folder-name, */

Copilot uses AI. Check for mistakes.
.folder-header .folder-name {
color: #ffffff !important;
}

.folder-header.expanded .folder-expand-icon {
color: #ffffff;
color: #ffffff !important;
}

.folder-header:hover {
background-color: rgba(255, 255, 255, 0.05) !important;
}
}

Expand Down Expand Up @@ -510,14 +536,54 @@
margin-left: 16px;
}

/* Expanded state container */
.expanded-container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
position: relative;
overflow-y: auto;
}

.search-input {
background-color: transparent;
margin-top: 4px;
margin-top: 8px;
margin-left: 16px;
/* margin-bottom: -24px; */
margin-bottom: -8px;
width: calc(100% - 32px);
max-width: calc(240px - 32px);
box-sizing: border-box;
order: 1; /* Always first */
}

/* Add folder button container */
.add-folder-button-container {
order: 2; /* Default: after search when no custom folders */
margin-left: 16px;
margin-right: 16px;
margin-top: 4px;
margin-bottom: 8px;
width: calc(100% - 32px);
box-sizing: border-box;
}

/* When custom folders exist, move add button to bottom */
.expanded-container.has-custom-folders .add-folder-button-container {
order: 4; /* After folders section */
position: sticky;
bottom: 0;
background-color: #ffffff;
padding: 8px 16px;
z-index: 10;
margin-top: auto;
}

/* Dark theme support for add button container when at bottom */
@media (prefers-color-scheme: dark) {
.expanded-container.has-custom-folders .add-folder-button-container {
background-color: #303030;
}
}

.search-input ::ng-deep * {
Expand All @@ -537,26 +603,8 @@
padding-bottom: 8px;
}

.add-folder-button-container {
margin-left: 16px;
margin-right: 16px;
margin-top: -12px;
margin-bottom: 12px;
width: calc(100% - 32px);
box-sizing: border-box;
}

.add-folder-button {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
font-weight: 500;
text-transform: none;
letter-spacing: 0.5px;
border-color: #e0e0e0 !important;
color: #616161 !important;
}

.add-folder-button:hover {
Expand All @@ -575,6 +623,9 @@
margin-bottom: 8px;
width: calc(100% - 32px);
box-sizing: border-box;
order: 3; /* After search and (optionally) add button */
flex: 1;
overflow-y: auto;
}

.folder-item {
Expand Down
Loading
Loading