Skip to content

Commit

Permalink
Improved support for server side tables, version bump
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrian Salceanu committed Sep 2, 2024
1 parent 6dff1f2 commit 545a0a2
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 26 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "StippleUI"
uuid = "a3c5d34a-b254-4859-a8fa-b86abb7e84a3"
authors = ["Adrian Salceanu <e@essenciary.com>"]
version = "0.23.3"
version = "0.23.4"

[deps]
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
Expand Down
12 changes: 5 additions & 7 deletions demos/tables/app2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,23 @@ using GenieFramework
using DataFrames
@genietools

StippleUI.Tables.set_max_rows_client_side(2000)
StippleUI.Tables.set_default_rows_per_page(20)
StippleUI.Tables.set_max_rows_client_side(11_000)

@app begin
big_data = sort!(DataFrame(rand(1_000_000, 2), ["x1", "x2"]))::DataFrame # we only sort so that the changes are more visible when filtering and paginating
small_data = sort!(DataFrame(rand(1_001, 2), ["y1", "y2"]))::DataFrame

@out dt1 = DataTable(big_data; rows_per_page = 20)
@out dt2 = DataTable(small_data; rows_per_page = 20, server_side = false)
@out dt1 = DataTable(big_data; server_side = true)
@out dt2 = DataTable(big_data)

@out loading = false

@event paginate_dt1 begin
@event dt1_request begin
@paginate(dt1, big_data)
@push
end

end

# @page("/", "ui2.jl.html")
@page("/", "ui2.jl")

end
32 changes: 24 additions & 8 deletions demos/tables/ui2.jl
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
table(:dt1,
paginationsync = Symbol("dt1.pagination"),
@on("request", :paginate_dt1),
server_side = true,
loading = :loading,
filter = Symbol("dt1.filter"),
title = "Random big data"
title = "Server side data"
)
table(:dt2,
paginationsync = Symbol("dt2.pagination"),
loading = :loading,
filter = Symbol("dt2.filter"),
title = "Random small data"
)
title = "Client side data"
)

# ParsedHTMLString("""
# <q-table
# row-key="__id"
# :loading="loading"
# :columns="dt2.columns"
# title="Random data"
# :data="dt2.data"
# :filter="dt2.filter"
# :pagination.sync="dt2.pagination"
# v-model="dt2">
# <template v-slot:top-right>
# <q-input dense debounce="300" v-model="dt2.filter" placeholder="Search">
# <template v-slot:append>
# <q-icon name="search" />
# </template>
# </q-input>
# </template>
# </q-table>
# """)
2 changes: 1 addition & 1 deletion demos/tables/ui2.jl.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<q-table row-key="__id" :loading="loading" :columns="dt.columns" title="Random data" :data="dt.data"
v-on:request="function(event) { handle_event(event, 'request') }" :filter.sync="dt.filter"
v-on:request="function(event) { handle_event(event, 'dt_request') }" :filter="dt.filter"
:pagination.sync="dt.pagination">
<template v-slot:top-right>
<q-input dense debounce="300" v-model="dt.filter" placeholder="Search">
Expand Down
34 changes: 25 additions & 9 deletions src/Tables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ register_normal_element("q__table", context = @__MODULE__)
const ID = "__id"
const DATAKEY = "data" # has to be changed to `rows` for Quasar 2
const DataTableSelection = Vector{Dict{String, Any}}
const DEFAULT_ROWS_PER_PAGE = 50
const DEFAULT_MAX_ROWS_CLIENT_SIDE = Ref(1000)

const DEFAULT_ROWS_PER_PAGE = Ref(50)
const DEFAULT_MAX_ROWS_CLIENT_SIDE = Ref(10_000)

set_default_rows_per_page(n) = (DEFAULT_ROWS_PER_PAGE[] = n)
get_default_rows_per_page() = DEFAULT_ROWS_PER_PAGE[]

set_max_rows_client_side(n) = (DEFAULT_MAX_ROWS_CLIENT_SIDE[] = n)
get_max_rows_client_side() = DEFAULT_MAX_ROWS_CLIENT_SIDE[]

struct2dict(s::T) where T = Dict{Symbol, Any}(zip(fieldnames(T), getfield.(Ref(s), fieldnames(T))))

