decidim-core 0.0.1 → 0.0.2
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 +4 -4
- data/Rakefile +1 -1
- data/app/assets/config/decidim_core_manifest.js +1 -0
- data/app/assets/javascripts/decidim.js.es6 +3 -2
- data/app/assets/javascripts/decidim/append_elements.js.es6 +8 -0
- data/app/assets/javascripts/decidim/filters.js.es6 +22 -0
- data/app/assets/javascripts/decidim/form_filter.component.js.es6 +176 -0
- data/app/assets/javascripts/decidim/form_filter.component.test.js +151 -0
- data/app/assets/javascripts/decidim/inline_svg.js.es6 +12 -0
- data/app/assets/javascripts/decidim/user_registrations.js.es6 +22 -0
- data/app/assets/stylesheets/decidim/_variables.scss +1 -1
- data/app/assets/stylesheets/decidim/modules/_comments.scss +3 -6
- data/app/assets/stylesheets/decidim/modules/_cookie-bar.scss +22 -0
- data/app/assets/stylesheets/decidim/modules/_layout.scss +9 -1
- data/app/assets/stylesheets/decidim/modules/_navbar.scss +8 -5
- data/app/assets/stylesheets/decidim/modules/_order-by.scss +0 -1
- data/app/assets/stylesheets/decidim/modules/_process-phase.scss +4 -0
- data/app/assets/stylesheets/decidim/modules/_timeline.scss +62 -80
- data/app/assets/stylesheets/decidim/modules/_typography.scss +20 -31
- data/app/assets/stylesheets/decidim/utils/_fontface.scss +4 -16
- data/app/assets/stylesheets/decidim/utils/_settings.scss +29 -26
- data/app/assets/stylesheets/decidim/utils/_variables.scss +22 -0
- data/app/commands/decidim/authorize_user.rb +17 -1
- data/app/commands/decidim/create_omniauth_registration.rb +92 -0
- data/app/commands/decidim/create_registration.rb +50 -0
- data/app/commands/decidim/invite_user.rb +50 -0
- data/app/commands/decidim/invite_user_again.rb +25 -0
- data/app/commands/decidim/remove_user_role.rb +26 -0
- data/app/controllers/concerns/decidim/feature_settings.rb +27 -0
- data/app/controllers/concerns/decidim/filter_resource.rb +71 -0
- data/app/controllers/concerns/decidim/form_factory.rb +21 -18
- data/app/controllers/concerns/decidim/needs_participatory_process.rb +2 -3
- data/app/controllers/decidim/devise/confirmations_controller.rb +2 -0
- data/app/controllers/decidim/devise/invitations_controller.rb +4 -0
- data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +96 -0
- data/app/controllers/decidim/devise/passwords_controller.rb +2 -0
- data/app/controllers/decidim/devise/registrations_controller.rb +34 -0
- data/app/controllers/decidim/devise/sessions_controller.rb +1 -0
- data/app/controllers/decidim/pages_controller.rb +10 -2
- data/app/controllers/decidim/participatory_process_steps_controller.rb +16 -0
- data/app/controllers/decidim/participatory_processes_controller.rb +6 -11
- data/app/forms/decidim/form.rb +6 -6
- data/app/forms/decidim/invite_admin_form.rb +37 -0
- data/app/forms/decidim/omniauth_registration_form.rb +24 -0
- data/app/forms/decidim/registration_form.rb +41 -0
- data/app/helpers/decidim/filters_helper.rb +21 -0
- data/app/helpers/decidim/layout_helper.rb +17 -1
- data/app/helpers/decidim/omniauth_helper.rb +23 -0
- data/app/helpers/decidim/paginate_helper.rb +21 -0
- data/app/helpers/decidim/participatory_process_helper.rb +14 -0
- data/app/helpers/decidim/participatory_process_steps_helper.rb +17 -0
- data/app/mailers/decidim/decidim_devise_mailer.rb +2 -2
- data/app/models/decidim/feature.rb +40 -0
- data/app/models/decidim/identity.rb +12 -0
- data/app/models/decidim/organization.rb +3 -10
- data/app/models/decidim/user.rb +3 -1
- data/app/models/decidim/user_group.rb +18 -0
- data/app/models/decidim/user_group_membership.rb +9 -0
- data/app/services/decidim/authorization_handler.rb +13 -13
- data/app/services/decidim/resource_search.rb +52 -0
- data/app/uploaders/decidim/organization_logo_uploader.rb +1 -1
- data/app/views/decidim/authorizations/new.html.erb +3 -1
- data/app/views/decidim/devise/omniauth_registrations/new.html.erb +40 -0
- data/app/views/decidim/devise/registrations/new.html.erb +21 -1
- data/app/views/decidim/devise/sessions/new.html.erb +1 -0
- data/app/views/decidim/devise/shared/_links.html.erb +0 -8
- data/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +21 -0
- data/app/views/decidim/participatory_process_steps/_participatory_process_step.html.erb +16 -0
- data/app/views/decidim/participatory_process_steps/_timeline.html.erb +7 -0
- data/app/views/decidim/participatory_process_steps/index.html.erb +12 -0
- data/app/views/decidim/participatory_processes/show.html.erb +5 -5
- data/app/views/decidim/shared/_login_modal.html.erb +30 -0
- data/app/views/devise/mailer/invite_admin.html.erb +17 -0
- data/app/views/devise/mailer/invite_admin.text.erb +15 -0
- data/app/views/devise/mailer/organization_admin_invitation_instructions.html.erb +1 -1
- data/app/views/devise/mailer/organization_admin_invitation_instructions.text.erb +1 -1
- data/app/views/layouts/decidim/_application.html.erb +1 -0
- data/app/views/layouts/decidim/_header.html.erb +1 -1
- data/app/views/layouts/decidim/_meta.html.erb +1 -0
- data/app/views/layouts/decidim/_process_header.html.erb +12 -1
- data/app/views/layouts/decidim/_process_header_steps.html.erb +1 -0
- data/app/views/layouts/decidim/_social_meta.html.erb +11 -0
- data/app/views/layouts/decidim/participatory_process.html.erb +4 -0
- data/app/views/pages/home.html.erb +29 -2
- data/config/i18n-tasks.yml +1 -0
- data/config/initializers/devise.rb +10 -1
- data/config/locales/ca.yml +45 -3
- data/config/locales/en.yml +45 -3
- data/config/locales/es.yml +45 -3
- data/config/routes.rb +9 -2
- data/config/secrets.yml +36 -0
- data/db/migrate/20170110133113_add_configuration_to_features.rb +7 -0
- data/db/migrate/20170110153807_add_handler_to_organization.rb +5 -0
- data/db/migrate/20170116110851_create_identities.rb +11 -0
- data/db/migrate/20170116135237_loosen_step_requirements.rb +6 -0
- data/db/migrate/20170117142904_add_uniqueness_field_to_authorizations.rb +7 -0
- data/db/migrate/20170119145359_create_user_groups.rb +11 -0
- data/db/migrate/20170119150255_create_user_group_memberships.rb +12 -0
- data/db/migrate/20170119150649_add_show_statistics_to_organization.rb +5 -0
- data/db/migrate/20170120120733_add_user_groups_verified.rb +5 -0
- data/db/seeds.rb +45 -79
- data/lib/decidim/core.rb +8 -0
- data/lib/decidim/core/engine.rb +8 -0
- data/lib/decidim/core/test/factories.rb +188 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/devise_failure_app.rb +1 -0
- data/lib/decidim/feature_manifest.rb +27 -0
- data/lib/decidim/features/base_controller.rb +8 -3
- data/lib/decidim/features/settings_manifest.rb +94 -0
- data/lib/decidim/filter_form_builder.rb +56 -0
- data/lib/decidim/form_builder.rb +4 -7
- data/vendor/assets/javascripts/svg-injector.js +464 -0
- metadata +142 -26
- data/app/assets/stylesheets/decidim/modules/_owl-carousel.scss +0 -72
- data/app/assets/stylesheets/decidim/modules/_phase-nav.scss +0 -177
- data/app/assets/stylesheets/decidim/utils/_helpers.sass +0 -21
- data/app/assets/stylesheets/decidim/utils/_keyframes.sass +0 -13
- data/app/assets/stylesheets/decidim/utils/_mixins.sass +0 -33
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 90088cf15e64d2ce6b1d18dc801aafd4f2bcaf25
|
|
4
|
+
data.tar.gz: 03fbfda546c53214106febeea0e31b94f5b07e8e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f2ddf2c4e04870bd329115a24a5c43680133b4cdc3e750b7606d67594123d2f8668f702ed0c80c56aef68f803e5727a3974e8289d3eb47532aa6ad50ac588e71
|
|
7
|
+
data.tar.gz: c3c192e8f660653064880131624f897d41ebe1a070925dd25a8780e4f182c731bc188962b931e54034139543d231d7b6fcc03beef7f58b8a4af8840cb5ba43d4
|
data/Rakefile
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
require "decidim/common_rake"
|
|
2
|
+
require "decidim/dev/common_rake"
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
// = require modernizr
|
|
3
3
|
// = require owl.carousel.min
|
|
4
4
|
// = require svg4everybody.min
|
|
5
|
-
// = require
|
|
5
|
+
// = require decidim/append_elements
|
|
6
|
+
// = require decidim/inline_svg
|
|
7
|
+
// = require decidim/user_registrations
|
|
6
8
|
|
|
7
9
|
/* globals svg4everybody */
|
|
8
10
|
|
|
9
11
|
$(document).on('turbolinks:load', () => {
|
|
10
12
|
$(document).foundation();
|
|
11
|
-
$('.js-append').appendAround();
|
|
12
13
|
svg4everybody();
|
|
13
14
|
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// = require ./form_filter.component
|
|
2
|
+
// = require_self
|
|
3
|
+
|
|
4
|
+
// Initializes the form filter. We're unmounting the component before
|
|
5
|
+
// changing the page so that we stop listening to events and we don't bind
|
|
6
|
+
// multiple times when re-visiting the page.
|
|
7
|
+
((exports) => {
|
|
8
|
+
const { Decidim: { FormFilterComponent } } = exports;
|
|
9
|
+
const formFilter = new FormFilterComponent('form.new_filter');
|
|
10
|
+
|
|
11
|
+
const onDocumentReady = () => {
|
|
12
|
+
formFilter.mountComponent();
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const onTurboLinksBeforeVisit = () => {
|
|
16
|
+
formFilter.unmountComponent();
|
|
17
|
+
$(document).off('turbolinks:before-visit', onTurboLinksBeforeVisit);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
$(document).ready(onDocumentReady);
|
|
21
|
+
$(document).on('turbolinks:before-visit', onTurboLinksBeforeVisit);
|
|
22
|
+
})(window);
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/* eslint-disable no-div-regex, no-useless-escape, no-param-reassign */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A plain Javascript component that handles the form filter.
|
|
5
|
+
* @class
|
|
6
|
+
* @augments Component
|
|
7
|
+
*/
|
|
8
|
+
((exports) => {
|
|
9
|
+
class FormFilterComponent {
|
|
10
|
+
mounted;
|
|
11
|
+
$form;
|
|
12
|
+
|
|
13
|
+
constructor(selector) {
|
|
14
|
+
this.$form = $(selector);
|
|
15
|
+
this.mounted = false;
|
|
16
|
+
|
|
17
|
+
this._onFormChange = this._onFormChange.bind(this);
|
|
18
|
+
this._onPopState = this._onPopState.bind(this);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Handles the logic for unmounting the component
|
|
23
|
+
* @public
|
|
24
|
+
* @returns {Void} - Returns nothing
|
|
25
|
+
*/
|
|
26
|
+
unmountComponent() {
|
|
27
|
+
if (this.mounted) {
|
|
28
|
+
this.mounted = false;
|
|
29
|
+
this.$form.off('change', 'input, select', this._onFormChange);
|
|
30
|
+
|
|
31
|
+
exports.onpopstate = null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Handles the logic for mounting the component
|
|
37
|
+
* @public
|
|
38
|
+
* @returns {Void} - Returns nothing
|
|
39
|
+
*/
|
|
40
|
+
mountComponent() {
|
|
41
|
+
if (this.$form.length > 0 && !this.mounted) {
|
|
42
|
+
this.mounted = true;
|
|
43
|
+
this.$form.on('change', 'input, select', this._onFormChange);
|
|
44
|
+
|
|
45
|
+
exports.onpopstate = this._onPopState;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Finds the current location.
|
|
51
|
+
* @private
|
|
52
|
+
* @returns {String} - Returns the current location.
|
|
53
|
+
*/
|
|
54
|
+
_getLocation() {
|
|
55
|
+
return exports.location.toString();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Finds the values of the location prams that match the given regexp.
|
|
60
|
+
* @private
|
|
61
|
+
* @param {Regexp} regex - a Regexp to match the params.
|
|
62
|
+
* @returns {String[]} - An array of values of the params that match the regexp.
|
|
63
|
+
*/
|
|
64
|
+
_getLocationParams(regex) {
|
|
65
|
+
const location = decodeURIComponent(this._getLocation());
|
|
66
|
+
let values = location.match(regex);
|
|
67
|
+
if (values) {
|
|
68
|
+
values = values.map((val) => val.match(/=(.*)/)[1]);
|
|
69
|
+
}
|
|
70
|
+
return values;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Parse current location and get filter values.
|
|
75
|
+
* @private
|
|
76
|
+
* @returns {Object} - An object where a key correspond to a filter field
|
|
77
|
+
* and the value is the current value for the filter.
|
|
78
|
+
*/
|
|
79
|
+
_parseLocationFilterValues() {
|
|
80
|
+
// Every location param is constructed like this: filter[key]=value
|
|
81
|
+
let regexpResult = decodeURIComponent(this._getLocation()).match(/filter\[([^\]]*)\](?:\[\])?=([^&]*)/g);
|
|
82
|
+
|
|
83
|
+
// The RegExp g flag returns null or an array of coincidences. It doesn't return the match groups
|
|
84
|
+
if (regexpResult) {
|
|
85
|
+
const filterParams = regexpResult.reduce((acc, result) => {
|
|
86
|
+
const [, key, value] = result.match(/filter\[([^\]]*)\](?:\[\])?=([^&]*)/);
|
|
87
|
+
acc[key] = value;
|
|
88
|
+
return acc;
|
|
89
|
+
}, {});
|
|
90
|
+
|
|
91
|
+
return filterParams;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Clears the form to start with a clean state.
|
|
99
|
+
* @private
|
|
100
|
+
* @returns {Void} - Returns nothing.
|
|
101
|
+
*/
|
|
102
|
+
_clearForm() {
|
|
103
|
+
this.$form.find('input[type=checkbox]').attr('checked', false);
|
|
104
|
+
this.$form.find('input[type=radio]').attr('checked', false);
|
|
105
|
+
|
|
106
|
+
// This ensure the form is reset in a valid state where a fieldset of
|
|
107
|
+
// radio buttons has the first selected.
|
|
108
|
+
this.$form.find('fieldset input[type=radio]:first').each(function () {
|
|
109
|
+
// I need the this to iterate a jQuery collection
|
|
110
|
+
$(this)[0].checked = true; // eslint-disable-line no-invalid-this
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Handles the logic when going back to a previous state in the filter form.
|
|
116
|
+
* @private
|
|
117
|
+
* @returns {Void} - Returns nothing.
|
|
118
|
+
*/
|
|
119
|
+
_onPopState() {
|
|
120
|
+
this._clearForm();
|
|
121
|
+
|
|
122
|
+
const filterParams = this._parseLocationFilterValues();
|
|
123
|
+
|
|
124
|
+
if (filterParams) {
|
|
125
|
+
const fieldIds = Object.keys(filterParams);
|
|
126
|
+
|
|
127
|
+
// Iterate the filter params and set the correct form values
|
|
128
|
+
fieldIds.forEach((fieldId) => {
|
|
129
|
+
let field = null;
|
|
130
|
+
|
|
131
|
+
// Since we are using Ruby on Rails generated forms the field ids for a
|
|
132
|
+
// checkbox or a radio button has the following form: filter_${key}_${value}
|
|
133
|
+
field = this.$form.find(`input#filter_${fieldId}_${filterParams[fieldId]}`);
|
|
134
|
+
|
|
135
|
+
if (field.length > 0) {
|
|
136
|
+
field[0].checked = true;
|
|
137
|
+
} else {
|
|
138
|
+
// If the field is not a checkbox neither a radio it means is a input or a select.
|
|
139
|
+
// Ruby on Rails ensure the ids are constructed like this: filter_${key}
|
|
140
|
+
field = this.$form.find(`input#filter_${fieldId},select#filter_${fieldId}`);
|
|
141
|
+
|
|
142
|
+
if (field.length > 0) {
|
|
143
|
+
field.val(filterParams[fieldId]);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
this.$form.submit();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Handles the logic to update the current location after a form change event.
|
|
154
|
+
* @private
|
|
155
|
+
* @returns {Void} - Returns nothing.
|
|
156
|
+
*/
|
|
157
|
+
_onFormChange() {
|
|
158
|
+
let newUrl = '';
|
|
159
|
+
const formAction = this.$form.attr('action');
|
|
160
|
+
const params = this.$form.serialize();
|
|
161
|
+
|
|
162
|
+
this.$form.submit();
|
|
163
|
+
|
|
164
|
+
if (formAction.indexOf('?') < 0) {
|
|
165
|
+
newUrl = `${formAction}?${params}`;
|
|
166
|
+
} else {
|
|
167
|
+
newUrl = `${formAction}&${params}`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
exports.history.pushState(null, null, newUrl);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
exports.Decidim = exports.Decidim || {};
|
|
175
|
+
exports.Decidim.FormFilterComponent = FormFilterComponent;
|
|
176
|
+
})(window);
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/* eslint-disable no-unused-expressions */
|
|
2
|
+
require('jquery');
|
|
3
|
+
require('./form_filter.component.js.es6');
|
|
4
|
+
|
|
5
|
+
const { Decidim: { FormFilterComponent } } = window;
|
|
6
|
+
|
|
7
|
+
describe('FormFilterComponent', () => {
|
|
8
|
+
const selector = 'form#new_filter';
|
|
9
|
+
let subject = null;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
let form = `
|
|
13
|
+
<form id="new_filter" action="/filters" method="get">
|
|
14
|
+
<fieldset>
|
|
15
|
+
<input id="filter_order_start_time_asc" value="asc" type="radio" name="order_start_time" checked />
|
|
16
|
+
<input id="filter_order_start_time_desc" value="desc" type="radio" name="order_start_time" />
|
|
17
|
+
</fieldset>
|
|
18
|
+
|
|
19
|
+
<fieldset>
|
|
20
|
+
<input id="filter_scope_id_1" value="1" type="checkbox" name="scope_id[]" />
|
|
21
|
+
<input id="filter_scope_id_2" value="2" type="checkbox" name="scope_id[]" />
|
|
22
|
+
<input id="filter_scope_id_3" value="3" type="checkbox" name="scope_id[]" />
|
|
23
|
+
</fieldset>
|
|
24
|
+
|
|
25
|
+
<fieldset>
|
|
26
|
+
<select id="filter_category_id" name="filter[category_id]">
|
|
27
|
+
<option value="1">Category 1</option>
|
|
28
|
+
<option value="2">Category 2</option>
|
|
29
|
+
</select>
|
|
30
|
+
</fieldset>
|
|
31
|
+
</form>
|
|
32
|
+
`;
|
|
33
|
+
$('body').append(form);
|
|
34
|
+
window.history = {
|
|
35
|
+
pushState: sinon.stub()
|
|
36
|
+
};
|
|
37
|
+
subject = new FormFilterComponent(selector);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('exists', () => {
|
|
41
|
+
expect(FormFilterComponent).to.exist;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('initializes unmounted', () => {
|
|
45
|
+
expect(subject.mounted).to.be.falsey;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('initializes the formSelector with the given selector', () => {
|
|
49
|
+
expect(subject.$form).to.deep.equal($(selector));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('when mounted', () => {
|
|
53
|
+
beforeEach(() => {
|
|
54
|
+
sinon.spy(subject.$form, 'on');
|
|
55
|
+
subject.mountComponent();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
afterEach(() => {
|
|
59
|
+
subject.$form.on.restore();
|
|
60
|
+
subject.unmountComponent();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('mounts the component', () => {
|
|
64
|
+
expect(subject.mounted).to.be.truthy;
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('mounts the component', () => {
|
|
68
|
+
expect(window.onpopstate).to.equal(subject._onPopState);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('binds the form change event', () => {
|
|
72
|
+
expect(subject.$form.on).to.have.been.calledWith('change', 'input, select', subject._onFormChange);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('on form change event', () => {
|
|
76
|
+
let stub = null;
|
|
77
|
+
|
|
78
|
+
beforeEach(() => {
|
|
79
|
+
stub = sinon.stub(subject.$form, 'submit');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('form is submitted', () => {
|
|
83
|
+
$(selector).find('input[name=order_start_time][value=desc]').trigger('change');
|
|
84
|
+
|
|
85
|
+
expect(stub).to.have.been.calledOnce;
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('sets the onpopostate callback', () => {
|
|
89
|
+
sinon.stub(subject.$form, 'serialize').returns('order_start_time=desc')
|
|
90
|
+
$(selector).find('input[name=order_start_time][value=desc]').trigger('change');
|
|
91
|
+
|
|
92
|
+
expect(window.history.pushState).to.have.been.calledWith(null, null, '/filters?order_start_time=desc');
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('onpopstate event', () => {
|
|
97
|
+
beforeEach(() => {
|
|
98
|
+
sinon.stub(subject.$form, 'submit');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('clears the form data', () => {
|
|
102
|
+
let clearFormSpy = sinon.spy(subject, '_clearForm');
|
|
103
|
+
|
|
104
|
+
window.onpopstate();
|
|
105
|
+
|
|
106
|
+
expect(clearFormSpy).to.have.been.called;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('sets the correct form fields based on the current location', () => {
|
|
110
|
+
sinon.stub(subject, '_getLocation').returns('/filters?order_start_time=desc&scope_id[]=1&scope_id[]=2&filter[category_id]=2')
|
|
111
|
+
|
|
112
|
+
window.onpopstate();
|
|
113
|
+
|
|
114
|
+
expect($(selector).find('select').val()).to.equal('2');
|
|
115
|
+
expect($(selector).find('input[name=order_start_time][value=desc]').attr('checked')).to.be.truthy;
|
|
116
|
+
expect($(selector).find('input[name=order_start_time][value=asc]').attr('checked')).to.be.falsey;
|
|
117
|
+
expect($(selector).find('input[name=scope_id][value=1]').attr('checked')).to.be.truthy;
|
|
118
|
+
expect($(selector).find('input[name=scope_id][value=2]').attr('checked')).to.be.truthy;
|
|
119
|
+
expect($(selector).find('input[name=scope_id][value=3]').attr('checked')).to.be.falsey;
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe('when unmounted', () => {
|
|
125
|
+
beforeEach(() => {
|
|
126
|
+
sinon.spy(subject.$form, 'off');
|
|
127
|
+
subject.mountComponent();
|
|
128
|
+
subject.unmountComponent();
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
afterEach(() => {
|
|
132
|
+
subject.$form.off.restore();
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('mounts the component', () => {
|
|
136
|
+
expect(subject.mounted).to.be.falsey;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('unbinds the form change event', () => {
|
|
140
|
+
expect(subject.$form.off).to.have.been.calledWith('change', 'input, select', subject._onFormChange);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('removes the onpopostate callback', () => {
|
|
144
|
+
expect(window.onpopstate).not.to.exist;
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
afterEach(() => {
|
|
149
|
+
$(selector).remove();
|
|
150
|
+
})
|
|
151
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// = require svg-injector
|
|
2
|
+
|
|
3
|
+
(function() {
|
|
4
|
+
let inlineSVG = function () {
|
|
5
|
+
let $externalSvg = $("img.external-svg");
|
|
6
|
+
SVGInjector($externalSvg, {
|
|
7
|
+
each: (svg) => $(svg).show()
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
$(document).on('turbolinks:load', inlineSVG);
|
|
12
|
+
}(window));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
$(document).on('turbolinks:load', () => {
|
|
2
|
+
const $userRegistrationForm = $('.register-form');
|
|
3
|
+
const $userGroupFields = $userRegistrationForm.find('.user-group-fields');
|
|
4
|
+
const inputSelector = 'input[name="user[sign_up_as]"]';
|
|
5
|
+
|
|
6
|
+
const setGroupFieldsVisibility = (value) => {
|
|
7
|
+
if (value === 'user') {
|
|
8
|
+
$userGroupFields.hide();
|
|
9
|
+
} else {
|
|
10
|
+
$userGroupFields.show();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
setGroupFieldsVisibility($userRegistrationForm.find(`${inputSelector}:checked`).val());
|
|
15
|
+
|
|
16
|
+
$userRegistrationForm.on('change', inputSelector, (event) => {
|
|
17
|
+
const value = event.target.value;
|
|
18
|
+
|
|
19
|
+
setGroupFieldsVisibility(value);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
});
|
|
@@ -57,9 +57,11 @@ $comment-form-bg: $light-gray;
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
.comment__footer
|
|
60
|
+
.comment__footer,
|
|
61
|
+
.comment__additionalreply{
|
|
61
62
|
padding: $comment-padding;
|
|
62
63
|
font-size: 90%;
|
|
64
|
+
@include clearfix;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
.comment--nested{
|
|
@@ -74,10 +76,6 @@ $comment-form-bg: $light-gray;
|
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
.comment__footer{
|
|
78
|
-
@include clearfix;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
79
|
.comment__reply{
|
|
82
80
|
float: left;
|
|
83
81
|
color: $muted;
|
|
@@ -116,4 +114,3 @@ $comment-form-bg: $light-gray;
|
|
|
116
114
|
display: block;
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
|
-
|