owncloud/core

View on GitHub
settings/js/users/groups.js

Summary

Maintainability
C
1 day
Test Coverage
/**
 * Copyright (c) 2014, Raghu Nayyar <beingminimal@gmail.com>
 * Copyright (c) 2014, Arthur Schiwon <blizzz@owncloud.com>
 * This file is licensed under the Affero General Public License version 3 or later.
 * See the COPYING-README file.
 */

var GroupList;
var GroupDeleteHandler;

(function () {
    GroupList = {
        activeGID: '',
        everyoneGID: '_everyone',
        filter: '',
        filterGroups: false,
        $userGroupList: null,
        $sortGroupBy: null,

        setUserGroupListEl: function($el) {
            this.$userGroupList = $el;
        },

        setUserGroupByEl: function($el) {
            this.$sortGroupBy = $el;
        },

        addGroup: function (gid, name, usercount) {
            var $li = $(
                '<li class="isgroup" data-gid="' + gid + '" data-usercount="0">' +
                '    <a href="#" class="dorename">' +
                '        <span class="groupname">' + name + '</span>' +
                '        <span class="usercount tag"></span>' +
                '    </a>' +
                '    <span class="utils">' +
                '        <a href="#" class="action delete" original-title="' + t('settings', 'Delete') + '">' +
                '            <img src="' + OC.imagePath('core', 'actions/delete') + '"/>' +
                '        </a>' +
                '    </span>' +
                '</li>');

            GroupList.setUserCount($li, usercount);
            $li.appendTo(this.$userGroupList);
            GroupList.sortGroups();
            return $li;
        },

        setUserCount: function (groupLiElement, usercount) {
            var $groupLiElement = $(groupLiElement);
            if (this.$sortGroupBy !== 1) {
                // If we don't sort by group count we don't display them either
                $groupLiElement.find('span.usercount.tag').remove();
                return;
            }

            if (usercount === undefined || usercount === 0 || usercount < 0) {
                usercount = 0;
                $groupLiElement.data('usercount', 0);
            } else {
                $groupLiElement.data('usercount', usercount);
            }
            $groupLiElement.find('.usercount').text(usercount);
        },

        getUserCount: function ($groupLiElement) {
            return parseInt($groupLiElement.data('usercount'), 10);
        },

        modGroupCount: function(gid, diff) {
            var $li = GroupList.getGroupLI(gid);
            var count = GroupList.getUserCount($li) + diff;
            GroupList.setUserCount($li, count);
        },

        incEveryoneCount: function() {
            GroupList.modGroupCount(GroupList.everyoneGID, 1);
        },

        decEveryoneCount: function() {
            GroupList.modGroupCount(GroupList.everyoneGID, -1);
        },

        incGroupCount: function(gid) {
            GroupList.modGroupCount(gid, 1);
        },

        decGroupCount: function(gid) {
            GroupList.modGroupCount(gid, -1);
        },

        getCurrentGID: function () {
            return GroupList.activeGID;
        },

        sortGroups: function () {
            var lis = this.$userGroupList.find('.isgroup').get();

            lis.sort(function (a, b) {
                // "Everyone" always at the top
                if ($(a).data('gid') === '_everyone') {
                    return -1;
                } else if ($(b).data('gid') === '_everyone') {
                    return 1;
                }

                // "admin" always as second
                if ($(a).data('gid') === 'admin') {
                    return -1;
                } else if ($(b).data('gid') === 'admin') {
                    return 1;
                }

                if (this.$sortGroupBy === 1) {
                    // Sort by user count first
                    var $usersGroupA = $(a).data('usercount'),
                        $usersGroupB = $(b).data('usercount');
                    if ($usersGroupA > 0 && $usersGroupA > $usersGroupB) {
                        return -1;
                    }
                    if ($usersGroupB > 0 && $usersGroupB > $usersGroupA) {
                        return 1;
                    }
                }

                // Fallback or sort by group name
                return UserList.alphanum(
                    $(a).find('a span').text(),
                    $(b).find('a span').text()
                );
            });

            var items = [];
            var self = this;
            $.each(lis, function (index, li) {
                items.push(li);
                if (items.length === 100) {
                    self.$userGroupList.append(items);
                    items = [];
                }
            });
            if (items.length > 0) {
                this.$userGroupList.append(items);
            }
        },

        createGroup: function (groupname) {
            $.post(
                OC.generateUrl('/settings/users/groups'),
                {
                    id: groupname
                },
                function (result) {
                    if (result.gid) {
                        var newGroups = {};
                        newGroups[result.gid] = result.name;
                        UserList.availableGroups = $.extend(UserList.availableGroups, newGroups);
                        GroupList.addGroup(result.gid, result.name);
                    }
                    GroupList.toggleAddGroup();
                }).fail(function(result) {
                    OC.Notification.showTemporary(t('settings', 'Error creating group: {message}', {
                        message: result.responseJSON.message
                    }));
                });
        },

        update: function () {
            if (GroupList.updating) {
                return;
            }
            GroupList.updating = true;
            $.get(
                OC.generateUrl('/settings/users/groups'),
                {
                    pattern: this.filter,
                    filterGroups: this.filterGroups ? 1 : 0,
                    sortGroups: this.$sortGroupBy
                },
                function (result) {

                    var lis = [];
                    if (result.status === 'success') {
                        $.each(result.data, function (i, subset) {
                            $.each(subset, function (index, group) {
                                if (GroupList.getGroupLI(group.name).length > 0) {
                                    GroupList.setUserCount(GroupList.getGroupLI(group.name).first(), group.usercount);
                                }
                                else {
                                    var $li = GroupList.addGroup(group.gid, group.name, group.usercount);

                                    $li.addClass('appear transparent');
                                    lis.push($li);
                                }
                            });
                        });
                        if (result.data.length > 0) {
                            GroupList.doSort();
                        }
                        else {
                            GroupList.noMoreEntries = true;
                        }
                        _.defer(function () {
                            $(lis).each(function () {
                                this.removeClass('transparent');
                            });
                        });
                    }
                    GroupList.updating = false;

                }
            );
        },

        elementBelongsToAddGroup: function (el) {
            return !(el !== $('#newgroup-form').get(0) &&
            $('#newgroup-form').find($(el)).length === 0);
        },

        hasAddGroupNameText: function () {
            var name = $('#newgroupname').val();
            return $.trim(name) !== '';

        },

        showGroup: function (gid) {
            GroupList.activeGID = gid;
            UserList.empty();
            UserList.update(gid);
            this.$userGroupList.find('li').removeClass('active');
            if (gid !== undefined) {
                //TODO: treat Everyone properly
                GroupList.getGroupLI(gid).addClass('active');
            }
        },

        isAddGroupButtonVisible: function () {
            return $('#newgroup-init').is(":visible");
        },

        toggleAddGroup: function (event) {
            if (GroupList.isAddGroupButtonVisible()) {
                event.stopPropagation();
                $('#newgroup-form').show();
                $('#newgroup-init').hide();
                $('#newgroupname').focus();
                GroupList.handleAddGroupInput('');
            }
            else {
                $('#newgroup-form').hide();
                $('#newgroup-init').show();
                $('#newgroupname').val('');
            }
        },

        handleAddGroupInput: function (input) {
            if(input.length) {
                $('#newgroup-form input[type="submit"]').attr('disabled', null);
            } else {
                $('#newgroup-form input[type="submit"]').attr('disabled', 'disabled');
            }
        },

        isGroupNameValid: function (groupname) {
            if ($.trim(groupname) === '') {
                OC.Notification.showTemporary(t('settings', 'Error creating group: {message}', {
                    message: t('settings', 'A valid group name must be provided')
                }));
                return false;
            }
            return true;
        },

        hide: function (gid) {
            GroupList.getGroupLI(gid).hide();
        },
        show: function (gid) {
            GroupList.getGroupLI(gid).show();
        },
        remove: function (gid) {
            GroupList.getGroupLI(gid).remove();
            GroupList.showGroup(GroupList.everyoneGID);
        },
        empty: function () {
            this.$userGroupList.find('.isgroup').filter(function(index, item){
                return $(item).data('gid') !== '';
            }).remove();
        },
        initDeleteHandling: function () {
            //set up handler
            GroupDeleteHandler = new DeleteHandler('/settings/users/groups', 'groupname',
                GroupList.hide, GroupList.remove, GroupList.show);

            //when to mark user for delete
            this.$userGroupList.on('click', '.delete', function () {
                // Call function for handling delete/undo
                var groupName = encodeURIComponent(GroupList.getElementGID(this)).toString();
                OC.dialogs.confirm(
                    t('settings', 'You are about to delete a group. This action can\'t be undone and is permanent. Are you sure that you want to permanently delete {groupName}?', {groupName:decodeURIComponent(groupName)}),
                    t('settings', 'Delete group'),
                    function (confirmation) {
                        if (confirmation) {
                            GroupDeleteHandler.mark(groupName);
                            GroupDeleteHandler.deleteEntry();
                        }
                    }
                );
            });
        },

        getGroupLI: function (gid) {
            return this.$userGroupList.find('li.isgroup').filter(function () {
                return GroupList.getElementGID(this) === gid;
            });
        },

        getElementGID: function (element) {
            return ($(element).closest('li').attr('data-gid') || '');
        },
        getEveryoneCount: function () {
            $.ajax({
                type: "GET",
                dataType: "json",
                url: OC.generateUrl('/settings/users/stats')
            }).success(function (data) {
                $('#everyonegroup').data('usercount', data.totalUsers);
                $('#everyonecount').text(data.totalUsers);
            });
        }
    };

    if (!OCA.UserManagement) {
        OCA.UserManagement = {};
    }
    OCA.UserManagement.GroupList = GroupList;
})();

