Description:
start update to 5.2
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r751:01b657de42d9 - - 29 files changed: 765 inserted, 140 deleted

@@ -0,0 +1,14
1 + %h1 New announcement
2 + = error_messages_for :announcement
3 + = simple_form_for(@announcement) do |f|
4 + .row
5 + .col-md-6
6 + = f.input :title
7 + = f.input :notes, label: 'Notes (shown internally, used to organize announcements)'
8 + = f.input :body
9 + = f.input :author
10 + = f.input :published
11 + = f.input :frontpage, label: 'Display in the front page only?'
12 + = f.input :contest_only, label: 'Display in contest only?'
13 + = f.button :submit, "Create", class: 'btn btn-primary'
14 + = link_to 'Back', announcements_path, class: 'btn btn-default'
@@ -0,0 +1,24
1 + %p
2 + %b Author:
3 + = h @announcement.author
4 + %p
5 + %b Title:
6 + = h @announcement.title
7 + %p
8 + %b Notes:
9 + = h @announcement.notes
10 + %p
11 + %b Body:
12 + = h markdown(@announcement.body)
13 + %p
14 + %b Published:
15 + = h @announcement.published
16 + %p
17 + %b Show on front page:
18 + = h @announcement.frontpage
19 + %p
20 + %b Show only in contest:
21 + = h @announcement.contest_only
22 + = link_to 'Edit', edit_announcement_path(@announcement)
23 + |
24 + = link_to 'Back', announcements_path
@@ -0,0 +1,179
1 + # frozen_string_literal: true
2 + #
3 + # Uncomment this and change the path if necessary to include your own
4 + # components.
5 + # See https://github.com/plataformatec/simple_form#custom-components to know
6 + # more about custom components.
7 + # Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
8 + #
9 + # Use this setup block to configure all options available in SimpleForm.
10 + SimpleForm.setup do |config|
11 + # Wrappers are used by the form builder to generate a
12 + # complete input. You can remove any component from the
13 + # wrapper, change the order or even add your own to the
14 + # stack. The options given below are used to wrap the
15 + # whole input.
16 + config.wrappers :default, class: :input,
17 + hint_class: :field_with_hint, error_class: :field_with_errors, valid_class: :field_without_errors do |b|
18 + ## Extensions enabled by default
19 + # Any of these extensions can be disabled for a
20 + # given input by passing: `f.input EXTENSION_NAME => false`.
21 + # You can make any of these extensions optional by
22 + # renaming `b.use` to `b.optional`.
23 +
24 + # Determines whether to use HTML5 (:email, :url, ...)
25 + # and required attributes
26 + b.use :html5
27 +
28 + # Calculates placeholders automatically from I18n
29 + # You can also pass a string as f.input placeholder: "Placeholder"
30 + b.use :placeholder
31 +
32 + ## Optional extensions
33 + # They are disabled unless you pass `f.input EXTENSION_NAME => true`
34 + # to the input. If so, they will retrieve the values from the model
35 + # if any exists. If you want to enable any of those
36 + # extensions by default, you can change `b.optional` to `b.use`.
37 +
38 + # Calculates maxlength from length validations for string inputs
39 + # and/or database column lengths
40 + b.optional :maxlength
41 +
42 + # Calculate minlength from length validations for string inputs
43 + b.optional :minlength
44 +
45 + # Calculates pattern from format validations for string inputs
46 + b.optional :pattern
47 +
48 + # Calculates min and max from length validations for numeric inputs
49 + b.optional :min_max
50 +
51 + # Calculates readonly automatically from readonly attributes
52 + b.optional :readonly
53 +
54 + ## Inputs
55 + # b.use :input, class: 'input', error_class: 'is-invalid', valid_class: 'is-valid'
56 + b.use :label_input
57 + b.use :hint, wrap_with: { tag: :span, class: :hint }
58 + b.use :error, wrap_with: { tag: :span, class: :error }
59 +
60 + ## full_messages_for
61 + # If you want to display the full error message for the attribute, you can
62 + # use the component :full_error, like:
63 + #
64 + # b.use :full_error, wrap_with: { tag: :span, class: :error }
65 + end
66 +
67 + # The default wrapper to be used by the FormBuilder.
68 + config.default_wrapper = :default
69 +
70 + # Define the way to render check boxes / radio buttons with labels.
71 + # Defaults to :nested for bootstrap config.
72 + # inline: input + label
73 + # nested: label > input
74 + config.boolean_style = :nested
75 +
76 + # Default class for buttons
77 + config.button_class = 'btn'
78 +
79 + # Method used to tidy up errors. Specify any Rails Array method.
80 + # :first lists the first message for each field.
81 + # Use :to_sentence to list all errors for each field.
82 + # config.error_method = :first
83 +
84 + # Default tag used for error notification helper.
85 + config.error_notification_tag = :div
86 +
87 + # CSS class to add for error notification helper.
88 + config.error_notification_class = 'error_notification'
89 +
90 + # Series of attempts to detect a default label method for collection.
91 + # config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
92 +
93 + # Series of attempts to detect a default value method for collection.
94 + # config.collection_value_methods = [ :id, :to_s ]
95 +
96 + # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
97 + # config.collection_wrapper_tag = nil
98 +
99 + # You can define the class to use on all collection wrappers. Defaulting to none.
100 + # config.collection_wrapper_class = nil
101 +
102 + # You can wrap each item in a collection of radio/check boxes with a tag,
103 + # defaulting to :span.
104 + # config.item_wrapper_tag = :span
105 +
106 + # You can define a class to use in all item wrappers. Defaulting to none.
107 + # config.item_wrapper_class = nil
108 +
109 + # How the label text should be generated altogether with the required text.
110 + # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }
111 +
112 + # You can define the class to use on all labels. Default is nil.
113 + # config.label_class = nil
114 +
115 + # You can define the default class to be used on forms. Can be overriden
116 + # with `html: { :class }`. Defaulting to none.
117 + # config.default_form_class = nil
118 +
119 + # You can define which elements should obtain additional classes
120 + # config.generate_additional_classes_for = [:wrapper, :label, :input]
121 +
122 + # Whether attributes are required by default (or not). Default is true.
123 + # config.required_by_default = true
124 +
125 + # Tell browsers whether to use the native HTML5 validations (novalidate form option).
126 + # These validations are enabled in SimpleForm's internal config but disabled by default
127 + # in this configuration, which is recommended due to some quirks from different browsers.
128 + # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations,
129 + # change this configuration to true.
130 + config.browser_validations = false
131 +
132 + # Collection of methods to detect if a file type was given.
133 + # config.file_methods = [ :mounted_as, :file?, :public_filename, :attached? ]
134 +
135 + # Custom mappings for input types. This should be a hash containing a regexp
136 + # to match as key, and the input type that will be used when the field name
137 + # matches the regexp as value.
138 + # config.input_mappings = { /count/ => :integer }
139 +
140 + # Custom wrappers for input types. This should be a hash containing an input
141 + # type as key and the wrapper that will be used for all inputs with specified type.
142 + # config.wrapper_mappings = { string: :prepend }
143 +
144 + # Namespaces where SimpleForm should look for custom input classes that
145 + # override default inputs.
146 + # config.custom_inputs_namespaces << "CustomInputs"
147 +
148 + # Default priority for time_zone inputs.
149 + # config.time_zone_priority = nil
150 +
151 + # Default priority for country inputs.
152 + # config.country_priority = nil
153 +
154 + # When false, do not use translations for labels.
155 + # config.translate_labels = true
156 +
157 + # Automatically discover new inputs in Rails' autoload path.
158 + # config.inputs_discovery = true
159 +
160 + # Cache SimpleForm inputs discovery
161 + # config.cache_discovery = !Rails.env.development?
162 +
163 + # Default class for inputs
164 + # config.input_class = nil
165 +
166 + # Define the default class of the input wrapper of the boolean input.
167 + config.boolean_label_class = 'checkbox'
168 +
169 + # Defines if the default input wrapper class should be included in radio
170 + # collection wrappers.
171 + # config.include_default_input_wrapper_class = true
172 +
173 + # Defines which i18n scope will be used in Simple Form.
174 + # config.i18n_scope = 'simple_form'
175 +
176 + # Defines validation classes to the input_field. By default it's nil.
177 + # config.input_field_valid_class = 'is-valid'
178 + # config.input_field_error_class = 'is-invalid'
179 + end
@@ -0,0 +1,439
1 + # frozen_string_literal: true
2 +
3 + # Please do not make direct changes to this file!
4 + # This generator is maintained by the community around simple_form-bootstrap:
5 + # https://github.com/rafaelfranca/simple_form-bootstrap
6 + # All future development, tests, and organization should happen there.
7 + # Background history: https://github.com/plataformatec/simple_form/issues/1561
8 +
9 + # Uncomment this and change the path if necessary to include your own
10 + # components.
11 + # See https://github.com/plataformatec/simple_form#custom-components
12 + # to know more about custom components.
13 + # Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
14 +
15 + # Use this setup block to configure all options available in SimpleForm.
16 + SimpleForm.setup do |config|
17 + # Default class for buttons
18 + config.button_class = 'btn'
19 +
20 + # Define the default class of the input wrapper of the boolean input.
21 + config.boolean_label_class = 'form-check-label'
22 +
23 + # How the label text should be generated altogether with the required text.
24 + config.label_text = lambda { |label, required, explicit_label| "#{label} #{required}" }
25 +
26 + # Define the way to render check boxes / radio buttons with labels.
27 + config.boolean_style = :inline
28 +
29 + # You can wrap each item in a collection of radio/check boxes with a tag
30 + config.item_wrapper_tag = :div
31 +
32 + # Defines if the default input wrapper class should be included in radio
33 + # collection wrappers.
34 + config.include_default_input_wrapper_class = false
35 +
36 + # CSS class to add for error notification helper.
37 + config.error_notification_class = 'alert alert-danger'
38 +
39 + # Method used to tidy up errors. Specify any Rails Array method.
40 + # :first lists the first message for each field.
41 + # :to_sentence to list all errors for each field.
42 + config.error_method = :to_sentence
43 +
44 + # add validation classes to `input_field`
45 + config.input_field_error_class = 'is-invalid'
46 + config.input_field_valid_class = 'is-valid'
47 +
48 +
49 + # vertical forms
50 + #
51 + # vertical default_wrapper
52 + config.wrappers :vertical_form, tag: 'div', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
53 + b.use :html5
54 + b.use :placeholder
55 + b.optional :maxlength
56 + b.optional :minlength
57 + b.optional :pattern
58 + b.optional :min_max
59 + b.optional :readonly
60 + b.use :label, class: 'form-control-label'
61 + b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
62 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
63 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
64 + end
65 +
66 + # vertical input for boolean
67 + config.wrappers :vertical_boolean, tag: 'fieldset', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
68 + b.use :html5
69 + b.optional :readonly
70 + b.wrapper :form_check_wrapper, tag: 'div', class: 'form-check' do |bb|
71 + bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
72 + bb.use :label, class: 'form-check-label'
73 + bb.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
74 + bb.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
75 + end
76 + end
77 +
78 + # vertical input for radio buttons and check boxes
79 + config.wrappers :vertical_collection, item_wrapper_class: 'form-check', tag: 'fieldset', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
80 + b.use :html5
81 + b.optional :readonly
82 + b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
83 + ba.use :label_text
84 + end
85 + b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
86 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
87 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
88 + end
89 +
90 + # vertical input for inline radio buttons and check boxes
91 + config.wrappers :vertical_collection_inline, item_wrapper_class: 'form-check form-check-inline', tag: 'fieldset', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
92 + b.use :html5
93 + b.optional :readonly
94 + b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
95 + ba.use :label_text
96 + end
97 + b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
98 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
99 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
100 + end
101 +
102 + # vertical file input
103 + config.wrappers :vertical_file, tag: 'div', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
104 + b.use :html5
105 + b.use :placeholder
106 + b.optional :maxlength
107 + b.optional :minlength
108 + b.optional :readonly
109 + b.use :label
110 + b.use :input, class: 'form-control-file', error_class: 'is-invalid', valid_class: 'is-valid'
111 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
112 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
113 + end
114 +
115 + # vertical multi select
116 + config.wrappers :vertical_multi_select, tag: 'div', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
117 + b.use :html5
118 + b.optional :readonly
119 + b.use :label, class: 'form-control-label'
120 + b.wrapper tag: 'div', class: 'd-flex flex-row justify-content-between align-items-center' do |ba|
121 + ba.use :input, class: 'form-control mx-1', error_class: 'is-invalid', valid_class: 'is-valid'
122 + end
123 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
124 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
125 + end
126 +
127 + # vertical range input
128 + config.wrappers :vertical_range, tag: 'div', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
129 + b.use :html5
130 + b.use :placeholder
131 + b.optional :readonly
132 + b.optional :step
133 + b.use :label
134 + b.use :input, class: 'form-control-range', error_class: 'is-invalid', valid_class: 'is-valid'
135 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
136 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
137 + end
138 +
139 +
140 + # horizontal forms
141 + #
142 + # horizontal default_wrapper
143 + config.wrappers :horizontal_form, tag: 'div', class: 'form-group row', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
144 + b.use :html5
145 + b.use :placeholder
146 + b.optional :maxlength
147 + b.optional :minlength
148 + b.optional :pattern
149 + b.optional :min_max
150 + b.optional :readonly
151 + b.use :label, class: 'col-sm-3 col-form-label'
152 + b.wrapper :grid_wrapper, tag: 'div', class: 'col-sm-9' do |ba|
153 + ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
154 + ba.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
155 + ba.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
156 + end
157 + end
158 +
159 + # horizontal input for boolean
160 + config.wrappers :horizontal_boolean, tag: 'div', class: 'form-group row', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
161 + b.use :html5
162 + b.optional :readonly
163 + b.wrapper tag: 'label', class: 'col-sm-3' do |ba|
164 + ba.use :label_text
165 + end
166 + b.wrapper :grid_wrapper, tag: 'div', class: 'col-sm-9' do |wr|
167 + wr.wrapper :form_check_wrapper, tag: 'div', class: 'form-check' do |bb|
168 + bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
169 + bb.use :label, class: 'form-check-label'
170 + bb.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
171 + bb.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
172 + end
173 + end
174 + end
175 +
176 + # horizontal input for radio buttons and check boxes
177 + config.wrappers :horizontal_collection, item_wrapper_class: 'form-check', tag: 'div', class: 'form-group row', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
178 + b.use :html5
179 + b.optional :readonly
180 + b.use :label, class: 'col-sm-3 form-control-label'
181 + b.wrapper :grid_wrapper, tag: 'div', class: 'col-sm-9' do |ba|
182 + ba.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
183 + ba.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
184 + ba.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
185 + end
186 + end
187 +
188 + # horizontal input for inline radio buttons and check boxes
189 + config.wrappers :horizontal_collection_inline, item_wrapper_class: 'form-check form-check-inline', tag: 'div', class: 'form-group row', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
190 + b.use :html5
191 + b.optional :readonly
192 + b.use :label, class: 'col-sm-3 form-control-label'
193 + b.wrapper :grid_wrapper, tag: 'div', class: 'col-sm-9' do |ba|
194 + ba.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
195 + ba.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
196 + ba.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
197 + end
198 + end
199 +
200 + # horizontal file input
201 + config.wrappers :horizontal_file, tag: 'div', class: 'form-group row', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
202 + b.use :html5
203 + b.use :placeholder
204 + b.optional :maxlength
205 + b.optional :minlength
206 + b.optional :readonly
207 + b.use :label, class: 'col-sm-3 form-control-label'
208 + b.wrapper :grid_wrapper, tag: 'div', class: 'col-sm-9' do |ba|
209 + ba.use :input, error_class: 'is-invalid', valid_class: 'is-valid'
210 + ba.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
211 + ba.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
212 + end
213 + end
214 +
215 + # horizontal multi select
216 + config.wrappers :horizontal_multi_select, tag: 'div', class: 'form-group row', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
217 + b.use :html5
218 + b.optional :readonly
219 + b.use :label, class: 'col-sm-3 control-label'
220 + b.wrapper :grid_wrapper, tag: 'div', class: 'col-sm-9' do |ba|
221 + ba.wrapper tag: 'div', class: 'd-flex flex-row justify-content-between align-items-center' do |bb|
222 + bb.use :input, class: 'form-control mx-1', error_class: 'is-invalid', valid_class: 'is-valid'
223 + end
224 + ba.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
225 + ba.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
226 + end
227 + end
228 +
229 + # horizontal range input
230 + config.wrappers :horizontal_range, tag: 'div', class: 'form-group row', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
231 + b.use :html5
232 + b.use :placeholder
233 + b.optional :readonly
234 + b.optional :step
235 + b.use :label, class: 'col-sm-3 form-control-label'
236 + b.wrapper :grid_wrapper, tag: 'div', class: 'col-sm-9' do |ba|
237 + ba.use :input, class: 'form-control-range', error_class: 'is-invalid', valid_class: 'is-valid'
238 + ba.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
239 + ba.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
240 + end
241 + end
242 +
243 +
244 + # inline forms
245 + #
246 + # inline default_wrapper
247 + config.wrappers :inline_form, tag: 'span', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
248 + b.use :html5
249 + b.use :placeholder
250 + b.optional :maxlength
251 + b.optional :minlength
252 + b.optional :pattern
253 + b.optional :min_max
254 + b.optional :readonly
255 + b.use :label, class: 'sr-only'
256 +
257 + b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
258 + b.use :error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
259 + b.optional :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
260 + end
261 +
262 + # inline input for boolean
263 + config.wrappers :inline_boolean, tag: 'span', class: 'form-check flex-wrap justify-content-start mr-sm-2', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
264 + b.use :html5
265 + b.optional :readonly
266 + b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'
267 + b.use :label, class: 'form-check-label'
268 + b.use :error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
269 + b.optional :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
270 + end
271 +
272 +
273 + # bootstrap custom forms
274 + #
275 + # custom input for boolean
276 + config.wrappers :custom_boolean, tag: 'fieldset', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
277 + b.use :html5
278 + b.optional :readonly
279 + b.wrapper :form_check_wrapper, tag: 'div', class: 'custom-control custom-checkbox' do |bb|
280 + bb.use :input, class: 'custom-control-input', error_class: 'is-invalid', valid_class: 'is-valid'
281 + bb.use :label, class: 'custom-control-label'
282 + bb.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
283 + bb.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
284 + end
285 + end
286 +
287 + config.wrappers :custom_boolean_switch, tag: 'fieldset', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
288 + b.use :html5
289 + b.optional :readonly
290 + b.wrapper :form_check_wrapper, tag: 'div', class: 'custom-control custom-checkbox-switch' do |bb|
291 + bb.use :input, class: 'custom-control-input', error_class: 'is-invalid', valid_class: 'is-valid'
292 + bb.use :label, class: 'custom-control-label'
293 + bb.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
294 + bb.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
295 + end
296 + end
297 +
298 + # custom input for radio buttons and check boxes
299 + config.wrappers :custom_collection, item_wrapper_class: 'custom-control', tag: 'fieldset', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
300 + b.use :html5
301 + b.optional :readonly
302 + b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
303 + ba.use :label_text
304 + end
305 + b.use :input, class: 'custom-control-input', error_class: 'is-invalid', valid_class: 'is-valid'
306 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
307 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
308 + end
309 +
310 + # custom input for inline radio buttons and check boxes
311 + config.wrappers :custom_collection_inline, item_wrapper_class: 'custom-control custom-control-inline', tag: 'fieldset', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
312 + b.use :html5
313 + b.optional :readonly
314 + b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|
315 + ba.use :label_text
316 + end
317 + b.use :input, class: 'custom-control-input', error_class: 'is-invalid', valid_class: 'is-valid'
318 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
319 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
320 + end
321 +
322 + # custom file input
323 + config.wrappers :custom_file, tag: 'div', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
324 + b.use :html5
325 + b.use :placeholder
326 + b.optional :maxlength
327 + b.optional :minlength
328 + b.optional :readonly
329 + b.use :label, class: 'form-control-label'
330 + b.wrapper :custom_file_wrapper, tag: 'div', class: 'custom-file' do |ba|
331 + ba.use :input, class: 'custom-file-input', error_class: 'is-invalid', valid_class: 'is-valid'
332 + ba.use :label, class: 'custom-file-label'
333 + ba.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
334 + end
335 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
336 + end
337 +
338 + # custom multi select
339 + config.wrappers :custom_multi_select, tag: 'div', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
340 + b.use :html5
341 + b.optional :readonly
342 + b.use :label, class: 'form-control-label'
343 + b.wrapper tag: 'div', class: 'd-flex flex-row justify-content-between align-items-center' do |ba|
344 + ba.use :input, class: 'custom-select mx-1', error_class: 'is-invalid', valid_class: 'is-valid'
345 + end
346 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
347 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
348 + end
349 +
350 + # custom range input
351 + config.wrappers :custom_range, tag: 'div', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
352 + b.use :html5
353 + b.use :placeholder
354 + b.optional :readonly
355 + b.optional :step
356 + b.use :label, class: 'form-control-label'
357 + b.use :input, class: 'custom-range', error_class: 'is-invalid', valid_class: 'is-valid'
358 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
359 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
360 + end
361 +
362 +
363 + # Input Group - custom component
364 + # see example app and config at https://github.com/rafaelfranca/simple_form-bootstrap
365 + # config.wrappers :input_group, tag: 'div', class: 'form-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
366 + # b.use :html5
367 + # b.use :placeholder
368 + # b.optional :maxlength
369 + # b.optional :minlength
370 + # b.optional :pattern
371 + # b.optional :min_max
372 + # b.optional :readonly
373 + # b.use :label, class: 'form-control-label'
374 + # b.wrapper :input_group_tag, tag: 'div', class: 'input-group' do |ba|
375 + # ba.optional :prepend
376 + # ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
377 + # ba.optional :append
378 + # end
379 + # b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback d-block' }
380 + # b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
381 + # end
382 +
383 +
384 + # Floating Labels form
385 + #
386 + # floating labels default_wrapper
387 + config.wrappers :floating_labels_form, tag: 'div', class: 'form-label-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
388 + b.use :html5
389 + b.use :placeholder
390 + b.optional :maxlength
391 + b.optional :minlength
392 + b.optional :pattern
393 + b.optional :min_max
394 + b.optional :readonly
395 + b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'
396 + b.use :label, class: 'form-control-label'
397 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
398 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
399 + end
400 +
401 + # custom multi select
402 + config.wrappers :floating_labels_select, tag: 'div', class: 'form-label-group', error_class: 'form-group-invalid', valid_class: 'form-group-valid' do |b|
403 + b.use :html5
404 + b.optional :readonly
405 + b.use :input, class: 'custom-select custom-select-lg', error_class: 'is-invalid', valid_class: 'is-valid'
406 + b.use :label, class: 'form-control-label'
407 + b.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }
408 + b.use :hint, wrap_with: { tag: 'small', class: 'form-text text-muted' }
409 + end
410 +
411 +
412 + # The default wrapper to be used by the FormBuilder.
413 + config.default_wrapper = :vertical_form
414 +
415 + # Custom wrappers for input types. This should be a hash containing an input
416 + # type as key and the wrapper that will be used for all inputs with specified type.
417 + config.wrapper_mappings = {
418 + boolean: :vertical_boolean,
419 + check_boxes: :vertical_collection,
420 + date: :vertical_multi_select,
421 + datetime: :vertical_multi_select,
422 + file: :vertical_file,
423 + radio_buttons: :vertical_collection,
424 + range: :vertical_range,
425 + time: :vertical_multi_select
426 + }
427 +
428 + # enable custom form wrappers
429 + # config.wrapper_mappings = {
430 + # boolean: :custom_boolean,
431 + # check_boxes: :custom_collection,
432 + # date: :custom_multi_select,
433 + # datetime: :custom_multi_select,
434 + # file: :custom_file,
435 + # radio_buttons: :custom_collection,
436 + # range: :custom_range,
437 + # time: :custom_multi_select
438 + # }
439 + end
@@ -0,0 +1,31
1 + en:
2 + simple_form:
3 + "yes": 'Yes'
4 + "no": 'No'
5 + required:
6 + text: 'required'
7 + mark: '*'
8 + # You can uncomment the line below if you need to overwrite the whole required html.
9 + # When using html, text and mark won't be used.
10 + # html: '<abbr title="required">*</abbr>'
11 + error_notification:
12 + default_message: "Please review the problems below:"
13 + # Examples
14 + # labels:
15 + # defaults:
16 + # password: 'Password'
17 + # user:
18 + # new:
19 + # email: 'E-mail to sign in.'
20 + # edit:
21 + # email: 'E-mail.'
22 + # hints:
23 + # defaults:
24 + # username: 'User name to sign in.'
25 + # password: 'No special characters, please.'
26 + # include_blanks:
27 + # defaults:
28 + # age: 'Rather not say'
29 + # prompts:
30 + # defaults:
31 + # age: 'Select your age'
@@ -0,0 +1,12
1 + -# frozen_string_literal: true
2 + = simple_form_for(@<%= singular_table_name %>) do |f|
3 + = f.error_notification
4 + = f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?
5 +
6 + .form-inputs
7 + <%- attributes.each do |attribute| -%>
8 + = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %>
9 + <%- end -%>
10 +
11 + .form-actions
12 + = f.button :submit
@@ -0,0 +1,5
1 + require "test_helper"
2 +
3 + class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
4 + driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
5 + end
@@ -0,0 +1,37
1 + require "application_system_test_case"
2 +
3 + class AnnouncementsTest < ApplicationSystemTestCase
4 + test "add new announcement" do
5 + visit root_path
6 + fill_in "Login", with: "admin"
7 + fill_in "Password", with: "admin"
8 + click_on "Login"
9 +
10 + assert_text "MAIN"
11 + assert_text "Submission"
12 +
13 + within :css, 'header' do
14 + click_on "Manage"
15 + click_on "Announcements"
16 + end
17 + assert_text "+ Add announcement"
18 +
19 + click_on "Add announcement", match: :first
20 +
21 + fill_in 'Title', with: 'test'
22 + fill_in 'Body', with: 'test body 12345'
23 + check 'Published'
24 +
25 + click_on 'Create'
26 +
27 + visit list_main_path
28 +
29 + assert_text "test body 12345"
30 +
31 + end
32 + # test "visiting the index" do
33 + # visit announcements_url
34 + #
35 + # assert_selector "h1", text: "Announcement"
36 + # end
37 + end
@@ -60,24 +60,25
60 #bootstrap add-ons
60 #bootstrap add-ons
61 gem 'bootstrap-sass', '~> 3.4.1'
61 gem 'bootstrap-sass', '~> 3.4.1'
62 gem 'bootstrap-switch-rails'
62 gem 'bootstrap-switch-rails'
63 gem 'bootstrap-toggle-rails'
63 gem 'bootstrap-toggle-rails'
64 gem 'autoprefixer-rails'
64 gem 'autoprefixer-rails'
65 gem 'momentjs-rails'
65 gem 'momentjs-rails'
66 gem 'rails_bootstrap_sortable'
66 gem 'rails_bootstrap_sortable'
67 gem 'bootstrap-datepicker-rails'
67 gem 'bootstrap-datepicker-rails'
68 gem 'bootstrap3-datetimepicker-rails'
68 gem 'bootstrap3-datetimepicker-rails'
69 gem 'jquery-datatables-rails'
69 gem 'jquery-datatables-rails'
70
70
71 #----------- user interface -----------------
71 #----------- user interface -----------------
72 + gem 'simple_form'
72 #select 2
73 #select 2
73 gem 'select2-rails'
74 gem 'select2-rails'
74 #ace editor
75 #ace editor
75 gem 'ace-rails-ap'
76 gem 'ace-rails-ap'
76 #paginator
77 #paginator
77 gem 'will_paginate', '~> 3.0.7'
78 gem 'will_paginate', '~> 3.0.7'
78
79
79 gem 'mail'
80 gem 'mail'
80 gem 'rdiscount'
81 gem 'rdiscount'
81 gem 'dynamic_form'
82 gem 'dynamic_form'
82 gem 'in_place_editing'
83 gem 'in_place_editing'
83 #gem 'verification', :git => 'https://github.com/sikachu/verification.git'
84 #gem 'verification', :git => 'https://github.com/sikachu/verification.git'
@@ -232,24 +232,27
232 sassc-rails (2.1.1)
232 sassc-rails (2.1.1)
233 railties (>= 4.0.0)
233 railties (>= 4.0.0)
234 sassc (>= 2.0)
234 sassc (>= 2.0)
235 sprockets (> 3.0)
235 sprockets (> 3.0)
236 sprockets-rails
236 sprockets-rails
237 tilt
237 tilt
238 select2-rails (4.0.3)
238 select2-rails (4.0.3)
239 thor (~> 0.14)
239 thor (~> 0.14)
240 selenium-webdriver (3.142.3)
240 selenium-webdriver (3.142.3)
241 childprocess (>= 0.5, < 2.0)
241 childprocess (>= 0.5, < 2.0)
242 rubyzip (~> 1.2, >= 1.2.2)
242 rubyzip (~> 1.2, >= 1.2.2)
243 sexp_processor (4.12.0)
243 sexp_processor (4.12.0)
244 + simple_form (4.1.0)
245 + actionpack (>= 5.0)
246 + activemodel (>= 5.0)
244 spring (2.1.0)
247 spring (2.1.0)
245 spring-watcher-listen (2.0.1)
248 spring-watcher-listen (2.0.1)
246 listen (>= 2.7, < 4.0)
249 listen (>= 2.7, < 4.0)
247 spring (>= 1.2, < 3.0)
250 spring (>= 1.2, < 3.0)
248 sprockets (3.7.2)
251 sprockets (3.7.2)
249 concurrent-ruby (~> 1.0)
252 concurrent-ruby (~> 1.0)
250 rack (> 1, < 3)
253 rack (> 1, < 3)
251 sprockets-rails (3.2.1)
254 sprockets-rails (3.2.1)
252 actionpack (>= 4.0)
255 actionpack (>= 4.0)
253 activesupport (>= 4.0)
256 activesupport (>= 4.0)
254 sprockets (>= 3.0.0)
257 sprockets (>= 3.0.0)
255 sqlite3 (1.4.1)
258 sqlite3 (1.4.1)
@@ -311,23 +314,24
311 minitest-reporters
314 minitest-reporters
312 momentjs-rails
315 momentjs-rails
313 mysql2
316 mysql2
314 puma
317 puma
315 rails (~> 5.2)
318 rails (~> 5.2)
316 rails-controller-testing
319 rails-controller-testing
317 rails_bootstrap_sortable
320 rails_bootstrap_sortable
318 rdiscount
321 rdiscount
319 rouge
322 rouge
320 sassc-rails
323 sassc-rails
321 select2-rails
324 select2-rails
322 selenium-webdriver
325 selenium-webdriver
326 + simple_form
323 spring
327 spring
324 spring-watcher-listen (~> 2.0.0)
328 spring-watcher-listen (~> 2.0.0)
325 sqlite3
329 sqlite3
326 uglifier
330 uglifier
327 web-console (>= 3.3.0)
331 web-console (>= 3.3.0)
328 webdriver
332 webdriver
329 will_paginate (~> 3.0.7)
333 will_paginate (~> 3.0.7)
330 yaml_db
334 yaml_db
331
335
332 BUNDLED WITH
336 BUNDLED WITH
333 1.17.2
337 1.17.2
@@ -1,23 +1,16
1 class GradersController < ApplicationController
1 class GradersController < ApplicationController
2
2
3 before_action :admin_authorization
3 before_action :admin_authorization
4
4
5 - verify :method => :post, :only => ['clear_all',
6 - 'start_exam',
7 - 'start_grading',
8 - 'stop_all',
9 - 'clear_terminated'],
10 - :redirect_to => {:action => 'index'}
11 -
12 def index
5 def index
13 redirect_to :action => 'list'
6 redirect_to :action => 'list'
14 end
7 end
15
8
16 def list
9 def list
17 @grader_processes = GraderProcess.find_running_graders
10 @grader_processes = GraderProcess.find_running_graders
18 @stalled_processes = GraderProcess.find_stalled_process
11 @stalled_processes = GraderProcess.find_stalled_process
19
12
20 @terminated_processes = GraderProcess.find_terminated_graders
13 @terminated_processes = GraderProcess.find_terminated_graders
21
14
22 @last_task = Task.last
15 @last_task = Task.last
23 @last_test_request = TestRequest.last
16 @last_test_request = TestRequest.last
@@ -6,33 +6,24
6 append_before_action :confirm_and_update_start_time,
6 append_before_action :confirm_and_update_start_time,
7 :except => [:index,
7 :except => [:index,
8 :login,
8 :login,
9 :confirm_contest_start]
9 :confirm_contest_start]
10
10
11 # to prevent log in box to be shown when user logged out of the
11 # to prevent log in box to be shown when user logged out of the
12 # system only in some tab
12 # system only in some tab
13 prepend_before_action :reject_announcement_refresh_when_logged_out,
13 prepend_before_action :reject_announcement_refresh_when_logged_out,
14 :only => [:announcements]
14 :only => [:announcements]
15
15
16 before_action :authenticate_by_ip_address, :only => [:list]
16 before_action :authenticate_by_ip_address, :only => [:list]
17
17
18 - # COMMENTED OUT: filter in each action instead
19 - # before_filter :verify_time_limit, :only => [:submit]
20 -
21 - verify :method => :post, :only => [:submit],
22 - :redirect_to => { :action => :index }
23 -
24 - # COMMENT OUT: only need when having high load
25 - # caches_action :index, :login
26 -
27 # NOTE: This method is not actually needed, 'config/routes.rb' has
18 # NOTE: This method is not actually needed, 'config/routes.rb' has
28 # assigned action login as a default action.
19 # assigned action login as a default action.
29 def index
20 def index
30 redirect_to :action => 'login'
21 redirect_to :action => 'login'
31 end
22 end
32
23
33 def login
24 def login
34 saved_notice = flash[:notice]
25 saved_notice = flash[:notice]
35 reset_session
26 reset_session
36 flash.now[:notice] = saved_notice
27 flash.now[:notice] = saved_notice
37
28
38 # EXPERIMENT:
29 # EXPERIMENT:
@@ -1,18 +1,16
1 class MessagesController < ApplicationController
1 class MessagesController < ApplicationController
2
2
3 before_action :authenticate
3 before_action :authenticate
4
4
5 - verify :method => :post, :only => ['create'],
6 - :redirect_to => { :action => 'list' }
7
5
8 before_filter :admin_authorization, :only => ['console','show',
6 before_filter :admin_authorization, :only => ['console','show',
9 'reply','hide','list_all']
7 'reply','hide','list_all']
10
8
11 def list
9 def list
12 @user = User.find(session[:user_id])
10 @user = User.find(session[:user_id])
13 @messages = Message.find_all_sent_by_user(@user)
11 @messages = Message.find_all_sent_by_user(@user)
14 end
12 end
15
13
16 def console
14 def console
17 @user = User.find(session[:user_id])
15 @user = User.find(session[:user_id])
18 @messages = Message.find_all_system_unreplied_messages
16 @messages = Message.find_all_system_unreplied_messages
@@ -2,43 +2,37
2
2
3 before_action :authenticate, :authorization
3 before_action :authenticate, :authorization
4 before_action :testcase_authorization, only: [:show_testcase]
4 before_action :testcase_authorization, only: [:show_testcase]
5
5
6 in_place_edit_for :problem, :name
6 in_place_edit_for :problem, :name
7 in_place_edit_for :problem, :full_name
7 in_place_edit_for :problem, :full_name
8 in_place_edit_for :problem, :full_score
8 in_place_edit_for :problem, :full_score
9
9
10 def index
10 def index
11 @problems = Problem.order(date_added: :desc)
11 @problems = Problem.order(date_added: :desc)
12 end
12 end
13
13
14 - # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
15 - verify :method => :post, :only => [ :create, :quick_create,
16 - :do_manage,
17 - :do_import,
18 - ],
19 - :redirect_to => { :action => :index }
20
14
21 def show
15 def show
22 @problem = Problem.find(params[:id])
16 @problem = Problem.find(params[:id])
23 end
17 end
24
18
25 def new
19 def new
26 @problem = Problem.new
20 @problem = Problem.new
27 @description = nil
21 @description = nil
28 end
22 end
29
23
30 def create
24 def create
31 @problem = Problem.new(problem_params)
25 @problem = Problem.new(problem_params)
32 - @description = Description.new(params[:description])
26 + @description = Description.new(problem_params[:description])
33 if @description.body!=''
27 if @description.body!=''
34 if !@description.save
28 if !@description.save
35 render :action => new and return
29 render :action => new and return
36 end
30 end
37 else
31 else
38 @description = nil
32 @description = nil
39 end
33 end
40 @problem.description = @description
34 @problem.description = @description
41 if @problem.save
35 if @problem.save
42 flash[:notice] = 'Problem was successfully created.'
36 flash[:notice] = 'Problem was successfully created.'
43 redirect_to action: :index
37 redirect_to action: :index
44 else
38 else
@@ -1,23 +1,16
1 class TestController < ApplicationController
1 class TestController < ApplicationController
2
2
3 before_action :authenticate, :check_viewability
3 before_action :authenticate, :check_viewability
4
4
5 - #
6 - # COMMENT OUT: filter in each action instead
7 - #
8 - # before_filter :verify_time_limit, :only => [:submit]
9 -
10 - verify :method => :post, :only => [:submit],
11 - :redirect_to => { :action => :index }
12
5
13 def index
6 def index
14 prepare_index_information
7 prepare_index_information
15 end
8 end
16
9
17 def submit
10 def submit
18 @user = User.find(session[:user_id])
11 @user = User.find(session[:user_id])
19
12
20 @submitted_test_request = TestRequest.new_from_form_params(@user,params[:test_request])
13 @submitted_test_request = TestRequest.new_from_form_params(@user,params[:test_request])
21
14
22 if ! @submitted_test_request.errors.empty?
15 if ! @submitted_test_request.errors.empty?
23 prepare_index_information
16 prepare_index_information
@@ -1,29 +1,20
1 require 'csv'
1 require 'csv'
2
2
3 class UserAdminController < ApplicationController
3 class UserAdminController < ApplicationController
4
4
5 include MailHelperMethods
5 include MailHelperMethods
6
6
7 before_action :admin_authorization
7 before_action :admin_authorization
8
8
9 - # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
10 - verify :method => :post, :only => [
11 - :create, :create_from_list,
12 - :update,
13 - :manage_contest,
14 - :bulk_mail
15 - ],
16 - :redirect_to => { :action => :list }
17 -
18 def index
9 def index
19 @user_count = User.count
10 @user_count = User.count
20 if params[:page] == 'all'
11 if params[:page] == 'all'
21 @users = User.all
12 @users = User.all
22 @paginated = false
13 @paginated = false
23 else
14 else
24 @users = User.paginate :page => params[:page]
15 @users = User.paginate :page => params[:page]
25 @paginated = true
16 @paginated = true
26 end
17 end
27 @users = User.all
18 @users = User.all
28 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
19 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
29 @contests = Contest.enabled
20 @contests = Contest.enabled
@@ -10,27 +10,24
10 :forget,
10 :forget,
11 :retrieve_password]
11 :retrieve_password]
12
12
13 before_action :verify_online_registration, :only => [:new,
13 before_action :verify_online_registration, :only => [:new,
14 :register,
14 :register,
15 :forget,
15 :forget,
16 :retrieve_password]
16 :retrieve_password]
17 before_action :authenticate, :profile_authorization, only: [:profile]
17 before_action :authenticate, :profile_authorization, only: [:profile]
18
18
19 before_action :admin_authorization, only: [:stat, :toggle_activate, :toggle_enable]
19 before_action :admin_authorization, only: [:stat, :toggle_activate, :toggle_enable]
20
20
21
21
22 - verify :method => :post, :only => [:chg_passwd],
23 - :redirect_to => { :action => :index }
24 -
25 #in_place_edit_for :user, :alias_for_editing
22 #in_place_edit_for :user, :alias_for_editing
26 #in_place_edit_for :user, :email_for_editing
23 #in_place_edit_for :user, :email_for_editing
27
24
28 def index
25 def index
29 if !GraderConfiguration['system.user_setting_enabled']
26 if !GraderConfiguration['system.user_setting_enabled']
30 redirect_to :controller => 'main', :action => 'list'
27 redirect_to :controller => 'main', :action => 'list'
31 else
28 else
32 @user = User.find(session[:user_id])
29 @user = User.find(session[:user_id])
33 end
30 end
34 end
31 end
35
32
36 def chg_passwd
33 def chg_passwd
@@ -1,13 +1,13
1 class Group < ActiveRecord::Base
1 class Group < ActiveRecord::Base
2 - has_many :groups_problems, class_name: GroupProblem
2 + has_many :groups_problems, class_name: 'GroupProblem'
3 has_many :problems, :through => :groups_problems
3 has_many :problems, :through => :groups_problems
4
4
5 - has_many :groups_users, class_name: GroupUser
5 + has_many :groups_users, class_name: 'GroupUser'
6 has_many :users, :through => :groups_users
6 has_many :users, :through => :groups_users
7
7
8 #has_and_belongs_to_many :problems
8 #has_and_belongs_to_many :problems
9 #has_and_belongs_to_many :users
9 #has_and_belongs_to_many :users
10
10
11
11
12 end
12 end
13
13
@@ -1,22 +1,22
1 class Problem < ActiveRecord::Base
1 class Problem < ActiveRecord::Base
2
2
3 belongs_to :description
3 belongs_to :description
4 has_and_belongs_to_many :contests, :uniq => true
4 has_and_belongs_to_many :contests, :uniq => true
5
5
6 #has_and_belongs_to_many :groups
6 #has_and_belongs_to_many :groups
7 - has_many :groups_problems, class_name: GroupProblem
7 + has_many :groups_problems, class_name: 'GroupProblem'
8 has_many :groups, :through => :groups_problems
8 has_many :groups, :through => :groups_problems
9
9
10 - has_many :problems_tags, class_name: ProblemTag
10 + has_many :problems_tags, class_name: 'ProblemTag'
11 has_many :tags, through: :problems_tags
11 has_many :tags, through: :problems_tags
12
12
13 has_many :test_pairs, :dependent => :delete_all
13 has_many :test_pairs, :dependent => :delete_all
14 has_many :testcases, :dependent => :destroy
14 has_many :testcases, :dependent => :destroy
15
15
16 has_many :submissions
16 has_many :submissions
17
17
18 validates_presence_of :name
18 validates_presence_of :name
19 validates_format_of :name, :with => /\A\w+\z/
19 validates_format_of :name, :with => /\A\w+\z/
20 validates_presence_of :full_name
20 validates_presence_of :full_name
21
21
22 scope :available, -> { where(available: true) }
22 scope :available, -> { where(available: true) }
@@ -1,4 +1,4
1 class Tag < ActiveRecord::Base
1 class Tag < ActiveRecord::Base
2 - has_many :problems_tags, class_name: ProblemTag
2 + has_many :problems_tags, class_name: 'ProblemTag'
3 has_many :problems, through: :problems_tags
3 has_many :problems, through: :problems_tags
4 end
4 end
@@ -1,24 +1,24
1 require 'digest/sha1'
1 require 'digest/sha1'
2 require 'net/pop'
2 require 'net/pop'
3 require 'net/https'
3 require 'net/https'
4 require 'net/http'
4 require 'net/http'
5 require 'json'
5 require 'json'
6
6
7 class User < ActiveRecord::Base
7 class User < ActiveRecord::Base
8
8
9 has_and_belongs_to_many :roles
9 has_and_belongs_to_many :roles
10
10
11 #has_and_belongs_to_many :groups
11 #has_and_belongs_to_many :groups
12 - has_many :groups_users, class_name: GroupUser
12 + has_many :groups_users, class_name: 'GroupUser'
13 has_many :groups, :through => :groups_users
13 has_many :groups, :through => :groups_users
14
14
15 has_many :test_requests, -> {order(submitted_at: :desc)}
15 has_many :test_requests, -> {order(submitted_at: :desc)}
16
16
17 has_many :messages, -> { order(created_at: :desc) },
17 has_many :messages, -> { order(created_at: :desc) },
18 :class_name => "Message",
18 :class_name => "Message",
19 :foreign_key => "sender_id"
19 :foreign_key => "sender_id"
20
20
21 has_many :replied_messages, -> { order(created_at: :desc) },
21 has_many :replied_messages, -> { order(created_at: :desc) },
22 :class_name => "Message",
22 :class_name => "Message",
23 :foreign_key => "receiver_id"
23 :foreign_key => "receiver_id"
24
24
@@ -1,23 +1,23
1 - content_for :head do
1 - content_for :head do
2 = stylesheet_link_tag 'problems'
2 = stylesheet_link_tag 'problems'
3 %h1 Problems
3 %h1 Problems
4 %p
4 %p
5 = link_to 'Import problems', {:action => 'import'}, class: 'btn btn-success btn-sm'
5 = link_to 'Import problems', {:action => 'import'}, class: 'btn btn-success btn-sm'
6 = link_to 'New problem', new_problem_path, class: 'btn btn-success btn-sm'
6 = link_to 'New problem', new_problem_path, class: 'btn btn-success btn-sm'
7 = link_to 'Bulk Manage', { action: 'manage'}, class: 'btn btn-info btn-sm'
7 = link_to 'Bulk Manage', { action: 'manage'}, class: 'btn btn-info btn-sm'
8 = link_to 'Turn off all problems', {:action => 'turn_all_off'}, class: 'btn btn-default btn-sm'
8 = link_to 'Turn off all problems', {:action => 'turn_all_off'}, class: 'btn btn-default btn-sm'
9 = link_to 'Turn on all problems', {:action => 'turn_all_on'}, class: 'btn btn-default btn-sm'
9 = link_to 'Turn on all problems', {:action => 'turn_all_on'}, class: 'btn btn-default btn-sm'
10 .submitbox
10 .submitbox
11 - = form_tag :action => 'quick_create' do
11 + = form_tag action: 'quick_create', controller: 'problems' do
12 %b Quick New:
12 %b Quick New:
13 %label{:for => "problem_name"} Name
13 %label{:for => "problem_name"} Name
14 = text_field 'problem', 'name'
14 = text_field 'problem', 'name'
15 |
15 |
16 %label{:for => "problem_full_name"} Full name
16 %label{:for => "problem_full_name"} Full name
17 = text_field 'problem', 'full_name'
17 = text_field 'problem', 'full_name'
18 = submit_tag "Create"
18 = submit_tag "Create"
19 %table.table.table-condense.table-hover
19 %table.table.table-condense.table-hover
20 %thead
20 %thead
21 %th Name
21 %th Name
22 %th Full name
22 %th Full name
23 %th.text-right Full score
23 %th.text-right Full score
@@ -1,8 +1,8
1 <h1>New problem</h1>
1 <h1>New problem</h1>
2
2
3 <%= form_tag :action => 'create' do %>
3 <%= form_tag :action => 'create' do %>
4 <%= render :partial => 'form' %>
4 <%= render :partial => 'form' %>
5 <%= submit_tag "Create" %>
5 <%= submit_tag "Create" %>
6 <% end %>
6 <% end %>
7
7
8 - <%= link_to 'Back', :action => 'list' %>
8 + <%= link_to 'Back', problems_path %>
@@ -1,13 +1,13
1 %h1 Editing user
1 %h1 Editing user
2
2
3 = form_tag( {:action => 'update', :id => @user}, {class: 'form-horizontal'}) do
3 = form_tag( {:action => 'update', :id => @user}, {class: 'form-horizontal'}) do
4 = error_messages_for 'user'
4 = error_messages_for 'user'
5 = render partial: "form"
5 = render partial: "form"
6 .form-group
6 .form-group
7 .col-md-offset-2.col-md-4
7 .col-md-offset-2.col-md-4
8 = submit_tag "Edit", class: 'btn btn-primary'
8 = submit_tag "Edit", class: 'btn btn-primary'
9
9
10
10
11 = link_to 'Show', :action => 'show', :id => @user
11 = link_to 'Show', :action => 'show', :id => @user
12 |
12 |
13 - = link_to 'Back', :action => 'list'
13 + = link_to 'Back', :action => 'index'
@@ -13,13 +13,13
13
13
14 # Enable origin-checking CSRF mitigation. Previous versions had false.
14 # Enable origin-checking CSRF mitigation. Previous versions had false.
15 Rails.application.config.action_controller.forgery_protection_origin_check = false
15 Rails.application.config.action_controller.forgery_protection_origin_check = false
16
16
17 # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
17 # Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
18 # Previous versions had false.
18 # Previous versions had false.
19 ActiveSupport.to_time_preserves_timezone = false
19 ActiveSupport.to_time_preserves_timezone = false
20
20
21 # Require `belongs_to` associations by default. Previous versions had false.
21 # Require `belongs_to` associations by default. Previous versions had false.
22 Rails.application.config.active_record.belongs_to_required_by_default = false
22 Rails.application.config.active_record.belongs_to_required_by_default = false
23
23
24 # Do not halt callback chains when a callback returns false. Previous versions had true.
24 # Do not halt callback chains when a callback returns false. Previous versions had true.
25 - ActiveSupport.halt_callback_chains_on_return_false = true
25 + # ActiveSupport.halt_callback_chains_on_return_false = true
@@ -29,24 +29,26
29 resources :problems do
29 resources :problems do
30 member do
30 member do
31 get 'toggle'
31 get 'toggle'
32 get 'toggle_test'
32 get 'toggle_test'
33 get 'toggle_view_testcase'
33 get 'toggle_view_testcase'
34 get 'stat'
34 get 'stat'
35 end
35 end
36 collection do
36 collection do
37 get 'turn_all_off'
37 get 'turn_all_off'
38 get 'turn_all_on'
38 get 'turn_all_on'
39 get 'import'
39 get 'import'
40 get 'manage'
40 get 'manage'
41 + get 'quick_create'
42 + post 'do_manage'
41 end
43 end
42 end
44 end
43
45
44 resources :groups do
46 resources :groups do
45 member do
47 member do
46 post 'add_user', to: 'groups#add_user', as: 'add_user'
48 post 'add_user', to: 'groups#add_user', as: 'add_user'
47 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
49 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
48 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
50 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
49 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
51 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
50 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
52 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
51 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
53 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
52 end
54 end
@@ -83,32 +85,34
83 collection do
85 collection do
84 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
86 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
85 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
87 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
86 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
88 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
87 end
89 end
88 end
90 end
89
91
90
92
91 #user admin
93 #user admin
92 resources :user_admin do
94 resources :user_admin do
93 collection do
95 collection do
94 match 'bulk_manage', via: [:get, :post]
96 match 'bulk_manage', via: [:get, :post]
97 + get 'bulk_mail'
95 get 'user_stat'
98 get 'user_stat'
96 get 'import'
99 get 'import'
97 get 'new_list'
100 get 'new_list'
98 get 'admin'
101 get 'admin'
99 get 'random_all_passwords'
102 get 'random_all_passwords'
100 get 'active'
103 get 'active'
101 get 'mass_mailing'
104 get 'mass_mailing'
102 match 'create_from_list', via: [:get, :post]
105 match 'create_from_list', via: [:get, :post]
106 + post 'grant_admin'
103 end
107 end
104 member do
108 member do
105 get 'clear_last_ip'
109 get 'clear_last_ip'
106 end
110 end
107 end
111 end
108
112
109 resources :contest_management, only: [:index] do
113 resources :contest_management, only: [:index] do
110 collection do
114 collection do
111 get 'user_stat'
115 get 'user_stat'
112 get 'clear_stat'
116 get 'clear_stat'
113 get 'clear_all_stat'
117 get 'clear_all_stat'
114 end
118 end
@@ -1,27 +1,28
1 - ENV["RAILS_ENV"] = "test"
1 + ENV['RAILS_ENV'] ||= 'test'
2 - require File.expand_path('../../config/environment', __FILE__)
2 + require_relative '../config/environment'
3 require 'rails/test_help'
3 require 'rails/test_help'
4
4
5 #reporter for beautiful result
5 #reporter for beautiful result
6 require "minitest/reporters"
6 require "minitest/reporters"
7 Minitest::Reporters.use!
7 Minitest::Reporters.use!
8
8
9 module SignInHelper
9 module SignInHelper
10 def sign_in_as(user,password)
10 def sign_in_as(user,password)
11 post login_login_path, {login: user, password: password }
11 post login_login_path, {login: user, password: password }
12 end
12 end
13 end
13 end
14
14
15 class ActiveSupport::TestCase
15 class ActiveSupport::TestCase
16 include SignInHelper
16 include SignInHelper
17 # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
17 # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
18 #
18 #
19 # Note: You'll currently still have to declare fixtures explicitly in integration tests
19 # Note: You'll currently still have to declare fixtures explicitly in integration tests
20 # -- they do not yet inherit this setting
20 # -- they do not yet inherit this setting
21 fixtures :all
21 fixtures :all
22
22
23 # Add more helper methods to be used by all tests here...
23 # Add more helper methods to be used by all tests here...
24
24
25 - self.use_transactional_fixtures = true
25 + self.use_transactional_tests = true
26 + #self.use_instantiated_fixtures = false
26 self.use_instantiated_fixtures = false
27 self.use_instantiated_fixtures = false
27 end
28 end
deleted file
deleted file
You need to be logged in to leave comments. Login now