{"action":"created","comment":{"url":"https://api.github.com/repos/oppia/oppia/pulls/comments/51783064","id":51783064,"diff_hunk":"@@ -0,0 +1,213 @@\n+// Copyright 2015 The Oppia Authors. All Rights Reserved.\n+//\n+// Licensed under the Apache License, Version 2.0 (the \"License\");\n+// you may not use this file except in compliance with the License.\n+// You may obtain a copy of the License at\n+//\n+//      http://www.apache.org/licenses/LICENSE-2.0\n+//\n+// Unless required by applicable law or agreed to in writing, software\n+// distributed under the License is distributed on an \"AS-IS\" BASIS,\n+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+// See the License for the specific language governing permissions and\n+// limitations under the License.\n+\n+/**\n+ * @fileoverview Primary controller for the collection editor page.\n+ *\n+ * @author mgowano@google.com (Abraham Mgowano)\n+ */\n+\n+// TODO(bhenning): These constants should be provided by the backend.\n+oppia.constant(\n+  'COLLECTION_DATA_URL', '/collection_handler/data/<collection_id>');\n+oppia.constant(\n+  'WRITABLE_COLLECTION_DATA_URL', '/collection_editor/data/<collection_id>');\n+\n+oppia.controller('CollectionEditor', ['$scope', 'CollectionBackendApiService',\n+  'WritableCollectionBackendApiService', 'CollectionUpdateService',\n+  'warningsData', function(\n+    $scope, CollectionBackendApiService, WritableCollectionBackendApiService,\n+    CollectionUpdateService, warningsData) {\n+    $scope.collection = null;\n+    $scope.collectionId = GLOBALS.collectionId;\n+    $scope.collectionSkills = null;\n+\n+    // Get the id of the collection to be loaded\n+    var pathnameArray = window.location.pathname.split('/');\n+    for (var i = 0; i < pathnameArray.length; i++) {\n+      if (pathnameArray[i] === 'create') {\n+        $scope.collectionId = pathnameArray[i + 1];\n+        break;\n+      }\n+    }\n+\n+    // Load the collection to be edited.\n+    CollectionBackendApiService.loadCollection($scope.collectionId).then(\n+      function(collection) {\n+        $scope.collection = collection;\n+        $scope.collectionSkills = collection.skills;\n+      }, function(error) {\n+        // TODO(mgowano): Handle not being able to load the collection.\n+        warningsData.addWarning(\n+          error || 'There was an error loading the collection.');\n+      });\n+\n+    var _arrayContainsCaseInsensitive = function(array, element) {\n+      var lowerElement = element.toLowerCase();\n+      for (var i = 0; i < array.length; i++) {\n+        if (array[i].toLowerCase() === lowerElement) {\n+          return true;\n+        }\n+      }\n+      return false;\n+    };\n+\n+    var _getCollectionNodeForExplorationId = function(explorationId) {\n+      for (var i = 0; i < $scope.collection.nodes.length; i++) {\n+        var collectionNode = $scope.collection.nodes[i];\n+        if (collectionNode.exploration_id == explorationId) {\n+          return collectionNode;\n+        }\n+      }\n+      return null;\n+    };\n+\n+    // Stores a pending list of changes.\n+    $scope.changeList = [];\n+\n+    $scope.addChange = function(change) {\n+      $scope.changeList.push(change);\n+    };\n+\n+    // TODO(mgowano): Handle a case where adding a pre-requisite skill\n+    // will result into having all exploration requiring pre-requisite\n+    // skills. At the moment this is only handled when a change is committed\n+    // to the backend.\n+    $scope.addPrerequisiteSkill = function(skillName, expId) {\n+      if (skillName && expId) {\n+        var collectionNode = _getCollectionNodeForExplorationId(expId);\n+        var prerequisiteSkills = collectionNode.prerequisite_skills;\n+        if (!_arrayContainsCaseInsensitive(prerequisiteSkills, skillName)) {\n+          prerequisiteSkills.push(skillName);\n+          return true;\n+        }\n+      }\n+      return false;\n+    };\n+\n+    // TODO(mgowano): Handle cases where deleting a pre-requisite skill results\n+    // to unreachable explorations.\n+    $scope.deletePrerequisiteSkill = function(skillIdx, expId) {","path":"core/templates/dev/head/collection_editor/CollectionEditor.js","position":101,"original_position":101,"commit_id":"546f0c7724c297788975a4525161e8a8350df377","original_commit_id":"546f0c7724c297788975a4525161e8a8350df377","user":{"login":"BenHenning","id":12983742,"avatar_url":"https://avatars.githubusercontent.com/u/12983742?v=3","gravatar_id":"","url":"https://api.github.com/users/BenHenning","html_url":"https://github.com/BenHenning","followers_url":"https://api.github.com/users/BenHenning/followers","following_url":"https://api.github.com/users/BenHenning/following{/other_user}","gists_url":"https://api.github.com/users/BenHenning/gists{/gist_id}","starred_url":"https://api.github.com/users/BenHenning/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BenHenning/subscriptions","organizations_url":"https://api.github.com/users/BenHenning/orgs","repos_url":"https://api.github.com/users/BenHenning/repos","events_url":"https://api.github.com/users/BenHenning/events{/privacy}","received_events_url":"https://api.github.com/users/BenHenning/received_events","type":"User","site_admin":false},"body":"Done.","created_at":"2016-02-03T20:36:22Z","updated_at":"2016-02-03T20:36:22Z","html_url":"https://github.com/oppia/oppia/pull/1433#discussion_r51783064","pull_request_url":"https://api.github.com/repos/oppia/oppia/pulls/1433","_links":{"self":{"href":"https://api.github.com/repos/oppia/oppia/pulls/comments/51783064"},"html":{"href":"https://github.com/oppia/oppia/pull/1433#discussion_r51783064"},"pull_request":{"href":"https://api.github.com/repos/oppia/oppia/pulls/1433"}}},"pull_request":{"url":"https://api.github.com/repos/oppia/oppia/pulls/1433","id":57408678,"html_url":"https://github.com/oppia/oppia/pull/1433","diff_url":"https://github.com/oppia/oppia/pull/1433.diff","patch_url":"https://github.com/oppia/oppia/pull/1433.patch","issue_url":"https://api.github.com/repos/oppia/oppia/issues/1433","number":1433,"state":"open","locked":false,"title":"Collection editor","user":{"login":"BenHenning","id":12983742,"avatar_url":"https://avatars.githubusercontent.com/u/12983742?v=3","gravatar_id":"","url":"https://api.github.com/users/BenHenning","html_url":"https://github.com/BenHenning","followers_url":"https://api.github.com/users/BenHenning/followers","following_url":"https://api.github.com/users/BenHenning/following{/other_user}","gists_url":"https://api.github.com/users/BenHenning/gists{/gist_id}","starred_url":"https://api.github.com/users/BenHenning/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BenHenning/subscriptions","organizations_url":"https://api.github.com/users/BenHenning/orgs","repos_url":"https://api.github.com/users/BenHenning/repos","events_url":"https://api.github.com/users/BenHenning/events{/privacy}","received_events_url":"https://api.github.com/users/BenHenning/received_events","type":"User","site_admin":false},"body":"These series of commits introduce the collection editor frontend and backend controllers. This is the MVP of the collection editor; it's fully functional and has an intentionally simplified UI.\r\n\r\nI have reviewed all of Abe's commits, though you are free to quickly glance over them if you'd like. I don't expect you to, but you might need to when reviewing other changes and, if you find anything, feel free to leave a comment. Please focus specifically on the commits I added, since those didn't go through a thorough review.\r\n\r\nAlso, the editor can be reached by going to the following URL with the development server:\r\n\r\n``localhost:8181/collection_editor/create/<exploration_id>``\r\n\r\nThanks!","created_at":"2016-01-27T19:20:42Z","updated_at":"2016-02-03T20:36:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"da5412454bab57c198a6ea3bd2907b9d1b872edf","assignee":{"login":"seanlip","id":10575562,"avatar_url":"https://avatars.githubusercontent.com/u/10575562?v=3","gravatar_id":"","url":"https://api.github.com/users/seanlip","html_url":"https://github.com/seanlip","followers_url":"https://api.github.com/users/seanlip/followers","following_url":"https://api.github.com/users/seanlip/following{/other_user}","gists_url":"https://api.github.com/users/seanlip/gists{/gist_id}","starred_url":"https://api.github.com/users/seanlip/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/seanlip/subscriptions","organizations_url":"https://api.github.com/users/seanlip/orgs","repos_url":"https://api.github.com/users/seanlip/repos","events_url":"https://api.github.com/users/seanlip/events{/privacy}","received_events_url":"https://api.github.com/users/seanlip/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/oppia/oppia/pulls/1433/commits","review_comments_url":"https://api.github.com/repos/oppia/oppia/pulls/1433/comments","review_comment_url":"https://api.github.com/repos/oppia/oppia/pulls/comments{/number}","comments_url":"https://api.github.com/repos/oppia/oppia/issues/1433/comments","statuses_url":"https://api.github.com/repos/oppia/oppia/statuses/546f0c7724c297788975a4525161e8a8350df377","head":{"label":"oppia:collection-editor","ref":"collection-editor","sha":"546f0c7724c297788975a4525161e8a8350df377","user":{"login":"oppia","id":11620230,"avatar_url":"https://avatars.githubusercontent.com/u/11620230?v=3","gravatar_id":"","url":"https://api.github.com/users/oppia","html_url":"https://github.com/oppia","followers_url":"https://api.github.com/users/oppia/followers","following_url":"https://api.github.com/users/oppia/following{/other_user}","gists_url":"https://api.github.com/users/oppia/gists{/gist_id}","starred_url":"https://api.github.com/users/oppia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oppia/subscriptions","organizations_url":"https://api.github.com/users/oppia/orgs","repos_url":"https://api.github.com/users/oppia/repos","events_url":"https://api.github.com/users/oppia/events{/privacy}","received_events_url":"https://api.github.com/users/oppia/received_events","type":"Organization","site_admin":false},"repo":{"id":40687563,"name":"oppia","full_name":"oppia/oppia","owner":{"login":"oppia","id":11620230,"avatar_url":"https://avatars.githubusercontent.com/u/11620230?v=3","gravatar_id":"","url":"https://api.github.com/users/oppia","html_url":"https://github.com/oppia","followers_url":"https://api.github.com/users/oppia/followers","following_url":"https://api.github.com/users/oppia/following{/other_user}","gists_url":"https://api.github.com/users/oppia/gists{/gist_id}","starred_url":"https://api.github.com/users/oppia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oppia/subscriptions","organizations_url":"https://api.github.com/users/oppia/orgs","repos_url":"https://api.github.com/users/oppia/repos","events_url":"https://api.github.com/users/oppia/events{/privacy}","received_events_url":"https://api.github.com/users/oppia/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/oppia/oppia","description":"Tool for collaboratively building intelligent tutors.","fork":false,"url":"https://api.github.com/repos/oppia/oppia","forks_url":"https://api.github.com/repos/oppia/oppia/forks","keys_url":"https://api.github.com/repos/oppia/oppia/keys{/key_id}","collaborators_url":"https://api.github.com/repos/oppia/oppia/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/oppia/oppia/teams","hooks_url":"https://api.github.com/repos/oppia/oppia/hooks","issue_events_url":"https://api.github.com/repos/oppia/oppia/issues/events{/number}","events_url":"https://api.github.com/repos/oppia/oppia/events","assignees_url":"https://api.github.com/repos/oppia/oppia/assignees{/user}","branches_url":"https://api.github.com/repos/oppia/oppia/branches{/branch}","tags_url":"https://api.github.com/repos/oppia/oppia/tags","blobs_url":"https://api.github.com/repos/oppia/oppia/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/oppia/oppia/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/oppia/oppia/git/refs{/sha}","trees_url":"https://api.github.com/repos/oppia/oppia/git/trees{/sha}","statuses_url":"https://api.github.com/repos/oppia/oppia/statuses/{sha}","languages_url":"https://api.github.com/repos/oppia/oppia/languages","stargazers_url":"https://api.github.com/repos/oppia/oppia/stargazers","contributors_url":"https://api.github.com/repos/oppia/oppia/contributors","subscribers_url":"https://api.github.com/repos/oppia/oppia/subscribers","subscription_url":"https://api.github.com/repos/oppia/oppia/subscription","commits_url":"https://api.github.com/repos/oppia/oppia/commits{/sha}","git_commits_url":"https://api.github.com/repos/oppia/oppia/git/commits{/sha}","comments_url":"https://api.github.com/repos/oppia/oppia/comments{/number}","issue_comment_url":"https://api.github.com/repos/oppia/oppia/issues/comments{/number}","contents_url":"https://api.github.com/repos/oppia/oppia/contents/{+path}","compare_url":"https://api.github.com/repos/oppia/oppia/compare/{base}...{head}","merges_url":"https://api.github.com/repos/oppia/oppia/merges","archive_url":"https://api.github.com/repos/oppia/oppia/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/oppia/oppia/downloads","issues_url":"https://api.github.com/repos/oppia/oppia/issues{/number}","pulls_url":"https://api.github.com/repos/oppia/oppia/pulls{/number}","milestones_url":"https://api.github.com/repos/oppia/oppia/milestones{/number}","notifications_url":"https://api.github.com/repos/oppia/oppia/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/oppia/oppia/labels{/name}","releases_url":"https://api.github.com/repos/oppia/oppia/releases{/id}","deployments_url":"https://api.github.com/repos/oppia/oppia/deployments","created_at":"2015-08-14T00:16:14Z","updated_at":"2016-02-03T01:29:05Z","pushed_at":"2016-02-03T17:47:18Z","git_url":"git://github.com/oppia/oppia.git","ssh_url":"git@github.com:oppia/oppia.git","clone_url":"https://github.com/oppia/oppia.git","svn_url":"https://github.com/oppia/oppia","homepage":"https://www.oppia.org","size":46213,"stargazers_count":73,"watchers_count":73,"language":"Python","has_issues":true,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":106,"mirror_url":null,"open_issues_count":263,"forks":106,"open_issues":263,"watchers":73,"default_branch":"develop"}},"base":{"label":"oppia:develop","ref":"develop","sha":"8967fa31917ce9f62e3bf415524b07d6859778fc","user":{"login":"oppia","id":11620230,"avatar_url":"https://avatars.githubusercontent.com/u/11620230?v=3","gravatar_id":"","url":"https://api.github.com/users/oppia","html_url":"https://github.com/oppia","followers_url":"https://api.github.com/users/oppia/followers","following_url":"https://api.github.com/users/oppia/following{/other_user}","gists_url":"https://api.github.com/users/oppia/gists{/gist_id}","starred_url":"https://api.github.com/users/oppia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oppia/subscriptions","organizations_url":"https://api.github.com/users/oppia/orgs","repos_url":"https://api.github.com/users/oppia/repos","events_url":"https://api.github.com/users/oppia/events{/privacy}","received_events_url":"https://api.github.com/users/oppia/received_events","type":"Organization","site_admin":false},"repo":{"id":40687563,"name":"oppia","full_name":"oppia/oppia","owner":{"login":"oppia","id":11620230,"avatar_url":"https://avatars.githubusercontent.com/u/11620230?v=3","gravatar_id":"","url":"https://api.github.com/users/oppia","html_url":"https://github.com/oppia","followers_url":"https://api.github.com/users/oppia/followers","following_url":"https://api.github.com/users/oppia/following{/other_user}","gists_url":"https://api.github.com/users/oppia/gists{/gist_id}","starred_url":"https://api.github.com/users/oppia/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oppia/subscriptions","organizations_url":"https://api.github.com/users/oppia/orgs","repos_url":"https://api.github.com/users/oppia/repos","events_url":"https://api.github.com/users/oppia/events{/privacy}","received_events_url":"https://api.github.com/users/oppia/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/oppia/oppia","description":"Tool for collaboratively building intelligent tutors.","fork":false,"url":"https://api.github.com/repos/oppia/oppia","forks_url":"https://api.github.com/repos/oppia/oppia/forks","keys_url":"https://api.github.com/repos/oppia/oppia/keys{/key_id}","collaborators_url":"https://api.github.com/repos/oppia/oppia/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/oppia/oppia/teams","hooks_url":"https://api.github.com/repos/oppia/oppia/hooks","issue_events_url":"https://api.github.com/repos/oppia/oppia/issues/events{/number}","events_url":"https://api.github.com/repos/oppia/oppia/events","assignees_url":"https://api.github.com/repos/oppia/oppia/assignees{/user}","branches_url":"https://api.github.com/repos/oppia/oppia/branches{/branch}","tags_url":"https://api.github.com/repos/oppia/oppia/tags","blobs_url":"https://api.github.com/repos/oppia/oppia/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/oppia/oppia/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/oppia/oppia/git/refs{/sha}","trees_url":"https://api.github.com/repos/oppia/oppia/git/trees{/sha}","statuses_url":"https://api.github.com/repos/oppia/oppia/statuses/{sha}","languages_url":"https://api.github.com/repos/oppia/oppia/languages","stargazers_url":"https://api.github.com/repos/oppia/oppia/stargazers","contributors_url":"https://api.github.com/repos/oppia/oppia/contributors","subscribers_url":"https://api.github.com/repos/oppia/oppia/subscribers","subscription_url":"https://api.github.com/repos/oppia/oppia/subscription","commits_url":"https://api.github.com/repos/oppia/oppia/commits{/sha}","git_commits_url":"https://api.github.com/repos/oppia/oppia/git/commits{/sha}","comments_url":"https://api.github.com/repos/oppia/oppia/comments{/number}","issue_comment_url":"https://api.github.com/repos/oppia/oppia/issues/comments{/number}","contents_url":"https://api.github.com/repos/oppia/oppia/contents/{+path}","compare_url":"https://api.github.com/repos/oppia/oppia/compare/{base}...{head}","merges_url":"https://api.github.com/repos/oppia/oppia/merges","archive_url":"https://api.github.com/repos/oppia/oppia/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/oppia/oppia/downloads","issues_url":"https://api.github.com/repos/oppia/oppia/issues{/number}","pulls_url":"https://api.github.com/repos/oppia/oppia/pulls{/number}","milestones_url":"https://api.github.com/repos/oppia/oppia/milestones{/number}","notifications_url":"https://api.github.com/repos/oppia/oppia/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/oppia/oppia/labels{/name}","releases_url":"https://api.github.com/repos/oppia/oppia/releases{/id}","deployments_url":"https://api.github.com/repos/oppia/oppia/deployments","created_at":"2015-08-14T00:16:14Z","updated_at":"2016-02-03T01:29:05Z","pushed_at":"2016-02-03T17:47:18Z","git_url":"git://github.com/oppia/oppia.git","ssh_url":"git@github.com:oppia/oppia.git","clone_url":"https://github.com/oppia/oppia.git","svn_url":"https://github.com/oppia/oppia","homepage":"https://www.oppia.org","size":46213,"stargazers_count":73,"watchers_count":73,"language":"Python","has_issues":true,"has_downloads":false,"has_wiki":true,"has_pages":false,"forks_count":106,"mirror_url":null,"open_issues_count":263,"forks":106,"open_issues":263,"watchers":73,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/oppia/oppia/pulls/1433"},"html":{"href":"https://github.com/oppia/oppia/pull/1433"},"issue":{"href":"https://api.github.com/repos/oppia/oppia/issues/1433"},"comments":{"href":"https://api.github.com/repos/oppia/oppia/issues/1433/comments"},"review_comments":{"href":"https://api.github.com/repos/oppia/oppia/pulls/1433/comments"},"review_comment":{"href":"https://api.github.com/repos/oppia/oppia/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/oppia/oppia/pulls/1433/commits"},"statuses":{"href":"https://api.github.com/repos/oppia/oppia/statuses/546f0c7724c297788975a4525161e8a8350df377"}}}}