From 111a1ef88407d8adaae00adfe28be25ed986a55b Mon Sep 17 00:00:00 2001
From: freddytuxworth <freddytuxworth@gmail.com>
Date: Thu, 18 Jun 2020 13:46:47 +0100
Subject: [PATCH] Add button to remove conference from recents list

Fixes #313, #283, #322, #127, #334
---
 app/features/recent-list/actionTypes.js       | 10 +++++++++
 app/features/recent-list/actions.js           | 19 ++++++++++++++++
 .../recent-list/components/RecentList.js      | 22 +++++++++++++++++++
 app/features/recent-list/reducer.js           | 22 +++++++++++++++++++
 .../recent-list/styled/ConferenceCard.js      |  6 +++--
 5 files changed, 77 insertions(+), 2 deletions(-)
 create mode 100644 app/features/recent-list/actionTypes.js
 create mode 100644 app/features/recent-list/actions.js

diff --git a/app/features/recent-list/actionTypes.js b/app/features/recent-list/actionTypes.js
new file mode 100644
index 0000000..bab4c96
--- /dev/null
+++ b/app/features/recent-list/actionTypes.js
@@ -0,0 +1,10 @@
+/**
+ * The type of (redux) action that is dispatched when a conference is removed from the recents list.
+ *
+ * @type {
+*     type: CONFERENCE_REMOVED,
+*     conference: Object
+* }
+*/
+export const CONFERENCE_REMOVED = Symbol('CONFERENCE_REMOVED');
+
diff --git a/app/features/recent-list/actions.js b/app/features/recent-list/actions.js
new file mode 100644
index 0000000..7b4e7a1
--- /dev/null
+++ b/app/features/recent-list/actions.js
@@ -0,0 +1,19 @@
+// @flow
+
+import { CONFERENCE_REMOVED } from './actionTypes';
+
+/**
+ * Notifies that conference is removed from recents list.
+ *
+ * @param {Object} conference - Conference Details.
+ * @returns {{
+*     type: CONFERENCE_REMOVED,
+*     conference: Object
+* }}
+*/
+export function conferenceRemoved(conference: Object) {
+    return {
+        type: CONFERENCE_REMOVED,
+        conference
+    };
+}
diff --git a/app/features/recent-list/components/RecentList.js b/app/features/recent-list/components/RecentList.js
index 8135757..2518b93 100644
--- a/app/features/recent-list/components/RecentList.js
+++ b/app/features/recent-list/components/RecentList.js
@@ -6,6 +6,7 @@ import { connect } from 'react-redux';
 import type { Dispatch } from 'redux';
 import { push } from 'react-router-redux';
 
+import { conferenceRemoved } from '../actions';
 import {
     ConferenceCard,
     ConferenceTitle,
@@ -13,6 +14,8 @@ import {
     TruncatedText
 } from '../styled';
 import type { RecentListItem } from '../types';
+import Button from '@atlaskit/button';
+import CrossIcon from '@atlaskit/icon/glyph/cross';
 
 type Props = {
 
@@ -58,6 +61,20 @@ class RecentList extends Component<Props, *> {
         return () => this.props.dispatch(push('/conference', conference));
     }
 
+    /**
+     * Creates a handler for removing a conference from the recents list.
+     *
+     * @param {RecentListItem} conference - Conference Details.
+     * @returns {void}
+     */
+    _onRemoveConference(conference: RecentListItem) {
+        return e => {
+            this.props.dispatch(conferenceRemoved(conference));
+            e.stopPropagation();
+        };
+    }
+
+
     /**
      * Renders the conference card.
      *
@@ -81,6 +98,11 @@ class RecentList extends Component<Props, *> {
                 <TruncatedText>
                     { this._renderDuration(conference) }
                 </TruncatedText>
+                <Button
+                    appearance = 'subtle'
+                    iconBefore = { <CrossIcon primaryColor = 'white' /> }
+                    onClick = { this._onRemoveConference(conference) }
+                    spacing = 'none' />
             </ConferenceCard>
         );
     }
diff --git a/app/features/recent-list/reducer.js b/app/features/recent-list/reducer.js
index 099fe5d..17e86db 100644
--- a/app/features/recent-list/reducer.js
+++ b/app/features/recent-list/reducer.js
@@ -1,6 +1,7 @@
 // @flow
 
 import { CONFERENCE_ENDED, CONFERENCE_JOINED } from '../conference';
+import { CONFERENCE_REMOVED } from './actionTypes';
 
 import type { RecentListItem } from './types';
 
@@ -34,6 +35,12 @@ export default (state: State = DEFAULT_STATE, action: Object) => {
             recentList: _insertConference(state.recentList, action.conference)
         };
 
+    case CONFERENCE_REMOVED:
+        return {
+            ...state,
+            recentList: _removeConference(state.recentList, action.conference)
+        };
+
     default:
         return state;
     }
@@ -65,6 +72,21 @@ function _insertConference(
     return newRecentList;
 }
 
+/**
+ * Remove a conference from the recent list array.
+ *
+ * @param {Array<RecentListItem>} recentList - Previous recent list array.
+ * @param {RecentListItem} toRemove - Conference to be removed.
+ * @returns {Array<RecentListItem>} - Updated recent list array.
+ */
+function _removeConference(
+        recentList: Array<RecentListItem>,
+        toRemove: RecentListItem
+): Array<RecentListItem> {
+    return recentList.filter(
+        (conference: RecentListItem) => conference !== toRemove);
+}
+
 /**
  * Update the EndTime of the last conference.
  *
diff --git a/app/features/recent-list/styled/ConferenceCard.js b/app/features/recent-list/styled/ConferenceCard.js
index fff3f75..11c85b6 100644
--- a/app/features/recent-list/styled/ConferenceCard.js
+++ b/app/features/recent-list/styled/ConferenceCard.js
@@ -6,8 +6,10 @@ export default styled.div`
     background: #1754A9;
     border-radius: 0.5em;
     color: white;
-    display: flex;
-    flex-direction: column;
+    display: grid;
+    grid-template-rows: repeat(4, auto);
+    grid-template-columns: 1fr auto;
+    grid-auto-flow: column;
     font-size: 0.9em;
     margin: 0.5em;
     padding: 1em;
-- 
GitLab