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 <jus@bitgrid.net>
  • Loading branch information
juliushaertl committed Mar 1, 2024
1 parent 89ba71e commit 146908c
Show file tree
Hide file tree
Showing 3 changed files with 321 additions and 13 deletions.
9 changes: 9 additions & 0 deletions l10n/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ msgstr ""
msgid "Options"
msgstr ""

msgid "Other resources"
msgstr ""

msgid "Password is secure"
msgstr ""

Expand Down Expand Up @@ -286,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 @@ -373,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
293 changes: 293 additions & 0 deletions src/components/NcRelatedResourcesPanel/NcTeamResources.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
<template>
<div v-if="appEnabled && isVisible" class="related-resources__team">
<div class="related-resources__header">
<h5>{{ t('Related team resources') }}</h5>
</div>
<div v-for="team in teamResources"
:key="team.teamId"
class="related-team"
:class="{ 'related-team__open': open(team.teamId) }">
<h5 class="related-team__header">
<a class="related-team__link" @click="toggleOpen(team.teamId)">
<AccountGroup :size="20" />
{{ team.displayName }}
</a>
<NcActions>
<NcActionLink :href="team.link" :label="t('View team')">
<template #icon>
<OpenInNew :size="20" />
</template>
</NcActionLink>
</NcActions>
<NcButton type="tertiary" @click.stop="toggleOpen(team.teamId)">
<ChevronUp v-if="open(team.teamId)"
:size="20" />
<ChevronDown v-else
:size="20" />
</NcButton>
</h5>

<div v-if="open(team.teamId)">
<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-if="resource.iconUrl" class="resource__icon">
<img :src="resource.iconURL" alt="">
</span>
<span class="resource__name">
{{ resource.label }}
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</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 NcActions from '../NcActions/NcActions.vue'
import NcActionLink from '../NcActionLink/NcActionLink.vue'
import NcIconSvgWrapper from '../NcIconSvgWrapper/NcIconSvgWrapper.vue'
import { t } from '../../l10n.js'
export default {
name: 'NcTeamResources',
components: {
AccountGroup,
ChevronDown,
ChevronUp,
OpenInNew,
NcButton,
NcActions,
NcActionLink,
NcIconSvgWrapper,
},
props: {
providerId: {
type: String,
default: null,
},
itemId: {
type: [String, Number],
default: null,
},
resourceType: {
type: String,
default: '',
},
/**
* Set the maximum number of resources to load
*/
limit: {
type: Number,
default: 0,
},
/**
* Only used by the files sidebar
*
* File info is passed when registered with `OCA.Sharing.ShareTabSections.registerSection()`
*/
fileInfo: {
type: Object,
default: null,
},
/**
* Make the header name dynamic
*/
header: {
type: String,
default: t('Related resources'),
},
headerOther: {
type: String,
default: t('Other resources'),
},
description: {
type: String,
default: t('Anything shared with the same group of people will show up here'),
},
/**
* If this element is used on a primary element set to true for primary styling.
*/
primary: {
type: Boolean,
default: false,
},
},
data() {
return {
appEnabled: OC?.appswebroots?.circles !== undefined && (OC.config.version.split('.')[0] ?? 0) >= 29,
loading: false,
error: null,
teamResources: null,
teamOpen: null,
}
},
computed: {
isVisible() {
return !this.loading && this.error === null && 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 === teamId
}
},
},
watch: {
providerId() {
this.fetchTeamResources()
},
itemId() {
this.fetchTeamResources()
},
},
created() {
this.fetchTeamResources()
},
methods: {
t,
async fetchTeamResources() {
try {
const response = await axios.get(generateOcsUrl(`/teams/resources/${this.providerId}/${this.itemId}`))
this.error = null
this.teamResources = response.data.ocs.data.teams
this.teamOpen = this.teamResources[0]?.teamId
} catch (e) {
this.error = e
console.error(e)
} finally {
this.loading = false
}
},
toggleOpen(teamId) {
this.teamOpen = this.teamOpen !== teamId ? teamId : null
},
},
}
</script>
<style lang="scss" scoped>
h5 {
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: 5px;
display: flex;
gap: 12px;
}
&__link {
display: flex;
flex-grow: 1;
align-items: center;
gap: 12px;
padding: 6px 12px;
font-weight: bold;
}
.related-team-provider {
padding: 6px 12px;
h6 {
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 146908c

Please sign in to comment.