ezframe 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,7 +29,7 @@ module Ezframe
29
29
  }
30
30
  tr_a = data_a.map do |data|
31
31
  @column_set.clear
32
- @column_set.values = data
32
+ @column_set.set_value(data, from_db: true)
33
33
  line = idx_keys.map do |key|
34
34
  view = @column_set[key].view
35
35
  Ht.td(Ht.a(href: "#{make_base_url(data[:id])}", child: view))
@@ -40,7 +40,7 @@ module Ezframe
40
40
  thead = Ht.thead(Ht.tr(th_a))
41
41
  tbody = Ht.tbody(tr_a)
42
42
  table_id = "enable_datatable_#{@class_snake}"
43
- return Ht.table(id: table_id, class: %w[enable_datatable], child: [ thead, tbody ], event: "on=load:command=enable_datatable:target=##{table_id}:size=10")
43
+ return Ht.table(id: table_id, class: %w[enable_datatable], child: [ thead, tbody ], ezload: "command=enable_datatable:target=##{table_id}:size=10")
44
44
  end
45
45
 
46
46
  # 新規登録フォーム表示
@@ -94,7 +94,7 @@ module Ezframe
94
94
  #--------------------------------------------------------------------------------------------------------
95
95
  # 検索
96
96
  def public_search_post
97
- Logger.info "public_search_post: #{@parsed_body.inspect}"
97
+ EzLog.info "public_search_post: #{@parsed_body.inspect}"
98
98
  sch_keys = @search_keys || @column_set.keys
99
99
  word = @params["word"]
100
100
  pattern = "%#{word}%"
@@ -107,7 +107,7 @@ module Ezframe
107
107
 
108
108
  # 詳細表示
109
109
  def show_detail_page
110
- Logger.info "show_detail_page: #{@request.params.inspect}"
110
+ EzLog.info "show_detail_page: #{@request.params.inspect}"
111
111
  id = get_id(@class_snake)
112
112
  unless @column_set.set_from_db(id)
113
113
  return show_message_page("no data", "data is not defined: #{id}")
@@ -146,7 +146,7 @@ module Ezframe
146
146
  class_name ||= @class_snake
147
147
  params = @request.env['url_params']
148
148
  return nil unless params
149
- # Logger.info "get_id: #{params.inspect}, #{class_name}"
149
+ # EzLog.info "get_id: #{params.inspect}, #{class_name}"
150
150
  return params[class_name.to_sym]
151
151
  end
152
152
 
@@ -0,0 +1,56 @@
1
+ module Ezframe
2
+ module EditorCommon
3
+ def get_id(class_name = nil)
4
+ class_name ||= @class_snake
5
+ params = @request.env['url_params']
6
+ # EzLog.info "get_id: #{params.inspect}, #{class_name}"
7
+ return params[class_name.to_sym]
8
+ end
9
+
10
+ # 新規登録ボタンの生成
11
+ def make_create_button(event = nil)
12
+ event ||= "on=click:url=#{make_base_url(@id)}/create"
13
+ return Ht.button(id: "#{@class_snake}-create-button", class: %[btn], child: [Ht.icon("add"), Message[:create_button_label]], event: event)
14
+ end
15
+
16
+ # 編集ボタンの生成
17
+ def make_edit_button(event = nil)
18
+ event ||= "on=click:url=#{make_base_url(@id)}/edit"
19
+ return Ht.button(class: %w[btn], event: event, child: [ Ht.icon("edit"), Message[:edit_button_label]])
20
+ end
21
+
22
+ # 削除ボタンの生成
23
+ def make_delete_button(event = nil)
24
+ event ||= "on=click:url=#{make_base_url(@id)}/delete"
25
+ return Ht.button(class: %w[btn right red], event: event, child: [Ht.icon("delete"), Message[:delete_button_label]])
26
+ end
27
+
28
+ # キャンセルボタンの生成
29
+ def make_cancel_button(event = nil)
30
+ event ||= "on=click:url=#{make_base_url(@id)}/detail:cancel=true:with=form"
31
+ return Ht.button(class: %w[btn red], child: [Ht.icon("cancel"), Message[:cancel_button_label]], event: event)
32
+ end
33
+
34
+ # 値の更新
35
+ def update_value
36
+ form = @event[:form]
37
+ @column_set.update(get_id, form)
38
+ end
39
+
40
+ # ラベル付きで1カラムのviewを表示
41
+ def show_label_view(key)
42
+ col = @column_set[key]
43
+ Ht.span([Ht.small(col.label), col.view(force: true)])
44
+ end
45
+
46
+ # ラベル付きで1カラムのformを表示
47
+ def show_label_edit(key)
48
+ col = @column_set[key]
49
+ Ht.span([Ht.small(col.label), col.form(force: true)])
50
+ end
51
+
52
+ def show_message_page(title, body)
53
+ return show_base_template(title: title, body: Html.convert(body))
54
+ end
55
+ end
56
+ end
@@ -1,14 +1,15 @@
1
1
  module Ezframe
