[ARVADOS-WORKBENCH2] updated: 1.2.0-223-g1baec2d

Git user git at public.curoverse.com
Fri Aug 31 01:39:30 EDT 2018


Summary of changes:
 .env                                               |   1 -
 package.json                                       |  28 +-
 src/common/api/common-resource-service.ts          |  27 +-
 src/common/config.ts                               | 102 +++++++-
 src/common/custom-theme.ts                         |   6 +
 src/common/file.ts                                 |  15 ++
 src/common/unionize.ts                             |  14 +
 src/common/webdav.test.ts                          |   4 +-
 src/common/webdav.ts                               |   8 +-
 src/components/breadcrumbs/breadcrumbs.tsx         |   2 +-
 .../collection-panel-files.tsx                     |  66 ++---
 .../data-explorer/data-explorer.test.tsx           |  23 +-
 src/components/data-table/data-column.ts           |  13 +-
 src/components/data-table/data-table.test.tsx      |  60 +++--
 .../details-attribute/details-attribute.tsx        |  17 +-
 .../file-upload-dialog/file-upload-dialog.tsx      |  52 ++++
 src/components/file-upload/file-upload.tsx         |  39 ++-
 src/components/form-dialog/form-dialog.tsx         |  82 ++++++
 .../list-item-text-icon/list-item-text-icon.tsx    |   2 +-
 src/components/side-panel/side-panel.tsx           | 128 ----------
 .../subprocess-filter/subprocess-filter.tsx        |  54 ++++
 src/components/tree/tree.test.tsx                  |  12 +-
 src/components/tree/tree.tsx                       |  25 +-
 src/index.tsx                                      |  42 ++-
 src/models/container-request.ts                    |  41 +++
 src/models/container.ts                            |  38 +++
 src/models/mount-types.ts                          |  56 ++++
 src/models/process.ts                              |  35 +--
 src/models/resource.ts                             |  44 +++-
 src/models/runtime-constraints.ts                  |  10 +
 src/models/scheduling-parameters.ts                |   9 +
 src/models/tree.test.ts                            |  10 +-
 src/models/tree.ts                                 |  35 ++-
 src/models/user.ts                                 |  18 +-
 src/routes/routes.ts                               |  84 ++++++
 .../ancestors-service/ancestors-service.ts         |  44 ++++
 .../collection-manifest-mapper.ts                  |   4 +-
 .../collection-service-files-response.ts           |  54 ++++
 .../collection-service/collection-service.ts       | 174 +++----------
 .../container-request-service.ts}                  |  26 +-
 .../container-service.ts}                          |  26 +-
 src/services/services.ts                           |  58 +++--
 .../user-service.ts}                               |  10 +-
 src/store/auth/auth-action.ts                      |   5 +-
 src/store/auth/auth-actions.test.ts                |   7 +-
 src/store/auth/auth-reducer.test.ts                |   3 +-
 src/store/breadcrumbs/breadcrumbs-actions.ts       |  46 ++++
 .../collection-panel/collection-panel-action.ts    |  24 +-
 .../collection-panel-files-actions.ts              |  65 +++--
 .../collection-panel-files-reducer.ts              |   8 +-
 .../collection-panel-files-state.ts                |  12 +-
 src/store/collections/collection-copy-actions.ts   |  49 ++++
 src/store/collections/collection-create-actions.ts |  45 ++++
 src/store/collections/collection-move-actions.ts   |  45 ++++
 .../collections/collection-partial-copy-actions.ts |  71 ++++++
 src/store/collections/collection-trash-actions.ts  |  39 ---
 src/store/collections/collection-update-actions.ts |  49 ++++
 src/store/collections/collection-upload-actions.ts |  46 ++++
 src/store/collections/collections-reducer.ts       |  20 --
 .../creator/collection-creator-action.ts           |  46 ----
 .../creator/collection-creator-reducer.test.ts     |  33 ---
 .../creator/collection-creator-reducer.ts          |  30 ---
 .../updater/collection-updater-action.ts           |  49 ----
 .../updater/collection-updater-reducer.ts          |  29 ---
 src/store/context-menu/context-menu-actions.ts     | 100 +++++++-
 src/store/data-explorer/data-explorer-action.ts    |   4 +-
 .../data-explorer-middleware-service.ts            |  18 ++
 .../data-explorer/data-explorer-reducer.test.tsx   |   4 +-
 src/store/details-panel/details-panel-action.ts    |  41 +--
 src/store/details-panel/details-panel-reducer.ts   |   7 +-
 src/store/dialog/dialog-actions.ts                 |   7 +-
 src/store/dialog/dialog-reducer.ts                 |   8 +-
 src/store/favorite-panel/favorite-panel-action.ts  |   2 +
 .../favorite-panel-middleware-service.ts           | 105 ++++----
 src/store/favorites/favorites-actions.ts           |   7 +-
 .../file-uploader-actions.ts}                      |  53 ++--
 .../file-uploader-reducer.ts}                      |  10 +-
 .../move-to-dialog/move-to-dialog.ts}              |   7 +-
 src/store/navigation/navigation-action.ts          | 115 ++-------
 src/store/processes/process.ts                     |  47 ++++
 src/store/processes/processes-actions.ts           |  52 ++++
 src/store/project-panel/project-panel-action.ts    |  16 +-
 .../project-panel-middleware-service.ts            | 135 ++++++----
 .../project-tree-picker-actions.ts                 |  46 ++++
 src/store/project/project-action.ts                | 107 --------
 src/store/project/project-reducer.test.ts          | 186 --------------
 src/store/project/project-reducer.ts               | 171 -------------
 src/store/projects/project-create-actions.ts       |  42 +++
 src/store/projects/project-move-actions.ts         |  43 ++++
 src/store/projects/project-update-actions.ts       |  43 ++++
 src/store/properties/properties-actions.ts         |  12 +
 src/store/properties/properties-reducer.ts         |  14 +
 src/store/properties/properties.ts                 |  23 ++
 src/store/resources/resources-actions.ts           |  31 +++
 src/store/resources/resources-reducer.ts           |  13 +
 src/store/resources/resources.ts                   |  41 +++
 .../side-panel-tree/side-panel-tree-actions.ts     | 162 ++++++++++++
 src/store/side-panel/side-panel-action.ts          |  37 ++-
 src/store/side-panel/side-panel-reducer.test.ts    |  33 ---
 src/store/side-panel/side-panel-reducer.ts         | 112 --------
 src/store/snackbar/snackbar-actions.ts             |   4 +-
 src/store/snackbar/snackbar-reducer.ts             |   2 +-
 src/store/store.ts                                 |  80 +++---
 src/store/trash-panel/trash-panel-action.ts        |   3 +
 .../trash-panel/trash-panel-middleware-service.ts  |   4 +-
 src/store/trash/trash-actions.ts                   |  66 +++++
 src/store/tree-picker/tree-picker-actions.ts       |  18 +-
 src/store/tree-picker/tree-picker-reducer.test.ts  | 112 ++++----
 src/store/tree-picker/tree-picker-reducer.ts       |  65 +++--
 src/store/tree-picker/tree-picker.ts               |  12 +-
 src/store/workbench/workbench-actions.ts           | 216 ++++++++++++++++
 src/validators/validators.tsx                      |   7 +-
 src/views-components/api-token/api-token.tsx       |   6 +-
 src/views-components/breadcrumbs/breadcrumbs.ts    |  30 +++
 .../collection-panel-files.ts                      |  27 +-
 .../action-sets/collection-action-set.ts           |  14 +-
 .../action-sets/collection-files-action-set.ts     |   5 +-
 .../collection-files-item-action-set.ts            |   7 +-
 .../action-sets/collection-resource-action-set.ts  |  18 +-
 ...lection-action-set.ts => process-action-set.ts} |  48 +++-
 .../context-menu/action-sets/project-action-set.ts |  30 ++-
 .../action-sets/root-project-action-set.ts         |  14 +-
 src/views-components/context-menu/context-menu.tsx |   3 +-
 .../create-collection-dialog-with-selected.tsx     |  29 ---
 .../create-collection-dialog.tsx                   |  44 ----
 .../create-project-dialog.tsx                      |  44 ----
 .../data-explorer/data-explorer.tsx                |  11 +-
 src/views-components/data-explorer/renderers.tsx   |  46 +++-
 .../details-panel/collection-details.tsx           |   2 +-
 .../details-panel/details-panel.tsx                |  32 ++-
 .../details-panel/process-details.tsx              |   6 +-
 .../details-panel/project-details.tsx              |   2 +-
 .../dialog-copy/dialog-collection-copy.tsx         |  34 +++
 .../dialog-copy/dialog-collection-partial-copy.tsx |  28 ++
 .../dialog-collection-create-selected.tsx          |  62 -----
 .../dialog-create/dialog-collection-create.tsx     | 137 ++--------
 .../dialog-create/dialog-project-create.tsx        | 111 ++------
 .../dialog-forms/copy-collection-dialog.ts         |  20 ++
 .../dialog-forms/create-collection-dialog.ts       |  20 ++
 .../dialog-forms/create-project-dialog.ts          |  20 ++
 .../dialog-forms/files-upload-collection-dialog.ts |  20 ++
 .../dialog-forms/move-collection-dialog.ts         |  21 ++
 .../dialog-forms/move-project-dialog.ts            |  22 ++
 .../dialog-forms/partial-copy-collection-dialog.ts |  19 ++
 .../dialog-forms/update-collection-dialog.ts       |  20 ++
 .../dialog-forms/update-project-dialog.ts          |  20 ++
 .../dialog-move/dialog-move-to.tsx                 |  26 ++
 .../dialog-update/dialog-collection-update.tsx     | 120 ++-------
 .../dialog-update/dialog-project-update.tsx        | 116 ++-------
 .../dialog-collection-files-upload.tsx             |  32 +++
 .../file-uploader/file-uploader.tsx                |  35 +++
 .../form-fields/collection-form-fields.tsx         |  34 +++
 .../form-fields/project-form-fields.tsx            |  22 ++
 .../main-app-bar/main-app-bar.test.tsx             |  62 ++---
 src/views-components/main-app-bar/main-app-bar.tsx |  20 +-
 .../project-tree-picker/project-tree-picker.tsx    | 134 ++++++++--
 .../project-tree/project-tree.test.tsx             |  14 +-
 .../rename-file-dialog/rename-file-dialog.tsx      |  52 ++--
 .../side-panel-tree/side-panel-tree.tsx            |  69 +++++
 src/views-components/side-panel/side-panel.tsx     |  45 ++++
 src/views-components/tree-picker/tree-picker.ts    |  50 ++--
 .../update-collection-dialog..tsx                  |  44 ----
 .../update-project-dialog.tsx                      |  42 ---
 src/views/collection-panel/collection-panel.tsx    | 155 ++++++-----
 src/views/favorite-panel/favorite-panel-item.ts    |  31 ---
 src/views/favorite-panel/favorite-panel.tsx        |  76 +++---
 .../process-panel/process-information-card.tsx     | 121 +++++++++
 src/views/process-panel/process-panel-root.tsx     |  69 +++++
 src/views/process-panel/process-panel.tsx          |  29 +++
 src/views/process-panel/subprocesses-card.tsx      |  46 ++++
 src/views/project-panel/project-panel-item.ts      |  33 ---
 src/views/project-panel/project-panel.tsx          |  97 +++----
 src/views/trash-panel/trash-panel.tsx              |  21 +-
 src/views/workbench/workbench.tsx                  | 284 +++------------------
 yarn.lock                                          | 174 +++++++------
 175 files changed, 4504 insertions(+), 3283 deletions(-)
 create mode 100644 src/common/file.ts
 create mode 100644 src/common/unionize.ts
 create mode 100644 src/components/file-upload-dialog/file-upload-dialog.tsx
 create mode 100644 src/components/form-dialog/form-dialog.tsx
 delete mode 100644 src/components/side-panel/side-panel.tsx
 create mode 100644 src/components/subprocess-filter/subprocess-filter.tsx
 create mode 100644 src/models/container-request.ts
 create mode 100644 src/models/container.ts
 create mode 100644 src/models/mount-types.ts
 create mode 100644 src/models/runtime-constraints.ts
 create mode 100644 src/models/scheduling-parameters.ts
 create mode 100644 src/routes/routes.ts
 create mode 100644 src/services/ancestors-service/ancestors-service.ts
 create mode 100644 src/services/collection-service/collection-service-files-response.ts
 copy src/services/{keep-service/keep-service.ts => container-request-service/container-request-service.ts} (55%)
 copy src/services/{keep-service/keep-service.ts => container-service/container-service.ts} (59%)
 copy src/services/{link-service/link-service.ts => user-service/user-service.ts} (65%)
 create mode 100644 src/store/breadcrumbs/breadcrumbs-actions.ts
 create mode 100644 src/store/collections/collection-copy-actions.ts
 create mode 100644 src/store/collections/collection-create-actions.ts
 create mode 100644 src/store/collections/collection-move-actions.ts
 create mode 100644 src/store/collections/collection-partial-copy-actions.ts
 delete mode 100644 src/store/collections/collection-trash-actions.ts
 create mode 100644 src/store/collections/collection-update-actions.ts
 create mode 100644 src/store/collections/collection-upload-actions.ts
 delete mode 100644 src/store/collections/collections-reducer.ts
 delete mode 100644 src/store/collections/creator/collection-creator-action.ts
 delete mode 100644 src/store/collections/creator/collection-creator-reducer.test.ts
 delete mode 100644 src/store/collections/creator/collection-creator-reducer.ts
 delete mode 100644 src/store/collections/updater/collection-updater-action.ts
 delete mode 100644 src/store/collections/updater/collection-updater-reducer.ts
 rename src/store/{collections/uploader/collection-uploader-actions.ts => file-uploader/file-uploader-actions.ts} (61%)
 rename src/store/{collections/uploader/collection-uploader-reducer.ts => file-uploader/file-uploader-reducer.ts} (69%)
 copy src/{models/empty.ts => store/move-to-dialog/move-to-dialog.ts} (59%)
 create mode 100644 src/store/processes/process.ts
 create mode 100644 src/store/processes/processes-actions.ts
 create mode 100644 src/store/project-tree-picker/project-tree-picker-actions.ts
 delete mode 100644 src/store/project/project-action.ts
 delete mode 100644 src/store/project/project-reducer.test.ts
 delete mode 100644 src/store/project/project-reducer.ts
 create mode 100644 src/store/projects/project-create-actions.ts
 create mode 100644 src/store/projects/project-move-actions.ts
 create mode 100644 src/store/projects/project-update-actions.ts
 create mode 100644 src/store/properties/properties-actions.ts
 create mode 100644 src/store/properties/properties-reducer.ts
 create mode 100644 src/store/properties/properties.ts
 create mode 100644 src/store/resources/resources-actions.ts
 create mode 100644 src/store/resources/resources-reducer.ts
 create mode 100644 src/store/resources/resources.ts
 create mode 100644 src/store/side-panel-tree/side-panel-tree-actions.ts
 delete mode 100644 src/store/side-panel/side-panel-reducer.test.ts
 delete mode 100644 src/store/side-panel/side-panel-reducer.ts
 create mode 100644 src/store/trash/trash-actions.ts
 create mode 100644 src/store/workbench/workbench-actions.ts
 create mode 100644 src/views-components/breadcrumbs/breadcrumbs.ts
 copy src/views-components/context-menu/action-sets/{collection-action-set.ts => process-action-set.ts} (68%)
 delete mode 100644 src/views-components/create-collection-dialog-with-selected/create-collection-dialog-with-selected.tsx
 delete mode 100644 src/views-components/create-collection-dialog/create-collection-dialog.tsx
 delete mode 100644 src/views-components/create-project-dialog/create-project-dialog.tsx
 create mode 100644 src/views-components/dialog-copy/dialog-collection-copy.tsx
 create mode 100644 src/views-components/dialog-copy/dialog-collection-partial-copy.tsx
 delete mode 100644 src/views-components/dialog-create/dialog-collection-create-selected.tsx
 create mode 100644 src/views-components/dialog-forms/copy-collection-dialog.ts
 create mode 100644 src/views-components/dialog-forms/create-collection-dialog.ts
 create mode 100644 src/views-components/dialog-forms/create-project-dialog.ts
 create mode 100644 src/views-components/dialog-forms/files-upload-collection-dialog.ts
 create mode 100644 src/views-components/dialog-forms/move-collection-dialog.ts
 create mode 100644 src/views-components/dialog-forms/move-project-dialog.ts
 create mode 100644 src/views-components/dialog-forms/partial-copy-collection-dialog.ts
 create mode 100644 src/views-components/dialog-forms/update-collection-dialog.ts
 create mode 100644 src/views-components/dialog-forms/update-project-dialog.ts
 create mode 100644 src/views-components/dialog-move/dialog-move-to.tsx
 create mode 100644 src/views-components/dialog-upload/dialog-collection-files-upload.tsx
 create mode 100644 src/views-components/file-uploader/file-uploader.tsx
 create mode 100644 src/views-components/form-fields/collection-form-fields.tsx
 create mode 100644 src/views-components/form-fields/project-form-fields.tsx
 create mode 100644 src/views-components/side-panel-tree/side-panel-tree.tsx
 create mode 100644 src/views-components/side-panel/side-panel.tsx
 delete mode 100644 src/views-components/update-collection-dialog/update-collection-dialog..tsx
 delete mode 100644 src/views-components/update-project-dialog/update-project-dialog.tsx
 delete mode 100644 src/views/favorite-panel/favorite-panel-item.ts
 create mode 100644 src/views/process-panel/process-information-card.tsx
 create mode 100644 src/views/process-panel/process-panel-root.tsx
 create mode 100644 src/views/process-panel/process-panel.tsx
 create mode 100644 src/views/process-panel/subprocesses-card.tsx
 delete mode 100644 src/views/project-panel/project-panel-item.ts

       via  1baec2d74e64375ce1b410f6a66fc8c8c9848307 (commit)
       via  25691034b44b9323cae96c8db002826880ccfd7e (commit)
       via  f63f3a5360ae6381d4b332bf86ef52b4e22107fb (commit)
       via  cba0f400f56889778321bdc0fdcf6cee236f6a79 (commit)
       via  9b28d6d29d9609adc86e3fdc136873c3cf6114ed (commit)
       via  f53d651573ef8c358cbdf38c7a56c6aed8178b61 (commit)
       via  b026476240a6f347b579e03efd53a9043f8daa5a (commit)
       via  3d996002ab1f259b31d07858d9c5d0a780600a00 (commit)
       via  9ccc7e8ebe82b97e219d65adeea8b03b2c9ed71a (commit)
       via  21ee15421471ce0f0aa4a1241cab3498c335d682 (commit)
       via  6149700b801fc2cdb83b0e700bbb319850ed471d (commit)
       via  2d887860caa003ddaf69d1f85ebdaf208e0b74c1 (commit)
       via  5163a70c5624a52c802a37d66b806b5e718c4151 (commit)
       via  c798ba784db88b406d27f3783501ab2800f5719a (commit)
       via  e2ea20e09a5e5a629eee78145f35a9ed443a5867 (commit)
       via  3bf48201c92fcb9827d134a96671f02035f544a6 (commit)
       via  4221f6e12bfbbf56ab8848e9c6c1b6b9eacbec64 (commit)
       via  78969103183f03a23557aa0b4d1739a0ff12dcb2 (commit)
       via  a54f5270f980d4c2c6143b6654fb96a57b7bf46c (commit)
       via  de519d0b84931f8ef5fb7d2aecdb67a911c3eabf (commit)
       via  1ca26fd87e061052b071e5039cc68c5a7434a8a5 (commit)
       via  5333321c0b65561a5e715236a5bc7fc319c8f1da (commit)
       via  4c9eb3858796cd5986d8397117549e15e19896e8 (commit)
       via  6a5c0fe0cd12635698d2b5a6df27b4291e5b0ecb (commit)
       via  9fbb245286171bc55fed5b5104361a1869a1d76b (commit)
       via  a6af19c842e41469fb832dff58d5a23747394a1c (commit)
       via  ae9841925d717e97a74f3ae17c414c638c56e496 (commit)
       via  d911869b4340a32575e3a2cdce26ebd543522e42 (commit)
       via  59b24ea9a90ba60563316a5c2ad4c7ce8a8c423d (commit)
       via  931bbc0730608697ddb30f5ad51d9cc19cca3679 (commit)
       via  0997bb068a2ecb8f6b0b13d22f3ef57ae1243405 (commit)
       via  e3b0f767bb84fa82188879e391b5feff15a3db0f (commit)
       via  c175f990704fdef165616125433e2079a00a3437 (commit)
       via  00acbabe840ee98597ef94751e22f48f44ee5777 (commit)
       via  9f4bca6531631fc5ed21435f31db36720d58512b (commit)
       via  dbde3a8cc8098e423fb7d7f7147ea8a664744957 (commit)
       via  d37d39ad8825b03c39915e1258e294abcf0c3b6a (commit)
       via  3d8c3da5fdc9488ac37d09211af8312e77ebebcb (commit)
       via  6a024c9a0ad6543bf95359b10bcd22aeec3e7dca (commit)
       via  cdc8a73914399a401642ca553e9d3d8b2d42db5c (commit)
       via  fb1ecf2421f8aac07d733d3bb56bb39312274f8c (commit)
       via  fb15af5c500ad8469240c59b17ff73b889bb022b (commit)
       via  4476731a9ec985c5abd97da453978af0dfa4406b (commit)
       via  cc493b89840b48f40c2beaf626994724331aa196 (commit)
       via  ed7a4222422dc52642365c83cc10ab0196da909a (commit)
       via  1a90c384645ab8880d68abb5dbee1d1193f80538 (commit)
       via  ddac62fc3f788162bd56bbd5bcacc2f9395c9cca (commit)
       via  64fcf842a75ade29706401a47759deab406f0dfd (commit)
       via  cda707f957a027a484f24f44090a4e5b995572a8 (commit)
       via  b979b48045c915f0ea95bb95d591f8ac306ddf06 (commit)
       via  5627bf1a83323d2b0364cb069564998eb8c6ca7a (commit)
       via  b4adbf55b9a1950d70e2e44c28efb13eb4d0f077 (commit)
       via  bef6136ae8f4e6d2ebae630940018a99946e6bda (commit)
       via  cdcdc08b57f7ae779d0b3f043bd255897579498d (commit)
       via  4157d0e93444cd1d2a631e7826f8cd831863b58a (commit)
       via  605e792e4854c7aad2f08e08fa7a8d9eba9d64a1 (commit)
       via  c3bec339e0f247f7cbc8698120b8ecf43629d3e7 (commit)
       via  fb6814e06cc846481043152b0d2ba5c88cc61f96 (commit)
       via  9bf2393f07c8a89eaf510a1e6ea3a8432303fcd6 (commit)
       via  1f0d4a9c57515816112baa3cb45bf97bec490737 (commit)
       via  d5e325adeee527001a70193bca5db4a02e726295 (commit)
       via  7b2c1a2e5b38246b9360fb062e66997ebfa888ea (commit)
       via  0c46a74e6c0397fa153c345857977f8654ec4471 (commit)
       via  09257d57b005094ea3752a7e90b90aa38518a0cf (commit)
       via  e6e91f83b899ef4a05a1b3af56d78388058c5e73 (commit)
       via  fc14bf232fe2cb77bf1f14ab0002fca606234214 (commit)
       via  ef649661d35999d3d6847861185172fac3e92db1 (commit)
       via  1e32e6134cd53c30cd8a9410572a443b37f76f2e (commit)
       via  1c0f11ed17dea5be97e8ca63385f979925f1fb08 (commit)
       via  d6d85de50096eb0053d58c5022fd4e949c830929 (commit)
       via  1bda4645781ebb80f6d0db901f857abff088d749 (commit)
       via  49e31d482873af1328b934bf8f07d8e1d00ce5b6 (commit)
       via  d842372e4f45ee06315e511529e65ae1d3f319a0 (commit)
       via  f0bdbd499c57a4a8f5db6a68411bfa8deb7ee291 (commit)
       via  a31e7b9a5c86f10239d93e327b792e0b1f8646b3 (commit)
       via  4beec12398b40d518e0e7c2671cea99c580433f7 (commit)
       via  71794c06557ccae7e54644ad23296aafde748d51 (commit)
       via  47eb02af0c2c7bc4f0f852400308033c72322af8 (commit)
       via  0cdeff59eefbd738d3bd87e2e666915b1e715715 (commit)
       via  2e9f1d88035d8ce2bf88b2881e8a3736fae7139b (commit)
       via  45cfc5acaa27151778f245bce76b027c06698b3d (commit)
       via  c4489d532c800a91ea66f3aaec98fc4a299e3e1e (commit)
       via  f4ed762732e8f5d2f7c4c08d5efbe92d4bce7f16 (commit)
       via  cad9f25fc5e75f6e4f09fe90abd42d0cd10eb492 (commit)
       via  e9a65be7cd7d5889d885794bf46ac3c6277eca3c (commit)
       via  f8a43920a3a9808e4aad77a73c5966b800e34882 (commit)
       via  9bad01c91c6c67d5067419ab709129ff1d1e6b18 (commit)
       via  067999ebaee9a0decd80d3251afa5b8c102e7907 (commit)
       via  e1405a5108ab48429606c9460595dad6bd2d82c0 (commit)
       via  540750a7749cb71ea0a8fde4b7a3689eeaa1c3dd (commit)
       via  2df6bac4eea43c9079641cd05262b29cbd285905 (commit)
       via  6ce4e6e255691116f2c8e229d45df571dffa6b9a (commit)
       via  135c3ebbca47d6a7a9fc63939e892fc63eebb891 (commit)
       via  4f0ce2a7fd797146981f8338c4f52bddf2705702 (commit)
       via  b478a2dc99c373634dffd5a1110f0fa3a53866ef (commit)
       via  13810782091128f6cf5b346243be77f5c1776d2c (commit)
       via  fe297524c4e7f0e7e43a5b946ec492edf12e2f67 (commit)
       via  625be3c28daeeab5e40d56648ae47b345a9b5ce2 (commit)
       via  0e9bf3f713937af55e9b8677ca8c87eeddeae4da (commit)
       via  7d8ec252adacdae04d5ee9d4c1b79e64267b1288 (commit)
       via  d0f49b7683fe607b6165c0232ff220080142eb57 (commit)
       via  e7a3d6c396fc36acf84ca9b152374b29d208816c (commit)
       via  2c2bd28224c2480276ae714c54ab1be0a6896efd (commit)
       via  57a762c6148cfee04635bdb06627b92e65ff3348 (commit)
       via  fdc1e3360333480c1325e69f59156e2c0ab4fe30 (commit)
       via  8583d365a7b7fb2d58fc486cbbfbf0ec952a8498 (commit)
       via  4f6816fb789db969073c14c3171ceb46d5ff4bc3 (commit)
       via  6661ea52b2e50ae43b421548007389fe3fa64fe6 (commit)
       via  208eaf2ad624e4ea6f0b084234b4116a4c55882c (commit)
       via  dd30e03643f9b093c1fe05b05481f75906faa0e7 (commit)
       via  5607033651dbfd135a49ac5af65def77269f7a7d (commit)
       via  90df34ba0e84b5735c48382362284b5f0382dd0e (commit)
       via  c067c93c2159b21980551e2d87ebb10f985cba84 (commit)
       via  a1310aae9f24935feae463542e9bfde298a5d9e4 (commit)
       via  da38a12dc33bcab311dcb73153b2ebf3483d2a60 (commit)
       via  7e52071485e119755819308658d10e461ed1c28a (commit)
       via  b12a180cf035192be3e22dfa5a2200d4969ce51a (commit)
       via  ad819c323f1623d357398e3b1344e0a8f1d38366 (commit)
       via  1700eb6123c054b185034c420d69ac41e2a749e6 (commit)
       via  e478b4da43dcf7c0625b145c906e39d77fb5941f (commit)
       via  b002d610f3e0e7a181e8119a3604c7577e0348f4 (commit)
       via  f135906f33ad05916bcc72cfd379217071484a09 (commit)
       via  5e11adf6c0acffbd9e78f6a0a1fe39bcecf75047 (commit)
       via  9c2399fe7eb9bffabb6c2316cc4bfb4068330efa (commit)
       via  15987424ea63c887e3ec5f8a1c42cc985301b884 (commit)
       via  8c0a8c26b37118e6e516da2cfaa19b26b8f1e5eb (commit)
       via  9f472b932176e09be950115feab148da3be5c321 (commit)
       via  d461d4da5432434916f21b0308c20148210a32f2 (commit)
       via  656ad1c0e84b1d9297373e13c385248dff05192e (commit)
       via  838af71bfe460c7f5a03121acf8a4d239893cdac (commit)
       via  d6a65f155ca546aea3a777e73076c2c80f2c88cc (commit)
       via  8d493281629ff304711a1175f59f6d477ae510e2 (commit)
       via  6ff11e5f5dba8e02a176bbe9455ba916e8990028 (commit)
       via  9c73ce8f871a403f2d9e15fbb15ef58fa6adc64c (commit)
       via  96e19f561cb0b3936e19c7659a7481615d0773d4 (commit)
       via  45d9b3d7298daf82bfb93c82e4f2f8c125c45e79 (commit)
       via  353c39122f1ebbcb47cf5ae4d2ea641b60439614 (commit)
       via  dffffdfbf3e0bce8a7cd4d6755d71d8084615b33 (commit)
       via  900081d75c21b924f4da42a94c1ca4ef7084a3df (commit)
       via  e2396eed71c581a862a151a8acd00abaae76a5e9 (commit)
       via  53022b7d9f1cad38d709f92e70b86f44cd436c18 (commit)
       via  33608c44bf33ab330ad1267ab8d56c08634673b5 (commit)
       via  31df208339af5e30665455e193cdbde90dabaf1d (commit)
       via  1bd016d1f30c72353e5e3b086dd9778b74efb516 (commit)
       via  9cbd6231837df8564953330fc63ce0fb9b9454cc (commit)
       via  75db1e88374315f84fdfb30faee84253e1383a28 (commit)
       via  e6ce4acd9ac2ed0d93e5aafe8df8fb1e16ee956d (commit)
       via  fa26c423867036cbc290ba68bf001a4bea76fddd (commit)
       via  80a9ee470d066aeb95e84338c8f57d558f715113 (commit)
       via  c0e5f8f04311c22ca8e0be32c1c1da88ae1cceec (commit)
       via  18bb503b7ba881d9c6b09446e3ecb70eb11fa17e (commit)
       via  57c0b10d162183c24cf9bab52f85ffe3d2754b32 (commit)
       via  8acf2e5e84bb64fe57ae0eb819d9a4556af10afa (commit)
       via  964b7f2cea81f087bbaddc94c9eeb08bab945742 (commit)
       via  01e4b29eb65a760650476a8f5f059413130921f4 (commit)
       via  07d646d908bcbd2b3de9ad22c02a93b65d04af2a (commit)
       via  fafe45583ad0aaa1a2325004a953d3154e6c15a9 (commit)
       via  42f46bf682cf6590b1d87424d616c5c9b9c9154d (commit)
       via  5a98bccbd21405c97baa35c288898fac16c2d567 (commit)
       via  b4f091ebd9f78c76cc7a182802d656f55c722f6d (commit)
       via  c1787278642d2ef02234ea27f94aaae9cdd52d40 (commit)
       via  f70757a56d4d119c0da5d675242268be786f0cbc (commit)
       via  8fb7517405c53a71782863fcb5863f9b5a948964 (commit)
       via  0b94fe12e8705098542008753ce5a5caa12a4218 (commit)
       via  37421f3062f84e7a5ce81606eab758a43b987b27 (commit)
       via  c4c906cb232d8974858e4da2393fb7a83a24fbd0 (commit)
       via  25aa8a7c81609525d300f38bc5b7d2344c4e1cdf (commit)
       via  f45dd93f467fe02c33908c0b4b3ff8ba01827bc9 (commit)
       via  f2b031de2183439f8aade2f290cd0e3f95f6438c (commit)
       via  67d63d61aa5a1f1bc1bb85bf6b788e6c0d21e298 (commit)
       via  158a4936f754ad78004e1bbcbb5af053a6a4073a (commit)
       via  2496ba1b64722e0dbcd55796d436ae8d5379e13d (commit)
       via  5a40b5b582b25e410622da8b7e484fad757f6bd1 (commit)
       via  8a057a6a69f4182cd3adc67c7d1071832ffeaa0b (commit)
       via  f0ac109691369516a5adf9370838cb4eacf16a45 (commit)
       via  1c1a44191e11b62a0640551ea73f2281b2ed9a7f (commit)
       via  5ca3e3c15a9741bd2e4dcaada9e7e0edc22306df (commit)
       via  e13e7dd672160e4ab5569c24133f4f6032db4a9a (commit)
       via  d260d2473cd7faefb0f06cedfb26ef5abda7e012 (commit)
       via  8c259b5122df8254613e8d23b0d860a7b1b37b41 (commit)
       via  a49f059145a3054052e1c79555bdeadf660d1c6a (commit)
       via  42c529f08bbeccaeb0d4c07f639c74504569c621 (commit)
       via  8b501e5ced1608766db8d16022d34c1ad363fcc8 (commit)
      from  f1065fb7260dd562ea2e826e9cbc508d7932ecca (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 1baec2d74e64375ce1b410f6a66fc8c8c9848307
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date:   Fri Aug 31 07:39:23 2018 +0200

    Adjust for new code structure
    
    Feature #13828
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>

diff --git a/src/store/navigation/navigation-action.ts b/src/store/navigation/navigation-action.ts
index 188acf1..2c0f209 100644
--- a/src/store/navigation/navigation-action.ts
+++ b/src/store/navigation/navigation-action.ts
@@ -28,6 +28,8 @@ export const navigateTo = (uuid: string) =>
 
 export const navigateToFavorites = push(Routes.FAVORITES);
 
+export const navigateToTrash = push(Routes.TRASH);
+
 export const navigateToProject = compose(push, getProjectUrl);
 
 export const navigateToCollection = compose(push, getCollectionUrl);
diff --git a/src/store/side-panel/side-panel-action.ts b/src/store/side-panel/side-panel-action.ts
index 8c7ef4a..3b66157 100644
--- a/src/store/side-panel/side-panel-action.ts
+++ b/src/store/side-panel/side-panel-action.ts
@@ -4,7 +4,7 @@
 
 import { Dispatch } from 'redux';
 import { isSidePanelTreeCategory, SidePanelTreeCategory } from '~/store/side-panel-tree/side-panel-tree-actions';
-import { navigateToFavorites, navigateTo } from '../navigation/navigation-action';
+import { navigateToFavorites, navigateTo, navigateToTrash } from '../navigation/navigation-action';
 import { snackbarActions } from '~/store/snackbar/snackbar-actions';
 
 export const navigateFromSidePanel = (id: string) =>
@@ -20,6 +20,8 @@ const getSidePanelTreeCategoryAction = (id: string) => {
     switch (id) {
         case SidePanelTreeCategory.FAVORITES:
             return navigateToFavorites;
+        case SidePanelTreeCategory.TRASH:
+            return navigateToTrash;
         default:
             return sidePanelTreeCategoryNotAvailable(id);
     }
@@ -29,4 +31,4 @@ const sidePanelTreeCategoryNotAvailable = (id: string) =>
     snackbarActions.OPEN_SNACKBAR({
         message: `${id} not available`,
         hideDuration: 3000,
-    });
\ No newline at end of file
+    });
diff --git a/src/views/project-panel/project-panel.tsx b/src/views/project-panel/project-panel.tsx
index 3c7dd30..622c5d8 100644
--- a/src/views/project-panel/project-panel.tsx
+++ b/src/views/project-panel/project-panel.tsx
@@ -26,6 +26,7 @@ import { PROJECT_PANEL_CURRENT_UUID } from '~/store/project-panel/project-panel-
 import { openCollectionCreateDialog } from '../../store/collections/collection-create-actions';
 import { openProjectCreateDialog } from '~/store/projects/project-create-actions';
 import { ContainerRequestState } from "~/models/container-request";
