summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/issues_bulk_assignment.js.es6
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/issues_bulk_assignment.js.es6')
-rw-r--r--app/assets/javascripts/issues_bulk_assignment.js.es6149
1 files changed, 149 insertions, 0 deletions
diff --git a/app/assets/javascripts/issues_bulk_assignment.js.es6 b/app/assets/javascripts/issues_bulk_assignment.js.es6
new file mode 100644
index 00000000000..0808f538f01
--- /dev/null
+++ b/app/assets/javascripts/issues_bulk_assignment.js.es6
@@ -0,0 +1,149 @@
+((global) => {
+
+ class IssuableBulkActions {
+ constructor({ container, form, issues } = {}) {
+ this.container = container || $('.content'),
+ this.form = form || this.getElement('.bulk-update');
+ this.issues = issues || this.getElement('.issues-list .issue');
+ this.form.data('bulkActions', this);
+ this.willUpdateLabels = false;
+ this.bindEvents();
+ // Fixes bulk-assign not working when navigating through pages
+ Issuable.initChecks();
+ }
+
+ getElement(selector) {
+ return this.container.find(selector);
+ }
+
+ bindEvents() {
+ return this.form.off('submit').on('submit', this.onFormSubmit.bind(this));
+ }
+
+ onFormSubmit(e) {
+ e.preventDefault();
+ return this.submit();
+ }
+
+ submit() {
+ const _this = this;
+ const xhr = $.ajax({
+ url: this.form.attr('action'),
+ method: this.form.attr('method'),
+ dataType: 'JSON',
+ data: this.getFormDataAsObject()
+ });
+ xhr.done(() => window.location.reload());
+ xhr.fail(() => new Flash("Issue update failed"));
+ return xhr.always(this.onFormSubmitAlways.bind(this));
+ }
+
+ onFormSubmitAlways() {
+ return this.form.find('[type="submit"]').enable();
+ }
+
+ getSelectedIssues() {
+ return this.issues.has('.selected_issue:checked');
+ }
+
+ getLabelsFromSelection() {
+ const labels = [];
+ this.getSelectedIssues().map(function() {
+ const labelsData = $(this).data('labels');
+ if (labelsData) {
+ return labelsData.map(function(labelId) {
+ if (labels.indexOf(labelId) === -1) {
+ return labels.push(labelId);
+ }
+ });
+ }
+ });
+ return labels;
+ }
+
+
+ /**
+ * Will return only labels that were marked previously and the user has unmarked
+ * @return {Array} Label IDs
+ */
+
+ getUnmarkedIndeterminedLabels() {
+ const result = [];
+ const labelsToKeep = [];
+
+ this.getElement('.labels-filter .is-indeterminate')
+ .each((i, el) => labelsToKeep.push($(el).data('labelId')));
+
+ this.getLabelsFromSelection().forEach((id) => {
+ if (labelsToKeep.indexOf(id) === -1) {
+ result.push(id);
+ }
+ });
+
+ return result;
+ }
+
+
+ /**
+ * Simple form serialization, it will return just what we need
+ * Returns key/value pairs from form data
+ */
+
+ getFormDataAsObject() {
+ const formData = {
+ update: {
+ state_event: this.form.find('input[name="update[state_event]"]').val(),
+ assignee_id: this.form.find('input[name="update[assignee_id]"]').val(),
+ milestone_id: this.form.find('input[name="update[milestone_id]"]').val(),
+ issuable_ids: this.form.find('input[name="update[issuable_ids]"]').val(),
+ subscription_event: this.form.find('input[name="update[subscription_event]"]').val(),
+ add_label_ids: [],
+ remove_label_ids: []
+ }
+ };
+ if (this.willUpdateLabels) {
+ this.getLabelsToApply().map(function(id) {
+ return formData.update.add_label_ids.push(id);
+ });
+ this.getLabelsToRemove().map(function(id) {
+ return formData.update.remove_label_ids.push(id);
+ });
+ }
+ return formData;
+ }
+
+ getLabelsToApply() {
+ const labelIds = [];
+ const $labels = this.form.find('.labels-filter input[name="update[label_ids][]"]');
+ $labels.each(function(k, label) {
+ if (label) {
+ return labelIds.push(parseInt($(label).val()));
+ }
+ });
+ return labelIds;
+ }
+
+
+ /**
+ * Returns Label IDs that will be removed from issue selection
+ * @return {Array} Array of labels IDs
+ */
+
+ getLabelsToRemove() {
+ const result = [];
+ const indeterminatedLabels = this.getUnmarkedIndeterminedLabels();
+ const labelsToApply = this.getLabelsToApply();
+ indeterminatedLabels.map(function(id) {
+ // We need to exclude label IDs that will be applied
+ // By not doing this will cause issues from selection to not add labels at all
+ if (labelsToApply.indexOf(id) === -1) {
+ return result.push(id);
+ }
+ });
+ return result;
+ }
+ }
+
+ global.IssuableBulkActions = IssuableBulkActions;
+
+})(window.gl || (window.gl = {}));