2
- class Logger
2
+ class EzLog
3
3
  class << self
4
4
  @instance = nil
5
5
 
6
6
  def writer(level="", msg)
7
- unless @instance
8
- @instance = File.open("log/#{ENV['RACK_ENV']||'development'}.log", "a+")
9
- @instance.sync = true
10
- end
11
- @instance.puts "#{Time.now.to_s}:#{level.upcase}:#{msg}"
7
+ # unless @instance
8
+ # @instance = File.open("log/#{ENV['RACK_ENV']||'development'}.log", "a+")
9
+ # @instance.sync = true
10
+ # end
11
+ # @instance.puts "#{Time.now.to_s}:#{level.upcase}:#{msg}"
12
+ File.open("log/#{ENV['RACK_ENV']||'development'}.log", "a+") {|f| f.puts "#{Time.now.to_s}:#{level.upcase}:#{msg}"}
12
13
  end
13
14
 
14
15
  def level=(lv)
@@ -14,7 +14,7 @@ module Ezframe
14
14
  h = ht_h.dup
15
15
  end
16
16
  else
17
- Logger.info("[WARN] wrap_tag: unknown type: #{ht_h.inspect}")
17
+ EzLog.info("[WARN] wrap_tag: unknown type: #{ht_h.inspect}")
18
18
  return nil
19
19
  end
20
20
  h[:tag] ||= __callee__.to_s
@@ -79,7 +79,7 @@ module Ezframe
79
79
  h[:selected] = "selected" if selected
80
80
  end
81
81
  h[:child] = v
82
- # Logger.info "select: hash: k=#{k}, v=#{v}, value=#{ht_h[:value]}"
82
+ # EzLog.info "select: hash: k=#{k}, v=#{v}, value=#{ht_h[:value]}"
83
83
  if ht_h[:value] && ht_h[:value].to_s == k.to_s
84
84
  h[:selected] = "selected"
85
85
  end
@@ -91,7 +91,7 @@ module Ezframe
91
91
  if %w[selected default].include?(v[2])
92
92
  h[:selected] = "selected"
93
93
  end
94
- # Logger.info "select: array: v=#{v}, value=#{ht_h[:value]}"
94
+ # EzLog.info "select: array: v=#{v}, value=#{ht_h[:value]}"
95
95
  if ht_h[:value] && ht_h[:value].to_s == v[0].to_s
96
96
  h[:selected] = "selected"
97
97
  end