+import { ProjectResource } from "~/models/project";
 
 type CssRules = 'root' | "toolbar" | "button";
 
@@ -57,14 +58,14 @@ export interface ProjectPanelFilter extends DataTableFilterItem {
     type: ResourceKind | ContainerRequestState;
 }
 
-export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
+export const projectPanelColumns: DataColumns<ProjectResource, ProjectPanelFilter> = [
     {
         name: ProjectPanelColumnNames.NAME,
         selected: true,
         configurable: true,
         sortDirection: SortDirection.ASC,
         filters: [],
-        render: uuid => <ResourceName uuid={uuid} />,
+        render: res => <ResourceName uuid={res.uuid} />,
         width: "450px"
     },
     {
@@ -89,7 +90,7 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
                 type: ContainerRequestState.UNCOMMITTED
             }
         ],
-        render: uuid => <ProcessStatus uuid={uuid} />,
+        render: res => <ProcessStatus uuid={res.uuid} />,
         width: "75px"
     },
     {
@@ -114,7 +115,7 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
                 type: ResourceKind.PROJECT
             }
         ],
-        render: uuid => <ResourceType uuid={uuid} />,
+        render: res => <ResourceType uuid={res.uuid} />,
         width: "125px"
     },
     {
@@ -123,7 +124,7 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: [],
-        render: uuid => <ResourceOwner uuid={uuid} />,
+        render: res => <ResourceOwner uuid={res.uuid} />,
         width: "200px"
     },
     {
@@ -132,7 +133,7 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: [],
-        render: uuid => <ResourceFileSize uuid={uuid} />,
+        render: res => <ResourceFileSize uuid={res.uuid} />,
         width: "50px"
     },
     {
@@ -141,7 +142,7 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: [],
-        render: uuid => <ResourceLastModifiedDate uuid={uuid} />,
+        render: res => <ResourceLastModifiedDate uuid={res.uuid} />,
         width: "150px"
     }
 ];
