added frontend and changed design
This commit is contained in:
parent
2fea8b3600
commit
36c31c0240
|
@ -1,4 +1,10 @@
|
|||
import { __version__, logger, EventType, Direction, LogLevel } from './jsmind.common.js'
|
||||
import {
|
||||
__version__,
|
||||
logger,
|
||||
EventType,
|
||||
Direction,
|
||||
LogLevel,
|
||||
} from './jsmind.common.js'
|
||||
import { merge_option } from './jsmind.option.js'
|
||||
import { Mind } from './jsmind.mind.js'
|
||||
import { Node } from './jsmind.node.js'
|
||||
|
@ -6,7 +12,11 @@ import { DataProvider } from './jsmind.data_provider.js'
|
|||
import { LayoutProvider } from './jsmind.layout_provider.js'
|
||||
import { ViewProvider } from './jsmind.view_provider.js'
|
||||
import { ShortcutProvider } from './jsmind.shortcut_provider.js'
|
||||
import { Plugin, register as _register_plugin, apply as apply_plugins } from './jsmind.plugin.js'
|
||||
import {
|
||||
Plugin,
|
||||
register as _register_plugin,
|
||||
apply as apply_plugins,
|
||||
} from './jsmind.plugin.js'
|
||||
import { format } from './jsmind.format.js'
|
||||
import { $ } from './jsmind.dom.js'
|
||||
import { util as _util } from './jsmind.util.js'
|
||||
|
@ -48,7 +58,8 @@ export default class jsMind {
|
|||
container: this.options.container,
|
||||
support_html: this.options.support_html,
|
||||
engine: this.options.view.engine,
|
||||
enable_device_pixel_ratio: this.options.view.enable_device_pixel_ratio,
|
||||
enable_device_pixel_ratio:
|
||||
this.options.view.enable_device_pixel_ratio,
|
||||
hmargin: this.options.view.hmargin,
|
||||
vmargin: this.options.view.vmargin,
|
||||
line_width: this.options.view.line_width,
|
||||
|
@ -56,7 +67,8 @@ export default class jsMind {
|
|||
line_style: this.options.view.line_style,
|
||||
custom_line_render: this.options.view.custom_line_render,
|
||||
draggable: this.options.view.draggable,
|
||||
hide_scrollbars_when_draggable: this.options.view.hide_scrollbars_when_draggable,
|
||||
hide_scrollbars_when_draggable:
|
||||
this.options.view.hide_scrollbars_when_draggable,
|
||||
node_overflow: this.options.view.node_overflow,
|
||||
zoom: this.options.view.zoom,
|
||||
custom_node_render: this.options.view.custom_node_render,
|
||||
|
@ -99,11 +111,15 @@ export default class jsMind {
|
|||
}
|
||||
// options are 'mousedown', 'click', 'dblclick', 'mousewheel'
|
||||
enable_event_handle(event_handle) {
|
||||
this.options.default_event_handle['enable_' + event_handle + '_handle'] = true
|
||||
this.options.default_event_handle[
|
||||
'enable_' + event_handle + '_handle'
|
||||
] = true
|
||||
}
|
||||
// options are 'mousedown', 'click', 'dblclick', 'mousewheel'
|
||||
disable_event_handle(event_handle) {
|
||||
this.options.default_event_handle['enable_' + event_handle + '_handle'] = false
|
||||
this.options.default_event_handle[
|
||||
'enable_' + event_handle + '_handle'
|
||||
] = false
|
||||
}
|
||||
set_theme(theme) {
|
||||
var theme_old = this.options.theme
|
||||
|
@ -164,7 +180,10 @@ export default class jsMind {
|
|||
// Use [Ctrl] + Mousewheel, to zoom in/out.
|
||||
mousewheel_handle(e) {
|
||||
// Test if mousewheel option is enabled and Ctrl key is pressed.
|
||||
if (!this.options.default_event_handle['enable_mousewheel_handle'] || !e.ctrlKey) {
|
||||
if (
|
||||
!this.options.default_event_handle['enable_mousewheel_handle'] ||
|
||||
!e.ctrlKey
|
||||
) {
|
||||
return
|
||||
}
|
||||
var evt = e || event
|
||||
|
@ -318,9 +337,16 @@ export default class jsMind {
|
|||
var the_parent_node = this.get_node(parent_node)
|
||||
var dir = Direction.of(direction)
|
||||
if (dir === undefined) {
|
||||
dir = this.layout.calculate_next_child_direction(the_parent_node)
|
||||
dir =
|
||||
this.layout.calculate_next_child_direction(the_parent_node)
|
||||
}
|
||||
var node = this.mind.add_node(the_parent_node, node_id, topic, data, dir)
|
||||
var node = this.mind.add_node(
|
||||
the_parent_node,
|
||||
node_id,
|
||||
topic,
|
||||
data,
|
||||
dir
|
||||
)
|
||||
if (!!node) {
|
||||
this.view.add_node(node)
|
||||
this.layout.layout()
|
||||
|
@ -344,9 +370,17 @@ export default class jsMind {
|
|||
var the_node_before = this.get_node(node_before)
|
||||
var dir = Direction.of(direction)
|
||||
if (dir === undefined) {
|
||||
dir = this.layout.calculate_next_child_direction(the_node_before.parent)
|
||||
dir = this.layout.calculate_next_child_direction(
|
||||
the_node_before.parent
|
||||
)
|
||||
}
|
||||
var node = this.mind.insert_node_before(the_node_before, node_id, topic, data, dir)
|
||||
var node = this.mind.insert_node_before(
|
||||
the_node_before,
|
||||
node_id,
|
||||
topic,
|
||||
data,
|
||||
dir
|
||||
)
|
||||
if (!!node) {
|
||||
this.view.add_node(node)
|
||||
this.layout.layout()
|
||||
|
@ -368,9 +402,17 @@ export default class jsMind {
|
|||
var the_node_after = this.get_node(node_after)
|
||||
var dir = Direction.of(direction)
|
||||
if (dir === undefined) {
|
||||
dir = this.layout.calculate_next_child_direction(the_node_after.parent)
|
||||
dir = this.layout.calculate_next_child_direction(
|
||||
the_node_after.parent
|
||||
)
|
||||
}
|
||||
var node = this.mind.insert_node_after(the_node_after, node_id, topic, data, dir)
|
||||
var node = this.mind.insert_node_after(
|
||||
the_node_after,
|
||||
node_id,
|
||||
topic,
|
||||
data,
|
||||
dir
|
||||
)
|
||||
if (!!node) {
|
||||
this.view.add_node(node)
|
||||
this.layout.layout()
|
||||
|
@ -453,7 +495,12 @@ export default class jsMind {
|
|||
move_node(node_id, before_id, parent_id, direction) {
|
||||
if (this.get_editable()) {
|
||||
var node = this.get_node(node_id)
|
||||
var updated_node = this.mind.move_node(node, before_id, parent_id, direction)
|
||||
var updated_node = this.mind.move_node(
|
||||
node,
|
||||
before_id,
|
||||
parent_id,
|
||||
direction
|
||||
)
|
||||
if (!!updated_node) {
|
||||
this.view.update_node(updated_node)
|
||||
this.layout.layout()
|
||||
|
@ -484,7 +531,11 @@ export default class jsMind {
|
|||
}
|
||||
this.mind.selected = node
|
||||
this.view.select_node(node)
|
||||
this.invoke_event_handle(EventType.select, { evt: 'select_node', data: [], node: node.id })
|
||||
this.invoke_event_handle(EventType.select, {
|
||||
evt: 'select_node',
|
||||
data: [],
|
||||
node: node.id,
|
||||
})
|
||||
}
|
||||
get_selected_node() {
|
||||
if (!!this.mind) {
|
||||
|
|
|
@ -44,14 +44,21 @@ Mind.prototype.add_node = function (
|
|||
parent_node,
|
||||
node_id,
|
||||
topic,
|
||||
data = {},
|
||||
data = undefined,
|
||||
direction,
|
||||
expanded,
|
||||
idx
|
||||
) {
|
||||
for (let style of ['leading-line-color', 'background-color', 'foreground-color']) {
|
||||
if (parent_node.data?.[style]) {
|
||||
data[style] = parent_node.data[style]
|
||||
if (data == undefined) {
|
||||
data = {}
|
||||
for (let style of [
|
||||
'leading-line-color',
|
||||
'background-color',
|
||||
'foreground-color',
|
||||
]) {
|
||||
if (data[style] == undefined && parent_node.data?.[style]) {
|
||||
data[style] = parent_node.data[style]
|
||||
}
|
||||
}
|
||||
}
|
||||
arguments[3] = data
|
||||
|
|
|
@ -1,13 +1,29 @@
|
|||
class Admin::MindMapsController < OrbitAdminController
|
||||
def landing_page
|
||||
table = UTable.find(params[:id])
|
||||
if table.mind_map.nil?
|
||||
@mind_map = MindMap.new
|
||||
@mind_map.u_table = table
|
||||
@mind_map.save
|
||||
else
|
||||
@mind_map = table.mind_map
|
||||
end
|
||||
|
||||
def index
|
||||
@table_fields = ["universal_table.mind_map","universal_table.created_time"]
|
||||
@table = UTable.find(params[:id])
|
||||
@mind_maps = Kaminari.paginate_array(@table.mind_maps).page(params[:page]).per(10)
|
||||
end
|
||||
|
||||
def new
|
||||
@table = UTable.find(params[:table])
|
||||
@mind_map = MindMap.new
|
||||
end
|
||||
|
||||
def edit
|
||||
uid = params[:id].split("-").last
|
||||
@mind_map = MindMap.where(:uid => uid).first
|
||||
@table = @mind_map.u_table
|
||||
end
|
||||
|
||||
def create
|
||||
mind_map = MindMap.new
|
||||
mind_params = mind_map_params
|
||||
mind_params[:mind_map_data] = JSON.parse(mind_params[:mind_map_data])
|
||||
mind_map.update_attributes(mind_map_params)
|
||||
mind_map.save
|
||||
redirect_to "/admin/universal_table/#{mind_map.u_table.id.to_s}/mind_maps"
|
||||
end
|
||||
|
||||
def update
|
||||
|
@ -16,9 +32,17 @@ class Admin::MindMapsController < OrbitAdminController
|
|||
mind_params[:mind_map_data] = JSON.parse(mind_params[:mind_map_data])
|
||||
mind_map.update_attributes(mind_map_params)
|
||||
mind_map.save
|
||||
redirect_to admin_universal_tables_path
|
||||
redirect_to "/admin/universal_table/#{mind_map.u_table.id.to_s}/mind_maps"
|
||||
end
|
||||
|
||||
def destroy
|
||||
uid = params[:id].split("-").last
|
||||
mind_map = MindMap.where(:uid => uid).first
|
||||
table = mind_map.u_table
|
||||
mind_map.destroy
|
||||
redirect_to "/admin/universal_table/#{table.id.to_s}/mind_maps"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mind_map_params
|
||||
|
|
|
@ -1,180 +1,13 @@
|
|||
class UniversalTablesController < ApplicationController
|
||||
include Admin::UniversalTablesHelper
|
||||
FrontendMethods = ["mind_map"]
|
||||
def index
|
||||
params = OrbitHelper.params
|
||||
table = UTable.where(:category_id => OrbitHelper.page_categories.first).first rescue nil
|
||||
page = OrbitHelper.page rescue Page.where(:page_id => params[:page_id]).first
|
||||
searchable_columns = []
|
||||
if !table.nil?
|
||||
reset = "hide"
|
||||
csrf_value = (0...46).map { ('a'..'z').to_a[rand(26)] }.join
|
||||
params_q = params["q"].to_h.each{|_, v| v.gsub!("\"", '')} rescue {}
|
||||
params_no = params["page_no"].to_s.gsub("\"",'')
|
||||
if params_q.present?
|
||||
query_string = '&' + params_q.map{|k, v| ["q[#{k}]",v]}.to_h.to_query
|
||||
else
|
||||
query_string = ''
|
||||
end
|
||||
query_string += "&page_no=#{params_no}" if params_no.present?
|
||||
# csrf_input = "<input type=\"hidden\" name=\"authenticity_token\" value=\"#{csrf_value}\">"
|
||||
csrf_input = ""
|
||||
have_serial_number = (page.layout != 'index1')
|
||||
table_heads = table.table_columns.where(:display_in_index => true).asc(:order).collect do |tc|
|
||||
field_key = tc.key
|
||||
field_value = params_q[field_key]
|
||||
field_value = nil if field_value.blank?
|
||||
search = ""
|
||||
sort_class = "sort"
|
||||
sort = ""
|
||||
form_field = "#{csrf_input}<input type=\"search\" class=\"form-control\" name=\"q[#{field_key}]\" value=\"#{field_value}\" placeholder=\"Search keyword\">"
|
||||
sort_url = "/#{I18n.locale.to_s}#{page.url}?sortcolumn=#{field_key}&sort=asc#{query_string}"
|
||||
title_class = ""
|
||||
case tc.type
|
||||
when "date"
|
||||
search = "hide"
|
||||
when "period","image"
|
||||
sort_class = "sort hide"
|
||||
search = "hide"
|
||||
sort_url = "#"
|
||||
sort = "hide"
|
||||
when "editor"
|
||||
sort_url = "#"
|
||||
sort = "hide"
|
||||
sort_class = "sort hide"
|
||||
when "text"
|
||||
if tc.make_categorizable
|
||||
select_values = tc.column_entries.distinct("text.#{I18n.locale.to_s}")
|
||||
form_field = "#{csrf_input}<select class=\"form-control\" name=\"q[#{field_key}]\">"
|
||||
if field_value.nil?
|
||||
select_values.insert(0, "")
|
||||
end
|
||||
select_values.each do |sv|
|
||||
if field_value && sv == field_value
|
||||
selected = " selected"
|
||||
else
|
||||
selected = ""
|
||||
end
|
||||
form_field += "<option value=\"#{sv}\"#{selected}>#{sv}</option>"
|
||||
end
|
||||
form_field += "</select>"
|
||||
end
|
||||
when "integer"
|
||||
if tc.make_categorizable
|
||||
select_values = tc.column_entries.distinct(:number)
|
||||
form_field = "#{csrf_input}<select class=\"form-control\" name=\"q[#{field_key}]\">"
|
||||
if field_value.nil?
|
||||
select_values.insert(0, "")
|
||||
end
|
||||
select_values.each do |sv|
|
||||
if field_value && sv == field_value
|
||||
selected = " selected"
|
||||
else
|
||||
selected = ""
|
||||
end
|
||||
form_field += "<option value=\"#{sv}\"#{selected}>#{sv}</option>"
|
||||
end
|
||||
form_field += "</select>"
|
||||
end
|
||||
end
|
||||
|
||||
if params["sortcolumn"] == field_key
|
||||
sort_class = params["sort"] == "asc" ? "sort-desc" : "sort-asc"
|
||||
sort_url = "/#{I18n.locale.to_s}#{page.url}?sortcolumn=#{field_key}&sort=#{params["sort"] == "asc" ? "desc" : "asc"}#{query_string}"
|
||||
end
|
||||
|
||||
title_class = title_class + "no-sort" if sort == "sort"
|
||||
title_class = title_class + " no-search" if search == "hide"
|
||||
|
||||
col_class = 'col-md-4 col-xs-12'
|
||||
|
||||
col = {
|
||||
"title" => tc.title,
|
||||
"type" => tc.type,
|
||||
"key" => field_key,
|
||||
"search" => search,
|
||||
"form-field" => form_field,
|
||||
"sort" => sort,
|
||||
"sort-class" => sort_class,
|
||||
"sort-url" => sort_url,
|
||||
"title-class" => title_class,
|
||||
"col-class" => col_class
|
||||
}
|
||||
if tc.is_searchable
|
||||
searchable_columns << col
|
||||
end
|
||||
col
|
||||
end
|
||||
tablecolumns = table.table_columns.where(:display_in_index => true).asc(:order)
|
||||
rows = []
|
||||
entries = get_entries(params, table, page)
|
||||
total_pages = entries.total_pages
|
||||
if have_serial_number
|
||||
page_no_offset = (params_no.present? ? [0, params_no.to_i - 1].max : 0)
|
||||
serial_number_count = page_no_offset * OrbitHelper.page_data_count
|
||||
table_heads.insert(0, {
|
||||
"title" => "No.",
|
||||
"type" => "",
|
||||
"key" => "",
|
||||
"search" => "hide",
|
||||
"form-field" => "",
|
||||
"sort" => "hide",
|
||||
"sort-class" => "sort hide",
|
||||
"sort-url" => "",
|
||||
"title-class" => " no-search"
|
||||
})
|
||||
end
|
||||
entries.each do |te|
|
||||
cols = []
|
||||
sort_value = ""
|
||||
if have_serial_number
|
||||
serial_number_count += 1
|
||||
cols << {"text" => serial_number_count.to_s}
|
||||
end
|
||||
tablecolumns.each do |column|
|
||||
ce = te.column_entries.where(:table_column_id => column.id).first rescue nil
|
||||
if !ce.nil?
|
||||
text = ce.get_frontend_text(column)
|
||||
if column.is_link_to_show
|
||||
text = "<a href='#{OrbitHelper.url_to_show("-" + te.uid)}'>#{text}</a>"
|
||||
end
|
||||
|
||||
cols << {"text" => text}
|
||||
else
|
||||
cols << {"text" => ""}
|
||||
end
|
||||
end
|
||||
rows << {
|
||||
"columns" => cols
|
||||
}
|
||||
end
|
||||
if params[:layout_type] == "mindmap"
|
||||
index_mind_maps
|
||||
else
|
||||
index_entries
|
||||
end
|
||||
export_button = ""
|
||||
if get_query(params).present?
|
||||
reset = ""
|
||||
if !OrbitHelper.current_user.nil?
|
||||
p = {}
|
||||
params.each do |k,v|
|
||||
p[k] = v if ["q","column","sort","sortcolumn"].include?(k)
|
||||
end
|
||||
export_button = "<a href='/xhr/universal_table/export.xlsx?cat=#{OrbitHelper.page_categories.first}&page_id=#{page.page_id}&#{p.to_param}'>Export</a>"
|
||||
end
|
||||
total_entries = t("universal_table.total_number_of_entries", :total_number => entries.total_count)
|
||||
elsif params["sortcolumn"].present?
|
||||
reset = ""
|
||||
end
|
||||
{
|
||||
"searchable-columns" => searchable_columns,
|
||||
"head-columns" => table_heads,
|
||||
"rows" => rows,
|
||||
"total_pages" => total_pages,
|
||||
"extras" => {
|
||||
"total_entries" => total_entries,
|
||||
"table-name" => table.title,
|
||||
"export_button" => export_button,
|
||||
"reset" => reset,
|
||||
"url" => "/#{I18n.locale.to_s}#{page.url}"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def export_filtered
|
||||
|
@ -352,7 +185,210 @@ class UniversalTablesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def mind_map
|
||||
def index_entries
|
||||
params = OrbitHelper.params
|
||||
table = UTable.where(:category_id => OrbitHelper.page_categories.first).first rescue nil
|
||||
page = OrbitHelper.page rescue Page.where(:page_id => params[:page_id]).first
|
||||
searchable_columns = []
|
||||
if !table.nil?
|
||||
reset = "hide"
|
||||
csrf_value = (0...46).map { ('a'..'z').to_a[rand(26)] }.join
|
||||
params_q = params["q"].to_h.each{|_, v| v.gsub!("\"", '')} rescue {}
|
||||
params_no = params["page_no"].to_s.gsub("\"",'')
|
||||
if params_q.present?
|
||||
query_string = '&' + params_q.map{|k, v| ["q[#{k}]",v]}.to_h.to_query
|
||||
else
|
||||
query_string = ''
|
||||
end
|
||||
query_string += "&page_no=#{params_no}" if params_no.present?
|
||||
# csrf_input = "<input type=\"hidden\" name=\"authenticity_token\" value=\"#{csrf_value}\">"
|
||||
csrf_input = ""
|
||||
have_serial_number = (page.layout != 'index1')
|
||||
table_heads = table.table_columns.where(:display_in_index => true).asc(:order).collect do |tc|
|
||||
field_key = tc.key
|
||||
field_value = params_q[field_key]
|
||||
field_value = nil if field_value.blank?
|
||||
search = ""
|
||||
sort_class = "sort"
|
||||
sort = ""
|
||||
form_field = "#{csrf_input}<input type=\"search\" class=\"form-control\" name=\"q[#{field_key}]\" value=\"#{field_value}\" placeholder=\"Search keyword\">"
|
||||
sort_url = "/#{I18n.locale.to_s}#{page.url}?sortcolumn=#{field_key}&sort=asc#{query_string}"
|
||||
title_class = ""
|
||||
case tc.type
|
||||
when "date"
|
||||
search = "hide"
|
||||
when "period","image"
|
||||
sort_class = "sort hide"
|
||||
search = "hide"
|
||||
sort_url = "#"
|
||||
sort = "hide"
|
||||
when "editor"
|
||||
sort_url = "#"
|
||||
sort = "hide"
|
||||
sort_class = "sort hide"
|
||||
when "text"
|
||||
if tc.make_categorizable
|
||||
select_values = tc.column_entries.distinct("text.#{I18n.locale.to_s}")
|
||||
form_field = "#{csrf_input}<select class=\"form-control\" name=\"q[#{field_key}]\">"
|
||||
if field_value.nil?
|
||||
select_values.insert(0, "")
|
||||
end
|
||||
select_values.each do |sv|
|
||||
if field_value && sv == field_value
|
||||
selected = " selected"
|
||||
else
|
||||
selected = ""
|
||||
end
|
||||
form_field += "<option value=\"#{sv}\"#{selected}>#{sv}</option>"
|
||||
end
|
||||
form_field += "</select>"
|
||||
end
|
||||
when "integer"
|
||||
if tc.make_categorizable
|
||||
select_values = tc.column_entries.distinct(:number)
|
||||
form_field = "#{csrf_input}<select class=\"form-control\" name=\"q[#{field_key}]\">"
|
||||
if field_value.nil?
|
||||
select_values.insert(0, "")
|
||||
end
|
||||
select_values.each do |sv|
|
||||
if field_value && sv == field_value
|
||||
selected = " selected"
|
||||
else
|
||||
selected = ""
|
||||
end
|
||||
form_field += "<option value=\"#{sv}\"#{selected}>#{sv}</option>"
|
||||
end
|
||||
form_field += "</select>"
|
||||
end
|
||||
end
|
||||
|
||||
if params["sortcolumn"] == field_key
|
||||
sort_class = params["sort"] == "asc" ? "sort-desc" : "sort-asc"
|
||||
sort_url = "/#{I18n.locale.to_s}#{page.url}?sortcolumn=#{field_key}&sort=#{params["sort"] == "asc" ? "desc" : "asc"}#{query_string}"
|
||||
end
|
||||
|
||||
title_class = title_class + "no-sort" if sort == "sort"
|
||||
title_class = title_class + " no-search" if search == "hide"
|
||||
|
||||
col_class = 'col-md-4 col-xs-12'
|
||||
|
||||
col = {
|
||||
"title" => tc.title,
|
||||
"type" => tc.type,
|
||||
"key" => field_key,
|
||||
"search" => search,
|
||||
"form-field" => form_field,
|
||||
"sort" => sort,
|
||||
"sort-class" => sort_class,
|
||||
"sort-url" => sort_url,
|
||||
"title-class" => title_class,
|
||||
"col-class" => col_class
|
||||
}
|
||||
if tc.is_searchable
|
||||
searchable_columns << col
|
||||
end
|
||||
col
|
||||
end
|
||||
tablecolumns = table.table_columns.where(:display_in_index => true).asc(:order)
|
||||
rows = []
|
||||
entries = get_entries(params, table, page)
|
||||
total_pages = entries.total_pages
|
||||
if have_serial_number
|
||||
page_no_offset = (params_no.present? ? [0, params_no.to_i - 1].max : 0)
|
||||
serial_number_count = page_no_offset * OrbitHelper.page_data_count
|
||||
table_heads.insert(0, {
|
||||
"title" => "No.",
|
||||
"type" => "",
|
||||
"key" => "",
|
||||
"search" => "hide",
|
||||
"form-field" => "",
|
||||
"sort" => "hide",
|
||||
"sort-class" => "sort hide",
|
||||
"sort-url" => "",
|
||||
"title-class" => " no-search"
|
||||
})
|
||||
end
|
||||
entries.each do |te|
|
||||
cols = []
|
||||
sort_value = ""
|
||||
if have_serial_number
|
||||
serial_number_count += 1
|
||||
cols << {"text" => serial_number_count.to_s}
|
||||
end
|
||||
tablecolumns.each do |column|
|
||||
ce = te.column_entries.where(:table_column_id => column.id).first rescue nil
|
||||
if !ce.nil?
|
||||
text = ce.get_frontend_text(column)
|
||||
if column.is_link_to_show
|
||||
text = "<a href='#{OrbitHelper.url_to_show("-" + te.uid)}'>#{text}</a>"
|
||||
end
|
||||
|
||||
cols << {"text" => text}
|
||||
else
|
||||
cols << {"text" => ""}
|
||||
end
|
||||
end
|
||||
rows << {
|
||||
"columns" => cols
|
||||
}
|
||||
end
|
||||
end
|
||||
export_button = ""
|
||||
if get_query(params).present?
|
||||
reset = ""
|
||||
if !OrbitHelper.current_user.nil?
|
||||
p = {}
|
||||
params.each do |k,v|
|
||||
p[k] = v if ["q","column","sort","sortcolumn"].include?(k)
|
||||
end
|
||||
export_button = "<a href='/xhr/universal_table/export.xlsx?cat=#{OrbitHelper.page_categories.first}&page_id=#{page.page_id}&#{p.to_param}'>Export</a>"
|
||||
end
|
||||
total_entries = t("universal_table.total_number_of_entries", :total_number => entries.total_count)
|
||||
elsif params["sortcolumn"].present?
|
||||
reset = ""
|
||||
end
|
||||
{
|
||||
"searchable-columns" => searchable_columns,
|
||||
"head-columns" => table_heads,
|
||||
"rows" => rows,
|
||||
"total_pages" => total_pages,
|
||||
"extras" => {
|
||||
"total_entries" => total_entries,
|
||||
"table-name" => table.title,
|
||||
"export_button" => export_button,
|
||||
"reset" => reset,
|
||||
"url" => "/#{I18n.locale.to_s}#{page.url}"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def index_mind_maps
|
||||
params = OrbitHelper.params
|
||||
table = UTable.where(:category_id => OrbitHelper.page_categories.first).first rescue nil
|
||||
page = OrbitHelper.page rescue Page.where(:page_id => params[:page_id]).first
|
||||
mindmaps = []
|
||||
mms = Kaminari.paginate_array(table.mind_maps).page(params["page_no"]).per(OrbitHelper.page_data_count)
|
||||
mms.each do |mindmap|
|
||||
mindmaps << {
|
||||
"title" => mindmap.title,
|
||||
"url" => OrbitHelper.url_to_show("-" + mindmap.uid) + "?method=mind_map"
|
||||
}
|
||||
end
|
||||
{
|
||||
"mindmaps" => mindmaps,
|
||||
"total_pages" => mms.total_pages,
|
||||
"extras" => {
|
||||
"table-name" => table.title
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def mind_map
|
||||
params = OrbitHelper.params
|
||||
mindmap = MindMap.where(:uid => params["uid"]).first
|
||||
{
|
||||
"title" => mindmap.title,
|
||||
"mind_map_data" => mindmap.mind_map_data
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
class MindMapNode
|
||||
include Mongoid::Document
|
||||
include Mongoid::Timestamps
|
||||
|
||||
field :node_id
|
||||
field :parent_node_id
|
||||
field :text, type: String
|
||||
field :expanded, type: Boolean
|
||||
field :background_color, type: String
|
||||
field :foreground_color, type: String
|
||||
field :leading_line_color, type: String
|
||||
field :link, type: String
|
||||
|
||||
belongs_to :mind_map
|
||||
end
|
|
@ -14,7 +14,7 @@ class UTable
|
|||
|
||||
has_many :table_columns, :dependent => :destroy
|
||||
has_many :table_entries, :dependent => :destroy
|
||||
has_one :mind_map, :dependent => :destroy
|
||||
has_many :mind_maps, :dependent => :destroy
|
||||
|
||||
accepts_nested_attributes_for :table_columns, :allow_destroy => true
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<fieldset class="utable-heading-wrap">
|
||||
<div class="utable-heading-header">
|
||||
<h4><%= t("universal_table.table_name") %> - <%= @mind_map.u_table.title %></h4>
|
||||
<h4><%= t("universal_table.table_name") %> - <%= @table.title %></h4>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
|
@ -38,7 +38,8 @@
|
|||
</fieldset>
|
||||
<fieldset class="utable-content">
|
||||
<div class="form-actions">
|
||||
<%= f.hidden_field :mind_map_data, id: "mind_map_data_field", value: "" %>
|
||||
<%= f.hidden_field :mind_map_data, id: "mind_map_data_field", value: "[]" %>
|
||||
<%= f.hidden_field :u_table_id, value: @table.id %>
|
||||
<input class="btn btn-primary pull-right" name="commit" type="submit" value="<%= t("save") %>">
|
||||
</div>
|
||||
</fieldset>
|
|
@ -0,0 +1,33 @@
|
|||
<table class="table main-list">
|
||||
<thead>
|
||||
<tr class="sort-header">
|
||||
<% @table_fields.each do |f| %>
|
||||
<%= thead(f) %>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @mind_maps.each do |mindmap| %>
|
||||
<tr id="mindmap_<%= mindmap.id.to_s %>">
|
||||
<td>
|
||||
<a href="<%= admin_mind_map_path(mindmap) %>"><%= mindmap.title %></a>
|
||||
<div class="quick-edit">
|
||||
<ul class="nav nav-pills">
|
||||
<li><a href="<%= edit_admin_mind_map_path(mindmap) %>"><%= t(:edit) %></a></li>
|
||||
<li><a href="<%= admin_mind_map_path(mindmap) %>" class="delete text-error" data-method="delete" data-confirm="Are you sure?"><%= t(:delete_) %></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<%= mindmap.created_at.strftime("%Y-%m-%d") %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<%=
|
||||
content_tag :div, class: "bottomnav clearfix" do
|
||||
content_tag(:div, paginate(@mind_maps), class: "pagination pagination-centered") +
|
||||
content_tag(:div, link_to(t(:new_),new_admin_mind_map_path(:table => @table.id.to_s), :class=>"btn btn-primary"), class: "pull-right")
|
||||
end
|
||||
%>
|
|
@ -21,15 +21,11 @@
|
|||
|
||||
// 心智圖初始數據
|
||||
// Initial mind map data
|
||||
<% if @mind_map.mind_map_data.empty? %>
|
||||
let mind = INITIAL_MIND
|
||||
<% else %>
|
||||
let mind = {
|
||||
meta: {},
|
||||
format: 'node_array',
|
||||
data: <%= raw @mind_map.mind_map_data.to_json %>
|
||||
}
|
||||
<% end %>
|
||||
|
||||
// 心智圖自訂選項(可參考 jsmind 官方文檔)
|
||||
// Custom options for the mind map (refer to the jsmind official documentation)
|
||||
|
@ -38,7 +34,7 @@
|
|||
editable: isEditable,
|
||||
theme: 'primary',
|
||||
mode: 'full',
|
||||
tableUID: '<%= @mind_map.u_table.uid %>',
|
||||
tableUID: '<%= @table.uid %>',
|
||||
text: {
|
||||
addNode: "<%= t("universal_table.add_node") %>",
|
||||
deleteNode: "<%= t("universal_table.delete_node") %>",
|
|
@ -0,0 +1,6 @@
|
|||
<% content_for :page_specific_javascript do %>
|
||||
<%= javascript_include_tag "lib/jquery.form" %>
|
||||
<% end %>
|
||||
<div id="index_table">
|
||||
<%= render 'index'%>
|
||||
</div>
|
|
@ -0,0 +1,89 @@
|
|||
<% content_for :page_specific_css do %>
|
||||
<%= stylesheet_link_tag "universal_table/universal-table" %>
|
||||
<%= stylesheet_link_tag "mind_map/mindmap" %>
|
||||
<% end %>
|
||||
<%= form_for @mind_map, url: admin_mind_maps_path, html: {class: "form-horizontal main-forms", id: "mind_map_form"} do |f| %>
|
||||
<%= render :partial => "form", locals: {f: f} %>
|
||||
<% end %>
|
||||
<script type="module">
|
||||
import '/assets/mind_map/utils/custom.overrides.js'
|
||||
import '/assets/mind_map/jsmind/plugins/jsmind.draggable-node.js'
|
||||
import { initJsmind, getJsmindData } from '/assets/mind_map/utils/custom.main.js'
|
||||
import { INITIAL_MIND } from '/assets/mind_map/utils/custom.config.js'
|
||||
|
||||
// 操控心智圖是否可編輯
|
||||
// Control whether the mind map is editable
|
||||
let isEditable = true
|
||||
|
||||
// 心智圖實例
|
||||
// Mind map instance
|
||||
let jm
|
||||
|
||||
// 心智圖初始數據
|
||||
// Initial mind map data
|
||||
let mind = INITIAL_MIND
|
||||
|
||||
// 心智圖自訂選項(可參考 jsmind 官方文檔)
|
||||
// Custom options for the mind map (refer to the jsmind official documentation)
|
||||
const options = {
|
||||
container: 'jsmind_container',
|
||||
editable: isEditable,
|
||||
theme: 'primary',
|
||||
mode: 'full',
|
||||
tableUID: '<%= @table.uid %>',
|
||||
text: {
|
||||
addNode: "<%= t("universal_table.add_node") %>",
|
||||
deleteNode: "<%= t("universal_table.delete_node") %>",
|
||||
strokeColor: "<%= t("universal_table.stroke_color") %>",
|
||||
bgColor: "<%= t("universal_table.bg_color") %>",
|
||||
textColor: "<%= t("universal_table.text_color") %>"
|
||||
},
|
||||
view: {
|
||||
engine: 'svg',
|
||||
draggable: true,
|
||||
node_overflow: 'wrap',
|
||||
},
|
||||
shortcut: {
|
||||
mapping: {
|
||||
// 避免與 Toolbar 按下 Enter 事件衝突
|
||||
// Avoid conflicts with the Enter key event in the Toolbar
|
||||
addbrother: 2048 + 13,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 初始化心智圖並掛載實例
|
||||
// Initialize the mind map and attach the instance
|
||||
jm = initJsmind(mind, options, isEditable)
|
||||
|
||||
// 儲存當前數據
|
||||
// Save the current data
|
||||
// document.getElementById('save_mind_map').addEventListener('click', (e) => {
|
||||
// e.preventDefault();
|
||||
// e.stopPropagation();
|
||||
// let data = getJsmindData(jm);
|
||||
// console.log(data);
|
||||
// })
|
||||
|
||||
// 調整可編輯狀態
|
||||
// Toggle the editable state
|
||||
document.getElementById('toggle_editable').addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
isEditable = !isEditable;
|
||||
e.target.innerHTML = isEditable ? '<%= t("universal_table.disable_editing") %>' : '<%= t("universal_table.enable_editing") %>';
|
||||
|
||||
mind = getJsmindData(jm);
|
||||
jm = initJsmind(mind, options, isEditable);
|
||||
return false;
|
||||
})
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const form = document.getElementById("mind_map_form");
|
||||
const hiddenField = document.getElementById("mind_map_data_field");
|
||||
form.addEventListener("submit", function (e) {
|
||||
const mindMapData = getJsmindData(jm);
|
||||
console.log(mindMapData);
|
||||
hiddenField.value = JSON.stringify(mindMapData.data);
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -16,7 +16,7 @@
|
|||
<ul class="nav nav-pills">
|
||||
<% if can_edit %>
|
||||
<li><a href="<%= edit_admin_universal_table_path(table) %>"><%= t(:edit) %></a></li>
|
||||
<li><a href="<%= "/admin/universal_table/#{table.id.to_s}/mind_map" %>"><%= t("universal_table.mind_map") %></a></li>
|
||||
<li><a href="<%= "/admin/universal_table/#{table.id.to_s}/mind_maps" %>"><%= t("universal_table.mind_map") %></a></li>
|
||||
<% if table.ordered_with_sort_number %>
|
||||
<li><a href="<%= admin_universal_table_edit_sort_path(table) %>"><%= t('universal_table.edit_sort') %></a></li>
|
||||
<% end %>
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<%
|
||||
data = action_data
|
||||
OrbitHelper.render_css_in_head(["mind_map/mindmap"])
|
||||
%>
|
||||
|
||||
<h2><%= data["title"] %></h2>
|
||||
<div id="jsmind_container"></div>
|
||||
<script type="module">
|
||||
import '/assets/mind_map/utils/custom.overrides.js'
|
||||
import '/assets/mind_map/jsmind/plugins/jsmind.draggable-node.js'
|
||||
import { initJsmind, getJsmindData } from '/assets/mind_map/utils/custom.main.js'
|
||||
import { INITIAL_MIND } from '/assets/mind_map/utils/custom.config.js'
|
||||
|
||||
// 操控心智圖是否可編輯
|
||||
// Control whether the mind map is editable
|
||||
let isEditable = false
|
||||
|
||||
// 心智圖實例
|
||||
// Mind map instance
|
||||
let jm
|
||||
|
||||
// 心智圖初始數據
|
||||
// Initial mind map data
|
||||
let mind = {
|
||||
meta: {},
|
||||
format: 'node_array',
|
||||
data: <%= raw data["mind_map_data"].to_json %>
|
||||
}
|
||||
|
||||
// 心智圖自訂選項(可參考 jsmind 官方文檔)
|
||||
// Custom options for the mind map (refer to the jsmind official documentation)
|
||||
const options = {
|
||||
container: 'jsmind_container',
|
||||
editable: isEditable,
|
||||
theme: 'primary',
|
||||
mode: 'full',
|
||||
tableUID: '',
|
||||
text: {
|
||||
addNode: "<%= t("universal_table.add_node") %>",
|
||||
deleteNode: "<%= t("universal_table.delete_node") %>",
|
||||
strokeColor: "<%= t("universal_table.stroke_color") %>",
|
||||
bgColor: "<%= t("universal_table.bg_color") %>",
|
||||
textColor: "<%= t("universal_table.text_color") %>"
|
||||
},
|
||||
view: {
|
||||
engine: 'svg',
|
||||
draggable: true,
|
||||
node_overflow: 'wrap',
|
||||
},
|
||||
shortcut: {
|
||||
mapping: {
|
||||
// 避免與 Toolbar 按下 Enter 事件衝突
|
||||
// Avoid conflicts with the Enter key event in the Toolbar
|
||||
addbrother: 2048 + 13,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 初始化心智圖並掛載實例
|
||||
// Initialize the mind map and attach the instance
|
||||
jm = initJsmind(mind, options, isEditable)
|
||||
|
||||
</script>
|
|
@ -22,7 +22,7 @@ Rails.application.routes.draw do
|
|||
patch "/universal_tables/update_entry", to: 'universal_tables#update_entry'
|
||||
post "/universal_tables/import_data_from_excel", to: 'universal_tables#import_data_from_excel'
|
||||
get "universal_tables/checkforthread", to: "universal_tables#checkforthread"
|
||||
get "/universal_table/:id/mind_map", to: "mind_maps#landing_page"
|
||||
get "/universal_table/:id/mind_maps", to: "mind_maps#index"
|
||||
resources :universal_tables do
|
||||
get "new_entry"
|
||||
delete "delete_entry"
|
||||
|
|
|
@ -24,6 +24,14 @@
|
|||
},
|
||||
"thumbnail" : "thumb.png",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"filename" : "mindmap",
|
||||
"name" : {
|
||||
"zh_tw" : "6. Mind Maps",
|
||||
"en" : "6. Mind Maps"
|
||||
},
|
||||
"thumbnail" : "thumb.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
<style>
|
||||
tr>th:first-child{
|
||||
display: none!important;
|
||||
}
|
||||
/* tr>td:first-child{
|
||||
display: none!important;
|
||||
} */
|
||||
.universal-table-index3{
|
||||
table-layout: auto!important;
|
||||
}
|
||||
.universal-dropdown-menu {
|
||||
padding: 15px 18px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.universal-th-text{
|
||||
white-space: pre!important;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
white-space: normal;
|
||||
}
|
||||
.universal-dropdown-menu {
|
||||
padding: 15px 18px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.universal-th-text {
|
||||
padding: 8px 0 0 0;
|
||||
display: inline;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.universal-dropdown {
|
||||
display: inline-block;
|
||||
}
|
||||
a.universal-btn {
|
||||
vertical-align: baseline;
|
||||
color: #fff;
|
||||
}
|
||||
.universal-table-index {
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #eee;
|
||||
table-layout: fixed;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.universal-table-index h3 {
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
.universal-table-index.table td{
|
||||
padding: 15px 18px;
|
||||
}
|
||||
.universal-table-index thead th:last-child .dropdown-menu {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
/* .universal-table-index tbody {
|
||||
counter-reset: item;
|
||||
} */
|
||||
.universal-th-icon {
|
||||
border: 1px solid #eee;
|
||||
padding: 5px 8px;
|
||||
margin-right: 5px;
|
||||
color: gray;
|
||||
cursor: pointer;
|
||||
}
|
||||
.universal-th-text.no-sort.no-search {
|
||||
position: relative;
|
||||
top: -6px;
|
||||
}
|
||||
.image-preview {
|
||||
width: 120px;
|
||||
}
|
||||
</style>
|
||||
<form class="form-inline universal-form-inline universal-form-inline5" action="{{url}}" method="get">
|
||||
<table class="table table-hover table-striped universal-table-index universal-table-index3">
|
||||
<caption>
|
||||
<h3>{{table-name}}</h3>
|
||||
</caption>
|
||||
<tbody>
|
||||
<tr class="tdken" data-level="0" data-list="mindmaps">
|
||||
<td><a href="{{url}}">{{title}}</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
{{pagination_goes_here}}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
$('.tdken>td:nth-child(4)').prepend($('.col-ken:nth-child(4)>.universal-th-text '));
|
||||
$('.tdken>td:nth-child(3)').prepend($('.col-ken:nth-child(3)>.universal-th-text '));
|
||||
$(".universal-th-text").append(" :");
|
||||
$(".tdken").append('<i class="fa-solid fa-thumbtack"></i>');
|
||||
});
|
||||
// $(document).ready(function(){
|
||||
// $("tr>th:first-child").removeClass("col-md-3");
|
||||
// $("tr>th:first-child").addClass("col-md-1");
|
||||
// $("tr>th:nth-child(2)").removeClass("col-md-3");
|
||||
// $("tr>th:nth-child(2)").addClass("col-md-6");
|
||||
// $("tr>th:nth-child(3)").removeClass("col-md-3");
|
||||
// $("tr>th:nth-child(3)").addClass("col-md-3");
|
||||
// $("tr>th:nth-child(4)").removeClass("col-md-3");
|
||||
// $("tr>th:nth-child(4)").addClass("col-md-2");
|
||||
// $("tr>th:nth-child(5)").removeClass("col-md-3");
|
||||
// $("tr>th:nth-child(5)").addClass("col-md-3");
|
||||
// });
|
||||
// $('.universal-table-index thead tr').prepend('<th></th>')
|
||||
// $('.universal-table-index tbody tr').prepend('<td></td>')
|
||||
</script>
|
Loading…
Reference in New Issue