diff --git a/packages/component-wizard/src/components/FileItem.js b/packages/component-wizard/src/components/FileItem.js
index a0853bf836a5c9d1c0006978f84d05bbb6888e0d..0d70a47081d14940fdffd72db1e0669239b84a46 100644
--- a/packages/component-wizard/src/components/FileItem.js
+++ b/packages/component-wizard/src/components/FileItem.js
@@ -19,7 +19,15 @@ const parseFileSize = size => {
   return `${size} bytes`
 }
 
-const FileItem = ({ dragHandle, name, size, id, removeFile, ...rest }) => (
+const FileItem = ({
+  dragHandle,
+  name,
+  size,
+  id,
+  removeFile,
+  previewFile,
+  ...rest
+}) => (
   <div className={classnames(classes['file-item'])}>
     {dragHandle}
     <div className={classnames(classes.info)}>
@@ -27,9 +35,9 @@ const FileItem = ({ dragHandle, name, size, id, removeFile, ...rest }) => (
       <span>{parseFileSize(size)}</span>
     </div>
     <div className={classnames(classes.buttons)}>
-      <a href={rest.signedUrl} target="_blank">
+      <button onClick={previewFile(id)}>
         <Icon color="#666">eye</Icon>
-      </a>
+      </button>
       <button onClick={removeFile(id)} title="Delete">
         <Icon color="#666">trash-2</Icon>
       </button>
diff --git a/packages/component-wizard/src/components/FileSection.js b/packages/component-wizard/src/components/FileSection.js
index 245dcc5ffc7d7a7b7c9bae8a6dc20577e68fe129..5f3726de3d4bea1d9aba109b9feeafba4c9e4b73 100644
--- a/packages/component-wizard/src/components/FileSection.js
+++ b/packages/component-wizard/src/components/FileSection.js
@@ -40,6 +40,7 @@ const FileSection = ({
   canDropFile,
   disabledFilepicker,
   dropSortableFile,
+  previewFile,
 }) =>
   connectFileDrop(
     connectDropTarget(
@@ -87,6 +88,7 @@ const FileSection = ({
           listId={listId}
           listItem={FileItem}
           moveItem={moveItem}
+          previewFile={previewFile}
           removeFile={removeFile}
         />
         <FileDropzone label="Drag files here or use the add button." />
diff --git a/packages/component-wizard/src/components/Files.js b/packages/component-wizard/src/components/Files.js
index 69f90a37a3b4b54b5d03e81ac90b1bc661f70e25..a54117c83319b5d95f5dc47f40f0fda6a93b105b 100644
--- a/packages/component-wizard/src/components/Files.js
+++ b/packages/component-wizard/src/components/Files.js
@@ -21,6 +21,7 @@ import {
   getRequestStatus,
   setAllFiles,
   moveFiles,
+  getSignedUrl,
 } from '../redux/files'
 
 const Files = ({
@@ -30,6 +31,7 @@ const Files = ({
   removeFile,
   changeList,
   dropSortableFile,
+  previewFile,
   ...rest
 }) => (
   <div>
@@ -43,6 +45,7 @@ const Files = ({
       listId="manuscripts"
       maxFiles={Number.POSITIVE_INFINITY}
       moveItem={moveItem('manuscripts')}
+      previewFile={previewFile}
       removeFile={removeFile('manuscripts')}
       title="Main manuscript"
     />
@@ -54,6 +57,7 @@ const Files = ({
       listId="supplementary"
       maxFiles={Number.POSITIVE_INFINITY}
       moveItem={moveItem('supplementary')}
+      previewFile={previewFile}
       removeFile={removeFile('supplementary')}
       title="Supplementarry files"
     />
@@ -67,6 +71,7 @@ const Files = ({
       listId="coverLetter"
       maxFiles={1}
       moveItem={moveItem('coverLetter')}
+      previewFile={previewFile}
       removeFile={removeFile('coverLetter')}
       title="Cover letter"
     />
@@ -86,6 +91,7 @@ export default compose(
       deleteFile,
       setAllFiles,
       moveFiles,
+      getSignedUrl,
     },
   ),
   lifecycle({
@@ -95,6 +101,12 @@ export default compose(
     },
   }),
   withHandlers({
+    previewFile: ({ getSignedUrl }) => fileId => e => {
+      e.preventDefault()
+      getSignedUrl(fileId).then(({ signedUrl }) => {
+        window.open(signedUrl)
+      })
+    },
     dropSortableFile: ({ files, setAllFiles }) => () => {
       setAllFiles(files)
     },
@@ -134,7 +146,7 @@ export default compose(
       version,
     }) => type => id => e => {
       e.preventDefault()
-      deleteFile(id, version.id)
+      deleteFile(id)
       const newFiles = {
         ...files,
         [type]: files[type].filter(f => f.id !== id),
diff --git a/packages/component-wizard/src/components/WizardStep.js b/packages/component-wizard/src/components/WizardStep.js
index 52b7609e4776cb2d1453fbeb0ad8d281f8bc39b6..ff5bdc3b9f3ba264388d94a8e9ca4f0054f84017 100644
--- a/packages/component-wizard/src/components/WizardStep.js
+++ b/packages/component-wizard/src/components/WizardStep.js
@@ -5,7 +5,6 @@ import { ValidatedField, Button } from '@pubsweet/ui'
 
 import classes from './WizardStep.local.scss'
 import AutosaveIndicator from './AutosaveIndicator'
-import Files from './Files'
 
 export default ({
   children: stepChildren,
diff --git a/packages/component-wizard/src/redux/files.js b/packages/component-wizard/src/redux/files.js
index 06ef16cc589075cd85c2980cea96336211c34b9d..93dddc958306d9723d6e729a9e85f5112eda6587 100644
--- a/packages/component-wizard/src/redux/files.js
+++ b/packages/component-wizard/src/redux/files.js
@@ -89,7 +89,7 @@ export const getRequestStatus = state => state.files.isFetching
 // thunked actions
 export const uploadFile = (file, type, fragmentId) => dispatch => {
   dispatch(uploadRequest(type))
-  return request('/aws-upload', createFileData(file, type, fragmentId))
+  return request('/aws', createFileData(file, type, fragmentId))
     .then(r => {
       dispatch(uploadSuccess())
       return r
@@ -97,9 +97,9 @@ export const uploadFile = (file, type, fragmentId) => dispatch => {
     .catch(err => dispatch(uploadFailure(err.message)))
 }
 
-export const deleteFile = (fileId, fragmentId) => dispatch => {
+export const deleteFile = fileId => dispatch => {
   dispatch(removeRequest())
-  return remove(`/aws-delete/${fragmentId}/${fileId}`)
+  return remove(`/aws/${fileId}`)
     .then(r => {
       dispatch(removeSuccess())
       return r
@@ -107,8 +107,7 @@ export const deleteFile = (fileId, fragmentId) => dispatch => {
     .catch(err => dispatch(removeFailure(err.message)))
 }
 
-export const getSignedUrl = (fileId, fragmentId) =>
-  get(`aws-signed-url/${fragmentId}/${fileId}`)
+export const getSignedUrl = fileId => dispatch => get(`/aws/${fileId}`)
 
 // reducer
 export default (state = initialState, action) => {
diff --git a/packages/components-faraday/src/components/Dashboard/Dashboard.js b/packages/components-faraday/src/components/Dashboard/Dashboard.js
index ed359ff49f353a936beb419d806e88fd27149c79..03de9a484ec044a8b9ece5cc9387577e04a92a14 100644
--- a/packages/components-faraday/src/components/Dashboard/Dashboard.js
+++ b/packages/components-faraday/src/components/Dashboard/Dashboard.js
@@ -1,6 +1,8 @@
 import React from 'react'
 import { get } from 'lodash'
 import { Button } from '@pubsweet/ui'
+import { connect } from 'react-redux'
+import { compose, withHandlers } from 'recompose'
 
 import classes from './Dashboard.local.scss'
 import DashboardItems from './DashboardItems'
@@ -13,6 +15,8 @@ const Dashboard = ({
   dashboard,
   deleteProject,
   listView,
+  filters,
+  getItems,
 }) => (
   <div className={classes.root}>
     <div className={classes.header}>
@@ -24,10 +28,48 @@ const Dashboard = ({
     <DashboardFilters changeView={changeViewMode} listView={listView} />
     <DashboardItems
       deleteProject={deleteProject}
-      list={get(currentUser, 'admin') ? dashboard.all : dashboard.owner}
+      list={getItems()}
       listView={listView}
     />
   </div>
 )
 
-export default Dashboard
+export default compose(
+  connect(state => ({
+    filters: state.filters.filter,
+    sortOrder: state.filters.sortValue,
+  })),
+  withHandlers({
+    getItems: ({ filters, sortOrder, currentUser, dashboard }) => () => {
+      const userItems = get(currentUser, 'admin')
+        ? dashboard.all
+        : dashboard.owner
+      const statusItems =
+        filters.status === 'all'
+          ? userItems
+          : userItems.filter(item => {
+              const itemStatus = get(item, 'status')
+              if (!itemStatus && filters.status === 'draft') {
+                return true
+              }
+              return itemStatus === filters.status
+            })
+      const ownerItems =
+        filters.owner === 'all'
+          ? statusItems
+          : statusItems.filter(item => {
+              const itemOwnerIds = item.owners.map(o => o.id)
+              if (filters.owner === 'me') {
+                return itemOwnerIds.includes(currentUser.id)
+              } else if (filters.owner === 'other') {
+                return !itemOwnerIds.includes(currentUser.id)
+              }
+              return false
+            })
+      return ownerItems.sort((a, b) => {
+        if (sortOrder === 'newest') return a.created - b.created < 0
+        return a.created - b.created > 0
+      })
+    },
+  }),
+)(Dashboard)
diff --git a/packages/components-faraday/src/components/Dashboard/Dashboard.local.scss b/packages/components-faraday/src/components/Dashboard/Dashboard.local.scss
index bc62ceb698f0cd2642e796653e52ab2a6b4426ac..c4b717e217a6feb5460725abb24d2f7a8944ae02 100644
--- a/packages/components-faraday/src/components/Dashboard/Dashboard.local.scss
+++ b/packages/components-faraday/src/components/Dashboard/Dashboard.local.scss
@@ -15,11 +15,24 @@
 }
 
 .filters {
+  align-items: flex-end;
+  display: flex;
+
   > span {
     border: 1px solid gray;
     margin: 0 0.5em;
     padding: 0 5px;
   }
+
+  .filter-group {
+    align-items: flex-start;
+    display: flex;
+    flex-direction: column;
+
+    > span {
+      margin-left: 10px;
+    }
+  }
 }
 
 .disabled {
diff --git a/packages/components-faraday/src/components/Dashboard/DashboardFilters.js b/packages/components-faraday/src/components/Dashboard/DashboardFilters.js
index 124ca55839ea2442c8289165f2bad12d730233b5..45ceb6508276a3ef3791d6f0bb2eb7c3f0c5ae4e 100644
--- a/packages/components-faraday/src/components/Dashboard/DashboardFilters.js
+++ b/packages/components-faraday/src/components/Dashboard/DashboardFilters.js
@@ -1,7 +1,27 @@
 import React from 'react'
-import { Icon } from '@pubsweet/ui'
+import { connect } from 'react-redux'
+import { Icon, Menu } from '@pubsweet/ui'
+import { compose, withHandlers } from 'recompose'
 
 import classes from './Dashboard.local.scss'
+import { changeFilter, changeSort } from './redux/filters'
+
+const statusFilterOptions = [
+  { label: 'All', value: 'all' },
+  { label: 'Submitted', value: 'submitted' },
+  { label: 'Draft', value: 'draft' },
+]
+
+const ownerFilterOptions = [
+  { label: 'Everyone', value: 'all' },
+  { label: 'My work', value: 'me' },
+  { label: `Other's work`, value: 'other' },
+]
+
+const sortOptions = [
+  { label: 'Newest first', value: 'newest' },
+  { label: 'Oldest first', value: 'oldest' },
+]
 
 const DashboardFilters = ({
   view,
@@ -9,14 +29,24 @@ const DashboardFilters = ({
   createdAt,
   changeView,
   listView,
+  changeFilter,
+  changeSort,
 }) => (
   <div className={classes.filtersContainer}>
     <div className={classes.filters}>
       Filter view:
-      <span> My work </span>
-      <span> Type </span>
-      <span> Status </span>
-      <span> Newest on top </span>
+      <div className={classes['filter-group']}>
+        <span>Owner</span>
+        <Menu onChange={changeFilter('owner')} options={ownerFilterOptions} />
+      </div>
+      <div className={classes['filter-group']}>
+        <span>Status</span>
+        <Menu onChange={changeFilter('status')} options={statusFilterOptions} />
+      </div>
+      <div className={classes['filter-group']}>
+        <span>Sort</span>
+        <Menu onChange={changeSort} options={sortOptions} />
+      </div>
     </div>
     <div className={classes.viewMode} onClick={changeView}>
       <div className={classes.icon}>
@@ -27,4 +57,11 @@ const DashboardFilters = ({
   </div>
 )
 
-export default DashboardFilters
+export default compose(
+  connect(null, { changeFilter, changeSort }),
+  withHandlers({
+    changeFilter: ({ changeFilter }) => filterKey => value => {
+      changeFilter(filterKey, value)
+    },
+  }),
+)(DashboardFilters)
diff --git a/packages/components-faraday/src/components/Dashboard/redux/filters.js b/packages/components-faraday/src/components/Dashboard/redux/filters.js
index 4bf55715d55526689310886a10853a6197741d78..e50016723b70f39788b05687f18390c02f650c68 100644
--- a/packages/components-faraday/src/components/Dashboard/redux/filters.js
+++ b/packages/components-faraday/src/components/Dashboard/redux/filters.js
@@ -1,5 +1,40 @@
-export default (state = {}, action) => {
+const initialState = {
+  filter: {
+    status: 'all',
+    owner: 'all',
+  },
+  sortValue: 'newest',
+}
+
+const CHANGE_FILTER = 'filters/CHANGE_FILTER'
+const CHANGE_SORT = 'filters/CHANGE_SORT'
+
+export const changeFilter = (filterKey, value) => ({
+  type: CHANGE_FILTER,
+  filterKey,
+  value,
+})
+
+export const changeSort = value => ({
+  type: CHANGE_SORT,
+  value,
+})
+
+export default (state = initialState, action) => {
   switch (action.type) {
+    case CHANGE_FILTER:
+      return {
+        ...state,
+        filter: {
+          ...state.filter,
+          [action.filterKey]: action.value,
+        },
+      }
+    case CHANGE_SORT:
+      return {
+        ...state,
+        sortValue: action.value,
+      }
     default:
       return state
   }