@@ -194,10 +195,16 @@ export const ProjectPanel = withStyles(styles)(
                 this.props.dispatch<any>(openCollectionCreateDialog(this.props.currentItemId));
             }
 
-            handleContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) => {
-                const kind = resourceKindToContextMenuKind(resourceUuid);
+            handleContextMenu = (event: React.MouseEvent<HTMLElement>, resource: ProjectResource) => {
+                const kind = resourceKindToContextMenuKind(resource.uuid);
                 if (kind) {
-                    this.props.dispatch<any>(openContextMenu(event, { name: '', uuid: resourceUuid, kind }));
+                    this.props.dispatch<any>(openContextMenu(event, {
+                        name: resource.name,
+                        uuid: resource.uuid,
+                        ownerUuid: resource.ownerUuid,
+                        isTrashed: resource.isTrashed,
+                        kind
+                    }));
                 }
             }
 
diff --git a/src/views/trash-panel/trash-panel.tsx b/src/views/trash-panel/trash-panel.tsx
index bfb9931..3c25a3e 100644
--- a/src/views/trash-panel/trash-panel.tsx
+++ b/src/views/trash-panel/trash-panel.tsx
@@ -20,6 +20,7 @@ import { TrashIcon } from '~/components/icon/icon';
 import { TRASH_PANEL_ID } from "~/store/trash-panel/trash-panel-action";
 import { getProperty } from "~/store/properties/properties";
 import { PROJECT_PANEL_CURRENT_UUID } from "~/store/project-panel/project-panel-action";
+import { openContextMenu, resourceKindToContextMenuKind } from "~/store/context-menu/context-menu-actions";
 
 type CssRules = "toolbar" | "button";
 
@@ -140,6 +141,13 @@ export const TrashPanel = withStyles(styles)(
                     defaultMessages={['Your trash list is empty.']}/>
                 ;
             }
+
+            handleContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) => {
+                const kind = resourceKindToContextMenuKind(resourceUuid);
+                if (kind) {
+                    this.props.dispatch<any>(openContextMenu(event, { name: '', uuid: resourceUuid, kind }));
+                }
+            }
         }
     )
 );

commit 25691034b44b9323cae96c8db002826880ccfd7e
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date:   Thu Aug 30 23:44:55 2018 +0200

    Post merge fixes
    
    Feature #13828
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>

