Skip to content

Commit

Permalink
feat: List team resources in related resources panel
Browse files Browse the repository at this point in the history
Signed-off-by: Julius Härtl <[email protected]>
  • Loading branch information
juliusknorr committed Mar 5, 2024
1 parent 3b81497 commit 80aa3af
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 13 deletions.
6 changes: 6 additions & 0 deletions l10n/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,9 @@ msgstr ""
msgid "Related resources"
msgstr ""

msgid "Related team resources"
msgstr ""

#. TRANSLATORS: A color name for RGB(191, 103, 139)
msgid "Rosy brown"
msgstr ""
Expand Down Expand Up @@ -376,6 +379,9 @@ msgstr ""
msgid "User status: {status}"
msgstr ""

msgid "View team"
msgstr ""

#. TRANSLATORS: A color name for RGB(211, 169, 103)
msgid "Whiskey"
msgstr ""
Expand Down
32 changes: 19 additions & 13 deletions src/components/NcRelatedResourcesPanel/NcRelatedResourcesPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,30 @@ export default {
</docs>

<template>
<div v-if="appEnabled && isVisible" class="related-resources">
<div class="related-resources__header">
<h5>{{ header }}</h5>
<p>{{ subline }}</p>
</div>
<div>
<NcTeamResources :provider-id="providerId"
:item-id="itemId" />

<div v-if="appEnabled && isVisible" class="related-resources">
<div class="related-resources__header">
<h5>{{ header }}</h5>
<p>{{ subline }}</p>
</div>

<NcResource v-for="resource in resources"
:key="resource.itemId"
class="related-resources__entry"
:icon="resource.icon"
:name="resource.title"
:url="resource.url" />
<NcResource v-for="resource in resources"
:key="resource.itemId"
class="related-resources__entry"
:icon="resource.icon"
:name="resource.title"
:url="resource.url" />
</div>
</div>
</template>

<script>
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'

import NcTeamResources from './NcTeamResources.vue'
import NcResource from './NcResource.vue'

import { t } from '../../l10n.js'
Expand All @@ -73,6 +78,7 @@ export default {

components: {
NcResource,
NcTeamResources,
},

props: {
Expand Down Expand Up @@ -255,10 +261,10 @@ export default {
<style lang="scss" scoped>
.related-resources {
&__header {
margin: 0 0 10px 46px;

h5 {
font-weight: bold;
margin-bottom: 6px;
}

p {
Expand Down
254 changes: 254 additions & 0 deletions src/components/NcRelatedResourcesPanel/NcTeamResources.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
<template>
<div v-if="appEnabled && isVisible" class="team-resources">
<h5 class="team-resources__header">
{{ t('Related team resources') }}
</h5>
<details v-for="team in teamResources"
:key="team.teamId"
name="Team resources"
class="related-team"
:open="open(team.teamId)"
@toggle="(event) => toggleOpen(team.teamId, event.target.open)">
<summary class="related-team__header">
<h5 class="related-team__name">
<AccountGroup :size="20" />
{{ team.displayName }}
</h5>
<NcButton type="tertiary"
:href="team.link"
:aria-label="t('View team')"
:title="t('View team')">
<template #icon>
<OpenInNew :size="20" />
</template>
</NcButton>

<ChevronUp v-if="open(team.teamId)"
:size="20" />
<ChevronDown v-else
:size="20" />
</summary>

<div>
<div v-for="provider in teamProviders(team.teamId)"
:key="provider.id"
class="related-team-provider">
<h6 v-if="provider.resources.length > 0">
{{ provider.name }}
</h6>
<ul>
<li v-for="resource in provider.resources" :key="resource.url" class="related-team-resource">
<a :href="resource.url" class="related-team-resource__link">
<span v-if="resource.iconEmoji" class="resource__icon">
{{ resource.iconEmoji }}
</span>
<NcIconSvgWrapper v-else-if="resource.iconSvg"
class="resource__icon"
:svg="resource.iconSvg"
:size="20" />
<span v-else-if="resource.iconUrl" class="resource__icon">
<img :src="resource.iconURL" alt="">
</span>
<span class="resource__name">
{{ resource.label }}
</span>
</a>
</li>
</ul>
</div>
</div>
</details>
</div>
</template>

<script>
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import AccountGroup from 'vue-material-design-icons/AccountGroup.vue'
import ChevronDown from 'vue-material-design-icons/ChevronDown.vue'
import ChevronUp from 'vue-material-design-icons/ChevronUp.vue'
import OpenInNew from 'vue-material-design-icons/OpenInNew.vue'
import NcButton from '../NcButton/NcButton.vue'
import NcIconSvgWrapper from '../NcIconSvgWrapper/NcIconSvgWrapper.vue'
import { t } from '../../l10n.js'
export default {
name: 'NcTeamResources',
components: {
AccountGroup,
ChevronDown,
ChevronUp,
OpenInNew,
NcButton,
NcIconSvgWrapper,
},
props: {
providerId: {
type: String,
default: null,
},
itemId: {
type: [String, Number],
default: null,
},
},
data() {
return {
appEnabled: OC?.appswebroots?.circles !== undefined && (OC.config.version.split('.')[0] ?? 0) >= 29,
loading: false,
teamResources: null,
teamOpen: [],
}
},
computed: {
isVisible() {
return !this.loading && this.teamResources?.length > 0
},
teamProviders() {
return (teamId) => {
const team = this.teamResources.find(t => t.teamId === teamId)
return team.resources?.reduce((acc, resource) => {
if (resource.provider.id === this.providerId && resource.id === String(this.itemId)) {
return acc
}
if (!acc[resource.provider.id]) {
acc[resource.provider.id] = resource.provider
acc[resource.provider.id].resources = []
}
if (resource.provider.id === this.providerId && resource.id === String(this.itemId)) {
return acc
}
acc[resource.provider.id].resources.push(resource)
return acc
}, {})
}
},
open() {
return (teamId) => {
return this.teamOpen.indexOf(teamId) !== -1
}
},
},
watch: {
providerId() {
this.fetchTeamResources()
},
itemId() {
this.fetchTeamResources()
},
},
created() {
this.fetchTeamResources()
},
methods: {
t,
async fetchTeamResources() {
try {
this.loading = true
const response = await axios.get(generateOcsUrl(`/teams/resources/${this.providerId}/${this.itemId}`))
this.teamResources = response.data.ocs.data.teams
this.teamOpen = [this.teamResources[0]?.teamId]
} catch (e) {
this.teamResources = null
console.error(e)
} finally {
this.loading = false
}
},
toggleOpen(teamId, open) {
if (open) {
this.teamOpen.push(teamId)
} else {
this.teamOpen.splice(this.teamOpen.indexOf(teamId), 1)
}
},
},
}
</script>
<style lang="scss" scoped>
.team-resources__header {
font-weight: bold;
margin-bottom: 6px;
}
.related-team {
border-radius: var(--border-radius-rounded);
border: 2px solid var(--color-border-dark);
margin-bottom: 6px;
&__open {
border-color: var(--color-primary-element);
}
&__header {
padding: 6px;
padding-right: 24px;
display: flex;
gap: 12px;
}
&__name {
display: flex;
flex-grow: 1;
align-items: center;
gap: 12px;
padding: 6px 12px;
font-weight: bold;
margin: 0;
}
.related-team-provider {
padding: 6px 12px;
&__name {
font-weight: bold;
margin-bottom: 3px;
}
&__link {
display: flex;
gap: 12px;
padding: 6px 12px;
font-weight: bold;
}
}
.related-team-resource {
&__link {
display: flex;
gap: 12px;
height: 44px;
align-items: center;
border-radius: var(--border-radius-large);
&:hover {
background-color: var(--color-background-hover);
}
&:focus {
background-color: var(--color-background-hover);
outline: 2px solid var(--color-primary-element);
}
}
.resource__icon {
width: 44px;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
}
}
</style>

0 comments on commit 80aa3af

Please sign in to comment.