From: Daniel Kutyła Date: Thu, 18 Feb 2021 21:12:08 +0000 (+0100) Subject: Merge branch '17306-Favorites-in-copy-dialog-is-different-to-favorite-list' X-Git-Tag: 2.1.2~1 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/40d96a9dafd0db3497a997a48ee223509de05de0?hp=ea1216cb8346848cb2f8dd09fda14803c83d3557 Merge branch '17306-Favorites-in-copy-dialog-is-different-to-favorite-list' closes #17306 Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła --- diff --git a/cypress/integration/favorites.js b/cypress/integration/favorites.js deleted file mode 100644 index 0855c94e..00000000 --- a/cypress/integration/favorites.js +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -describe('Favorites tests', function() { - let activeUser; - let adminUser; - - before(function() { - // Only set up common users once. These aren't set up as aliases because - // aliases are cleaned up after every test. Also it doesn't make sense - // to set the same users on beforeEach() over and over again, so we - // separate a little from Cypress' 'Best Practices' here. - cy.getUser('admin', 'Admin', 'User', true, true) - .as('adminUser').then(function() { - adminUser = this.adminUser; - } - ); - cy.getUser('collectionuser1', 'Collection', 'User', false, true) - .as('activeUser').then(function() { - activeUser = this.activeUser; - } - ); - }) - - beforeEach(function() { - cy.clearCookies() - cy.clearLocalStorage() - }) - - it('checks that Public favorites does not appear under shared with me', function() { - cy.loginAs(adminUser); - cy.contains('Shared with me').click(); - cy.get('main').contains('Public favorites').should('not.exist'); - }) - - it('creates and removes a public favorite', function() { - cy.loginAs(adminUser); - cy.createGroup(adminUser.token, { - name: `my-favorite-project`, - group_class: 'project', - }).as('myFavoriteProject').then(function() { - cy.contains('Refresh').click(); - cy.get('main').contains('my-favorite-project').rightclick(); - cy.contains('Add to public favorites').click(); - cy.contains('Public Favorites').click(); - cy.get('main').contains('my-favorite-project').rightclick(); - cy.contains('Remove from public favorites').click(); - cy.get('main').contains('my-favorite-project').should('not.exist'); - cy.trashGroup(adminUser.token, this.myFavoriteProject.uuid); - }); - }) -}) diff --git a/cypress/integration/favorites.spec.js b/cypress/integration/favorites.spec.js new file mode 100644 index 00000000..eca35bc4 --- /dev/null +++ b/cypress/integration/favorites.spec.js @@ -0,0 +1,222 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +describe('Favorites tests', function () { + let activeUser; + let adminUser; + + before(function () { + // Only set up common users once. These aren't set up as aliases because + // aliases are cleaned up after every test. Also it doesn't make sense + // to set the same users on beforeEach() over and over again, so we + // separate a little from Cypress' 'Best Practices' here. + cy.getUser('admin', 'Admin', 'User', true, true) + .as('adminUser').then(function () { + adminUser = this.adminUser; + } + ); + cy.getUser('collectionuser1', 'Collection', 'User', false, true) + .as('activeUser').then(function () { + activeUser = this.activeUser; + } + ); + }) + + beforeEach(function () { + cy.clearCookies() + cy.clearLocalStorage() + }) + + it('checks that Public favorites does not appear under shared with me', function () { + cy.loginAs(adminUser); + cy.contains('Shared with me').click(); + cy.get('main').contains('Public favorites').should('not.exist'); + }); + + it('creates and removes a public favorite', function () { + cy.loginAs(adminUser); + cy.createGroup(adminUser.token, { + name: `my-favorite-project`, + group_class: 'project', + }).as('myFavoriteProject').then(function () { + cy.contains('Refresh').click(); + cy.get('main').contains('my-favorite-project').rightclick(); + cy.contains('Add to public favorites').click(); + cy.contains('Public Favorites').click(); + cy.get('main').contains('my-favorite-project').rightclick(); + cy.contains('Remove from public favorites').click(); + cy.get('main').contains('my-favorite-project').should('not.exist'); + cy.trashGroup(adminUser.token, this.myFavoriteProject.uuid); + }); + }); + + it('can copy collection to favorites', () => { + cy.loginAs(adminUser); + + cy.createGroup(adminUser.token, { + name: `my-shared-writable-project ${Math.floor(Math.random() * 999999)}`, + group_class: 'project', + }).as('mySharedWritableProject').then(function (mySharedWritableProject) { + cy.contains('Refresh').click(); + cy.get('main').contains(mySharedWritableProject.name).rightclick(); + cy.get('[data-cy=context-menu]').within(() => { + cy.contains('Share').click(); + }); + cy.get('[id="select-permissions"]').as('selectPermissions'); + cy.get('@selectPermissions').click(); + cy.contains('Write').click(); + cy.get('.sharing-dialog').as('sharingDialog'); + cy.get('[data-cy=invite-people-field]').find('input').type(activeUser.user.email); + cy.get('[role=tooltip]').click(); + cy.get('@sharingDialog').contains('Save').click(); + }); + + cy.createGroup(adminUser.token, { + name: `my-shared-readonly-project ${Math.floor(Math.random() * 999999)}`, + group_class: 'project', + }).as('mySharedReadonlyProject').then(function (mySharedReadonlyProject) { + cy.contains('Refresh').click(); + cy.get('main').contains(mySharedReadonlyProject.name).rightclick(); + cy.get('[data-cy=context-menu]').within(() => { + cy.contains('Share').click(); + }); + cy.get('.sharing-dialog').as('sharingDialog'); + cy.get('[data-cy=invite-people-field]').find('input').type(activeUser.user.email); + cy.get('[role=tooltip]').click(); + cy.get('@sharingDialog').contains('Save').click(); + }); + + cy.createGroup(activeUser.token, { + name: `my-project ${Math.floor(Math.random() * 999999)}`, + group_class: 'project', + }).as('myProject1'); + + cy.createCollection(adminUser.token, { + name: `Test collection ${Math.floor(Math.random() * 999999)}`, + owner_uuid: activeUser.user.uuid, + manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n" + }) + .as('testCollection'); + + cy.getAll('@mySharedWritableProject', '@mySharedReadonlyProject', '@myProject1', '@testCollection') + .then(function ([mySharedWritableProject, mySharedReadonlyProject, myProject1, testCollection]) { + cy.loginAs(activeUser); + + cy.contains('Shared with me').click(); + + cy.get('main').contains(mySharedWritableProject.name).rightclick(); + cy.get('[data-cy=context-menu]').within(() => { + cy.contains('Add to favorites').click(); + }); + + cy.get('main').contains(mySharedReadonlyProject.name).rightclick(); + cy.get('[data-cy=context-menu]').within(() => { + cy.contains('Add to favorites').click(); + }); + + cy.doSearch(`${activeUser.user.uuid}`); + + cy.get('main').contains(myProject1.name).rightclick(); + cy.get('[data-cy=context-menu]').within(() => { + cy.contains('Add to favorites').click(); + }); + + cy.contains(testCollection.name).rightclick(); + cy.get('[data-cy=context-menu]').within(() => { + cy.contains('Move to').click(); + }); + + cy.get('[data-cy=form-dialog]').within(function () { + cy.get('[data-cy=projects-tree-favourites-tree-picker]').find('i').click(); + cy.contains(myProject1.name); + cy.contains(mySharedWritableProject.name); + cy.get('[data-cy=projects-tree-favourites-tree-picker]') + .should('not.contain', mySharedReadonlyProject.name); + cy.contains(mySharedWritableProject.name).click(); + cy.get('[data-cy=form-submit-btn]').click(); + }); + + cy.doSearch(`${mySharedWritableProject.uuid}`); + cy.get('main').contains(testCollection.name); + }); + }); + + it('can copy selected into the collection', () => { + cy.loginAs(adminUser); + + cy.createCollection(adminUser.token, { + name: `Test source collection ${Math.floor(Math.random() * 999999)}`, + manifest_text: ". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n" + }) + .as('testSourceCollection').then(function (testSourceCollection) { + cy.contains('Refresh').click(); + cy.get('main').contains(testSourceCollection.name).rightclick(); + cy.get('[data-cy=context-menu]').within(() => { + cy.contains('Share').click(); + }); + cy.get('[id="select-permissions"]').as('selectPermissions'); + cy.get('@selectPermissions').click(); + cy.contains('Write').click(); + cy.get('.sharing-dialog').as('sharingDialog'); + cy.get('[data-cy=invite-people-field]').find('input').type(activeUser.user.email); + cy.get('[role=tooltip]').click(); + cy.get('@sharingDialog').contains('Save').click(); + }); + + cy.createCollection(adminUser.token, { + name: `Test target collection ${Math.floor(Math.random() * 999999)}`, + }) + .as('testTargetCollection').then(function (testTargetCollection) { + cy.contains('Refresh').click(); + cy.get('main').contains(testTargetCollection.name).rightclick(); + cy.get('[data-cy=context-menu]').within(() => { + cy.contains('Share').click(); + }); + cy.get('[id="select-permissions"]').as('selectPermissions'); + cy.get('@selectPermissions').click(); + cy.contains('Write').click(); + cy.get('.sharing-dialog').as('sharingDialog'); + cy.get('[data-cy=invite-people-field]').find('input').type(activeUser.user.email); + cy.get('[role=tooltip]').click(); + cy.get('@sharingDialog').contains('Save').click(); + }); + + cy.getAll('@testSourceCollection', '@testTargetCollection') + .then(function ([testSourceCollection, testTargetCollection]) { + cy.loginAs(activeUser); + + cy.get('.layout-pane-primary') + .contains('Projects').click(); + + cy.get('main').contains(testTargetCollection.name).rightclick(); + cy.get('[data-cy=context-menu]').within(() => { + cy.contains('Add to favorites').click(); + }); + + cy.get('main').contains(testSourceCollection.name).click(); + cy.get('[data-cy=collection-files-panel]').contains('bar'); + cy.get('[data-cy=collection-files-panel]').find('input[type=checkbox]').click({ force: true }); + cy.get('[data-cy=collection-files-panel-options-btn]').click(); + cy.get('[data-cy=context-menu]') + .contains('Copy selected into the collection').click(); + + cy.get('[data-cy=projects-tree-favourites-tree-picker]') + .find('i') + .click(); + + cy.get('[data-cy=projects-tree-favourites-tree-picker]') + .contains(testTargetCollection.name) + .click(); + + cy.get('[data-cy=form-submit-btn]').click(); + + cy.get('.layout-pane-primary') + .contains('Projects').click(); + + cy.get('main').contains(testTargetCollection.name).click(); + + cy.get('[data-cy=collection-files-panel]').contains('bar'); + }); + }); +}); \ No newline at end of file diff --git a/cypress/support/commands.js b/cypress/support/commands.js index bba04ba8..24e4b73a 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -32,17 +32,17 @@ const controllerURL = Cypress.env('controller_url'); const systemToken = Cypress.env('system_token'); Cypress.Commands.add( - "doRequest", (method='GET', path='', data=null, qs=null, - token=systemToken, auth=false, followRedirect=true) => { - return cy.request({ - method: method, - url: `${controllerURL}/${path}`, - body: data, - qs: auth ? qs : Object.assign({api_token: token}, qs), - auth: auth ? {bearer: `${token}`} : undefined, - followRedirect: followRedirect - }) - } + "doRequest", (method = 'GET', path = '', data = null, qs = null, + token = systemToken, auth = false, followRedirect = true) => { + return cy.request({ + method: method, + url: `${controllerURL}/${path}`, + body: data, + qs: auth ? qs : Object.assign({ api_token: token }, qs), + auth: auth ? { bearer: `${token}` } : undefined, + followRedirect: followRedirect + }) +} ) // This resets the DB removing all content and seeding it with the fixtures. @@ -54,7 +54,7 @@ Cypress.Commands.add( ) Cypress.Commands.add( - "getUser", (username, first_name='', last_name='', is_admin=false, is_active=true) => { + "getUser", (username, first_name = '', last_name = '', is_admin = false, is_active = true) => { // Create user if not already created return cy.doRequest('POST', '/auth/controller/callback', { auth_info: JSON.stringify({ @@ -66,30 +66,30 @@ Cypress.Commands.add( }), return_to: ',https://example.local' }, null, systemToken, true, false) // Don't follow redirects so we can catch the token - .its('headers.location').as('location') - // Get its token and set the account up as admin and/or active - .then(function() { - this.userToken = this.location.split("=")[1] - assert.isString(this.userToken) - return cy.doRequest('GET', '/arvados/v1/users', null, { - filters: `[["username", "=", "${username}"]]` - }) - .its('body.items.0') - .as('aUser') - .then(function() { - cy.doRequest('PUT', `/arvados/v1/users/${this.aUser.uuid}`, { - user: { - is_admin: is_admin, - is_active: is_active - } - }) - .its('body') - .as('theUser') - .then(function() { - return {user: this.theUser, token: this.userToken}; + .its('headers.location').as('location') + // Get its token and set the account up as admin and/or active + .then(function () { + this.userToken = this.location.split("=")[1] + assert.isString(this.userToken) + return cy.doRequest('GET', '/arvados/v1/users', null, { + filters: `[["username", "=", "${username}"]]` }) + .its('body.items.0') + .as('aUser') + .then(function () { + cy.doRequest('PUT', `/arvados/v1/users/${this.aUser.uuid}`, { + user: { + is_admin: is_admin, + is_active: is_active + } + }) + .its('body') + .as('theUser') + .then(function () { + return { user: this.theUser, token: this.userToken }; + }) + }) }) - }) } ) @@ -145,31 +145,31 @@ Cypress.Commands.add( Cypress.Commands.add( "createResource", (token, suffix, data) => { - return cy.doRequest('POST', '/arvados/v1/'+suffix, data, null, token, true) - .its('body').as('resource') - .then(function() { - return this.resource; - }) + return cy.doRequest('POST', '/arvados/v1/' + suffix, data, null, token, true) + .its('body').as('resource') + .then(function () { + return this.resource; + }) } ) Cypress.Commands.add( "deleteResource", (token, suffix, uuid) => { - return cy.doRequest('DELETE', '/arvados/v1/'+suffix+'/'+uuid) - .its('body').as('resource') - .then(function() { - return this.resource; - }) + return cy.doRequest('DELETE', '/arvados/v1/' + suffix + '/' + uuid) + .its('body').as('resource') + .then(function () { + return this.resource; + }) } ) Cypress.Commands.add( "updateResource", (token, suffix, uuid, data) => { - return cy.doRequest('PUT', '/arvados/v1/'+suffix+'/'+uuid, data, null, token, true) - .its('body').as('resource') - .then(function() { - return this.resource; - }) + return cy.doRequest('PUT', '/arvados/v1/' + suffix + '/' + uuid, data, null, token, true) + .its('body').as('resource') + .then(function () { + return this.resource; + }) } ) @@ -186,4 +186,14 @@ Cypress.Commands.add( "doSearch", (searchTerm) => { cy.get('[data-cy=searchbar-input-field]').type(`{selectall}${searchTerm}{enter}`); } -) \ No newline at end of file +) + +Cypress.Commands.add('getAll', (...elements) => { + const promise = cy.wrap([], { log: false }) + + for (let element of elements) { + promise.then(arr => cy.get(element).then(got => cy.wrap([...arr, got]))) + } + + return promise +}) \ No newline at end of file diff --git a/src/services/favorite-service/favorite-service.ts b/src/services/favorite-service/favorite-service.ts index fbb2a52f..fce81004 100644 --- a/src/services/favorite-service/favorite-service.ts +++ b/src/services/favorite-service/favorite-service.ts @@ -45,7 +45,7 @@ export class FavoriteService { results.items.map(item => this.linkService.delete(item.uuid)))); } - list(userUuid: string, { filters, limit, offset, linkOrder, contentOrder }: FavoriteListArguments = {}): Promise> { + list(userUuid: string, { filters, limit, offset, linkOrder, contentOrder }: FavoriteListArguments = {}, showOnlyOwned: boolean = true): Promise> { const listFilters = new FilterBuilder() .addEqual('owner_uuid', userUuid) .addEqual('link_class', LinkClass.STAR) @@ -60,7 +60,7 @@ export class FavoriteService { }) .then(results => { const uuids = results.items.map(item => item.headUuid); - return this.groupsService.contents(userUuid, { + return this.groupsService.contents(showOnlyOwned ? userUuid : '', { limit, offset, order: contentOrder, diff --git a/src/store/collections/collection-partial-copy-actions.ts b/src/store/collections/collection-partial-copy-actions.ts index 74fa17b3..09c6bb66 100644 --- a/src/store/collections/collection-partial-copy-actions.ts +++ b/src/store/collections/collection-partial-copy-actions.ts @@ -112,6 +112,13 @@ export const copyCollectionPartialToSelectedCollection = ({ collectionUuid }: Co dispatch(startSubmit(COLLECTION_PARTIAL_COPY_TO_SELECTED_COLLECTION)); const state = getState(); const currentCollection = state.collectionPanel.item; + + if (currentCollection && !currentCollection.manifestText) { + const fetchedCurrentCollection = await services.collectionService.get(currentCollection.uuid); + currentCollection.manifestText = fetchedCurrentCollection.manifestText; + currentCollection.unsignedManifestText = fetchedCurrentCollection.unsignedManifestText; + } + if (currentCollection) { try { dispatch(progressIndicatorActions.START_WORKING(COLLECTION_PARTIAL_COPY_TO_SELECTED_COLLECTION)); @@ -127,10 +134,10 @@ export const copyCollectionPartialToSelectedCollection = ({ collectionUuid }: Co } }); const diffPathToRemove = _.difference(paths, pathsToRemove); - await services.collectionService.deleteFiles(selectedCollection.uuid, pathsToRemove); + await services.collectionService.deleteFiles(selectedCollection.uuid, pathsToRemove.map(path => path.replace(currentCollection.uuid, collectionUuid))); const collectionWithDeletedFiles = await services.collectionService.get(collectionUuid); - await services.collectionService.update(collectionUuid, { manifestText: `${collectionWithDeletedFiles.manifestText}${currentCollection.manifestText ? currentCollection.manifestText : currentCollection.unsignedManifestText}` }); - await services.collectionService.deleteFiles(collectionWithDeletedFiles.uuid, diffPathToRemove); + await services.collectionService.update(collectionUuid, { manifestText: `${collectionWithDeletedFiles.manifestText}${(currentCollection.manifestText ? currentCollection.manifestText : currentCollection.unsignedManifestText) || ''}` }); + await services.collectionService.deleteFiles(collectionWithDeletedFiles.uuid, diffPathToRemove.map(path => path.replace(currentCollection.uuid, collectionUuid))); dispatch(dialogActions.CLOSE_DIALOG({ id: COLLECTION_PARTIAL_COPY_TO_SELECTED_COLLECTION })); dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Files has been copied to selected collection.', diff --git a/src/store/tree-picker/tree-picker-actions.ts b/src/store/tree-picker/tree-picker-actions.ts index 3fa5187a..d11f7527 100644 --- a/src/store/tree-picker/tree-picker-actions.ts +++ b/src/store/tree-picker/tree-picker-actions.ts @@ -21,6 +21,7 @@ import { mapTree } from '../../models/tree'; import { LinkResource, LinkClass } from "~/models/link"; import { mapTreeValues } from "~/models/tree"; import { sortFilesTree } from "~/services/collection-service/collection-service-files-response"; +import { GroupResource } from "~/models/group"; export const treePickerActions = unionize({ LOAD_TREE_PICKER_NODE: ofType<{ id: string, pickerId: string }>(), @@ -236,7 +237,8 @@ interface LoadFavoritesProjectParams { includeFiles?: boolean; } -export const loadFavoritesProject = (params: LoadFavoritesProjectParams) => +export const loadFavoritesProject = (params: LoadFavoritesProjectParams, + options: { showOnlyOwned: boolean, showOnlyWritable: boolean } = { showOnlyOwned: true, showOnlyWritable: false }) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { const { pickerId, includeCollections = false, includeFiles = false } = params; const uuid = getUserUuid(getState()); @@ -248,12 +250,18 @@ export const loadFavoritesProject = (params: LoadFavoritesProjectParams) => fb => fb.getFilters(), )(new FilterBuilder()); - const { items } = await services.favoriteService.list(uuid, { filters }); + const { items } = await services.favoriteService.list(uuid, { filters }, options.showOnlyOwned); dispatch(receiveTreePickerData({ id: 'Favorites', pickerId, - data: items, + data: items.filter((item) => { + if (options.showOnlyWritable && (item as GroupResource).writableBy && (item as GroupResource).writableBy.indexOf(uuid) === -1) { + return false; + } + + return true; + }), extractNodeData: item => ({ id: item.uuid, value: item, diff --git a/src/views-components/projects-tree-picker/favorites-tree-picker.tsx b/src/views-components/projects-tree-picker/favorites-tree-picker.tsx index 09704066..2f149f4a 100644 --- a/src/views-components/projects-tree-picker/favorites-tree-picker.tsx +++ b/src/views-components/projects-tree-picker/favorites-tree-picker.tsx @@ -11,7 +11,7 @@ import { loadFavoritesProject } from '~/store/tree-picker/tree-picker-actions'; export const FavoritesTreePicker = connect(() => ({ rootItemIcon: FavoriteIcon, }), (dispatch: Dispatch): Pick => ({ - loadRootItem: (_, pickerId, includeCollections, includeFiles) => { - dispatch(loadFavoritesProject({ pickerId, includeCollections, includeFiles })); + loadRootItem: (_, pickerId, includeCollections, includeFiles, options) => { + dispatch(loadFavoritesProject({ pickerId, includeCollections, includeFiles }, options)); }, }))(ProjectsTreePicker); \ No newline at end of file diff --git a/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx b/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx index 07b1ad81..eb756d72 100644 --- a/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx +++ b/src/views-components/projects-tree-picker/generic-projects-tree-picker.tsx @@ -33,7 +33,9 @@ export interface ProjectsTreePickerDataProps { showSelection?: boolean; relatedTreePickers?: string[]; disableActivation?: string[]; - loadRootItem: (item: TreeItem, pickerId: string, includeCollections?: boolean, includeFiles?: boolean) => void; + options?: { showOnlyOwned: boolean, showOnlyWritable: boolean }; + loadRootItem: (item: TreeItem, pickerId: string, + includeCollections?: boolean, includeFiles?: boolean, options?: { showOnlyOwned: boolean, showOnlyWritable: boolean }) => void; } export type ProjectsTreePickerProps = ProjectsTreePickerDataProps & Partial; @@ -43,7 +45,7 @@ const mapStateToProps = (_: any, { rootItemIcon, showSelection }: ProjectsTreePi showSelection: isSelectionVisible(showSelection), }); -const mapDispatchToProps = (dispatch: Dispatch, { loadRootItem, includeCollections, includeFiles, relatedTreePickers, ...props }: ProjectsTreePickerProps): PickedTreePickerProps => ({ +const mapDispatchToProps = (dispatch: Dispatch, { loadRootItem, includeCollections, includeFiles, relatedTreePickers, options, ...props }: ProjectsTreePickerProps): PickedTreePickerProps => ({ onContextMenu: () => { return; }, toggleItemActive: (event, item, pickerId) => { @@ -67,7 +69,7 @@ const mapDispatchToProps = (dispatch: Dispatch, { loadRootItem, includeCollectio : loadProject({ id, pickerId, includeCollections, includeFiles }) ); } else if (!('type' in data) && loadRootItem) { - loadRootItem(item as TreeItem, pickerId, includeCollections, includeFiles); + loadRootItem(item as TreeItem, pickerId, includeCollections, includeFiles, options); } } else if (status === TreeItemStatus.LOADED) { dispatch(treePickerActions.TOGGLE_TREE_PICKER_NODE_COLLAPSE({ id, pickerId })); diff --git a/src/views-components/projects-tree-picker/projects-tree-picker.tsx b/src/views-components/projects-tree-picker/projects-tree-picker.tsx index 10bb5eb8..f28d173e 100644 --- a/src/views-components/projects-tree-picker/projects-tree-picker.tsx +++ b/src/views-components/projects-tree-picker/projects-tree-picker.tsx @@ -17,6 +17,7 @@ export interface ProjectsTreePickerProps { includeCollections?: boolean; includeFiles?: boolean; showSelection?: boolean; + options?: { showOnlyOwned: boolean, showOnlyWritable: boolean }; toggleItemActive?: (event: React.MouseEvent, item: TreeItem, pickerId: string) => void; toggleItemSelection?: (event: React.MouseEvent, item: TreeItem, pickerId: string) => void; } @@ -33,7 +34,9 @@ export const ProjectsTreePicker = ({ pickerId, ...props }: ProjectsTreePickerPro - +
+ +
; }; diff --git a/src/views-components/projects-tree-picker/tree-picker-field.tsx b/src/views-components/projects-tree-picker/tree-picker-field.tsx index a8ab05f6..436a3e45 100644 --- a/src/views-components/projects-tree-picker/tree-picker-field.tsx +++ b/src/views-components/projects-tree-picker/tree-picker-field.tsx @@ -14,7 +14,8 @@ export const ProjectTreePickerField = (props: WrappedFieldProps & PickerIdProp)
+ toggleItemActive={handleChange(props)} + options={{ showOnlyOwned: false, showOnlyWritable: true }} /> {props.meta.dirty && props.meta.error && {props.meta.error} @@ -30,6 +31,7 @@ export const CollectionTreePickerField = (props: WrappedFieldProps & PickerIdPro {props.meta.dirty && props.meta.error && diff --git a/src/views-components/sharing-dialog/sharing-dialog-component.tsx b/src/views-components/sharing-dialog/sharing-dialog-component.tsx index 1792bd67..2038ad96 100644 --- a/src/views-components/sharing-dialog/sharing-dialog-component.tsx +++ b/src/views-components/sharing-dialog/sharing-dialog-component.tsx @@ -25,6 +25,7 @@ export default (props: SharingDialogDataProps & SharingDialogActionProps) => { const { children, open, loading, advancedEnabled, saveEnabled, onAdvanced, onClose, onExited, onSave } = props; return - + - + ;