Skip to content

Commit

Permalink
feat(landingPage): Add list of members to the landing page
Browse files Browse the repository at this point in the history
Show list of members on landing page if it's not a public share.

Signed-off-by: Jonas <jonas@freesources.org>
  • Loading branch information
mejo- committed Jul 31, 2023
1 parent 5a8adf4 commit cb4e164
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/components/Page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
@click="toggle('sidebar')" />
</NcActions>
</h1>
<LandingPageWidgets v-if="isLandingPage" />
<TextEditor :key="`text-editor-${currentPage.id}`"
ref="texteditor" />
</div>
Expand All @@ -113,6 +114,7 @@ import NcEmojiPicker from '@nextcloud/vue/dist/Components/NcEmojiPicker.js'
import CollectivesIcon from './Icon/CollectivesIcon.vue'
import EmoticonOutlineIcon from 'vue-material-design-icons/EmoticonOutline.vue'
import EditButton from './Page/EditButton.vue'
import LandingPageWidgets from './Page/LandingPageWidgets.vue'
import PageActionMenu from './Page/PageActionMenu.vue'
import PageTemplateIcon from './Icon/PageTemplateIcon.vue'
import TextEditor from './Page/TextEditor.vue'
Expand All @@ -128,6 +130,7 @@ export default {
CollectivesIcon,
EditButton,
EmoticonOutlineIcon,
LandingPageWidgets,
NcActionButton,
NcActions,
NcButton,
Expand Down
32 changes: 32 additions & 0 deletions src/components/Page/LandingPageWidgets.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<div class="landing-page-widgets">
<MembersWidget v-if="!isPublic" />
</div>
</template>

<script>
import { mapGetters } from 'vuex'
import MembersWidget from './LandingPageWidgets/MembersWidget.vue'
export default {
name: 'LandingPageWidgets',
components: {
MembersWidget,
},
computed: {
...mapGetters([
'isPublic',
]),
},
}
</script>

<style lang="scss" scoped>
.landing-page-widgets {
margin: auto;
padding-left: 12px;
max-width: 670px;
}
</style>
126 changes: 126 additions & 0 deletions src/components/Page/LandingPageWidgets/MembersWidget.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<template>
<div class="members-widget">
<WidgetHeading :title="t('collectives', 'Collective members')" />
<div class="members-widget-members">
<NcAvatar v-for="member in trimmedMembers"
:key="member.singleId"
:user-id="member.userId"
:display-name="member.displayName"
:is-no-user="isNoUser(member)"
:icon-class="iconClass(member)"
:disable-menu="true"
:tooltip-message="member.displayName"
:size="44" />
<NcButton v-if="showMoreButton"
type="secondary"
:aria-label="t('collectives', 'Show all members of the collective')"
@click="openCollectiveMembers()">
<template #icon>
<DotsHorizontalIcon :size="20" />
</template>
</NcButton>
</div>
</div>
</template>

<script>
import { mapActions, mapGetters, mapMutations } from 'vuex'
import { NcAvatar, NcButton } from '@nextcloud/vue'
import DotsHorizontalIcon from 'vue-material-design-icons/DotsHorizontal.vue'
import { GET_CIRCLE_MEMBERS } from '../../../store/actions.js'
import { circlesMemberTypes } from '../../../constants.js'
import WidgetHeading from './WidgetHeading.vue'
const SHOW_MEMBERS_COUNT = 3
export default {
name: 'MembersWidget',
components: {
DotsHorizontalIcon,
NcAvatar,
NcButton,
WidgetHeading,
},
computed: {
...mapGetters([
'circleMembersSorted',
'circleMemberType',
'currentCollective',
'isCollectiveAdmin',
'recentPagesUserIds',
]),
sortedMembers() {
return this.circleMembersSorted(this.currentCollective.circleId)
.slice()
.sort(this.sortLastActiveFirst)
},
trimmedMembers() {
return this.sortedMembers
.slice(0, SHOW_MEMBERS_COUNT)
},
isNoUser() {
return function(member) {
return this.circleMemberType(member) !== circlesMemberTypes.TYPE_USER
}
},
iconClass() {
return function(member) {
return this.isNoUser(member) ? 'icon-group-white' : null
}
},
showMoreButton() {
return this.isCollectiveAdmin(this.currentCollective)
|| this.sortedMembers.length > SHOW_MEMBERS_COUNT
},
},
beforeMount() {
this.dispatchGetCircleMembers(this.currentCollective.circleId)
},
methods: {
...mapActions({
dispatchGetCircleMembers: GET_CIRCLE_MEMBERS,
}),
...mapMutations([
'setMembersCollectiveId',
]),
openCollectiveMembers() {
this.setMembersCollectiveId(this.currentCollective.id)
},
/**
* @param {object} m1 First member
* @param {string} m1.userId First member user ID
* @param {object} m2 Second member
* @param {string} m2.userId Second member user ID
*/
sortLastActiveFirst(m1, m2) {
if (this.recentPagesUserIds.includes(m1.userId) && this.recentPagesUserIds.includes(m2.userId)) {
return this.recentPagesUserIds.indexOf(m1.userId) > this.recentPagesUserIds.indexOf(m2.userId)
} else if (this.recentPagesUserIds.includes(m1.userId)) {
return -1
} else if (this.recentPagesUserIds.includes(m2.userId)) {
return 1
}
},
},
}
</script>

<style lang="scss" scoped>
.members-widget-members {
display: flex;
flex-direction: row;
gap: 12px;
}
</style>
27 changes: 27 additions & 0 deletions src/components/Page/LandingPageWidgets/WidgetHeading.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<template>
<div class="widget-heading">
{{ title }}
</div>
</template>

<script>
export default {
name: 'WidgetHeading',
props: {
title: {
type: String,
required: true,
},
},
}
</script>

<style scoped>
.widget-heading {
padding: 30px 0 12px 0;
font-size: 20px;
font-weight: bold;
color: var(--color-text-maxcontrast);
}
</style>
11 changes: 11 additions & 0 deletions src/components/Page/TextEditor.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<template>
<div>
<WidgetHeading v-if="isLandingPage"
:title="t('collectives', 'Description')"
class="text-container-heading" />
<div v-show="showRichText"
id="text-container"
:key="'text-' + currentPage.id"
Expand All @@ -20,6 +23,7 @@
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
import Editor from './Editor.vue'
import RichText from './RichText.vue'
import WidgetHeading from './LandingPageWidgets/WidgetHeading.vue'
import { mapActions, mapGetters, mapMutations } from 'vuex'
import {
GET_VERSIONS,
Expand All @@ -33,6 +37,7 @@ export default {
components: {
Editor,
RichText,
WidgetHeading,
},
mixins: [
Expand All @@ -56,6 +61,7 @@ export default {
'currentPage',
'currentPageDavUrl',
'hasVersionsLoaded',
'isLandingPage',
'isTemplatePage',
'isTextEdit',
'isPublic',
Expand Down Expand Up @@ -251,6 +257,11 @@ export default {
</script>
<style lang="scss" scoped>
.text-container-heading {
max-width: 670px;
margin: auto;
padding-left: 14px;
}
#text-container {
display: block;
Expand Down
16 changes: 16 additions & 0 deletions src/store/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,22 @@ export default {
trashPages(state) {
return state.trashPages.sort((a, b) => b.trashTimestamp - a.trashTimestamp)
},

recentPages(state) {
return state.pages
.slice()
.sort(sortOrders.byTimestamp)
},

recentPagesUserIds(_state, getters) {
return getters.recentPages
// take only userIds
.map(p => p.lastUserId)
// filter out duplicates
.filter((value, index, array) => {
return array.indexOf(value) === index
})
},
},

mutations: {
Expand Down

0 comments on commit cb4e164

Please sign in to comment.