{"action":"created","comment":{"url":"https://api.github.com/repos/guardian/facia-tool/pulls/comments/186716872","pull_request_review_id":118349200,"id":186716872,"diff_hunk":"@@ -4,64 +4,68 @@ import { createSelector } from 'reselect';\n import { breakingNewsFrontId } from '../constants/fronts';\n \n import type {\n-  FrontConfig,\n-  FrontDetail,\n-  FrontsClientConfig,\n   Front,\n-  ConfigCollection\n+  ConfigCollection,\n+  FrontDetailFull,\n+  FrontsWithIds,\n+  FrontsByPriority\n } from '../types/FrontsConfig';\n \n import type { State } from '../types/State';\n \n-const frontsSelector = (state: State): Front => state.frontsConfig.fronts;\n-const collectionsSelector = (state: State): ConfigCollection =>\n-  state.frontsConfig.collections;\n+const getFrontsConfig = (state: State) => state.frontsConfig || {};\n \n-const prioritySelector = (state: State, priority: string) => priority;\n+const rawFrontsSelector = (state: State): Front =>\n+  getFrontsConfig(state).fronts || {};\n \n-const frontsIdSelector = createSelector([frontsSelector], fronts => {\n+const getFronts = createSelector(\n+  [rawFrontsSelector],\n+  (fronts: Front): FrontsWithIds =>\n+    Object.keys(fronts)\n+      .map((id): FrontDetailFull => ({\n+        id,\n+        ...fronts[id],\n+        priority: fronts[id].priority || 'editorial'\n+      }))\n+      .reduce(\n+        (acc: FrontsWithIds, front: FrontDetailFull): FrontsWithIds => ({\n+          ...acc,\n+          [front.id]: front\n+        }),\n+        {}\n+      )\n+);\n+\n+const getFrontsByPriority = createSelector(\n+  [getFronts],\n+  (fronts: FrontsWithIds): FrontsByPriority =>\n+    Object.keys(fronts).reduce(\n+      (acc: FrontsByPriority, id): FrontsByPriority => {\n+        const front = fronts[id];\n+        return {\n+          ...acc,\n+          [front.priority]: [...(acc[front.priority] || []), fronts[id]]\n+        };\n+      },\n+      {}\n+    )\n+);\n+\n+const getFrontsWithPriority = (\n+  state: State,\n+  priority: string\n+): FrontDetailFull[] => getFrontsByPriority(state)[priority] || [];","path":"client-v2/src/selectors/frontsSelectors.js","position":63,"original_position":63,"commit_id":"e3ed7eb81171086507f254d44b5ce754a96a6093","original_commit_id":"e3ed7eb81171086507f254d44b5ce754a96a6093","user":{"login":"Reettaphant","id":3066534,"avatar_url":"https://avatars2.githubusercontent.com/u/3066534?v=4","gravatar_id":"","url":"https://api.github.com/users/Reettaphant","html_url":"https://github.com/Reettaphant","followers_url":"https://api.github.com/users/Reettaphant/followers","following_url":"https://api.github.com/users/Reettaphant/following{/other_user}","gists_url":"https://api.github.com/users/Reettaphant/gists{/gist_id}","starred_url":"https://api.github.com/users/Reettaphant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Reettaphant/subscriptions","organizations_url":"https://api.github.com/users/Reettaphant/orgs","repos_url":"https://api.github.com/users/Reettaphant/repos","events_url":"https://api.github.com/users/Reettaphant/events{/privacy}","received_events_url":"https://api.github.com/users/Reettaphant/received_events","type":"User","site_admin":false},"body":"Ok, I think I get it. So if we are passing in component props to selectors, we should separate out the logic that uses the prop from all other data manipulation we are doing.","created_at":"2018-05-08T12:57:04Z","updated_at":"2018-05-08T12:57:04Z","html_url":"https://github.com/guardian/facia-tool/pull/310#discussion_r186716872","pull_request_url":"https://api.github.com/repos/guardian/facia-tool/pulls/310","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/guardian/facia-tool/pulls/comments/186716872"},"html":{"href":"https://github.com/guardian/facia-tool/pull/310#discussion_r186716872"},"pull_request":{"href":"https://api.github.com/repos/guardian/facia-tool/pulls/310"}},"in_reply_to_id":186697029},"pull_request":{"url":"https://api.github.com/repos/guardian/facia-tool/pulls/310","id":185482547,"html_url":"https://github.com/guardian/facia-tool/pull/310","diff_url":"https://github.com/guardian/facia-tool/pull/310.diff","patch_url":"https://github.com/guardian/facia-tool/pull/310.patch","issue_url":"https://api.github.com/repos/guardian/facia-tool/issues/310","number":310,"state":"open","locked":false,"title":"Richieahb/refactor dropdown","user":{"login":"RichieAHB","id":1652187,"avatar_url":"https://avatars3.githubusercontent.com/u/1652187?v=4","gravatar_id":"","url":"https://api.github.com/users/RichieAHB","html_url":"https://github.com/RichieAHB","followers_url":"https://api.github.com/users/RichieAHB/followers","following_url":"https://api.github.com/users/RichieAHB/following{/other_user}","gists_url":"https://api.github.com/users/RichieAHB/gists{/gist_id}","starred_url":"https://api.github.com/users/RichieAHB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RichieAHB/subscriptions","organizations_url":"https://api.github.com/users/RichieAHB/orgs","repos_url":"https://api.github.com/users/RichieAHB/repos","events_url":"https://api.github.com/users/RichieAHB/events{/privacy}","received_events_url":"https://api.github.com/users/RichieAHB/received_events","type":"User","site_admin":false},"body":"This refactors the `FrontsDropdown` component away from being a \"fronts\" dropdown to just being a dropdown (while adding a `FrontsDropdown` container). Most if not all of the logic is the same as before but all of the data handling around fronts that is required for the dropdown is being done outside the dumb component now (and in some slightly changed selectors). E.g. our component is now not dependent on `react-router` (through using `history.push`) and `priority`. This pattern can be used in other places in the app too. Find a fronts component; describe it in terms of it's own domain; take any data munging logic out of the component and instead do this when mapping our state (or router params) to props; pass in in through a container.\r\n\r\nI've also split out `collection` and `fronts` out from `frontsConfig` in our selectors so that we can use them separately nice and deep in the component tree only where needed.\r\n\r\nThis PR is open to discussion and I may have missed some reasons for doing other bits and pieces in here but I think some of these patterns will be really useful as the app grows. Arguably doing it here is a bit pedantic but there are some other places in the app (specifically around collections etc.) that would benefit from this going forward and would take a bit more of a discussion to draw some boundaries.","created_at":"2018-05-02T15:50:46Z","updated_at":"2018-05-08T12:57:04Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b94a8f8df9968a88e00b3b254d4e2c00506417b4","assignee":null,"assignees":[],"requested_reviewers":[{"login":"jonathonherbert","id":7767575,"avatar_url":"https://avatars1.githubusercontent.com/u/7767575?v=4","gravatar_id":"","url":"https://api.github.com/users/jonathonherbert","html_url":"https://github.com/jonathonherbert","followers_url":"https://api.github.com/users/jonathonherbert/followers","following_url":"https://api.github.com/users/jonathonherbert/following{/other_user}","gists_url":"https://api.github.com/users/jonathonherbert/gists{/gist_id}","starred_url":"https://api.github.com/users/jonathonherbert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jonathonherbert/subscriptions","organizations_url":"https://api.github.com/users/jonathonherbert/orgs","repos_url":"https://api.github.com/users/jonathonherbert/repos","events_url":"https://api.github.com/users/jonathonherbert/events{/privacy}","received_events_url":"https://api.github.com/users/jonathonherbert/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/guardian/facia-tool/pulls/310/commits","review_comments_url":"https://api.github.com/repos/guardian/facia-tool/pulls/310/comments","review_comment_url":"https://api.github.com/repos/guardian/facia-tool/pulls/comments{/number}","comments_url":"https://api.github.com/repos/guardian/facia-tool/issues/310/comments","statuses_url":"https://api.github.com/repos/guardian/facia-tool/statuses/e3ed7eb81171086507f254d44b5ce754a96a6093","head":{"label":"guardian:richieahb/refactor-dropdown","ref":"richieahb/refactor-dropdown","sha":"e3ed7eb81171086507f254d44b5ce754a96a6093","user":{"login":"guardian","id":164318,"avatar_url":"https://avatars0.githubusercontent.com/u/164318?v=4","gravatar_id":"","url":"https://api.github.com/users/guardian","html_url":"https://github.com/guardian","followers_url":"https://api.github.com/users/guardian/followers","following_url":"https://api.github.com/users/guardian/following{/other_user}","gists_url":"https://api.github.com/users/guardian/gists{/gist_id}","starred_url":"https://api.github.com/users/guardian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guardian/subscriptions","organizations_url":"https://api.github.com/users/guardian/orgs","repos_url":"https://api.github.com/users/guardian/repos","events_url":"https://api.github.com/users/guardian/events{/privacy}","received_events_url":"https://api.github.com/users/guardian/received_events","type":"Organization","site_admin":false},"repo":{"id":40353770,"name":"facia-tool","full_name":"guardian/facia-tool","owner":{"login":"guardian","id":164318,"avatar_url":"https://avatars0.githubusercontent.com/u/164318?v=4","gravatar_id":"","url":"https://api.github.com/users/guardian","html_url":"https://github.com/guardian","followers_url":"https://api.github.com/users/guardian/followers","following_url":"https://api.github.com/users/guardian/following{/other_user}","gists_url":"https://api.github.com/users/guardian/gists{/gist_id}","starred_url":"https://api.github.com/users/guardian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guardian/subscriptions","organizations_url":"https://api.github.com/users/guardian/orgs","repos_url":"https://api.github.com/users/guardian/repos","events_url":"https://api.github.com/users/guardian/events{/privacy}","received_events_url":"https://api.github.com/users/guardian/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/guardian/facia-tool","description":"Guardian front pages editor","fork":false,"url":"https://api.github.com/repos/guardian/facia-tool","forks_url":"https://api.github.com/repos/guardian/facia-tool/forks","keys_url":"https://api.github.com/repos/guardian/facia-tool/keys{/key_id}","collaborators_url":"https://api.github.com/repos/guardian/facia-tool/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/guardian/facia-tool/teams","hooks_url":"https://api.github.com/repos/guardian/facia-tool/hooks","issue_events_url":"https://api.github.com/repos/guardian/facia-tool/issues/events{/number}","events_url":"https://api.github.com/repos/guardian/facia-tool/events","assignees_url":"https://api.github.com/repos/guardian/facia-tool/assignees{/user}","branches_url":"https://api.github.com/repos/guardian/facia-tool/branches{/branch}","tags_url":"https://api.github.com/repos/guardian/facia-tool/tags","blobs_url":"https://api.github.com/repos/guardian/facia-tool/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/guardian/facia-tool/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/guardian/facia-tool/git/refs{/sha}","trees_url":"https://api.github.com/repos/guardian/facia-tool/git/trees{/sha}","statuses_url":"https://api.github.com/repos/guardian/facia-tool/statuses/{sha}","languages_url":"https://api.github.com/repos/guardian/facia-tool/languages","stargazers_url":"https://api.github.com/repos/guardian/facia-tool/stargazers","contributors_url":"https://api.github.com/repos/guardian/facia-tool/contributors","subscribers_url":"https://api.github.com/repos/guardian/facia-tool/subscribers","subscription_url":"https://api.github.com/repos/guardian/facia-tool/subscription","commits_url":"https://api.github.com/repos/guardian/facia-tool/commits{/sha}","git_commits_url":"https://api.github.com/repos/guardian/facia-tool/git/commits{/sha}","comments_url":"https://api.github.com/repos/guardian/facia-tool/comments{/number}","issue_comment_url":"https://api.github.com/repos/guardian/facia-tool/issues/comments{/number}","contents_url":"https://api.github.com/repos/guardian/facia-tool/contents/{+path}","compare_url":"https://api.github.com/repos/guardian/facia-tool/compare/{base}...{head}","merges_url":"https://api.github.com/repos/guardian/facia-tool/merges","archive_url":"https://api.github.com/repos/guardian/facia-tool/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/guardian/facia-tool/downloads","issues_url":"https://api.github.com/repos/guardian/facia-tool/issues{/number}","pulls_url":"https://api.github.com/repos/guardian/facia-tool/pulls{/number}","milestones_url":"https://api.github.com/repos/guardian/facia-tool/milestones{/number}","notifications_url":"https://api.github.com/repos/guardian/facia-tool/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/guardian/facia-tool/labels{/name}","releases_url":"https://api.github.com/repos/guardian/facia-tool/releases{/id}","deployments_url":"https://api.github.com/repos/guardian/facia-tool/deployments","created_at":"2015-08-07T09:54:57Z","updated_at":"2018-05-08T10:07:10Z","pushed_at":"2018-05-08T11:39:58Z","git_url":"git://github.com/guardian/facia-tool.git","ssh_url":"git@github.com:guardian/facia-tool.git","clone_url":"https://github.com/guardian/facia-tool.git","svn_url":"https://github.com/guardian/facia-tool","homepage":null,"size":350180,"stargazers_count":7,"watchers_count":7,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"archived":false,"open_issues_count":12,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":4,"open_issues":12,"watchers":7,"default_branch":"master"}},"base":{"label":"guardian:master","ref":"master","sha":"157c9241d09cdfcd13bd19da4e5049d21ab88d9d","user":{"login":"guardian","id":164318,"avatar_url":"https://avatars0.githubusercontent.com/u/164318?v=4","gravatar_id":"","url":"https://api.github.com/users/guardian","html_url":"https://github.com/guardian","followers_url":"https://api.github.com/users/guardian/followers","following_url":"https://api.github.com/users/guardian/following{/other_user}","gists_url":"https://api.github.com/users/guardian/gists{/gist_id}","starred_url":"https://api.github.com/users/guardian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guardian/subscriptions","organizations_url":"https://api.github.com/users/guardian/orgs","repos_url":"https://api.github.com/users/guardian/repos","events_url":"https://api.github.com/users/guardian/events{/privacy}","received_events_url":"https://api.github.com/users/guardian/received_events","type":"Organization","site_admin":false},"repo":{"id":40353770,"name":"facia-tool","full_name":"guardian/facia-tool","owner":{"login":"guardian","id":164318,"avatar_url":"https://avatars0.githubusercontent.com/u/164318?v=4","gravatar_id":"","url":"https://api.github.com/users/guardian","html_url":"https://github.com/guardian","followers_url":"https://api.github.com/users/guardian/followers","following_url":"https://api.github.com/users/guardian/following{/other_user}","gists_url":"https://api.github.com/users/guardian/gists{/gist_id}","starred_url":"https://api.github.com/users/guardian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guardian/subscriptions","organizations_url":"https://api.github.com/users/guardian/orgs","repos_url":"https://api.github.com/users/guardian/repos","events_url":"https://api.github.com/users/guardian/events{/privacy}","received_events_url":"https://api.github.com/users/guardian/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/guardian/facia-tool","description":"Guardian front pages editor","fork":false,"url":"https://api.github.com/repos/guardian/facia-tool","forks_url":"https://api.github.com/repos/guardian/facia-tool/forks","keys_url":"https://api.github.com/repos/guardian/facia-tool/keys{/key_id}","collaborators_url":"https://api.github.com/repos/guardian/facia-tool/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/guardian/facia-tool/teams","hooks_url":"https://api.github.com/repos/guardian/facia-tool/hooks","issue_events_url":"https://api.github.com/repos/guardian/facia-tool/issues/events{/number}","events_url":"https://api.github.com/repos/guardian/facia-tool/events","assignees_url":"https://api.github.com/repos/guardian/facia-tool/assignees{/user}","branches_url":"https://api.github.com/repos/guardian/facia-tool/branches{/branch}","tags_url":"https://api.github.com/repos/guardian/facia-tool/tags","blobs_url":"https://api.github.com/repos/guardian/facia-tool/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/guardian/facia-tool/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/guardian/facia-tool/git/refs{/sha}","trees_url":"https://api.github.com/repos/guardian/facia-tool/git/trees{/sha}","statuses_url":"https://api.github.com/repos/guardian/facia-tool/statuses/{sha}","languages_url":"https://api.github.com/repos/guardian/facia-tool/languages","stargazers_url":"https://api.github.com/repos/guardian/facia-tool/stargazers","contributors_url":"https://api.github.com/repos/guardian/facia-tool/contributors","subscribers_url":"https://api.github.com/repos/guardian/facia-tool/subscribers","subscription_url":"https://api.github.com/repos/guardian/facia-tool/subscription","commits_url":"https://api.github.com/repos/guardian/facia-tool/commits{/sha}","git_commits_url":"https://api.github.com/repos/guardian/facia-tool/git/commits{/sha}","comments_url":"https://api.github.com/repos/guardian/facia-tool/comments{/number}","issue_comment_url":"https://api.github.com/repos/guardian/facia-tool/issues/comments{/number}","contents_url":"https://api.github.com/repos/guardian/facia-tool/contents/{+path}","compare_url":"https://api.github.com/repos/guardian/facia-tool/compare/{base}...{head}","merges_url":"https://api.github.com/repos/guardian/facia-tool/merges","archive_url":"https://api.github.com/repos/guardian/facia-tool/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/guardian/facia-tool/downloads","issues_url":"https://api.github.com/repos/guardian/facia-tool/issues{/number}","pulls_url":"https://api.github.com/repos/guardian/facia-tool/pulls{/number}","milestones_url":"https://api.github.com/repos/guardian/facia-tool/milestones{/number}","notifications_url":"https://api.github.com/repos/guardian/facia-tool/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/guardian/facia-tool/labels{/name}","releases_url":"https://api.github.com/repos/guardian/facia-tool/releases{/id}","deployments_url":"https://api.github.com/repos/guardian/facia-tool/deployments","created_at":"2015-08-07T09:54:57Z","updated_at":"2018-05-08T10:07:10Z","pushed_at":"2018-05-08T11:39:58Z","git_url":"git://github.com/guardian/facia-tool.git","ssh_url":"git@github.com:guardian/facia-tool.git","clone_url":"https://github.com/guardian/facia-tool.git","svn_url":"https://github.com/guardian/facia-tool","homepage":null,"size":350180,"stargazers_count":7,"watchers_count":7,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"archived":false,"open_issues_count":12,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":4,"open_issues":12,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/guardian/facia-tool/pulls/310"},"html":{"href":"https://github.com/guardian/facia-tool/pull/310"},"issue":{"href":"https://api.github.com/repos/guardian/facia-tool/issues/310"},"comments":{"href":"https://api.github.com/repos/guardian/facia-tool/issues/310/comments"},"review_comments":{"href":"https://api.github.com/repos/guardian/facia-tool/pulls/310/comments"},"review_comment":{"href":"https://api.github.com/repos/guardian/facia-tool/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/guardian/facia-tool/pulls/310/commits"},"statuses":{"href":"https://api.github.com/repos/guardian/facia-tool/statuses/e3ed7eb81171086507f254d44b5ce754a96a6093"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"Reettaphant"}}