diff --git a/R/vsc.R b/R/vsc.R index b6a55d3bf..3b3889b73 100644 --- a/R/vsc.R +++ b/R/vsc.R @@ -241,26 +241,38 @@ if (use_httpgd && "httpgd" %in% .packages(all.available = TRUE)) { show_view <- !identical(getOption("vsc.view", "Two"), FALSE) if (show_view) { - dataview_data_type <- function(x) { - if (is.numeric(x)) { - if (is.null(attr(x, "class"))) { - "num" - } else { - "num-fmt" + get_column_def <- function(name, field, value) { + filter <- TRUE + if (is.numeric(value)) { + type <- "numericColumn" + if (is.null(attr(value, "class"))) { + filter <- "agNumberColumnFilter" } - } else if (inherits(x, "Date")) { - "date" + } else if (inherits(value, "Date")) { + type <- "dateColumn" + filter <- "agDateColumnFilter" } else { - "string" + type <- "textColumn" + filter <- "agTextColumnFilter" } + list( + headerName = name, + field = field, + type = type, + filter = filter + ) } dataview_table <- function(data) { + if (is.matrix(data)) { + data <- as.data.frame.matrix(data) + } + if (is.data.frame(data)) { nrow <- nrow(data) colnames <- colnames(data) if (is.null(colnames)) { - colnames <- sprintf("(X%d)", seq_len(ncol(data))) + colnames <- sprintf("V%d", seq_len(ncol(data))) } else { colnames <- trimws(colnames) } @@ -270,49 +282,23 @@ if (show_view) { } else { rownames <- seq_len(nrow) } + colnames <- c("(row)", colnames) + fields <- sprintf("x%d", seq_along(colnames)) data <- c(list(" " = rownames), .subset(data)) - colnames <- c(" ", colnames) - types <- vapply(data, dataview_data_type, - character(1L), USE.NAMES = FALSE) - data <- vapply(data, function(x) { - trimws(format(x)) - }, character(nrow), USE.NAMES = FALSE) - dim(data) <- c(length(rownames), length(colnames)) - } else if (is.matrix(data)) { - if (is.factor(data)) { - data <- format(data) - } - types <- rep(dataview_data_type(data), ncol(data)) - colnames <- colnames(data) - colnames(data) <- NULL - if (is.null(colnames)) { - colnames <- sprintf("(X%d)", seq_len(ncol(data))) - } else { - colnames <- trimws(colnames) - } - rownames <- rownames(data) - rownames(data) <- NULL - data <- trimws(format(data)) - if (is.null(rownames)) { - types <- c("num", types) - rownames <- seq_len(nrow(data)) - } else { - types <- c("string", types) - rownames <- trimws(rownames) - } - dim(data) <- c(length(rownames), length(colnames)) - colnames <- c(" ", colnames) - data <- cbind(rownames, data) + names(data) <- fields + class(data) <- "data.frame" + attr(data, "row.names") <- .set_row_names(nrow) + columns <- .mapply(get_column_def, + list(colnames, fields, data), + NULL + ) + list( + columns = columns, + data = data + ) } else { - stop("data must be data.frame or matrix") + stop("data must be a data.frame or a matrix") } - columns <- .mapply(function(title, type) { - class <- if (type == "string") "text-left" else "text-right" - list(title = scalar(title), - className = scalar(class), - type = scalar(type)) - }, list(colnames, types), NULL) - list(columns = columns, data = data) } show_dataview <- function(x, title, uuid = NULL, @@ -377,7 +363,7 @@ if (show_view) { if (is.data.frame(x) || is.matrix(x)) { data <- dataview_table(x) file <- tempfile(tmpdir = tempdir, fileext = ".json") - jsonlite::write_json(data, file, matrix = "rowmajor") + jsonlite::write_json(data, file, auto_unbox = TRUE) request("dataview", source = "table", type = "json", title = title, file = file, viewer = viewer, uuid = uuid) } else if (is.list(x)) { diff --git a/package.json b/package.json index 4fd2159d2..5a0c63305 100644 --- a/package.json +++ b/package.json @@ -1418,12 +1418,10 @@ "yamljs": "^0.3.0" }, "dependencies": { + "ag-grid-community": "^25.3.0", "bootstrap": "^5.0.1", "cheerio": "1.0.0-rc.10", "crypto": "^1.0.1", - "datatables.net": "^1.10.25", - "datatables.net-bs4": "^1.10.25", - "datatables.net-fixedheader-jqui": "^3.1.9", "ejs": "^3.1.6", "fs-extra": "^10.0.0", "highlight.js": "^10.7.2", diff --git a/src/session.ts b/src/session.ts index 527abb075..c266e5d9a 100644 --- a/src/session.ts +++ b/src/session.ts @@ -347,51 +347,165 @@ export async function showDataView(source: string, type: string, title: string, export async function getTableHtml(webview: Webview, file: string): Promise { resDir = isGuestSession ? guestResDir : resDir; const content = await readContent(file, 'utf8'); - return ` - - - - - - -
-
-
- - - - - + + + + + + +
`; @@ -412,11 +526,42 @@ export async function getListHtml(webview: Webview, file: string): Promise