Skip to content

Commit

Permalink
Feature: Desktop-View - Fix avatar button styling when out of office …
Browse files Browse the repository at this point in the history
…is active
  • Loading branch information
Benjamin Scharf committed May 13, 2024
1 parent f877aab commit 5873d1b
Show file tree
Hide file tree
Showing 31 changed files with 225 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ withDefaults(defineProps<Props>(), {
</script>

<template>
<!-- eslint-disable vuejs-accessibility/no-static-element-interactions-->
<header
class="group/heading flex cursor-default justify-between px-0 text-base font-normal leading-5 text-stone-200 active:text-stone-200 dark:text-neutral-500 dark:active:text-neutral-500"
:class="{ 'cursor-pointer': collapsible }"
@click="collapsible && $emit('toggle-collapsed', title)"
@keydown.enter="collapsible && $emit('toggle-collapsed', title)"
>
<slot name="title">
<h4 class="grow text-base ltr:mr-auto rtl:ml-auto">
Expand All @@ -36,7 +39,7 @@ withDefaults(defineProps<Props>(), {
group="heading"
class="mt-0.5 rtl:order-1"
orientation="vertical"
@click.stop="collapsible && $emit('toggle-collapsed', title)"
@keydown.enter="collapsible && $emit('toggle-collapsed', title)"
/>
</header>
</template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export const OrganizationMembersFragmentDoc = gql`
lastname
fullname
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
active
vip
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ fragment organizationMembers on Organization {
lastname
fullname
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
active
vip
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ beforeEach(() => {
mockOnlineNotificationSeenGql()
})

vi.hoisted(() => {
vi.setSystemTime(new Date('2024-11-11T00:00:00Z'))
})

describe('static organization', () => {
it('shows organization', async () => {
mockPermissions(['admin.organization'])
Expand Down Expand Up @@ -146,6 +150,8 @@ describe('static organization', () => {
internalId: 300,
vip: true,
outOfOffice: false,
outOfOfficeStartAt: null,
outOfOfficeEndAt: null,
firstname: 'Jane',
lastname: 'Hunter',
fullname: 'Jane Hunter',
Expand All @@ -161,6 +167,8 @@ describe('static organization', () => {
internalId: 400,
vip: true,
outOfOffice: true,
outOfOfficeStartAt: '2024-11-10',
outOfOfficeEndAt: '2024-11-20',
firstname: 'Max',
lastname: 'Mustermann',
fullname: 'Max Mustermann',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export const SearchDocument = gql`
image
active
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
vip
organization {
id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ query search(
image
active
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
vip
organization {
id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ describe('user avatars', () => {
type: 'user',
image: 'avatar.png',
outOfOffice: false,
outOfOfficeStartAt: null,
outOfOfficeEndAt: null,
vip: false,
active: false,
})
Expand All @@ -222,7 +224,10 @@ describe('user avatars', () => {
it('renders article user when he is out of office', async () => {
const articles = defaultArticles()
const { author } = articles.description!.edges[0].node

author.outOfOffice = true
author.outOfOfficeStartAt = '2021-12-01'
author.outOfOfficeEndAt = '2022-02-01'
author.active = true
author.vip = true
author.firstname = 'Max'
Expand All @@ -240,6 +245,8 @@ describe('user avatars', () => {
).toBeAvatarElement({
type: 'user',
outOfOffice: true,
outOfOfficeStartAt: '2021-12-01',
outOfOfficeEndAt: '2022-02-01',
vip: true,
active: true,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ describe('static organization', () => {
lastname: 'Hunter',
fullname: 'Jane Hunter',
outOfOffice: false,
outOfOfficeStartAt: null,
outOfOfficeEndAt: null,
active: true,
image: null,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ describe('visiting ticket user page', () => {
email: 'some-email@mail.com',
web: 'https://some-web.com',
vip: true,
outOfOffice: false,
outOfOfficeStartAt: null,
outOfOfficeEndAt: null,
phone: '80542243532',
mobile: '2432332143',
fax: 'fax.fax',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export const TicketLiveUserAttributesFragmentDoc = gql`
email
vip
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
active
image
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ fragment ticketLiveUserAttributes on TicketLiveUser {
email
vip
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
active
image
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export const TicketArticleAttributesFragmentDoc = gql`
image
vip
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
authorizations {
provider
uid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ fragment ticketArticleAttributes on TicketArticle {
image
vip
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
authorizations {
provider
uid
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export const TicketAttributesFragmentDoc = gql`
vip
active
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
email
organization {
id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ fragment ticketAttributes on Ticket {
vip
active
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
email
organization {
id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export const TicketMentionFragmentDoc = gql`
fullname
vip
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
active
image
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ fragment ticketMention on Mention {
fullname
vip
outOfOffice
outOfOfficeStartAt
outOfOfficeEndAt
active
image
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ describe('visiting user page', () => {
email: 'some-email@mail.com',
web: 'https://some-web.com',
vip: true,
outOfOffice: false,
outOfOfficeStartAt: null,
outOfOfficeEndAt: null,
phone: '80542243532',
mobile: '2432332143',
fax: 'fax.fax',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
import { getIdFromGraphQLId } from '#shared/graphql/utils.ts'
import { getUserAvatarClasses } from '#shared/initializer/initializeUserAvatarClasses.ts'
import { useReactiveNow } from '#shared/composables/useReactiveNow.ts'
import { useDateFormat } from '@vueuse/shared'
import CommonAvatar from '../CommonAvatar/CommonAvatar.vue'
import type { AvatarSize } from '../CommonAvatar/index.ts'
import type { AvatarUser } from './types.ts'
Expand Down Expand Up @@ -84,10 +86,27 @@ const isVip = computed(() => {
return !props.personal && props.entity.vip
})
const currentDate = useReactiveNow()
const isOutOfOffice = computed(() => {
if (
props.entity.outOfOffice &&
props.entity.outOfOfficeStartAt &&
props.entity.outOfOfficeEndAt
) {
const today = useDateFormat(currentDate.value, 'YYYY-MM-DD')
const startDate = props.entity?.outOfOfficeStartAt
const endDate = props.entity?.outOfOfficeEndAt
return startDate <= today.value && endDate >= today.value // Today is between start and end date
}
return false
})
const className = computed(() => {
const classes = [colorClass.value]
if (props.entity.outOfOffice) {
if (isOutOfOffice.value) {
classes.push('opacity-100 grayscale-[70%]')
} else if (props.entity.active === false) {
classes.push('opacity-20 grayscale')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import { SYSTEM_USER_ID } from '#shared/utils/constants.ts'
import { initializeUserAvatarClasses } from '#shared/initializer/initializeUserAvatarClasses.ts'
import { renderComponent } from '#tests/support/components/index.ts'

import { useDateFormat } from '@vueuse/shared'
import CommonUserAvatar, { type Props } from '../CommonUserAvatar.vue'

const USER_ID = convertToGraphQLId('User', '123')

vi.hoisted(() => {
vi.setSystemTime(new Date('2024-11-11T00:00:00Z'))
})

initializeUserAvatarClasses({
backgroundColors: [
'bg-gray',
Expand Down Expand Up @@ -101,7 +106,7 @@ describe('CommonUserAvatar', () => {
expect(view.queryByIconName('some-unknown-source')).not.toBeInTheDocument()
})

it('renders active and outOfOffice', async () => {
it('renders active', async () => {
const view = renderComponent(CommonUserAvatar, {
props: <Props>{
entity: {
Expand All @@ -120,17 +125,6 @@ describe('CommonUserAvatar', () => {
entity: {
id: USER_ID,
active: false,
outOfOffice: true,
},
})

expect(avatar).toHaveClass('grayscale-[70%]')

await view.rerender(<Props>{
entity: {
id: USER_ID,
active: false,
outOfOffice: false,
},
})

Expand Down Expand Up @@ -182,4 +176,87 @@ describe('CommonUserAvatar', () => {
'background-image: url(/api/users/image/100.png)',
)
})

describe('out of office state', () => {
let today: string
beforeAll(() => {
today = useDateFormat(new Date(), 'YYYY-MM-DD').value
})

it('out of office date is in presentence', async () => {
const view = renderComponent(CommonUserAvatar, {
props: <Props>{
entity: {
id: USER_ID,
active: true,
},
},
})

await view.rerender(<Props>{
entity: {
id: USER_ID,
outOfOffice: true,
outOfOfficeStartAt: '2024-10-11',
outOfOfficeEndAt: '2024-12-11',
},
})

const avatar = view.getByTestId('common-avatar')

expect(avatar).toHaveClass('grayscale-[70%]')
})

it('out of office date is in past', async () => {
const view = renderComponent(CommonUserAvatar, {
props: <Props>{
entity: {
id: USER_ID,
active: true,
},
},
})

const [year, month, day] = today.split('-')
const outOfOfficeStartAt = `${year}-${(+month - 2).toString().padStart(2, '0')}-${day}`
const outOfOfficeEndAt = `${year}-${(+month - 1).toString().padStart(2, '0')}-${day}`

await view.rerender(<Props>{
entity: {
id: USER_ID,
outOfOffice: true,
outOfOfficeStartAt,
outOfOfficeEndAt,
},
})

const avatar = view.getByTestId('common-avatar')

expect(avatar).not.toHaveClass('grayscale-[70%]')
})

it('out of office date is in future', async () => {
const view = renderComponent(CommonUserAvatar, {
props: <Props>{
entity: {
id: USER_ID,
active: true,
},
},
})

await view.rerender(<Props>{
entity: {
id: USER_ID,
outOfOffice: true,
outOfOfficeStartAt: '2024-12-11',
outOfOfficeEndAt: '2025-01-11',
},
})

const avatar = view.getByTestId('common-avatar')

expect(avatar).not.toHaveClass('grayscale-[70%]')
})
})
})
2 changes: 2 additions & 0 deletions app/frontend/shared/components/CommonUserAvatar/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export interface AvatarUser {
mobile?: Maybe<string>
vip?: Maybe<boolean>
outOfOffice?: Maybe<boolean>
outOfOfficeEndAt?: Maybe<string>
outOfOfficeStartAt?: Maybe<string>
active?: Maybe<boolean>
image?: Maybe<string>
id: string
Expand Down

0 comments on commit 5873d1b

Please sign in to comment.