<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
(function(cloudStack) {
    cloudStack.sections.events = {
        title: 'label.menu.events',
        id: 'events',
        sectionSelect: {
            preFilter: function(args) {
                if (isAdmin())
                    return ["events", "alerts"];
                else
                    return ["events"];
            },
            label: 'label.select-view'
        },
        sections: {
            events: {
                type: 'select',
                title: 'label.menu.events',
                listView: {
                    id: 'events',
                    label: 'label.menu.events',
                    multiSelect: true,
                    fields: {
                        description: {
                            label: 'label.description'
                        },
                        level: {
                            label: 'label.level'
                        },
                        type: {
                            label: 'Type'
                        },
                        domain: {
                            label: 'label.domain'
                        },
                        account: {
                            label: 'label.account'
                        },
                        created: {
                            label: 'label.date',
                            converter: cloudStack.converters.toLocalDate
                        }
                    },

                    actions: {
                        // Remove multiple events
                        removeMulti: {
                            label: 'label.delete.events',
                            isHeader: true,
                            addRow: false,
                            isMultiSelectAction: true,
                            messages: {
                                confirm: function(args) {
                                    return 'Please confirm you would like to remove the selected events';
                                },
                                notification: function(args) {
                                    return 'label.delete.events';
                                }
                            },
                            action: function(args) {
                                var events = args.context.events;

                                $.ajax({
                                    url: createURL("deleteEvents"),
                                    data: {
                                        ids: $(events).map(function(index, event) {
                                            return event.id;
                                        }).toArray().join(',')
                                    },
                                    success: function(data) {
                                        args.response.success();
                                        $(window).trigger('cloudStack.fullRefresh');
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        },

                        remove: {
                            label: 'label.delete.events',
                            isHeader: true,
                            addRow: false,
                            messages: {
                                notification: function(args) {
                                    return 'label.delete.events';
                                }
                            },
                            createForm: {
                                title: 'label.delete.events',
                                desc: '',
                                fields: {
                                    type: {
                                        label: 'label.by.event.type',
                                        docID: 'helpEventsDeleteType'
                                    },
                                    startdate: {
                                        label: 'label.by.date.start',
                                        docID: 'helpEventsDeleteDate',
                                        isDatepicker: true
                                    },
                                    enddate: {
                                        label: 'label.by.date.end',
                                        docID: 'helpEventsDeleteDate',
                                        isDatepicker: true
                                    }
                                }
                            },
                            action: function(args) {

                                var data = {};

                                if (args.data.type != "")
                                    $.extend(data, {
                                        type: args.data.type
                                    });

                                if (args.data.startdate != "")
                                    $.extend(data, {
                                        startdate: args.data.startdate
                                    });

                                if (args.data.enddate != "")
                                    $.extend(data, {
                                        enddate: args.data.enddate
                                    });

                                $.ajax({
                                    url: createURL("deleteEvents"),
                                    data: data,
                                    success: function(data) {
                                        args.response.success();
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        },

                        archive: {
                            label: 'label.archive.events',
                            isHeader: true,
                            addRow: false,
                            messages: {
                                notification: function(args) {
                                    return 'label.archive.events';
                                }
                            },
                            createForm: {
                                title: 'label.archive.events',
                                desc: '',
                                fields: {
                                    type: {
                                        label: 'label.by.event.type',
                                        docID: 'helpEventsArchiveType'
                                    },
                                    startdate: {
                                        label: 'label.by.date.start',
                                        docID: 'helpEventsArchiveDate',
                                        isDatepicker: true
                                    },
                                    enddate: {
                                        label: 'label.by.date.end',
                                        docID: 'helpEventsArchiveDate',
                                        isDatepicker: true
                                    }
                                }
                            },
                            action: function(args) {
                                var data = {};

                                if (args.data.type != "")
                                    $.extend(data, {
                                        type: args.data.type
                                    });

                                if (args.data.startdate != "")
                                    $.extend(data, {
                                        startdate: args.data.startdate
                                    });

                                if (args.data.enddate != "")
                                    $.extend(data, {
                                        enddate: args.data.enddate
                                    });

                                $.ajax({
                                    url: createURL("archiveEvents"),
                                    data: data,
                                    dataType: 'json',
                                    async: false,

                                    success: function(data) {
                                        args.response.success();
                                    }
                                });

                            }
                        },

                        // Archive multiple events
                        archiveMulti: {
                            label: 'label.archive.events',
                            isHeader: true,
                            addRow: false,
                            isMultiSelectAction: true,
                            messages: {
                                confirm: function(args) {
                                    return 'Please confirm you would like to archive the selected events';
                                },
                                notification: function(args) {
                                    return 'label.archive.events';
                                }
                            },
                            action: function(args) {
                                var events = args.context.events;

                                $.ajax({
                                    url: createURL("archiveEvents"),
                                    data: {
                                        ids: $(events).map(function(index, event) {
                                            return event.id;
                                        }).toArray().join(',')
                                    },
                                    success: function(data) {
                                        args.response.success();
                                        $(window).trigger('cloudStack.fullRefresh');
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        }

                    },

                    advSearchFields: {
                        level: {
                            label: 'label.level',
                            select: function(args) {
                                args.response.success({
                                    data: [{
                                        id: '',
                                        description: ''
                                    }, {
                                        id: 'INFO',
                                        description: 'INFO'
                                    }, {
                                        id: 'WARN',
                                        description: 'WARN'
                                    }, {
                                        id: 'ERROR',
                                        description: 'ERROR'
                                    }]
                                });
                            }
                        },

                        domainid: {
                            label: 'Domain',
                            select: function(args) {
                                if (isAdmin() || isDomainAdmin()) {
                                    $.ajax({
                                        url: createURL('listDomains'),
                                        data: {
                                            listAll: true,
                                            details: 'min'
                                        },
                                        success: function(json) {
                                            var array1 = [{
                                                id: '',
                                                description: ''
                                            }];
                                            var domains = json.listdomainsresponse.domain;
                                            if (domains != null && domains.length > 0) {
                                                for (var i = 0; i < domains.length; i++) {
                                                    array1.push({
                                                        id: domains[i].id,
                                                        description: domains[i].path
                                                    });
                                                }
                                            }
                                            args.response.success({
                                                data: array1
                                            });
                                        }
                                    });
                                } else {
                                    args.response.success({
                                        data: null
                                    });
                                }
                            },
                            isHidden: function(args) {
                                if (isAdmin() || isDomainAdmin())
                                    return false;
                                else
                                    return true;
                            }
                        },

                        account: {
                            label: 'Account',
                            isHidden: function(args) {
                                if (isAdmin() || isDomainAdmin())
                                    return false;
                                else
                                    return true;
                            }
                        }
                    },

                    dataProvider: function(args) {
                        var data = {};
                        listViewDataProvider(args, data);

                        $.ajax({
                            url: createURL('listEvents'),
                            data: data,
                            success: function(json) {
                                var items = json.listeventsresponse.event;
                                args.response.success({
                                    data: items
                                });
                            }
                        });
                    },
                    detailView: {
                        name: 'label.details',
                        actions: {

                            // Remove single event
                            remove: {
                                label: 'Delete',
                                messages: {
                                    notification: function(args) {
                                        return 'Event Deleted';
                                    },
                                    confirm: function() {
                                        return 'Are you sure you want to remove this event?';
                                    }
                                },
                                action: function(args) {

                                    $.ajax({
                                        url: createURL("deleteEvents&ids=" + args.context.events[0].id),
                                        success: function(json) {
                                            args.response.success();
                                            $(window).trigger('cloudStack.fullRefresh');
                                        }

                                    });
                                }
                            },

                            // Archive single event
                            archive: {
                                label: 'Archive',
                                messages: {
                                    notification: function(args) {
                                        return 'Event Archived';
                                    },
                                    confirm: function() {
                                        return 'Please confirm that you want to archive this event.';
                                    }
                                },
                                action: function(args) {

                                    $.ajax({
                                        url: createURL("archiveEvents&ids=" + args.context.events[0].id),
                                        success: function(json) {
                                            args.response.success();
                                            $(window).trigger('cloudStack.fullRefresh');
                                        }
                                    });
                                }
                            }
                        },
                        tabs: {
                            details: {
                                title: 'label.details',
                                fields: [{
                                    description: {
                                        label: 'label.description'
                                    },
                                    state: {
                                        label: 'label.state'
                                    },
                                    level: {
                                        label: 'label.level'
                                    },
                                    type: {
                                        label: 'label.type'
                                    },
                                    domain: {
                                        label: 'label.domain'
                                    },
                                    account: {
                                        label: 'label.account'
                                    },
                                    username: {
                                        label: 'label.initiated.by'
                                    },
                                    created: {
                                        label: 'label.date',
                                        converter: cloudStack.converters.toLocalDate
                                    },
                                    id: {
                                        label: 'label.id'
                                    }
                                }],
                                dataProvider: function(args) {
                                    $.ajax({
                                        url: createURL("listEvents&id=" + args.context.events[0].id),
                                        dataType: "json",
                                        async: true,
                                        success: function(json) {
                                            var item = json.listeventsresponse.event[0];
                                            args.response.success({
                                                data: item
                                            });
                                        }
                                    });
                                }
                            }
                        }
                    }
                }
            },
            alerts: {
                type: 'select',
                title: 'label.menu.alerts',
                listView: {
                    id: 'alerts',
                    label: 'label.menu.alerts',
                    fields: {
                        description: {
                            label: 'label.description'
                        },
                        type: {
                            label: 'Type'
                        },
                        sent: {
                            label: 'label.date',
                            converter: cloudStack.converters.toLocalDate
                        }
                    },

                    actions: {
                        // Remove multiple Alerts
                        remove: {
                            label: 'label.delete.alerts',
                            isHeader: true,
                            addRow: false,
                            messages: {
                                notification: function(args) {
                                    return 'label.delete.alerts';
                                }
                            },
                            createForm: {
                                title: 'label.delete.alerts',
                                desc: '',
                                fields: {
                                    type: {
                                        label: 'label.by.alert.type',
                                        docID: 'helpAlertsDeleteType'
                                    },
                                    startdate: {
                                        label: 'label.by.date.start',
                                        docID: 'helpAlertsDeleteDate',
                                        isDatepicker: true
                                    },
                                    enddate: {
                                        label: 'label.by.date.end',
                                        docID: 'helpAlertsDeleteDate',
                                        isDatepicker: true
                                    }
                                }
                            },
                            action: function(args) {

                                var data = {};

                                if (args.data.type != "")
                                    $.extend(data, {
                                        type: args.data.type
                                    });

                                if (args.data.startdate != "")
                                    $.extend(data, {
                                        startdate: args.data.startdate
                                    });

                                if (args.data.enddate != "")
                                    $.extend(data, {
                                        enddate: args.data.enddate
                                    });

                                $.ajax({
                                    url: createURL("deleteAlerts"),
                                    data: data,
                                    dataType: 'json',
                                    async: false,

                                    success: function(data) {
                                        args.response.success();
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        },

                        // Archive multiple Alerts
                        archive: {
                            label: 'label.archive.alerts',
                            isHeader: true,
                            addRow: false,
                            messages: {
                                notification: function(args) {
                                    return 'label.archive.alerts';
                                }
                            },
                            createForm: {
                                title: 'label.archive.alerts',
                                desc: '',
                                fields: {
                                    type: {
                                        label: 'label.by.alert.type',
                                        docID: 'helpAlertsArchiveType'
                                    },
                                    startdate: {
                                        label: 'label.by.date.start',
                                        docID: 'helpAlertsArchiveDate',
                                        isDatepicker: true
                                    },
                                    enddate: {
                                        label: 'label.by.date.end',
                                        docID: 'helpAlertsArchiveDate',
                                        isDatepicker: true
                                    }

                                }
                            },
                            action: function(args) {
                                var data = {};

                                if (args.data.type != "")
                                    $.extend(data, {
                                        type: args.data.type
                                    });

                                if (args.data.startdate != "")
                                    $.extend(data, {
                                        startdate: args.data.startdate
                                    });

                                if (args.data.enddate != "")
                                    $.extend(data, {
                                        enddate: args.data.enddate
                                    });

                                $.ajax({
                                    url: createURL("archiveAlerts"),
                                    data: data,
                                    dataType: 'json',
                                    async: false,

                                    success: function(data) {
                                        args.response.success();
                                    }
                                });
                            }
                        }
                    },

                    dataProvider: function(args) {
                        var data = {};
                        listViewDataProvider(args, data);

                        $.ajax({
                            url: createURL('listAlerts'),
                            data: data,
                            async: true,
                            success: function(json) {
                                var items = json.listalertsresponse.alert;
                                args.response.success({
                                    data: items
                                });
                            }
                        });
                    },
                    detailView: {
                        name: 'Alert details',
                        actions: {

                            // Remove single Alert
                            remove: {
                                label: 'Delete',
                                messages: {
                                    notification: function(args) {
                                        return 'Alert Deleted';
                                    },
                                    confirm: function() {
                                        return 'Are you sure you want to delete this alert ?';
                                    }
                                },
                                action: function(args) {

                                    $.ajax({
                                        url: createURL("deleteAlerts&ids=" + args.context.alerts[0].id),
                                        success: function(json) {
                                            args.response.success();
                                            $(window).trigger('cloudStack.fullRefresh');
                                        }
                                    });

                                }
                            },

                            archive: {
                                label: 'Archive',
                                messages: {
                                    notification: function(args) {
                                        return 'Alert Archived';
                                    },
                                    confirm: function() {
                                        return 'Please confirm that you want to archive this alert.';
                                    }
                                },
                                action: function(args) {

                                    $.ajax({
                                        url: createURL("archiveAlerts&ids=" + args.context.alerts[0].id),
                                        success: function(json) {
                                            args.response.success();
                                            $(window).trigger('cloudStack.fullRefresh');
                                        }
                                    });
                                }
                            }

                        },

                        tabs: {
                            details: {
                                title: 'label.details',
                                fields: [{
                                    id: {
                                        label: 'ID'
                                    },
                                    description: {
                                        label: 'label.description'
                                    },
                                    sent: {
                                        label: 'label.date',
                                        converter: cloudStack.converters.toLocalDate
                                    }
                                }],
                                dataProvider: function(args) {
                                    $.ajax({
                                        url: createURL("listAlerts&id=" + args.context.alerts[0].id),
                                        dataType: "json",
                                        async: true,
                                        success: function(json) {
                                            var item = json.listalertsresponse.alert[0];
                                            args.response.success({
                                                data: item
                                            });
                                        }
                                    });
                                }
                            }
                        }
                    }
                }
            }
        }
    };
})(cloudStack);
<commit_msg>Alerts UI: Implement multi-select delete/archive alerts<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
(function(cloudStack) {
    cloudStack.sections.events = {
        title: 'label.menu.events',
        id: 'events',
        sectionSelect: {
            preFilter: function(args) {
                if (isAdmin())
                    return ["events", "alerts"];
                else
                    return ["events"];
            },
            label: 'label.select-view'
        },
        sections: {
            events: {
                type: 'select',
                title: 'label.menu.events',
                listView: {
                    id: 'events',
                    label: 'label.menu.events',
                    multiSelect: true,
                    fields: {
                        description: {
                            label: 'label.description'
                        },
                        level: {
                            label: 'label.level'
                        },
                        type: {
                            label: 'Type'
                        },
                        domain: {
                            label: 'label.domain'
                        },
                        account: {
                            label: 'label.account'
                        },
                        created: {
                            label: 'label.date',
                            converter: cloudStack.converters.toLocalDate
                        }
                    },

                    actions: {
                        // Remove multiple events
                        removeMulti: {
                            label: 'label.delete.events',
                            isHeader: true,
                            addRow: false,
                            isMultiSelectAction: true,
                            messages: {
                                confirm: function(args) {
                                    return 'Please confirm you would like to remove the selected events';
                                },
                                notification: function(args) {
                                    return 'label.delete.events';
                                }
                            },
                            action: function(args) {
                                var events = args.context.events;

                                $.ajax({
                                    url: createURL("deleteEvents"),
                                    data: {
                                        ids: $(events).map(function(index, event) {
                                            return event.id;
                                        }).toArray().join(',')
                                    },
                                    success: function(data) {
                                        args.response.success();
                                        $(window).trigger('cloudStack.fullRefresh');
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        },

                        remove: {
                            label: 'label.delete.events',
                            isHeader: true,
                            addRow: false,
                            messages: {
                                notification: function(args) {
                                    return 'label.delete.events';
                                }
                            },
                            createForm: {
                                title: 'label.delete.events',
                                desc: '',
                                fields: {
                                    type: {
                                        label: 'label.by.event.type',
                                        docID: 'helpEventsDeleteType'
                                    },
                                    startdate: {
                                        label: 'label.by.date.start',
                                        docID: 'helpEventsDeleteDate',
                                        isDatepicker: true
                                    },
                                    enddate: {
                                        label: 'label.by.date.end',
                                        docID: 'helpEventsDeleteDate',
                                        isDatepicker: true
                                    }
                                }
                            },
                            action: function(args) {

                                var data = {};

                                if (args.data.type != "")
                                    $.extend(data, {
                                        type: args.data.type
                                    });

                                if (args.data.startdate != "")
                                    $.extend(data, {
                                        startdate: args.data.startdate
                                    });

                                if (args.data.enddate != "")
                                    $.extend(data, {
                                        enddate: args.data.enddate
                                    });

                                $.ajax({
                                    url: createURL("deleteEvents"),
                                    data: data,
                                    success: function(data) {
                                        args.response.success();
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        },

                        archive: {
                            label: 'label.archive.events',
                            isHeader: true,
                            addRow: false,
                            messages: {
                                notification: function(args) {
                                    return 'label.archive.events';
                                }
                            },
                            createForm: {
                                title: 'label.archive.events',
                                desc: '',
                                fields: {
                                    type: {
                                        label: 'label.by.event.type',
                                        docID: 'helpEventsArchiveType'
                                    },
                                    startdate: {
                                        label: 'label.by.date.start',
                                        docID: 'helpEventsArchiveDate',
                                        isDatepicker: true
                                    },
                                    enddate: {
                                        label: 'label.by.date.end',
                                        docID: 'helpEventsArchiveDate',
                                        isDatepicker: true
                                    }
                                }
                            },
                            action: function(args) {
                                var data = {};

                                if (args.data.type != "")
                                    $.extend(data, {
                                        type: args.data.type
                                    });

                                if (args.data.startdate != "")
                                    $.extend(data, {
                                        startdate: args.data.startdate
                                    });

                                if (args.data.enddate != "")
                                    $.extend(data, {
                                        enddate: args.data.enddate
                                    });

                                $.ajax({
                                    url: createURL("archiveEvents"),
                                    data: data,
                                    dataType: 'json',
                                    async: false,

                                    success: function(data) {
                                        args.response.success();
                                    }
                                });

                            }
                        },

                        // Archive multiple events
                        archiveMulti: {
                            label: 'label.archive.events',
                            isHeader: true,
                            addRow: false,
                            isMultiSelectAction: true,
                            messages: {
                                confirm: function(args) {
                                    return 'Please confirm you would like to archive the selected events';
                                },
                                notification: function(args) {
                                    return 'label.archive.events';
                                }
                            },
                            action: function(args) {
                                var events = args.context.events;

                                $.ajax({
                                    url: createURL("archiveEvents"),
                                    data: {
                                        ids: $(events).map(function(index, event) {
                                            return event.id;
                                        }).toArray().join(',')
                                    },
                                    success: function(data) {
                                        args.response.success();
                                        $(window).trigger('cloudStack.fullRefresh');
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        }

                    },

                    advSearchFields: {
                        level: {
                            label: 'label.level',
                            select: function(args) {
                                args.response.success({
                                    data: [{
                                        id: '',
                                        description: ''
                                    }, {
                                        id: 'INFO',
                                        description: 'INFO'
                                    }, {
                                        id: 'WARN',
                                        description: 'WARN'
                                    }, {
                                        id: 'ERROR',
                                        description: 'ERROR'
                                    }]
                                });
                            }
                        },

                        domainid: {
                            label: 'Domain',
                            select: function(args) {
                                if (isAdmin() || isDomainAdmin()) {
                                    $.ajax({
                                        url: createURL('listDomains'),
                                        data: {
                                            listAll: true,
                                            details: 'min'
                                        },
                                        success: function(json) {
                                            var array1 = [{
                                                id: '',
                                                description: ''
                                            }];
                                            var domains = json.listdomainsresponse.domain;
                                            if (domains != null && domains.length > 0) {
                                                for (var i = 0; i < domains.length; i++) {
                                                    array1.push({
                                                        id: domains[i].id,
                                                        description: domains[i].path
                                                    });
                                                }
                                            }
                                            args.response.success({
                                                data: array1
                                            });
                                        }
                                    });
                                } else {
                                    args.response.success({
                                        data: null
                                    });
                                }
                            },
                            isHidden: function(args) {
                                if (isAdmin() || isDomainAdmin())
                                    return false;
                                else
                                    return true;
                            }
                        },

                        account: {
                            label: 'Account',
                            isHidden: function(args) {
                                if (isAdmin() || isDomainAdmin())
                                    return false;
                                else
                                    return true;
                            }
                        }
                    },

                    dataProvider: function(args) {
                        var data = {};
                        listViewDataProvider(args, data);

                        $.ajax({
                            url: createURL('listEvents'),
                            data: data,
                            success: function(json) {
                                var items = json.listeventsresponse.event;
                                args.response.success({
                                    data: items
                                });
                            }
                        });
                    },
                    detailView: {
                        name: 'label.details',
                        actions: {

                            // Remove single event
                            remove: {
                                label: 'Delete',
                                messages: {
                                    notification: function(args) {
                                        return 'Event Deleted';
                                    },
                                    confirm: function() {
                                        return 'Are you sure you want to remove this event?';
                                    }
                                },
                                action: function(args) {

                                    $.ajax({
                                        url: createURL("deleteEvents&ids=" + args.context.events[0].id),
                                        success: function(json) {
                                            args.response.success();
                                            $(window).trigger('cloudStack.fullRefresh');
                                        }

                                    });
                                }
                            },

                            // Archive single event
                            archive: {
                                label: 'Archive',
                                messages: {
                                    notification: function(args) {
                                        return 'Event Archived';
                                    },
                                    confirm: function() {
                                        return 'Please confirm that you want to archive this event.';
                                    }
                                },
                                action: function(args) {

                                    $.ajax({
                                        url: createURL("archiveEvents&ids=" + args.context.events[0].id),
                                        success: function(json) {
                                            args.response.success();
                                            $(window).trigger('cloudStack.fullRefresh');
                                        }
                                    });
                                }
                            }
                        },
                        tabs: {
                            details: {
                                title: 'label.details',
                                fields: [{
                                    description: {
                                        label: 'label.description'
                                    },
                                    state: {
                                        label: 'label.state'
                                    },
                                    level: {
                                        label: 'label.level'
                                    },
                                    type: {
                                        label: 'label.type'
                                    },
                                    domain: {
                                        label: 'label.domain'
                                    },
                                    account: {
                                        label: 'label.account'
                                    },
                                    username: {
                                        label: 'label.initiated.by'
                                    },
                                    created: {
                                        label: 'label.date',
                                        converter: cloudStack.converters.toLocalDate
                                    },
                                    id: {
                                        label: 'label.id'
                                    }
                                }],
                                dataProvider: function(args) {
                                    $.ajax({
                                        url: createURL("listEvents&id=" + args.context.events[0].id),
                                        dataType: "json",
                                        async: true,
                                        success: function(json) {
                                            var item = json.listeventsresponse.event[0];
                                            args.response.success({
                                                data: item
                                            });
                                        }
                                    });
                                }
                            }
                        }
                    }
                }
            },
            alerts: {
                type: 'select',
                title: 'label.menu.alerts',
                listView: {
                    id: 'alerts',
                    label: 'label.menu.alerts',
                    multiSelect: true,
                    fields: {
                        description: {
                            label: 'label.description'
                        },
                        type: {
                            label: 'Type'
                        },
                        sent: {
                            label: 'label.date',
                            converter: cloudStack.converters.toLocalDate
                        }
                    },

                    actions: {
                        // Remove multiple Alerts
                        removeMulti: {
                            label: 'label.delete.alerts',
                            isHeader: true,
                            addRow: false,
                            isMultiSelectAction: true,
                            messages: {
                                confirm: function(args) {
                                    return 'Please confirm you would like to remove the selected alerts';
                                },
                                notification: function(args) {
                                    return 'label.delete.alerts';
                                }
                            },
                            action: function(args) {
                                var events = args.context.alerts;

                                $.ajax({
                                    url: createURL("deleteAlerts"),
                                    data: {
                                        ids: $(events).map(function(index, event) {
                                            return event.id;
                                        }).toArray().join(',')
                                    },
                                    success: function(data) {
                                        args.response.success();
                                        $(window).trigger('cloudStack.fullRefresh');
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        },

                        remove: {
                            label: 'label.delete.alerts',
                            isHeader: true,
                            addRow: false,
                            messages: {
                                notification: function(args) {
                                    return 'label.delete.alerts';
                                }
                            },
                            createForm: {
                                title: 'label.delete.alerts',
                                desc: '',
                                fields: {
                                    type: {
                                        label: 'label.by.alert.type',
                                        docID: 'helpAlertsDeleteType'
                                    },
                                    startdate: {
                                        label: 'label.by.date.start',
                                        docID: 'helpAlertsDeleteDate',
                                        isDatepicker: true
                                    },
                                    enddate: {
                                        label: 'label.by.date.end',
                                        docID: 'helpAlertsDeleteDate',
                                        isDatepicker: true
                                    }
                                }
                            },
                            action: function(args) {

                                var data = {};

                                if (args.data.type != "")
                                    $.extend(data, {
                                        type: args.data.type
                                    });

                                if (args.data.startdate != "")
                                    $.extend(data, {
                                        startdate: args.data.startdate
                                    });

                                if (args.data.enddate != "")
                                    $.extend(data, {
                                        enddate: args.data.enddate
                                    });

                                $.ajax({
                                    url: createURL("deleteAlerts"),
                                    data: data,
                                    dataType: 'json',
                                    async: false,

                                    success: function(data) {
                                        args.response.success();
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        },

                        // Archive multiple Alerts
                        archiveMulti: {
                            label: 'label.archive.alerts',
                            isHeader: true,
                            addRow: false,
                            isMultiSelectAction: true,
                            messages: {
                                confirm: function(args) {
                                    return 'Please confirm you would like to archive the selected alerts';
                                },
                                notification: function(args) {
                                    return 'label.archive.alerts';
                                }
                            },
                            action: function(args) {
                                var events = args.context.alerts;

                                $.ajax({
                                    url: createURL("archiveAlerts"),
                                    data: {
                                        ids: $(events).map(function(index, event) {
                                            return event.id;
                                        }).toArray().join(',')
                                    },
                                    success: function(data) {
                                        args.response.success();
                                        $(window).trigger('cloudStack.fullRefresh');
                                    },
                                    error:function(data) {
                                        args.response.error(parseXMLHttpResponse(data));
                                    }
                                });
                            }
                        },

                        archive: {
                            label: 'label.archive.alerts',
                            isHeader: true,
                            addRow: false,
                            messages: {
                                notification: function(args) {
                                    return 'label.archive.alerts';
                                }
                            },
                            createForm: {
                                title: 'label.archive.alerts',
                                desc: '',
                                fields: {
                                    type: {
                                        label: 'label.by.alert.type',
                                        docID: 'helpAlertsArchiveType'
                                    },
                                    startdate: {
                                        label: 'label.by.date.start',
                                        docID: 'helpAlertsArchiveDate',
                                        isDatepicker: true
                                    },
                                    enddate: {
                                        label: 'label.by.date.end',
                                        docID: 'helpAlertsArchiveDate',
                                        isDatepicker: true
                                    }

                                }
                            },
                            action: function(args) {
                                var data = {};

                                if (args.data.type != "")
                                    $.extend(data, {
                                        type: args.data.type
                                    });

                                if (args.data.startdate != "")
                                    $.extend(data, {
                                        startdate: args.data.startdate
                                    });

                                if (args.data.enddate != "")
                                    $.extend(data, {
                                        enddate: args.data.enddate
                                    });

                                $.ajax({
                                    url: createURL("archiveAlerts"),
                                    data: data,
                                    dataType: 'json',
                                    async: false,

                                    success: function(data) {
                                        args.response.success();
                                    }
                                });
                            }
                        }
                    },

                    dataProvider: function(args) {
                        var data = {};
                        listViewDataProvider(args, data);

                        $.ajax({
                            url: createURL('listAlerts'),
                            data: data,
                            async: true,
                            success: function(json) {
                                var items = json.listalertsresponse.alert;
                                args.response.success({
                                    data: items
                                });
                            }
                        });
                    },
                    detailView: {
                        name: 'Alert details',
                        actions: {

                            // Remove single Alert
                            remove: {
                                label: 'Delete',
                                messages: {
                                    notification: function(args) {
                                        return 'Alert Deleted';
                                    },
                                    confirm: function() {
                                        return 'Are you sure you want to delete this alert ?';
                                    }
                                },
                                action: function(args) {

                                    $.ajax({
                                        url: createURL("deleteAlerts&ids=" + args.context.alerts[0].id),
                                        success: function(json) {
                                            args.response.success();
                                            $(window).trigger('cloudStack.fullRefresh');
                                        }
                                    });

                                }
                            },

                            archive: {
                                label: 'Archive',
                                messages: {
                                    notification: function(args) {
                                        return 'Alert Archived';
                                    },
                                    confirm: function() {
                                        return 'Please confirm that you want to archive this alert.';
                                    }
                                },
                                action: function(args) {

                                    $.ajax({
                                        url: createURL("archiveAlerts&ids=" + args.context.alerts[0].id),
                                        success: function(json) {
                                            args.response.success();
                                            $(window).trigger('cloudStack.fullRefresh');
                                        }
                                    });
                                }
                            }

                        },

                        tabs: {
                            details: {
                                title: 'label.details',
                                fields: [{
                                    id: {
                                        label: 'ID'
                                    },
                                    description: {
                                        label: 'label.description'
                                    },
                                    sent: {
                                        label: 'label.date',
                                        converter: cloudStack.converters.toLocalDate
                                    }
                                }],
                                dataProvider: function(args) {
                                    $.ajax({
                                        url: createURL("listAlerts&id=" + args.context.alerts[0].id),
                                        dataType: "json",
                                        async: true,
                                        success: function(json) {
                                            var item = json.listalertsresponse.alert[0];
                                            args.response.success({
                                                data: item
                                            });
                                        }
                                    });
                                }
                            }
                        }
                    }
                }
            }
        }
    };
})(cloudStack);
<|endoftext|>


<commit_before>import * as React from "react";
import { polyfill } from "react-lifecycles-compat";
import PropTypes from "prop-types";
import debounce from "lodash.debounce";
import isEqual from "lodash.isequal";
import Input from "@crave/farmblocks-input-text";

import DropdownWrapper from "./styledComponents/DropdownWrapper";
import Menu from "./components/Menu";

class SearchField extends React.Component {
  state = {
    highlightedIndex: -1,
    focused: false,
    inputValue: "",
    lastValue: "",
    lastItems: [],
    selectedItem: null
  };

  debouncedOnSearchChange = debounce(
    this.props.onSearchChange,
    this.props.debounceDelay
  );

  onSearchChange = event => {
    const { value } = event.target;
    this.setState({
      inputValue: value,
      highlightedIndex: -1,
      selectedItem: null
    });
    this.debouncedOnSearchChange(value);
    if (!value) {
      this.debouncedOnSearchChange.flush();
      this.props.onChange();
    }
  };

  componentDidUpdate = prevProps => {
    if (
      prevProps.debounceDelay !== this.props.debounceDelay ||
      prevProps.onSearchChange !== this.props.onSearchChange
    ) {
      this.debouncedOnSearchChange && this.debouncedOnSearchChange.cancel();
      this.debouncedOnSearchChange = debounce(
        this.props.onSearchChange,
        this.props.debounceDelay
      );
    }
  };

  static getDerivedStateFromProps = (props, state) => {
    const valueChanged = props.value !== state.lastValue;
    if (valueChanged || !isEqual(props.items, state.lastItems)) {
      const selectedItem =
        props.items && props.items.find(item => item.value === props.value);
      const inputValue = selectedItem
        ? selectedItem.label
        : valueChanged
          ? ""
          : state.inputValue;
      return {
        inputValue,
        selectedItem,
        lastValue: props.value,
        lastItems: props.items
      };
    }
    return null;
  };

  componentWillUnmount = () => {
    this.debouncedOnSearchChange.cancel();
  };

  changeHighlight = modifier => {
    this.setState(prevState => {
      const { items } = this.props;
      const highlightedIndex = items
        ? Math.max(
            Math.min(prevState.highlightedIndex + modifier, items.length - 1),
            -1
          )
        : -1;
      this.scroller && this.scroller.centerChildByIndex(highlightedIndex);
      return {
        highlightedIndex
      };
    });
  };

  onKeyDown = event => {
    const { key } = event;
    switch (key) {
      case "Enter":
        if (this.state.highlightedIndex < 0) {
          this.debouncedOnSearchChange.flush();
        } else {
          this.onChange(this.state.highlightedIndex);
        }
        break;
      case "Escape":
        this.setState({ highlightedIndex: -1 });
        break;
      case "ArrowUp":
        event.preventDefault();
        this.changeHighlight(-1);
        break;
      case "ArrowDown":
        event.preventDefault();
        this.changeHighlight(1);
        break;
    }
  };

  onChange = index => {
    const selectedItem = this.props.items && this.props.items[index];
    if (selectedItem) {
      this.setState({ selectedItem });
      this.props.onChange(selectedItem.value);
    }
    this.input && this.input.blur();
  };

  onFocus = () => this.setState({ focused: true, highlightedIndex: -1 });

  onBlur = () => {
    const focusReset = { focused: false, highlightedIndex: -1 };
    this.setState(prevState => {
      if (prevState.selectedItem) {
        return focusReset;
      }
      this.props.onSearchChange("");
      this.props.onChange();
      return { ...focusReset, inputValue: "", selectedItem: null };
    });
  };

  preventBlur = event => {
    event.preventDefault();
  };

  onItemClick = ({ currentTarget }) => {
    const selectedIndex =
      this.scroller &&
      this.scroller.wrapper && // ref inside a ref 😜
      Array.from(this.scroller.wrapper.childNodes).indexOf(currentTarget);

    this.onChange(selectedIndex);
  };

  _renderMenu = props => {
    const { highlightedIndex } = this.state;

    return (
      <Menu
        {...props}
        innerRef={node => (this.scroller = node)}
        onItemClick={this.onItemClick}
        highlightedIndex={highlightedIndex}
      />
    );
  };

  getInputValue = () => {
    const { selectedItem, highlightedIndex, inputValue } = this.state;
    if (selectedItem) return selectedItem.label;
    if (highlightedIndex === -1) return inputValue;

    const { items } = this.props;
    const highlightedItem = items && items[highlightedIndex];

    if (highlightedItem) return highlightedItem.label;
    return "";
  };

  render() {
    const {
      width,
      onSearchChange,
      debounceDelay,
      maxMenuHeight,
      items,
      onScrollReachEnd,
      onChange,
      footer,
      value,
      zIndex,
      ...inputProps
    } = this.props;

    const menuProps = {
      maxMenuHeight,
      items,
      onScrollReachEnd,
      footer
    };

    const { focused, selectedItem } = this.state;

    return (
      <DropdownWrapper
        style={{ width, zIndex }}
        className={!focused && !!selectedItem && "selected"}
      >
        <Input
          value={this.getInputValue()}
          onChange={this.onSearchChange}
          type={selectedItem ? "text" : "search"}
          clearable
          clearIcon={selectedItem ? "wg-edit" : undefined}
          displayBlock
          onKeyDown={this.onKeyDown}
          onFocus={this.onFocus}
          onBlur={this.onBlur}
          innerRef={node => (this.input = node)}
          {...inputProps}
        />
        {focused && (items || footer) && this._renderMenu(menuProps)}
      </DropdownWrapper>
    );
  }

  static defaultProps = {
    onSearchChange: () => false,
    onScrollReachEnd: () => false,
    onChange: () => false,
    width: 200,
    maxMenuHeight: 353,
    debounceDelay: 500
  };

  static propTypes = {
    width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    debounceDelay: PropTypes.number,
    onSearchChange: PropTypes.func,
    onChange: PropTypes.func,
    zIndex: PropTypes.number,
    ...Menu.propTypes
  };
}

// For React 16.2 or older
polyfill(SearchField);

export default SearchField;
<commit_msg>refactor(search-field): innerRef is no longer needed by the input after the mousedown change<commit_after>import * as React from "react";
import { polyfill } from "react-lifecycles-compat";
import PropTypes from "prop-types";
import debounce from "lodash.debounce";
import isEqual from "lodash.isequal";
import Input from "@crave/farmblocks-input-text";

import DropdownWrapper from "./styledComponents/DropdownWrapper";
import Menu from "./components/Menu";

class SearchField extends React.Component {
  state = {
    highlightedIndex: -1,
    focused: false,
    inputValue: "",
    lastValue: "",
    lastItems: [],
    selectedItem: null
  };

  debouncedOnSearchChange = debounce(
    this.props.onSearchChange,
    this.props.debounceDelay
  );

  onSearchChange = event => {
    const { value } = event.target;
    this.setState({
      inputValue: value,
      highlightedIndex: -1,
      selectedItem: null
    });
    this.debouncedOnSearchChange(value);
    if (!value) {
      this.debouncedOnSearchChange.flush();
      this.props.onChange();
    }
  };

  componentDidUpdate = prevProps => {
    if (
      prevProps.debounceDelay !== this.props.debounceDelay ||
      prevProps.onSearchChange !== this.props.onSearchChange
    ) {
      this.debouncedOnSearchChange && this.debouncedOnSearchChange.cancel();
      this.debouncedOnSearchChange = debounce(
        this.props.onSearchChange,
        this.props.debounceDelay
      );
    }
  };

  static getDerivedStateFromProps = (props, state) => {
    const valueChanged = props.value !== state.lastValue;
    if (valueChanged || !isEqual(props.items, state.lastItems)) {
      const selectedItem =
        props.items && props.items.find(item => item.value === props.value);
      const inputValue = selectedItem
        ? selectedItem.label
        : valueChanged
          ? ""
          : state.inputValue;
      return {
        inputValue,
        selectedItem,
        lastValue: props.value,
        lastItems: props.items
      };
    }
    return null;
  };

  componentWillUnmount = () => {
    this.debouncedOnSearchChange.cancel();
  };

  changeHighlight = modifier => {
    this.setState(prevState => {
      const { items } = this.props;
      const highlightedIndex = items
        ? Math.max(
            Math.min(prevState.highlightedIndex + modifier, items.length - 1),
            -1
          )
        : -1;
      this.scroller && this.scroller.centerChildByIndex(highlightedIndex);
      return {
        highlightedIndex
      };
    });
  };

  onKeyDown = event => {
    const { key } = event;
    switch (key) {
      case "Enter":
        if (this.state.highlightedIndex < 0) {
          this.debouncedOnSearchChange.flush();
        } else {
          this.onChange(this.state.highlightedIndex);
        }
        break;
      case "Escape":
        this.setState({ highlightedIndex: -1 });
        break;
      case "ArrowUp":
        event.preventDefault();
        this.changeHighlight(-1);
        break;
      case "ArrowDown":
        event.preventDefault();
        this.changeHighlight(1);
        break;
    }
  };

  onChange = index => {
    const selectedItem = this.props.items && this.props.items[index];
    if (selectedItem) {
      this.setState({ selectedItem });
      this.props.onChange(selectedItem.value);
    }
  };

  onFocus = () => this.setState({ focused: true, highlightedIndex: -1 });

  onBlur = () => {
    const focusReset = { focused: false, highlightedIndex: -1 };
    this.setState(prevState => {
      if (prevState.selectedItem) {
        return focusReset;
      }
      this.props.onSearchChange("");
      this.props.onChange();
      return { ...focusReset, inputValue: "", selectedItem: null };
    });
  };

  preventBlur = event => {
    event.preventDefault();
  };

  onItemClick = ({ currentTarget }) => {
    const selectedIndex =
      this.scroller &&
      this.scroller.wrapper && // ref inside a ref 😜
      Array.from(this.scroller.wrapper.childNodes).indexOf(currentTarget);

    this.onChange(selectedIndex);
  };

  _renderMenu = props => {
    const { highlightedIndex } = this.state;

    return (
      <Menu
        {...props}
        innerRef={node => (this.scroller = node)}
        onItemClick={this.onItemClick}
        highlightedIndex={highlightedIndex}
      />
    );
  };

  getInputValue = () => {
    const { selectedItem, highlightedIndex, inputValue } = this.state;
    if (selectedItem) return selectedItem.label;
    if (highlightedIndex === -1) return inputValue;

    const { items } = this.props;
    const highlightedItem = items && items[highlightedIndex];

    if (highlightedItem) return highlightedItem.label;
    return "";
  };

  render() {
    const {
      width,
      onSearchChange,
      debounceDelay,
      maxMenuHeight,
      items,
      onScrollReachEnd,
      onChange,
      footer,
      value,
      zIndex,
      ...inputProps
    } = this.props;

    const menuProps = {
      maxMenuHeight,
      items,
      onScrollReachEnd,
      footer
    };

    const { focused, selectedItem } = this.state;

    return (
      <DropdownWrapper
        style={{ width, zIndex }}
        className={!focused && !!selectedItem && "selected"}
      >
        <Input
          value={this.getInputValue()}
          onChange={this.onSearchChange}
          type={selectedItem ? "text" : "search"}
          clearable
          clearIcon={selectedItem ? "wg-edit" : undefined}
          displayBlock
          onKeyDown={this.onKeyDown}
          onFocus={this.onFocus}
          onBlur={this.onBlur}
          {...inputProps}
        />
        {focused && (items || footer) && this._renderMenu(menuProps)}
      </DropdownWrapper>
    );
  }

  static defaultProps = {
    onSearchChange: () => false,
    onScrollReachEnd: () => false,
    onChange: () => false,
    width: 200,
    maxMenuHeight: 353,
    debounceDelay: 500
  };

  static propTypes = {
    width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    debounceDelay: PropTypes.number,
    onSearchChange: PropTypes.func,
    onChange: PropTypes.func,
    zIndex: PropTypes.number,
    ...Menu.propTypes
  };
}

// For React 16.2 or older
polyfill(SearchField);

export default SearchField;
<|endoftext|>


<commit_before><commit_msg>Moved <select> based filter to SelectionFilter<commit_after><|endoftext|>


<commit_before>$.widget("wheregroup.queryResultView", {
    tableDefaults: {
        lengthChange: false,
        pageLength:   15,
        searching:    true,
        info:         true,
        processing:   false,
        ordering:     true,
        paging:       true,
        autoWidth:    false
    },

    /**
     * Settings for saving
     */
    preparedData:{
    },

    table: null,

    /**
     * Constructor
     */
    _create: function() {
        this.render(this.element.data('query'));
    },

    /**
     * Render
     */
    render: function(query) {
        var widget = this;
        var element = $(widget.element);
        var table;

        this.element.attr('data-id', query.id);
        $('input[name="extent-only"]', this.element).on('change', function() {
            widget._trigger('changeExtend', null, {
                query:   query,
                widget:  widget,
                element: element,
                checked: $(this).prop('checked')
            });
        }).prop('checked', !!query.extendOnly);

        function escapeHtml(text) {
            'use strict';
            return text.replace(/["&'\/<>]/g, function (a) {
                return {
                    '"': '"', '&': '&', "'": ''',
                    '/': '/',  '<': '<',  '>': '>'
                }[a];
            });
        }

        var columns = [];

        _.each(query.fields, function(definition) {
            columns.push({
                title: definition.title,
                data:  function(row, type, val, meta) {
                    var data = row.data[definition.fieldName];
                    if(typeof (data) == 'string') {
                        data = escapeHtml(data);
                    }
                    return data;
                }
            });
        });

        var tableOptions = _.extend({
            columns: columns,
            createdRow: function(tr, feature) {
                $(tr).data({feature: feature});
                feature.tableRow = tr;
            }
        }, this.tableDefaults)

        // Add buttons column
        tableOptions.columnDefs = [{
            targets: -1,
            width: '1%',
            orderable: false,
            searchable: false,
            defaultContent: $('.-tpl-query-table-buttons', this.element).remove().html()
        }];
        tableOptions.columns.push({
            data: null,
            title: ''
        });

        table = this.table = $('.resultQueries', this.element).resultTable(tableOptions);

        table.find("tbody")
            .off('click', '> tr')
            .on('click', '> tr[role="row"]', function(e) {
                if ($(e.target).parentsUntil(this).is('.buttons')) {
                    return;
                }
                var olFeature = $(this).data('feature');
                if(!olFeature) {
                    return;
                }

                widget._trigger('featureClick', null, {
                    feature:  olFeature,
                    ui: this,
                    query: query
                });
                return false;
            })
            .off('mouseover', '> tr')
            .on('mouseover', '> tr[role="row"]', function(e) {
                if ($(e.target).parentsUntil(this).is('.buttons')) {
                    return;
                }
                var olFeature = $(this).data('feature');
                if(!olFeature) {
                    return false;
                }

                widget._trigger('featureOver', null, {
                    feature:  olFeature
                });
                return false;
            })
            .off('mouseout', '> tr')
            .on('mouseout', '> tr[role="row"]', function(e) {
                if ($(e.target).parentsUntil(this).is('.buttons')) {
                    return;
                }
                var olFeature = $(this).data('feature');
                if(!olFeature) {
                    return false;
                }

                widget._trigger('featureOut', null, {
                    feature:  olFeature
                });
                return false;
            })
            .on('click', '.-fn-zoomto', function() {
                widget._trigger('zoomTo', null, {
                    feature: $(this).closest('tr').data('feature'),
                });
            })
            .on('click', '.-fn-toggle-visibility', function() {
                widget._trigger('toggleVisibility', null, {
                    feature: $(this).closest('tr').data('feature'),
                    ui:      $(this)
                });
            })
            .on('click', '.-fn-bookmark', function() {
                widget._trigger('mark', null, {
                    ui: this
                });
            })
        ;

        element.append(table);

        // Add placeholder to result table filter search input
        $('input[type="search"]', table).attr('placeholder', _.pluck(query.fields, 'title').join(', '));

        return element;
    },

    updateList: function(list) {
        var $table = $('table:first', this.table);
        var tableApi = $table.dataTable().api();
        tableApi.clear();
        tableApi.rows.add(list);
        tableApi.draw();
    }
});

<commit_msg>Remove redundant table button event order workarounds<commit_after>$.widget("wheregroup.queryResultView", {
    tableDefaults: {
        lengthChange: false,
        pageLength:   15,
        searching:    true,
        info:         true,
        processing:   false,
        ordering:     true,
        paging:       true,
        autoWidth:    false
    },

    /**
     * Settings for saving
     */
    preparedData:{
    },

    table: null,

    /**
     * Constructor
     */
    _create: function() {
        this.render(this.element.data('query'));
    },

    /**
     * Render
     */
    render: function(query) {
        var widget = this;
        var element = $(widget.element);
        var table;

        this.element.attr('data-id', query.id);
        $('input[name="extent-only"]', this.element).on('change', function() {
            widget._trigger('changeExtend', null, {
                query:   query,
                widget:  widget,
                element: element,
                checked: $(this).prop('checked')
            });
        }).prop('checked', !!query.extendOnly);

        function escapeHtml(text) {
            'use strict';
            return text.replace(/["&'\/<>]/g, function (a) {
                return {
                    '"': '"', '&': '&', "'": ''',
                    '/': '/',  '<': '<',  '>': '>'
                }[a];
            });
        }

        var columns = [];

        _.each(query.fields, function(definition) {
            columns.push({
                title: definition.title,
                data:  function(row, type, val, meta) {
                    var data = row.data[definition.fieldName];
                    if(typeof (data) == 'string') {
                        data = escapeHtml(data);
                    }
                    return data;
                }
            });
        });

        var tableOptions = _.extend({
            columns: columns,
            createdRow: function(tr, feature) {
                $(tr).data({feature: feature});
                feature.tableRow = tr;
            }
        }, this.tableDefaults)

        // Add buttons column
        tableOptions.columnDefs = [{
            targets: -1,
            width: '1%',
            orderable: false,
            searchable: false,
            defaultContent: $('.-tpl-query-table-buttons', this.element).remove().html()
        }];
        tableOptions.columns.push({
            data: null,
            title: ''
        });

        table = this.table = $('.resultQueries', this.element).resultTable(tableOptions);

        table.find("tbody")
            .on('click', '> tr[role="row"]', function(e) {
                var olFeature = $(this).data('feature');
                if(!olFeature) {
                    return;
                }

                widget._trigger('featureClick', null, {
                    feature:  olFeature,
                    ui: this,
                    query: query
                });
                return false;
            })
            .on('mouseover', '> tr[role="row"]', function(e) {
                var olFeature = $(this).data('feature');
                if(!olFeature) {
                    return false;
                }

                widget._trigger('featureOver', null, {
                    feature:  olFeature
                });
                return false;
            })
            .on('mouseout', '> tr[role="row"]', function(e) {
                var olFeature = $(this).data('feature');
                if(!olFeature) {
                    return false;
                }

                widget._trigger('featureOut', null, {
                    feature:  olFeature
                });
                return false;
            })
            .on('click', '.-fn-zoomto', function() {
                widget._trigger('zoomTo', null, {
                    feature: $(this).closest('tr').data('feature'),
                });
            })
            .on('click', '.-fn-toggle-visibility', function() {
                widget._trigger('toggleVisibility', null, {
                    feature: $(this).closest('tr').data('feature'),
                    ui:      $(this)
                });
            })
            .on('click', '.-fn-bookmark', function() {
                widget._trigger('mark', null, {
                    ui: this
                });
            })
        ;

        element.append(table);

        // Add placeholder to result table filter search input
        $('input[type="search"]', table).attr('placeholder', _.pluck(query.fields, 'title').join(', '));

        return element;
    },

    updateList: function(list) {
        var $table = $('table:first', this.table);
        var tableApi = $table.dataTable().api();
        tableApi.clear();
        tableApi.rows.add(list);
        tableApi.draw();
    }
});

<|endoftext|>


<commit_before><commit_msg>Integrate Doug's changes with existing code<commit_after><|endoftext|>