student_mvp 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 (127) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +35 -0
  3. data/Rakefile +4 -0
  4. data/doc/Add_student_presenter.html +238 -0
  5. data/doc/App_logger.html +386 -0
  6. data/doc/Base_presenter.html +265 -0
  7. data/doc/Binary_tree.html +300 -0
  8. data/doc/Binary_tree_iterator.html +217 -0
  9. data/doc/Contact_sort_decorator.html +219 -0
  10. data/doc/DB_client.html +252 -0
  11. data/doc/Data_list.html +625 -0
  12. data/doc/Data_list_student_short.html +148 -0
  13. data/doc/Data_storage_strategy.html +178 -0
  14. data/doc/Data_table.html +264 -0
  15. data/doc/Deep_dup.html +152 -0
  16. data/doc/Edit_contacts_presenter.html +199 -0
  17. data/doc/Edit_git_presenter.html +192 -0
  18. data/doc/Edit_student_presenter.html +464 -0
  19. data/doc/Field_filter_decorator.html +219 -0
  20. data/doc/Filter.html +148 -0
  21. data/doc/Filter_decorator.html +209 -0
  22. data/doc/Full_name_filter_decorator.html +211 -0
  23. data/doc/Full_name_sort_decorator.html +217 -0
  24. data/doc/Gemfile.html +98 -0
  25. data/doc/Git_sort_decorator.html +220 -0
  26. data/doc/Has_not_field_filter_decorator.html +209 -0
  27. data/doc/JSON_storage_strategy.html +183 -0
  28. data/doc/Person.html +511 -0
  29. data/doc/README_md.html +147 -0
  30. data/doc/Rakefile.html +94 -0
  31. data/doc/Replace_student_presenter.html +204 -0
  32. data/doc/Sort_decorator.html +214 -0
  33. data/doc/Student.html +755 -0
  34. data/doc/StudentMvp/Error.html +105 -0
  35. data/doc/StudentMvp.html +111 -0
  36. data/doc/Student_list_presenter.html +667 -0
  37. data/doc/Student_short.html +398 -0
  38. data/doc/Students_list.html +341 -0
  39. data/doc/Students_list_DB.html +361 -0
  40. data/doc/Students_list_file.html +460 -0
  41. data/doc/Students_list_file_adapter.html +341 -0
  42. data/doc/Students_list_interface.html +298 -0
  43. data/doc/YAML_storage_strategy.html +183 -0
  44. data/doc/bin/setup.html +96 -0
  45. data/doc/created.rid +44 -0
  46. data/doc/css/fonts.css +167 -0
  47. data/doc/css/rdoc.css +662 -0
  48. data/doc/fonts/Lato-Light.ttf +0 -0
  49. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  50. data/doc/fonts/Lato-Regular.ttf +0 -0
  51. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  52. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  53. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  54. data/doc/images/add.png +0 -0
  55. data/doc/images/arrow_up.png +0 -0
  56. data/doc/images/brick.png +0 -0
  57. data/doc/images/brick_link.png +0 -0
  58. data/doc/images/bug.png +0 -0
  59. data/doc/images/bullet_black.png +0 -0
  60. data/doc/images/bullet_toggle_minus.png +0 -0
  61. data/doc/images/bullet_toggle_plus.png +0 -0
  62. data/doc/images/date.png +0 -0
  63. data/doc/images/delete.png +0 -0
  64. data/doc/images/find.png +0 -0
  65. data/doc/images/loadingAnimation.gif +0 -0
  66. data/doc/images/macFFBgHack.png +0 -0
  67. data/doc/images/package.png +0 -0
  68. data/doc/images/page_green.png +0 -0
  69. data/doc/images/page_white_text.png +0 -0
  70. data/doc/images/page_white_width.png +0 -0
  71. data/doc/images/plugin.png +0 -0
  72. data/doc/images/ruby.png +0 -0
  73. data/doc/images/tag_blue.png +0 -0
  74. data/doc/images/tag_green.png +0 -0
  75. data/doc/images/transparent.png +0 -0
  76. data/doc/images/wrench.png +0 -0
  77. data/doc/images/wrench_orange.png +0 -0
  78. data/doc/images/zoom.png +0 -0
  79. data/doc/index.html +174 -0
  80. data/doc/js/darkfish.js +114 -0
  81. data/doc/js/navigation.js +105 -0
  82. data/doc/js/navigation.js.gz +0 -0
  83. data/doc/js/search.js +110 -0
  84. data/doc/js/search_index.js +1 -0
  85. data/doc/js/search_index.js.gz +0 -0
  86. data/doc/js/searcher.js +229 -0
  87. data/doc/js/searcher.js.gz +0 -0
  88. data/doc/table_of_contents.html +1047 -0
  89. data/lib/data_access/DB_client/DB_client.rb +26 -0
  90. data/lib/deep_dup/deep_dup.rb +14 -0
  91. data/lib/logger/logger.rb +64 -0
  92. data/lib/models/binary_tree/binary_tree.rb +163 -0
  93. data/lib/models/binary_tree/binary_tree_iterator.rb +36 -0
  94. data/lib/models/data_list/data_list.rb +97 -0
  95. data/lib/models/data_list/data_list_student_short.rb +16 -0
  96. data/lib/models/data_storage_strategy/JSON_storage_strategy.rb +20 -0
  97. data/lib/models/data_storage_strategy/YAML_storage_strategy.rb +20 -0
  98. data/lib/models/data_storage_strategy/data_storage_strategy.rb +11 -0
  99. data/lib/models/data_table/data_table.rb +52 -0
  100. data/lib/models/filter/filter.rb +5 -0
  101. data/lib/models/filter/filter_decorator.rb +14 -0
  102. data/lib/models/filter/sort_decorator.rb +15 -0
  103. data/lib/models/filter/student_filters/contact_sort_decorator.rb +50 -0
  104. data/lib/models/filter/student_filters/field_filter_decorator.rb +34 -0
  105. data/lib/models/filter/student_filters/full_name_filter_decorator.rb +26 -0
  106. data/lib/models/filter/student_filters/full_name_sort_decorator.rb +32 -0
  107. data/lib/models/filter/student_filters/git_sort_decorator.rb +35 -0
  108. data/lib/models/filter/student_filters/has_not_field_filter_decorator.rb +24 -0
  109. data/lib/models/person/person.rb +72 -0
  110. data/lib/models/student/student.rb +204 -0
  111. data/lib/models/student_short/student_short.rb +98 -0
  112. data/lib/models/students_list/students_list.rb +32 -0
  113. data/lib/models/students_list/students_list_DB.rb +95 -0
  114. data/lib/models/students_list/students_list_file.rb +134 -0
  115. data/lib/models/students_list/students_list_file_adapter.rb +45 -0
  116. data/lib/models/students_list/students_list_interface.rb +25 -0
  117. data/lib/presenters/base_presenters/base_presenter.rb +26 -0
  118. data/lib/presenters/base_presenters/student_list_presenter.rb +273 -0
  119. data/lib/presenters/edit_student/add_student_presenter.rb +46 -0
  120. data/lib/presenters/edit_student/edit_contacts_presenter.rb +36 -0
  121. data/lib/presenters/edit_student/edit_git_presenter.rb +28 -0
  122. data/lib/presenters/edit_student/edit_student_presenter.rb +109 -0
  123. data/lib/presenters/edit_student/replace_student_presenter.rb +37 -0
  124. data/lib/student_mvp/version.rb +5 -0
  125. data/lib/student_mvp.rb +8 -0
  126. data/sig/student_mvp.rbs +4 -0
  127. metadata +253 -0