@@ -0,0 +1,238 @@
1
+ # frozen_string_literal: true
2
+ module Ezframe
3
+ class MainEditor < PageBase
4
+ include EditorCommon
5
+
6
+ # 一覧ページ生成
7
+ def public_default_get
8
+ @id = get_id
9
+ if @id
10
+ return make_detail_page
11
+ else
12
+ data_a = list_for_index
13
+ div = [ Ht.div(id: "detail-top-area", child: make_index_top), Ht.div(id: "index-area", child: make_index_table(data_a)) ]
14
+ layout = index_layout(center: Ht.form(child: div))
15
+ return show_base_template(title: Message[:index_page_title], body: Html.convert(layout))
16
+ end
17
+ end
18
+
19
+ # 一覧ページの上部に表示するボタン等の生成
20
+ def make_index_top
21
+ make_create_button
22
+ end
23
+
24
+ # 新規登録フォーム表示
25
+ def public_create_get
26
+ @column_set.clear
27
+ table = make_edit_form(:create)
28
+ layout = main_layout(center: Ht.form(child: table), type: 2)
29
+ show_base_template(title: Message[:parent_create_page_title], body: Html.convert(layout))
30
+ end
31
+
32
+ # 新規登録受信
33
+ def public_create_post
34
+ validation = @column_set.validate(@form)
35
+ if @event[:branch] == "single_validate"
36
+ EzLog.debug("public_create_post: single validate: event=#{@event}, form=#{@form}")
37
+ return single_validation(validation, @event[:target_key])
38
+ end
39
+ unless @form
40
+ return { inject: "#center-panel", body: Ht.form(child: make_edit_form(:create)) }
41
+ else
42
+ if count_errors(validation) > 0
43
+ cmd_a = full_validation(validation)
44
+ EzLog.debug("public_create_post: cmd_a=#{cmd_a}")
45
+ return cmd_a if cmd_a.length > 0
46
+ end
47
+ # 値の保存
48
+ id = create_data(@form)
49
+ return { redirect: make_base_url(id) }
50
+ end
51
+ end
52
+
53
+
54
+ # データ編集受信
55
+ def public_edit_post
56
+ EzLog.debug("public_edit_post: #{@form}")
57
+ @id = get_id
58
+ validation = @column_set.validate(@form)
59
+ if @event[:branch] == "single_validate"
60
+ EzLog.debug("public_edit_post: single validate:event=#{@event}, form=#{@form}")
61
+ return single_validation(validation, @event[:target_key])
62
+ end
63
+ unless @form
64
+ data = @column_set.set_from_db(@id)
65
+ return show_message_page("no data", "data is not defined: #{@id}") unless data
66
+ return { inject: "#center-panel", body: Html.convert(Ht.form(make_edit_form)) }
67
+ else
68
+ if count_errors(validation) > 0
69
+ cmd_a = full_validation(validation)
70
+ return cmd_a
71
+ end
72
+ # 値を保存
73
+ update_data(@id, @form)
74
+ return { redirect: make_base_url(@id) }
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ # 新規データの生成
81
+ def create_data(form)
82
+ @column_set.clear
83
+ @column_set[:id].value = id = @column_set.create(form)
84
+ return id
85
+ end
86
+
87
+ # データの更新
88
+ def update_data(id, form)
89
+ @column_set.update(id, form)
90
+ end
91
+
92
+ # 自動入力を行う
93
+ def exec_completion
94
+ return nil
95
+ end
96
+
97
+ # 一覧テーブルの生成
98
+ def make_index_table(data_a)
99
+ EzLog.debug("make_index_table: #{data_a.length}")
100
+ target_keys = @index_keys
101
+ unless target_keys
102
+ target_keys = @column_set.keys.select {|k| !@column_set[k].no_view? }
103
+ end
104
+ tr_a = data_a.map do |data|
105
+ # EzLog.debug("data=#{data}")
106
+ @column_set.clear
107
+ @column_set.set_values(data, from_db: true)
108
+ line = target_keys.map do |key|
109
+ view = @column_set[key].view
110
+ Ht.td(Ht.a(href: "#{make_base_url(data[:id])}", child: view))
111
+ end
112
+ EzLog.debug("line=#{line}")
113
+ Ht.tr(line)
114
+ end
115
+ th_a = target_keys.map {|key| Ht.th(@column_set[key.to_sym].label) }
116
+ thead = Ht.thead(Ht.tr(th_a))
117
+ tbody = Ht.tbody(tr_a)
118
+ table_id = "enable_datatable_#{@class_snake}"
119
+ return Ht.table(id: table_id, class: %w[enable_datatable], child: [ thead, tbody ], ezload: "command=enable_datatable:target=##{table_id}:size=10")
120
+ end
121
+
122
+ # 編集フォームの生成
123
+ def make_edit_form(command = :edit)
124
+ table = []
125
+ matrix = @column_set.map do |column|
126
+ next if column.no_edit?
127
+ form = column.form
128
+ table.push Ht.p([ Ht.small(column.label), form ]) if form
129
+ end
130
+ send_button = Ht.button(id: "edit-finish-button", child: Message[:edit_finish_button_label], class: %w[btn], event: "on=click:url=#{make_base_url}/#{command}:with=form")
131
+ cancel_button = edit_cancel_button
132
+ cancel_button[:event] = "on=click:command=redirect:url=#{make_base_url}"
133
+ table.push(Ht.p([send_button, cancel_button]))
134
+ return table
135
+ end
136
+
137
+ # 詳細表示
138
+ def make_detail_page
139
+ # EzLog.info "make_detail_page: #{@request.params.inspect}"
140
+ id = get_id(@class_snake)
141
+ unless @column_set.set_from_db(id)
142
+ return show_message_page("no data", "data is not defined: #{id}")
143
+ end
144
+ right = nil
145
+ right = right_tabs if @with_right_tabs
146
+ layout = main_layout( center: make_detail_table, right: right)
147
+ return show_base_template(title: Message[:customer_detail], body: Html.convert(layout))
148
+ end
149
+
150
+ private
151
+
152
+ # 1カラムに対してだけバリデーションを行う。
153
+ def single_validation(result, target_key)
154
+ unless target_key
155
+ raise "target_key is empty: #{result}"
156
+ return []
157
+ end
158
+ cmd_a = []
159
+ if result[target_key.to_sym]
160
+ cmd_a = show_validate_result(result)
161
+ end
162
+ if count_errors(result) == 0
163
+ cmd_a.unshift({ reset_error: "#error-box-#{target_key}"})
164
+ end
165
+ comp_a = exec_completion(@form)
166
+ cmd_a += comp_a if comp_a
167
+ EzLog.debug("reset_error: #error-box-#{target_key}")
168
+ EzLog.debug("single_validation: target_key=#{target_key}, result=#{result}, count=#{count_errors(result)}, cmd_a=#{cmd_a}")
169
+ return cmd_a
170
+ end
171
+
172
+ # 全てのカラムに対してバリデーションを行う
173
+ def full_validation(result)
174
+ cmd_a = show_validate_result(result)
175
+ cmd_a.unshift({ reset_error: ".error-box" })
176
+ EzLog.debug("full_validation: full, cmd_a=#{cmd_a}")
177
+ return cmd_a
178
+ end
179
+
180
+ # フォームの値の有効性チェックし、ajax用返信ハッシュを生成
181
+ def show_validate_result(validate_result)
182
+ cmd_a = []
183
+ validate_result.each do |key, status|
184
+ norm, err = status
185
+ EzLog.debug("norm=#{norm}, err=#{err}")
186
+ if norm
187
+ cmd_a.push({ set_value: "input[name=#{key}]", value: norm })
188
+ end
189
+ if err
190
+ msg = Message[err.to_sym]||err
191
+ cmd_a.push({ set_error: "#error-box-#{key}", value: msg })
192
+ end
193
+ end
194
+ return cmd_a
195
+ end
196
+
197
+ # validate_resultの中のエラーの数を数える
198
+ def count_errors(validate_result)
199
+ return validate_result.count {|k, a| a[1] }
200
+ end
201
+
202
+ # 詳細ページの表の生成
203
+ def make_detail_table
204
+ table = []
205
+ array = @column_set.map do |column|
206
+ next if column.no_view?
207
+ edit_btn = nil
208
+ if column.type.to_s == "textarea"
209
+ view = Ht.pre(id: "#{@class_snake}-#{column.key}-view", child: column.view)
210
+ else
211
+ view = Ht.span(id: "#{@class_snake}-#{column.key}-view", child: column.view)
212
+ end
213
+ table.push Ht.p(class: %w[hover-button-box], child: [ Ht.small(column.label), view, edit_btn ].compact)
214
+ end
215
+ edit_btn = Ht.button(id: "#{@class_snake}-detail-edit-button", class: %w[btn], child: [ Ht.icon("edit"), Message[:edit_button_label] ], event: "on=click:url=#{make_base_url}/edit")
216
+ table.push edit_btn
217
+ return table
218
+ end
219
+
220
+ # 一覧ページ用のデータリスト生成
221
+ def list_for_index(where: nil)
222
+ where ||= {}
223
+ where[:deleted_at] = nil
224
+ sql = @column_set.dataset.where(where).order(@sort_key).sql
225
+ EzLog.debug("list_for_index: #{sql}")
226
+ return @column_set.dataset.where(where).order(@sort_key).all
227
+ end
228
+
229
+ def edit_cancel_button
230
+ Ht.span(class: %w[btn red small waves-effect waves-light switch-button], child: Ht.icon("clear"))
231
+ end
232
+
233
+ def make_create_button(event = nil)
234
+ event ||= "on=click:command=redirect:url=#{make_base_url}/create"
235
+ return Ht.button(class: %w[btn], child: [ Ht.icon("add"), Message[:create_button_label] ], event: event )
236
+ end
237
+ end
238
+ end
@@ -4,8 +4,8 @@ module Ezframe
4
4
  class Materialize
