Skip to content

Commit c4d0015

Browse files
authored
Merge pull request #5545 from lyttam/BOAC-6670
BOAC-6670: moves author details to a tooltip
2 parents 0b87114 + 51b2472 commit c4d0015

6 files changed

Lines changed: 483 additions & 459 deletions

File tree

src/components/appointment/AdvisingAppointment.vue

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
<template>
2-
<article class="w-100">
2+
<div class="w-100">
33
<div
44
v-if="!isOpen"
55
:id="`appointment-${appointment.id}-is-closed`"
6-
class="appointment-snippet-when-closed d-flex"
6+
:aria-controls="`appointment-${appointment.id}-is-open`"
7+
:aria-expanded="false"
8+
class="appointment-snippet-when-closed cursor-pointer d-flex"
9+
role="button"
10+
:tabindex="0"
11+
@click="onClickOpen"
12+
@keyup.enter="onClickOpen"
713
>
814
<div
915
:id="`appointment-${appointment.id}-details-closed`"
@@ -60,34 +66,6 @@
6066
show-reason
6167
/>
6268
</div>
63-
<div
64-
v-if="get(advisor, 'name') && (appointment.legacySource || ['Calendly', 'YCBM'].includes(appointment.createdBy))"
65-
class="pt-2"
66-
>
67-
<a
68-
v-if="advisor.uid"
69-
:id="`appointment-${appointment.id}-advisor-name`"
70-
:aria-label="`${advisor.name} UC Berkeley Directory page (opens in new tab)`"
71-
:href="`https://www.berkeley.edu/directory/results?search-term=${advisor.name}`"
72-
target="_blank"
73-
>
74-
{{ advisor.name }}
75-
</a>
76-
<span v-if="!advisor.uid" :id="`appointment-${appointment.id}-advisor-name`">
77-
{{ advisor.name }}
78-
</span>
79-
<span v-if="advisor.title" :id="`appointment-${appointment.id}-advisor-role`">
80-
- {{ advisor.title }}
81-
</span>
82-
<span v-if="appointment.legacySource" class="font-italic text-medium-emphasis">
83-
(appointment imported from {{ appointment.legacySource }})
84-
</span>
85-
</div>
86-
<div v-if="size(get(advisor, 'departments'))" class="text-medium-emphasis">
87-
<span v-for="(dept, index) in advisor.departments" :key="dept.deptCode">
88-
<span :id="`appointment-${appointment.id}-advisor-dept-${index}`">{{ dept.deptName }}</span>
89-
</span>
90-
</div>
9169
<div
9270
v-if="appointment.appointmentType"
9371
:id="`appointment-${appointment.id}-type`"
@@ -138,21 +116,14 @@
138116
</div>
139117
</div>
140118
</section>
141-
<AdvisingNoteComments
142-
v-if="['Calendly', 'YCBM'].includes(appointment.createdBy)"
143-
class="border-t-sm py-4"
144-
:class="{'sr-only': !isOpen}"
145-
:note="appointment"
146-
/>
147-
</article>
119+
</div>
148120
</template>
149121