diff --git a/src/models/container-request.ts b/src/models/container-request.ts
new file mode 100644
index 0000000..78891c7
--- /dev/null
+++ b/src/models/container-request.ts
@@ -0,0 +1,41 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Resource, ResourceKind } from "./resource";
+import { MountType } from "~/models/mount-types";
+import { RuntimeConstraints } from './runtime-constraints';
+import { SchedulingParameters } from './scheduling-parameters';
+
+export enum ContainerRequestState {
+    UNCOMMITTED = "Uncommitted",
+    COMMITTED = "Committed",
+    FINAL = "Final"
+}
+
+export interface ContainerRequestResource extends Resource {
+    kind: ResourceKind.CONTAINER_REQUEST;
+    name: string;
+    description: string;
+    properties: any;
+    state: ContainerRequestState;
+    requestingContainerUuid: string | null;
+    containerUuid: string | null;
+    containerCountMax: number;
+    mounts: MountType[];
+    runtimeConstraints: RuntimeConstraints;
+    schedulingParameters: SchedulingParameters;
+    containerImage: string;
+    environment: any;
+    cwd: string;
+    command: string[];
+    outputPath: string;
+    outputName: string;
+    outputTtl: number;
+    priority: number | null;
+    expiresAt: string;
+    useExisting: boolean;
+    logUuid: string | null;
+    outputUuid: string | null;
+    filters: string;
+}
diff --git a/src/models/process.ts b/src/models/process.ts
index bcfbd3a..1e04cb1 100644
--- a/src/models/process.ts
+++ b/src/models/process.ts
@@ -2,37 +2,6 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import { Resource, ResourceKind } from "./resource";
+import { ContainerRequestResource } from "./container-request";
 
-export enum ProcessState {
-    UNCOMMITTED = "Uncommitted",
-    COMMITTED = "Committed",
-    FINAL = "Final"
-}
-
-export interface ProcessResource extends Resource {
-    kind: ResourceKind.PROCESS;
-    name: string;
-    description: string;
-    properties: any;
-    state: ProcessState;
-    requestingContainerUuid: string;
-    containerUuid: string;
-    containerCountMax: number;
-    mounts: any;
-    runtimeConstraints: any;
-    schedulingParameters: any;
-    containerImage: string;
-    environment: any;
-    cwd: string;
-    command: string[];
-    outputPath: string;
-    outputName: string;
-    outputTtl: number;
-    priority: number;
-    expiresAt: string;
-    useExisting: boolean;
-    logUuid: string;
-    outputUuid: string;
-    filters: string;
-}
+export type ProcessResource = ContainerRequestResource;
diff --git a/src/routes/routes.ts b/src/routes/routes.ts
index 20dd135..d119321 100644
--- a/src/routes/routes.ts
+++ b/src/routes/routes.ts
@@ -6,9 +6,9 @@ import { History, Location } from 'history';
 import { RootStore } from '~/store/store';
 import { matchPath } from 'react-router';
 import { ResourceKind, RESOURCE_UUID_PATTERN, extractUuidKind } from '~/models/resource';
-import { getProjectUrl } from '../models/project';
+import { getProjectUrl } from '~/models/project';
 import { getCollectionUrl } from '~/models/collection';
-import { loadProject, loadFavorites, loadCollection } from '~/store/workbench/workbench-actions';
+import { loadProject, loadFavorites, loadCollection, loadTrash } from '~/store/workbench/workbench-actions';
 import { loadProcess } from '~/store/processes/processes-actions';
 
 export const Routes = {
@@ -18,6 +18,7 @@ export const Routes = {
     COLLECTIONS: `/collections/:id(${RESOURCE_UUID_PATTERN})`,
     PROCESSES: `/processes/:id(${RESOURCE_UUID_PATTERN})`,
     FAVORITES: '/favorites',
+    TRASH: '/trash'
 };
 
 export const getResourceUrl = (uuid: string) => {
@@ -40,15 +41,18 @@ export const addRouteChangeHandlers = (history: History, store: RootStore) => {
     history.listen(handler);
 };
 
+export interface ResourceRouteParams {
+    id: string;
+}
+
 export const matchRootRoute = (route: string) =>
     matchPath(route, { path: Routes.ROOT, exact: true });
 
 export const matchFavoritesRoute = (route: string) =>
     matchPath(route, { path: Routes.FAVORITES });
 
-export interface ResourceRouteParams {
-    id: string;
-}
+export const matchTrashRoute = (route: string) =>
+    matchPath(route, { path: Routes.TRASH });
 
 export const matchProjectRoute = (route: string) =>
     matchPath<ResourceRouteParams>(route, { path: Routes.PROJECTS });
@@ -64,6 +68,7 @@ const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
     const projectMatch = matchProjectRoute(pathname);
     const collectionMatch = matchCollectionRoute(pathname);
     const favoriteMatch = matchFavoritesRoute(pathname);
+    const trashMatch = matchTrashRoute(pathname);
     const processMatch = matchProcessRoute(pathname);
     if (projectMatch) {
         store.dispatch(loadProject(projectMatch.params.id));
@@ -71,6 +76,8 @@ const handleLocationChange = (store: RootStore) => ({ pathname }: Location) => {
         store.dispatch(loadCollection(collectionMatch.params.id));
     } else if (favoriteMatch) {
         store.dispatch(loadFavorites());
+    } else if (trashMatch) {
+        store.dispatch(loadTrash());
     } else if (processMatch) {
         store.dispatch(loadProcess(processMatch.params.id));
     }
diff --git a/src/services/ancestors-service/ancestors-service.ts b/src/services/ancestors-service/ancestors-service.ts
index 1cd42fb..daab58b 100644
--- a/src/services/ancestors-service/ancestors-service.ts
+++ b/src/services/ancestors-service/ancestors-service.ts
@@ -6,7 +6,7 @@ import { GroupsService } from "~/services/groups-service/groups-service";
 import { UserService } from '../user-service/user-service';
 import { GroupResource } from '~/models/group';
 import { UserResource } from '~/models/user';
-import { extractUuidObjectType, ResourceObjectType } from "~/models/resource";
+import { extractUuidObjectType, ResourceObjectType, TrashResource } from "~/models/resource";
 
 export class AncestorService {
     constructor(
@@ -14,7 +14,7 @@ export class AncestorService {
         private userService: UserService
     ) { }
 
-    async ancestors(uuid: string, rootUuid: string): Promise<Array<UserResource | GroupResource>> {
+    async ancestors(uuid: string, rootUuid: string): Promise<Array<UserResource | GroupResource | TrashResource>> {
         const service = this.getService(extractUuidObjectType(uuid));
         if (service) {
             const resource = await service.get(uuid);
@@ -41,4 +41,4 @@ export class AncestorService {
                 return undefined;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/services/collection-service/collection-service.ts b/src/services/collection-service/collection-service.ts
index e26da78..581747b 100644
--- a/src/services/collection-service/collection-service.ts
+++ b/src/services/collection-service/collection-service.ts
@@ -11,6 +11,7 @@ import { AuthService } from "../auth-service/auth-service";
 import { mapTreeValues } from "~/models/tree";
 import { parseFilesResponse } from "./collection-service-files-response";
 import { fileToArrayBuffer } from "~/common/file";
+import * as _ from 'lodash';
 
 export type UploadProgress = (fileId: number, loaded: number, total: number, currentTime: number) => void;
 
@@ -84,5 +85,5 @@ export class CollectionService extends CommonResourceService<CollectionResource>
             })
             .then(CommonResourceService.mapResponseKeys);
     }
-    
+
 }
diff --git a/src/store/collections/collection-trash-actions.ts b/src/store/collections/collection-trash-actions.ts
deleted file mode 100644
index c6d4ee0..0000000
--- a/src/store/collections/collection-trash-actions.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import { Dispatch } from "redux";
-import { RootState } from "~/store/store";
-import { ServiceRepository } from "~/services/services";
-import { snackbarActions } from "~/store/snackbar/snackbar-actions";
-import { sidePanelActions } from "~/store/side-panel/side-panel-action";
-import { SidePanelId } from "~/store/side-panel/side-panel-reducer";
-import { trashPanelActions } from "~/store/trash-panel/trash-panel-action";
-import { getProjectList, projectActions } from "~/store/project/project-action";
-
-export const toggleCollectionTrashed = (resource: { uuid: string; name: string, isTrashed?: boolean, ownerUuid?: string }) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<any> => {
-        dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Working..." }));
-        if (resource.isTrashed) {
-            return services.collectionService.untrash(resource.uuid).then(() => {
-                dispatch<any>(getProjectList(resource.ownerUuid)).then(() => {
-                    dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(SidePanelId.PROJECTS));
-                    dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN({ itemId: resource.ownerUuid!!, open: true, recursive: true }));
-                });
-                dispatch(trashPanelActions.REQUEST_ITEMS());
-                dispatch(snackbarActions.CLOSE_SNACKBAR());
-                dispatch(snackbarActions.OPEN_SNACKBAR({
-                    message: "Restored from trash",
-                    hideDuration: 2000
-                }));
-            });
-        } else {
-            return services.collectionService.trash(resource.uuid).then(() => {
-                dispatch(snackbarActions.CLOSE_SNACKBAR());
-                dispatch(snackbarActions.OPEN_SNACKBAR({
-                    message: "Added to trash",
-                    hideDuration: 2000
-                }));
-            });
-        }
-    };
diff --git a/src/store/context-menu/context-menu-actions.ts b/src/store/context-menu/context-menu-actions.ts
index a1ed6c5..5ec3a84 100644
--- a/src/store/context-menu/context-menu-actions.ts
+++ b/src/store/context-menu/context-menu-actions.ts
@@ -27,7 +27,7 @@ export type ContextMenuResource = {
     description?: string;
     kind: ContextMenuKind;
     isTrashed?: boolean;
-}
+};
 
 export const openContextMenu = (event: React.MouseEvent<HTMLElement>, resource: ContextMenuResource) =>
     (dispatch: Dispatch) => {
diff --git a/src/store/project/project-action.ts b/src/store/project/project-action.ts
deleted file mode 100644
index bb5da19..0000000
--- a/src/store/project/project-action.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-import { default as unionize, ofType, UnionOf } from "unionize";
-
-import { ProjectResource } from "~/models/project";
-import { Dispatch } from "redux";
-import { FilterBuilder } from "~/common/api/filter-builder";
-import { RootState } from "../store";
-import { checkPresenceInFavorites } from "../favorites/favorites-actions";
-import { ServiceRepository } from "~/services/services";
-import { projectPanelActions } from "~/store/project-panel/project-panel-action";
-import { updateDetails } from "~/store/details-panel/details-panel-action";
-import { snackbarActions } from "~/store/snackbar/snackbar-actions";
-import { trashPanelActions } from "~/store/trash-panel/trash-panel-action";
-import { sidePanelActions } from "~/store/side-panel/side-panel-action";
-import { SidePanelId } from "~/store/side-panel/side-panel-reducer";
-
-export const projectActions = unionize({
-    OPEN_PROJECT_CREATOR: ofType<{ ownerUuid: string }>(),
-    CLOSE_PROJECT_CREATOR: ofType<{}>(),
-    CREATE_PROJECT: ofType<Partial<ProjectResource>>(),
-    CREATE_PROJECT_SUCCESS: ofType<ProjectResource>(),
-    OPEN_PROJECT_UPDATER: ofType<{ uuid: string}>(),
-    CLOSE_PROJECT_UPDATER: ofType<{}>(),
-    UPDATE_PROJECT_SUCCESS: ofType<ProjectResource>(),
-    REMOVE_PROJECT: ofType<string>(),
-    PROJECTS_REQUEST: ofType<string>(),
-    PROJECTS_SUCCESS: ofType<{ projects: ProjectResource[], parentItemId?: string }>(),
-    TOGGLE_PROJECT_TREE_ITEM_OPEN: ofType<{ itemId: string, open?: boolean, recursive?: boolean }>(),
-    TOGGLE_PROJECT_TREE_ITEM_ACTIVE: ofType<{ itemId: string, active?: boolean, recursive?: boolean }>(),
-    RESET_PROJECT_TREE_ACTIVITY: ofType<string>()
-}, {
-    tag: 'type',
-    value: 'payload'
-});
-
-export const PROJECT_FORM_NAME = 'projectEditDialog';
-
-export const getProjectList = (parentUuid: string = '') =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        dispatch(projectActions.PROJECTS_REQUEST(parentUuid));
-        return services.projectService.list({
-            filters: new FilterBuilder()
-                .addEqual("ownerUuid", parentUuid)
-                .getFilters()
-        }).then(({ items: projects }) => {
-            dispatch(projectActions.PROJECTS_SUCCESS({ projects, parentItemId: parentUuid }));
-            dispatch<any>(checkPresenceInFavorites(projects.map(project => project.uuid)));
-            return projects;
-        });
-    };
-
-export const createProject = (project: Partial<ProjectResource>) =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const { ownerUuid } = getState().projects.creator;
-        const projectData = { ownerUuid, ...project };
-        dispatch(projectActions.CREATE_PROJECT(projectData));
-        return services.projectService
-            .create(projectData)
-            .then(project => dispatch(projectActions.CREATE_PROJECT_SUCCESS(project)));
-    };
-
-export const updateProject = (project: Partial<ProjectResource>) =>
-    (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
-        const { uuid } = getState().projects.updater;
-        return services.projectService
-            .update(uuid, project)
-            .then(project => {
-                dispatch(projectActions.UPDATE_PROJECT_SUCCESS(project));
-                dispatch(projectPanelActions.REQUEST_ITEMS());
-                dispatch<any>(getProjectList(project.ownerUuid));
-                dispatch<any>(updateDetails(project));
-            });
-    };
-
-export const toggleProjectTrashed = (resource: { uuid: string; name: string, isTrashed?: boolean, ownerUuid?: string }) =>
-    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<any> => {
-        dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Working..." }));
-        if (resource.isTrashed) {
-            return services.groupsService.untrash(resource.uuid).then(() => {
-                dispatch<any>(getProjectList(resource.ownerUuid)).then(() => {
-                    dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(SidePanelId.PROJECTS));
-                    dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN({ itemId: resource.ownerUuid!!, open: true, recursive: true }));
-                });
-                dispatch(trashPanelActions.REQUEST_ITEMS());
-                dispatch(snackbarActions.CLOSE_SNACKBAR());
-                dispatch(snackbarActions.OPEN_SNACKBAR({
-                    message: "Restored from trash",
-                    hideDuration: 2000
-                }));
-            });
-        } else {
-            return services.groupsService.trash(resource.uuid).then(() => {
-                dispatch<any>(getProjectList(resource.ownerUuid)).then(() => {
-                    dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN({ itemId: resource.ownerUuid!!, open: true, recursive: true }));
-                });
-                dispatch(snackbarActions.CLOSE_SNACKBAR());
-                dispatch(snackbarActions.OPEN_SNACKBAR({
-                    message: "Added to trash",
-                    hideDuration: 2000
-                }));
-            });
-        }
-    };
-
-export type ProjectAction = UnionOf<typeof projectActions>;
diff --git a/src/store/store.ts b/src/store/store.ts
index 584d05e..d2371e8 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -28,6 +28,8 @@ import { resourcesReducer } from '~/store/resources/resources-reducer';
 import { propertiesReducer } from './properties/properties-reducer';
 import { RootState } from './store';
 import { fileUploaderReducer } from './file-uploader/file-uploader-reducer';
