Skip to content
Draft
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 @@ -375,15 +375,51 @@
}

.db-table_withActions ::ng-deep .mat-header-row .mat-column-select {
padding-top: 18px;
padding-top: 8px;
display: flex;
align-items: center;
justify-content: center;
}

th.mat-header-cell, td.mat-cell {
padding-right: 20px;
}

.db-table ::ng-deep .mat-mdc-header-cell .mat-sort-header-content {
text-align: left;
text-align: left !important;
justify-content: flex-start !important;
align-items: flex-start !important;
display: flex !important;
width: 100%;
padding-top: 8px !important;
}

.db-table ::ng-deep .mat-sort-header-container {
align-items: flex-start !important;
justify-content: flex-start !important;
padding-top: 0 !important;
display: flex !important;
}

.db-table ::ng-deep .mat-mdc-header-cell {
vertical-align: top !important;
text-align: left !important;
justify-content: flex-start !important;
align-items: flex-start !important;
display: flex !important;
}

.db-table ::ng-deep .mat-mdc-header-cell .mat-sort-header-content > div {
text-align: left !important;
white-space: normal !important;
word-wrap: break-word !important;
line-height: 1.2 !important;
align-self: flex-start !important;
}

.db-table ::ng-deep .mat-mdc-header-cell .mat-sort-header-arrow {
align-self: flex-start !important;
margin-top: 8px !important;
}