@@ -0,0 +1,134 @@
1
+ require_relative '../student/student.rb'
2
+ require_relative '../student_short/student_short.rb'
3
+ require_relative '../data_list/data_list_student_short.rb'
4
+ require_relative '../binary_tree/binary_tree.rb'
5
+ require_relative './students_list_interface.rb'
6
+
7
+ class Students_list_file < Students_list_interface
8
+ # constructor
9
+ def initialize(file_path, data_storage_strategy)
10
+ self.file_path = file_path
11
+ self.data_storage_strategy = data_storage_strategy
12
+ self.students = read
13
+ end
14
+
15
+ # read from data storage
16
+ def read
17
+ self.data_storage_strategy.read(self.file_path)
18
+ end
19
+
20
+ # write to data storage
21
+ def write
22
+ self.data_storage_strategy.write(self.file_path, self.students)
23
+ end
24
+
25
+ # get student by id
26
+ def get_student_by_id(id)
27
+ self.students.find { |student| student.id == id }
28
+ end
29
+
30
+ # get data_list_student_short of k n students
31
+ def get_k_n_student_short_list(k, n, filter = nil, data_list = nil)
32
+ start = (k - 1) * n
33
+ filtered = filter ? filter.apply(self.students) : self.students
34
+ selected = filtered[start, n] || []
35
+ students_short = selected.map { |student| Student_short.new_from_student_obj(student) }
36
+ data_list ||= Data_list_student_short.new(students_short)
37
+ data_list.index = start + 1
38
+ data_list.data = students_short
39
+ data_list
40
+ end
41
+
42
+ # sort by full name
43
+ def sort_by_full_name!
44
+ self.students.sort_by! { |student| student.get_full_name }
45
+ self.write
46
+ end
47
+
48
+ # add student
49
+ def add_student(student)
50
+ begin
51
+ check_unique_fileds(email: student.email, telegram: student.telegram, phone_number: student.phone_number, git: student.git)
52
+ rescue => e
53
+ raise e
54
+ end
55
+ max_id = self.students.map(&:id).max || 0
56
+ student.id = max_id + 1
57
+ self.students << student
58
+ self.write
59
+ end
60
+
61
+ # replace student by id
62
+ def replace_student(id, new_student)
63
+ index = self.students.find_index { |student| student.id == id }
64
+ raise IndexError, 'Unknown student id' if index.nil?
65
+ begin
66
+ check_unique_fileds(email: new_student.email, telegram: new_student.telegram,
67
+ phone_number: new_student.phone_number, git: new_student.git, current_student: self.students[index])
68
+ rescue => e
69
+ raise e
70
+ end
71
+ new_student.id = id
72
+ self.students[index] = new_student
73
+ self.write
74
+ end
75
+
76
+ # delete student by id
77
+ def delete_student(id)
78
+ self.students.reject! { |student| student.id == id }
79
+ self.write
80
+ end
81
+
82
+ # get count of students
83
+ def get_student_short_count(filter = nil)
84
+ filter ? filter.apply(self.students).size : self.students.size
85
+ end
86
+
87
+ private
88
+ attr_accessor :file_path, :students, :data_storage_strategy
89
+
90
+ def check_unique_fileds(email: nil, telegram: nil, phone_number: nil, git: nil, current_student: nil)
91
+ if !email.nil? && (current_student.nil? || email != current_student.email) && !unique_email?(email)
92
+ raise 'Duplicate email'
93
+ end
94
+
95
+ if !telegram.nil? && (current_student.nil? || telegram != current_student.telegram) && !unique_telegram?(telegram)
96
+ raise 'Duplicate telegram'
97
+ end
98
+
99
+ if !phone_number.nil? && (current_student.nil? || phone_number != current_student.phone_number) && !unique_phone_number?(phone_number)
100
+ raise 'Duplicate phone number'
101
+ end
102
+
103
+ if !git.nil? && (current_student.nil? || git != current_student.git) && !unique_git?(git)
104
+ raise 'Duplicate git'
105
+ end
106
+ end
107
+
108
+ def unique_email?(email)
109
+ unique?(:email, email)
110
+ end
111
+
112
+ def unique_telegram?(telegram)
113
+ unique?(:telegram, telegram)
114
+ end
115
+
116
+ def unique_phone_number?(phone_number)
117
+ unique?(:phone_number, phone_number)
118
+ end
119
+
120
+ def unique_git?(git)
121
+ unique?(:git, git)
122
+ end
123
+
124
+ def unique?(key_type, key)
125
+ tree = Binary_tree.new
126
+ self.students.each do |student|
127
+ student.key_type = key_type
128
+ tree.add(student)
129
+ end
130
+
131
+ finded = tree.find(key)
132
+ return finded.nil?
133
+ end
134
+ end
@@ -0,0 +1,45 @@
1
+ require_relative '../student/student.rb'
2
+ require_relative '../student_short/student_short.rb'
3
+ require_relative '../data_list/data_list_student_short.rb'
4
+ require_relative '../binary_tree/binary_tree.rb'
5
+ require_relative './students_list_interface.rb'
6
+
7
+ class Students_list_file_adapter < Students_list_interface
8
+ # constructor
9
+ def initialize(adaptee)
10
+ self.adaptee = adaptee
11
+ end
12
+
13
+ # get student by id
14
+ def get_student_by_id(id)
15
+ self.adaptee.get_student_by_id(id)
16
+ end
17
+
18
+ # get data_list_student_short of k n students
19
+ def get_k_n_student_short_list(k, n, filter = nil, data_list = nil)
20
+ self.adaptee.get_k_n_student_short_list(k, n, filter, data_list)
21
+ end
22
+
23
+ # add student
24
+ def add_student(student)
25
+ self.adaptee.add_student(student)
26
+ end
27
+
28
+ # replace student by id
29
+ def replace_student(id, new_student)
30
+ self.adaptee.replace_student(id, new_student)
31
+ end
32
+
33
+ # delete student by id
34
+ def delete_student(id)
35
+ self.adaptee.delete_student(id)
36
+ end
37
+
38
+ # get count of students
39
+ def get_student_short_count(filter = nil)
40
+ self.adaptee.get_student_short_count(filter)
41
+ end
42
+
43
+ private
44
+ attr_accessor :adaptee
45
+ end
@@ -0,0 +1,25 @@
1
+ class Students_list_interface
2
+ def get_student_by_id(id)
3
+ raise NotImplementedError
4
+ end
5
+
6
+ def get_k_n_student_short_list(k, n, filter = nil, data_list = nil)
7
+ raise NotImplementedError
8
+ end
9
+
10
+ def add_student(student)
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def replace_student(id, new_student)
15
+ raise NotImplementedError
16
+ end
17
+
18
+ def delete_student(id)
19
+ raise NotImplementedError
20
+ end
21
+
22
+ def get_student_short_count(filter = nil)
23
+ raise NotImplementedError
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ require_relative '../../logger/logger.rb'
2
+
3
+ # == Base_presenter
4
+ # Базовый класс для презентеров.
5
+ # Управляет основными атрибутами и логикой взаимодействия между представлениями и данными.
6
+ class Base_presenter
7
+ # Инициализация базового презентера.
8
+ #
9
+ # @param view [Base_view_interface] Объект представления, с которым работает презентер.
10
+ def initialize(view)
11
+ self.view = view
12
+ self.logger = App_logger.instance
13
+ end
14
+
15
+ protected
16
+
17
+ # @!attribute [rw] view
18
+ # @return [Base_view_interface] Объект представления.
19
+ # @!attribute [rw] entities_list
20
+ # @return [Students_list, nil] Список сущностей.
21
+ # @!attribute [rw] data_list
22
+ # @return [Data_list, nil] Список данных.
23
+ # @!attribute [rw] logger
24
+ # @return [App_logger] Логгер для записи событий.
25
+ attr_accessor :view, :entities_list, :data_list, :logger
26
+ end
@@ -0,0 +1,273 @@
1
+ require 'mysql2'
2
+ require_relative '../../models/students_list/students_list.rb'
3
+ require_relative '../../models/students_list/students_list_DB'
4
+ require_relative '../../models/data_list/data_list_student_short'
5
+ require_relative '../../models/students_list/students_list_file_adapter'
6
+ require_relative '../../models/students_list/students_list_file'
7
+ require_relative '../../models/data_storage_strategy/JSON_storage_strategy'
8
+ require_relative '../../models/student/student.rb'
9
+ require_relative './base_presenter'
10
+ require_relative '../../models/filter/filter.rb'
11
+ require_relative '../../models/filter/student_filters/field_filter_decorator.rb'
12
+ require_relative '../../models/filter/student_filters/full_name_filter_decorator.rb'
13
+ require_relative '../../models/filter/student_filters/has_not_field_filter_decorator.rb'
14
+ require_relative '../../models/filter/student_filters/contact_sort_decorator.rb'
15
+ require_relative '../../models/filter/student_filters/git_sort_decorator.rb'
16
+ require_relative '../../models/filter/student_filters/full_name_sort_decorator.rb'
17
+
18
+ # == Student_list_presenter
19
+ # Презентер для управления списком студентов.
20
+ # Отвечает за логику отображения, фильтрации и сортировки данных о студентах.
21
+ class Student_list_presenter < Base_presenter
22
+
23
+ # Инициализация презентера списка студентов.
24
+ # Настраивает список студентов, фильтры и порядок сортировки.
25
+ #
26
+ # @param view [Base_view_interface] Представление, отображающее список студентов.
27
+ def initialize(view)
28
+ super(view)
29
+ self.logger.debug("Инициализация Student_list_presenter")
30
+ begin
31
+ self.logger.debug("Инициализация Students_list")
32
+ self.entities_list = Students_list.new(Students_list_DB.new)
33
+ # self.entities_list = Students_list.new(Students_list_file_adapter.new(Students_list_file.new('./students.json', JSON_storage_strategy.new)))
34
+ self.logger.debug("Инициализация Data_list_student_short")
35
+ self.data_list = Data_list_student_short.new([])
36
+ self.filters = Filter.new
37
+ self.sort_order = {
38
+ order: :asc,
39
+ col_index: 0
40
+ }
41
+ rescue StandardError => e
42
+ error_msg = "Ошибка при получении доступа к файлу: #{e.message}"
43
+ self.logger.error(error_msg)
44
+ self.view.show_error(error_msg)
45
+ end
46
+ end
47
+
48
+ # Обновление данных в таблице студентов.
49
+ # Выполняет сброс фильтров, применяет новые фильтры и обновляет представление.
50
+ def refresh_data
51
+ self.logger.info "Обновление таблицы студентов"
52
+ self.data_list.clear_selected
53
+ self.reset_filters
54
+ self.apply_filters
55
+ begin
56
+ self.logger.info "Поиск студентов в хранилище"
57
+ self.data_list = self.entities_list.get_k_n_student_short_list(self.view.current_page, self.view.rows_per_page, self.filters, self.data_list)
58
+ self.data_list.count = self.entities_list.get_student_short_count
59
+ self.view.update_view({ columns: self.data_list.get_names, total_count: self.data_list.count, table_data: self.data_list.retrieve_data })
60
+ rescue => e
61
+ error_msg = "Ошибка при получении данных: #{e.message}"
62
+ self.logger.error error_msg
63
+ self.view.show_error(error_msg)
64
+ end
65
+
66
+ self.logger.info "Таблица студентов обновлена"
67
+ end
68
+
69
+ # Добавление нового студента.
70
+ #
71
+ # @param student [Student] Объект студента для добавления.
72
+ def add_student(student)
73
+ self.logger.info "Добавление студента в хранилище"
74
+ self.logger.debug "Данные студента: #{student.to_line_s}"
75
+ self.entities_list.add_student(student)
76
+ self.logger.info "Студент добавлен в хранилище"
77
+ self.refresh_data
78
+ end
79
+
80
+ # Выбор строки таблицы.
81
+ #
82
+ # @param number [Integer] Индекс строки для выбора.
83
+ def select(number)
84
+ begin
85
+ self.data_list.select(number)
86
+ self.logger.info "Выделена строка: #{number}"
87
+ self.view.update_button_states
88
+ rescue
89
+ self.logger.error "Ошибка при выделении строки: #{number}"
90
+ end
91
+ end
92
+
93
+ # Удаление выделения строки таблицы.
94
+ #
95
+ # @param number [Integer] Индекс строки для удаления выбора.
96
+ def deselect(number)
97
+ begin
98
+ self.data_list.deselect(number)
99
+ self.logger.info "Выделение со строки: #{number} убрано"
100
+ self.view.update_button_states
101
+ rescue
102
+ self.logger.error "Ошибка при удалении выделения строки: #{number}"
103
+ end
104
+ end
105
+
106
+ # Получение списка ID выбранных студентов.
107
+ #
108
+ # @return [Array<Integer>] Список ID выбранных студентов.
109
+ def get_selected
110
+ selected = self.data_list.get_selected
111
+ self.logger.debug "Выделенные студенты: #{selected}"
112
+ selected
113
+ end
114
+
115
+ # Получение объекта студента по ID.
116
+ #
117
+ # @return [Student] Объект студента.
118
+ def get_student(id)
119
+ self.logger.info "Получение студента по id: #{id}"
120
+ student = self.entities_list.get_student_by_id(id)
121
+ self.logger.debug "Студент: #{student.to_line_s}"
122
+ student
123
+ end
124
+
125
+ # Изменение студента.
126
+ #
127
+ # @param student [Student] Объект студента для изменения.
128
+ def replace_student(student)
129
+ self.logger.info "Замена студента с id: #{student.id}"
130
+ self.logger.debug "Замена студента: #{student.to_line_s}"
131
+ self.entities_list.replace_student(student.id, student)
132
+ self.refresh_data
133
+ end
134
+
135
+ # Удаление выбранных студентов в таблице студентов.
136
+ def delete_student
137
+ ids = self.get_selected
138
+ begin
139
+ ids.each do |id|
140
+ self.logger.info "Удаление студента с id: #{id}"
141
+ self.entities_list.delete_student(id)
142
+ end
143
+ rescue => e
144
+ error_msg = "Ошибка при удалении: #{e.message}"
145
+ self.logger.error error_msg
146
+ self.view.show_error(error_msg)
147
+ ensure
148
+ self.refresh_data
149
+ self.check_and_update_page
150
+ end
151
+ end
152
+
153
+ # Проверка и, если нужно, смена страницы в таблице.
154
+ # Используется после удаления студента.
155
+ def check_and_update_page()
156
+ if self.view.current_page > self.view.total_pages
157
+ switch_page(-1)
158
+ end
159
+ end
160
+
161
+ # Изменение текущей страницы в таблице.
162
+ #
163
+ # @param direction [Integer] Направление для изменения страницы.
164
+ def switch_page(direction)
165
+ new_page = self.view.current_page + direction
166
+ if new_page < 1 || new_page > self.view.total_pages
167
+ return
168
+ end
169
+ self.logger.info "Переключение страницы на: #{new_page}"
170
+ self.view.current_page = new_page
171
+ self.refresh_data
172
+ end
173
+
174
+ # Применение фильтров.
175
+ def apply_filters
176
+ self.logger.info "Установка фильтров"
177
+ self.apply_full_name_filter
178
+ self.apply_git_filter
179
+ self.apply_email_filter
180
+ self.apply_phone_number_filter
181
+ self.apply_telegram_filter
182
+ self.apply_sort
183
+ end
184
+
185
+ # Сброс фильтров
186
+ def reset_filters
187
+ self.logger.info "Сброс фильтров"
188
+ self.filters = Filter.new
189
+ end
190
+
191
+ # Установка порядка сортировки и сортировка данных в таблице.
192
+ #
193
+ # @param column_index [Integer] Индекс столбца, по которому выполняется сортировка.
194
+ def set_sort_order(column_index)
195
+ if self.sort_order[:col_index] == column_index
196
+ self.sort_order[:order] = self.sort_order[:order] == :asc ? :desc : :asc
197
+ else
198
+ self.sort_order[:col_index] = column_index
199
+ self.sort_order[:order] = :asc
200
+ end
201
+ self.refresh_data
202
+ end
203
+
204
+ private
205
+ # @!attribute [rw] filters
206
+ # @return [Filter] Объект фильтра.
207
+ # @!attribute [rw] sort_order
208
+ # @return [Hash<Symbol, Object>, nil] Порядок сортировки.
209
+ attr_accessor :filters, :sort_order
210
+
211
+ # Устанавливка фильтра по полю ФИО.
212
+ def apply_full_name_filter
213
+ self.logger.info "Установка фильтра по ФИО: #{self.view.filters['name'][:text_field].text}"
214
+ name = self.view.filters['name'][:text_field].text
215
+ self.filters = Full_name_filter_decorator.new(self.filters, self.view.filters['name'][:text_field].text) unless name.nil? || name.empty?
216
+ end
217
+
218
+ # Устанавливка фильтра по полю.
219
+ #
220
+ # @param field_key [String] Ключ фильтра из view.
221
+ # @param filter_field [String] Имя поля.
222
+ # @param filter_type [Symbol] Тип поля.
223
+ def apply_field_filter(field_key, filter_field, filter_type = :text_field)
224
+ filter_config = self.view.filters[field_key]
225
+ flag = filter_config[:combo].currentItem
226
+ text = filter_config[filter_type].text.strip if filter_type == :text_field
227
+
228
+ case flag
229
+ when 0
230
+ return
231
+ when 1
232
+ self.logger.info "Установка фильтра по #{field_key} #{text}" unless text.nil? || text.empty?
233
+ self.filters = Field_filter_decorator.new(self.filters, filter_field, text) unless text.nil? || text.empty?
234
+ when 2
235
+ self.logger.info "Установка фильтра по #{field_key}: нет значения"
236
+ self.filters = Has_not_field_filter_decorator.new(self.filters, filter_field)
237
+ end
238
+ end
239
+
240
+ # Устанавливка фильтра по git.
241
+ def apply_git_filter
242
+ apply_field_filter('Git:', 'git')
243
+ end
244
+
245
+ # Устанавливка фильтра по email.
246
+ def apply_email_filter
247
+ apply_field_filter('Email:', 'email')
248
+ end
249
+
250
+ # Устанавливка фильтра по телефону.
251
+ def apply_phone_number_filter
252
+ apply_field_filter('Телефон:', 'phone_number')
253
+ end
254
+
255
+ # Устанавливка фильтра по telegram.
256
+ def apply_telegram_filter
257
+ apply_field_filter('Telegram:', 'telegram')
258
+ end
259
+
260
+ # Устанавливка сортировки.
261
+ def apply_sort
262
+ case self.sort_order[:col_index]
263
+ when 1
264
+ self.filters = Full_name_sort_decorator.new(self.filters, self.sort_order[:order])
265
+ when 2
266
+ self.filters = Git_sort_decorator.new(self.filters, self.sort_order[:order])
267
+ when 3
268
+ self.filters = Contact_sort_decorator.new(self.filters, self.sort_order[:order])
269
+ else
270
+ self.filters
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,46 @@
1
+ require 'date'
2
+ require_relative '../../models/student/student.rb'
3
+ require_relative './edit_contacts_presenter'
4
+
5
+ # == Add_student_presenter
6
+ # Презентер для добавления нового студента.
7
+ class Add_student_presenter < Edit_student_presenter
8
+
9
+ # Операция добавления нового студента.
10
+ #
11
+ # @param student_data [Hash] Данные студента.
12
+ def operation(student_data)
13
+ begin
14
+ self.logger.debug "Создание объекта студента: #{student_data.to_s}"
15
+ new_student(student_data)
16
+ self.parent_presenter.add_student(self.student)
17
+ self.view.close
18
+ rescue => e
19
+ error_msg = "Ошибка при добавлении студента: #{e.message}"
20
+ self.logger.error error_msg
21
+ self.view.show_error_message(error_msg)
22
+ end
23
+ end
24
+
25
+ # Заполнение полей интерфейса пустыми данными для нового студента.
26
+ def populate_fields
27
+ data = {
28
+ "first_name" => "",
29
+ "name" => "",
30
+ "patronymic" => "",
31
+ "birthdate" => "",
32
+ }
33
+ self.view.update_view data
34
+ end
35
+
36
+ # Проверка валидности данных студента при добавлении.
37
+ #
38
+ # @param student_data [Hash] Данные студента.
39
+ # @return [Boolean] Возвращает true, если данные валидны.
40
+ def valid_data?(student_data)
41
+ self.logger.debug "Проверка валидности данных: #{student_data.to_s}"
42
+ res = super(student_data)
43
+ self.logger.info "Валидность данных: #{res}"
44
+ res
45
+ end
46
+ end
@@ -0,0 +1,36 @@
1
+ require 'date'
2
+ require_relative '../../models/student/student.rb'
3
+ require_relative './edit_contacts_presenter'
4
+
5
+ # == Edit_contacts_presenter
6
+ # Презентер для редактирования контактной информации студента.
7
+ class Edit_contacts_presenter < Edit_student_presenter
8
+
9
+ # Заполнение полей интерфейса текущими контактами студента.
10
+ def populate_fields
11
+ self.get_student
12
+ data = {
13
+ "telegram" => self.student.telegram,
14
+ "email" => self.student.email,
15
+ "phone_number" => self.student.phone_number,
16
+ }
17
+ self.view.update_view data
18
+ end
19
+
20
+ # Проверка валидности контактных данных студента.
21
+ #
22
+ # @param student_data [Hash] Контактные данные студента.
23
+ # @return [Boolean] Возвращает true, если данные валидны.
24
+ def valid_data?(student_data)
25
+ data = student_data.transform_values { |value| value.strip }
26
+ self.logger.debug "Проверка валидности данных: #{data.to_s}"
27
+ valid = Student.valid_phone_number?(data["phone_number"]) && Student.valid_email?(data["email"]) &&
28
+ Student.valid_telegram?(data["telegram"])
29
+ unchanged = self.student.telegram == data["telegram"] &&
30
+ self.student.email == data["email"] &&
31
+ self.student.phone_number == data["phone_number"]
32
+ res = valid && !unchanged
33
+ self.logger.info "Валидность данных: #{res}"
34
+ res
35
+ end
36
+ end
@@ -0,0 +1,28 @@
1
+ require_relative '../../models/student/student.rb'
2
+ require_relative './edit_contacts_presenter'
3
+
4
+ # == Edit_git_presenter
5
+ # Презентер для редактирования информации о GitHub аккаунте студента.
6
+ class Edit_git_presenter < Edit_student_presenter
7
+
8
+ # Заполнение полей интерфейса текущими данными о Git студента.
9
+ def populate_fields
10
+ self.get_student
11
+ data = {
12
+ "git" => self.student.git,
13
+ }
14
+ self.view.update_view data
15
+ end
16
+
17
+ # Проверка валидности данных о Git.
18
+ #
19
+ # @param student_data [Hash] Данные о Git.
20
+ # @return [Boolean] Возвращает true, если данные валидны.
21
+ def valid_data?(student_data)
22
+ data = student_data.transform_values { |value| value.strip }
23
+ self.logger.debug "Проверка валидности данных: #{data.to_s}"
24
+ res = Student.valid_git?(data["git"]) && self.student.git != data["git"]
25
+ self.logger.info "Валидность данных: #{res}"
26
+ res
27
+ end
28
+ end