+import { TrashPanelMiddlewareService } from "~/store/trash-panel/trash-panel-middleware-service";
+import { TRASH_PANEL_ID } from "~/store/trash-panel/trash-panel-action";
 
 const composeEnhancers =
     (process.env.NODE_ENV === 'development' &&
diff --git a/src/store/trash-panel/trash-panel-action.ts b/src/store/trash-panel/trash-panel-action.ts
index 84d5602..6be9322 100644
--- a/src/store/trash-panel/trash-panel-action.ts
+++ b/src/store/trash-panel/trash-panel-action.ts
@@ -3,6 +3,9 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import { bindDataExplorerActions } from "../data-explorer/data-explorer-action";
+import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
 
 export const TRASH_PANEL_ID = "trashPanel";
 export const trashPanelActions = bindDataExplorerActions(TRASH_PANEL_ID);
+
+export const loadTrashPanel = () => trashPanelActions.REQUEST_ITEMS();
diff --git a/src/store/trash-panel/trash-panel-middleware-service.ts b/src/store/trash-panel/trash-panel-middleware-service.ts
index 3a4da39..85bc0ad 100644
--- a/src/store/trash-panel/trash-panel-middleware-service.ts
+++ b/src/store/trash-panel/trash-panel-middleware-service.ts
@@ -8,7 +8,6 @@ import { DataColumns } from "~/components/data-table/data-table";
 import { ServiceRepository } from "~/services/services";
 import { SortDirection } from "~/components/data-table/data-column";
 import { FilterBuilder } from "~/common/api/filter-builder";
-import { checkPresenceInFavorites } from "../favorites/favorites-actions";
 import { trashPanelActions } from "./trash-panel-action";
 import { Dispatch, MiddlewareAPI } from "redux";
 import { OrderBuilder, OrderDirection } from "~/common/api/order-builder";
@@ -17,6 +16,7 @@ import { resourceToDataItem, TrashPanelItem } from "~/views/trash-panel/trash-pa
 import { TrashPanelColumnNames, TrashPanelFilter } from "~/views/trash-panel/trash-panel";
 import { ProjectResource } from "~/models/project";
 import { ProjectPanelColumnNames } from "~/views/project-panel/project-panel";
+import { updateFavorites } from "~/store/favorites/favorites-actions";
 
 export class TrashPanelMiddlewareService extends DataExplorerMiddlewareService {
     constructor(private services: ServiceRepository, id: string) {
@@ -64,7 +64,7 @@ export class TrashPanelMiddlewareService extends DataExplorerMiddlewareService {
                     page: Math.floor(response.offset / response.limit),
                     rowsPerPage: response.limit
                 }));
-                api.dispatch<any>(checkPresenceInFavorites(response.items.map(item => item.uuid)));
+                api.dispatch<any>(updateFavorites(response.items.map(item => item.uuid)));
             })
             .catch(() => {
                 api.dispatch(trashPanelActions.SET_ITEMS({
diff --git a/src/store/trash/trash-actions.ts b/src/store/trash/trash-actions.ts
new file mode 100644
index 0000000..97d8185
--- /dev/null
+++ b/src/store/trash/trash-actions.ts
@@ -0,0 +1,66 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch } from "redux";
+import { RootState } from "~/store/store";
+import { ServiceRepository } from "~/services/services";
+import { snackbarActions } from "~/store/snackbar/snackbar-actions";
+import { trashPanelActions } from "~/store/trash-panel/trash-panel-action";
+
+export const toggleProjectTrashed = (resource: { uuid: string; name: string, isTrashed?: boolean, ownerUuid?: string }) =>
+    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<any> => {
+        dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Working..." }));
+        if (resource.isTrashed) {
+            return services.groupsService.untrash(resource.uuid).then(() => {
+                // dispatch<any>(getProjectList(resource.ownerUuid)).then(() => {
+                //     dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(SidePanelId.PROJECTS));
+                //     dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN({ itemId: resource.ownerUuid!!, open: true, recursive: true }));
+                // });
+                dispatch(trashPanelActions.REQUEST_ITEMS());
+                dispatch(snackbarActions.CLOSE_SNACKBAR());
+                dispatch(snackbarActions.OPEN_SNACKBAR({
+                    message: "Restored from trash",
+                    hideDuration: 2000
+                }));
+            });
+        } else {
+            return services.groupsService.trash(resource.uuid).then(() => {
+                // dispatch<any>(getProjectList(resource.ownerUuid)).then(() => {
+                //     dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN({ itemId: resource.ownerUuid!!, open: true, recursive: true }));
+                // });
+                dispatch(snackbarActions.CLOSE_SNACKBAR());
+                dispatch(snackbarActions.OPEN_SNACKBAR({
+                    message: "Added to trash",
+                    hideDuration: 2000
+                }));
+            });
+        }
+    };
+
+export const toggleCollectionTrashed = (resource: { uuid: string; name: string, isTrashed?: boolean, ownerUuid?: string }) =>
+    async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise<any> => {
+        dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Working..." }));
+        if (resource.isTrashed) {
+            return services.collectionService.untrash(resource.uuid).then(() => {
+                // dispatch<any>(getProjectList(resource.ownerUuid)).then(() => {
+                //     dispatch(sidePanelActions.TOGGLE_SIDE_PANEL_ITEM_OPEN(SidePanelId.PROJECTS));
+                //     dispatch(projectActions.TOGGLE_PROJECT_TREE_ITEM_OPEN({ itemId: resource.ownerUuid!!, open: true, recursive: true }));
+                // });
+                dispatch(trashPanelActions.REQUEST_ITEMS());
+                dispatch(snackbarActions.CLOSE_SNACKBAR());
+                dispatch(snackbarActions.OPEN_SNACKBAR({
+                    message: "Restored from trash",
+                    hideDuration: 2000
+                }));
+            });
+        } else {
+            return services.collectionService.trash(resource.uuid).then(() => {
+                dispatch(snackbarActions.CLOSE_SNACKBAR());
+                dispatch(snackbarActions.OPEN_SNACKBAR({
+                    message: "Added to trash",
+                    hideDuration: 2000
+                }));
+            });
+        }
+    };
diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts
index 3c68c00..012ef90 100644
--- a/src/store/workbench/workbench-actions.ts
+++ b/src/store/workbench/workbench-actions.ts
@@ -30,6 +30,8 @@ import * as collectionUpdateActions from '~/store/collections/collection-update-
 import * as collectionMoveActions from '~/store/collections/collection-move-actions';
 import * as processesActions from '../processes/processes-actions';
 import { getProcess } from '../processes/process';
+import { trashPanelColumns } from "~/views/trash-panel/trash-panel";
+import { loadTrashPanel, trashPanelActions } from "~/store/trash-panel/trash-panel-action";
 
 
 export const loadWorkbench = () =>
@@ -41,6 +43,7 @@ export const loadWorkbench = () =>
             if (userResource) {
                 dispatch(projectPanelActions.SET_COLUMNS({ columns: projectPanelColumns }));
                 dispatch(favoritePanelActions.SET_COLUMNS({ columns: favoritePanelColumns }));
+                dispatch(trashPanelActions.SET_COLUMNS({ columns: trashPanelColumns }));
                 dispatch<any>(initSidePanelTree());
                 if (router.location) {
                     const match = matchRootRoute(router.location.pathname);
@@ -63,6 +66,12 @@ export const loadFavorites = () =>
         dispatch<any>(setSidePanelBreadcrumbs(SidePanelTreeCategory.FAVORITES));
     };
 
+export const loadTrash = () =>
+    (dispatch: Dispatch) => {
+        dispatch<any>(activateSidePanelTreeItem(SidePanelTreeCategory.TRASH));
+        dispatch<any>(loadTrashPanel());
+        dispatch<any>(setSidePanelBreadcrumbs(SidePanelTreeCategory.TRASH));
+    };
 
 export const loadProject = (uuid: string) =>
     async (dispatch: Dispatch) => {
@@ -204,4 +213,4 @@ const reloadProjectMatchingUuid = (matchingUuids: string[]) =>
         if (currentProjectPanelUuid && matchingUuids.some(uuid => uuid === currentProjectPanelUuid)) {
             dispatch<any>(loadProject(currentProjectPanelUuid));
         }
-    };
\ No newline at end of file
+    };
diff --git a/src/views-components/context-menu/action-sets/collection-action-set.ts b/src/views-components/context-menu/action-sets/collection-action-set.ts
index f260036..a7d16c6 100644
--- a/src/views-components/context-menu/action-sets/collection-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-action-set.ts
@@ -11,7 +11,7 @@ import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-acti
 import { openMoveCollectionDialog } from '~/store/collections/collection-move-actions';
 import { openCollectionCopyDialog } from "~/store/collections/collection-copy-actions";
 import { ToggleTrashAction } from "~/views-components/context-menu/actions/trash-action";
-import { toggleCollectionTrashed } from "~/store/collections/collection-trash-actions";
+import { toggleCollectionTrashed } from "~/store/trash/trash-actions";
 
 export const collectionActionSet: ContextMenuActionSet = [[
     {
diff --git a/src/views-components/context-menu/action-sets/collection-resource-action-set.ts b/src/views-components/context-menu/action-sets/collection-resource-action-set.ts
index a1df838..f1df0c0 100644
--- a/src/views-components/context-menu/action-sets/collection-resource-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-resource-action-set.ts
@@ -11,6 +11,7 @@ import { openCollectionUpdateDialog } from "~/store/collections/collection-updat
 import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
 import { openMoveCollectionDialog } from '~/store/collections/collection-move-actions';
 import { openCollectionCopyDialog } from '~/store/collections/collection-copy-actions';
+import { toggleCollectionTrashed } from "~/store/trash/trash-actions";
 
 export const collectionResourceActionSet: ContextMenuActionSet = [[
     {
diff --git a/src/views-components/context-menu/action-sets/project-action-set.ts b/src/views-components/context-menu/action-sets/project-action-set.ts
index d2412e7..eca395b 100644
--- a/src/views-components/context-menu/action-sets/project-action-set.ts
+++ b/src/views-components/context-menu/action-sets/project-action-set.ts
@@ -2,32 +2,30 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import { reset, initialize } from "redux-form";
-
 import { ContextMenuActionSet } from "../context-menu-action-set";
-import { projectActions, PROJECT_FORM_NAME, toggleProjectTrashed } from "~/store/project/project-action";
-import { NewProjectIcon, RenameIcon } from "~/components/icon/icon";
+import { NewProjectIcon, RenameIcon, CopyIcon, MoveToIcon } from "~/components/icon/icon";
 import { ToggleFavoriteAction } from "../actions/favorite-action";
 import { toggleFavorite } from "~/store/favorites/favorites-actions";
 import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
-import { PROJECT_CREATE_DIALOG } from "../../dialog-create/dialog-project-create";
+import { openMoveProjectDialog } from '~/store/projects/project-move-actions';
+import { openProjectCreateDialog } from '~/store/projects/project-create-actions';
+import { openProjectUpdateDialog } from '~/store/projects/project-update-actions';
 import { ToggleTrashAction } from "~/views-components/context-menu/actions/trash-action";
+import { toggleProjectTrashed } from "~/store/trash/trash-actions";
 
 export const projectActionSet: ContextMenuActionSet = [[
     {
         icon: NewProjectIcon,
         name: "New project",
         execute: (dispatch, resource) => {
-            dispatch(reset(PROJECT_CREATE_DIALOG));
-            dispatch(projectActions.OPEN_PROJECT_CREATOR({ ownerUuid: resource.uuid }));
+            dispatch<any>(openProjectCreateDialog(resource.uuid));
         }
     },
     {
         icon: RenameIcon,
         name: "Edit project",
         execute: (dispatch, resource) => {
-            dispatch(projectActions.OPEN_PROJECT_UPDATER({ uuid: resource.uuid }));
-            dispatch(initialize(PROJECT_FORM_NAME, { name: resource.name, description: resource.description }));
+            dispatch<any>(openProjectUpdateDialog(resource));
         }
     },
     {
@@ -43,5 +41,17 @@ export const projectActionSet: ContextMenuActionSet = [[
         execute: (dispatch, resource) => {
             dispatch<any>(toggleProjectTrashed(resource));
         }
-    }
+    },
+    {
+        icon: MoveToIcon,
+        name: "Move to",
+        execute: (dispatch, resource) => dispatch<any>(openMoveProjectDialog(resource))
+    },
+    {
+        icon: CopyIcon,
+        name: "Copy to project",
+        execute: (dispatch, resource) => {
+            // add code
+        }
+    },
 ]];
diff --git a/src/views/favorite-panel/favorite-panel.tsx b/src/views/favorite-panel/favorite-panel.tsx
index 62b037e..b915f98 100644
--- a/src/views/favorite-panel/favorite-panel.tsx
+++ b/src/views/favorite-panel/favorite-panel.tsx
@@ -9,7 +9,6 @@ import { DispatchProp, connect } from 'react-redux';
 import { DataColumns } from '~/components/data-table/data-table';
 import { RouteComponentProps } from 'react-router';
 import { DataTableFilterItem } from '~/components/data-table-filters/data-table-filters';
-import { ProcessState } from '~/models/process';
 import { SortDirection } from '~/components/data-table/data-column';
 import { ResourceKind } from '~/models/resource';
 import { resourceLabel } from '~/common/labels';
@@ -18,10 +17,10 @@ import { FAVORITE_PANEL_ID } from "~/store/favorite-panel/favorite-panel-action"
 import { ResourceFileSize, ResourceLastModifiedDate, ProcessStatus, ResourceType, ResourceOwner, ResourceName } from '~/views-components/data-explorer/renderers';
 import { FavoriteIcon } from '~/components/icon/icon';
 import { Dispatch } from 'redux';
-import { contextMenuActions, openContextMenu, resourceKindToContextMenuKind } from '~/store/context-menu/context-menu-actions';
-import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
-import { loadDetailsPanel } from '../../store/details-panel/details-panel-action';
+import { openContextMenu, resourceKindToContextMenuKind } from '~/store/context-menu/context-menu-actions';
+import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
 import { navigateTo } from '~/store/navigation/navigation-action';
+import { ContainerRequestState } from "~/models/container-request";
 
 type CssRules = "toolbar" | "button";
 
@@ -45,7 +44,7 @@ export enum FavoritePanelColumnNames {
 }
 
 export interface FavoritePanelFilter extends DataTableFilterItem {
-    type: ResourceKind | ProcessState;
+    type: ResourceKind | ContainerRequestState;
 }
 
 export const favoritePanelColumns: DataColumns<string, FavoritePanelFilter> = [
@@ -65,19 +64,19 @@ export const favoritePanelColumns: DataColumns<string, FavoritePanelFilter> = [
         sortDirection: SortDirection.NONE,
         filters: [
             {
-                name: ProcessState.COMMITTED,
+                name: ContainerRequestState.COMMITTED,
                 selected: true,
-                type: ProcessState.COMMITTED
+                type: ContainerRequestState.COMMITTED
             },
             {
-                name: ProcessState.FINAL,
+                name: ContainerRequestState.FINAL,
                 selected: true,
-                type: ProcessState.FINAL
+                type: ContainerRequestState.FINAL
             },
             {
-                name: ProcessState.UNCOMMITTED,
+                name: ContainerRequestState.UNCOMMITTED,
                 selected: true,
-                type: ProcessState.UNCOMMITTED
+                type: ContainerRequestState.UNCOMMITTED
             }
         ],
         render: uuid => <ProcessStatus uuid={uuid} />,
diff --git a/src/views/project-panel/project-panel.tsx b/src/views/project-panel/project-panel.tsx
index 37a6d20..3c7dd30 100644
--- a/src/views/project-panel/project-panel.tsx
+++ b/src/views/project-panel/project-panel.tsx
@@ -10,7 +10,6 @@ import { DataColumns } from '~/components/data-table/data-table';
 import { RouteComponentProps } from 'react-router';
 import { RootState } from '~/store/store';
 import { DataTableFilterItem } from '~/components/data-table-filters/data-table-filters';
-import { ProcessState } from '~/models/process';
 import { SortDirection } from '~/components/data-table/data-column';
 import { ResourceKind } from '~/models/resource';
 import { resourceLabel } from '~/common/labels';
@@ -18,17 +17,15 @@ import { ArvadosTheme } from '~/common/custom-theme';
 import { ResourceFileSize, ResourceLastModifiedDate, ProcessStatus, ResourceType, ResourceOwner } from '~/views-components/data-explorer/renderers';
 import { ProjectIcon } from '~/components/icon/icon';
 import { ResourceName } from '~/views-components/data-explorer/renderers';
-import { ResourcesState, getResource } from '~/store/resources/resources';
+import { ResourcesState } from '~/store/resources/resources';
 import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
-import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
-import { contextMenuActions, resourceKindToContextMenuKind, openContextMenu } from '~/store/context-menu/context-menu-actions';
-import { CollectionResource } from '~/models/collection';
-import { ProjectResource } from '~/models/project';
+import { resourceKindToContextMenuKind, openContextMenu } from '~/store/context-menu/context-menu-actions';
 import { navigateTo } from '~/store/navigation/navigation-action';
 import { getProperty } from '~/store/properties/properties';
 import { PROJECT_PANEL_CURRENT_UUID } from '~/store/project-panel/project-panel-action';
 import { openCollectionCreateDialog } from '../../store/collections/collection-create-actions';
 import { openProjectCreateDialog } from '~/store/projects/project-create-actions';
+import { ContainerRequestState } from "~/models/container-request";
 
 type CssRules = 'root' | "toolbar" | "button";
 
@@ -57,7 +54,7 @@ export enum ProjectPanelColumnNames {
 }
 
 export interface ProjectPanelFilter extends DataTableFilterItem {
-    type: ResourceKind | ProcessState;
+    type: ResourceKind | ContainerRequestState;
 }
 
 export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
@@ -77,19 +74,19 @@ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
         sortDirection: SortDirection.NONE,
         filters: [
             {
-                name: ProcessState.COMMITTED,
+                name: ContainerRequestState.COMMITTED,
                 selected: true,
-                type: ProcessState.COMMITTED
+                type: ContainerRequestState.COMMITTED
             },
             {
-                name: ProcessState.FINAL,
+                name: ContainerRequestState.FINAL,
                 selected: true,
-                type: ProcessState.FINAL
+                type: ContainerRequestState.FINAL
             },
             {
-                name: ProcessState.UNCOMMITTED,
+                name: ContainerRequestState.UNCOMMITTED,
                 selected: true,
-                type: ProcessState.UNCOMMITTED
+                type: ContainerRequestState.UNCOMMITTED
             }
         ],
         render: uuid => <ProcessStatus uuid={uuid} />,
diff --git a/src/views/trash-panel/trash-panel.tsx b/src/views/trash-panel/trash-panel.tsx
index fa73c0b..bfb9931 100644
--- a/src/views/trash-panel/trash-panel.tsx
+++ b/src/views/trash-panel/trash-panel.tsx
@@ -18,6 +18,8 @@ import { ArvadosTheme } from '~/common/custom-theme';
 import { renderName, renderType, renderFileSize, renderDate } from '~/views-components/data-explorer/renderers';
 import { TrashIcon } from '~/components/icon/icon';
 import { TRASH_PANEL_ID } from "~/store/trash-panel/trash-panel-action";
+import { getProperty } from "~/store/properties/properties";
+import { PROJECT_PANEL_CURRENT_UUID } from "~/store/project-panel/project-panel-action";
 
 type CssRules = "toolbar" | "button";
 
@@ -43,7 +45,7 @@ export interface TrashPanelFilter extends DataTableFilterItem {
     type: ResourceKind;
 }
 
-export const columns: DataColumns<TrashPanelItem, TrashPanelFilter> = [
+export const trashPanelColumns: DataColumns<TrashPanelItem, TrashPanelFilter> = [
     {
         name: TrashPanelColumnNames.NAME,
         selected: true,
@@ -119,16 +121,17 @@ interface TrashPanelActionProps {
     onItemRouteChange: (itemId: string) => void;
 }
 
-type TrashPanelProps = TrashPanelDataProps & TrashPanelActionProps & DispatchProp
-                        & WithStyles<CssRules> & RouteComponentProps<{ id: string }>;
+type TrashPanelProps = TrashPanelDataProps & TrashPanelActionProps & DispatchProp & WithStyles<CssRules>;
 
 export const TrashPanel = withStyles(styles)(
-    connect((state: RootState) => ({ currentItemId: state.projects.currentItemId }))(
+    connect((state: RootState) => ({
+        currentItemId: getProperty(PROJECT_PANEL_CURRENT_UUID)(state.properties),
+        resources: state.resources
+    }))(
         class extends React.Component<TrashPanelProps> {
             render() {
                 return <DataExplorer
                     id={TRASH_PANEL_ID}
-                    columns={columns}
                     onRowClick={this.props.onItemClick}
                     onRowDoubleClick={this.props.onItemDoubleClick}
                     onContextMenu={this.props.onContextMenu}
@@ -137,12 +140,6 @@ export const TrashPanel = withStyles(styles)(
                     defaultMessages={['Your trash list is empty.']}/>
                 ;
             }
-
-            componentWillReceiveProps({ match, currentItemId, onItemRouteChange }: TrashPanelProps) {
-                if (match.params.id !== currentItemId) {
-                    onItemRouteChange(match.params.id);
-                }
-            }
         }
     )
 );
diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx
index ea3a278..68bb970 100644
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@ -40,7 +40,6 @@ import { FilesUploadCollectionDialog } from '~/views-components/dialog-forms/fil
 import { PartialCopyCollectionDialog } from '~/views-components/dialog-forms/partial-copy-collection-dialog';
 
 import { TrashPanel } from "~/views/trash-panel/trash-panel";
-import { trashPanelActions } from "~/store/trash-panel/trash-panel-action";
 
 const APP_BAR_HEIGHT = 100;
 
@@ -170,7 +169,7 @@ export const Workbench = withStyles(styles)(
                                     <Route path={Routes.COLLECTIONS} component={CollectionPanel} />
                                     <Route path={Routes.FAVORITES} component={FavoritePanel} />
                                     <Route path={Routes.PROCESSES} component={ProcessPanel} />
-                                    <Route path="/trash" render={this.renderTrashPanel} />
+                                    <Route path={Routes.TRASH} component={TrashPanel} />
                                 </Switch>
                             </div>
                             {user && <DetailsPanel />}

commit f63f3a5360ae6381d4b332bf86ef52b4e22107fb
Merge: f1065fb cba0f40
Author: Daniel Kos <daniel.kos at contractors.roche.com>
Date:   Thu Aug 30 19:59:36 2018 +0200

    refs #master Merge branch 'origin/master' into 13828-trash-view
    
    # Conflicts:
    #       package.json
    #       src/models/container-request.ts
    #       src/models/resource.ts
    #       src/services/collection-service/collection-service.ts
    #       src/services/services.ts
    #       src/store/navigation/navigation-action.ts
    #       src/store/project/project-action.ts
    #       src/store/project/project-reducer.test.ts
    #       src/store/project/project-reducer.ts
    #       src/store/side-panel/side-panel-reducer.ts
    #       src/store/store.ts
    #       src/views-components/context-menu/action-sets/collection-action-set.ts
    #       src/views-components/context-menu/action-sets/collection-resource-action-set.ts
    #       src/views-components/context-menu/action-sets/project-action-set.ts
    #       src/views/favorite-panel/favorite-panel-item.ts
    #       src/views/project-panel/project-panel-item.ts
    #       src/views/workbench/workbench.tsx
    
    Arvados-DCO-1.1-Signed-off-by: Daniel Kos <daniel.kos at contractors.roche.com>

diff --cc src/models/resource.ts
index ab487da,3290bdf..aff1b24
--- a/src/models/resource.ts
+++ b/src/models/resource.ts
@@@ -14,14 -14,10 +14,16 @@@ export interface Resource 
      etag: string;
  }
  
 +export interface TrashResource extends Resource {
 +    trashAt: string;
 +    deleteAt: string;
 +    isTrashed: boolean;
 +}
 +
  export enum ResourceKind {
      COLLECTION = "arvados#collection",
+     CONTAINER = "arvados#container",
+     CONTAINER_REQUEST = "arvados#containerRequest",
      GROUP = "arvados#group",
      PROCESS = "arvados#containerRequest",
      PROJECT = "arvados#group",
diff --cc src/services/collection-service/collection-service.ts
index ad493b5,c0d61bd..e26da78
--- a/src/services/collection-service/collection-service.ts
+++ b/src/services/collection-service/collection-service.ts
@@@ -43,141 -28,44 +28,61 @@@ export class CollectionService extends 
          return Promise.reject();
      }
  
-     async deleteFile(collectionUuid: string, filePath: string) {
-         return this.webdavClient.delete(`/c=${collectionUuid}${filePath}`);
-     }
- 
-     extractFilesData(document: Document) {
-         const collectionUrlPrefix = /\/c=[0-9a-zA-Z\-]*/;
-         return Array
-             .from(document.getElementsByTagName('D:response'))
-             .slice(1) // omit first element which is collection itself
-             .map(element => {
-                 const name = getTagValue(element, 'D:displayname', '');
-                 const size = parseInt(getTagValue(element, 'D:getcontentlength', '0'), 10);
-                 const pathname = getTagValue(element, 'D:href', '');
-                 const nameSuffix = `/${name || ''}`;
-                 const directory = pathname
-                     .replace(collectionUrlPrefix, '')
-                     .replace(nameSuffix, '');
-                 const href = this.webdavClient.defaults.baseURL + pathname + '?api_token=' + this.authService.getApiToken();
- 
-                 const data = {
-                     url: href,
-                     id: `${directory}/${name}`,
-                     name,
-                     path: directory,
-                 };
- 
-                 return getTagValue(element, 'D:resourcetype', '')
-                     ? createCollectionDirectory(data)
-                     : createCollectionFile({ ...data, size });
- 
-             });
+     async deleteFiles(collectionUuid: string, filePaths: string[]) {
+         for (const path of filePaths) {
+             await this.webdavClient.delete(`c=${collectionUuid}${path}`);
+         }
      }
  
-     private readFile(file: File): Promise<ArrayBuffer> {
-         return new Promise<ArrayBuffer>(resolve => {
-             const reader = new FileReader();
-             reader.onload = () => {
-                 resolve(reader.result as ArrayBuffer);
-             };
- 
-             reader.readAsArrayBuffer(file);
-         });
+     async uploadFiles(collectionUuid: string, files: File[], onProgress?: UploadProgress) {
+         // files have to be uploaded sequentially
+         for (let idx = 0; idx < files.length; idx++) {
+             await this.uploadFile(collectionUuid, files[idx], idx, onProgress);
+         }
      }
  
-     private uploadFile(keepServiceHost: string, file: File, fileId: number, onProgress?: UploadProgress): Promise<CollectionFile> {
-         return this.readFile(file).then(content => {
-             return axios.post<string>(keepServiceHost, content, {
-                 headers: {
-                     'Content-Type': 'text/octet-stream'
-                 },
-                 onUploadProgress: (e: ProgressEvent) => {
-                     if (onProgress) {
-                         onProgress(fileId, e.loaded, e.total, Date.now());
-                     }
-                     console.log(`${e.loaded} / ${e.total}`);
-                 }
-             }).then(data => createCollectionFile({
-                 id: data.data,
-                 name: file.name,
-                 size: file.size
-             }));
-         });
+     moveFile(collectionUuid: string, oldPath: string, newPath: string) {
+         return this.webdavClient.move(
+             `c=${collectionUuid}${oldPath}`,
+             `c=${collectionUuid}${encodeURI(newPath)}`
+         );
      }
  
-     private async updateManifest(collectionUuid: string, files: CollectionFile[]): Promise<CollectionResource> {
-         const collection = await this.get(collectionUuid);
-         const manifest: KeepManifestStream[] = parseKeepManifestText(collection.manifestText);
- 
-         files.forEach(f => {
-             let kms = manifest.find(stream => stream.name === f.path);
-             if (!kms) {
-                 kms = {
-                     files: [],
-                     locators: [],
-                     name: f.path
-                 };
-                 manifest.push(kms);
+     private extendFileURL = (file: CollectionDirectory | CollectionFile) => ({
+         ...file,
+         url: this.webdavClient.defaults.baseURL + file.url + '?api_token=' + this.authService.getApiToken()
+     })
+ 
+     private async uploadFile(collectionUuid: string, file: File, fileId: number, onProgress: UploadProgress = () => { return; }) {
+         const fileURL = `c=${collectionUuid}/${file.name}`;
+         const fileContent = await fileToArrayBuffer(file);
+         const requestConfig = {
+             headers: {
+                 'Content-Type': 'text/octet-stream'
+             },
+             onUploadProgress: (e: ProgressEvent) => {
+                 onProgress(fileId, e.loaded, e.total, Date.now());
              }
-             kms.locators.push(f.id);
-             const len = kms.files.length;
-             const nextPos = len > 0
-                 ? parseInt(kms.files[len - 1].position, 10) + kms.files[len - 1].size
-                 : 0;
-             kms.files.push({
-                 name: f.name,
-                 position: nextPos.toString(),
-                 size: f.size
-             });
-         });
- 
-         console.log(manifest);
- 
-         const manifestText = stringifyKeepManifest(manifest);
-         const data = { ...collection, manifestText };
-         return this.update(collectionUuid, CommonResourceService.mapKeys(_.snakeCase)(data));
-     }
- 
-     uploadFiles(collectionUuid: string, files: File[], onProgress?: UploadProgress): Promise<CollectionResource | never> {
-         const filters = new FilterBuilder()
-             .addEqual("service_type", "proxy");
- 
-         return this.keepService.list({ filters: filters.getFilters() }).then(data => {
-             if (data.items && data.items.length > 0) {
-                 const serviceHost =
-                     (data.items[0].serviceSslFlag ? "https://" : "http://") +
-                     data.items[0].serviceHost +
-                     ":" + data.items[0].servicePort;
- 
-                 console.log("serviceHost", serviceHost);
+         };
+         return this.webdavClient.put(fileURL, fileContent, requestConfig);
  
-                 const files$ = files.map((f, idx) => this.uploadFile(serviceHost, f, idx, onProgress));
-                 return Promise.all(files$).then(values => {
-                     return this.updateManifest(collectionUuid, values);
-                 });
-             } else {
-                 return Promise.reject("Missing keep service host");
-             }
-         });
      }
  
 +    trash(uuid: string): Promise<CollectionResource> {
 +        return this.serverApi
 +            .post(this.resourceType + `${uuid}/trash`)
 +            .then(CommonResourceService.mapResponseKeys);
 +    }
 +
 +    untrash(uuid: string): Promise<CollectionResource> {
 +        const params = {
 +            ensure_unique_name: true
 +        };
 +        return this.serverApi
 +            .post(this.resourceType + `${uuid}/untrash`, {
 +                params: CommonResourceService.mapKeys(_.snakeCase)(params)
 +            })
 +            .then(CommonResourceService.mapResponseKeys);
 +    }
- 
++    
  }
diff --cc src/store/context-menu/context-menu-actions.ts
index 8e5eb1e,cf66a53..a1ed6c5
--- a/src/store/context-menu/context-menu-actions.ts
+++ b/src/store/context-menu/context-menu-actions.ts
@@@ -2,15 -2,92 +2,105 @@@
  //
  // SPDX-License-Identifier: AGPL-3.0
  
- import { default as unionize, ofType, UnionOf } from "unionize";
+ import { unionize, ofType, UnionOf } from '~/common/unionize';
  import { ContextMenuPosition, ContextMenuResource } from "./context-menu-reducer";
+ import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
+ import { Dispatch } from 'redux';
+ import { RootState } from '~/store/store';
+ import { getResource } from '../resources/resources';
+ import { ProjectResource } from '~/models/project';
 -import { UserResource } from '../../models/user';
++import { UserResource } from '~/models/user';
+ import { isSidePanelTreeCategory } from '~/store/side-panel-tree/side-panel-tree-actions';
+ import { extractUuidKind, ResourceKind } from '~/models/resource';
  
  export const contextMenuActions = unionize({
      OPEN_CONTEXT_MENU: ofType<{ position: ContextMenuPosition, resource: ContextMenuResource }>(),
      CLOSE_CONTEXT_MENU: ofType<{}>()
- }, {
-         tag: 'type',
-         value: 'payload'
-     });
+ });
  
  export type ContextMenuAction = UnionOf<typeof contextMenuActions>;
+ 
 -export const openContextMenu = (event: React.MouseEvent<HTMLElement>, resource: { name: string; uuid: string; description?: string; kind: ContextMenuKind; }) =>
++export type ContextMenuResource = {
++    name: string;
++    uuid: string;
++    ownerUuid: string;
++    description?: string;
++    kind: ContextMenuKind;
++    isTrashed?: boolean;
++}
++
++export const openContextMenu = (event: React.MouseEvent<HTMLElement>, resource: ContextMenuResource) =>
+     (dispatch: Dispatch) => {
+         event.preventDefault();
+         dispatch(
+             contextMenuActions.OPEN_CONTEXT_MENU({
+                 position: { x: event.clientX, y: event.clientY },
+                 resource
+             })
+         );
+     };
+ 
+ export const openRootProjectContextMenu = (event: React.MouseEvent<HTMLElement>, projectUuid: string) =>
+     (dispatch: Dispatch, getState: () => RootState) => {
 -        const userResource = getResource<UserResource>(projectUuid)(getState().resources);
 -        if (userResource) {
++        const res = getResource<UserResource>(projectUuid)(getState().resources);
++        if (res) {
+             dispatch<any>(openContextMenu(event, {
+                 name: '',
 -                uuid: userResource.uuid,
 -                kind: ContextMenuKind.ROOT_PROJECT
++                uuid: res.uuid,
++                ownerUuid: res.uuid,
++                kind: ContextMenuKind.ROOT_PROJECT,
++                isTrashed: false
+             }));
+         }
+     };
+ 
+ export const openProjectContextMenu = (event: React.MouseEvent<HTMLElement>, projectUuid: string) =>
+     (dispatch: Dispatch, getState: () => RootState) => {
 -        const projectResource = getResource<ProjectResource>(projectUuid)(getState().resources);
 -        if (projectResource) {
++        const res = getResource<ProjectResource>(projectUuid)(getState().resources);
++        if (res) {
+             dispatch<any>(openContextMenu(event, {
 -                name: projectResource.name,
 -                uuid: projectResource.uuid,
 -                kind: ContextMenuKind.PROJECT
++                name: res.name,
++                uuid: res.uuid,
++                kind: ContextMenuKind.PROJECT,
++                ownerUuid: res.ownerUuid,
++                isTrashed: res.isTrashed
+             }));
+         }
+     };
+ 
+ export const openSidePanelContextMenu = (event: React.MouseEvent<HTMLElement>, id: string) =>
+     (dispatch: Dispatch, getState: () => RootState) => {
+         if (!isSidePanelTreeCategory(id)) {
+             const kind = extractUuidKind(id);
+             if (kind === ResourceKind.USER) {
+                 dispatch<any>(openRootProjectContextMenu(event, id));
+             } else if (kind === ResourceKind.PROJECT) {
+                 dispatch<any>(openProjectContextMenu(event, id));
+             }
+         }
+     };
+ 
+ export const openProcessContextMenu = (event: React.MouseEvent<HTMLElement>) =>
+     (dispatch: Dispatch, getState: () => RootState) => {
+         const resource = {
+             uuid: '',
+             name: '',
+             description: '',
+             kind: ContextMenuKind.PROCESS
+         };
+         dispatch<any>(openContextMenu(event, resource));
+     };
+ 
+ export const resourceKindToContextMenuKind = (uuid: string) => {
+     const kind = extractUuidKind(uuid);
+     switch (kind) {
+         case ResourceKind.PROJECT:
+             return ContextMenuKind.PROJECT;
+         case ResourceKind.COLLECTION:
+             return ContextMenuKind.COLLECTION_RESOURCE;
+         case ResourceKind.USER:
+             return ContextMenuKind.ROOT_PROJECT;
+         default:
+             return;
+     }
+ };
diff --cc src/views-components/context-menu/action-sets/collection-action-set.ts
index c8fb3cb,b3fdc3f..f260036
--- a/src/views-components/context-menu/action-sets/collection-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-action-set.ts
@@@ -6,10 -6,10 +6,12 @@@ import { ContextMenuActionSet } from ".
  import { ToggleFavoriteAction } from "../actions/favorite-action";
  import { toggleFavorite } from "~/store/favorites/favorites-actions";
  import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, ProvenanceGraphIcon, AdvancedIcon, RemoveIcon } from "~/components/icon/icon";
- import { openUpdater } from "~/store/collections/updater/collection-updater-action";
+ import { openCollectionUpdateDialog } from "~/store/collections/collection-update-actions";
  import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
+ import { openMoveCollectionDialog } from '~/store/collections/collection-move-actions';
+ import { openCollectionCopyDialog } from "~/store/collections/collection-copy-actions";
 +import { ToggleTrashAction } from "~/views-components/context-menu/actions/trash-action";
 +import { toggleCollectionTrashed } from "~/store/collections/collection-trash-actions";
  
  export const collectionActionSet: ContextMenuActionSet = [[
      {
diff --cc src/views-components/context-menu/action-sets/collection-resource-action-set.ts
index dbc9e23,a299b93..a1df838
--- a/src/views-components/context-menu/action-sets/collection-resource-action-set.ts
+++ b/src/views-components/context-menu/action-sets/collection-resource-action-set.ts
@@@ -4,12 -4,12 +4,13 @@@
  
  import { ContextMenuActionSet } from "../context-menu-action-set";
  import { ToggleFavoriteAction } from "../actions/favorite-action";
++import { ToggleTrashAction } from "~/views-components/context-menu/actions/trash-action";
  import { toggleFavorite } from "~/store/favorites/favorites-actions";
  import { RenameIcon, ShareIcon, MoveToIcon, CopyIcon, DetailsIcon, RemoveIcon } from "~/components/icon/icon";
- import { openUpdater } from "~/store/collections/updater/collection-updater-action";
+ import { openCollectionUpdateDialog } from "~/store/collections/collection-update-actions";
  import { favoritePanelActions } from "~/store/favorite-panel/favorite-panel-action";
- import { ToggleTrashAction } from "~/views-components/context-menu/actions/trash-action";
- import { toggleCollectionTrashed } from "~/store/collections/collection-trash-actions";
+ import { openMoveCollectionDialog } from '~/store/collections/collection-move-actions';
+ import { openCollectionCopyDialog } from '~/store/collections/collection-copy-actions';
  
  export const collectionResourceActionSet: ContextMenuActionSet = [[
      {
diff --cc src/views/collection-panel/collection-panel.tsx
index 9e32700,348b548..8a0e2f8
--- a/src/views/collection-panel/collection-panel.tsx
+++ b/src/views/collection-panel/collection-panel.tsx
@@@ -60,76 -63,98 +63,96 @@@ type CollectionPanelProps = CollectionP
  
  
  export const CollectionPanel = withStyles(styles)(
-     connect((state: RootState) => ({
-         item: state.collectionPanel.item,
-         tags: state.collectionPanel.tags
-     }))(
+     connect((state: RootState, props: RouteComponentProps<{ id: string }>) => {
+         const collection = getResource(props.match.params.id)(state.resources);
+         return {
+             item: collection,
+             tags: state.collectionPanel.tags
+         };
+     })(
          class extends React.Component<CollectionPanelProps> {
 -
              render() {
-                 const { classes, item, tags, onContextMenu } = this.props;
+                 const { classes, item, tags } = this.props;
                  return <div>
-                         <Card className={classes.card}>
-                             <CardHeader
-                                 avatar={ <CollectionIcon className={classes.iconHeader} /> }
-                                 action={
-                                     <IconButton
-                                         aria-label="More options"
-                                         onClick={event => onContextMenu(event, item)}>
-                                         <MoreOptionsIcon />
-                                     </IconButton>
-                                 }
-                                 title={item && item.name }
-                                 subheader={item && item.description} />
-                             <CardContent>
-                                 <Grid container direction="column">
-                                     <Grid item xs={6}>
-                                     <DetailsAttribute classValue={classes.value}
-                                             label='Collection UUID'
-                                             value={item && item.uuid}>
-                                         <CopyToClipboard text={item && item.uuid}>
-                                             <CopyIcon className={classes.copyIcon} />
-                                         </CopyToClipboard>
+                     <Card className={classes.card}>
+                         <CardHeader
+                             avatar={<CollectionIcon className={classes.iconHeader} />}
+                             action={
+                                 <IconButton
+                                     aria-label="More options"
+                                     onClick={this.handleContextMenu}>
+                                     <MoreOptionsIcon />
+                                 </IconButton>
+                             }
+                             title={item && item.name}
+                             subheader={item && item.description} />
+                         <CardContent>
+                             <Grid container direction="column">
+                                 <Grid item xs={6}>
+                                     <DetailsAttribute classLabel={classes.label} classValue={classes.value}
+                                         label='Collection UUID'
+                                         value={item && item.uuid}>
+                                         <Tooltip title="Copy uuid">
+                                             <CopyToClipboard text={item && item.uuid} onCopy={() => this.onCopy()}>
+                                                 <CopyIcon className={classes.copyIcon} />
+                                             </CopyToClipboard>
+                                         </Tooltip>
                                      </DetailsAttribute>
-                                     <DetailsAttribute label='Number of files' value='14' />
-                                     <DetailsAttribute label='Content size' value='54 MB' />
-                                     <DetailsAttribute classValue={classes.value} label='Owner' value={item && item.ownerUuid} />
-                                     </Grid>
+                                     <DetailsAttribute classLabel={classes.label} classValue={classes.value}
+                                         label='Number of files' value='14' />
+                                     <DetailsAttribute classLabel={classes.label} classValue={classes.value}
+                                         label='Content size' value='54 MB' />
+                                     <DetailsAttribute classLabel={classes.label} classValue={classes.value}
+                                         label='Owner' value={item && item.ownerUuid} />
                                  </Grid>
-                             </CardContent>
-                         </Card>
+                             </Grid>
+                         </CardContent>
+                     </Card>
  
-                         <Card className={classes.card}>
-                             <CardHeader title="Properties" />
-                             <CardContent>
-                                 <Grid container direction="column">
-                                     <Grid item xs={12}><CollectionTagForm /></Grid>
-                                     <Grid item xs={12}>
-                                         {
-                                             tags.map(tag => {
-                                                 return <Chip key={tag.etag} className={classes.tag}
-                                                     onDelete={this.handleDelete(tag.uuid)}
-                                                     label={renderTagLabel(tag)}  />;
-                                             })
-                                         }
-                                     </Grid>
+                     <Card className={classes.card}>
+                         <CardHeader title="Properties" />
+                         <CardContent>
+                             <Grid container direction="column">
+                                 <Grid item xs={12}><CollectionTagForm /></Grid>
+                                 <Grid item xs={12}>
+                                     {
+                                         tags.map(tag => {
+                                             return <Chip key={tag.etag} className={classes.tag}
+                                                 onDelete={this.handleDelete(tag.uuid)}
+                                                 label={renderTagLabel(tag)} />;
+                                         })
+                                     }
                                  </Grid>
-                             </CardContent>
-                         </Card>
-                         <div className={classes.card}>
-                             <CollectionPanelFiles/>
-                         </div>
-                     </div>;
+                             </Grid>
+                         </CardContent>
+                     </Card>
+                     <div className={classes.card}>
+                         <CollectionPanelFiles />
+                     </div>
+                 </div>;
+             }
+ 
+             handleContextMenu = (event: React.MouseEvent<any>) => {
+                 const { uuid, name, description } = this.props.item;
+                 const resource = {
+                     uuid,
+                     name,
+                     description,
+                     kind: ContextMenuKind.COLLECTION
+                 };
+                 this.props.dispatch<any>(openContextMenu(event, resource));
              }
  
              handleDelete = (uuid: string) => () => {
                  this.props.dispatch<any>(deleteCollectionTag(uuid));
              }
  
-             componentWillReceiveProps({ match, item, onItemRouteChange }: CollectionPanelProps) {
-                 if (!item || match.params.id !== item.uuid) {
-                     onItemRouteChange(match.params.id);
-                 }
+             onCopy = () => {
+                 this.props.dispatch(snackbarActions.OPEN_SNACKBAR({
+                     message: "Uuid has been copied",
+                     hideDuration: 2000
+                 }));
              }
 -
          }
      )
  );
diff --cc src/views/favorite-panel/favorite-panel.tsx
index 49f1f4a,9fbae5c..62b037e
--- a/src/views/favorite-panel/favorite-panel.tsx
+++ b/src/views/favorite-panel/favorite-panel.tsx
@@@ -9,9 -8,8 +8,8 @@@ import { DataExplorer } from "~/views-c
  import { DispatchProp, connect } from 'react-redux';
  import { DataColumns } from '~/components/data-table/data-table';
  import { RouteComponentProps } from 'react-router';
- import { RootState } from '~/store/store';
  import { DataTableFilterItem } from '~/components/data-table-filters/data-table-filters';
 -import { ContainerRequestState } from '~/models/container-request';
 +import { ProcessState } from '~/models/process';
  import { SortDirection } from '~/components/data-table/data-column';
  import { ResourceKind } from '~/models/resource';
  import { resourceLabel } from '~/common/labels';
@@@ -42,10 -45,10 +45,10 @@@ export enum FavoritePanelColumnNames 
  }
  
  export interface FavoritePanelFilter extends DataTableFilterItem {
 -    type: ResourceKind | ContainerRequestState;
 +    type: ResourceKind | ProcessState;
  }
  
- export const columns: DataColumns<FavoritePanelItem, FavoritePanelFilter> = [
+ export const favoritePanelColumns: DataColumns<string, FavoritePanelFilter> = [
      {
          name: FavoritePanelColumnNames.NAME,
          selected: true,
@@@ -62,22 -65,22 +65,22 @@@
          sortDirection: SortDirection.NONE,
          filters: [
              {
 -                name: ContainerRequestState.COMMITTED,
 +                name: ProcessState.COMMITTED,
                  selected: true,
 -                type: ContainerRequestState.COMMITTED
 +                type: ProcessState.COMMITTED
              },
              {
 -                name: ContainerRequestState.FINAL,
 +                name: ProcessState.FINAL,
                  selected: true,
 -                type: ContainerRequestState.FINAL
 +                type: ProcessState.FINAL
              },
              {
 -                name: ContainerRequestState.UNCOMMITTED,
 +                name: ProcessState.UNCOMMITTED,
                  selected: true,
 -                type: ContainerRequestState.UNCOMMITTED
 +                type: ProcessState.UNCOMMITTED
              }
          ],
-         render: renderStatus,
+         render: uuid => <ProcessStatus uuid={uuid} />,
          width: "75px"
      },
      {
diff --cc src/views/project-panel/project-panel.tsx
index f63584b,0694643..37a6d20
--- a/src/views/project-panel/project-panel.tsx
+++ b/src/views/project-panel/project-panel.tsx
@@@ -47,10 -57,10 +57,10 @@@ export enum ProjectPanelColumnNames 
  }
  
  export interface ProjectPanelFilter extends DataTableFilterItem {
 -    type: ResourceKind | ContainerRequestState;
 +    type: ResourceKind | ProcessState;
  }
  
- export const columns: DataColumns<ProjectPanelItem, ProjectPanelFilter> = [
+ export const projectPanelColumns: DataColumns<string, ProjectPanelFilter> = [
      {
          name: ProjectPanelColumnNames.NAME,
          selected: true,
@@@ -67,22 -77,22 +77,22 @@@
          sortDirection: SortDirection.NONE,
          filters: [
              {
 -                name: ContainerRequestState.COMMITTED,
 +                name: ProcessState.COMMITTED,
                  selected: true,
 -                type: ContainerRequestState.COMMITTED
 +                type: ProcessState.COMMITTED
              },
              {
 -                name: ContainerRequestState.FINAL,
 +                name: ProcessState.FINAL,
                  selected: true,
 -                type: ContainerRequestState.FINAL
 +                type: ProcessState.FINAL
              },
              {
 -                name: ContainerRequestState.UNCOMMITTED,
 +                name: ProcessState.UNCOMMITTED,
                  selected: true,
 -                type: ContainerRequestState.UNCOMMITTED
 +                type: ProcessState.UNCOMMITTED
              }
          ],
-         render: renderStatus,
+         render: uuid => <ProcessStatus uuid={uuid} />,
          width: "75px"
      },
      {
diff --cc src/views/workbench/workbench.tsx
index 8028f2c,ef5fe21..ea3a278
--- a/src/views/workbench/workbench.tsx
+++ b/src/views/workbench/workbench.tsx
@@@ -46,16 -24,24 +24,27 @@@ import { AuthService } from "~/services
  import { RenameFileDialog } from '~/views-components/rename-file-dialog/rename-file-dialog';
  import { FileRemoveDialog } from '~/views-components/file-remove-dialog/file-remove-dialog';
  import { MultipleFilesRemoveDialog } from '~/views-components/file-remove-dialog/multiple-files-remove-dialog';
- import { DialogCollectionCreateWithSelectedFile } from '~/views-components/create-collection-dialog-with-selected/create-collection-dialog-with-selected';
- import { COLLECTION_CREATE_DIALOG } from '~/views-components/dialog-create/dialog-collection-create';
- import { PROJECT_CREATE_DIALOG } from '~/views-components/dialog-create/dialog-project-create';
+ import { Routes } from '~/routes/routes';
+ import { SidePanel } from '~/views-components/side-panel/side-panel';
+ import { ProcessPanel } from '~/views/process-panel/process-panel';
+ import { Breadcrumbs } from '~/views-components/breadcrumbs/breadcrumbs';
+ import { CreateProjectDialog } from '~/views-components/dialog-forms/create-project-dialog';
+ import { CreateCollectionDialog } from '~/views-components/dialog-forms/create-collection-dialog';
+ import { CopyCollectionDialog } from '~/views-components/dialog-forms/copy-collection-dialog';
+ import { UpdateCollectionDialog } from '~/views-components/dialog-forms/update-collection-dialog';
+ import { UpdateProjectDialog } from '~/views-components/dialog-forms/update-project-dialog';
+ import { MoveProjectDialog } from '~/views-components/dialog-forms/move-project-dialog';
+ import { MoveCollectionDialog } from '~/views-components/dialog-forms/move-collection-dialog';
+ 
+ import { FilesUploadCollectionDialog } from '~/views-components/dialog-forms/files-upload-collection-dialog';
+ import { PartialCopyCollectionDialog } from '~/views-components/dialog-forms/partial-copy-collection-dialog';
+ 
 +import { TrashPanel } from "~/views/trash-panel/trash-panel";
 +import { trashPanelActions } from "~/store/trash-panel/trash-panel-action";
 +
- const DRAWER_WITDH = 240;
  const APP_BAR_HEIGHT = 100;
  
- type CssRules = 'root' | 'appBar' | 'drawerPaper' | 'content' | 'contentWrapper' | 'toolbar';
+ type CssRules = 'root' | 'appBar' | 'content' | 'contentWrapper';
  
  const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
      root: {
@@@ -233,11 -163,10 +166,11 @@@ export const Workbench = withStyles(sty
                          <main className={classes.contentWrapper}>
                              <div className={classes.content}>
                                  <Switch>
-                                     <Route path='/' exact render={() => <Redirect to={`/projects/${this.props.authService.getUuid()}`}  />} />
-                                     <Route path="/projects/:id" render={this.renderProjectPanel} />
-                                     <Route path="/favorites" render={this.renderFavoritePanel} />
+                                     <Route path={Routes.PROJECTS} component={ProjectPanel} />
+                                     <Route path={Routes.COLLECTIONS} component={CollectionPanel} />
+                                     <Route path={Routes.FAVORITES} component={FavoritePanel} />
+                                     <Route path={Routes.PROCESSES} component={ProcessPanel} />
 +                                    <Route path="/trash" render={this.renderTrashPanel} />
-                                     <Route path="/collections/:id" render={this.renderCollectionPanel} />
                                  </Switch>
                              </div>
                              {user && <DetailsPanel />}

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list