5
5
  class << self
6
6
  def into_html_header
7
- css_a = Config[:extra_css_list].map {|file| "<link href=\"#{file}\" rel=\"stylesheet\">\n" }
8
- js_a = Config[:extra_js_list].map {|file| "<script src=\"#{file}\"></script>\n" }
7
+ css_a = Config[:extra_css_list]&.map {|file| "<link href=\"#{file}\" rel=\"stylesheet\">\n" }
8
+ js_a = Config[:extra_js_list]&.map {|file| "<script src=\"#{file}\"></script>\n" }
9
9
 
10
10
  css_files = Dir["./asset/css/*.css"]||[]
11
11
  css_a += css_files.sort.map do |file|
@@ -32,7 +32,7 @@ module Ezframe
32
32
  new_h = ht_h.map { |v| convert(v) }
33
33
  elsif ht_h.is_a?(Hash)
34
34
  unless ht_h[:tag]
35
- Logger.info("convert: no tag: #{ht_h.inspect}")
35
+ EzLog.info("convert: no tag: #{ht_h.inspect}")
36
36
  return nil
37
37
  end
38
38
  case ht_h[:tag].to_sym
@@ -54,7 +54,7 @@ module Ezframe
54
54
 
55
55
  def icon(ht_h)
56
56
  new_h = ht_h.clone