.db-table-cell-checkbox {
Expand Down Expand Up @@ -430,6 +466,10 @@ th.mat-header-cell, td.mat-cell {
justify-content: flex-end;
}

.db-table-header-actions {
padding-top: 8px !important;
}

.table-cell-content {
overflow: hidden;
white-space: nowrap;
Expand Down Expand Up @@ -503,3 +543,81 @@ tr.mat-row:hover {
.hidden {
display: none;
}

/* Columns Menu Drag and Drop Styles */
.columns-list {
max-height: 400px;
overflow-y: auto;
padding: 8px 0;
}

.draggable-column-item {
cursor: move;
display: flex !important;
align-items: center;
justify-content: flex-start;
gap: 0px;
padding: 8px 24px 8px 8px !important;
min-height: 48px !important;
transition: background-color 0.2s ease;
}

.draggable-column-item .drag-handle {
color: #9e9e9e;
cursor: grab;
font-size: 20px;
width: 20px;
height: 20px;
margin-right: 0px;
flex-shrink: 0;
}

.draggable-column-item ::ng-deep .mat-mdc-checkbox {
align-items: center !important;
}

.draggable-column-item ::ng-deep .mat-mdc-checkbox-label {
text-align: left;
line-height: 1.5;
}

.draggable-column-item ::ng-deep .mdc-form-field {
align-items: center !important;
}

.draggable-column-item:active .drag-handle {
cursor: grabbing;
}

.draggable-column-item:hover .drag-handle {
color: #616161;
}

@media (prefers-color-scheme: dark) {
.draggable-column-item .drag-handle {
color: #757575;
}

.draggable-column-item:hover .drag-handle {
color: #bdbdbd;
}
}

.cdk-drag-preview.draggable-column-item {
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12);
opacity: 0.9;
}

.cdk-drag-placeholder {
opacity: 0.3;
}

.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}

.columns-list.cdk-drop-list-dragging .draggable-column-item:not(.cdk-drag-placeholder) {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,24 @@ <h2 class="mat-h2 table-name">{{ displayName }}</h2>
/
{{ tableData.columns.length }})
</button>
<mat-menu #menu="matMenu">
<button mat-menu-item
role="menuitemcheckbox"
*ngFor="let column of tableData.columns"
(click)="$event.stopPropagation();">
<mat-checkbox
[disabled]="tableData.displayedDataColumns.length === 1 && column.selected"
(change)="tableData.changleColumnList(connectionID, name)"
[(ngModel)]="column.selected">
{{column.normalizedTitle}}
</mat-checkbox>
</button>
<mat-menu #menu="matMenu" class="columns-menu">
<div cdkDropList (cdkDropListDropped)="onColumnsMenuDrop($event)" class="columns-list">
<button mat-menu-item
role="menuitemcheckbox"
*ngFor="let column of sortedColumns"
cdkDrag
[cdkDragData]="column"
class="draggable-column-item"
(click)="$event.stopPropagation();">
<mat-icon class="drag-handle">drag_indicator</mat-icon>
<mat-checkbox
[disabled]="tableData.displayedDataColumns.length === 1 && column.selected"
(change)="onColumnVisibilityChange()"
[(ngModel)]="column.selected">
{{column.normalizedTitle}}
</mat-checkbox>
</button>
</div>
</mat-menu>
</div>
<button mat-icon-button type="button"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as JSON5 from 'json5';

import { ActivatedRoute, Router } from '@angular/router';
import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges, ViewChild, ChangeDetectorRef } from '@angular/core';
import { CustomAction, TableForeignKey, TablePermissions, TableProperties, TableRow, Widget } from 'src/app/models/table';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { UIwidgets, tableDisplayTypes } from '../../../consts/table-display-types';
Expand All @@ -13,7 +13,7 @@ import { CommonModule } from '@angular/common';
import { ConnectionsService } from 'src/app/services/connections.service';
import { DbTableExportDialogComponent } from './db-table-export-dialog/db-table-export-dialog.component';
import { DbTableImportDialogComponent } from './db-table-import-dialog/db-table-import-dialog.component';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { DragDropModule, CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { DynamicModule } from 'ng-dynamic-component';
import { ForeignKeyDisplayComponent } from '../../ui-components/table-display-fields/foreign-key/foreign-key.component';
import JsonURL from "@jsonurl/jsonurl";
Expand All @@ -40,6 +40,7 @@ import { SavedFiltersPanelComponent } from './saved-filters-panel/saved-filters-
import { SelectionModel } from '@angular/cdk/collections';
import { TableRowService } from 'src/app/services/table-row.service';
import { TableStateService } from 'src/app/services/table-state.service';
import { TablesService } from 'src/app/services/tables.service';
import { formatFieldValue } from 'src/app/lib/format-field-value';
import { getTableTypes } from 'src/app/lib/setup-table-row-structure';
import { merge } from 'rxjs';
Expand All @@ -53,6 +54,7 @@ interface Column {

@Component({
selector: 'app-db-table-view',
standalone: true,
templateUrl: './db-table-view.component.html',
styleUrls: ['./db-table-view.component.css'],
imports: [
Expand Down Expand Up @@ -147,9 +149,11 @@ export class DbTableViewComponent implements OnInit {
private _notifications: NotificationsService,
private _tableRow: TableRowService,
private _connections: ConnectionsService,
private _tables: TablesService,
private route: ActivatedRoute,
public router: Router,
public dialog: MatDialog,
private cdr: ChangeDetectorRef,
) {}

ngAfterViewInit() {
Expand Down Expand Up @@ -522,4 +526,95 @@ export class DbTableViewComponent implements OnInit {
console.log('table view fiers filterSelected:', $event)
this.applyFilter.emit($event);
}

get sortedColumns() {
if (!this.tableData || !this.tableData.columns) {
return [];
}
// Sort columns: visible (selected=true) first, then hidden (selected=false)
return [...this.tableData.columns].sort((a, b) => {
if (a.selected === b.selected) return 0;
return a.selected ? -1 : 1;
});
}

onColumnVisibilityChange() {
this.tableData.changleColumnList(this.connectionID, this.name);
this.cdr.detectChanges();
}

onColumnsMenuDrop(event: CdkDragDrop<string[]>) {
if (event.previousIndex === event.currentIndex) {
return;
}

// Reorder columns array in the menu
moveItemInArray(this.tableData.columns, event.previousIndex, event.currentIndex);

// Update dataColumns array
this.tableData.dataColumns = this.tableData.columns.map(column => column.title);

// Update displayedDataColumns to match the new order (only visible columns)
const newDisplayedOrder = this.tableData.columns
.filter(col => col.selected)
.map(col => col.title);

this.tableData.displayedDataColumns = newDisplayedOrder;

// Update full displayed columns list - THIS UPDATES THE TABLE IMMEDIATELY
if (this.tableData.keyAttributes && this.tableData.keyAttributes.length) {
this.tableData.displayedColumns = ['select', ...newDisplayedOrder, 'actions'];
} else {
this.tableData.displayedColumns = [...newDisplayedOrder];
}

// Update normalized columns mapping to maintain consistency
this.updateNormalizedColumnsMapping();

// Force Angular to detect changes and re-render the table immediately
this.cdr.detectChanges();

// Save the new order to table settings (list_fields)
this.saveColumnsOrderToSettings(this.tableData.columns.map(col => col.title));

console.log('Columns reordered in menu - table updated:', newDisplayedOrder);
}

private updateNormalizedColumnsMapping() {
// Rebuild normalized columns mapping to match new order
const newNormalizedColumns = {};
this.tableData.columns.forEach(column => {
if (this.tableData.dataNormalizedColumns[column.title]) {
newNormalizedColumns[column.title] = this.tableData.dataNormalizedColumns[column.title];
}
});
this.tableData.dataNormalizedColumns = newNormalizedColumns;
}

private saveColumnsOrderToSettings(columnsOrder: string[]) {
this._tables.fetchTableSettings(this.connectionID, this.name).subscribe({
next: (currentSettings) => {
const isSettingsExist = Object.keys(currentSettings).length !== 0;

const updatedSettings = {
...currentSettings,
connection_id: this.connectionID,
table_name: this.name,
list_fields: columnsOrder
};

this._tables.updateTableSettings(isSettingsExist, this.connectionID, this.name, updatedSettings).subscribe({
next: () => {
console.log('Column order saved to table settings');
},
error: (error) => {
console.error('Error saving column order:', error);
}
});
},
error: (error) => {
console.error('Error fetching table settings:', error);
}
});
}
}