From 9446f04f7d67ac87ef6646c4826d435fb05d558c Mon Sep 17 00:00:00 2001 From: William Glass-Husain Date: Fri, 16 Apr 2021 10:27:18 -0700 Subject: [PATCH] TEMPLATE-529. translate v3 keys to v2 when logging in (#236) TEMPLATE-529. translate v3 keys to v2 when logging in --- .gitignore | 1 + CHANGELOG.md | 36 + .../assignment/assignment.min.js.map | 2 +- dist/components/assignment/index.html | 188 +- dist/components/login/login.css | 580 +- dist/components/login/login.html | 130 +- dist/components/login/login.js | 342 +- dist/components/login/login.js.map | 2 +- dist/components/readme.md | 40 +- dist/epicenter.js | 6150 +++---- dist/epicenter.js.map | 2 +- dist/epicenter.min.js | 2 +- dist/epicenter.min.js.map | 2 +- package-lock.json | 14448 ---------------- src/managers/auth-manager-v3/index.js | 65 +- src/service/user-api-adapter/index.js | 16 + 16 files changed, 3835 insertions(+), 18171 deletions(-) delete mode 100644 package-lock.json diff --git a/.gitignore b/.gitignore index b23b04ef..7e45d6d5 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,4 @@ coverage/ **/.DS_Store *.orig +package.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index fd2bc4d3..54f52413 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,39 @@ + +### 2.13.5 +This is a bug fix release. + +### Bug Fixes +- The v3 login component now correctly converts the v3 user keys to v2 user ids. For early users + these are the same but for recently created users these may be different. + + +### 2.13.4 +This is a bug fix release. + +### Bug Fixes +- Fully remove all session cookies when logging out. Previously did not remove epicenter-scenario cookie. + + +### 2.13.3 +This is a minor release. + +### Improvements +-- expose rawDataChannel for settingsManager APIs. + + +### 2.13.2 +This is a minor release. + +### Bug Fixes +-- Fix the samesite cookie setting to work with local development. + + +### 2.13.1 +This is a minor release. + +### Bug Fixes +-- Use the v3 member API with multiple groups. + ### 2.13.0 diff --git a/dist/components/assignment/assignment.min.js.map b/dist/components/assignment/assignment.min.js.map index 9d04480d..91621802 100644 --- a/dist/components/assignment/assignment.min.js.map +++ b/dist/components/assignment/assignment.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///assignment.min.js","webpack:///webpack/bootstrap 5b36529e33521661d9bd","webpack:///./src/util/inherit.js","webpack:///./src/components/assignment/js/service-locator.js","webpack:///./src/components/assignment/js/base-model.js","webpack:///./src/components/assignment/js/defaults.js","webpack:///./src/components/assignment/js/user-model.js","webpack:///./src/components/assignment/js/base-collection.js","webpack:///./src/components/assignment/js/index.js","webpack:///./src/components/assignment/js/assignment.js","webpack:///./src/components/assignment/js/users-collection.js","webpack:///./src/components/assignment/js/worlds-collection.js","webpack:///./src/components/assignment/js/world-model.js","webpack:///./src/components/assignment/js/project-model.js","webpack:///./src/components/assignment/js/assignment-row.js","webpack:///./src/util/ajax-queue.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","inherit","C","P","F","__super","constructor","extend","dest","obj","Array","slice","arguments","current","j","length","key","base","props","staticProps","parent","child","apply","this","env","require","cache","worldApi","service","World","memberApi","Member","_","pick","userApi","User","BaseModel","attr","options","defaults","result","_data","set","initialize","val","attrs","remove","collection","toJSON","keys","account","project","group","groupId","token","server","host","protocol","merge","classFrom","Base","serviceLocator","world","role","active","isWorldComplete","firstName","lastName","makeActive","params","userId","original","makeUserActive","fail","bind","makeInactive","makeUserInactive","BaseCollection","models","_models","idAttribute","create","model","reset","concat","forEach","push","sort","sortFn","a","b","getById","id","find","each","cb","ctx","all","every","invoke","fn","filter","size","map","pluck","field","App","window","forio","MultiplayerAssignmentComponent","setEnvironment","omit","UsersCollection","WorldsCollection","ProjectModel","AssignemntRow","default","AjaxQueue","Assignment","el","$","$el","partialRight","users","worlds","bindAll","bindEvents","on","saveEdit","toggleControlls","selectAll","usassignSelected","autoAssignAll","load","join","setUsersCollection","joinUsers","render","when","fetch","then","updateControls","_showUpdating","maxUsers","_hideUpdating","getSelectedIds","data","findRowViews","ids","rowViews","unassignUsers","dtd","Deferred","done","resolve","queue","user","add","partial","updateUser","execute","promise","e","preventDefault","makeUsersInactive","rows","view","empty","sortTable","renderTable","getTableParams","mult","direction","nameDirection","userNameDirection","prop","an","bn","localeCompare","header","arrowDir","arrow","append","query","location","search","substr","split","q","u","updateControlsForSelection","updateAutoAssignButton","updateStatus","incompleteWorlds","getIncompleteWorldsCount","unassignedUsers","getUnassignedUsersCount","totalWorlds","usersText","worldsText","text","addClass","removeClass","numSelected","isDynamicAssignment","hasRoles","hide","show","allUsersAssigned","target","checked","total","removeAttr","css","opacity","Model","aw","toLowerCase","bw","am","manager","AuthManager","session","getCurrentUserSessionInfo","auth_token","ajaxSetup","headers","Authorization","me","splitIdChunks","userIds","idGroups","splice","loadUsersInfo","nonFacAndActive","endUsers","members","endUserIds","chunkedUsers","chunkedPromises","userGroups","reduce","acc","userGroup","getGroupDetails","reject","UserModel","doneFn","after","autoAssign","parse","w","worldName","prevWorld","getWorldByUser","curWorld","getOrCreateWorld","removeUser","addUser","getWordByName","Error","getWorldByUserId","getWorldNames","getNextWorldName","properNames","test","lastWorld","numWorld","match","num","places","zeros","digits","toString","needed","usersCollection","usersHash","isComplete","index","list","_worldApi","updateConfig","userObj","save","checkWorld","delete","mapUsers","res","createWorld","addUsers","savedUsers","isNew","roles","getProjectSettings","settings","__webpack_exports__","userRowTemplate","trim","AssignmentRow","template","editTemplate","editUserRowTemplate","setEditMode","cancelEdit","off","animate","height","duration","complete","removeEditMode","updateData","trigger","templ","vm","optionalRoles","newWorld","html","context","next","shift"],"mappings":"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","file":"assignment.min.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 6);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/**\n/* Inherit from a class (using prototype borrowing)\n*/\n\n\nfunction inherit(C, P) {\n var F = function () {};\n F.prototype = P.prototype;\n C.prototype = new F();\n C.__super = P.prototype;\n C.prototype.constructor = C;\n}\n\n/**\n* Shallow copy of an object\n* @param {Object} dest object to extend\n* @return {Object} extended object\n*/\nvar extend = function (dest /*, var_args*/) {\n var obj = Array.prototype.slice.call(arguments, 1);\n var current;\n for (var j = 0; j < obj.length; j++) {\n if (!(current = obj[j])) {\n //eslint-disable-line\n continue;\n }\n\n // do not wrap inner in dest.hasOwnProperty or bad things will happen\n for (var key in current) {\n //eslint-disable-line\n dest[key] = current[key];\n }\n }\n\n return dest;\n};\n\nmodule.exports = function (base, props, staticProps) {\n var parent = base;\n var child;\n\n child = props && props.hasOwnProperty('constructor') ? props.constructor : function () {\n return parent.apply(this, arguments);\n };\n\n // add static properties to the child constructor function\n extend(child, parent, staticProps);\n\n // associate prototype chain\n inherit(child, parent);\n\n // add instance properties\n if (props) {\n extend(child.prototype, props);\n }\n\n // done\n return child;\n};\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar env = __webpack_require__(3);\n\nvar cache = {};\n\nmodule.exports = {\n worldApi: function () {\n if (!cache.worldApi) {\n cache.worldApi = new F.service.World(env.get());\n }\n return cache.worldApi;\n },\n\n memberApi: function () {\n if (!cache.memberApi) {\n cache.memberApi = new F.service.Member(_.pick(env.get(), ['groupId', 'server']));\n }\n\n return cache.memberApi;\n },\n\n userApi: function () {\n if (!cache.userApi) {\n cache.userApi = new F.service.User(_.pick(env.get(), ['account', 'server']));\n }\n\n return cache.userApi;\n }\n};\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar BaseModel = function (attr, options) {\n attr = _.defaults({}, attr, _.result(this, 'defaults'));\n this._data = {};\n this.set(attr, options);\n this.initialize.apply(this, arguments);\n};\n\n_.extend(BaseModel.prototype, {\n initialize: function (attr, options) {},\n\n set: function (key, val, options) {\n if (key === null) {\n return this;\n }\n\n var attrs;\n if (typeof key === 'object') {\n attrs = key;\n options = val;\n } else {\n (attrs = {})[key] = val;\n }\n\n options = options || {};\n\n _.extend(this._data, attrs);\n\n return this;\n },\n\n get: function (key, options) {\n return this._data[key];\n },\n\n remove: function () {\n if (this.collection) {\n this.collection.remove(this);\n }\n\n return this;\n },\n\n toJSON: function () {\n return this._data;\n },\n\n pick: function (keys) {\n return _.pick(this._data, keys);\n }\n\n});\n\nmodule.exports = BaseModel;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar env = {\n account: '',\n project: '',\n group: '',\n groupId: '',\n token: '',\n server: {\n host: 'api.forio.com',\n protocol: 'https'\n }\n};\n\nmodule.exports = {\n set: function (options) {\n env = _.merge(env, options);\n },\n\n get: function () {\n return env;\n }\n};\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar classFrom = __webpack_require__(0);\nvar Base = __webpack_require__(2);\nvar serviceLocator = __webpack_require__(1);\n\nmodule.exports = classFrom(Base, {\n defaults: {\n world: '',\n role: '',\n active: true,\n isWorldComplete: true,\n firstName: '',\n lastName: ''\n },\n\n makeActive: function () {\n var memberApi = serviceLocator.memberApi();\n var params = {\n userId: this.get('id'),\n groupId: this.get('groupId')\n };\n\n var original = this.get('active');\n this.set('active', true);\n\n return memberApi.makeUserActive(params).fail(function () {\n // revert the change\n this.set('active', original);\n }.bind(this));\n },\n\n makeInactive: function () {\n var memberApi = serviceLocator.memberApi();\n var params = {\n userId: this.get('id'),\n groupId: this.get('groupId')\n };\n\n var original = this.get('active');\n this.set('active', false);\n\n return memberApi.makeUserInactive(params).fail(function () {\n // revert the change\n this.set('active', original);\n }.bind(this));\n }\n\n});\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar BaseCollection = function (models, options) {\n this._models = [];\n this.options = options;\n this.initialize.apply(this, arguments);\n};\n\n_.extend(BaseCollection.prototype, {\n idAttribute: 'id',\n\n initialize: function (models, options) {},\n\n create: function (attr, options) {\n var m = new this.model(attr, options);\n this.set(m);\n return m;\n },\n\n reset: function (models, options) {\n this._models.length = 0;\n this.set(models);\n },\n\n remove: function (model) {\n _.remove(this._models, function (m) {\n return m === model;\n });\n\n delete model.collection;\n\n return model;\n },\n\n set: function (models) {\n var _this = this;\n\n if (!models) {\n return;\n }\n\n models = [].concat(models);\n\n if (!models.length) {\n return;\n }\n\n models.forEach(function (m) {\n if (!(m instanceof _this.model)) {\n m = new _this.model(m);\n }\n m.collection = _this;\n _this._models.push(m);\n });\n\n this.sort();\n\n return models;\n },\n\n sortFn: function (a, b) {\n return b._data[this.idAttribute] - a._data[this.idAttribute];\n },\n\n sort: function () {\n this._models = this._models.sort(this.sortFn.bind(this));\n\n return this._models;\n },\n\n getById: function (id) {\n var _this2 = this;\n\n return _.find(this._models, function (m) {\n return m.get(_this2.idAttribute) === id;\n });\n },\n\n each: function (cb, ctx) {\n return _.each(this._models, cb, ctx || this);\n },\n\n all: function (cb, ctx) {\n return _.every(this._models, cb, ctx || this);\n },\n\n toJSON: function () {\n return _.invoke(this._models, 'toJSON');\n },\n\n find: function (fn) {\n return _.find(this._models, fn);\n },\n\n filter: function (fn) {\n return _.filter(this._models, fn);\n },\n\n size: function () {\n return this._models.length;\n },\n\n map: function (fn, ctx) {\n return _.map(this._models, function (model) {\n return fn.call(ctx, model.toJSON());\n });\n },\n\n pluck: function (field) {\n return this.map(function (m) {\n return m[field];\n });\n }\n\n});\n\nmodule.exports = BaseCollection;\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n(function () {\n var App = __webpack_require__(7);\n\n window.forio = window.forio || {};\n window.forio.MultiplayerAssignmentComponent = App;\n})();\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar UsersCollection = __webpack_require__(8);\nvar WorldsCollection = __webpack_require__(9);\nvar ProjectModel = __webpack_require__(11);\nvar AssignemntRow = __webpack_require__(12).default;\nvar env = __webpack_require__(3);\nvar AjaxQueue = __webpack_require__(13);\n\nfunction setEnvironment(options) {\n env.set(_.omit(options, 'el'));\n}\n\nvar Assignment = function (options) {\n setEnvironment(options);\n this.initialize(options);\n};\n\nAssignment.prototype = {\n\n initialize: function (options) {\n this.el = typeof options.el === 'string' ? $(options.el)[0] : options.el;\n this.$el = $(this.el);\n this.$ = _.partialRight($, this.el);\n\n this.users = new UsersCollection();\n this.worlds = new WorldsCollection();\n this.project = new ProjectModel();\n\n _.bindAll(this, ['render', 'renderTable', 'toggleControlls', 'saveEdit', 'selectAll', 'usassignSelected', '_showUpdating', '_hideUpdating', 'autoAssignAll', 'makeUserInactive']);\n\n this.bindEvents();\n },\n\n bindEvents: function () {\n this.$el.on('update', 'tr', this.saveEdit);\n this.$el.on('click', 'input:checkbox:not(#select-all)', this.toggleControlls);\n this.$el.on('click', '#select-all', this.selectAll);\n this.$el.on('click', '.unassign-user', this.usassignSelected);\n this.$el.on('click', '.auto-assign-all', this.autoAssignAll);\n this.$el.on('click', '.make-user-inactive', this.makeUserInactive);\n },\n\n load: function () {\n var join = function () {\n this.worlds.setUsersCollection(this.users);\n this.worlds.joinUsers();\n this.render();\n }.bind(this);\n\n return $.when(this.worlds.fetch(), this.users.fetch(), this.project.fetch()).then(join);\n },\n\n saveEdit: function () {\n this.worlds.fetch().then(function () {\n this.worlds.joinUsers();\n this.render();\n this.updateControls();\n }.bind(this));\n },\n\n autoAssignAll: function () {\n this._showUpdating();\n var maxUsers = +this.$('#max-users').val();\n return this.worlds.autoAssignAll({ maxUsers: maxUsers }).then(this._hideUpdating).fail(this._hideUpdating).then(function () {\n this.worlds.joinUsers();\n this.render();\n }.bind(this));\n },\n\n getSelectedIds: function () {\n return this.$('tbody :checkbox:checked').map(function () {\n return $(this).data('id');\n }).get();\n },\n\n findRowViews: function (ids) {\n var _this = this;\n\n return ids.map(function (id) {\n return _this.rowViews[id];\n });\n },\n\n unassignUsers: function (ids) {\n var _this2 = this;\n\n var dtd = $.Deferred();\n var done = function () {\n dtd.resolve();\n };\n\n // for now we need to sequence the calls to unassign users from worlds\n var queue = new AjaxQueue();\n\n ids.forEach(function (userId) {\n var user = _this2.users.getById(userId);\n user.set('world', '');\n user.set('role', '');\n queue.add(_.partial(_.bind(_this2.worlds.updateUser, _this2.worlds), user));\n });\n\n queue.execute(this).then(done);\n\n return dtd.promise();\n },\n\n usassignSelected: function (e) {\n e.preventDefault();\n\n var ids = this.getSelectedIds();\n\n var done = function () {\n this.worlds.fetch().then(function () {\n this.worlds.joinUsers();\n this._hideUpdating();\n this.render();\n }.bind(this));\n }.bind(this);\n\n this._showUpdating();\n\n return this.unassignUsers(ids).then(done);\n },\n\n makeUserInactive: function (e) {\n e.preventDefault();\n var ids = this.getSelectedIds();\n var done = function () {\n this.toggleControlls();\n }.bind(this);\n\n var makeUsersInactive = function () {\n var rows = this.findRowViews(ids);\n // for now we need to sequence the calls to patch the users\n // since the API can only operate on one call per group at a time\n var queue = new AjaxQueue();\n rows.forEach(function (view) {\n var user = view.model;\n queue.add(function () {\n return view.makeInactive().then(function () {\n user.remove();\n view.remove();\n });\n });\n });\n\n queue.execute(this).then(done);\n }.bind(this);\n\n return this.unassignUsers(ids).then(makeUsersInactive);\n },\n\n render: function () {\n this.$('table tbody').empty();\n this.sortTable();\n this.renderTable();\n this.toggleControlls();\n },\n\n sortTable: function () {\n // get the sort params and sort if necessary\n var params = this.getTableParams();\n\n var mult = params.hasOwnProperty('direction') && params.direction === 'desc' ? -1 : 1;\n var nameDirection = params.hasOwnProperty('sort') && params.sort === 'name' && mult > 0 ? 'desc' : 'asc';\n var userNameDirection = params.hasOwnProperty('sort') && params.sort === 'userName' && mult > 0 ? 'desc' : 'asc';\n this.$('table .header-name a').prop('href', '?sort=name&direction=' + nameDirection);\n this.$('table .header-username a').prop('href', '?sort=userName&direction=' + userNameDirection);\n\n if (params.hasOwnProperty('sort')) {\n this.users.sortFn = function (a, b) {\n var an = a.get(params.sort) || '';\n var bn = b.get(params.sort) || '';\n if (params.sort === 'name') {\n an = a.get('firstName') + a.get('lastName');\n bn = b.get('firstName') + b.get('lastName');\n }\n return mult * an.localeCompare(bn);\n };\n this.users.sort();\n\n var header = params.sort === 'name' ? this.$('table .header-name') : this.$('table .header-username');\n var arrowDir = mult > 0 ? 'caret-up' : 'caret-down';\n var arrow = this.$('');\n header.append(arrow);\n }\n },\n\n getTableParams: function () {\n var query = location.search !== '' ? location.search.substr(1).split('&') : [];\n var params = {};\n for (var i = 0; i < query.length; i++) {\n var q = query[i].split('=');\n params[q[0]] = q[1];\n }\n return params;\n },\n\n renderTable: function () {\n var _this3 = this;\n\n this.rowViews = {};\n var rows = [];\n this.users.each(function (u) {\n var view = new AssignemntRow({ model: u, worlds: _this3.worlds, project: _this3.project });\n _this3.rowViews[u.get('id')] = view;\n rows.push(view.render().el);\n });\n\n this.$('table tbody').append(rows);\n },\n\n updateControls: function () {\n this.updateControlsForSelection();\n this.updateAutoAssignButton();\n this.updateStatus();\n },\n\n updateStatus: function () {\n var incompleteWorlds = this.worlds.getIncompleteWorldsCount();\n var unassignedUsers = this.users.getUnassignedUsersCount();\n var totalWorlds = this.worlds.size();\n\n var usersText = 'All users have been assigned.';\n if (unassignedUsers) {\n usersText = unassignedUsers === 1 ? '1 user needs assignment.' : unassignedUsers + ' users need assignment.';\n }\n var worldsText = 'All worlds are complete.';\n if (!totalWorlds) {\n worldsText = 'No worlds have been created.';\n } else if (incompleteWorlds) {\n worldsText = incompleteWorlds === 1 ? '1 incomplete world needs attention.' : incompleteWorlds + ' incomplete worlds need attention.';\n }\n\n this.$('#users-status .text').text(usersText);\n this.$('#worlds-status .text').text(worldsText);\n\n if (unassignedUsers) {\n this.$('#users-status').addClass('incomplete');\n } else {\n this.$('#users-status').removeClass('incomplete');\n }\n\n if (incompleteWorlds || !totalWorlds) {\n this.$('#worlds-status').addClass('incomplete');\n } else {\n this.$('#worlds-status').removeClass('incomplete');\n }\n\n this.$('.status-widget').addClass('visible');\n },\n\n updateControlsForSelection: function () {\n var numSelected = this.$('tbody :checkbox:checked').length;\n this.$('.component.controls')[numSelected ? 'addClass' : 'removeClass']('visible');\n },\n\n updateAutoAssignButton: function () {\n\n if (this.project.isDynamicAssignment()) {\n var hasRoles = this.project.hasRoles();\n this.$('.table-controls .single').hide();\n this.$('.table-controls .dynamic').show();\n this.$('.table-controls .dynamic-no-roles-text')[hasRoles ? 'hide' : 'show']();\n this.$('.table-controls .no-roles')[hasRoles ? 'hide' : 'show']();\n } else {\n this.$('.table-controls .dynamic').hide();\n this.$('.table-controls .dynamic-no-roles-text').hide();\n this.$('.table-controls .single').show();\n this.$('.table-controls .no-roles').show();\n }\n\n if (this.users.allUsersAssigned()) {\n this.$('.table-controls').removeClass('visible');\n } else {\n this.$('.table-controls').addClass('visible');\n }\n },\n\n selectAll: function (e) {\n this.$('tbody :checkbox').prop('checked', e.target.checked);\n this.updateControls();\n },\n\n toggleControlls: function (e) {\n var total = this.$('tbody :checkbox');\n var checked = this.$('tbody :checkbox:checked');\n\n if (total.length === checked.length) {\n this.$('#select-all').attr('checked', 'checked');\n } else {\n this.$('#select-all').removeAttr('checked');\n }\n\n this.updateControls();\n },\n\n _showUpdating: function () {\n this.$el.css({ opacity: 0.4 });\n },\n\n _hideUpdating: function () {\n this.$el.css({ opacity: 1 });\n }\n\n};\n\nmodule.exports = Assignment;\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar classFrom = __webpack_require__(0);\n\nvar Model = __webpack_require__(4);\nvar Base = __webpack_require__(5);\nvar env = __webpack_require__(3);\nvar serviceLocator = __webpack_require__(1);\n\nmodule.exports = classFrom(Base, {\n model: Model,\n\n sortFn: function (a, b) {\n var aw = a.get('world').toLowerCase();\n var bw = b.get('world').toLowerCase();\n if (aw !== bw) {\n return aw < bw ? -1 : 1;\n }\n\n return b.get('userName') > a.get('userName') ? -1 : 1;\n },\n\n initialize: function () {\n var am = new F.manager.AuthManager();\n var session = am.getCurrentUserSessionInfo();\n var token = session.auth_token;\n if (token) {\n $.ajaxSetup({\n headers: {\n Authorization: 'Bearer ' + token\n }\n });\n }\n },\n\n allUsersAssigned: function () {\n return this.all(function (u) {\n return !!u.get('world');\n });\n },\n\n getUnassignedUsersCount: function () {\n return this.filter(function (u) {\n return !u.get('world');\n }).length;\n },\n\n fetch: function () {\n var dtd = $.Deferred();\n var me = this;\n var groupId = env.get().groupId;\n\n var getGroupUsers = function () {\n var memberApi = serviceLocator.memberApi();\n var userApi = serviceLocator.userApi();\n\n var loadGroupMembers = function () {\n return memberApi.getGroupDetails();\n };\n\n var splitIdChunks = function (userIds) {\n var idGroupSize = 100;\n var idGroups = [];\n while (userIds.length >= idGroupSize) {\n idGroups.push(userIds.splice(0, idGroupSize));\n }\n\n if (userIds.length) {\n idGroups.push(userIds);\n }\n\n return idGroups;\n };\n\n var loadUsersInfo = function (group) {\n var nonFacAndActive = function (u) {\n return u.active && u.role !== 'facilitator';\n };\n var endUsers = group.members.filter(function (m) {\n return nonFacAndActive(m);\n });\n var endUserIds = endUsers.map(function (u) {\n return u.userId;\n });\n var chunkedUsers = splitIdChunks(endUserIds);\n var chunkedPromises = chunkedUsers.map(function (users) {\n return userApi.get({ id: users });\n });\n return $.when.apply($, chunkedPromises).then(function (userGroups) {\n var totalUsers = userGroups.reduce(function (acc, userGroup) {\n return acc.concat(userGroup);\n }, []);\n\n return totalUsers;\n });\n };\n\n return loadGroupMembers().then(loadUsersInfo).fail(dtd.reject);\n };\n\n getGroupUsers().then(function (users) {\n users = users.map(function (u) {\n return $.extend(u, { groupId: groupId });\n });\n me.set(users);\n dtd.resolve(users);\n });\n\n return dtd.promise();\n }\n\n});\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar classFrom = __webpack_require__(0);\nvar Model = __webpack_require__(10);\nvar UserModel = __webpack_require__(4);\nvar serviceLocator = __webpack_require__(1);\n\nvar Base = __webpack_require__(5);\nvar __super = Base.prototype;\n\nvar doneFn = function (dtd, after) {\n return _.after(after, dtd.resolve);\n};\n\nvar worldApi;\n\nmodule.exports = classFrom(Base, {\n model: Model,\n\n initialize: function () {\n __super.initialize.apply(this, arguments);\n worldApi = serviceLocator.worldApi();\n },\n\n autoAssignAll: function (options) {\n return worldApi.autoAssign(options).then(function (worlds) {\n this.reset(this.parse(worlds));\n }.bind(this));\n },\n\n getIncompleteWorldsCount: function () {\n return this.filter(function (w) {\n return !w.get('complete');\n }).length;\n },\n\n updateUser: function (user) {\n var worldName = user.get('world');\n var dtd = $.Deferred();\n var prevWorld = this.getWorldByUser(user);\n var curWorld = this.getOrCreateWorld(worldName);\n var done = doneFn(dtd, 1);\n\n // check if there's anything to do\n if (!prevWorld && !curWorld) {\n return dtd.resolve().promise();\n }\n\n if (prevWorld && curWorld && prevWorld.get('id') === curWorld.get('id')) {\n //worlds are the same, but role changed\n return curWorld.updateUser(user);\n }\n if (prevWorld) {\n prevWorld.removeUser(user).then(function () {\n if (curWorld) {\n return curWorld.addUser(user);\n }\n }).then(done);\n } else if (curWorld) {\n curWorld.addUser(user).then(done);\n }\n\n return dtd.promise();\n },\n\n getOrCreateWorld: function (worldName) {\n if (!worldName) {\n return;\n }\n\n var world = this.getWordByName(worldName);\n\n if (!world) {\n world = this.create({ name: worldName });\n }\n\n return world;\n },\n\n getWordByName: function (worldName) {\n return this.find(function (world) {\n return world.get('name') === worldName;\n });\n },\n\n getWorldByUser: function (user) {\n if (!user.get) {\n throw new Error('getWorldByUser expectes a model (' + user + ')');\n }\n\n var id = user.get('id');\n return this.getWorldByUserId(id);\n },\n\n getWorldByUserId: function (userId) {\n return this.find(function (world) {\n return _.find(world.get('users'), function (u) {\n return u.get('id') === userId;\n });\n });\n },\n\n getWorldNames: function () {\n return this.pluck('name').sort();\n },\n\n getNextWorldName: function () {\n var pad = function (num, places) {\n var zeros = '000000000000000000';\n var digits = num.toString().length;\n var needed = places - digits;\n return zeros.substr(0, needed) + num;\n };\n\n var worlds = this.getWorldNames();\n\n if (!worlds.length) {\n return 'World001';\n }\n\n var properNames = _.filter(worlds, function (w) {\n return (/World\\d\\d\\d/.test(w)\n );\n }).sort();\n var lastWorld = properNames[properNames.length - 1];\n var numWorld = +lastWorld.match(/World(\\d\\d\\d)/)[1];\n var placesToPad = 3;\n return 'World' + pad(numWorld + 1, placesToPad);\n },\n\n setUsersCollection: function (usersCollection) {\n this.usersCollection = usersCollection;\n },\n\n joinUsers: function () {\n var usersHash = {};\n var usersCollection = this.usersCollection;\n usersCollection.each(function (u) {\n u.set({ isWorldComplete: true });\n return usersHash[u.get('id')] = u;\n });\n\n this.each(function (w, i) {\n var name = w.get('name');\n var isComplete = w.get('complete');\n w.set({ index: i, name: name || i + 1 + '' });\n _.each(w.get('users'), function (u) {\n if (usersHash[u.get('userId')]) {\n usersHash[u.get('userId')].set({ world: name, role: u.get('role'), isWorldComplete: isComplete });\n }\n });\n });\n\n usersCollection.sort();\n },\n\n fetch: function () {\n return worldApi.list().then(function (worlds) {\n this.reset(this.parse(worlds));\n }.bind(this));\n },\n\n parse: function (worlds) {\n if (worlds.length) {\n worlds = _.map(worlds, function (w) {\n var users = _.map(w.users, function (u) {\n // in the world api users Ids comes as userId\n // make sure we add it as id so we can use the\n // same code to access models that come from the\n // member/local api as with the world api\n u.id = u.userId;\n return new UserModel(u);\n });\n\n w.users = users;\n\n return w;\n });\n }\n\n return worlds;\n }\n});\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar serviceLocator = __webpack_require__(1);\nvar classFrom = __webpack_require__(0);\nvar Base = __webpack_require__(2);\nvar __super = Base.prototype;\n\nmodule.exports = classFrom(Base, {\n\n defaults: {\n users: null,\n model: 'model.eqn'\n },\n\n initialize: function () {\n __super.initialize.apply(this, arguments);\n\n this._data.users = this._data.users || [];\n\n this._worldApi = serviceLocator.worldApi();\n\n var id = this.get('id');\n if (id) {\n this._worldApi.updateConfig({ filter: id });\n }\n },\n\n updateUser: function (user) {\n if (!user) {\n throw new Error('updateUser: No user passed to update');\n }\n var userObj = user.toJSON();\n userObj.userId = userObj.id;\n return this._worldApi.updateUser(userObj, { id: this.get('id') });\n },\n\n addUser: function (user) {\n var users = this.get('users');\n users.push(user);\n\n return this.save();\n },\n\n removeUser: function (user) {\n var id = this.get('id');\n var checkWorld = function () {\n if (!this.get('users').length) {\n this.remove();\n return this._worldApi.updateConfig({ filter: id }).delete();\n }\n }.bind(this);\n\n _.remove(this.get('users'), function (u) {\n return u.get('id') === user.get('id');\n });\n\n return this._worldApi.updateConfig({ filter: id }).removeUser({ userId: user.get('id') }).then(checkWorld);\n },\n\n save: function () {\n var me = this;\n var mapUsers = function () {\n return _.map(this.get('users'), function (u) {\n var res = { userId: u.get('id') };\n var role = u.get('role');\n\n if (role) {\n res.role = role;\n }\n\n return res;\n });\n }.bind(this);\n\n var createWorld = _.partial(this._worldApi.create, this.pick(['model', 'name', 'minUsers']));\n var addUsers = _.partial(me._worldApi.addUsers, mapUsers(), { filter: me.get('id') });\n var savedUsers = this.get('users');\n if (this.isNew()) {\n // we need to create the world in the API and then add the users\n return createWorld().then(function (world) {\n me.set(world);\n me._worldApi.updateConfig({ filter: world.id });\n }).then(addUsers).then(function (users) {\n // since we re-set the world, re-set the users\n me.set('users', savedUsers);\n });\n } else {\n // the world is already created just add the users\n return addUsers();\n }\n },\n\n isNew: function () {\n return !this.get('lastModified');\n }\n\n});\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar serviceLocator = __webpack_require__(1);\n\nvar classFrom = __webpack_require__(0);\nvar Base = __webpack_require__(2);\n// var __super = Base.prototype;\n\nmodule.exports = classFrom(Base, {\n\n isDynamicAssignment: function () {\n return this.get('worlds') === 'dynamic';\n },\n\n hasRoles: function () {\n var roles = this.get('roles');\n return roles && !!roles.length;\n },\n\n fetch: function () {\n var api = serviceLocator.worldApi();\n\n return api.getProjectSettings().then(function (settings) {\n this.set(settings);\n }.bind(this));\n }\n});\n\n/***/ }),\n/* 12 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\nvar userRowTemplate = '\\n \"\\n <%= !isWorldComplete ? \\'\\' : \\'\\' %>\\n <%= world %>\\n <%= role %>\\n <%= lastName %>\\n <%= userName %>\\n <%= !world ? \\'\\' : \\'\\' %>\\n \\n'.trim();\nvar editUserRowTemplate = '\\n \"\\n \\n \\n \\n \\n \\n \\n \\n <%= lastName %>\\n <%= userName %>\\n <%= !world ? \\'\\' : \\'\\' %>\\n \\n \\n \\n \\n';\n\nvar AssignmentRow = function (options) {\n this.$el = $('');\n this.el = this.$el[0];\n this.$ = _.partialRight($, this.$el);\n\n this.model = options.model;\n this.options = options;\n this.worlds = options.worlds;\n this.project = options.project;\n\n _.bindAll(this, ['setEditMode', 'removeEditMode', 'saveEdit', 'cancelEdit', 'updateData']);\n\n this.bindEvents();\n};\n\n_.extend(AssignmentRow.prototype, {\n\n template: _.template(userRowTemplate),\n editTemplate: _.template(editUserRowTemplate),\n\n bindEvents: function () {\n this.$el.on('click', 'button.edit', this.setEditMode);\n this.$el.on('click', 'button.save', this.saveEdit);\n this.$el.on('click', 'button.cancel', this.cancelEdit);\n },\n\n remove: function () {\n this.$el.off('click', null, null);\n // this only gives a delay to remove the tr\n // animation of height of the tr does not work\n this.$(':checkbox').attr('checked', false);\n this.$el.css({ opacity: 0.3 }).animate({ height: 0 }, {\n duration: 300,\n complete: function () {\n this.remove();\n }\n });\n },\n\n makeInactive: function () {\n return this.model.makeInactive();\n },\n\n setEditMode: function () {\n this.model.set('edit-mode', true);\n this.render();\n },\n\n removeEditMode: function () {\n this.model.set('edit-mode', false);\n this.render();\n },\n\n saveEdit: function () {\n var me = this;\n this.updateData();\n this.worlds.updateUser(this.model).then(function () {\n me.removeEditMode();\n me.$el.trigger('update', me);\n });\n },\n\n cancelEdit: function () {\n this.removeEditMode();\n },\n\n render: function () {\n var templ = this.model.get('edit-mode') ? this.editTemplate : this.template;\n var vm = _.extend({\n roles: this.project.get('roles'),\n optionalRoles: this.project.get('optionalRoles'),\n worlds: this.worlds.getWorldNames(),\n newWorld: this.worlds.getNextWorldName()\n }, this.model.toJSON());\n\n this.$el.html(templ(vm));\n\n return this;\n },\n\n updateData: function () {\n var me = this;\n this.$('[data-field]').each(function () {\n var el = $(this);\n var field = el.data('field');\n var val = el.val();\n\n me.model.set(field, val);\n });\n }\n});\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (AssignmentRow);\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/**\n* Utility class to make ajax calls sequencial\n*/\n\nfunction AjaxQueue() {\n this.queue = [];\n}\n\n$.extend(AjaxQueue.prototype, {\n add: function (fn) {\n return this.queue.push(fn);\n },\n\n execute: function (context) {\n var dtd = $.Deferred();\n var me = this;\n context = context || this;\n\n function next() {\n if (me.queue.length) {\n var fn = me.queue.shift();\n\n fn.call(context).then(next).fail(dtd.reject);\n } else {\n dtd.resolve();\n }\n }\n\n next();\n\n return dtd.promise();\n }\n});\n\nmodule.exports = AjaxQueue;\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// assignment.min.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 6);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 5b36529e33521661d9bd","/**\n/* Inherit from a class (using prototype borrowing)\n*/\n'use strict';\n\nfunction inherit(C, P) {\n var F = function () {};\n F.prototype = P.prototype;\n C.prototype = new F();\n C.__super = P.prototype;\n C.prototype.constructor = C;\n}\n\n/**\n* Shallow copy of an object\n* @param {Object} dest object to extend\n* @return {Object} extended object\n*/\nvar extend = function (dest /*, var_args*/) {\n var obj = Array.prototype.slice.call(arguments, 1);\n var current;\n for (var j = 0; j < obj.length; j++) {\n if (!(current = obj[j])) { //eslint-disable-line\n continue;\n }\n\n // do not wrap inner in dest.hasOwnProperty or bad things will happen\n for (var key in current) { //eslint-disable-line\n dest[key] = current[key];\n }\n }\n\n return dest;\n};\n\nmodule.exports = function (base, props, staticProps) {\n var parent = base;\n var child;\n\n child = props && props.hasOwnProperty('constructor') ? props.constructor : function () { return parent.apply(this, arguments); };\n\n // add static properties to the child constructor function\n extend(child, parent, staticProps);\n\n // associate prototype chain\n inherit(child, parent);\n\n // add instance properties\n if (props) {\n extend(child.prototype, props);\n }\n\n // done\n return child;\n};\n\n\n\n// WEBPACK FOOTER //\n// ./src/util/inherit.js","'use strict';\n\nvar env = require('./defaults.js');\n\nvar cache = {};\n\nmodule.exports = {\n worldApi: function () {\n if (!cache.worldApi) {\n cache.worldApi = new F.service.World(env.get());\n }\n return cache.worldApi;\n },\n\n memberApi: function () {\n if (!cache.memberApi) {\n cache.memberApi = new F.service.Member(_.pick(env.get(), ['groupId', 'server']));\n }\n\n return cache.memberApi;\n },\n\n userApi: function () {\n if (!cache.userApi) {\n cache.userApi = new F.service.User(_.pick(env.get(), ['account', 'server']));\n }\n\n return cache.userApi;\n }\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/service-locator.js","'use strict';\n\n\nvar BaseModel = function (attr, options) {\n attr = _.defaults({}, attr, _.result(this, 'defaults'));\n this._data = {};\n this.set(attr, options);\n this.initialize.apply(this, arguments);\n};\n\n_.extend(BaseModel.prototype, {\n initialize: function (attr, options) {\n\n },\n\n set: function (key, val, options) {\n if (key === null) {\n return this;\n }\n\n var attrs;\n if (typeof key === 'object') {\n attrs = key;\n options = val;\n } else {\n (attrs = {})[key] = val;\n }\n\n options = options || {};\n\n _.extend(this._data, attrs);\n\n return this;\n },\n\n get: function (key, options) {\n return this._data[key];\n },\n\n remove: function () {\n if (this.collection) {\n this.collection.remove(this);\n }\n\n return this;\n },\n\n toJSON: function () {\n return this._data;\n },\n\n pick: function (keys) {\n return _.pick(this._data, keys);\n }\n\n});\n\nmodule.exports = BaseModel;\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/base-model.js","'use strict';\n\nvar env = {\n account: '',\n project: '',\n group: '',\n groupId: '',\n token: '',\n server: {\n host: 'api.forio.com',\n protocol: 'https'\n }\n};\n\nmodule.exports = {\n set: function (options) {\n env = _.merge(env, options);\n },\n\n get: function () {\n return env;\n }\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/defaults.js","'use strict';\n\nvar classFrom = require('../../../util/inherit');\nvar Base = require('./base-model');\nvar serviceLocator = require('./service-locator');\n\n\nmodule.exports = classFrom(Base, {\n defaults: {\n world: '',\n role: '',\n active: true,\n isWorldComplete: true,\n firstName: '',\n lastName: ''\n },\n\n makeActive: function () {\n var memberApi = serviceLocator.memberApi();\n var params = {\n userId: this.get('id'),\n groupId: this.get('groupId')\n };\n\n var original = this.get('active');\n this.set('active', true);\n\n return memberApi.makeUserActive(params)\n .fail(function () {\n // revert the change\n this.set('active', original);\n }.bind(this));\n },\n\n makeInactive: function () {\n var memberApi = serviceLocator.memberApi();\n var params = {\n userId: this.get('id'),\n groupId: this.get('groupId')\n };\n\n var original = this.get('active');\n this.set('active', false);\n\n return memberApi.makeUserInactive(params)\n .fail(function () {\n // revert the change\n this.set('active', original);\n }.bind(this));\n }\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/user-model.js","'use strict';\n\nvar BaseCollection = function (models, options) {\n this._models = [];\n this.options = options;\n this.initialize.apply(this, arguments);\n};\n\n_.extend(BaseCollection.prototype, {\n idAttribute: 'id',\n\n initialize: function (models, options) {\n },\n\n create: function (attr, options) {\n var m = new this.model(attr, options);\n this.set(m);\n return m;\n },\n\n reset: function (models, options) {\n this._models.length = 0;\n this.set(models);\n },\n\n remove: function (model) {\n _.remove(this._models, function (m) {\n return m === model;\n });\n\n delete model.collection;\n\n return model;\n },\n\n set: function (models) {\n if (!models) {\n return;\n }\n\n models = [].concat(models);\n\n if (!models.length) {\n return;\n }\n\n models.forEach((m)=> {\n if (!(m instanceof this.model)) {\n m = new this.model(m);\n }\n m.collection = this;\n this._models.push(m);\n });\n\n this.sort();\n\n return models;\n },\n\n sortFn: function (a, b) {\n return b._data[this.idAttribute] - a._data[this.idAttribute];\n },\n\n sort: function () {\n this._models = this._models.sort(this.sortFn.bind(this));\n\n return this._models;\n },\n\n getById: function (id) {\n return _.find(this._models, (m)=> {\n return m.get(this.idAttribute) === id;\n });\n },\n\n each: function (cb, ctx) {\n return _.each(this._models, cb, ctx || this);\n },\n\n all: function (cb, ctx) {\n return _.every(this._models, cb, ctx || this);\n },\n\n toJSON: function () {\n return _.invoke(this._models, 'toJSON');\n },\n\n find: function (fn) {\n return _.find(this._models, fn);\n },\n\n filter: function (fn) {\n return _.filter(this._models, fn);\n },\n\n size: function () {\n return this._models.length;\n },\n\n map: function (fn, ctx) {\n return _.map(this._models, function (model) {\n return fn.call(ctx, model.toJSON());\n });\n },\n\n pluck: function (field) {\n return this.map(function (m) {\n return m[field];\n });\n }\n\n});\n\nmodule.exports = BaseCollection;\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/base-collection.js","(function () {\n var App = require('./assignment.js');\n\n window.forio = window.forio || {};\n window.forio.MultiplayerAssignmentComponent = App;\n}());\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/index.js","'use strict';\n\nvar UsersCollection = require('./users-collection');\nvar WorldsCollection = require('./worlds-collection');\nvar ProjectModel = require('./project-model');\nvar AssignemntRow = require('./assignment-row').default;\nvar env = require('./defaults');\nvar AjaxQueue = require('../../../util/ajax-queue');\n\nfunction setEnvironment(options) {\n env.set(_.omit(options, 'el'));\n}\n\nvar Assignment = function (options) {\n setEnvironment(options);\n this.initialize(options);\n};\n\nAssignment.prototype = {\n\n initialize: function (options) {\n this.el = typeof options.el === 'string' ? $(options.el)[0] : options.el;\n this.$el = $(this.el);\n this.$ = _.partialRight($, this.el);\n\n this.users = new UsersCollection();\n this.worlds = new WorldsCollection();\n this.project = new ProjectModel();\n\n _.bindAll(this, ['render', 'renderTable', 'toggleControlls', 'saveEdit', 'selectAll', 'usassignSelected', '_showUpdating', '_hideUpdating', 'autoAssignAll', 'makeUserInactive']);\n\n this.bindEvents();\n },\n\n bindEvents: function () {\n this.$el.on('update', 'tr', this.saveEdit);\n this.$el.on('click', 'input:checkbox:not(#select-all)', this.toggleControlls);\n this.$el.on('click', '#select-all', this.selectAll);\n this.$el.on('click', '.unassign-user', this.usassignSelected);\n this.$el.on('click', '.auto-assign-all', this.autoAssignAll);\n this.$el.on('click', '.make-user-inactive', this.makeUserInactive);\n },\n\n load: function () {\n var join = function () {\n this.worlds.setUsersCollection(this.users);\n this.worlds.joinUsers();\n this.render();\n }.bind(this);\n\n return $.when(\n this.worlds.fetch(),\n this.users.fetch(),\n this.project.fetch()\n ).then(join);\n },\n\n saveEdit: function () {\n this.worlds.fetch()\n .then(function () {\n this.worlds.joinUsers();\n this.render();\n this.updateControls();\n }.bind(this));\n },\n\n autoAssignAll: function () {\n this._showUpdating();\n var maxUsers = +this.$('#max-users').val();\n return this.worlds.autoAssignAll({ maxUsers: maxUsers })\n .then(this._hideUpdating)\n .fail(this._hideUpdating)\n .then(function () {\n this.worlds.joinUsers();\n this.render();\n }.bind(this));\n },\n\n getSelectedIds: function () {\n return this.$('tbody :checkbox:checked').map(function () {\n return $(this).data('id');\n }).get();\n },\n\n findRowViews: function (ids) {\n return ids.map((id)=> {\n return this.rowViews[id];\n });\n },\n\n unassignUsers: function (ids) {\n var dtd = $.Deferred();\n var done = function () {\n dtd.resolve();\n };\n\n // for now we need to sequence the calls to unassign users from worlds\n var queue = new AjaxQueue();\n\n ids.forEach((userId)=> {\n var user = this.users.getById(userId);\n user.set('world', '');\n user.set('role', '');\n queue.add(_.partial(_.bind(this.worlds.updateUser, this.worlds), user));\n });\n\n queue.execute(this).then(done);\n\n return dtd.promise();\n },\n\n usassignSelected: function (e) {\n e.preventDefault();\n\n var ids = this.getSelectedIds();\n\n var done = function () {\n this.worlds.fetch().then(function () {\n this.worlds.joinUsers();\n this._hideUpdating();\n this.render();\n\n }.bind(this));\n }.bind(this);\n\n this._showUpdating();\n\n return this.unassignUsers(ids).then(done);\n },\n\n makeUserInactive: function (e) {\n e.preventDefault();\n var ids = this.getSelectedIds();\n var done = function () {\n this.toggleControlls();\n }.bind(this);\n\n var makeUsersInactive = function () {\n var rows = this.findRowViews(ids);\n // for now we need to sequence the calls to patch the users\n // since the API can only operate on one call per group at a time\n var queue = new AjaxQueue();\n rows.forEach((view)=> {\n var user = view.model;\n queue.add(function () {\n return view.makeInactive()\n .then(function () {\n user.remove();\n view.remove();\n });\n });\n\n });\n\n queue.execute(this).then(done);\n }.bind(this);\n\n return this.unassignUsers(ids)\n .then(makeUsersInactive);\n\n\n },\n\n render: function () {\n this.$('table tbody').empty();\n this.sortTable();\n this.renderTable();\n this.toggleControlls();\n },\n\n sortTable: function () {\n // get the sort params and sort if necessary\n var params = this.getTableParams();\n\n var mult = params.hasOwnProperty('direction') && params.direction === 'desc' ? -1 : 1;\n var nameDirection = params.hasOwnProperty('sort') && params.sort === 'name' && mult > 0 ? 'desc' : 'asc';\n var userNameDirection = params.hasOwnProperty('sort') && params.sort === 'userName' && mult > 0 ? 'desc' : 'asc';\n this.$('table .header-name a').prop('href', '?sort=name&direction=' + nameDirection);\n this.$('table .header-username a').prop('href', '?sort=userName&direction=' + userNameDirection);\n\n if (params.hasOwnProperty('sort')) {\n this.users.sortFn = function (a, b) {\n var an = (a.get(params.sort) || '');\n var bn = (b.get(params.sort) || '');\n if (params.sort === 'name') {\n an = (a.get('firstName') + a.get('lastName'));\n bn = (b.get('firstName') + b.get('lastName'));\n }\n return mult * an.localeCompare(bn);\n };\n this.users.sort();\n\n var header = params.sort === 'name' ? this.$('table .header-name') : this.$('table .header-username');\n var arrowDir = mult > 0 ? 'caret-up' : 'caret-down';\n var arrow = this.$('');\n header.append(arrow);\n }\n },\n\n getTableParams: function () {\n var query = location.search !== '' ? location.search.substr(1).split('&') : [];\n var params = {};\n for (var i = 0; i < query.length; i++) {\n var q = query[i].split('=');\n params[q[0]] = q[1];\n }\n return params;\n },\n\n renderTable: function () {\n this.rowViews = {};\n var rows = [];\n this.users.each((u)=> {\n var view = new AssignemntRow({ model: u, worlds: this.worlds, project: this.project });\n this.rowViews[u.get('id')] = view;\n rows.push(view.render().el);\n });\n\n this.$('table tbody').append(rows);\n },\n\n\n updateControls: function () {\n this.updateControlsForSelection();\n this.updateAutoAssignButton();\n this.updateStatus();\n },\n\n updateStatus: function () {\n var incompleteWorlds = this.worlds.getIncompleteWorldsCount();\n var unassignedUsers = this.users.getUnassignedUsersCount();\n var totalWorlds = this.worlds.size();\n\n var usersText = 'All users have been assigned.';\n if (unassignedUsers) {\n usersText = unassignedUsers === 1 ? '1 user needs assignment.' : unassignedUsers + ' users need assignment.';\n }\n var worldsText = 'All worlds are complete.';\n if (!totalWorlds) {\n worldsText = 'No worlds have been created.';\n } else if (incompleteWorlds) {\n worldsText = incompleteWorlds === 1 ? '1 incomplete world needs attention.' : incompleteWorlds + ' incomplete worlds need attention.';\n }\n\n this.$('#users-status .text').text(usersText);\n this.$('#worlds-status .text').text(worldsText);\n\n if (unassignedUsers) {\n this.$('#users-status').addClass('incomplete');\n } else {\n this.$('#users-status').removeClass('incomplete');\n }\n\n if (incompleteWorlds || !totalWorlds) {\n this.$('#worlds-status').addClass('incomplete');\n } else {\n this.$('#worlds-status').removeClass('incomplete');\n }\n\n this.$('.status-widget').addClass('visible');\n },\n\n updateControlsForSelection: function () {\n var numSelected = this.$('tbody :checkbox:checked').length;\n this.$('.component.controls')[numSelected ? 'addClass' : 'removeClass']('visible');\n },\n\n updateAutoAssignButton: function () {\n\n if (this.project.isDynamicAssignment()) {\n var hasRoles = this.project.hasRoles();\n this.$('.table-controls .single').hide();\n this.$('.table-controls .dynamic').show();\n this.$('.table-controls .dynamic-no-roles-text')[hasRoles ? 'hide' : 'show']();\n this.$('.table-controls .no-roles')[hasRoles ? 'hide' : 'show']();\n } else {\n this.$('.table-controls .dynamic').hide();\n this.$('.table-controls .dynamic-no-roles-text').hide();\n this.$('.table-controls .single').show();\n this.$('.table-controls .no-roles').show();\n\n }\n\n if (this.users.allUsersAssigned()) {\n this.$('.table-controls').removeClass('visible');\n } else {\n this.$('.table-controls').addClass('visible');\n }\n },\n\n selectAll: function (e) {\n this.$('tbody :checkbox').prop('checked', e.target.checked);\n this.updateControls();\n },\n\n toggleControlls: function (e) {\n var total = this.$('tbody :checkbox');\n var checked = this.$('tbody :checkbox:checked');\n\n if (total.length === checked.length) {\n this.$('#select-all').attr('checked', 'checked');\n } else {\n this.$('#select-all').removeAttr('checked');\n }\n\n this.updateControls();\n },\n\n _showUpdating: function () {\n this.$el.css({ opacity: 0.4 });\n },\n\n _hideUpdating: function () {\n this.$el.css({ opacity: 1 });\n }\n\n};\n\nmodule.exports = Assignment;\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/assignment.js","'use strict';\n\nvar classFrom = require('../../../util/inherit');\n\nvar Model = require('./user-model');\nvar Base = require('./base-collection');\nvar env = require('./defaults');\nvar serviceLocator = require('./service-locator');\n\n\nmodule.exports = classFrom(Base, {\n model: Model,\n\n sortFn: function (a, b) {\n var aw = a.get('world').toLowerCase();\n var bw = b.get('world').toLowerCase();\n if (aw !== bw) {\n return aw < bw ? -1 : 1;\n }\n\n return b.get('userName') > a.get('userName') ? -1 : 1;\n },\n\n initialize: function () {\n const am = new F.manager.AuthManager();\n const session = am.getCurrentUserSessionInfo();\n const token = session.auth_token;\n if (token) {\n $.ajaxSetup({\n headers: {\n Authorization: 'Bearer ' + token\n }\n });\n }\n },\n\n allUsersAssigned: function () {\n return this.all(function (u) {\n return !!u.get('world');\n });\n },\n\n getUnassignedUsersCount: function () {\n return this.filter(function (u) {\n return !u.get('world');\n }).length;\n },\n\n fetch: function () {\n var dtd = $.Deferred();\n var me = this;\n var groupId = env.get().groupId;\n\n var getGroupUsers = function () {\n var memberApi = serviceLocator.memberApi();\n var userApi = serviceLocator.userApi();\n\n var loadGroupMembers = function () {\n return memberApi.getGroupDetails();\n };\n\n var splitIdChunks = function (userIds) {\n var idGroupSize = 100;\n var idGroups = [];\n while (userIds.length >= idGroupSize) {\n idGroups.push(userIds.splice(0, idGroupSize));\n }\n\n if (userIds.length) {\n idGroups.push(userIds);\n }\n\n return idGroups;\n };\n\n var loadUsersInfo = function (group) {\n var nonFacAndActive = function (u) { return u.active && u.role !== 'facilitator'; };\n const endUsers = group.members.filter((m)=> nonFacAndActive(m));\n const endUserIds = endUsers.map((u)=> u.userId);\n var chunkedUsers = splitIdChunks(endUserIds);\n var chunkedPromises = chunkedUsers.map(function (users) {\n return userApi.get({ id: users });\n });\n return $.when.apply($, chunkedPromises).then(function (userGroups) {\n var totalUsers = userGroups.reduce(function (acc, userGroup) {\n return acc.concat(userGroup);\n }, []);\n\n return totalUsers;\n });\n };\n\n return loadGroupMembers()\n .then(loadUsersInfo)\n .fail(dtd.reject);\n };\n\n getGroupUsers()\n .then(function (users) {\n users = users.map(function (u) { return $.extend(u, { groupId: groupId }); });\n me.set(users);\n dtd.resolve(users);\n });\n\n return dtd.promise();\n }\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/users-collection.js","'use strict';\n\nvar classFrom = require('../../../util/inherit');\nvar Model = require('./world-model');\nvar UserModel = require('./user-model');\nvar serviceLocator = require('./service-locator');\n\nvar Base = require('./base-collection');\nvar __super = Base.prototype;\n\nvar doneFn = function (dtd, after) {\n return _.after(after, dtd.resolve);\n};\n\nvar worldApi;\n\nmodule.exports = classFrom(Base, {\n model: Model,\n\n initialize: function () {\n __super.initialize.apply(this, arguments);\n worldApi = serviceLocator.worldApi();\n },\n\n autoAssignAll: function (options) {\n return worldApi.autoAssign(options)\n .then(function (worlds) {\n this.reset(this.parse(worlds));\n }.bind(this));\n },\n\n getIncompleteWorldsCount: function () {\n return this.filter(function (w) {\n return !w.get('complete');\n }).length;\n },\n\n updateUser: function (user) {\n var worldName = user.get('world');\n var dtd = $.Deferred();\n var prevWorld = this.getWorldByUser(user);\n var curWorld = this.getOrCreateWorld(worldName);\n var done = doneFn(dtd, 1);\n\n // check if there's anything to do\n if (!prevWorld && !curWorld) {\n return dtd.resolve().promise();\n }\n\n if (prevWorld && curWorld && prevWorld.get('id') === curWorld.get('id')) {\n //worlds are the same, but role changed\n return curWorld.updateUser(user);\n }\n if (prevWorld) {\n prevWorld.removeUser(user)\n .then(function () {\n if (curWorld) {\n return curWorld.addUser(user);\n }\n })\n .then(done);\n } else if (curWorld) {\n curWorld.addUser(user)\n .then(done);\n }\n\n return dtd.promise();\n },\n\n getOrCreateWorld: function (worldName) {\n if (!worldName) {\n return;\n }\n\n var world = this.getWordByName(worldName);\n\n if (!world) {\n world = this.create({ name: worldName });\n }\n\n return world;\n },\n\n getWordByName: function (worldName) {\n return this.find(function (world) {\n return world.get('name') === worldName;\n });\n },\n\n getWorldByUser: function (user) {\n if (!user.get) {\n throw new Error('getWorldByUser expectes a model (' + user + ')');\n }\n\n var id = user.get('id');\n return this.getWorldByUserId(id);\n },\n\n getWorldByUserId: function (userId) {\n return this.find(function (world) {\n return _.find(world.get('users'), function (u) {\n return u.get('id') === userId;\n });\n });\n },\n\n getWorldNames: function () {\n return this.pluck('name').sort();\n },\n\n getNextWorldName: function () {\n var pad = function (num, places) {\n var zeros = '000000000000000000';\n var digits = num.toString().length;\n var needed = places - digits;\n return zeros.substr(0, needed) + num;\n };\n\n var worlds = this.getWorldNames();\n\n if (!worlds.length) {\n return 'World001';\n }\n\n var properNames = _.filter(worlds, function (w) { return (/World\\d\\d\\d/).test(w); }).sort();\n var lastWorld = properNames[properNames.length - 1];\n var numWorld = +lastWorld.match(/World(\\d\\d\\d)/)[1];\n var placesToPad = 3;\n return 'World' + pad(numWorld + 1, placesToPad);\n },\n\n setUsersCollection: function (usersCollection) {\n this.usersCollection = usersCollection;\n },\n\n joinUsers: function () {\n var usersHash = {};\n var usersCollection = this.usersCollection;\n usersCollection.each(function (u) {\n u.set({ isWorldComplete: true });\n return (usersHash[u.get('id')] = u);\n });\n\n this.each((w, i)=> {\n var name = w.get('name');\n var isComplete = w.get('complete');\n w.set({ index: i, name: name || (i + 1) + '' });\n _.each(w.get('users'), function (u) {\n if (usersHash[u.get('userId')]) {\n usersHash[u.get('userId')].set({ world: name, role: u.get('role'), isWorldComplete: isComplete });\n }\n });\n });\n\n usersCollection.sort();\n },\n\n fetch: function () {\n return worldApi.list()\n .then(function (worlds) {\n this.reset(this.parse(worlds));\n }.bind(this));\n },\n\n parse: function (worlds) {\n if (worlds.length) {\n worlds = _.map(worlds, function (w) {\n var users = _.map(w.users, function (u) {\n // in the world api users Ids comes as userId\n // make sure we add it as id so we can use the\n // same code to access models that come from the\n // member/local api as with the world api\n u.id = u.userId;\n return new UserModel(u);\n });\n\n w.users = users;\n\n return w;\n });\n }\n\n return worlds;\n }\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/worlds-collection.js","'use strict';\nvar serviceLocator = require('./service-locator');\nvar classFrom = require('../../../util/inherit');\nvar Base = require('./base-model');\nvar __super = Base.prototype;\n\nmodule.exports = classFrom(Base, {\n\n defaults: {\n users: null,\n model: 'model.eqn'\n },\n\n initialize: function () {\n __super.initialize.apply(this, arguments);\n\n this._data.users = this._data.users || [];\n\n this._worldApi = serviceLocator.worldApi();\n\n var id = this.get('id');\n if (id) {\n this._worldApi.updateConfig({ filter: id });\n }\n },\n\n updateUser: function (user) {\n if (!user) {\n throw new Error('updateUser: No user passed to update');\n }\n const userObj = user.toJSON();\n userObj.userId = userObj.id;\n return this._worldApi.updateUser(userObj, { id: this.get('id') });\n },\n\n addUser: function (user) {\n var users = this.get('users');\n users.push(user);\n\n return this.save();\n },\n\n removeUser: function (user) {\n var id = this.get('id');\n var checkWorld = function () {\n if (!this.get('users').length) {\n this.remove();\n return this._worldApi.updateConfig({ filter: id }).delete();\n }\n }.bind(this);\n\n _.remove(this.get('users'), function (u) {\n return u.get('id') === user.get('id');\n });\n\n return this._worldApi\n .updateConfig({ filter: id })\n .removeUser({ userId: user.get('id') })\n .then(checkWorld);\n },\n\n save: function () {\n var me = this;\n var mapUsers = function () {\n return _.map(this.get('users'), function (u) {\n var res = { userId: u.get('id') };\n var role = u.get('role');\n\n if (role) {\n res.role = role;\n }\n\n return res;\n });\n }.bind(this);\n\n var createWorld = _.partial(this._worldApi.create, this.pick(['model', 'name', 'minUsers']));\n var addUsers = _.partial(me._worldApi.addUsers, mapUsers(), { filter: me.get('id') });\n var savedUsers = this.get('users');\n if (this.isNew()) {\n // we need to create the world in the API and then add the users\n return createWorld()\n .then(function (world) {\n me.set(world);\n me._worldApi.updateConfig({ filter: world.id });\n })\n .then(addUsers)\n .then(function (users) {\n // since we re-set the world, re-set the users\n me.set('users', savedUsers);\n });\n } else {\n // the world is already created just add the users\n return addUsers();\n }\n },\n\n isNew: function () {\n return !this.get('lastModified');\n }\n\n});\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/world-model.js","'use strict';\n\nvar serviceLocator = require('./service-locator');\n\nvar classFrom = require('../../../util/inherit');\nvar Base = require('./base-model');\n// var __super = Base.prototype;\n\nmodule.exports = classFrom(Base, {\n\n isDynamicAssignment: function () {\n return this.get('worlds') === 'dynamic';\n },\n\n hasRoles: function () {\n var roles = this.get('roles');\n return roles && !!roles.length;\n },\n\n fetch: function () {\n var api = serviceLocator.worldApi();\n\n return api.getProjectSettings().then(function (settings) {\n this.set(settings);\n }.bind(this));\n }\n});\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/project-model.js","const userRowTemplate = `\n \"\n <%= !isWorldComplete ? '' : '' %>\n <%= world %>\n <%= role %>\n <%= lastName %>\n <%= userName %>\n <%= !world ? '' : '' %>\n \n`.trim();\nconst editUserRowTemplate = `\n \"\n \n \n \n \n \n \n \n <%= lastName %>\n <%= userName %>\n <%= !world ? '' : '' %>\n \n \n \n \n`;\n\nvar AssignmentRow = function (options) {\n this.$el = $('');\n this.el = this.$el[0];\n this.$ = _.partialRight($, this.$el);\n\n this.model = options.model;\n this.options = options;\n this.worlds = options.worlds;\n this.project = options.project;\n\n _.bindAll(this, ['setEditMode', 'removeEditMode', 'saveEdit', 'cancelEdit', 'updateData']);\n\n this.bindEvents();\n\n};\n\n_.extend(AssignmentRow.prototype, {\n\n template: _.template(userRowTemplate),\n editTemplate: _.template(editUserRowTemplate),\n\n bindEvents: function () {\n this.$el.on('click', 'button.edit', this.setEditMode);\n this.$el.on('click', 'button.save', this.saveEdit);\n this.$el.on('click', 'button.cancel', this.cancelEdit);\n },\n\n remove: function () {\n this.$el.off('click', null, null);\n // this only gives a delay to remove the tr\n // animation of height of the tr does not work\n this.$(':checkbox').attr('checked', false);\n this.$el\n .css({ opacity: 0.3 })\n .animate({ height: 0 }, {\n duration: 300,\n complete: function () {\n this.remove();\n }\n });\n },\n\n makeInactive: function () {\n return this.model.makeInactive();\n },\n\n setEditMode: function () {\n this.model.set('edit-mode', true);\n this.render();\n },\n\n removeEditMode: function () {\n this.model.set('edit-mode', false);\n this.render();\n },\n\n saveEdit: function () {\n var me = this;\n this.updateData();\n this.worlds\n .updateUser(this.model)\n .then(function () {\n me.removeEditMode();\n me.$el.trigger('update', me);\n });\n },\n\n cancelEdit: function () {\n this.removeEditMode();\n },\n\n render: function () {\n var templ = this.model.get('edit-mode') ? this.editTemplate : this.template;\n var vm = _.extend({\n roles: this.project.get('roles'),\n optionalRoles: this.project.get('optionalRoles'),\n worlds: this.worlds.getWorldNames(),\n newWorld: this.worlds.getNextWorldName()\n }, this.model.toJSON());\n\n this.$el.html(templ(vm));\n\n return this;\n },\n\n updateData: function () {\n var me = this;\n this.$('[data-field]').each(function () {\n var el = $(this);\n var field = el.data('field');\n var val = el.val();\n\n me.model.set(field, val);\n });\n }\n});\n\n\nexport default AssignmentRow;\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/assignment-row.js","'use strict';\n\n/**\n* Utility class to make ajax calls sequencial\n*/\nfunction AjaxQueue() {\n this.queue = [];\n}\n\n$.extend(AjaxQueue.prototype, {\n add: function (fn) {\n return this.queue.push(fn);\n },\n\n execute: function (context) {\n var dtd = $.Deferred();\n var me = this;\n context = context || this;\n\n function next() {\n if (me.queue.length) {\n var fn = me.queue.shift();\n\n fn.call(context)\n .then(next)\n .fail(dtd.reject);\n } else {\n dtd.resolve();\n }\n }\n\n next();\n\n return dtd.promise();\n }\n});\n\n\nmodule.exports = AjaxQueue;\n\n\n// WEBPACK FOOTER //\n// ./src/util/ajax-queue.js"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///assignment.min.js","webpack:///webpack/bootstrap e43f576d3dda2a1c6a33","webpack:///./src/util/inherit.js","webpack:///./src/components/assignment/js/service-locator.js","webpack:///./src/components/assignment/js/base-model.js","webpack:///./src/components/assignment/js/defaults.js","webpack:///./src/components/assignment/js/user-model.js","webpack:///./src/components/assignment/js/base-collection.js","webpack:///./src/components/assignment/js/index.js","webpack:///./src/components/assignment/js/assignment.js","webpack:///./src/components/assignment/js/users-collection.js","webpack:///./src/components/assignment/js/worlds-collection.js","webpack:///./src/components/assignment/js/world-model.js","webpack:///./src/components/assignment/js/project-model.js","webpack:///./src/components/assignment/js/assignment-row.js","webpack:///./src/util/ajax-queue.js"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","i","l","call","m","c","d","name","getter","o","Object","defineProperty","configurable","enumerable","get","n","__esModule","object","property","prototype","hasOwnProperty","p","s","inherit","C","P","F","__super","constructor","extend","dest","obj","Array","slice","arguments","current","j","length","key","base","props","staticProps","parent","child","apply","this","env","require","cache","worldApi","service","World","memberApi","Member","_","pick","userApi","User","BaseModel","attr","options","defaults","result","_data","set","initialize","val","attrs","remove","collection","toJSON","keys","account","project","group","groupId","token","server","host","protocol","merge","classFrom","Base","serviceLocator","world","role","active","isWorldComplete","firstName","lastName","makeActive","params","userId","original","makeUserActive","fail","bind","makeInactive","makeUserInactive","BaseCollection","models","_models","idAttribute","create","model","reset","concat","forEach","push","sort","sortFn","a","b","getById","id","find","each","cb","ctx","all","every","invoke","fn","filter","size","map","pluck","field","App","window","forio","MultiplayerAssignmentComponent","setEnvironment","omit","UsersCollection","WorldsCollection","ProjectModel","AssignemntRow","default","AjaxQueue","Assignment","el","$","$el","partialRight","users","worlds","bindAll","bindEvents","on","saveEdit","toggleControlls","selectAll","usassignSelected","autoAssignAll","load","join","setUsersCollection","joinUsers","render","when","fetch","then","updateControls","_showUpdating","maxUsers","_hideUpdating","getSelectedIds","data","findRowViews","ids","rowViews","unassignUsers","dtd","Deferred","done","resolve","queue","user","add","partial","updateUser","execute","promise","e","preventDefault","makeUsersInactive","rows","view","empty","sortTable","renderTable","getTableParams","mult","direction","nameDirection","userNameDirection","prop","an","bn","localeCompare","header","arrowDir","arrow","append","query","location","search","substr","split","q","u","updateControlsForSelection","updateAutoAssignButton","updateStatus","incompleteWorlds","getIncompleteWorldsCount","unassignedUsers","getUnassignedUsersCount","totalWorlds","usersText","worldsText","text","addClass","removeClass","numSelected","isDynamicAssignment","hasRoles","hide","show","allUsersAssigned","target","checked","total","removeAttr","css","opacity","Model","aw","toLowerCase","bw","am","manager","AuthManager","session","getCurrentUserSessionInfo","auth_token","ajaxSetup","headers","Authorization","me","splitIdChunks","userIds","idGroups","splice","loadUsersInfo","nonFacAndActive","endUsers","members","endUserIds","chunkedUsers","chunkedPromises","userGroups","reduce","acc","userGroup","getGroupDetails","reject","UserModel","doneFn","after","autoAssign","parse","w","worldName","prevWorld","getWorldByUser","curWorld","getOrCreateWorld","removeUser","addUser","getWordByName","Error","getWorldByUserId","getWorldNames","getNextWorldName","properNames","test","lastWorld","numWorld","match","num","places","zeros","digits","toString","needed","usersCollection","usersHash","isComplete","index","list","_worldApi","updateConfig","userObj","save","checkWorld","delete","mapUsers","res","createWorld","addUsers","savedUsers","isNew","roles","getProjectSettings","settings","__webpack_exports__","userRowTemplate","trim","AssignmentRow","template","editTemplate","editUserRowTemplate","setEditMode","cancelEdit","off","animate","height","duration","complete","removeEditMode","updateData","trigger","templ","vm","optionalRoles","newWorld","html","context","next","shift"],"mappings":"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","file":"assignment.min.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 6);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n/**\r\n/* Inherit from a class (using prototype borrowing)\r\n*/\n\n\nfunction inherit(C, P) {\n var F = function () {};\n F.prototype = P.prototype;\n C.prototype = new F();\n C.__super = P.prototype;\n C.prototype.constructor = C;\n}\n\n/**\r\n* Shallow copy of an object\r\n* @param {Object} dest object to extend\r\n* @return {Object} extended object\r\n*/\nvar extend = function (dest /*, var_args*/) {\n var obj = Array.prototype.slice.call(arguments, 1);\n var current;\n for (var j = 0; j < obj.length; j++) {\n if (!(current = obj[j])) {\n //eslint-disable-line\n continue;\n }\n\n // do not wrap inner in dest.hasOwnProperty or bad things will happen\n for (var key in current) {\n //eslint-disable-line\n dest[key] = current[key];\n }\n }\n\n return dest;\n};\n\nmodule.exports = function (base, props, staticProps) {\n var parent = base;\n var child;\n\n child = props && props.hasOwnProperty('constructor') ? props.constructor : function () {\n return parent.apply(this, arguments);\n };\n\n // add static properties to the child constructor function\n extend(child, parent, staticProps);\n\n // associate prototype chain\n inherit(child, parent);\n\n // add instance properties\n if (props) {\n extend(child.prototype, props);\n }\n\n // done\n return child;\n};\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar env = __webpack_require__(3);\n\nvar cache = {};\n\nmodule.exports = {\n worldApi: function () {\n if (!cache.worldApi) {\n cache.worldApi = new F.service.World(env.get());\n }\n return cache.worldApi;\n },\n\n memberApi: function () {\n if (!cache.memberApi) {\n cache.memberApi = new F.service.Member(_.pick(env.get(), ['groupId', 'server']));\n }\n\n return cache.memberApi;\n },\n\n userApi: function () {\n if (!cache.userApi) {\n cache.userApi = new F.service.User(_.pick(env.get(), ['account', 'server']));\n }\n\n return cache.userApi;\n }\n};\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar BaseModel = function (attr, options) {\n attr = _.defaults({}, attr, _.result(this, 'defaults'));\n this._data = {};\n this.set(attr, options);\n this.initialize.apply(this, arguments);\n};\n\n_.extend(BaseModel.prototype, {\n initialize: function (attr, options) {},\n\n set: function (key, val, options) {\n if (key === null) {\n return this;\n }\n\n var attrs;\n if (typeof key === 'object') {\n attrs = key;\n options = val;\n } else {\n (attrs = {})[key] = val;\n }\n\n options = options || {};\n\n _.extend(this._data, attrs);\n\n return this;\n },\n\n get: function (key, options) {\n return this._data[key];\n },\n\n remove: function () {\n if (this.collection) {\n this.collection.remove(this);\n }\n\n return this;\n },\n\n toJSON: function () {\n return this._data;\n },\n\n pick: function (keys) {\n return _.pick(this._data, keys);\n }\n\n});\n\nmodule.exports = BaseModel;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar env = {\n account: '',\n project: '',\n group: '',\n groupId: '',\n token: '',\n server: {\n host: 'api.forio.com',\n protocol: 'https'\n }\n};\n\nmodule.exports = {\n set: function (options) {\n env = _.merge(env, options);\n },\n\n get: function () {\n return env;\n }\n};\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar classFrom = __webpack_require__(0);\nvar Base = __webpack_require__(2);\nvar serviceLocator = __webpack_require__(1);\n\nmodule.exports = classFrom(Base, {\n defaults: {\n world: '',\n role: '',\n active: true,\n isWorldComplete: true,\n firstName: '',\n lastName: ''\n },\n\n makeActive: function () {\n var memberApi = serviceLocator.memberApi();\n var params = {\n userId: this.get('id'),\n groupId: this.get('groupId')\n };\n\n var original = this.get('active');\n this.set('active', true);\n\n return memberApi.makeUserActive(params).fail(function () {\n // revert the change\n this.set('active', original);\n }.bind(this));\n },\n\n makeInactive: function () {\n var memberApi = serviceLocator.memberApi();\n var params = {\n userId: this.get('id'),\n groupId: this.get('groupId')\n };\n\n var original = this.get('active');\n this.set('active', false);\n\n return memberApi.makeUserInactive(params).fail(function () {\n // revert the change\n this.set('active', original);\n }.bind(this));\n }\n\n});\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar BaseCollection = function (models, options) {\n this._models = [];\n this.options = options;\n this.initialize.apply(this, arguments);\n};\n\n_.extend(BaseCollection.prototype, {\n idAttribute: 'id',\n\n initialize: function (models, options) {},\n\n create: function (attr, options) {\n var m = new this.model(attr, options);\n this.set(m);\n return m;\n },\n\n reset: function (models, options) {\n this._models.length = 0;\n this.set(models);\n },\n\n remove: function (model) {\n _.remove(this._models, function (m) {\n return m === model;\n });\n\n delete model.collection;\n\n return model;\n },\n\n set: function (models) {\n var _this = this;\n\n if (!models) {\n return;\n }\n\n models = [].concat(models);\n\n if (!models.length) {\n return;\n }\n\n models.forEach(function (m) {\n if (!(m instanceof _this.model)) {\n m = new _this.model(m);\n }\n m.collection = _this;\n _this._models.push(m);\n });\n\n this.sort();\n\n return models;\n },\n\n sortFn: function (a, b) {\n return b._data[this.idAttribute] - a._data[this.idAttribute];\n },\n\n sort: function () {\n this._models = this._models.sort(this.sortFn.bind(this));\n\n return this._models;\n },\n\n getById: function (id) {\n var _this2 = this;\n\n return _.find(this._models, function (m) {\n return m.get(_this2.idAttribute) === id;\n });\n },\n\n each: function (cb, ctx) {\n return _.each(this._models, cb, ctx || this);\n },\n\n all: function (cb, ctx) {\n return _.every(this._models, cb, ctx || this);\n },\n\n toJSON: function () {\n return _.invoke(this._models, 'toJSON');\n },\n\n find: function (fn) {\n return _.find(this._models, fn);\n },\n\n filter: function (fn) {\n return _.filter(this._models, fn);\n },\n\n size: function () {\n return this._models.length;\n },\n\n map: function (fn, ctx) {\n return _.map(this._models, function (model) {\n return fn.call(ctx, model.toJSON());\n });\n },\n\n pluck: function (field) {\n return this.map(function (m) {\n return m[field];\n });\n }\n\n});\n\nmodule.exports = BaseCollection;\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n(function () {\n var App = __webpack_require__(7);\n\n window.forio = window.forio || {};\n window.forio.MultiplayerAssignmentComponent = App;\n})();\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar UsersCollection = __webpack_require__(8);\nvar WorldsCollection = __webpack_require__(9);\nvar ProjectModel = __webpack_require__(11);\nvar AssignemntRow = __webpack_require__(12).default;\nvar env = __webpack_require__(3);\nvar AjaxQueue = __webpack_require__(13);\n\nfunction setEnvironment(options) {\n env.set(_.omit(options, 'el'));\n}\n\nvar Assignment = function (options) {\n setEnvironment(options);\n this.initialize(options);\n};\n\nAssignment.prototype = {\n\n initialize: function (options) {\n this.el = typeof options.el === 'string' ? $(options.el)[0] : options.el;\n this.$el = $(this.el);\n this.$ = _.partialRight($, this.el);\n\n this.users = new UsersCollection();\n this.worlds = new WorldsCollection();\n this.project = new ProjectModel();\n\n _.bindAll(this, ['render', 'renderTable', 'toggleControlls', 'saveEdit', 'selectAll', 'usassignSelected', '_showUpdating', '_hideUpdating', 'autoAssignAll', 'makeUserInactive']);\n\n this.bindEvents();\n },\n\n bindEvents: function () {\n this.$el.on('update', 'tr', this.saveEdit);\n this.$el.on('click', 'input:checkbox:not(#select-all)', this.toggleControlls);\n this.$el.on('click', '#select-all', this.selectAll);\n this.$el.on('click', '.unassign-user', this.usassignSelected);\n this.$el.on('click', '.auto-assign-all', this.autoAssignAll);\n this.$el.on('click', '.make-user-inactive', this.makeUserInactive);\n },\n\n load: function () {\n var join = function () {\n this.worlds.setUsersCollection(this.users);\n this.worlds.joinUsers();\n this.render();\n }.bind(this);\n\n return $.when(this.worlds.fetch(), this.users.fetch(), this.project.fetch()).then(join);\n },\n\n saveEdit: function () {\n this.worlds.fetch().then(function () {\n this.worlds.joinUsers();\n this.render();\n this.updateControls();\n }.bind(this));\n },\n\n autoAssignAll: function () {\n this._showUpdating();\n var maxUsers = +this.$('#max-users').val();\n return this.worlds.autoAssignAll({ maxUsers: maxUsers }).then(this._hideUpdating).fail(this._hideUpdating).then(function () {\n this.worlds.joinUsers();\n this.render();\n }.bind(this));\n },\n\n getSelectedIds: function () {\n return this.$('tbody :checkbox:checked').map(function () {\n return $(this).data('id');\n }).get();\n },\n\n findRowViews: function (ids) {\n var _this = this;\n\n return ids.map(function (id) {\n return _this.rowViews[id];\n });\n },\n\n unassignUsers: function (ids) {\n var _this2 = this;\n\n var dtd = $.Deferred();\n var done = function () {\n dtd.resolve();\n };\n\n // for now we need to sequence the calls to unassign users from worlds\n var queue = new AjaxQueue();\n\n ids.forEach(function (userId) {\n var user = _this2.users.getById(userId);\n user.set('world', '');\n user.set('role', '');\n queue.add(_.partial(_.bind(_this2.worlds.updateUser, _this2.worlds), user));\n });\n\n queue.execute(this).then(done);\n\n return dtd.promise();\n },\n\n usassignSelected: function (e) {\n e.preventDefault();\n\n var ids = this.getSelectedIds();\n\n var done = function () {\n this.worlds.fetch().then(function () {\n this.worlds.joinUsers();\n this._hideUpdating();\n this.render();\n }.bind(this));\n }.bind(this);\n\n this._showUpdating();\n\n return this.unassignUsers(ids).then(done);\n },\n\n makeUserInactive: function (e) {\n e.preventDefault();\n var ids = this.getSelectedIds();\n var done = function () {\n this.toggleControlls();\n }.bind(this);\n\n var makeUsersInactive = function () {\n var rows = this.findRowViews(ids);\n // for now we need to sequence the calls to patch the users\n // since the API can only operate on one call per group at a time\n var queue = new AjaxQueue();\n rows.forEach(function (view) {\n var user = view.model;\n queue.add(function () {\n return view.makeInactive().then(function () {\n user.remove();\n view.remove();\n });\n });\n });\n\n queue.execute(this).then(done);\n }.bind(this);\n\n return this.unassignUsers(ids).then(makeUsersInactive);\n },\n\n render: function () {\n this.$('table tbody').empty();\n this.sortTable();\n this.renderTable();\n this.toggleControlls();\n },\n\n sortTable: function () {\n // get the sort params and sort if necessary\n var params = this.getTableParams();\n\n var mult = params.hasOwnProperty('direction') && params.direction === 'desc' ? -1 : 1;\n var nameDirection = params.hasOwnProperty('sort') && params.sort === 'name' && mult > 0 ? 'desc' : 'asc';\n var userNameDirection = params.hasOwnProperty('sort') && params.sort === 'userName' && mult > 0 ? 'desc' : 'asc';\n this.$('table .header-name a').prop('href', '?sort=name&direction=' + nameDirection);\n this.$('table .header-username a').prop('href', '?sort=userName&direction=' + userNameDirection);\n\n if (params.hasOwnProperty('sort')) {\n this.users.sortFn = function (a, b) {\n var an = a.get(params.sort) || '';\n var bn = b.get(params.sort) || '';\n if (params.sort === 'name') {\n an = a.get('firstName') + a.get('lastName');\n bn = b.get('firstName') + b.get('lastName');\n }\n return mult * an.localeCompare(bn);\n };\n this.users.sort();\n\n var header = params.sort === 'name' ? this.$('table .header-name') : this.$('table .header-username');\n var arrowDir = mult > 0 ? 'caret-up' : 'caret-down';\n var arrow = this.$('');\n header.append(arrow);\n }\n },\n\n getTableParams: function () {\n var query = location.search !== '' ? location.search.substr(1).split('&') : [];\n var params = {};\n for (var i = 0; i < query.length; i++) {\n var q = query[i].split('=');\n params[q[0]] = q[1];\n }\n return params;\n },\n\n renderTable: function () {\n var _this3 = this;\n\n this.rowViews = {};\n var rows = [];\n this.users.each(function (u) {\n var view = new AssignemntRow({ model: u, worlds: _this3.worlds, project: _this3.project });\n _this3.rowViews[u.get('id')] = view;\n rows.push(view.render().el);\n });\n\n this.$('table tbody').append(rows);\n },\n\n updateControls: function () {\n this.updateControlsForSelection();\n this.updateAutoAssignButton();\n this.updateStatus();\n },\n\n updateStatus: function () {\n var incompleteWorlds = this.worlds.getIncompleteWorldsCount();\n var unassignedUsers = this.users.getUnassignedUsersCount();\n var totalWorlds = this.worlds.size();\n\n var usersText = 'All users have been assigned.';\n if (unassignedUsers) {\n usersText = unassignedUsers === 1 ? '1 user needs assignment.' : unassignedUsers + ' users need assignment.';\n }\n var worldsText = 'All worlds are complete.';\n if (!totalWorlds) {\n worldsText = 'No worlds have been created.';\n } else if (incompleteWorlds) {\n worldsText = incompleteWorlds === 1 ? '1 incomplete world needs attention.' : incompleteWorlds + ' incomplete worlds need attention.';\n }\n\n this.$('#users-status .text').text(usersText);\n this.$('#worlds-status .text').text(worldsText);\n\n if (unassignedUsers) {\n this.$('#users-status').addClass('incomplete');\n } else {\n this.$('#users-status').removeClass('incomplete');\n }\n\n if (incompleteWorlds || !totalWorlds) {\n this.$('#worlds-status').addClass('incomplete');\n } else {\n this.$('#worlds-status').removeClass('incomplete');\n }\n\n this.$('.status-widget').addClass('visible');\n },\n\n updateControlsForSelection: function () {\n var numSelected = this.$('tbody :checkbox:checked').length;\n this.$('.component.controls')[numSelected ? 'addClass' : 'removeClass']('visible');\n },\n\n updateAutoAssignButton: function () {\n\n if (this.project.isDynamicAssignment()) {\n var hasRoles = this.project.hasRoles();\n this.$('.table-controls .single').hide();\n this.$('.table-controls .dynamic').show();\n this.$('.table-controls .dynamic-no-roles-text')[hasRoles ? 'hide' : 'show']();\n this.$('.table-controls .no-roles')[hasRoles ? 'hide' : 'show']();\n } else {\n this.$('.table-controls .dynamic').hide();\n this.$('.table-controls .dynamic-no-roles-text').hide();\n this.$('.table-controls .single').show();\n this.$('.table-controls .no-roles').show();\n }\n\n if (this.users.allUsersAssigned()) {\n this.$('.table-controls').removeClass('visible');\n } else {\n this.$('.table-controls').addClass('visible');\n }\n },\n\n selectAll: function (e) {\n this.$('tbody :checkbox').prop('checked', e.target.checked);\n this.updateControls();\n },\n\n toggleControlls: function (e) {\n var total = this.$('tbody :checkbox');\n var checked = this.$('tbody :checkbox:checked');\n\n if (total.length === checked.length) {\n this.$('#select-all').attr('checked', 'checked');\n } else {\n this.$('#select-all').removeAttr('checked');\n }\n\n this.updateControls();\n },\n\n _showUpdating: function () {\n this.$el.css({ opacity: 0.4 });\n },\n\n _hideUpdating: function () {\n this.$el.css({ opacity: 1 });\n }\n\n};\n\nmodule.exports = Assignment;\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar classFrom = __webpack_require__(0);\n\nvar Model = __webpack_require__(4);\nvar Base = __webpack_require__(5);\nvar env = __webpack_require__(3);\nvar serviceLocator = __webpack_require__(1);\n\nmodule.exports = classFrom(Base, {\n model: Model,\n\n sortFn: function (a, b) {\n var aw = a.get('world').toLowerCase();\n var bw = b.get('world').toLowerCase();\n if (aw !== bw) {\n return aw < bw ? -1 : 1;\n }\n\n return b.get('userName') > a.get('userName') ? -1 : 1;\n },\n\n initialize: function () {\n var am = new F.manager.AuthManager();\n var session = am.getCurrentUserSessionInfo();\n var token = session.auth_token;\n if (token) {\n $.ajaxSetup({\n headers: {\n Authorization: 'Bearer ' + token\n }\n });\n }\n },\n\n allUsersAssigned: function () {\n return this.all(function (u) {\n return !!u.get('world');\n });\n },\n\n getUnassignedUsersCount: function () {\n return this.filter(function (u) {\n return !u.get('world');\n }).length;\n },\n\n fetch: function () {\n var dtd = $.Deferred();\n var me = this;\n var groupId = env.get().groupId;\n\n var getGroupUsers = function () {\n var memberApi = serviceLocator.memberApi();\n var userApi = serviceLocator.userApi();\n\n var loadGroupMembers = function () {\n return memberApi.getGroupDetails();\n };\n\n var splitIdChunks = function (userIds) {\n var idGroupSize = 100;\n var idGroups = [];\n while (userIds.length >= idGroupSize) {\n idGroups.push(userIds.splice(0, idGroupSize));\n }\n\n if (userIds.length) {\n idGroups.push(userIds);\n }\n\n return idGroups;\n };\n\n var loadUsersInfo = function (group) {\n var nonFacAndActive = function (u) {\n return u.active && u.role !== 'facilitator';\n };\n var endUsers = group.members.filter(function (m) {\n return nonFacAndActive(m);\n });\n var endUserIds = endUsers.map(function (u) {\n return u.userId;\n });\n var chunkedUsers = splitIdChunks(endUserIds);\n var chunkedPromises = chunkedUsers.map(function (users) {\n return userApi.get({ id: users });\n });\n return $.when.apply($, chunkedPromises).then(function (userGroups) {\n var totalUsers = userGroups.reduce(function (acc, userGroup) {\n return acc.concat(userGroup);\n }, []);\n\n return totalUsers;\n });\n };\n\n return loadGroupMembers().then(loadUsersInfo).fail(dtd.reject);\n };\n\n getGroupUsers().then(function (users) {\n users = users.map(function (u) {\n return $.extend(u, { groupId: groupId });\n });\n me.set(users);\n dtd.resolve(users);\n });\n\n return dtd.promise();\n }\n\n});\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar classFrom = __webpack_require__(0);\nvar Model = __webpack_require__(10);\nvar UserModel = __webpack_require__(4);\nvar serviceLocator = __webpack_require__(1);\n\nvar Base = __webpack_require__(5);\nvar __super = Base.prototype;\n\nvar doneFn = function (dtd, after) {\n return _.after(after, dtd.resolve);\n};\n\nvar worldApi;\n\nmodule.exports = classFrom(Base, {\n model: Model,\n\n initialize: function () {\n __super.initialize.apply(this, arguments);\n worldApi = serviceLocator.worldApi();\n },\n\n autoAssignAll: function (options) {\n return worldApi.autoAssign(options).then(function (worlds) {\n this.reset(this.parse(worlds));\n }.bind(this));\n },\n\n getIncompleteWorldsCount: function () {\n return this.filter(function (w) {\n return !w.get('complete');\n }).length;\n },\n\n updateUser: function (user) {\n var worldName = user.get('world');\n var dtd = $.Deferred();\n var prevWorld = this.getWorldByUser(user);\n var curWorld = this.getOrCreateWorld(worldName);\n var done = doneFn(dtd, 1);\n\n // check if there's anything to do\n if (!prevWorld && !curWorld) {\n return dtd.resolve().promise();\n }\n\n if (prevWorld && curWorld && prevWorld.get('id') === curWorld.get('id')) {\n //worlds are the same, but role changed\n return curWorld.updateUser(user);\n }\n if (prevWorld) {\n prevWorld.removeUser(user).then(function () {\n if (curWorld) {\n return curWorld.addUser(user);\n }\n }).then(done);\n } else if (curWorld) {\n curWorld.addUser(user).then(done);\n }\n\n return dtd.promise();\n },\n\n getOrCreateWorld: function (worldName) {\n if (!worldName) {\n return;\n }\n\n var world = this.getWordByName(worldName);\n\n if (!world) {\n world = this.create({ name: worldName });\n }\n\n return world;\n },\n\n getWordByName: function (worldName) {\n return this.find(function (world) {\n return world.get('name') === worldName;\n });\n },\n\n getWorldByUser: function (user) {\n if (!user.get) {\n throw new Error('getWorldByUser expectes a model (' + user + ')');\n }\n\n var id = user.get('id');\n return this.getWorldByUserId(id);\n },\n\n getWorldByUserId: function (userId) {\n return this.find(function (world) {\n return _.find(world.get('users'), function (u) {\n return u.get('id') === userId;\n });\n });\n },\n\n getWorldNames: function () {\n return this.pluck('name').sort();\n },\n\n getNextWorldName: function () {\n var pad = function (num, places) {\n var zeros = '000000000000000000';\n var digits = num.toString().length;\n var needed = places - digits;\n return zeros.substr(0, needed) + num;\n };\n\n var worlds = this.getWorldNames();\n\n if (!worlds.length) {\n return 'World001';\n }\n\n var properNames = _.filter(worlds, function (w) {\n return (/World\\d\\d\\d/.test(w)\n );\n }).sort();\n var lastWorld = properNames[properNames.length - 1];\n var numWorld = +lastWorld.match(/World(\\d\\d\\d)/)[1];\n var placesToPad = 3;\n return 'World' + pad(numWorld + 1, placesToPad);\n },\n\n setUsersCollection: function (usersCollection) {\n this.usersCollection = usersCollection;\n },\n\n joinUsers: function () {\n var usersHash = {};\n var usersCollection = this.usersCollection;\n usersCollection.each(function (u) {\n u.set({ isWorldComplete: true });\n return usersHash[u.get('id')] = u;\n });\n\n this.each(function (w, i) {\n var name = w.get('name');\n var isComplete = w.get('complete');\n w.set({ index: i, name: name || i + 1 + '' });\n _.each(w.get('users'), function (u) {\n if (usersHash[u.get('userId')]) {\n usersHash[u.get('userId')].set({ world: name, role: u.get('role'), isWorldComplete: isComplete });\n }\n });\n });\n\n usersCollection.sort();\n },\n\n fetch: function () {\n return worldApi.list().then(function (worlds) {\n this.reset(this.parse(worlds));\n }.bind(this));\n },\n\n parse: function (worlds) {\n if (worlds.length) {\n worlds = _.map(worlds, function (w) {\n var users = _.map(w.users, function (u) {\n // in the world api users Ids comes as userId\n // make sure we add it as id so we can use the\n // same code to access models that come from the\n // member/local api as with the world api\n u.id = u.userId;\n return new UserModel(u);\n });\n\n w.users = users;\n\n return w;\n });\n }\n\n return worlds;\n }\n});\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar serviceLocator = __webpack_require__(1);\nvar classFrom = __webpack_require__(0);\nvar Base = __webpack_require__(2);\nvar __super = Base.prototype;\n\nmodule.exports = classFrom(Base, {\n\n defaults: {\n users: null,\n model: 'model.eqn'\n },\n\n initialize: function () {\n __super.initialize.apply(this, arguments);\n\n this._data.users = this._data.users || [];\n\n this._worldApi = serviceLocator.worldApi();\n\n var id = this.get('id');\n if (id) {\n this._worldApi.updateConfig({ filter: id });\n }\n },\n\n updateUser: function (user) {\n if (!user) {\n throw new Error('updateUser: No user passed to update');\n }\n var userObj = user.toJSON();\n userObj.userId = userObj.id;\n return this._worldApi.updateUser(userObj, { id: this.get('id') });\n },\n\n addUser: function (user) {\n var users = this.get('users');\n users.push(user);\n\n return this.save();\n },\n\n removeUser: function (user) {\n var id = this.get('id');\n var checkWorld = function () {\n if (!this.get('users').length) {\n this.remove();\n return this._worldApi.updateConfig({ filter: id }).delete();\n }\n }.bind(this);\n\n _.remove(this.get('users'), function (u) {\n return u.get('id') === user.get('id');\n });\n\n return this._worldApi.updateConfig({ filter: id }).removeUser({ userId: user.get('id') }).then(checkWorld);\n },\n\n save: function () {\n var me = this;\n var mapUsers = function () {\n return _.map(this.get('users'), function (u) {\n var res = { userId: u.get('id') };\n var role = u.get('role');\n\n if (role) {\n res.role = role;\n }\n\n return res;\n });\n }.bind(this);\n\n var createWorld = _.partial(this._worldApi.create, this.pick(['model', 'name', 'minUsers']));\n var addUsers = _.partial(me._worldApi.addUsers, mapUsers(), { filter: me.get('id') });\n var savedUsers = this.get('users');\n if (this.isNew()) {\n // we need to create the world in the API and then add the users\n return createWorld().then(function (world) {\n me.set(world);\n me._worldApi.updateConfig({ filter: world.id });\n }).then(addUsers).then(function (users) {\n // since we re-set the world, re-set the users\n me.set('users', savedUsers);\n });\n } else {\n // the world is already created just add the users\n return addUsers();\n }\n },\n\n isNew: function () {\n return !this.get('lastModified');\n }\n\n});\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar serviceLocator = __webpack_require__(1);\n\nvar classFrom = __webpack_require__(0);\nvar Base = __webpack_require__(2);\n// var __super = Base.prototype;\n\nmodule.exports = classFrom(Base, {\n\n isDynamicAssignment: function () {\n return this.get('worlds') === 'dynamic';\n },\n\n hasRoles: function () {\n var roles = this.get('roles');\n return roles && !!roles.length;\n },\n\n fetch: function () {\n var api = serviceLocator.worldApi();\n\n return api.getProjectSettings().then(function (settings) {\n this.set(settings);\n }.bind(this));\n }\n});\n\n/***/ }),\n/* 12 */\n/***/ (function(module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\nObject.defineProperty(__webpack_exports__, \"__esModule\", { value: true });\nvar userRowTemplate = '\\n \"\\n <%= !isWorldComplete ? \\'\\' : \\'\\' %>\\n <%= world %>\\n <%= role %>\\n <%= lastName %>\\n <%= userName %>\\n <%= !world ? \\'\\' : \\'\\' %>\\n \\n'.trim();\nvar editUserRowTemplate = '\\n \"\\n \\n \\n \\n \\n \\n \\n \\n <%= lastName %>\\n <%= userName %>\\n <%= !world ? \\'\\' : \\'\\' %>\\n \\n \\n \\n \\n';\n\nvar AssignmentRow = function (options) {\n this.$el = $('');\n this.el = this.$el[0];\n this.$ = _.partialRight($, this.$el);\n\n this.model = options.model;\n this.options = options;\n this.worlds = options.worlds;\n this.project = options.project;\n\n _.bindAll(this, ['setEditMode', 'removeEditMode', 'saveEdit', 'cancelEdit', 'updateData']);\n\n this.bindEvents();\n};\n\n_.extend(AssignmentRow.prototype, {\n\n template: _.template(userRowTemplate),\n editTemplate: _.template(editUserRowTemplate),\n\n bindEvents: function () {\n this.$el.on('click', 'button.edit', this.setEditMode);\n this.$el.on('click', 'button.save', this.saveEdit);\n this.$el.on('click', 'button.cancel', this.cancelEdit);\n },\n\n remove: function () {\n this.$el.off('click', null, null);\n // this only gives a delay to remove the tr\n // animation of height of the tr does not work\n this.$(':checkbox').attr('checked', false);\n this.$el.css({ opacity: 0.3 }).animate({ height: 0 }, {\n duration: 300,\n complete: function () {\n this.remove();\n }\n });\n },\n\n makeInactive: function () {\n return this.model.makeInactive();\n },\n\n setEditMode: function () {\n this.model.set('edit-mode', true);\n this.render();\n },\n\n removeEditMode: function () {\n this.model.set('edit-mode', false);\n this.render();\n },\n\n saveEdit: function () {\n var me = this;\n this.updateData();\n this.worlds.updateUser(this.model).then(function () {\n me.removeEditMode();\n me.$el.trigger('update', me);\n });\n },\n\n cancelEdit: function () {\n this.removeEditMode();\n },\n\n render: function () {\n var templ = this.model.get('edit-mode') ? this.editTemplate : this.template;\n var vm = _.extend({\n roles: this.project.get('roles'),\n optionalRoles: this.project.get('optionalRoles'),\n worlds: this.worlds.getWorldNames(),\n newWorld: this.worlds.getNextWorldName()\n }, this.model.toJSON());\n\n this.$el.html(templ(vm));\n\n return this;\n },\n\n updateData: function () {\n var me = this;\n this.$('[data-field]').each(function () {\n var el = $(this);\n var field = el.data('field');\n var val = el.val();\n\n me.model.set(field, val);\n });\n }\n});\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (AssignmentRow);\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/**\r\n* Utility class to make ajax calls sequencial\r\n*/\n\nfunction AjaxQueue() {\n this.queue = [];\n}\n\n$.extend(AjaxQueue.prototype, {\n add: function (fn) {\n return this.queue.push(fn);\n },\n\n execute: function (context) {\n var dtd = $.Deferred();\n var me = this;\n context = context || this;\n\n function next() {\n if (me.queue.length) {\n var fn = me.queue.shift();\n\n fn.call(context).then(next).fail(dtd.reject);\n } else {\n dtd.resolve();\n }\n }\n\n next();\n\n return dtd.promise();\n }\n});\n\nmodule.exports = AjaxQueue;\n\n/***/ })\n/******/ ]);\n\n\n// WEBPACK FOOTER //\n// assignment.min.js"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 6);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap e43f576d3dda2a1c6a33","/**\r\n/* Inherit from a class (using prototype borrowing)\r\n*/\r\n'use strict';\r\n\r\nfunction inherit(C, P) {\r\n var F = function () {};\r\n F.prototype = P.prototype;\r\n C.prototype = new F();\r\n C.__super = P.prototype;\r\n C.prototype.constructor = C;\r\n}\r\n\r\n/**\r\n* Shallow copy of an object\r\n* @param {Object} dest object to extend\r\n* @return {Object} extended object\r\n*/\r\nvar extend = function (dest /*, var_args*/) {\r\n var obj = Array.prototype.slice.call(arguments, 1);\r\n var current;\r\n for (var j = 0; j < obj.length; j++) {\r\n if (!(current = obj[j])) { //eslint-disable-line\r\n continue;\r\n }\r\n\r\n // do not wrap inner in dest.hasOwnProperty or bad things will happen\r\n for (var key in current) { //eslint-disable-line\r\n dest[key] = current[key];\r\n }\r\n }\r\n\r\n return dest;\r\n};\r\n\r\nmodule.exports = function (base, props, staticProps) {\r\n var parent = base;\r\n var child;\r\n\r\n child = props && props.hasOwnProperty('constructor') ? props.constructor : function () { return parent.apply(this, arguments); };\r\n\r\n // add static properties to the child constructor function\r\n extend(child, parent, staticProps);\r\n\r\n // associate prototype chain\r\n inherit(child, parent);\r\n\r\n // add instance properties\r\n if (props) {\r\n extend(child.prototype, props);\r\n }\r\n\r\n // done\r\n return child;\r\n};\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/util/inherit.js","'use strict';\r\n\r\nvar env = require('./defaults.js');\r\n\r\nvar cache = {};\r\n\r\nmodule.exports = {\r\n worldApi: function () {\r\n if (!cache.worldApi) {\r\n cache.worldApi = new F.service.World(env.get());\r\n }\r\n return cache.worldApi;\r\n },\r\n\r\n memberApi: function () {\r\n if (!cache.memberApi) {\r\n cache.memberApi = new F.service.Member(_.pick(env.get(), ['groupId', 'server']));\r\n }\r\n\r\n return cache.memberApi;\r\n },\r\n\r\n userApi: function () {\r\n if (!cache.userApi) {\r\n cache.userApi = new F.service.User(_.pick(env.get(), ['account', 'server']));\r\n }\r\n\r\n return cache.userApi;\r\n }\r\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/service-locator.js","'use strict';\r\n\r\n\r\nvar BaseModel = function (attr, options) {\r\n attr = _.defaults({}, attr, _.result(this, 'defaults'));\r\n this._data = {};\r\n this.set(attr, options);\r\n this.initialize.apply(this, arguments);\r\n};\r\n\r\n_.extend(BaseModel.prototype, {\r\n initialize: function (attr, options) {\r\n\r\n },\r\n\r\n set: function (key, val, options) {\r\n if (key === null) {\r\n return this;\r\n }\r\n\r\n var attrs;\r\n if (typeof key === 'object') {\r\n attrs = key;\r\n options = val;\r\n } else {\r\n (attrs = {})[key] = val;\r\n }\r\n\r\n options = options || {};\r\n\r\n _.extend(this._data, attrs);\r\n\r\n return this;\r\n },\r\n\r\n get: function (key, options) {\r\n return this._data[key];\r\n },\r\n\r\n remove: function () {\r\n if (this.collection) {\r\n this.collection.remove(this);\r\n }\r\n\r\n return this;\r\n },\r\n\r\n toJSON: function () {\r\n return this._data;\r\n },\r\n\r\n pick: function (keys) {\r\n return _.pick(this._data, keys);\r\n }\r\n\r\n});\r\n\r\nmodule.exports = BaseModel;\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/base-model.js","'use strict';\n\nvar env = {\n account: '',\n project: '',\n group: '',\n groupId: '',\n token: '',\n server: {\n host: 'api.forio.com',\n protocol: 'https'\n }\n};\n\nmodule.exports = {\n set: function (options) {\n env = _.merge(env, options);\n },\n\n get: function () {\n return env;\n }\n};\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/defaults.js","'use strict';\n\nvar classFrom = require('../../../util/inherit');\nvar Base = require('./base-model');\nvar serviceLocator = require('./service-locator');\n\n\nmodule.exports = classFrom(Base, {\n defaults: {\n world: '',\n role: '',\n active: true,\n isWorldComplete: true,\n firstName: '',\n lastName: ''\n },\n\n makeActive: function () {\n var memberApi = serviceLocator.memberApi();\n var params = {\n userId: this.get('id'),\n groupId: this.get('groupId')\n };\n\n var original = this.get('active');\n this.set('active', true);\n\n return memberApi.makeUserActive(params)\n .fail(function () {\n // revert the change\n this.set('active', original);\n }.bind(this));\n },\n\n makeInactive: function () {\n var memberApi = serviceLocator.memberApi();\n var params = {\n userId: this.get('id'),\n groupId: this.get('groupId')\n };\n\n var original = this.get('active');\n this.set('active', false);\n\n return memberApi.makeUserInactive(params)\n .fail(function () {\n // revert the change\n this.set('active', original);\n }.bind(this));\n }\n\n});\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/user-model.js","'use strict';\r\n\r\nvar BaseCollection = function (models, options) {\r\n this._models = [];\r\n this.options = options;\r\n this.initialize.apply(this, arguments);\r\n};\r\n\r\n_.extend(BaseCollection.prototype, {\r\n idAttribute: 'id',\r\n\r\n initialize: function (models, options) {\r\n },\r\n\r\n create: function (attr, options) {\r\n var m = new this.model(attr, options);\r\n this.set(m);\r\n return m;\r\n },\r\n\r\n reset: function (models, options) {\r\n this._models.length = 0;\r\n this.set(models);\r\n },\r\n\r\n remove: function (model) {\r\n _.remove(this._models, function (m) {\r\n return m === model;\r\n });\r\n\r\n delete model.collection;\r\n\r\n return model;\r\n },\r\n\r\n set: function (models) {\r\n if (!models) {\r\n return;\r\n }\r\n\r\n models = [].concat(models);\r\n\r\n if (!models.length) {\r\n return;\r\n }\r\n\r\n models.forEach((m)=> {\r\n if (!(m instanceof this.model)) {\r\n m = new this.model(m);\r\n }\r\n m.collection = this;\r\n this._models.push(m);\r\n });\r\n\r\n this.sort();\r\n\r\n return models;\r\n },\r\n\r\n sortFn: function (a, b) {\r\n return b._data[this.idAttribute] - a._data[this.idAttribute];\r\n },\r\n\r\n sort: function () {\r\n this._models = this._models.sort(this.sortFn.bind(this));\r\n\r\n return this._models;\r\n },\r\n\r\n getById: function (id) {\r\n return _.find(this._models, (m)=> {\r\n return m.get(this.idAttribute) === id;\r\n });\r\n },\r\n\r\n each: function (cb, ctx) {\r\n return _.each(this._models, cb, ctx || this);\r\n },\r\n\r\n all: function (cb, ctx) {\r\n return _.every(this._models, cb, ctx || this);\r\n },\r\n\r\n toJSON: function () {\r\n return _.invoke(this._models, 'toJSON');\r\n },\r\n\r\n find: function (fn) {\r\n return _.find(this._models, fn);\r\n },\r\n\r\n filter: function (fn) {\r\n return _.filter(this._models, fn);\r\n },\r\n\r\n size: function () {\r\n return this._models.length;\r\n },\r\n\r\n map: function (fn, ctx) {\r\n return _.map(this._models, function (model) {\r\n return fn.call(ctx, model.toJSON());\r\n });\r\n },\r\n\r\n pluck: function (field) {\r\n return this.map(function (m) {\r\n return m[field];\r\n });\r\n }\r\n\r\n});\r\n\r\nmodule.exports = BaseCollection;\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/base-collection.js","(function () {\r\n var App = require('./assignment.js');\r\n\r\n window.forio = window.forio || {};\r\n window.forio.MultiplayerAssignmentComponent = App;\r\n}());\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/index.js","'use strict';\r\n\r\nvar UsersCollection = require('./users-collection');\r\nvar WorldsCollection = require('./worlds-collection');\r\nvar ProjectModel = require('./project-model');\r\nvar AssignemntRow = require('./assignment-row').default;\r\nvar env = require('./defaults');\r\nvar AjaxQueue = require('../../../util/ajax-queue');\r\n\r\nfunction setEnvironment(options) {\r\n env.set(_.omit(options, 'el'));\r\n}\r\n\r\nvar Assignment = function (options) {\r\n setEnvironment(options);\r\n this.initialize(options);\r\n};\r\n\r\nAssignment.prototype = {\r\n\r\n initialize: function (options) {\r\n this.el = typeof options.el === 'string' ? $(options.el)[0] : options.el;\r\n this.$el = $(this.el);\r\n this.$ = _.partialRight($, this.el);\r\n\r\n this.users = new UsersCollection();\r\n this.worlds = new WorldsCollection();\r\n this.project = new ProjectModel();\r\n\r\n _.bindAll(this, ['render', 'renderTable', 'toggleControlls', 'saveEdit', 'selectAll', 'usassignSelected', '_showUpdating', '_hideUpdating', 'autoAssignAll', 'makeUserInactive']);\r\n\r\n this.bindEvents();\r\n },\r\n\r\n bindEvents: function () {\r\n this.$el.on('update', 'tr', this.saveEdit);\r\n this.$el.on('click', 'input:checkbox:not(#select-all)', this.toggleControlls);\r\n this.$el.on('click', '#select-all', this.selectAll);\r\n this.$el.on('click', '.unassign-user', this.usassignSelected);\r\n this.$el.on('click', '.auto-assign-all', this.autoAssignAll);\r\n this.$el.on('click', '.make-user-inactive', this.makeUserInactive);\r\n },\r\n\r\n load: function () {\r\n var join = function () {\r\n this.worlds.setUsersCollection(this.users);\r\n this.worlds.joinUsers();\r\n this.render();\r\n }.bind(this);\r\n\r\n return $.when(\r\n this.worlds.fetch(),\r\n this.users.fetch(),\r\n this.project.fetch()\r\n ).then(join);\r\n },\r\n\r\n saveEdit: function () {\r\n this.worlds.fetch()\r\n .then(function () {\r\n this.worlds.joinUsers();\r\n this.render();\r\n this.updateControls();\r\n }.bind(this));\r\n },\r\n\r\n autoAssignAll: function () {\r\n this._showUpdating();\r\n var maxUsers = +this.$('#max-users').val();\r\n return this.worlds.autoAssignAll({ maxUsers: maxUsers })\r\n .then(this._hideUpdating)\r\n .fail(this._hideUpdating)\r\n .then(function () {\r\n this.worlds.joinUsers();\r\n this.render();\r\n }.bind(this));\r\n },\r\n\r\n getSelectedIds: function () {\r\n return this.$('tbody :checkbox:checked').map(function () {\r\n return $(this).data('id');\r\n }).get();\r\n },\r\n\r\n findRowViews: function (ids) {\r\n return ids.map((id)=> {\r\n return this.rowViews[id];\r\n });\r\n },\r\n\r\n unassignUsers: function (ids) {\r\n var dtd = $.Deferred();\r\n var done = function () {\r\n dtd.resolve();\r\n };\r\n\r\n // for now we need to sequence the calls to unassign users from worlds\r\n var queue = new AjaxQueue();\r\n\r\n ids.forEach((userId)=> {\r\n var user = this.users.getById(userId);\r\n user.set('world', '');\r\n user.set('role', '');\r\n queue.add(_.partial(_.bind(this.worlds.updateUser, this.worlds), user));\r\n });\r\n\r\n queue.execute(this).then(done);\r\n\r\n return dtd.promise();\r\n },\r\n\r\n usassignSelected: function (e) {\r\n e.preventDefault();\r\n\r\n var ids = this.getSelectedIds();\r\n\r\n var done = function () {\r\n this.worlds.fetch().then(function () {\r\n this.worlds.joinUsers();\r\n this._hideUpdating();\r\n this.render();\r\n\r\n }.bind(this));\r\n }.bind(this);\r\n\r\n this._showUpdating();\r\n\r\n return this.unassignUsers(ids).then(done);\r\n },\r\n\r\n makeUserInactive: function (e) {\r\n e.preventDefault();\r\n var ids = this.getSelectedIds();\r\n var done = function () {\r\n this.toggleControlls();\r\n }.bind(this);\r\n\r\n var makeUsersInactive = function () {\r\n var rows = this.findRowViews(ids);\r\n // for now we need to sequence the calls to patch the users\r\n // since the API can only operate on one call per group at a time\r\n var queue = new AjaxQueue();\r\n rows.forEach((view)=> {\r\n var user = view.model;\r\n queue.add(function () {\r\n return view.makeInactive()\r\n .then(function () {\r\n user.remove();\r\n view.remove();\r\n });\r\n });\r\n\r\n });\r\n\r\n queue.execute(this).then(done);\r\n }.bind(this);\r\n\r\n return this.unassignUsers(ids)\r\n .then(makeUsersInactive);\r\n\r\n\r\n },\r\n\r\n render: function () {\r\n this.$('table tbody').empty();\r\n this.sortTable();\r\n this.renderTable();\r\n this.toggleControlls();\r\n },\r\n\r\n sortTable: function () {\r\n // get the sort params and sort if necessary\r\n var params = this.getTableParams();\r\n\r\n var mult = params.hasOwnProperty('direction') && params.direction === 'desc' ? -1 : 1;\r\n var nameDirection = params.hasOwnProperty('sort') && params.sort === 'name' && mult > 0 ? 'desc' : 'asc';\r\n var userNameDirection = params.hasOwnProperty('sort') && params.sort === 'userName' && mult > 0 ? 'desc' : 'asc';\r\n this.$('table .header-name a').prop('href', '?sort=name&direction=' + nameDirection);\r\n this.$('table .header-username a').prop('href', '?sort=userName&direction=' + userNameDirection);\r\n\r\n if (params.hasOwnProperty('sort')) {\r\n this.users.sortFn = function (a, b) {\r\n var an = (a.get(params.sort) || '');\r\n var bn = (b.get(params.sort) || '');\r\n if (params.sort === 'name') {\r\n an = (a.get('firstName') + a.get('lastName'));\r\n bn = (b.get('firstName') + b.get('lastName'));\r\n }\r\n return mult * an.localeCompare(bn);\r\n };\r\n this.users.sort();\r\n\r\n var header = params.sort === 'name' ? this.$('table .header-name') : this.$('table .header-username');\r\n var arrowDir = mult > 0 ? 'caret-up' : 'caret-down';\r\n var arrow = this.$('');\r\n header.append(arrow);\r\n }\r\n },\r\n\r\n getTableParams: function () {\r\n var query = location.search !== '' ? location.search.substr(1).split('&') : [];\r\n var params = {};\r\n for (var i = 0; i < query.length; i++) {\r\n var q = query[i].split('=');\r\n params[q[0]] = q[1];\r\n }\r\n return params;\r\n },\r\n\r\n renderTable: function () {\r\n this.rowViews = {};\r\n var rows = [];\r\n this.users.each((u)=> {\r\n var view = new AssignemntRow({ model: u, worlds: this.worlds, project: this.project });\r\n this.rowViews[u.get('id')] = view;\r\n rows.push(view.render().el);\r\n });\r\n\r\n this.$('table tbody').append(rows);\r\n },\r\n\r\n\r\n updateControls: function () {\r\n this.updateControlsForSelection();\r\n this.updateAutoAssignButton();\r\n this.updateStatus();\r\n },\r\n\r\n updateStatus: function () {\r\n var incompleteWorlds = this.worlds.getIncompleteWorldsCount();\r\n var unassignedUsers = this.users.getUnassignedUsersCount();\r\n var totalWorlds = this.worlds.size();\r\n\r\n var usersText = 'All users have been assigned.';\r\n if (unassignedUsers) {\r\n usersText = unassignedUsers === 1 ? '1 user needs assignment.' : unassignedUsers + ' users need assignment.';\r\n }\r\n var worldsText = 'All worlds are complete.';\r\n if (!totalWorlds) {\r\n worldsText = 'No worlds have been created.';\r\n } else if (incompleteWorlds) {\r\n worldsText = incompleteWorlds === 1 ? '1 incomplete world needs attention.' : incompleteWorlds + ' incomplete worlds need attention.';\r\n }\r\n\r\n this.$('#users-status .text').text(usersText);\r\n this.$('#worlds-status .text').text(worldsText);\r\n\r\n if (unassignedUsers) {\r\n this.$('#users-status').addClass('incomplete');\r\n } else {\r\n this.$('#users-status').removeClass('incomplete');\r\n }\r\n\r\n if (incompleteWorlds || !totalWorlds) {\r\n this.$('#worlds-status').addClass('incomplete');\r\n } else {\r\n this.$('#worlds-status').removeClass('incomplete');\r\n }\r\n\r\n this.$('.status-widget').addClass('visible');\r\n },\r\n\r\n updateControlsForSelection: function () {\r\n var numSelected = this.$('tbody :checkbox:checked').length;\r\n this.$('.component.controls')[numSelected ? 'addClass' : 'removeClass']('visible');\r\n },\r\n\r\n updateAutoAssignButton: function () {\r\n\r\n if (this.project.isDynamicAssignment()) {\r\n var hasRoles = this.project.hasRoles();\r\n this.$('.table-controls .single').hide();\r\n this.$('.table-controls .dynamic').show();\r\n this.$('.table-controls .dynamic-no-roles-text')[hasRoles ? 'hide' : 'show']();\r\n this.$('.table-controls .no-roles')[hasRoles ? 'hide' : 'show']();\r\n } else {\r\n this.$('.table-controls .dynamic').hide();\r\n this.$('.table-controls .dynamic-no-roles-text').hide();\r\n this.$('.table-controls .single').show();\r\n this.$('.table-controls .no-roles').show();\r\n\r\n }\r\n\r\n if (this.users.allUsersAssigned()) {\r\n this.$('.table-controls').removeClass('visible');\r\n } else {\r\n this.$('.table-controls').addClass('visible');\r\n }\r\n },\r\n\r\n selectAll: function (e) {\r\n this.$('tbody :checkbox').prop('checked', e.target.checked);\r\n this.updateControls();\r\n },\r\n\r\n toggleControlls: function (e) {\r\n var total = this.$('tbody :checkbox');\r\n var checked = this.$('tbody :checkbox:checked');\r\n\r\n if (total.length === checked.length) {\r\n this.$('#select-all').attr('checked', 'checked');\r\n } else {\r\n this.$('#select-all').removeAttr('checked');\r\n }\r\n\r\n this.updateControls();\r\n },\r\n\r\n _showUpdating: function () {\r\n this.$el.css({ opacity: 0.4 });\r\n },\r\n\r\n _hideUpdating: function () {\r\n this.$el.css({ opacity: 1 });\r\n }\r\n\r\n};\r\n\r\nmodule.exports = Assignment;\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/assignment.js","'use strict';\r\n\r\nvar classFrom = require('../../../util/inherit');\r\n\r\nvar Model = require('./user-model');\r\nvar Base = require('./base-collection');\r\nvar env = require('./defaults');\r\nvar serviceLocator = require('./service-locator');\r\n\r\n\r\nmodule.exports = classFrom(Base, {\r\n model: Model,\r\n\r\n sortFn: function (a, b) {\r\n var aw = a.get('world').toLowerCase();\r\n var bw = b.get('world').toLowerCase();\r\n if (aw !== bw) {\r\n return aw < bw ? -1 : 1;\r\n }\r\n\r\n return b.get('userName') > a.get('userName') ? -1 : 1;\r\n },\r\n\r\n initialize: function () {\r\n const am = new F.manager.AuthManager();\r\n const session = am.getCurrentUserSessionInfo();\r\n const token = session.auth_token;\r\n if (token) {\r\n $.ajaxSetup({\r\n headers: {\r\n Authorization: 'Bearer ' + token\r\n }\r\n });\r\n }\r\n },\r\n\r\n allUsersAssigned: function () {\r\n return this.all(function (u) {\r\n return !!u.get('world');\r\n });\r\n },\r\n\r\n getUnassignedUsersCount: function () {\r\n return this.filter(function (u) {\r\n return !u.get('world');\r\n }).length;\r\n },\r\n\r\n fetch: function () {\r\n var dtd = $.Deferred();\r\n var me = this;\r\n var groupId = env.get().groupId;\r\n\r\n var getGroupUsers = function () {\r\n var memberApi = serviceLocator.memberApi();\r\n var userApi = serviceLocator.userApi();\r\n\r\n var loadGroupMembers = function () {\r\n return memberApi.getGroupDetails();\r\n };\r\n\r\n var splitIdChunks = function (userIds) {\r\n var idGroupSize = 100;\r\n var idGroups = [];\r\n while (userIds.length >= idGroupSize) {\r\n idGroups.push(userIds.splice(0, idGroupSize));\r\n }\r\n\r\n if (userIds.length) {\r\n idGroups.push(userIds);\r\n }\r\n\r\n return idGroups;\r\n };\r\n\r\n var loadUsersInfo = function (group) {\r\n var nonFacAndActive = function (u) { return u.active && u.role !== 'facilitator'; };\r\n const endUsers = group.members.filter((m)=> nonFacAndActive(m));\r\n const endUserIds = endUsers.map((u)=> u.userId);\r\n var chunkedUsers = splitIdChunks(endUserIds);\r\n var chunkedPromises = chunkedUsers.map(function (users) {\r\n return userApi.get({ id: users });\r\n });\r\n return $.when.apply($, chunkedPromises).then(function (userGroups) {\r\n var totalUsers = userGroups.reduce(function (acc, userGroup) {\r\n return acc.concat(userGroup);\r\n }, []);\r\n\r\n return totalUsers;\r\n });\r\n };\r\n\r\n return loadGroupMembers()\r\n .then(loadUsersInfo)\r\n .fail(dtd.reject);\r\n };\r\n\r\n getGroupUsers()\r\n .then(function (users) {\r\n users = users.map(function (u) { return $.extend(u, { groupId: groupId }); });\r\n me.set(users);\r\n dtd.resolve(users);\r\n });\r\n\r\n return dtd.promise();\r\n }\r\n\r\n});\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/users-collection.js","'use strict';\r\n\r\nvar classFrom = require('../../../util/inherit');\r\nvar Model = require('./world-model');\r\nvar UserModel = require('./user-model');\r\nvar serviceLocator = require('./service-locator');\r\n\r\nvar Base = require('./base-collection');\r\nvar __super = Base.prototype;\r\n\r\nvar doneFn = function (dtd, after) {\r\n return _.after(after, dtd.resolve);\r\n};\r\n\r\nvar worldApi;\r\n\r\nmodule.exports = classFrom(Base, {\r\n model: Model,\r\n\r\n initialize: function () {\r\n __super.initialize.apply(this, arguments);\r\n worldApi = serviceLocator.worldApi();\r\n },\r\n\r\n autoAssignAll: function (options) {\r\n return worldApi.autoAssign(options)\r\n .then(function (worlds) {\r\n this.reset(this.parse(worlds));\r\n }.bind(this));\r\n },\r\n\r\n getIncompleteWorldsCount: function () {\r\n return this.filter(function (w) {\r\n return !w.get('complete');\r\n }).length;\r\n },\r\n\r\n updateUser: function (user) {\r\n var worldName = user.get('world');\r\n var dtd = $.Deferred();\r\n var prevWorld = this.getWorldByUser(user);\r\n var curWorld = this.getOrCreateWorld(worldName);\r\n var done = doneFn(dtd, 1);\r\n\r\n // check if there's anything to do\r\n if (!prevWorld && !curWorld) {\r\n return dtd.resolve().promise();\r\n }\r\n\r\n if (prevWorld && curWorld && prevWorld.get('id') === curWorld.get('id')) {\r\n //worlds are the same, but role changed\r\n return curWorld.updateUser(user);\r\n }\r\n if (prevWorld) {\r\n prevWorld.removeUser(user)\r\n .then(function () {\r\n if (curWorld) {\r\n return curWorld.addUser(user);\r\n }\r\n })\r\n .then(done);\r\n } else if (curWorld) {\r\n curWorld.addUser(user)\r\n .then(done);\r\n }\r\n\r\n return dtd.promise();\r\n },\r\n\r\n getOrCreateWorld: function (worldName) {\r\n if (!worldName) {\r\n return;\r\n }\r\n\r\n var world = this.getWordByName(worldName);\r\n\r\n if (!world) {\r\n world = this.create({ name: worldName });\r\n }\r\n\r\n return world;\r\n },\r\n\r\n getWordByName: function (worldName) {\r\n return this.find(function (world) {\r\n return world.get('name') === worldName;\r\n });\r\n },\r\n\r\n getWorldByUser: function (user) {\r\n if (!user.get) {\r\n throw new Error('getWorldByUser expectes a model (' + user + ')');\r\n }\r\n\r\n var id = user.get('id');\r\n return this.getWorldByUserId(id);\r\n },\r\n\r\n getWorldByUserId: function (userId) {\r\n return this.find(function (world) {\r\n return _.find(world.get('users'), function (u) {\r\n return u.get('id') === userId;\r\n });\r\n });\r\n },\r\n\r\n getWorldNames: function () {\r\n return this.pluck('name').sort();\r\n },\r\n\r\n getNextWorldName: function () {\r\n var pad = function (num, places) {\r\n var zeros = '000000000000000000';\r\n var digits = num.toString().length;\r\n var needed = places - digits;\r\n return zeros.substr(0, needed) + num;\r\n };\r\n\r\n var worlds = this.getWorldNames();\r\n\r\n if (!worlds.length) {\r\n return 'World001';\r\n }\r\n\r\n var properNames = _.filter(worlds, function (w) { return (/World\\d\\d\\d/).test(w); }).sort();\r\n var lastWorld = properNames[properNames.length - 1];\r\n var numWorld = +lastWorld.match(/World(\\d\\d\\d)/)[1];\r\n var placesToPad = 3;\r\n return 'World' + pad(numWorld + 1, placesToPad);\r\n },\r\n\r\n setUsersCollection: function (usersCollection) {\r\n this.usersCollection = usersCollection;\r\n },\r\n\r\n joinUsers: function () {\r\n var usersHash = {};\r\n var usersCollection = this.usersCollection;\r\n usersCollection.each(function (u) {\r\n u.set({ isWorldComplete: true });\r\n return (usersHash[u.get('id')] = u);\r\n });\r\n\r\n this.each((w, i)=> {\r\n var name = w.get('name');\r\n var isComplete = w.get('complete');\r\n w.set({ index: i, name: name || (i + 1) + '' });\r\n _.each(w.get('users'), function (u) {\r\n if (usersHash[u.get('userId')]) {\r\n usersHash[u.get('userId')].set({ world: name, role: u.get('role'), isWorldComplete: isComplete });\r\n }\r\n });\r\n });\r\n\r\n usersCollection.sort();\r\n },\r\n\r\n fetch: function () {\r\n return worldApi.list()\r\n .then(function (worlds) {\r\n this.reset(this.parse(worlds));\r\n }.bind(this));\r\n },\r\n\r\n parse: function (worlds) {\r\n if (worlds.length) {\r\n worlds = _.map(worlds, function (w) {\r\n var users = _.map(w.users, function (u) {\r\n // in the world api users Ids comes as userId\r\n // make sure we add it as id so we can use the\r\n // same code to access models that come from the\r\n // member/local api as with the world api\r\n u.id = u.userId;\r\n return new UserModel(u);\r\n });\r\n\r\n w.users = users;\r\n\r\n return w;\r\n });\r\n }\r\n\r\n return worlds;\r\n }\r\n});\r\n\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/worlds-collection.js","'use strict';\r\nvar serviceLocator = require('./service-locator');\r\nvar classFrom = require('../../../util/inherit');\r\nvar Base = require('./base-model');\r\nvar __super = Base.prototype;\r\n\r\nmodule.exports = classFrom(Base, {\r\n\r\n defaults: {\r\n users: null,\r\n model: 'model.eqn'\r\n },\r\n\r\n initialize: function () {\r\n __super.initialize.apply(this, arguments);\r\n\r\n this._data.users = this._data.users || [];\r\n\r\n this._worldApi = serviceLocator.worldApi();\r\n\r\n var id = this.get('id');\r\n if (id) {\r\n this._worldApi.updateConfig({ filter: id });\r\n }\r\n },\r\n\r\n updateUser: function (user) {\r\n if (!user) {\r\n throw new Error('updateUser: No user passed to update');\r\n }\r\n const userObj = user.toJSON();\r\n userObj.userId = userObj.id;\r\n return this._worldApi.updateUser(userObj, { id: this.get('id') });\r\n },\r\n\r\n addUser: function (user) {\r\n var users = this.get('users');\r\n users.push(user);\r\n\r\n return this.save();\r\n },\r\n\r\n removeUser: function (user) {\r\n var id = this.get('id');\r\n var checkWorld = function () {\r\n if (!this.get('users').length) {\r\n this.remove();\r\n return this._worldApi.updateConfig({ filter: id }).delete();\r\n }\r\n }.bind(this);\r\n\r\n _.remove(this.get('users'), function (u) {\r\n return u.get('id') === user.get('id');\r\n });\r\n\r\n return this._worldApi\r\n .updateConfig({ filter: id })\r\n .removeUser({ userId: user.get('id') })\r\n .then(checkWorld);\r\n },\r\n\r\n save: function () {\r\n var me = this;\r\n var mapUsers = function () {\r\n return _.map(this.get('users'), function (u) {\r\n var res = { userId: u.get('id') };\r\n var role = u.get('role');\r\n\r\n if (role) {\r\n res.role = role;\r\n }\r\n\r\n return res;\r\n });\r\n }.bind(this);\r\n\r\n var createWorld = _.partial(this._worldApi.create, this.pick(['model', 'name', 'minUsers']));\r\n var addUsers = _.partial(me._worldApi.addUsers, mapUsers(), { filter: me.get('id') });\r\n var savedUsers = this.get('users');\r\n if (this.isNew()) {\r\n // we need to create the world in the API and then add the users\r\n return createWorld()\r\n .then(function (world) {\r\n me.set(world);\r\n me._worldApi.updateConfig({ filter: world.id });\r\n })\r\n .then(addUsers)\r\n .then(function (users) {\r\n // since we re-set the world, re-set the users\r\n me.set('users', savedUsers);\r\n });\r\n } else {\r\n // the world is already created just add the users\r\n return addUsers();\r\n }\r\n },\r\n\r\n isNew: function () {\r\n return !this.get('lastModified');\r\n }\r\n\r\n});\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/world-model.js","'use strict';\n\nvar serviceLocator = require('./service-locator');\n\nvar classFrom = require('../../../util/inherit');\nvar Base = require('./base-model');\n// var __super = Base.prototype;\n\nmodule.exports = classFrom(Base, {\n\n isDynamicAssignment: function () {\n return this.get('worlds') === 'dynamic';\n },\n\n hasRoles: function () {\n var roles = this.get('roles');\n return roles && !!roles.length;\n },\n\n fetch: function () {\n var api = serviceLocator.worldApi();\n\n return api.getProjectSettings().then(function (settings) {\n this.set(settings);\n }.bind(this));\n }\n});\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/project-model.js","const userRowTemplate = `\r\n \"\r\n <%= !isWorldComplete ? '' : '' %>\r\n <%= world %>\r\n <%= role %>\r\n <%= lastName %>\r\n <%= userName %>\r\n <%= !world ? '' : '' %>\r\n \r\n`.trim();\r\nconst editUserRowTemplate = `\r\n \"\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <%= lastName %>\r\n <%= userName %>\r\n <%= !world ? '' : '' %>\r\n \r\n \r\n \r\n \r\n`;\r\n\r\nvar AssignmentRow = function (options) {\r\n this.$el = $('');\r\n this.el = this.$el[0];\r\n this.$ = _.partialRight($, this.$el);\r\n\r\n this.model = options.model;\r\n this.options = options;\r\n this.worlds = options.worlds;\r\n this.project = options.project;\r\n\r\n _.bindAll(this, ['setEditMode', 'removeEditMode', 'saveEdit', 'cancelEdit', 'updateData']);\r\n\r\n this.bindEvents();\r\n\r\n};\r\n\r\n_.extend(AssignmentRow.prototype, {\r\n\r\n template: _.template(userRowTemplate),\r\n editTemplate: _.template(editUserRowTemplate),\r\n\r\n bindEvents: function () {\r\n this.$el.on('click', 'button.edit', this.setEditMode);\r\n this.$el.on('click', 'button.save', this.saveEdit);\r\n this.$el.on('click', 'button.cancel', this.cancelEdit);\r\n },\r\n\r\n remove: function () {\r\n this.$el.off('click', null, null);\r\n // this only gives a delay to remove the tr\r\n // animation of height of the tr does not work\r\n this.$(':checkbox').attr('checked', false);\r\n this.$el\r\n .css({ opacity: 0.3 })\r\n .animate({ height: 0 }, {\r\n duration: 300,\r\n complete: function () {\r\n this.remove();\r\n }\r\n });\r\n },\r\n\r\n makeInactive: function () {\r\n return this.model.makeInactive();\r\n },\r\n\r\n setEditMode: function () {\r\n this.model.set('edit-mode', true);\r\n this.render();\r\n },\r\n\r\n removeEditMode: function () {\r\n this.model.set('edit-mode', false);\r\n this.render();\r\n },\r\n\r\n saveEdit: function () {\r\n var me = this;\r\n this.updateData();\r\n this.worlds\r\n .updateUser(this.model)\r\n .then(function () {\r\n me.removeEditMode();\r\n me.$el.trigger('update', me);\r\n });\r\n },\r\n\r\n cancelEdit: function () {\r\n this.removeEditMode();\r\n },\r\n\r\n render: function () {\r\n var templ = this.model.get('edit-mode') ? this.editTemplate : this.template;\r\n var vm = _.extend({\r\n roles: this.project.get('roles'),\r\n optionalRoles: this.project.get('optionalRoles'),\r\n worlds: this.worlds.getWorldNames(),\r\n newWorld: this.worlds.getNextWorldName()\r\n }, this.model.toJSON());\r\n\r\n this.$el.html(templ(vm));\r\n\r\n return this;\r\n },\r\n\r\n updateData: function () {\r\n var me = this;\r\n this.$('[data-field]').each(function () {\r\n var el = $(this);\r\n var field = el.data('field');\r\n var val = el.val();\r\n\r\n me.model.set(field, val);\r\n });\r\n }\r\n});\r\n\r\n\r\nexport default AssignmentRow;\n\n\n// WEBPACK FOOTER //\n// ./src/components/assignment/js/assignment-row.js","'use strict';\r\n\r\n/**\r\n* Utility class to make ajax calls sequencial\r\n*/\r\nfunction AjaxQueue() {\r\n this.queue = [];\r\n}\r\n\r\n$.extend(AjaxQueue.prototype, {\r\n add: function (fn) {\r\n return this.queue.push(fn);\r\n },\r\n\r\n execute: function (context) {\r\n var dtd = $.Deferred();\r\n var me = this;\r\n context = context || this;\r\n\r\n function next() {\r\n if (me.queue.length) {\r\n var fn = me.queue.shift();\r\n\r\n fn.call(context)\r\n .then(next)\r\n .fail(dtd.reject);\r\n } else {\r\n dtd.resolve();\r\n }\r\n }\r\n\r\n next();\r\n\r\n return dtd.promise();\r\n }\r\n});\r\n\r\n\r\nmodule.exports = AjaxQueue;\n\n\n// WEBPACK FOOTER //\n// ./src/util/ajax-queue.js"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/components/assignment/index.html b/dist/components/assignment/index.html index e06e6549..3b7adfb7 100644 --- a/dist/components/assignment/index.html +++ b/dist/components/assignment/index.html @@ -1,94 +1,94 @@ - - - - - - Multiplayer World Assignment Component - - - - - - - - - -
-
-
- -
-
- - -
-
-
-
-
- - Automatically assign users - - - - - - - - - - - - -
-
-
- - -
- - - - - - - - - - - - - - -
WorldRoleNameUsernameUnassigned
-
- -
-
-
- - - - - - + + + + + + Multiplayer World Assignment Component + + + + + + + + + +
+
+
+ +
+
+ + +
+
+
+
+
+ + Automatically assign users + + + + + + + + + + + + +
+
+
+ + +
+ + + + + + + + + + + + + + +
WorldRoleNameUsernameUnassigned
+
+ +
+
+
+ + + + + + diff --git a/dist/components/login/login.css b/dist/components/login/login.css index f0f61a3a..4fe8f4f5 100644 --- a/dist/components/login/login.css +++ b/dist/components/login/login.css @@ -1,291 +1,291 @@ -/* - General Styles -*/ - -body { - background-color: rgb(252, 254, 255); - color: rgb(87, 87, 94); - - font-family: "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif; - font-size: 14px; - line-height: 1.618; -} - -/* - Login Form Styles -*/ - -#login { - margin: 0 auto; - padding: 10% 40px; -} - -#login h4 { - font-size: 19px; -} - -@media all and (max-width: 899px) { - #login { - width: 560px; - } -} - -@media all and (min-width: 900px) { - #login { - width: 50%; - } -} - -.control label { - display: inline-block; - margin-bottom: 5px; - - font-weight: 600; -} - -.form-control { - display: block; - height: 33px; - width: 100%; - padding: 6px 12px; - border: 1px solid rgb(204, 204, 204); - border-radius: 3px; - - color: rgb(87, 87, 94); - background-color: rgb(252, 254, 255); - background-image: none; - - font-size: 12px; - line-height: 1.618; - - -webkit-box-shadow: none; - -moz-box-shadow: none; - box-shadow: none; - - -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - -moz-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; -} - -.alert { - margin-top: 20px; - border-radius: 2px; - - text-align: center; -} - -/* - Buttons -*/ - -.btn { - position: relative; - vertical-align: middle; - - border: 1px solid rgb(76, 148, 255); - border-radius: 20px; - display: inline-block; - overflow: hidden; - margin-bottom: 0; - padding: 6px 24px; - - background-color: transparent; - color: rgb(76, 148, 255); - - font-size: 14px; - font-weight: normal; - text-align: center; - text-decoration: none; - white-space: nowrap; - - cursor: pointer; - - -webkit-transition: all 0.3s; - -moz-transition: all 0.3s; - transition: all 0.3s; - - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; -} - -.btn.disabled, -.btn[disabled], -.btn.disabled:hover, -.btn[disabled]:hover { - background-color: rgb(187, 187, 194); - border-color: rgb(187, 187, 194); - color: rgb(245, 248, 249); -} - -.btn-primary { - border: 1px solid rgb(76, 148, 255); - color: rgb(76, 148, 255); -} - -.btn-primary:hover, -.btn-primary:active { - background-color: rgb(76, 148, 255); - border-color: rgb(76, 148, 255); - color: rgb(245, 248, 249); - - outline: none; -} - -.btn-signin { - border: 1px solid rgb(83, 193, 101); - color: rgb(83, 193, 101); -} - -.btn-signin:hover, -.btn-signin:active { - background-color: rgb(83, 193, 101); - border-color: rgb(83, 193, 101); - color: rgb(245, 248, 249); - - outline: none; -} - -.btn:active, -.btn:focus { - outline: none; -} - -/* - Group Selection Popup Styles -*/ - -.group-selection-dialog { - display: none; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - z-index: 9999; - background-color: rgba(252, 254, 255, 0.6); - -} - -.group-selection-dialog .panel { - opacity: 1; - position: absolute; - left: 50%; - top: 25%; - transform: translate(-50%, -50%); - -webkit-transform: translate(-50%, -50%); - -moz--transform: translate(-50%, -50%); - -ms-transform: translate(-50%, -50%); - border: solid 1px rgb(187, 187, 194); - border-radius: 4px; - background-color: rgb(252, 254, 255); - box-shadow: 0px 0px 10px rgba(86, 86, 93, 0.4); -} - -@media all and (max-width: 899px) { - .group-selection-dialog .panel { - width: 400px; - } -} - -@media all and (min-width: 900px) { - .group-selection-dialog .panel { - width: 50%; - } -} - -.group-selection-dialog .panel > div { - padding: 8px 15px; -} - -.group-selection-dialog .panel > .panel-heading { - margin-bottom: 10px; - background-color: rgb(76, 148, 255); - font-size: 14px; -} - -.group-selection-dialog .panel-title { - color: rgb(252, 254, 255); -} - -.group-selection-dialog .close { - position: absolute; - right: 15px; - top: 10px; - - display: inline-block; - height: 20px; - width: 20px; - opacity: 1; - - cursor: pointer; - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -ms-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); -} - -.group-selection-dialog .close::before { - content: ""; - position: absolute; - left: 9px; - - height: 20px; - width: 2px; - - background: rgb(252, 254, 255); -} - -.group-selection-dialog .close::after { - content: ""; - position: absolute; - left: 0; - top: 9px; - - height: 2px; - width: 20px; - - background: rgb(252, 254, 255); -} - -.group-selection-dialog select { - height: 34px; - font-size: 14px; - width: 100% !important; -} - -.group-selection-dialog .panel > .panel-footer { - background-color: transparent; - border-color: transparent; - margin-top: 20px; - padding-bottom: 16px; - text-align: right; -} - -/* - Misc Styles -*/ - -.powered-by { - height: 20px; - width: 100%; - position: absolute; - bottom: 20px; - right: 0px; - background-image: url('https://s3.amazonaws.com/cdn-common.forio.com/marketing/Epicenter/common/made-with-epicenter.png'); - background-size: contain; - background-repeat: no-repeat; - background-position: 50%; - -} - -.error-text { - display: none; -} -.has-error .error-text { - display: block; +/* + General Styles +*/ + +body { + background-color: rgb(252, 254, 255); + color: rgb(87, 87, 94); + + font-family: "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif; + font-size: 14px; + line-height: 1.618; +} + +/* + Login Form Styles +*/ + +#login { + margin: 0 auto; + padding: 10% 40px; +} + +#login h4 { + font-size: 19px; +} + +@media all and (max-width: 899px) { + #login { + width: 560px; + } +} + +@media all and (min-width: 900px) { + #login { + width: 50%; + } +} + +.control label { + display: inline-block; + margin-bottom: 5px; + + font-weight: 600; +} + +.form-control { + display: block; + height: 33px; + width: 100%; + padding: 6px 12px; + border: 1px solid rgb(204, 204, 204); + border-radius: 3px; + + color: rgb(87, 87, 94); + background-color: rgb(252, 254, 255); + background-image: none; + + font-size: 12px; + line-height: 1.618; + + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; + + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + -moz-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} + +.alert { + margin-top: 20px; + border-radius: 2px; + + text-align: center; +} + +/* + Buttons +*/ + +.btn { + position: relative; + vertical-align: middle; + + border: 1px solid rgb(76, 148, 255); + border-radius: 20px; + display: inline-block; + overflow: hidden; + margin-bottom: 0; + padding: 6px 24px; + + background-color: transparent; + color: rgb(76, 148, 255); + + font-size: 14px; + font-weight: normal; + text-align: center; + text-decoration: none; + white-space: nowrap; + + cursor: pointer; + + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + transition: all 0.3s; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} + +.btn.disabled, +.btn[disabled], +.btn.disabled:hover, +.btn[disabled]:hover { + background-color: rgb(187, 187, 194); + border-color: rgb(187, 187, 194); + color: rgb(245, 248, 249); +} + +.btn-primary { + border: 1px solid rgb(76, 148, 255); + color: rgb(76, 148, 255); +} + +.btn-primary:hover, +.btn-primary:active { + background-color: rgb(76, 148, 255); + border-color: rgb(76, 148, 255); + color: rgb(245, 248, 249); + + outline: none; +} + +.btn-signin { + border: 1px solid rgb(83, 193, 101); + color: rgb(83, 193, 101); +} + +.btn-signin:hover, +.btn-signin:active { + background-color: rgb(83, 193, 101); + border-color: rgb(83, 193, 101); + color: rgb(245, 248, 249); + + outline: none; +} + +.btn:active, +.btn:focus { + outline: none; +} + +/* + Group Selection Popup Styles +*/ + +.group-selection-dialog { + display: none; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 9999; + background-color: rgba(252, 254, 255, 0.6); + +} + +.group-selection-dialog .panel { + opacity: 1; + position: absolute; + left: 50%; + top: 25%; + transform: translate(-50%, -50%); + -webkit-transform: translate(-50%, -50%); + -moz--transform: translate(-50%, -50%); + -ms-transform: translate(-50%, -50%); + border: solid 1px rgb(187, 187, 194); + border-radius: 4px; + background-color: rgb(252, 254, 255); + box-shadow: 0px 0px 10px rgba(86, 86, 93, 0.4); +} + +@media all and (max-width: 899px) { + .group-selection-dialog .panel { + width: 400px; + } +} + +@media all and (min-width: 900px) { + .group-selection-dialog .panel { + width: 50%; + } +} + +.group-selection-dialog .panel > div { + padding: 8px 15px; +} + +.group-selection-dialog .panel > .panel-heading { + margin-bottom: 10px; + background-color: rgb(76, 148, 255); + font-size: 14px; +} + +.group-selection-dialog .panel-title { + color: rgb(252, 254, 255); +} + +.group-selection-dialog .close { + position: absolute; + right: 15px; + top: 10px; + + display: inline-block; + height: 20px; + width: 20px; + opacity: 1; + + cursor: pointer; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} + +.group-selection-dialog .close::before { + content: ""; + position: absolute; + left: 9px; + + height: 20px; + width: 2px; + + background: rgb(252, 254, 255); +} + +.group-selection-dialog .close::after { + content: ""; + position: absolute; + left: 0; + top: 9px; + + height: 2px; + width: 20px; + + background: rgb(252, 254, 255); +} + +.group-selection-dialog select { + height: 34px; + font-size: 14px; + width: 100% !important; +} + +.group-selection-dialog .panel > .panel-footer { + background-color: transparent; + border-color: transparent; + margin-top: 20px; + padding-bottom: 16px; + text-align: right; +} + +/* + Misc Styles +*/ + +.powered-by { + height: 20px; + width: 100%; + position: absolute; + bottom: 20px; + right: 0px; + background-image: url('https://s3.amazonaws.com/cdn-common.forio.com/marketing/Epicenter/common/made-with-epicenter.png'); + background-size: contain; + background-repeat: no-repeat; + background-position: 50%; + +} + +.error-text { + display: none; +} +.has-error .error-text { + display: block; } \ No newline at end of file diff --git a/dist/components/login/login.html b/dist/components/login/login.html index 4319e700..547308b4 100644 --- a/dist/components/login/login.html +++ b/dist/components/login/login.html @@ -1,65 +1,65 @@ - - - - - - - - - - - - - - - - - - - - - - - -
-
-

Please Login to this Simulation

-
-
- - -
-
- - -
- - - - - -
- -
- - -
-
-
- - + + + + + + + + + + + + + + + + + + + + + + + +
+
+

Please Login to this Simulation

+
+
+ + +
+
+ + +
+ + + + + +
+ +
+ + +
+
+
+ + diff --git a/dist/components/login/login.js b/dist/components/login/login.js index c9b87769..c24ae2d4 100644 --- a/dist/components/login/login.js +++ b/dist/components/login/login.js @@ -1,171 +1,171 @@ -$(function () { - 'use strict'; - - var groupSelectionTemplate; - - var showError = function (msg) { - $('#login-message').text(msg).show(); - }; - - var getAccountProjectFromUrl = function () { - var url = window.location.href; - var parts = url.match(/https?:\/\/([^/]*)\/app\/([^/]*)\/([^/]*)/) || []; - return { - account: parts[2], - project: parts[3], //eslint-disable-line - }; - }; - - var selectGroup = function (userName, password, account, project, groups, action) { - var dlg = (dlg = $('.group-selection-dialog')).length ? dlg : $(groupSelectionTemplate).appendTo($('body')); //eslint-disable-line - dlg.attr('action', action); - var select = $('#login-group', dlg); - select.find('[value!=""]').remove(); - $.each(groups, function () { - $('