From ac4766306dab4afb43cf866037028e6845db39d8 Mon Sep 17 00:00:00 2001 From: Stefan Kuethe Date: Thu, 19 Sep 2024 08:26:18 +0200 Subject: [PATCH 1/3] Refactor --- NAMESPACE | 1 - R/columns.R | 11 ++++++----- R/spreadsheet.R | 1 + _pkgdown.yml | 1 - examples/multiple_spreadsheets.R | 4 ++-- man/create_columns.Rd | 18 ------------------ man/spreadsheet_def.Rd | 18 ++++++++++++++++++ man/tabulator.Rd | 4 ++-- 8 files changed, 29 insertions(+), 29 deletions(-) delete mode 100644 man/create_columns.Rd diff --git a/NAMESPACE b/NAMESPACE index bd0c0b0..98b88bf 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,7 +1,6 @@ # Generated by roxygen2: do not edit by hand export(add_row) -export(create_columns) export(delete_selected_rows) export(for_each_col) export(redo) diff --git a/R/columns.R b/R/columns.R index 429467d..458a474 100644 --- a/R/columns.R +++ b/R/columns.R @@ -1,8 +1,8 @@ -#' Create column definitions from data -#' @param data (data.frame) data -#' @param editor (bool): Whether to make columns editable. -#' @param filter (bool): Whether to add a header filter to the columns. -#' @export +# #' Create column definitions from data +# #' @param data (data.frame) data +# #' @param editor (bool): Whether to make columns editable. +# #' @param filter (bool): Whether to add a header filter to the columns. +# #' @returns list # TODO: We do not need to export this func anymore create_columns <- function(data, editor = FALSE, filter = FALSE) { data <- fix_colnames(data) @@ -87,6 +87,7 @@ for_each_col <- function(widget, columns = NULL, .f, ...) { } # Formatters #### +# TODO: Move formatters to separate file #' Set HTML formatter #' @param widget (\code{\link{tabulator}}) A tabulator widget. diff --git a/R/spreadsheet.R b/R/spreadsheet.R index 0f73ce4..b112e4f 100644 --- a/R/spreadsheet.R +++ b/R/spreadsheet.R @@ -4,6 +4,7 @@ #' @param data (list): The initial data of the spreadsheet. #' Set to \code{NULL} to create an empty spreadsheet. #' @returns list +#' @example examples/multiple_spreadsheets.R #' @export spreadsheet_def <- function(title, key = NULL, data = NULL) { return(compact(as.list(environment()))) diff --git a/_pkgdown.yml b/_pkgdown.yml index b11a6ff..154732b 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -50,7 +50,6 @@ reference: Utitily functions contents: - spreadsheet_def - - create_columns - title: Data Sets contents: diff --git a/examples/multiple_spreadsheets.R b/examples/multiple_spreadsheets.R index 109ed3d..e2e2733 100644 --- a/examples/multiple_spreadsheets.R +++ b/examples/multiple_spreadsheets.R @@ -1,11 +1,11 @@ setup <- tabulator_options( spreadsheet = TRUE, spreadsheet_sheets = list( - list( + spreadsheet_def( title = "First", data = list(c(1, 2, 3)) ), - list( + spreadsheet_def( title = "Second", data = list(c(4, 5, 6)) ) diff --git a/man/create_columns.Rd b/man/create_columns.Rd deleted file mode 100644 index 392a5f3..0000000 --- a/man/create_columns.Rd +++ /dev/null @@ -1,18 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/columns.R -\name{create_columns} -\alias{create_columns} -\title{Create column definitions from data} -\usage{ -create_columns(data, editor = FALSE, filter = FALSE) -} -\arguments{ -\item{data}{(data.frame) data} - -\item{editor}{(bool): Whether to make columns editable.} - -\item{filter}{(bool): Whether to add a header filter to the columns.} -} -\description{ -Create column definitions from data -} diff --git a/man/spreadsheet_def.Rd b/man/spreadsheet_def.Rd index a928c0f..e8e9772 100644 --- a/man/spreadsheet_def.Rd +++ b/man/spreadsheet_def.Rd @@ -20,3 +20,21 @@ list \description{ Create a spreadsheet definition } +\examples{ +setup <- tabulator_options( + spreadsheet = TRUE, + spreadsheet_sheets = list( + spreadsheet_def( + title = "First", + data = list(c(1, 2, 3)) + ), + spreadsheet_def( + title = "Second", + data = list(c(4, 5, 6)) + ) + ), + spreadsheet_sheet_tabs = TRUE +) + +tabulator(data = NULL, setup, theme = "midnight") +} diff --git a/man/tabulator.Rd b/man/tabulator.Rd index 16faa85..b94b550 100644 --- a/man/tabulator.Rd +++ b/man/tabulator.Rd @@ -59,11 +59,11 @@ Dots in column names are replaced by underscores. setup <- tabulator_options( spreadsheet = TRUE, spreadsheet_sheets = list( - list( + spreadsheet_def( title = "First", data = list(c(1, 2, 3)) ), - list( + spreadsheet_def( title = "Second", data = list(c(4, 5, 6)) ) From a973e072feeef0ceb935b28f61420c36940487c9 Mon Sep 17 00:00:00 2001 From: Stefan Kuethe Date: Thu, 19 Sep 2024 08:29:34 +0200 Subject: [PATCH 2/3] Minify bindings --- inst/htmlwidgets/rtabulator.js | 137 +-------------------------------- 1 file changed, 1 insertion(+), 136 deletions(-) diff --git a/inst/htmlwidgets/rtabulator.js b/inst/htmlwidgets/rtabulator.js index 25827a7..87904ce 100644 --- a/inst/htmlwidgets/rtabulator.js +++ b/inst/htmlwidgets/rtabulator.js @@ -1,136 +1 @@ -(() => { - // src/utils.js - function convertToDataFrame(data) { - res = {}; - if (data.length === 0) { - return res; - } - keys = Object.keys(data[0]); - keys.forEach((key) => res[key] = data.map((item) => item[key])); - return res; - } - - // src/events.js - function addEventListeners(table, el) { - table.on("rowClick", function(e, row) { - const inputName = `${el.id}_row_clicked`; - console.log(inputName, row.getData()); - Shiny.onInputChange(inputName, row.getData()); - }); - table.on("rowClick", (e, row) => { - const inputName = `${el.id}_rows_selected:rtabulator.data`; - const data = table.getSelectedRows().map((row2) => row2.getData()); - console.log(inputName, data); - Shiny.onInputChange(inputName, { data: convertToDataFrame(data) }); - }); - table.on("cellEdited", function(cell) { - const inputName = `${el.id}_cell_edited`; - console.log(inputName, cell.getData()); - Shiny.onInputChange(inputName, cell.getData()); - }); - table.on("dataFiltered", function(filters, rows) { - const inputName = `${el.id}_data_filtered:rtabulator.data`; - const data = rows.map((row) => row.getData()); - console.log(inputName, data); - Shiny.onInputChange(inputName, { data: convertToDataFrame(data) }); - }); - } - - // src/widget.js - function run_calls(el, table, calls) { - calls.forEach(([method_name, options]) => { - if (method_name === "getData") { - const inputName = `${el.id}_get_data:rtabulator.data`; - console.log("custom call", inputName); - Shiny.setInputValue( - inputName, - { data: convertToDataFrame(table.getData()) }, - { priority: "event" } - ); - return; - } - if (method_name === "deleteSelectedRows") { - console.log("custom call"); - const rows = table.getSelectedRows(); - rows.forEach((row) => { - console.log(row.getIndex()); - table.deleteRow(row.getIndex()); - }); - return; - } - if (method_name === "getSheetData") { - const inputName = `${el.id}_get_sheet_data:rtabulator.sheet_data`; - console.log("custom call", inputName); - Shiny.setInputValue( - inputName, - { data: table.getSheetData() }, - { priority: "event" } - ); - return; - } - console.log(method_name, options); - table[method_name](...options); - }); - } - var TabulatorWidget = class { - constructor(container, data, options) { - options.data = data; - this._container = container; - console.log("columns", options.columns); - if (data !== null && options.columns == null) { - options.autoColumns = true; - } - if (options.spreadsheet && options.spreadsheetData == null) { - options.spreadsheetData = []; - } - this._table = new Tabulator(this._container, options); - if (typeof Shiny === "object") { - addEventListeners(this._table, this._container); - this._addShinyMessageHandler(); - } - } - _addShinyMessageHandler() { - const messageHandlerName = `tabulator-${this._container.id}`; - Shiny.addCustomMessageHandler(messageHandlerName, (payload) => { - console.log(payload); - run_calls(this._container, this._table, payload.calls); - }); - } - getTable() { - return this._table; - } - }; - - // src/index-r.js - function tabulatorFactory(widgetElement, width, height) { - let table = null; - function renderValue(payload) { - console.log(payload); - if (payload.stylesheetText) { - document.head.insertAdjacentHTML( - "beforeend", - `` - ); - } - if (payload.options === null) { - payload.options = {}; - } - let data = null; - if (payload.options.spreadsheet === true) { - payload.options.spreadsheetData = payload.data; - } else { - data = HTMLWidgets.dataframeToD3(payload.data); - } - const widget = new TabulatorWidget(widgetElement, data, payload.options); - table = widget.getTable(); - } - function resize(width2, height2) { - } - return { renderValue, resize }; - } - HTMLWidgets.widget({ - name: "rtabulator", - type: "output", - factory: tabulatorFactory - }); -})(); +(()=>{function i(o){return res={},o.length===0||(keys=Object.keys(o[0]),keys.forEach(e=>res[e]=o.map(a=>a[e]))),res}function d(o,e){o.on("rowClick",function(a,t){let r=`${e.id}_row_clicked`;console.log(r,t.getData()),Shiny.onInputChange(r,t.getData())}),o.on("rowClick",(a,t)=>{let r=`${e.id}_rows_selected:rtabulator.data`,s=o.getSelectedRows().map(n=>n.getData());console.log(r,s),Shiny.onInputChange(r,{data:i(s)})}),o.on("cellEdited",function(a){let t=`${e.id}_cell_edited`;console.log(t,a.getData()),Shiny.onInputChange(t,a.getData())}),o.on("dataFiltered",function(a,t){let r=`${e.id}_data_filtered:rtabulator.data`,s=t.map(n=>n.getData());console.log(r,s),Shiny.onInputChange(r,{data:i(s)})})}function u(o,e,a){a.forEach(([t,r])=>{if(t==="getData"){let s=`${o.id}_get_data:rtabulator.data`;console.log("custom call",s),Shiny.setInputValue(s,{data:i(e.getData())},{priority:"event"});return}if(t==="deleteSelectedRows"){console.log("custom call"),e.getSelectedRows().forEach(n=>{console.log(n.getIndex()),e.deleteRow(n.getIndex())});return}if(t==="getSheetData"){let s=`${o.id}_get_sheet_data:rtabulator.sheet_data`;console.log("custom call",s),Shiny.setInputValue(s,{data:e.getSheetData()},{priority:"event"});return}console.log(t,r),e[t](...r)})}var c=class{constructor(e,a,t){t.data=a,this._container=e,console.log("columns",t.columns),a!==null&&t.columns==null&&(t.autoColumns=!0),t.spreadsheet&&t.spreadsheetData==null&&(t.spreadsheetData=[]),this._table=new Tabulator(this._container,t),typeof Shiny=="object"&&(d(this._table,this._container),this._addShinyMessageHandler())}_addShinyMessageHandler(){let e=`tabulator-${this._container.id}`;Shiny.addCustomMessageHandler(e,a=>{console.log(a),u(this._container,this._table,a.calls)})}getTable(){return this._table}};function g(o,e,a){let t=null;function r(n){console.log(n),n.stylesheetText&&document.head.insertAdjacentHTML("beforeend",``),n.options===null&&(n.options={});let l=null;n.options.spreadsheet===!0?n.options.spreadsheetData=n.data:l=HTMLWidgets.dataframeToD3(n.data),t=new c(o,l,n.options).getTable()}function s(n,l){}return{renderValue:r,resize:s}}HTMLWidgets.widget({name:"rtabulator",type:"output",factory:g});})(); From a9dbcc823c13829368a4ac5e3883c5862b0cfadb Mon Sep 17 00:00:00 2001 From: Stefan Kuethe Date: Thu, 19 Sep 2024 08:44:37 +0200 Subject: [PATCH 3/3] Add LICENSE.note --- LICENSE.note | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 LICENSE.note diff --git a/LICENSE.note b/LICENSE.note new file mode 100644 index 0000000..92f1836 --- /dev/null +++ b/LICENSE.note @@ -0,0 +1,8 @@ +The rtabulator package as a whole is distributed under MIT. +The rtabulator package includes other open source software components. +The following is a list of these components: + +* tabulator.js: MIT +* rtabulator.js: written by package authors + +Full copies of the license agreements used by these components are included in `inst/htmlwidgets/libs`.