Skip to content
Merged
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
88 changes: 37 additions & 51 deletions R/vsc.R
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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,
Expand Down Expand Up @@ -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)) {
Expand Down
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
213 changes: 179 additions & 34 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,51 +347,165 @@ export async function showDataView(source: string, type: string, title: string,
export async function getTableHtml(webview: Webview, file: string): Promise<string> {
resDir = isGuestSession ? guestResDir : resDir;
const content = await readContent(file, 'utf8');

return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'bootstrap.min.css'))))}" rel="stylesheet">
<link href="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'dataTables.bootstrap4.min.css'))))}" rel="stylesheet">
<link href="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'fixedHeader.jqueryui.min.css'))))}" rel="stylesheet">
<style type="text/css">
<style media="only screen">
html, body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}

html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
}

body {
color: black;
background-color: white;
padding: 0;
overflow: auto;
}

/* Styling for wrapper and header */

[class*="vscode"] div.ag-root-wrapper {
background-color: var(--vscode-editor-background);
}

[class*="vscode"] div.ag-header {
background-color: var(--vscode-sideBar-background);
}

[class*="vscode"] div.ag-header-cell[aria-sort="ascending"], div.ag-header-cell[aria-sort="descending"] {
color: var(--vscode-textLink-activeForeground);
}
table {
font-size: 0.75em;

/* Styling for rows and cells */

[class*="vscode"] div.ag-row {
color: var(--vscode-editor-foreground);
}

[class*="vscode"] .ag-row-hover {
background-color: var(--vscode-list-hoverBackground) !important;
color: var(--vscode-list-hoverForeground);
}

[class*="vscode"] .ag-row-selected {
background-color: var(--vscode-editor-selectionBackground) !important;
color: var(--vscode-editor-selectionForeground) !important;
}

[class*="vscode"] div.ag-row-even {
border: 0px;
background-color: var(--vscode-editor-background);
}

[class*="vscode"] div.ag-row-odd {
border: 0px;
background-color: var(--vscode-sideBar-background);
}

[class*="vscode"] div.ag-ltr div.ag-has-focus div.ag-cell-focus:not(div.ag-cell-range-selected) {
border-color: var(--vscode-editorCursor-foreground);
}

/* Styling for the filter pop-up */

[class*="vscode"] div.ag-menu {
background-color: var(--vscode-notifications-background);
color: var(--vscode-notifications-foreground);
border-color: var(--vscode-notifications-border);
}

[class*="vscode"] div.ag-filter-apply-panel-button {
background-color: var(--vscode-button-background);
color: var(--vscode-button-foreground);
border: 0;
padding: 5px 10px;
font-size: 12px;
}

[class*="vscode"] div.ag-picker-field-wrapper {
background-color: var(--vscode-editor-background);
color: var(--vscode-editor-foreground);
border-color: var(--vscode-notificationCenter-border);
}

[class*="vscode"] input[class^=ag-] {
border-color: var(--vscode-notificationCenter-border) !important;
}
</style>
</head>
<body>
<div class="container-fluid">
<table id="data-table" class="display table table-sm table-striped table-condensed table-hover"></table>
</div>
<script src="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'jquery.min.js'))))}"></script>
<script src="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'jquery.dataTables.min.js'))))}"></script>
<script src="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'dataTables.bootstrap4.min.js'))))}"></script>
<script src="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'dataTables.fixedHeader.min.js'))))}"></script>
<script src="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'fixedHeader.jqueryui.min.js'))))}"></script>
<script src="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'ag-grid-community.min.noStyle.js'))))}"></script>
<link href="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'ag-grid.min.css'))))}" rel="stylesheet">
<link href="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'ag-theme-balham.min.css'))))}" rel="stylesheet">
<link href="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'ag-theme-balham-dark.min.css'))))}" rel="stylesheet">
<script>
var data = ${String(content)};
$(document).ready(function () {
$("#data-table").DataTable({
data: data.data,
columns: data.columns,
paging: false,
autoWidth: false,
order: [],
fixedHeader: true
});
$("#data-table tbody").on("click", "tr", function() {
$(this).toggleClass("table-active");
const data = ${String(content)};
function updateTheme() {
const gridDiv = document.querySelector('#myGrid');
if (document.body.classList.contains('vscode-light')) {
gridDiv.className = 'ag-theme-balham';
} else {
gridDiv.className = 'ag-theme-balham-dark';
}
}
function autoSizeAll(skipHeader) {
var allColumnIds = [];
gridOptions.columnApi.getAllColumns().forEach(function (column) {
allColumnIds.push(column.colId);
});
gridOptions.columnApi.autoSizeColumns(allColumnIds, skipHeader);
}
const gridOptions = {
defaultColDef: {
sortable: true,
resizable: true,
filter: true,
filterParams: {
buttons: ['reset', 'apply']
}
},
columnDefs: data.columns,
rowData: data.data,
rowSelection: 'multiple',
pagination: true,
enableCellTextSelection: true,
ensureDomOrder: true,
onGridReady: function (params) {
gridOptions.api.sizeColumnsToFit();
autoSizeAll(false);
}
};
document.addEventListener('DOMContentLoaded', () => {
const gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
});
function onload() {
updateTheme();
const observer = new MutationObserver(function (event) {
updateTheme();
});
observer.observe(document.body, {
attributes: true,
attributeFilter: ['class'],
childList: false,
characterData: false
});
}
</script>
</head>
<body onload='onload()'>
<div id="myGrid" style="height: 100%;"></div>
</body>
</html>
`;
Expand All @@ -412,11 +526,42 @@ export async function getListHtml(webview: Webview, file: string): Promise<strin
<link href="${String(webview.asWebviewUri(Uri.file(path.join(resDir, 'jquery.json-viewer.css'))))}" rel="stylesheet">
<style type="text/css">
body {
color: black;
background-color: white;
color: var(--vscode-editor-foreground);
background-color: var(--vscode-editor-background);
}

.json-document {
padding: 0 0;
}

pre#json-renderer {
border: 1px solid #aaa;
font-family: var(--vscode-editor-font-family);
border: 0;
}

ul.json-dict, ol.json-array {
color: var(--vscode-symbolIcon-fieldForeground);
border-left: 1px dotted var(--vscode-editorLineNumber-foreground);
}

.json-literal {
color: var(--vscode-symbolIcon-variableForeground);
}

.json-string {
color: var(--vscode-symbolIcon-stringForeground);
}

a.json-toggle:before {
color: var(--vscode-button-secondaryBackground);
}

a.json-toggle:hover:before {
color: var(--vscode-button-secondaryHoverBackground);
}

a.json-placeholder {
color: var(--vscode-input-placeholderForeground);
}
</style>
<script>
Expand Down
12 changes: 4 additions & 8 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,10 @@ module.exports = {
patterns: [
{ from: './node_modules/jquery/dist/jquery.min.js', to: 'resources' },
{ from: './node_modules/jquery.json-viewer/json-viewer', to: 'resources' },
{ from: './node_modules/bootstrap/dist/js/bootstrap.min.js', to: 'resources' },
{ from: './node_modules/bootstrap/dist/css/bootstrap.min.css', to: 'resources' },
{ from: './node_modules/datatables.net-bs4/js/dataTables.bootstrap4.min.js', to: 'resources' },
{ from: './node_modules/datatables.net-bs4/css/dataTables.bootstrap4.min.css', to: 'resources' },
{ from: './node_modules/datatables.net/js/jquery.dataTables.min.js', to: 'resources' },
{ from: './node_modules/datatables.net-fixedheader/js/dataTables.fixedHeader.min.js', to: 'resources' },
{ from: './node_modules/datatables.net-fixedheader-jqui/js/fixedHeader.jqueryui.min.js', to: 'resources' },
{ from: './node_modules/datatables.net-fixedheader-jqui/css/fixedHeader.jqueryui.min.css', to: 'resources' },
{ from: './node_modules/ag-grid-community/dist/ag-grid-community.min.noStyle.js', to: 'resources' },
{ from: './node_modules/ag-grid-community/dist/styles/ag-grid.min.css', to: 'resources' },
{ from: './node_modules/ag-grid-community/dist/styles/ag-theme-balham.min.css', to: 'resources' },
{ from: './node_modules/ag-grid-community/dist/styles/ag-theme-balham-dark.min.css', to: 'resources' },
]
}),
],
Expand Down
Loading