$(document).ready( function () {
    var $userGroupList = $('#usergrouplist');
    GroupList.setUserGroupListEl($userGroupList);
    GroupList.initDeleteHandling();
    var $sortGroupBy = $userGroupList.data('sort-groups');
    GroupList.setUserGroupByEl($sortGroupBy);
    if ($sortGroupBy === 1) {
        // Disabled due to performance issues, when we don't need it for sorting
        GroupList.getEveryoneCount();
    } else {
        $userGroupList.find('span.usercount.tag').remove();
    }

    // Display or hide of Create Group List Element
    $('#newgroup-form').hide();
    $('#newgroup-init').on('click', function (e) {
        GroupList.toggleAddGroup(e);
    });

    $(document).on('click keydown keyup', function(event) {
        if(!GroupList.isAddGroupButtonVisible() &&
            !GroupList.elementBelongsToAddGroup(event.target) &&
            !GroupList.hasAddGroupNameText()) {
            GroupList.toggleAddGroup();
        }
        // Escape
        if(!GroupList.isAddGroupButtonVisible() && event.keyCode && event.keyCode === 27) {
            GroupList.toggleAddGroup();
        }
    });


    // Responsible for Creating Groups.
    $('#newgroup-form form').submit(function (event) {
        event.preventDefault();
        if(GroupList.isGroupNameValid($('#newgroupname').val())) {
            GroupList.createGroup($('#newgroupname').val());
        }
    });

    // click on group name
    $userGroupList.on('click', '.isgroup', function () {
        GroupList.showGroup(GroupList.getElementGID(this));
    });

    $('#newgroupname').on('input', function(){
        GroupList.handleAddGroupInput(this.value);
    });
});