57
- Logger.info "[warn] no name attribute for icon ht_h: #{ht_h.inspect}" unless new_h[:name]
57
+ EzLog.info "[warn] no name attribute for icon ht_h: #{ht_h.inspect}" unless new_h[:name]
58
58
  new_h.add_class(%w[material-icons align-icon])
59
59
  new_h.update({ tag: "i", child: ht_h[:name] })
60
60
  new_h.delete(:name)
@@ -16,14 +16,14 @@ module Ezframe
16
16
 
17
17
  def load_one_file(file)
18
18
  begin
19
- yaml = YAML.load_file(file)
19
+ yaml = YAML.load(File.open(file), symbolize_names: true)
20
20
  rescue
21
- Logger.info("YAML load error: #{file}")
21
+ EzLog.info("YAML load error: #{file}")
22
22
  return
23
23
  end
24
24
  if /([a-z]{2})\.yml$/ =~ file
25
25
  lang = $1
26
- @catalog[lang.to_sym] = yaml.recursively_symbolize_keys
26
+ @catalog[lang.to_sym] = yaml # .recursively_symbolize_keys
27
27
  end
28
28
  end
29
29
 
@@ -27,10 +27,10 @@ module Ezframe
27
27
  @request = request
28
28
  @column_set = ColumnSets.get(@class_snake)
29
29
  @dataset = DB.dataset(@class_snake)
30
- Logger.debug "column_set is not defined: #{@class_snake}" unless @column_set
30
+ EzLog.debug "column_set is not defined: #{@class_snake}" unless @column_set
31
31
  @params = parse_query_string(request.env["QUERY_STRING"])
32
32
  @params.update(request.params)
33
- # Logger.info "set_request: params=#{@params.inspect}" if @params.length > 0
33
+ # EzLog.info "set_request: params=#{@params.inspect}" if @params.length > 0
34
34
  # @id, @key = @params[:id], @params[:key]
35
35
  @env = @request.env
36
36
  @session = @env["rack.session"]
@@ -42,11 +42,11 @@ module Ezframe
42
42
  else
43
43
  @parsed_body = parse_query_string(body)
44
44
  end
45
- # Logger.info "parsed_body=#{@parsed_body.inspect}"
45
+ # EzLog.info "parsed_body=#{@parsed_body.inspect}"
46
46
  @event = @parsed_body[:event] || {}
47
47
  @form = @event[:form]
48
48
 
49
- # Logger.info "event=#{@event}"
49
+ # EzLog.info "event=#{@event}"
50
50
  end
51
51
  end
52
52
 
@@ -54,7 +54,7 @@ module Ezframe
54
54
  def make_base_url(id = nil)
55
55
  path = Route::get_path(@class_snake)
56
56
  params = @request.env["url_params"] || {}
57
- # Logger.info "make_base_url: params=#{params}"
57
+ # EzLog.info "make_base_url: params=#{params}"
58
58
  # params[@class_snake.to_sym] = id
59
59
  path_s = path.map do |pa|
60
60
  if pa == @class_snake.to_sym && id
@@ -65,7 +65,7 @@ module Ezframe
65
65
  pa
66
66
  end
67
67
  end.join("/")
68
- # Logger.info "path_s=#{path_s}"
68
+ # EzLog.info "path_s=#{path_s}"
69
69
  return "/#{path_s}"
70
70
  end
71
71
 
@@ -82,12 +82,12 @@ module Ezframe
82
82
  def parse_json_body(body)
83
83
  return {} if !body || body.length==0
84
84
  begin
85
- json = JSON.parse(body)
85
+ json = JSON.parse(body, symbolize_names: true)
86
86
  rescue => e
87
- Logger.info "ERROR: #{e.class}:#{e.message}\n#{e.backtrace}"
87
+ EzLog.info "ERROR: #{e.class}:#{e.message}\n#{e.backtrace}"
88
88
  return nil
89
89
  end
90
- json = json.recursively_symbolize_keys if json.is_a?(Hash) || json.is_a?(Array)
90
+ # json = json.recursively_symbolize_keys if json.is_a?(Hash) || json.is_a?(Array)
91
91
  return json
92
92
  end
93
93