summaryrefslogtreecommitdiffstats
path: root/asset/js/widget/SearchEditor.js
blob: b8235f0b2a53e6a78f8df5018664dd0e5b2f8e8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
define(["../notjQuery", "../vendor/Sortable"], function ($, Sortable) {

    "use strict";

    class SearchEditor {
        constructor(form) {
            this.form = form;
        }

        bind() {
            $(this.form).on('end', this.onRuleDropped, this);

            this.form.querySelectorAll('ol').forEach(sortable => {
                let options = {
                    scroll: true,
                    group: 'rules',
                    direction: 'vertical',
                    invertSwap: true,
                    handle: '.drag-initiator'
                };

                Sortable.create(sortable, options);
            });

            return this;
        }

        refresh(form) {
            if (form === this.form) {
                // If the DOM node is still the same, nothing has changed
                return;
            }

            this.form = form;
            this.bind();
        }

        destroy() {
            this.form = null;
            this.filterInput = null;
        }

        onRuleDropped(event) {
            if (event.to === event.from && event.newIndex === event.oldIndex) {
                // The user dropped the rule at its previous position
                return;
            }

            let placement = 'before';
            let neighbour = event.to.querySelector(':scope > :nth-child(' + (event.newIndex + 2) + ')');
            if (! neighbour) {
                // User dropped the rule at the end of a group
                placement = 'after';
                neighbour = event.to.querySelector(':scope > :nth-child(' + event.newIndex + ')')
                if (! neighbour) {
                    // User dropped the rule into an empty group
                    placement = 'to';
                    neighbour = event.to.closest('[id]');
                }
            }

            // It's a submit element, the very first one, otherwise Icinga Web 2 sends another "structural-change"
            this.form.insertBefore(
                $.render(
                    '<input type="hidden" name="structural-change[1]" value="' + placement + ':' + neighbour.id + '">'
                ),
                this.form.firstChild
            );
            this.form.insertBefore(
                $.render('<input type="submit" name="structural-change[0]" value="move-rule:' + event.item.id + '">'),
                this.form.firstChild
            );

            $(this.form).trigger('submit');
        }
    }

    return SearchEditor;
});