Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign shared with list #7252

Merged
merged 10 commits into from
Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog/unreleased/enhancement-redesign-shared-with-list
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Enhancement: Redesign shared with list

We've redesigned the shared with list, to achieve more spacing and a better user experience.
We've also fixed a bug, where the role in a child of a share wasn't shown.

https://github.com/owncloud/web/pull/7252
https://github.com/owncloud/web/issues/7110
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
:accessible-label="$gettext('User')"
/>
<div class="files-collaborators-autocomplete-user-text oc-text-truncate">
<span class="oc-text-bold files-collaborators-autocomplete-username" v-text="item.label" />
<span class="files-collaborators-autocomplete-username" v-text="item.label" />
<span
v-if="item.value.shareWithAdditionalInfo"
class="files-collaborators-autocomplete-additional-info"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
}`"
class="files-collaborators-collaborator oc-flex oc-flex-middle oc-py-xs oc-flex-between"
>
<div class="oc-width-2-3 oc-flex oc-flex-middle" style="gap: 10px">
<div class="oc-width-1-1 oc-flex oc-flex-middle" style="gap: 10px">
<avatar-image
v-if="isUser || isSpace"
:userid="share.collaborator.name"
Expand All @@ -21,29 +21,87 @@
:name="shareTypeKey"
class="files-collaborators-collaborator-indicator"
/>
<div class="oc-text-truncate">
<p v-oc-tooltip="shareDisplayNameTooltip" class="oc-text-bold oc-text-truncate oc-m-rm">
<span
aria-hidden="true"
class="files-collaborators-collaborator-name"
v-text="shareDisplayName"
/>
<span
v-if="shareAdditionalInfo"
aria-hidden="true"
class="files-collaborators-collaborator-additional-info"
v-text="shareAdditionalInfo"
/>
<div class="oc-text-truncate oc-width-1-1">
<div class="oc-flex oc-flex-middle">
<span v-oc-tooltip="shareDisplayNameTooltip" class="oc-text-truncate oc-m-rm">
<span
aria-hidden="true"
class="files-collaborators-collaborator-name"
v-text="shareDisplayName"
/>
</span>
<span class="oc-invisible-sr" v-text="screenreaderShareDisplayName" />
</p>
<p class="oc-m-rm oc-flex">
<span
aria-hidden="true"
class="files-collaborators-collaborator-share-type"
v-text="shareTypeText"
/>
<span v-if="sharedParentRoute" class="oc-resource-indicators oc-text-truncate">
<span class="oc-mx-s">·</span>
<oc-button
:id="`share-access-details-toggle-${share.id}`"
class="oc-ml-xs files-collaborators-collaborator-access-details-button"
appearance="raw"
>
<oc-icon name="information" fill-type="line" size="small" />
</oc-button>
<oc-drop
class="share-access-details-drop"
:toggle="`#share-access-details-toggle-${share.id}`"
mode="click"
>
<h5 v-translate class="oc-text-bold oc-mt-rm">Access details</h5>
<oc-list>
<li v-if="shareAdditionalInfo" class="oc-flex">
<span v-translate class="oc-width-1-2">Addition</span
><span
class="files-collaborators-collaborator-additional-info oc-width-1-2"
v-text="shareAdditionalInfo"
/>
</li>
<li class="oc-flex">
<span v-translate class="oc-width-1-2">Type</span
><span
class="files-collaborators-collaborator-share-type oc-width-1-2"
v-text="shareTypeText"
/>
</li>
</oc-list>
</oc-drop>
</div>
<div class="oc-m-rm oc-flex oc-flex-middle oc-flex-between">
<div>
<div v-if="canEditOrDelete" class="oc-flex oc-flex-nowrap oc-flex-right oc-flex-middle">
<role-dropdown
:resource="highlightedFile"
:dom-selector="shareDomSelector"
:existing-permissions="share.customPermissions"
:existing-role="share.role"
:allow-share-permission="hasResharing || isSpace"
class="files-collaborators-collaborator-role"
@optionChange="shareRoleChanged"
/>
</div>
<div v-else-if="share.role">
<span class="oc-mr-xs" v-text="share.role.label" />
</div>
</div>
<div class="oc-flex oc-flex-between oc-flex-middle oc-pl-s">
<span v-if="hasExpirationDate">
<oc-icon
v-oc-tooltip="expirationDate"
class="files-collaborators-collaborator-expiration"
data-testid="recipient-info-expiration-date"
:aria-label="expirationDate"
name="calendar"
fill-type="line"
/>
<span class="oc-invisible-sr" v-text="screenreaderShareExpiration" />
</span>
<edit-dropdown
v-if="canEditOrDelete"
class="files-collaborators-collaborator-edit"
data-testid="collaborator-edit"
:expiration-date="share.expires ? share.expires : null"
:share-category="shareCategory"
@expirationDateChanged="shareExpirationChanged"
@removeShare="removeShare"
/>
</div>
<div v-if="sharedParentRoute" class="oc-resource-indicators oc-text-truncate">
<router-link
v-oc-tooltip="$gettext('Navigate to parent folder')"
class="parent-folder oc-text-truncate"
Expand All @@ -53,47 +111,10 @@
<oc-icon name="folder-2" size="small" fill-type="line" class="oc-px-xs" />
<span class="text oc-text-truncate" v-text="sharedParentDir" />
</router-link>
</span>
<span class="oc-invisible-sr" v-text="screenreaderShareDetails" />
</p>
<p v-if="hasExpirationDate" class="oc-m-rm">
<span
v-oc-tooltip="expirationDate"
aria-hidden="true"
class="files-collaborators-collaborator-expiration"
data-testid="recipient-info-expiration-date"
tabindex="0"
v-text="shareExpirationText"
/>
<span class="oc-invisible-sr" v-text="screenreaderShareExpiration" />
</p>
</div>
</div>
</div>
</div>
<div
v-if="canEditOrDelete"
class="oc-width-1-3 oc-flex oc-flex-nowrap oc-flex-right oc-flex-middle"
>
<role-dropdown
:resource="highlightedFile"
:dom-selector="shareDomSelector"
:existing-permissions="share.customPermissions"
:existing-role="share.role"
:allow-share-permission="hasResharing || isSpace"
class="files-collaborators-collaborator-role"
@optionChange="shareRoleChanged"
/>
<edit-dropdown
class="files-collaborators-collaborator-edit"
data-testid="collaborator-edit"
:expiration-date="share.expires ? share.expires : null"
:share-category="shareCategory"
@expirationDateChanged="shareExpirationChanged"
@removeShare="removeShare"
/>
</div>
<div v-else-if="share.role">
<span class="oc-mr-xs" v-text="share.role.label" />
</div>
</div>
</template>

