Improved progress display
Previously, the progress bar updated only after completing an entire table. For large tables such as LIBARC, this could make the application appear to have stopped responding. Phase 10 updates the interface while rows are being exported.
This commit is contained in:
@@ -30,6 +30,9 @@ struct MainView: View {
|
||||
@State private var resultFilter = ""
|
||||
@State private var resultSortColumn = 0
|
||||
@State private var resultSortAscending = true
|
||||
@State private var hiddenResultColumns: Set<Int> = []
|
||||
@State private var resultPage = 0
|
||||
private let resultPageSize = 1_000
|
||||
@State private var showingEditor = false
|
||||
@State private var showingDatabaseTransfer = false
|
||||
@State private var showingQueryHistory = false
|
||||
@@ -814,6 +817,21 @@ struct MainView: View {
|
||||
Button(resultSortAscending ? "Ascending" : "Descending") {
|
||||
resultSortAscending.toggle()
|
||||
}
|
||||
Menu("Columns") {
|
||||
Button("Show All Columns") { hiddenResultColumns.removeAll() }
|
||||
Divider()
|
||||
ForEach(model.result.columns.indices, id: \.self) { index in
|
||||
Button {
|
||||
if hiddenResultColumns.contains(index) {
|
||||
hiddenResultColumns.remove(index)
|
||||
} else {
|
||||
hiddenResultColumns.insert(index)
|
||||
}
|
||||
} label: {
|
||||
Label(model.result.columns[index], systemImage: hiddenResultColumns.contains(index) ? "square" : "checkmark.square")
|
||||
}
|
||||
}
|
||||
}
|
||||
Button("Export CSV") { exportResultCSV() }
|
||||
}
|
||||
Text(model.queryDurationText)
|
||||
@@ -837,13 +855,36 @@ struct MainView: View {
|
||||
}
|
||||
} else {
|
||||
resultGrid
|
||||
HStack(spacing: 12) {
|
||||
Text("\(displayedRows.count) matching rows · showing \(min(resultPage * resultPageSize + 1, displayedRows.count))–\(min((resultPage + 1) * resultPageSize, displayedRows.count))")
|
||||
.foregroundStyle(.secondary)
|
||||
Spacer()
|
||||
Button("Previous") { resultPage = max(0, resultPage - 1) }
|
||||
.disabled(resultPage == 0)
|
||||
Text("Page \(resultPage + 1) / \(max(1, (displayedRows.count + resultPageSize - 1) / resultPageSize))")
|
||||
Button("Next") { resultPage += 1 }
|
||||
.disabled((resultPage + 1) * resultPageSize >= displayedRows.count)
|
||||
}
|
||||
.font(.system(size: 11))
|
||||
.padding(.horizontal, 12)
|
||||
.padding(.vertical, 5)
|
||||
.background(WB.header)
|
||||
}
|
||||
}
|
||||
.onChange(of: resultFilter) { _, _ in resultPage = 0 }
|
||||
.onChange(of: resultSortColumn) { _, _ in resultPage = 0 }
|
||||
.onChange(of: resultSortAscending) { _, _ in resultPage = 0 }
|
||||
.onChange(of: model.result.columns) { _, _ in
|
||||
resultPage = 0
|
||||
hiddenResultColumns.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var resultGrid: some View {
|
||||
NativeResultGrid(columns: model.result.columns, rows: displayedRows)
|
||||
let rows = displayedRows
|
||||
let start = min(resultPage * resultPageSize, rows.count)
|
||||
let end = min(start + resultPageSize, rows.count)
|
||||
return NativeResultGrid(columns: model.result.columns, rows: Array(rows[start..<end]), hiddenColumnIndices: hiddenResultColumns)
|
||||
}
|
||||
|
||||
private var displayedRows: [[String]] {
|
||||
@@ -1348,6 +1389,7 @@ struct NativeResultGrid: NSViewRepresentable {
|
||||
|
||||
let columns: [String]
|
||||
let rows: [[String]]
|
||||
var hiddenColumnIndices: Set<Int> = []
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator()
|
||||
@@ -1385,7 +1427,7 @@ struct NativeResultGrid: NSViewRepresentable {
|
||||
table.delegate = context.coordinator
|
||||
table.dataSource = context.coordinator
|
||||
|
||||
configureColumns(table)
|
||||
configureColumns(table, hiddenIndices: hiddenColumnIndices)
|
||||
|
||||
scroll.documentView = table
|
||||
table.reloadData()
|
||||
@@ -1406,19 +1448,22 @@ struct NativeResultGrid: NSViewRepresentable {
|
||||
context.coordinator.columns = columns
|
||||
context.coordinator.rows = rows
|
||||
|
||||
if oldColumns != columns {
|
||||
configureColumns(table)
|
||||
if oldColumns != columns || Set(table.tableColumns.compactMap { column -> Int? in
|
||||
let identifier = column.identifier.rawValue
|
||||
return identifier.hasPrefix("column_") ? Int(identifier.dropFirst(7)) : nil
|
||||
}) != Set(columns.indices).subtracting(hiddenColumnIndices) {
|
||||
configureColumns(table, hiddenIndices: hiddenColumnIndices)
|
||||
}
|
||||
|
||||
table.reloadData()
|
||||
}
|
||||
|
||||
private func configureColumns(_ table: NSTableView) {
|
||||
private func configureColumns(_ table: NSTableView, hiddenIndices: Set<Int>) {
|
||||
for column in Array(table.tableColumns) {
|
||||
table.removeTableColumn(column)
|
||||
}
|
||||
|
||||
for (index, name) in columns.enumerated() {
|
||||
for (index, name) in columns.enumerated() where !hiddenIndices.contains(index) {
|
||||
let identifier = NSUserInterfaceItemIdentifier(
|
||||
"column_\(index)"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user