ezframe 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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