papaSquidLib 0.1.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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +69 -0
  4. data/lib/controllers/tab_students_controller.rb +43 -0
  5. data/lib/data_sources/db_client.rb +35 -0
  6. data/lib/db_config/config.yaml +5 -0
  7. data/lib/db_config/library_config.yaml +5 -0
  8. data/lib/db_config/migrations/create_db.sql +3 -0
  9. data/lib/db_config/migrations/create_tables.sql +29 -0
  10. data/lib/db_config/mock_data/mock_data.sql +72 -0
  11. data/lib/logger.rb +27 -0
  12. data/lib/main.rb +6 -0
  13. data/lib/manager/controllers/manager_input_form_controller_create.rb +44 -0
  14. data/lib/manager/controllers/manager_input_form_controller_edit.rb +54 -0
  15. data/lib/manager/controllers/manager_list_controller.rb +99 -0
  16. data/lib/manager/manager_db_data_source.rb +63 -0
  17. data/lib/manager/ui/manager_input_form.rb +69 -0
  18. data/lib/manager/ui/manager_list_view.rb +168 -0
  19. data/lib/models/manager.rb +41 -0
  20. data/lib/models/student.rb +102 -0
  21. data/lib/models/student_base.rb +100 -0
  22. data/lib/models/student_short.rb +50 -0
  23. data/lib/models/task.rb +49 -0
  24. data/lib/models/user.rb +32 -0
  25. data/lib/papaSquidLib/version.rb +5 -0
  26. data/lib/papa_squid_lib.rb +6 -0
  27. data/lib/repositories/adapters/db_source_adapter.rb +54 -0
  28. data/lib/repositories/adapters/file_source_adapter.rb +37 -0
  29. data/lib/repositories/containers/data_list.rb +74 -0
  30. data/lib/repositories/containers/data_list_student_short.rb +18 -0
  31. data/lib/repositories/containers/data_table.rb +35 -0
  32. data/lib/repositories/data_sources/db_data_source.rb +32 -0
  33. data/lib/repositories/data_sources/file_data_source.rb +75 -0
  34. data/lib/repositories/data_sources/transformers/data_transformer_base.rb +15 -0
  35. data/lib/repositories/data_sources/transformers/data_transformer_json.rb +16 -0
  36. data/lib/repositories/data_sources/transformers/data_transformer_yaml.rb +16 -0
  37. data/lib/repositories/student_repository.rb +32 -0
  38. data/lib/state_holders/list_state_notifier.rb +60 -0
  39. data/lib/task/controllers/task_input_form_controller_create.rb +43 -0
  40. data/lib/task/controllers/task_input_form_controller_edit.rb +57 -0
  41. data/lib/task/controllers/task_list_controller.rb +93 -0
  42. data/lib/task/task_db_data_source.rb +85 -0
  43. data/lib/task/ui/task_input_form.rb +67 -0
  44. data/lib/task/ui/task_input_form_factory.rb +26 -0
  45. data/lib/task/ui/task_list_view.rb +163 -0
  46. data/lib/user/controllers/user_input_form_controller_create.rb +42 -0
  47. data/lib/user/controllers/user_input_form_controller_edit.rb +53 -0
  48. data/lib/user/controllers/user_list_controller.rb +99 -0
  49. data/lib/user/ui/user_input_form.rb +69 -0
  50. data/lib/user/ui/user_list_view.rb +170 -0
  51. data/lib/user/user_db_data_source.rb +71 -0
  52. data/lib/views/main_window.rb +32 -0
  53. data/lib/views/tab_students.rb +148 -0
  54. data/papaSquidLib.gemspec +15 -0
  55. data/test/manager_test.rb +27 -0
  56. data/test/state_notifier_test.rb +82 -0
  57. data/test/task_test.rb +51 -0
  58. data/test/user_test.rb +39 -0
  59. metadata +113 -0
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+ require 'glimmer-dsl-libui'
3
+ require_relative '../controllers/task_input_form_controller_create.rb'
4
+ require './lib/models/task'
5
+ require 'win32api'
6
+
7
+ class TaskInputForm
8
+ include Glimmer
9
+
10
+ def initialize(controller, fields_to_create, existing_student = nil)
11
+ @fields_to_create=fields_to_create
12
+ @item = existing_student.to_hash unless existing_student.nil?
13
+ @controller = controller
14
+ @entries = {}
15
+ end
16
+
17
+ def on_create
18
+ @controller.on_view_created
19
+ end
20
+
21
+ def create
22
+ @root_container = window('Задание', 300, 70) {
23
+ resizable false
24
+
25
+ vertical_box {
26
+ @student_form = form {
27
+ stretchy false
28
+
29
+ fields = @fields_to_create
30
+
31
+ fields.each do |field|
32
+ @entries[field[0]] = entry {
33
+ label field[1]
34
+ }
35
+ end
36
+ }
37
+
38
+ button('Сохранить') {
39
+ stretchy false
40
+
41
+ on_clicked {
42
+ values = @entries.transform_values { |v| v.text.force_encoding("utf-8").strip }
43
+ values.transform_values! { |v| v.empty? ? nil : v}
44
+ @controller.process_fields(values)
45
+ }
46
+ }
47
+ }
48
+ }
49
+ on_create
50
+ @root_container
51
+ end
52
+
53
+ def set_value(field, value)
54
+ return unless @entries.include?(field)
55
+ @entries[field].text = value
56
+ end
57
+
58
+ def make_readonly(*fields)
59
+ fields.each do |field|
60
+ @entries[field].read_only = true
61
+ end
62
+ end
63
+
64
+ def close
65
+ @root_container.destroy
66
+ end
67
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TaskInputFormFactory
4
+ def self.create_create_form(controller)
5
+ TaskInputForm.new(controller, fields_for_create)
6
+ end
7
+
8
+ def self.create_edit_form(controller, existing_task)
9
+ TaskInputForm.new(controller, fields_for_edit(existing_task), existing_task)
10
+ end
11
+
12
+ private_class_method def self.fields_for_create
13
+ [
14
+ [:user_id, 'ID пользователя'],
15
+ [:manager_id, 'ID менеджера'],
16
+ [:description, 'Описание']
17
+ ]
18
+ end
19
+
20
+ private_class_method def self.fields_for_edit(task)
21
+ [
22
+ [:description, 'Описание', task.description],
23
+ [:completed, 'Завершено', task.completed]
24
+ ]
25
+ end
26
+ end
@@ -0,0 +1,163 @@
1
+ # frozen_string_literal: true
2
+ require_relative '../controllers/task_list_controller'
3
+ require_relative 'task_input_form'
4
+
5
+ class TaskListView
6
+ include Glimmer
7
+
8
+ PAGE_SIZE = 20
9
+
10
+ def initialize
11
+ @controller = TaskListController.new(self)
12
+ @current_page = 1
13
+ @total_count = 0
14
+ end
15
+
16
+ def on_create
17
+ @controller.on_view_created
18
+ @controller.refresh_data(@current_page, PAGE_SIZE)
19
+ end
20
+
21
+ def update(tasks)
22
+ @items = []
23
+ i = 0
24
+ item_num = 0
25
+ tasks.each do |task|
26
+ i += 1
27
+ item_num = ((@current_page - 1) * PAGE_SIZE) + i
28
+ @items << Struct.new(:№, :id, :id_пользователя, :id_менеджера, :дата_создания, :описание, :статус).new(item_num, task.task_id, task.user_id, task.manager_id, task.date, task.description, task.completed)
29
+ end
30
+
31
+ @table.model_array = @items
32
+ @page_label.text = "#{@current_page} / #{(@total_count / PAGE_SIZE.to_f).ceil}"
33
+ end
34
+
35
+ def update_student_count(new_cnt)
36
+ @total_count = new_cnt
37
+ @page_label.text = "#{@current_page} / #{(@total_count / PAGE_SIZE.to_f).ceil}"
38
+ end
39
+
40
+ def create
41
+
42
+ root_container = horizontal_box {
43
+ # Секция 1
44
+ vertical_box {
45
+ stretchy false
46
+
47
+ vertical_box {
48
+ stretchy false
49
+
50
+ label {
51
+ text 'Завершено'
52
+ }
53
+ combobox { |c|
54
+ items ['Не важно','Сделано','Не сделано']
55
+ selected 0
56
+ on_selected do
57
+ @controller.filter_completed(@current_page, PAGE_SIZE, c.selected)
58
+ end
59
+ }
60
+
61
+ label {
62
+ text 'Сортировка'
63
+ }
64
+ combobox { |c|
65
+ items ['ID',
66
+ 'ID пользователя',
67
+ 'ID менеджера',
68
+ 'Дата создания',
69
+ 'Описание',
70
+ 'Статус'
71
+ ]
72
+ selected 0
73
+ on_selected do
74
+ @controller.sort(@current_page, PAGE_SIZE, c.selected)
75
+ end
76
+ }
77
+ }
78
+ }
79
+
80
+ # Секция 2
81
+ vertical_box {
82
+ @table = refined_table(
83
+ table_editable: false,
84
+ filter: lambda do |row_hash, query|
85
+ utf8_query = query.force_encoding("utf-8")
86
+ row_hash['Имя пользователя'].include?(utf8_query)
87
+ end,
88
+ table_columns: {
89
+ '№' => :text,
90
+ 'ID' => :text,
91
+ 'ID пользователя' => :text,
92
+ 'ID менеджера' => :text,
93
+ 'Дата создания' => :text,
94
+ 'Описание' => :text,
95
+ 'Статус' => :text
96
+ },
97
+ per_page: PAGE_SIZE,
98
+
99
+ )
100
+
101
+ @pages = horizontal_box {
102
+ stretchy false
103
+
104
+ button("<") {
105
+ stretchy true
106
+
107
+ on_clicked do
108
+ @current_page = [@current_page - 1, 1].max
109
+ @controller.refresh_data(@current_page, PAGE_SIZE)
110
+ end
111
+
112
+ }
113
+ @page_label = label("...") { stretchy false }
114
+ button(">") {
115
+ stretchy true
116
+
117
+ on_clicked do
118
+ @current_page = [@current_page + 1, (@total_count / PAGE_SIZE.to_f).ceil].min
119
+ @controller.refresh_data(@current_page, PAGE_SIZE)
120
+ end
121
+ }
122
+ }
123
+ }
124
+
125
+ # Секция 3
126
+ vertical_box {
127
+ stretchy false
128
+
129
+ button('Добавить') {
130
+ stretchy false
131
+
132
+ on_clicked {
133
+ @controller.show_modal_add
134
+ }
135
+ }
136
+ button('Изменить') {
137
+ stretchy false
138
+
139
+ on_clicked {
140
+ @controller.show_modal_edit(@current_page, PAGE_SIZE, @table.selection) unless @table.selection.nil?
141
+ }
142
+ }
143
+ button('Удалить') {
144
+ stretchy false
145
+
146
+ on_clicked {
147
+ @controller.delete_selected(@current_page, PAGE_SIZE, @table.selection) unless @table.selection.nil?
148
+ @controller.refresh_data(@current_page, PAGE_SIZE)
149
+ }
150
+ }
151
+ button('Обновить') {
152
+ stretchy false
153
+
154
+ on_clicked {
155
+ @controller.refresh_data(@current_page, PAGE_SIZE)
156
+ }
157
+ }
158
+ }
159
+ }
160
+ on_create
161
+ root_container
162
+ end
163
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'win32api'
4
+
5
+ class UserInputFormControllerCreate
6
+ def initialize(parent_controller)
7
+ @parent_controller = parent_controller
8
+ @user_rep = UserDbDataSource.new
9
+ end
10
+
11
+ def set_view(view)
12
+ @view = view
13
+ end
14
+
15
+ def on_view_created
16
+ # begin
17
+ # @student_rep = StudentRepository.new(DBSourceAdapter.new)
18
+ # rescue Mysql2::Error::ConnectionError
19
+ # on_db_conn_error
20
+ # end
21
+ end
22
+
23
+ def process_fields(fields)
24
+ begin
25
+ item = User.new(-1, *fields.values)
26
+ item = @user_rep.add(item)
27
+ @parent_controller.state_notifier.add(item)
28
+ @view.close
29
+ rescue ArgumentError => e
30
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
31
+ api.call(0, e.message, 'Error', 0)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def on_db_conn_error
38
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
39
+ api.call(0, "No connection to DB", "Error", 0)
40
+ @view.close
41
+ end
42
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'win32api'
4
+
5
+ class UserInputFormControllerEdit
6
+ def initialize(parent_controller, item)
7
+ @parent_controller = parent_controller
8
+ @item = item
9
+ @user_rep = UserDbDataSource.new
10
+ end
11
+
12
+ def set_view(view)
13
+ @view = view
14
+ end
15
+
16
+ def on_view_created
17
+ # begin
18
+ # @student_rep = StudentRepository.new(DBSourceAdapter.new)
19
+ # rescue Mysql2::Error::ConnectionError
20
+ # on_db_conn_error
21
+ # end
22
+
23
+ # @item = @author_rep.get(@item_id)
24
+ # @view.make_readonly(:git, :telegram, :email, :phone)
25
+ populate_fields(@item)
26
+ end
27
+
28
+ def populate_fields(item)
29
+ @view.set_value(:first_name, item.first_name)
30
+ @view.set_value(:last_name, item.last_name)
31
+ @view.set_value(:father_name, item.father_name)
32
+ end
33
+
34
+ def process_fields(fields)
35
+ begin
36
+ item = User.new(@item.user_id, *fields.values)
37
+ item = @user_rep.change(item)
38
+ @parent_controller.state_notifier.replace(@item, item)
39
+ @view.close
40
+ rescue ArgumentError => e
41
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
42
+ api.call(0, e.message, 'Error', 0)
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def on_db_conn_error
49
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
50
+ api.call(0, "No connection to DB", "Error", 0)
51
+ @view.close
52
+ end
53
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/state_holders/list_state_notifier'
4
+ require_relative '../ui/user_input_form'
5
+ require_relative 'user_input_form_controller_create'
6
+ require_relative 'user_input_form_controller_edit'
7
+ require_relative '../user_db_data_source'
8
+ require 'win32api'
9
+
10
+ # Класс UserListController отвечает за управление списком
11
+ # авторов, используя различные методы для обновления данных и
12
+ # взаимодействия с пользовательским интерфейсом.
13
+ class UserListController
14
+
15
+ attr_reader :state_notifier;
16
+
17
+ def initialize(view)
18
+ LoggerHolder.instance.debug('UserListController: initialize')
19
+ @view = view
20
+ @state_notifier = ListStateNotifier.new
21
+ @state_notifier.add_listener(@view)
22
+ @user_rep = UserDbDataSource.new
23
+
24
+ @sort_columns = %w[UserID FirstName LastName FatherName]
25
+ @sort_by = @sort_columns.first
26
+
27
+ @father_name_filter_columns = [nil, true, false]
28
+ @father_name_filter = @father_name_filter_columns.first
29
+ end
30
+
31
+ def on_view_created
32
+ # begin
33
+ # @student_rep = StudentRepository.new(DBSourceAdapter.new)
34
+ # rescue Mysql2::Error::ConnectionError
35
+ # on_db_conn_error
36
+ # end
37
+ end
38
+
39
+ def show_view
40
+ @view.create.show
41
+ end
42
+
43
+ def show_modal_add
44
+ LoggerHolder.instance.debug('UserListController: show_modal_add')
45
+ controller = UserInputFormControllerCreate.new(self)
46
+ view = UserInputForm.new(controller)
47
+ controller.set_view(view)
48
+ view.create.show
49
+ end
50
+
51
+ # метод, который создает контроллер UserInputFormControllerEdit, представление UserInputForm, устанавливает связи между ними и показывает модальное окно.
52
+ def show_modal_edit(current_page, per_page, selected_row)
53
+ LoggerHolder.instance.debug('UserListController: show_modal_edit')
54
+ # item_num = (current_page - 1) * per_page + selected_row
55
+ item = @state_notifier.get(selected_row)
56
+ controller = UserInputFormControllerEdit.new(self, item)
57
+ view = UserInputForm.new(controller)
58
+ controller.set_view(view)
59
+ view.create.show
60
+ end
61
+
62
+ # метод, который получает выбранный элемент из state_notifier, удаляет его из базы данных и из state_notifier
63
+ def delete_selected(current_page, per_page, selected_row)
64
+ LoggerHolder.instance.debug('UserListController: delete_selected')
65
+ begin
66
+ item = @state_notifier.get(selected_row)
67
+ @user_rep.delete(item.user_id)
68
+ @state_notifier.delete(item)
69
+ rescue
70
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
71
+ api.call(0, "You cannot delete the user because he is associated with some book", "Error", 0)
72
+ end
73
+ end
74
+
75
+ # етод, который получает список авторов из базы данных, устанавливает их в state_notifier и обновляет пользовательский интерфейс
76
+ def refresh_data(page, per_page)
77
+ items = @user_rep.get_list(per_page, page, @sort_by, 'ASC', @father_name_filter)
78
+ @state_notifier.set_all(items)
79
+ @view.update_student_count(@user_rep.count)
80
+ end
81
+
82
+ def sort(page, per_page, sort_index)
83
+ @sort_by = @sort_columns[sort_index]
84
+ refresh_data(page, per_page)
85
+ end
86
+
87
+ def filter_father_name(page, per_page, filter_index)
88
+ @father_name_filter = @father_name_filter_columns[filter_index]
89
+ refresh_data(page, per_page)
90
+ end
91
+
92
+ private
93
+
94
+ def on_db_conn_error
95
+ api = Win32API.new('user32', 'MessageBox', ['L', 'P', 'P', 'L'], 'I')
96
+ api.call(0, "No connection to DB", "Error", 0)
97
+ exit(false)
98
+ end
99
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+ require_relative '../controllers/user_input_form_controller_create'
5
+ require './lib/models/user'
6
+ require 'win32api'
7
+
8
+ class UserInputForm
9
+ include Glimmer
10
+
11
+ def initialize(controller, existing_student = nil)
12
+ @item = existing_student.to_hash unless existing_student.nil?
13
+ @controller = controller
14
+ @entries = {}
15
+ end
16
+
17
+ def on_create
18
+ @controller.on_view_created
19
+ end
20
+
21
+ def create
22
+ @root_container = window('Пользователь', 300, 70) {
23
+ resizable false
24
+
25
+ vertical_box {
26
+ @student_form = form {
27
+ stretchy false
28
+
29
+ fields = [[:first_name, 'Имя Пользователя'], [:last_name, 'Фамилия Пользователя'], [:father_name, 'Отчество пользователя']]
30
+
31
+ fields.each do |field|
32
+ @entries[field[0]] = entry {
33
+ label field[1]
34
+ }
35
+ end
36
+ }
37
+
38
+ button('Сохранить') {
39
+ stretchy false
40
+
41
+ on_clicked {
42
+ values = @entries.transform_values { |v| v.text.force_encoding("utf-8").strip }
43
+ values.transform_values! { |v| v.empty? ? nil : v}
44
+
45
+ @controller.process_fields(values)
46
+ }
47
+ }
48
+ }
49
+ }
50
+ on_create
51
+ @root_container
52
+ end
53
+
54
+ def set_value(field, value)
55
+ return unless @entries.include?(field)
56
+ print value.class
57
+ @entries[field].text = value
58
+ end
59
+
60
+ def make_readonly(*fields)
61
+ fields.each do |field|
62
+ @entries[field].read_only = true
63
+ end
64
+ end
65
+
66
+ def close
67
+ @root_container.destroy
68
+ end
69
+ end
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'glimmer-dsl-libui'
4
+ require_relative '../controllers/user_list_controller'
5
+ require_relative 'user_input_form'
6
+
7
+ class UserListView
8
+ include Glimmer
9
+
10
+ PAGE_SIZE = 20
11
+
12
+ def initialize
13
+ @controller = UserListController.new(self)
14
+ @current_page = 1
15
+ @total_count = 0
16
+ end
17
+
18
+ def on_create
19
+ @controller.on_view_created
20
+ @controller.refresh_data(@current_page, PAGE_SIZE)
21
+ end
22
+
23
+ # Метод наблюдателя datalist
24
+ # def on_datalist_changed(new_table)
25
+ # arr = new_table.to_2d_array
26
+ # arr.map do |row|
27
+ # row[3] = [row[3][:value], contact_color(row[3][:type])] unless row[3].nil?
28
+ # end
29
+ # @table.model_array = arr
30
+ # end
31
+
32
+ def update(users)
33
+ @items = []
34
+
35
+ i = 0
36
+ item_num = 0
37
+ users.each do |user|
38
+ i += 1
39
+ item_num = ((@current_page - 1) * PAGE_SIZE) + i
40
+ print("USERid=#{user.user_id}")
41
+ @items << Struct.new(:№, :id, :имя_пользователя, :фамилия_пользователя, :отчество_пользователя).new(item_num, user.user_id, user.first_name, user.last_name, user.father_name)
42
+ end
43
+
44
+ @table.model_array = @items
45
+ @page_label.text = "#{@current_page} / #{(@total_count / PAGE_SIZE.to_f).ceil}"
46
+ end
47
+
48
+ def update_student_count(new_cnt)
49
+ @total_count = new_cnt
50
+ @page_label.text = "#{@current_page} / #{(@total_count / PAGE_SIZE.to_f).ceil}"
51
+ end
52
+
53
+ def create
54
+
55
+ root_container = horizontal_box {
56
+ # Секция 1
57
+ vertical_box {
58
+ stretchy false
59
+
60
+ vertical_box {
61
+ stretchy false
62
+
63
+ label {
64
+ text 'Отчество'
65
+ }
66
+ combobox { |c|
67
+ items ['Не важно','Есть','Нет']
68
+ selected 0
69
+ on_selected do
70
+ @controller.filter_father_name(@current_page, PAGE_SIZE, c.selected)
71
+ end
72
+ }
73
+
74
+ label {
75
+ text 'Сортировка'
76
+ }
77
+ combobox { |c|
78
+ items ['ID', 'Имя пользователя', 'Фамилия пользователя', 'Отчество пользователя']
79
+ selected 0
80
+ on_selected do
81
+ @controller.sort(@current_page, PAGE_SIZE, c.selected)
82
+ end
83
+ }
84
+ }
85
+
86
+
87
+ }
88
+
89
+ # Секция 2
90
+ vertical_box {
91
+ @table = refined_table(
92
+ table_editable: false,
93
+ filter: lambda do |row_hash, query|
94
+ utf8_query = query.force_encoding("utf-8")
95
+ row_hash['Имя пользователя'].include?(utf8_query)
96
+ end,
97
+ table_columns: {
98
+ '№' => :text,
99
+ 'ID' => :text,
100
+ 'Имя пользователя' => :text,
101
+ 'Фамилия пользователя' => :text,
102
+ 'Отчество пользователя' => :text,
103
+ },
104
+ per_page: PAGE_SIZE,
105
+
106
+ )
107
+
108
+ @pages = horizontal_box {
109
+ stretchy false
110
+
111
+ button("<") {
112
+ stretchy true
113
+
114
+ on_clicked do
115
+ @current_page = [@current_page - 1, 1].max
116
+ @controller.refresh_data(@current_page, PAGE_SIZE)
117
+ end
118
+
119
+ }
120
+ @page_label = label("...") { stretchy false }
121
+ button(">") {
122
+ stretchy true
123
+
124
+ on_clicked do
125
+ @current_page = [@current_page + 1, (@total_count / PAGE_SIZE.to_f).ceil].min
126
+ @controller.refresh_data(@current_page, PAGE_SIZE)
127
+ end
128
+ }
129
+ }
130
+ }
131
+
132
+ # Секция 3
133
+ vertical_box {
134
+ stretchy false
135
+
136
+ button('Добавить') {
137
+ stretchy false
138
+
139
+ on_clicked {
140
+ @controller.show_modal_add
141
+ }
142
+ }
143
+ button('Изменить') {
144
+ stretchy false
145
+
146
+ on_clicked {
147
+ @controller.show_modal_edit(@current_page, PAGE_SIZE, @table.selection) unless @table.selection.nil?
148
+ }
149
+ }
150
+ button('Удалить') {
151
+ stretchy false
152
+
153
+ on_clicked {
154
+ @controller.delete_selected(@current_page, PAGE_SIZE, @table.selection) unless @table.selection.nil?
155
+ @controller.refresh_data(@current_page, PAGE_SIZE)
156
+ }
157
+ }
158
+ button('Обновить') {
159
+ stretchy false
160
+
161
+ on_clicked {
162
+ @controller.refresh_data(@current_page, PAGE_SIZE)
163
+ }
164
+ }
165
+ }
166
+ }
167
+ on_create
168
+ root_container
169
+ end
170
+ end