150122
<script setup>
151123
import {computed, onMounted, ref, watch} from 'vue'
152124
import {get, size} from 'lodash'
153125
import {mdiCommentOutline, mdiPaperclip} from '@mdi/js'
154126
import AppointmentCanceledIndicator from '@/components/appointment/AppointmentCanceledIndicator'
155-
import AdvisingNoteComments from '@/components/note/comment/AdvisingNoteComments'
156127
import {getCalnetProfileByCsid, getCalnetProfileByUid} from '@/api/user'
157128
import PillItem from '@/components/util/PillItem'
158129
import {pluralize} from '@/lib/utils'
@@ -168,6 +139,10 @@ const props = defineProps({
168139
required: true,
169140
type: Boolean
170141
},
142+
onClickOpen: {
143+
required: true,
144+
type: Function
145+
},
171146
student: {
172147
required: true,
173148
type: Object

src/components/note/AdvisingNote.vue

Lines changed: 27 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
<template>
2-
<article :id="`note-${note.id}-outer`" class="advising-note-outer w-100">
2+
<div :id="`note-${note.id}-outer`" class="advising-note-outer w-100">
33
<div
4-
:id="`note-${note.id}-is-closed`"
5-
aria-level="3"
4+
:id="`${note.eForm ? 'eForm' : 'note'}-${note.id}-is-closed`"
5+
:aria-controls="isOpen ? undefined : `note-${note.id}-is-open`"
6+
:aria-expanded="isOpen ? undefined : false"
67
class="d-flex w-100"
78
:class="{
89
'font-size-18': !note.peerAdvisingDepartmentId,
9-
'note-snippet-when-closed': !isOpen
10+
'cursor-pointer note-snippet-when-closed': !isOpen
1011
}"
11-
role="heading"
12+
:role="isOpen ? undefined : 'button'"
13+
:tabindex="isOpen ? undefined : 0"
14+
@click="onClickOpen"
15+
@keyup.enter="onClickOpen"
1216
>
1317
<div v-if="note.isDraft" :id="`note-${note.id}-is-draft`" class="d-flex align-center">
1418
<v-badge
@@ -55,7 +59,7 @@
5559
</div>
5660
<section
5761
:id="`note-${note.id}-is-open`"
58-
class="note-body pb-4"
62+
class="note-body"
5963
:class="{'sr-only': !isOpen}"
6064
>
6165
<div v-if="(note.subject || note.isDraft) && note.message" class="open-note-message-container py-3">
@@ -64,69 +68,16 @@
6468
<div v-if="!note.subject && !note.message && note.eForm" class="py-3">
6569
<AdvisingEForm :note="note" />
6670
</div>
67-
<div v-if="isAuthorDetailsLoaded && !isNil(author) && !author.name && !author.email && !note.eForm" class="font-size-14 py-3 text-medium-emphasis">
68-
Advisor profile not found
69-
<span v-if="note.legacySource" class="font-italic">
70-
(note imported from {{ note.legacySource }})
71-
</span>
72-
</div>
73-
<div v-if="isAuthorDetailsLoaded && author && !note.eForm" class="py-3">
74-
<div v-if="author.name || author.email">
75-
<span class="sr-only">Note created by </span>
76-
<span v-if="author.uid && author.name">
77-
<router-link
78-
v-if="currentUser.isAdmin && note.peerAdvisingDepartmentId"
79-
:id="`note-${note.id}-link-to-peer-advisor-home`"
80-
:to="`/peer_advisor/${author.uid}/home`"
81-
>
82-
{{ author.name }}
83-
</router-link>
84-
<a
85-
v-if="!currentUser.isAdmin || !note.peerAdvisingDepartmentId"
86-
:id="`note-${note.id}-author-name`"
87-
:aria-label="`${author.name} UC Berkeley Directory page (opens in new tab)`"
88-
:href="`https://www.berkeley.edu/directory/results?search-term=${author.name}`"
89-
target="_blank"
90-
>
91-
{{ author.name }}
92-
</a>
93-
</span>
94-
<span v-if="!author.uid && author.name" :id="`note-${note.id}-author-name`">
95-
{{ author.name }}
96-
</span>
97-
<span v-if="!author.uid && !author.name && author.email" :id="`note-${note.id}-author-email`">
98-
{{ author.email }}
99-
</span>
100-
<span v-if="author.role || author.title">
101-
- <span :id="`note-${note.id}-author-role`">{{ capitalizeAllWords(replace(author.role || author.title, '_', ' ')) }}</span>
102-
</span>
103-
<span v-if="note.legacySource" class="font-italic text-medium-emphasis">
104-
(note imported from {{ note.legacySource }})
105-
</span>
106-
</div>
107-
<div v-if="note.peerAdvisingDepartmentId">
108-
<span :id="`note-${note.id}-peer-advising-department`">{{ peerAdvisingDepartment.name }}</span>
109-
<div
110-
v-if="peerAdvisingDepartment.deptName !== peerAdvisingDepartment.name"
111-
:id="`note-${note.id}-university-department-of-peer-advisor`"
112-
class="text-medium-emphasis"
113-
>
114-
{{ peerAdvisingDepartment.deptName }}
115-
</div>
116-
</div>
117-
<div v-if="!note.peerAdvisingDepartmentId" class="text-medium-emphasis">
118-
<div v-for="(deptName, index) in authorDepartments" :key="index">
119-
<span :id="`note-${note.id}-author-dept-${index}`">{{ deptName }}</span>
120-
</div>
121-
</div>
122-
</div>
123-
<div v-if="note.topics && size(note.topics)" class="mt-5">
124-
<AdvisingNoteTopics
125-
label-class="text-medium-emphasis"
126-
:note="note"
127-
read-only
128-
/>
71+
<div v-if="!note.eForm && note.legacySource" class="font-italic text-medium-emphasis">
72+
(note imported from {{ note.legacySource }})
12973
</div>
74+
<AdvisingNoteTopics
75+
v-if="note.topics && size(note.topics)"
76+
class="mt-5"
77+
label-class="text-medium-emphasis"
78+
:note="note"
79+
read-only
80+
/>
13081
<div v-if="note.contactType" class="mt-5">
13182
<div class="font-size-16 font-weight-bold text-medium-emphasis">Contact Type</div>
13283
<div :id="`note-${note.id}-contact-type`">{{ note.contactType }}</div>
@@ -146,12 +97,6 @@
14697
/>
14798
</div>
14899
</section>
149-
<AdvisingNoteComments
150-
v-if="!note.legacySource || note.eForm"
151-
class="border-t-sm py-4"
152-
:class="{'sr-only': !isOpen}"
153-
:note="note"
154-
/>
155100
<AreYouSureModal
156101
v-model="showConfirmDeleteAttachment"
157102
button-label-confirm="Delete"
@@ -161,23 +106,20 @@
161106
>
162107
Are you sure you want to delete the <strong>'{{ attachmentToDelete.displayName }}'</strong> attachment?
163108
</AreYouSureModal>
164-
</article>
109+
</div>
165110
</template>
166111

167112
<script setup>
168-
import {computed, onMounted, ref, watch} from 'vue'
169-
import {get, isNil, map, orderBy, replace, size} from 'lodash'
113+
import {computed, ref} from 'vue'
114+
import {size} from 'lodash'
170115
import {mdiCommentOutline, mdiPaperclip} from '@mdi/js'
171116
import AdvisingEForm from '@/components/note/eform/AdvisingEForm'
172117
import AdvisingNoteAttachments from '@/components/note/AdvisingNoteAttachments'
173-
import AdvisingNoteComments from '@/components/note/comment/AdvisingNoteComments'
174118
import AdvisingNoteTopics from '@/components/note/AdvisingNoteTopics'
175119
import AreYouSureModal from '@/components/util/AreYouSureModal'
176120
import {addAttachments, removeAttachment} from '@/api/notes'
177-
import {alertScreenReader, capitalizeAllWords, oxfordJoin, pluralize} from '@/lib/utils'
121+
import {alertScreenReader, pluralize} from '@/lib/utils'
178122
import {canUserEditNote, summarizeNoteForAcademicTimeline} from '@/lib/note.js'
179-
import {findPeerAdvisingDepartment, getBoaUserRoles} from '@/lib/berkeley-department'
180-
import {getCalnetProfileByCsid, getCalnetProfileByUid} from '@/api/user'
181123
import {useContextStore} from '@/stores/context'
182124
import {useNoteStore} from '@/stores/note-edit-session'
183125
@@ -197,6 +139,10 @@ const props = defineProps({
197139
note: {
198140
required: true,
199141
type: Object
142+
},
143+
onClickOpen: {
144+
required: true,
145+
type: Function
200146
}
201147
})
202148
@@ -205,28 +151,16 @@ const noteStore = useNoteStore()
205151
206152
const addAttachmentInputElementId = `note-${props.note.id}-choose-file-for-note-attachment`
207153
const attachmentToDelete = ref()
208-
const author = ref(get(props.note, 'author'))
209-
const authorDepartments = computed(() => orderBy(map(author.value.departments, 'deptName')))
210154
const currentUser = contextStore.currentUser
211-
const isAuthorDetailsLoaded = ref(false)
212155
const isUpdatingAttachments = ref(false)
213156
const noteSummary = computed(() => {
214157
const note = props.note
215158
const showNoteMessage = props.isOpen && !note.subject && !note.peerAdvisingDepartmentId && size(note.message)
216159
return showNoteMessage ? note.message : summarizeNoteForAcademicTimeline(note, !props.isOpen)
217160
})
218-
const peerAdvisingDepartment = computed(() => props.note.peerAdvisingDepartmentId ? findPeerAdvisingDepartment(props.note.peerAdvisingDepartmentId) : undefined)
219161
const showConfirmDeleteAttachment = ref(false)
220162
const showNoteAttachmentsWidget = computed(() => (!props.note.legacySource && canUserEditNote(props.note, currentUser)) || size(props.note.attachments))
221163
222-
watch(() => props.isOpen, () => {
223-
loadAuthorDetails()
224-
})
225-
226-
onMounted(() => {
227-
loadAuthorDetails()
228-
})
229-
230164
const addNoteAttachments = attachments => {
231165
return new Promise(resolve => {
232166
isUpdatingAttachments.value = true
@@ -256,45 +190,6 @@ const confirmedRemoveAttachment = () => {
256190
}
257191
}
258192
259-
const loadAuthorDetails = () => {
260-
const requiresLazyLoad = (
261-
props.isOpen &&
262-
(
263-
!get(props.note, 'author.name') ||
264-
!get(props.note, 'author.role') ||
265-
get(author.value, 'uid') !== get(props.note, 'author.uid') ||
266-
get(author.value, 'sid') !== get(props.note, 'author.sid')
267-
)
268-
)
269-
if (requiresLazyLoad) {
270-
const hasIdentifier = get(props.note, 'author.uid') || get(props.note, 'author.sid')
271-
if (hasIdentifier) {
272-
const author_uid = props.note.author.uid
273-
const callback = data => {
274-
author.value = data
275-
author.value.role = author.value.role || author.value.title
276-
if (!author.value.role && author.value.departments.length) {
277-
author.value.role = oxfordJoin(getBoaUserRoles(author.value.departments[0]))
278-
}
279-
}
280-
if (author_uid) {
281-
if (author_uid === currentUser.uid) {
282-
callback(currentUser)
283-
isAuthorDetailsLoaded.value = true
284-
} else {
285-
getCalnetProfileByUid(author_uid).then(callback).finally(() => isAuthorDetailsLoaded.value = true)
286-
}
287-
} else if (props.note.author.sid) {
288-
getCalnetProfileByCsid(props.note.author.sid).then(callback).finally(() => isAuthorDetailsLoaded.value = true)
289-
}
290-
} else {
291-
isAuthorDetailsLoaded.value = true
292-
}
293-
} else {
294-
isAuthorDetailsLoaded.value = true
295-
}
296-
}
297-
298193
const removeAttachmentByIndex = index => {
299194
attachmentToDelete.value = props.note.attachments[index]
300195
showConfirmDeleteAttachment.value = true

0 commit comments

Comments
 (0)