mirror of
https://github.com/nextcloud/contacts.git
synced 2025-08-20 13:54:12 +00:00
fix: Make circle members visible again by moving them out of the modal
Signed-off-by: Julius Knorr <jus@bitgrid.net>
This commit is contained in:

committed by
Ferdinand Thiessen

parent
466863442d
commit
f25e5d1327
@ -72,41 +72,7 @@
|
|||||||
@update:value="onDescriptionChangeDebounce" />
|
@update:value="onDescriptionChangeDebounce" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section v-if="circle.isMember" class="circle-details-section">
|
<section v-if="circle.isMember">
|
||||||
<ContentHeading>
|
|
||||||
{{ t('contacts', 'Members') }}
|
|
||||||
</ContentHeading>
|
|
||||||
<div class="avatar-box">
|
|
||||||
<div ref="avatarList" class="avatar-list">
|
|
||||||
<Avatar v-for="member in membersLimited"
|
|
||||||
:key="member.singleId"
|
|
||||||
:user="member.userId"
|
|
||||||
:display-name="member.displayName"
|
|
||||||
:is-no-user="!member.isUser"
|
|
||||||
:icon-class="member.isUser ? null : 'icon-group-white'"
|
|
||||||
:size="avatarSize" />
|
|
||||||
<Avatar v-if="hasExtraMembers">
|
|
||||||
<template #icon>
|
|
||||||
<DotsHorizontal :size="16" />
|
|
||||||
</template>
|
|
||||||
</Avatar>
|
|
||||||
</div>
|
|
||||||
<Button class="members-button" @click="showMembersModal = true">
|
|
||||||
<template #icon>
|
|
||||||
<AccountMultiplePlus :size="20" />
|
|
||||||
</template>
|
|
||||||
{{ t('contacts', 'Manage members') }}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<Modal v-if="showMembersModal" @close="showMembersModal=false">
|
|
||||||
<div class="members-modal">
|
|
||||||
<h2>{{ t('contacts', 'Team members') }}</h2>
|
|
||||||
<MemberList :list="members" />
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<ContentHeading>
|
<ContentHeading>
|
||||||
{{ t('contacts', 'Team resources') }}
|
{{ t('contacts', 'Team resources') }}
|
||||||
</ContentHeading>
|
</ContentHeading>
|
||||||
@ -136,6 +102,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section v-if="members.length > 0">
|
||||||
|
<ContentHeading>
|
||||||
|
{{ t('contacts', 'Team members') }}
|
||||||
|
</ContentHeading>
|
||||||
|
<MemberList :list="members" />
|
||||||
|
</section>
|
||||||
|
|
||||||
<Modal v-if="(circle.isOwner || circle.isAdmin) && !circle.isPersonal && showSettingsModal" @close="showSettingsModal=false">
|
<Modal v-if="(circle.isOwner || circle.isAdmin) && !circle.isPersonal && showSettingsModal" @close="showSettingsModal=false">
|
||||||
<div class="circle-settings">
|
<div class="circle-settings">
|
||||||
<h2>{{ t('contacts', 'Team settings') }}</h2>
|
<h2>{{ t('contacts', 'Team settings') }}</h2>
|
||||||
@ -216,8 +189,6 @@ import Cog from 'vue-material-design-icons/Cog.vue'
|
|||||||
import Login from 'vue-material-design-icons/Login.vue'
|
import Login from 'vue-material-design-icons/Login.vue'
|
||||||
import Logout from 'vue-material-design-icons/Logout.vue'
|
import Logout from 'vue-material-design-icons/Logout.vue'
|
||||||
import IconDelete from 'vue-material-design-icons/Delete.vue'
|
import IconDelete from 'vue-material-design-icons/Delete.vue'
|
||||||
import AccountMultiplePlus from 'vue-material-design-icons/AccountMultiplePlus.vue'
|
|
||||||
import DotsHorizontal from 'vue-material-design-icons/DotsHorizontal.vue'
|
|
||||||
|
|
||||||
import { CircleEdit, editCircle } from '../services/circles.ts'
|
import { CircleEdit, editCircle } from '../services/circles.ts'
|
||||||
import CircleActionsMixin from '../mixins/CircleActionsMixin.js'
|
import CircleActionsMixin from '../mixins/CircleActionsMixin.js'
|
||||||
@ -239,14 +210,12 @@ export default {
|
|||||||
CirclePasswordSettings,
|
CirclePasswordSettings,
|
||||||
ContentHeading,
|
ContentHeading,
|
||||||
DetailsHeader,
|
DetailsHeader,
|
||||||
DotsHorizontal,
|
|
||||||
ListItem,
|
ListItem,
|
||||||
Cog,
|
Cog,
|
||||||
Login,
|
Login,
|
||||||
Logout,
|
Logout,
|
||||||
Modal,
|
Modal,
|
||||||
IconDelete,
|
IconDelete,
|
||||||
AccountMultiplePlus,
|
|
||||||
RichContenteditable,
|
RichContenteditable,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -445,17 +414,9 @@ export default {
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.members-modal {
|
:deep(.app-content-list) {
|
||||||
padding: 12px;
|
max-width: 100%;
|
||||||
|
border: 0;
|
||||||
h2 {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.app-content-list) {
|
|
||||||
max-width: 100%;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.circle-settings {
|
.circle-settings {
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</AppContentList>
|
</AppContentList>
|
||||||
|
|
||||||
<AppContentList v-else :class="{ showdetails: showDetails }">
|
<AppContentList v-else>
|
||||||
<div class="members-list__new">
|
<div class="members-list__new">
|
||||||
<Button v-if="circle.canManageMembers"
|
<Button v-if="circle.canManageMembers"
|
||||||
@click="onShowPicker(circle.id)">
|
@click="onShowPicker(circle.id)">
|
||||||
@ -38,13 +38,6 @@
|
|||||||
</template>
|
</template>
|
||||||
{{ t('contacts', 'Add members') }}
|
{{ t('contacts', 'Add members') }}
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-if="isMobile"
|
|
||||||
@click="showCircleDetails">
|
|
||||||
<template #icon>
|
|
||||||
<IconInfo :size="20" />
|
|
||||||
</template>
|
|
||||||
{{ t('contacts', 'Show team details') }}
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MembersListItem v-for="member in filteredList"
|
<MembersListItem v-for="member in filteredList"
|
||||||
@ -78,7 +71,6 @@ import MembersListItem from './MembersList/MembersListItem.vue'
|
|||||||
import EntityPicker from './EntityPicker/EntityPicker.vue'
|
import EntityPicker from './EntityPicker/EntityPicker.vue'
|
||||||
import IconContact from 'vue-material-design-icons/AccountMultiple.vue'
|
import IconContact from 'vue-material-design-icons/AccountMultiple.vue'
|
||||||
import IconAdd from 'vue-material-design-icons/Plus.vue'
|
import IconAdd from 'vue-material-design-icons/Plus.vue'
|
||||||
import IconInfo from 'vue-material-design-icons/InformationOutline.vue'
|
|
||||||
import RouterMixin from '../mixins/RouterMixin.js'
|
import RouterMixin from '../mixins/RouterMixin.js'
|
||||||
|
|
||||||
import { getRecommendations, getSuggestions } from '../services/collaborationAutocompletion.js'
|
import { getRecommendations, getSuggestions } from '../services/collaborationAutocompletion.js'
|
||||||
@ -96,7 +88,6 @@ export default {
|
|||||||
EmptyContent,
|
EmptyContent,
|
||||||
IconContact,
|
IconContact,
|
||||||
IconAdd,
|
IconAdd,
|
||||||
IconInfo,
|
|
||||||
IconLoading,
|
IconLoading,
|
||||||
MembersListItem,
|
MembersListItem,
|
||||||
},
|
},
|
||||||
@ -112,11 +103,6 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
showDetails: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
@ -154,11 +140,15 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
filteredList() {
|
filteredList() {
|
||||||
|
const groupList = CIRCLES_MEMBER_GROUPING.map((group) => {
|
||||||
|
group.label = group.labelStandalone
|
||||||
|
return group
|
||||||
|
})
|
||||||
return Object.keys(this.groupedList)
|
return Object.keys(this.groupedList)
|
||||||
// Object.keys returns string
|
// Object.keys returns string
|
||||||
.map(type => parseInt(type, 10))
|
.map(type => parseInt(type, 10))
|
||||||
// Map populated types to the group entry
|
// Map populated types to the group entry
|
||||||
.map(type => CIRCLES_MEMBER_GROUPING.find(group => group.type === type))
|
.map(type => groupList.find(group => group.type === type))
|
||||||
// Removed undefined group
|
// Removed undefined group
|
||||||
.filter(group => group !== undefined)
|
.filter(group => group !== undefined)
|
||||||
// Injecting headings
|
// Injecting headings
|
||||||
@ -288,10 +278,6 @@ export default {
|
|||||||
this.pickerData = []
|
this.pickerData = []
|
||||||
this.pickerSelection = {}
|
this.pickerSelection = {}
|
||||||
},
|
},
|
||||||
|
|
||||||
showCircleDetails() {
|
|
||||||
this.$emit('update:showDetails', true)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -304,12 +290,12 @@ export default {
|
|||||||
|
|
||||||
&__new {
|
&__new {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
display: inline-flex;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
height: 44px;
|
|
||||||
background-position: 14px center;
|
background-position: 14px center;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,18 +111,20 @@ export const PUBLIC_CIRCLE_CONFIG = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Represents the picker options but also the
|
// Represents the picker options (label is used lower case in a list of options: Search users, groups, teams, ...)
|
||||||
// sorting of the members list
|
// labelStandalone is used as heading for the member list where we need it starting captialized
|
||||||
export const CIRCLES_MEMBER_GROUPING = [
|
export const CIRCLES_MEMBER_GROUPING = [
|
||||||
{
|
{
|
||||||
id: `picker-${ShareType.User}`,
|
id: `picker-${ShareType.User}`,
|
||||||
label: t('contacts', 'users'),
|
label: t('contacts', 'users'),
|
||||||
|
labelStandalone: t('contacts', 'Users'),
|
||||||
share: ShareType.User,
|
share: ShareType.User,
|
||||||
type: MEMBER_TYPE_USER,
|
type: MEMBER_TYPE_USER,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `picker-${ShareType.Group}`,
|
id: `picker-${ShareType.Group}`,
|
||||||
label: t('contacts', 'groups'),
|
label: t('contacts', 'groups'),
|
||||||
|
labelStandalone: t('contacts', 'Groups'),
|
||||||
share: ShareType.Group,
|
share: ShareType.Group,
|
||||||
type: MEMBER_TYPE_GROUP,
|
type: MEMBER_TYPE_GROUP,
|
||||||
},
|
},
|
||||||
@ -142,19 +144,22 @@ export const CIRCLES_MEMBER_GROUPING = [
|
|||||||
{
|
{
|
||||||
id: `picker-${ShareType.Team}`,
|
id: `picker-${ShareType.Team}`,
|
||||||
label: t('contacts', 'teams'),
|
label: t('contacts', 'teams'),
|
||||||
|
labelStandalone: t('contacts', 'Teams'),
|
||||||
share: ShareType.Team,
|
share: ShareType.Team,
|
||||||
type: MEMBER_TYPE_CIRCLE,
|
type: MEMBER_TYPE_CIRCLE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `picker-${ShareType.Email}`,
|
id: `picker-${ShareType.Email}`,
|
||||||
label: t('contacts', 'email addresses'),
|
label: t('contacts', 'email addresses'),
|
||||||
|
labelStandalone: t('contacts', 'Email addresses'),
|
||||||
share: ShareType.Email,
|
share: ShareType.Email,
|
||||||
type: MEMBER_TYPE_MAIL,
|
type: MEMBER_TYPE_MAIL,
|
||||||
},
|
},
|
||||||
// TODO: implement SHARE_TYPE_CONTACT
|
// TODO: implement SHARE_TYPE_CONTACT
|
||||||
{
|
{
|
||||||
id: 'picker-contact',
|
id: 'picker-contact',
|
||||||
label: t('contacts', 'teams'),
|
label: t('contacts', 'contacts'),
|
||||||
|
labelStandalone: t('contacts', 'Contacts'),
|
||||||
share: ShareType.Email,
|
share: ShareType.Email,
|
||||||
type: MEMBER_TYPE_CONTACT,
|
type: MEMBER_TYPE_CONTACT,
|
||||||
},
|
},
|
||||||
|
@ -214,7 +214,7 @@ export default class Contact {
|
|||||||
*
|
*
|
||||||
* @readonly
|
* @readonly
|
||||||
* @memberof Contact
|
* @memberof Contact
|
||||||
*/
|
*/
|
||||||
get hasPhoto() {
|
get hasPhoto() {
|
||||||
return this.dav && this.dav.hasphoto
|
return this.dav && this.dav.hasphoto
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user