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.
- checksums.yaml +7 -0
- data/README.md +35 -0
- data/Rakefile +4 -0
- data/doc/Add_student_presenter.html +238 -0
- data/doc/App_logger.html +386 -0
- data/doc/Base_presenter.html +265 -0
- data/doc/Binary_tree.html +300 -0
- data/doc/Binary_tree_iterator.html +217 -0
- data/doc/Contact_sort_decorator.html +219 -0
- data/doc/DB_client.html +252 -0
- data/doc/Data_list.html +625 -0
- data/doc/Data_list_student_short.html +148 -0
- data/doc/Data_storage_strategy.html +178 -0
- data/doc/Data_table.html +264 -0
- data/doc/Deep_dup.html +152 -0
- data/doc/Edit_contacts_presenter.html +199 -0
- data/doc/Edit_git_presenter.html +192 -0
- data/doc/Edit_student_presenter.html +464 -0
- data/doc/Field_filter_decorator.html +219 -0
- data/doc/Filter.html +148 -0
- data/doc/Filter_decorator.html +209 -0
- data/doc/Full_name_filter_decorator.html +211 -0
- data/doc/Full_name_sort_decorator.html +217 -0
- data/doc/Gemfile.html +98 -0
- data/doc/Git_sort_decorator.html +220 -0
- data/doc/Has_not_field_filter_decorator.html +209 -0
- data/doc/JSON_storage_strategy.html +183 -0
- data/doc/Person.html +511 -0
- data/doc/README_md.html +147 -0
- data/doc/Rakefile.html +94 -0
- data/doc/Replace_student_presenter.html +204 -0
- data/doc/Sort_decorator.html +214 -0
- data/doc/Student.html +755 -0
- data/doc/StudentMvp/Error.html +105 -0
- data/doc/StudentMvp.html +111 -0
- data/doc/Student_list_presenter.html +667 -0
- data/doc/Student_short.html +398 -0
- data/doc/Students_list.html +341 -0
- data/doc/Students_list_DB.html +361 -0
- data/doc/Students_list_file.html +460 -0
- data/doc/Students_list_file_adapter.html +341 -0
- data/doc/Students_list_interface.html +298 -0
- data/doc/YAML_storage_strategy.html +183 -0
- data/doc/bin/setup.html +96 -0
- data/doc/created.rid +44 -0
- data/doc/css/fonts.css +167 -0
- data/doc/css/rdoc.css +662 -0
- data/doc/fonts/Lato-Light.ttf +0 -0
- data/doc/fonts/Lato-LightItalic.ttf +0 -0
- data/doc/fonts/Lato-Regular.ttf +0 -0
- data/doc/fonts/Lato-RegularItalic.ttf +0 -0
- data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
- data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
- data/doc/images/add.png +0 -0
- data/doc/images/arrow_up.png +0 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/delete.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_blue.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/transparent.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +174 -0
- data/doc/js/darkfish.js +114 -0
- data/doc/js/navigation.js +105 -0
- data/doc/js/navigation.js.gz +0 -0
- data/doc/js/search.js +110 -0
- data/doc/js/search_index.js +1 -0
- data/doc/js/search_index.js.gz +0 -0
- data/doc/js/searcher.js +229 -0
- data/doc/js/searcher.js.gz +0 -0
- data/doc/table_of_contents.html +1047 -0
- data/lib/data_access/DB_client/DB_client.rb +26 -0
- data/lib/deep_dup/deep_dup.rb +14 -0
- data/lib/logger/logger.rb +64 -0
- data/lib/models/binary_tree/binary_tree.rb +163 -0
- data/lib/models/binary_tree/binary_tree_iterator.rb +36 -0
- data/lib/models/data_list/data_list.rb +97 -0
- data/lib/models/data_list/data_list_student_short.rb +16 -0
- data/lib/models/data_storage_strategy/JSON_storage_strategy.rb +20 -0
- data/lib/models/data_storage_strategy/YAML_storage_strategy.rb +20 -0
- data/lib/models/data_storage_strategy/data_storage_strategy.rb +11 -0
- data/lib/models/data_table/data_table.rb +52 -0
- data/lib/models/filter/filter.rb +5 -0
- data/lib/models/filter/filter_decorator.rb +14 -0
- data/lib/models/filter/sort_decorator.rb +15 -0
- data/lib/models/filter/student_filters/contact_sort_decorator.rb +50 -0
- data/lib/models/filter/student_filters/field_filter_decorator.rb +34 -0
- data/lib/models/filter/student_filters/full_name_filter_decorator.rb +26 -0
- data/lib/models/filter/student_filters/full_name_sort_decorator.rb +32 -0
- data/lib/models/filter/student_filters/git_sort_decorator.rb +35 -0
- data/lib/models/filter/student_filters/has_not_field_filter_decorator.rb +24 -0
- data/lib/models/person/person.rb +72 -0
- data/lib/models/student/student.rb +204 -0
- data/lib/models/student_short/student_short.rb +98 -0
- data/lib/models/students_list/students_list.rb +32 -0
- data/lib/models/students_list/students_list_DB.rb +95 -0
- data/lib/models/students_list/students_list_file.rb +134 -0
- data/lib/models/students_list/students_list_file_adapter.rb +45 -0
- data/lib/models/students_list/students_list_interface.rb +25 -0
- data/lib/presenters/base_presenters/base_presenter.rb +26 -0
- data/lib/presenters/base_presenters/student_list_presenter.rb +273 -0
- data/lib/presenters/edit_student/add_student_presenter.rb +46 -0
- data/lib/presenters/edit_student/edit_contacts_presenter.rb +36 -0
- data/lib/presenters/edit_student/edit_git_presenter.rb +28 -0
- data/lib/presenters/edit_student/edit_student_presenter.rb +109 -0
- data/lib/presenters/edit_student/replace_student_presenter.rb +37 -0
- data/lib/student_mvp/version.rb +5 -0
- data/lib/student_mvp.rb +8 -0
- data/sig/student_mvp.rbs +4 -0
- 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
|