Expand Down Expand Up @@ -190,14 +211,13 @@ export default defineComponent({
},

shareAdditionalInfo() {
if (!this.share.collaborator.additionalInfo) {
return
}
return ` (${this.share.collaborator.additionalInfo})`
return this.share.collaborator.additionalInfo
AlexAndBear marked this conversation as resolved.
Show resolved Hide resolved
},

shareDisplayNameTooltip() {
return this.shareDisplayName + (this.shareAdditionalInfo || '')
return (
this.shareDisplayName + (this.shareAdditionalInfo ? `(${this.shareAdditionalInfo})` : '')
)
},

screenreaderShareDisplayName() {
Expand All @@ -214,11 +234,6 @@ export default defineComponent({
return this.$gettextInterpolate(translated, context)
},

screenreaderShareDetails() {
const translated = this.$gettext('Share type: %{ shareType }')
return this.$gettextInterpolate(translated, { shareType: this.shareTypeText })
},

shareExpirationText() {
const translated = this.$gettext('Expires %{ expiryDateRelative }')
return this.$gettextInterpolate(translated, {
Expand Down Expand Up @@ -258,6 +273,12 @@ export default defineComponent({

sharedParentDir() {
return this.sharedParentRoute?.params?.item.split('/').pop()
},

shareDetailsHelperContent() {
return {
text: this.$gettext('Invite persons or groups to access this file or folder.')
}
}
},
methods: {
Expand Down
2 changes: 1 addition & 1 deletion packages/web-app-files/src/helpers/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ export function buildCollaboratorShare(s, file, allowSharePermission): Share {
share.customPermissions = SharePermissions.bitmaskToPermissions(s.permissions)
share.role = PeopleShareRoles.getByBitmask(
parseInt(s.permissions),
file.isFolder,
file.isFolder || file.type === 'folder',
allowSharePermission
)
// share.email = '[email protected]' // hm, where do we get the mail from? share_with_additional_info:Object?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const selectors = {
notUserAvatar: 'oc-avatar-item-stub.files-collaborators-collaborator-indicator',
collaboratorAdditionalInfo: '.files-collaborators-collaborator-additional-info',
collaboratorName: '.files-collaborators-collaborator-name',
shareType: '.files-collaborators-collaborator-share-type',
accessDetailsButton: '.files-collaborators-collaborator-access-details-button',
collaboratorRole: '.files-collaborators-collaborator-role',
collaboratorEdit: '.files-collaborators-collaborator-edit',
shareInheritanceIndicators: '.oc-resource-indicators'
Expand Down Expand Up @@ -58,25 +58,9 @@ describe('Collaborator ListItem component', () => {
const wrapper = createWrapper()
expect(wrapper.find(selectors.collaboratorName).text()).toEqual('Brian Murphy')
})
describe('additionalInfo', () => {
it('shows additional information about the collaborator if set', () => {
const wrapper = createWrapper()
expect(wrapper.find(selectors.collaboratorAdditionalInfo).text()).toEqual(
'([email protected])'
)
})
it('does not show additional information about the collaborator if not set', () => {
const wrapper = createWrapper({
collaborator: {
displayName: 'Alice Hansen'
}
})
expect(wrapper.find(selectors.collaboratorAdditionalInfo).exists()).toBeFalsy()
})
})
it.each(ShareTypes.authenticated)('shows a label for the share type', (shareType) => {
it.each(ShareTypes.authenticated)('shows a button for the access details', (shareType) => {
const wrapper = createWrapper({ shareType: shareType.value })
expect(wrapper.find(selectors.shareType).text()).toBe(shareType.label)
expect(wrapper.find(selectors.accessDetailsButton).exists()).toBeTruthy()
})
})
describe('modifiable property', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,38 @@

exports[`Collaborator ListItem component share inheritance indicators show when sharedParentRoute is given 1`] = `
<div data-testid="collaborator-user-item-brian" class="files-collaborators-collaborator oc-flex oc-flex-middle oc-py-xs oc-flex-between">
<div class="oc-width-2-3 oc-flex oc-flex-middle" style="gap: 10px;">
<div class="oc-width-1-1 oc-flex oc-flex-middle" style="gap: 10px;">
<avatar-image-stub userid="brian" user-name="Brian Murphy" width="48" class="files-collaborators-collaborator-indicator"></avatar-image-stub>
<div class="oc-text-truncate">
<p class="oc-text-bold oc-text-truncate oc-m-rm"><span aria-hidden="true" class="files-collaborators-collaborator-name">Brian Murphy</span> <span aria-hidden="true" class="files-collaborators-collaborator-additional-info"> ([email protected])</span> <span class="oc-invisible-sr">Share receiver name: Brian Murphy ([email protected])</span></p>
<p class="oc-m-rm oc-flex"><span aria-hidden="true" class="files-collaborators-collaborator-share-type">User</span> <span class="oc-resource-indicators oc-text-truncate"><span class="oc-mx-s">·</span>
<router-link-stub to="[object Object]" class="parent-folder oc-text-truncate"><span class="text">via</span>
<oc-icon-stub name="folder-2" size="small" fill-type="line" class="oc-px-xs"></oc-icon-stub> <span class="text oc-text-truncate">folder</span>
</router-link-stub>
</span> <span class="oc-invisible-sr">Share type: User</span>
</p>
<!---->
<div class="oc-text-truncate oc-width-1-1">
<div class="oc-flex oc-flex-middle"><span class="oc-text-truncate oc-m-rm"><span aria-hidden="true" class="files-collaborators-collaborator-name">Brian Murphy</span></span> <span class="oc-invisible-sr">Share receiver name: Brian Murphy ([email protected])</span>
<oc-button-stub id="share-access-details-toggle-asdf" appearance="raw" class="oc-ml-xs files-collaborators-collaborator-access-details-button">
<oc-icon-stub name="information" fill-type="line" size="small"></oc-icon-stub>
</oc-button-stub>
<oc-drop-stub toggle="#share-access-details-toggle-asdf" mode="click" class="share-access-details-drop">
<h5 class="oc-text-bold oc-mt-rm" data-msgid="Access details" data-current-language="en_US">Access details</h5>
<oc-list-stub>
<li class="oc-flex"><span class="oc-width-1-2" data-msgid="Addition" data-current-language="en_US">Addition</span><span class="files-collaborators-collaborator-additional-info oc-width-1-2">[email protected]</span></li>
<li class="oc-flex"><span class="oc-width-1-2" data-msgid="Type" data-current-language="en_US">Type</span><span class="files-collaborators-collaborator-share-type oc-width-1-2">User</span></li>
</oc-list-stub>
</oc-drop-stub>
</div>
<div class="oc-m-rm oc-flex oc-flex-middle oc-flex-between">
<div>
<div class="oc-flex oc-flex-nowrap oc-flex-right oc-flex-middle">
<role-dropdown-stub resource="[object Object]" existingrole="[object Object]" existingpermissions="" domselector="asdf" class="files-collaborators-collaborator-role"></role-dropdown-stub>
</div>
</div>
<div class="oc-flex oc-flex-between oc-flex-middle oc-pl-s">
<!---->
<edit-dropdown-stub sharecategory="user" data-testid="collaborator-edit" class="files-collaborators-collaborator-edit"></edit-dropdown-stub>
</div>
<div class="oc-resource-indicators oc-text-truncate">
<router-link-stub to="[object Object]" class="parent-folder oc-text-truncate"><span class="text">via</span>
<oc-icon-stub name="folder-2" size="small" fill-type="line" class="oc-px-xs"></oc-icon-stub> <span class="text oc-text-truncate">folder</span>
</router-link-stub>
</div>
</div>
</div>
</div>
<div class="oc-width-1-3 oc-flex oc-flex-nowrap oc-flex-right oc-flex-middle">
<role-dropdown-stub resource="[object Object]" existingrole="[object Object]" existingpermissions="" domselector="asdf" class="files-collaborators-collaborator-role"></role-dropdown-stub>
<edit-dropdown-stub sharecategory="user" data-testid="collaborator-edit" class="files-collaborators-collaborator-edit"></edit-dropdown-stub>
</div>
</div>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ Feature: Shares in share-with pages
Then user "Brian Murphy" should be listed with additional info "<additional-info-result>" in the collaborators list on the webUI
Examples:
| additional-info-field | additional-info-result |
| id | (Brian) |
| email | (brian@example.org) |
| id | Brian |
| email | brian@example.org |

@issue-ocis-1328
Scenario: collaborators list does not contain additional info when disabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ Feature: Shares collaborator list
Then user "Brian Murphy" should be listed with additional info "<additional-info-result>" in the collaborators list on the webUI
Examples:
| additional-info-field | additional-info-result |
| id | (Brian) |
| email | (brian@example.org) |
| id | Brian |
| email | brian@example.org |


Scenario: collaborators list does not contain additional info when disabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,19 @@ module.exports = {

results = listItemElementIds.map(async (collaboratorElementId) => {
const collaboratorResult = {}

let accessDetailsBtn = null
await this.api.elementIdElement(
collaboratorElementId,
'css selector',
this.elements.collaboratorAccessDetailsButton,
(result) => {
accessDetailsBtn = result.value.ELEMENT
}
)
await this.api.elementIdClick(accessDetailsBtn)
this.waitForElementVisible(this.elements.collaboratorAccessDetailsDrop)

for (const attrName in subSelectors) {
let attrElementId = null
await this.api.elementIdElement(
Expand All @@ -161,7 +174,7 @@ module.exports = {
collaboratorResult[attrName] = false
}
}

this.api.mouseButtonClick()
return collaboratorResult
})

Expand Down Expand Up @@ -273,6 +286,12 @@ module.exports = {
expirationDatePickerTrigger: {
selector: '//button[contains(@class, "files-collaborators-expiration-button")]',
locateStrategy: 'xpath'
},
collaboratorAccessDetailsButton: {
selector: '.files-collaborators-collaborator-access-details-button'
},
collaboratorAccessDetailsDrop: {
selector: '.share-access-details-drop'
}
}
}