Expand Down Expand Up @@ -81,7 +86,7 @@ julia> DataTablePagination(rows_per_page=50)
sort_by::Symbol = :desc
descending::Bool = false
page::Int = 1
rows_per_page::Int = DEFAULT_ROWS_PER_PAGE
rows_per_page::Int = DEFAULT_ROWS_PER_PAGE[]
rows_number::Union{Int,Nothing} = nothing
_filter::AbstractString = "" # keep track of filter value for improving performance
end
Expand Down Expand Up @@ -181,16 +186,16 @@ function DataTable{T}(
sort_by::Symbol = :desc,
descending::Bool = false,
page::Int = 1,
rows_per_page::Int = DEFAULT_ROWS_PER_PAGE,
rows_per_page::Int = DEFAULT_ROWS_PER_PAGE[],
rows_number::Union{Int,Nothing} = nothing,

# options
server_side::Bool = true
server_side::Bool = false
) where {T}
if (isnothing(rows_number) && ! server_side) && size(data, 1) > DEFAULT_MAX_ROWS_CLIENT_SIDE[]
@warn """
The number of rows exceeds the maximum number of rows that can be displayed client side.
This can have negative effects on performance, both in terms of loading time and responsiveness.
Loading too many rows can have a negative effects on performance, both in terms of loading time and responsiveness.
Automatically truncating your data to $(DEFAULT_MAX_ROWS_CLIENT_SIDE[]) rows.
If you want to display more rows client side,
Expand Down Expand Up @@ -572,8 +577,17 @@ function table( fieldname::Symbol,
change_inner_class::Union{Nothing,AbstractString,AbstractDict,Vector} = nothing,
change_inner_style::Union{Nothing,AbstractString,AbstractDict,Vector} = nothing,

filter_placeholder::Union{Symbol,String,Nothing} = "Search",

server_side::Bool = false, # if true, the table data, pagination and filtering is rendered server side
server_side_event::Union{Symbol,String,Nothing} = nothing, # event name for server side handling

kwargs...) :: ParsedHTMLString

server_side && server_side_event === nothing && (server_side_event = "$(fieldname)_request")
paginationsync === nothing && (paginationsync = "$fieldname.pagination")
filter === nothing && (filter = Symbol("$fieldname.filter"))

if !isa(edit, Bool) || edit || cell_class !== nothing || cell_style !== nothing
cell_kwargs, kwargs = filter_kwargs(kwargs) do p
startswith(String(p[1]), "cell_") ? Symbol(String(p[1])[6:end]) => p[2] : nothing
Expand All @@ -590,10 +604,10 @@ function table( fieldname::Symbol,

end

if filter !== nothing && paginationsync !== nothing # by convention, assume paginationsync is used only for server side filtering
if filter !== nothing && paginationsync !== nothing
filter_input = [ParsedHTMLString("""
<template v-slot:top-right>
<q-input dense debounce="300" v-model="$filter" placeholder="Search">
<q-input dense debounce="300" v-model="$filter" placeholder="$filter_placeholder">
<template v-slot:append>
<q-icon name="search" />
</template>
Expand All @@ -611,6 +625,7 @@ function table( fieldname::Symbol,
:fieldname => fieldname,
(filter === nothing ? [] : [:filter => filter])...,
(paginationsync === nothing ? [] : [:paginationsync => paginationsync])...,
(server_side_event === nothing ? [] : [Symbol("v-on:request") => "function(event){handle_event(event,'$server_side_event')}"])...,
kwargs...
])...
)
Expand Down Expand Up @@ -673,7 +688,7 @@ function Base.parse(::Type{DataTablePagination}, d::Dict{String,Any})
dtp.sort_by = get!(d, "sortBy", "desc") |> Symbol
dtp.page = get!(d, "page", 1)
dtp.descending = get!(d, "descending", false)
dtp.rows_per_page = get!(d, "rowsPerPage", DEFAULT_ROWS_PER_PAGE)
dtp.rows_per_page = get!(d, "rowsPerPage", DEFAULT_ROWS_PER_PAGE[])

dtp
end
Expand Down Expand Up @@ -825,6 +840,7 @@ export process_request

function process_request(data, datatable::DataTable, pagination::DataTablePagination, filter::AbstractString = "")
event = params(:payload, nothing)
# @show event

if event !== nothing &&
isa(get(event, "event", false), AbstractDict) &&
Expand Down

0 comments on commit 545a0a2

Please sign in to comment.