Class: Table

Inherits:
Gloo::Core::Obj
  • Object
show all
Defined in:
lib/table.rb

Overview

Author

Eric Crane (mailto:eric.crane@mac.com)

Copyright

Copyright (c) 2020 Eric Crane. All rights reserved.

A data table. The table container headers and data.

Constant Summary collapse

KEYWORD =
'table'.freeze
KEYWORD_SHORT =
'tbl'.freeze
HEADERS =
'headers'.freeze
DATA =
'data'.freeze
CELLS =
'cells'.freeze
STYLES =
'styles'.freeze
ALWAYS_ROWS =
'always_rows'.freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.doc_dataObject

Get the object's documentation data.



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/table.rb', line 276

def self.doc_data
  {
    :name => KEYWORD,
    :shortcut => KEYWORD_SHORT,
    :description => 'A data table.',
    :children => [
      'headers (container) — A list of headers. The name of each header object must match the name of the object in the data container; the value of the header is what will be displayed.',
      'data (container) — The table\'s data. Contains one or more containers, each representing one row of data.',
      'cells (container) — Optional. If present, cells can be formatted with a child per column you want to format; you don\'t need to specify a child for every column.',
      'always_rows (boolean) — Optional. By default, if a table\'s data is only 1 row, it shows that row in a vertical table. Marking this true means a horizontal table is shown even if only one row is returned.'
    ],
    :messages => [
      'show — Show the contents of the table in the CLI.'
    ],
    :examples => <<~EXAMPLES.strip
      t [tbl] :
        on_load [script] :
          tell t to show
        headers [can] :
          name : Name
          phone : Tel
          notes : Notes
        data [alias] : table_data
      table_data [can] :
        1 [can] :
          name : Joe
          phone : 312-555-1212
          notes : Play golf with Joe
        2 [can] :
          name : Sally
          phone : 708-555-1212
          notes : met Sally at the meetup last week
        3 [can] :
          name : Frank
          phone : 312-555-1213
          notes : Frank Lee Speaking
    EXAMPLES
  }
end

.messagesObject

Get a list of message names that this object receives.



163
164
165
# File 'lib/table.rb', line 163

def self.messages
  return super + %w[show render]
end

.short_typenameObject

The short name of the object type.



28
29
30
# File 'lib/table.rb', line 28

def self.short_typename
  return KEYWORD_SHORT
end

.typenameObject

The name of the object type.



21
22
23
# File 'lib/table.rb', line 21

def self.typename
  return KEYWORD
end

Instance Method Details

#add_children_on_create?Boolean

Does this object have children to add when an object is created in interactive mode? This does not apply during obj load, etc.

Returns:

  • (Boolean)


140
141
142
# File 'lib/table.rb', line 140

def add_children_on_create?
  return true
end

#add_default_childrenObject

Add children to this object. This is used by containers to add children needed for default configurations.



149
150
151
152
153
# File 'lib/table.rb', line 149

def add_default_children
  fac = @engine.factory
  fac.create_can HEADERS, self
  fac.create_can DATA, self
end

#always_rowsObject

Always show rows, even if only 1 row is found.



46
47
48
49
50
51
# File 'lib/table.rb', line 46

def always_rows
  o = find_child ALWAYS_ROWS

  return false unless o
  return o.value
end

#build_columns(result_data) ⇒ Object

Build the column list based on the result data and the headers defined in the table object.



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/table.rb', line 228

def build_columns result_data
  head_children = find_child HEADERS
  cell_renderers = find_child CELLS

  columns = []
  return columns unless result_data
  
  result_data.each_with_index do |c,index|
    visible = true
    name = c
    title = c
    display_index = index

    if head_children
      child = head_children.find_child c
      if child
        title = child.value
        display_index = head_children.child_index( c )
      else
        visible = false
      end
    end

    cell_renderer = nil
    if cell_renderers
      this_cr = cell_renderers.find_child( c )
      cell_renderer = this_cr.value if this_cr
    end

    columns << { 
      name: name, 
      title: title, 
      visible: visible, 
      data_index: index,
      display_index: display_index,
      cell_renderer: cell_renderer
    }
  end
  return columns.sort_by { |hsh| hsh[ :display_index ] }
end

#cell_renderersObject

Get cell renderer hash keyed by column name.



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/table.rb', line 118

def cell_renderers
  h = {}
  o = find_child CELLS
  return h unless o

  o.children.each do |c|
    h[ c.name ] = c.value
  end

  return h
end

#columnsObject

Get the list of column names. Returns nil if there is none.



57
58
59
60
61
62
# File 'lib/table.rb', line 57

def columns
  o = find_child HEADERS
  return [] unless o

  return o.children.map( &:name )
end

#dataObject

Get the list of data elements.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/table.rb', line 67

def data
  o = find_child DATA
  return [] unless o
  
  o = Gloo::Objs::Alias.resolve_alias( @engine, o )
  return [] unless o
  
  if o.is_a? Query
    @engine.log.debug "Table getting data from query."
    begin
      result = o.run_query
      return result
    rescue => e
      @engine.log_exception e
      return nil
    end
  else
    cols = self.columns

    if o.children&.first.children.empty?
      # It is a simgle row table.
      rows = [ cols.map { |h| o.find_child( h )&.value } ]
    else
      rows = o.children.map do |e|
        cols.map { |h| e.find_child( h )&.value }
      end
    end

    return [ cols, rows ]
  end
end

#headersObject

Get the list of headers. Returns nil if there is none.



36
37
38
39
40
41
# File 'lib/table.rb', line 36

def headers
  o = find_child HEADERS
  return [] unless o

  return o.children.map( &:value )
end

#msg_renderObject



175
176
177
# File 'lib/table.rb', line 175

def msg_render
  return render
end

#msg_showObject

Show the table in the CLI.



170
171
172
173
# File 'lib/table.rb', line 170

def msg_show
  title = self.value
  @engine.platform.table.show headers, data[1], title
end

#render(render_ƒ) ⇒ Object

Render the table. The render_ƒ is 'render_html', 'render_text', 'render_json', etc.



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/table.rb', line 188

def render render_ƒ
  begin
    result = self.data
    head = self.headers 
    head = result[0] if head.empty?
    rows = result[1]

    columns = build_columns result[0]

    params = { 
      head: head, 
      cols: result[0],
      columns: columns,
      rows: rows,
      styles: self.styles,
      cell_renderers: self.cell_renderers
    }

    if self.always_rows
      params[ :always_rows ] = true
    end

    # helper = Gloo::WebSvr::TableRenderer.new( @engine )
    helper = @engine.running_app&.create_table_renderer
    if helper
      return helper.data_to_table params
    else
      @engine.log.error "Table renderer not found."
      return nil
    end
  rescue => e
    @engine.log_exception e
    return nil
  end
end

#stylesObject

Get the styles for the table, if any.



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/table.rb', line 102

def styles
  style_h = {} 
  o = find_child STYLES
  return style_h unless o
  o = Gloo::Objs::Alias.resolve_alias( @engine, o )

  o.children.each do |c|
    style_h[ c.name ] = c.value
  end

  return style_h
end