Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update navbar UI per Figma #19926

Merged
merged 8 commits into from
Jan 28, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 33 additions & 37 deletions packages/app/cypress/e2e/sidebar_navigation.cy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { Interception } from '@packages/net-stubbing/lib/external-types'

describe('Sidebar Navigation', () => {
context('as e2e testing type', () => {
beforeEach(() => {
Expand Down Expand Up @@ -75,10 +73,6 @@ describe('Sidebar Navigation', () => {
cy.percySnapshot()
cy.get('[data-cy="sidebar-header"]').trigger('mouseout')

cy.get('[data-cy="switch-testing-type"]').realHover()
cy.contains('#tooltip-target > div', 'E2E Testing')
cy.get('[data-cy="switch-testing-type"]').trigger('mouseout')

cy.get('[data-e2e-href="/runs"]').realHover()
cy.contains('#tooltip-target > div', 'Runs')
cy.get('[data-e2e-href="/runs"]').trigger('mouseout')
Expand Down Expand Up @@ -107,26 +101,38 @@ describe('Sidebar Navigation', () => {
cy.findAllByText('todos').eq(1).should('be.visible')
})

it('displays the project name (expanded state)', () => {
it('displays the project name and opens a modal to switch testing type', () => {
cy.findByLabelText('Sidebar').closest('[aria-expanded]').should('have.attr', 'aria-expanded', 'true')

cy.findAllByText('todos').eq(1).should('be.visible')
})

it('has menu item labeled by current active testing type that opens a modal to switch testing type (expanded state)', () => {
cy.findByLabelText('Sidebar').closest('[aria-expanded]').should('have.attr', 'aria-expanded', 'true')
cy.get('[data-cy="sidebar-header"]').within(() => {
cy.get('[data-cy="testing-type-e2e"]').should('be.visible')
cy.findByText('todos').should('be.visible')
}).click()

cy.findByText('E2E Testing').should('be.visible')
cy.get('[data-cy="switch-testing-type"]').click()
cy.findByText('Choose a testing type').should('be.visible')

cy.get('[data-cy-testingtype=e2e]').within(() => {
cy.contains('Configured')
})

cy.intercept('mutation-SwitchTestingType_ReconfigureProject').as('SwitchTestingType')
cy.get('[data-cy-testingtype="component"]').click()
cy.wait('@SwitchTestingType').then((interception: Interception) => {
expect(interception.request.url).to.include('graphql/mutation-SwitchTestingType_ReconfigureProject')
cy.get('[data-cy-testingtype="component"]').within(() => {
cy.contains('Not Configured')
}).click()

cy.wait('@SwitchTestingType').then((interception) => {
expect(interception.request.body.variables.testingType).eq('component')
})

cy.get('[aria-label="Close"]').click()
cy.findByText('Choose a testing type').should('not.exist')

cy.findByLabelText('toggle navigation', {
selector: 'button',
}).click()

cy.get('[data-cy="sidebar-header"]').click()
cy.findByText('Choose a testing type').should('be.visible')
})

it('has unlabeled menu item that shows the keyboard shortcuts modal (expanded state)', () => {
Expand Down Expand Up @@ -175,20 +181,6 @@ describe('Sidebar Navigation', () => {
cy.get('[data-cy="app-header-bar"]').findByText('Settings').should('be.visible')
cy.get('.router-link-active').findByText('Settings').should('be.visible')
})

it('shows if testing type is configured when clicking switch testing type', () => {
cy.openProject('pristine-with-e2e-testing')

cy.findByText('E2E Testing').should('be.visible')
cy.get('[data-cy="switch-testing-type"]').click()
cy.get('[data-cy-testingtype=e2e]').within(() => {
cy.contains('Configured')
})

cy.get('[data-cy-testingtype=component]').within(() => {
cy.contains('Not Configured')
})
})
})

context('as component testing type', () => {
Expand All @@ -198,15 +190,19 @@ describe('Sidebar Navigation', () => {
cy.startAppServer('component')
cy.visitApp()

cy.findByText('Component Testing').should('be.visible')
cy.get('[data-cy="switch-testing-type"]').click()
cy.get('[data-cy-testingtype=e2e]').within(() => {
cy.contains('Not Configured')
})

cy.get('[data-cy="sidebar-header"]').within(() => cy.get('[data-cy="testing-type-component"]')).click()
cy.get('[data-cy-testingtype=component]').within(() => {
cy.contains('Configured')
})

cy.intercept('mutation-SwitchTestingType_ReconfigureProject').as('SwitchTestingType')
cy.get('[data-cy-testingtype="e2e"]').within(() => {
cy.contains('Not Configured')
}).click()

cy.wait('@SwitchTestingType').then((interception) => {
expect(interception.request.body.variables.testingType).eq('e2e')
})
})
})
})
6 changes: 1 addition & 5 deletions packages/app/src/navigation/SidebarNavigation.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,13 @@ describe('SidebarNavigation', () => {
cy.contains('#tooltip-target > div', 'test-project').should('be.visible')
cy.get('[data-cy="sidebar-header"]').trigger('mouseout')

cy.get('[data-cy="switch-testing-type"]').realHover()
cy.contains('#tooltip-target > div', 'E2E Testing').should('be.visible')
cy.get('[data-cy="switch-testing-type"]').trigger('mouseout')

cy.get('[data-e2e-href="/runs"]').realHover()
cy.contains('#tooltip-target > div', 'Runs').should('be.visible')
cy.get('[data-e2e-href="/runs"]').trigger('mouseout')
})

it('opens a modal to switch testing type', { viewportWidth: 1280 }, () => {
mountComponent()
cy.get('[data-cy="switch-testing-type"]').click()
cy.get('[data-cy="sidebar-header"]').click()
})
})
50 changes: 6 additions & 44 deletions packages/app/src/navigation/SidebarNavigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,45 +20,14 @@
</div>
</button>
<div class="flex flex-col flex-1 overflow-y-auto ">
<SidebarTooltip
class="border-b flex border-gray-900 flex-shrink-0 h-64px items-center"
:disabled="mainStore.navBarExpanded"
:popper-top-offset="4"
popper-class="h-56px"
data-cy="sidebar-header"
>
<i-cy-bookmark_x24
class="flex-shrink-0
h-24px
mx-20px
w-24px
icon-dark-gray-200 icon-light-gray-900"
/>
<div class="text-gray-50 text-size-16px leading-24px truncate">
{{ currentProject?.title ?? 'Cypress' }}
<p class="text-gray-600 text-size-14px leading-20px truncate">
{{ currentProject?.branch }}
</p>
</div>

<template #popper>
<div class="text-left text-gray-50 text-size-16px leading-16px truncate">
{{ currentProject?.title ?? 'Cypress' }}
<p class="text-gray-600 text-size-14px leading-20px truncate">
{{ currentProject?.branch }}
</p>
</div>
</template>
</SidebarTooltip>

<SidebarNavigationHeader
v-if="query.data.value"
:gql="query.data.value"
/>
<nav
class="space-y-1 bg-gray-1000 flex-1"
aria-label="Sidebar"
>
<SwitchTestingTypeButton
v-if="query.data.value"
:gql="query.data.value"
/>
<RouterLink
v-for="item in navigation"
v-slot="{ isActive }"
Expand Down Expand Up @@ -108,7 +77,6 @@
import { computed, ref } from 'vue'
import { gql, useQuery } from '@urql/vue'
import SidebarNavigationRow from './SidebarNavigationRow.vue'
import SwitchTestingTypeButton from './SwitchTestingTypeButton.vue'
import KeyboardBindingsModal from './KeyboardBindingsModal.vue'
import CodeIcon from '~icons/cy/code-editor_x24'
import RunsIcon from '~icons/cy/runs_x24'
Expand All @@ -120,6 +88,7 @@ import { SideBarNavigationDocument } from '../generated/graphql'
import CypressLogo from '@packages/frontend-shared/src/assets/logos/cypress_s.png'
import { useI18n } from '@cy/i18n'
import { useRoute } from 'vue-router'
import SidebarNavigationHeader from './SidebarNavigationHeader.vue'

const { t } = useI18n()

Expand All @@ -131,19 +100,12 @@ const navigation = [

gql`
query SideBarNavigation {
...SwitchTestingTypeButton
currentProject {
id
title
branch
}
...SidebarNavigationHeader
}
`

const query = useQuery({ query: SideBarNavigationDocument, requestPolicy: 'network-only' })

const currentProject = computed(() => query.data.value?.currentProject)

const bindingsOpen = ref(false)

const mainStore = useMainStore()
Expand Down
93 changes: 93 additions & 0 deletions packages/app/src/navigation/SidebarNavigationHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<template>
<SidebarTooltip
v-if="testingType"
class="border-b cursor-pointer flex border-gray-900 flex-shrink-0 h-64px pl-20px transition-all duration-300 items-center hover:bg-gray-900"
:disabled="mainStore.navBarExpanded"
:popper-top-offset="4"
popper-class="h-56px"
data-cy="sidebar-header"
tabindex="0"
@click="showModal = true"
@keydown.enter="showModal = true"
>
<SwitchTestingTypeModal
:show="showModal"
:gql="props.gql"
@close="showModal = false"
/>
<component
:is="testingType.icon"
class="
flex-shrink-0 h-24px
mr-20px w-24px
icon-dark-jade-600 icon-light-jade-300
children:transition
children:duration-300"
/>
<div class="text-gray-50 text-size-16px leading-24px truncate">
{{ props.gql.currentProject?.title ?? 'Cypress' }}
<p class="text-gray-600 text-size-14px leading-20px truncate">
{{ props.gql.currentProject?.branch }}
</p>
</div>

<template #popper>
<div class="text-left text-gray-50 text-size-16px leading-16px truncate">
{{ props.gql.currentProject?.title ?? 'Cypress' }}
<p class="text-gray-600 text-size-14px leading-20px truncate">
{{ props.gql.currentProject?.branch }}
</p>
</div>
</template>
</SidebarTooltip>
</template>

<script lang="ts" setup>
import { computed, ref } from 'vue'
import { gql } from '@urql/vue'
import type { SidebarNavigationHeaderFragment } from '../generated/graphql'
import { useMainStore } from '../store'
import SidebarTooltip from './SidebarTooltip.vue'
import SwitchTestingTypeModal from './SwitchTestingTypeModal.vue'
import IconE2E from '~icons/cy/testing-type-e2e-solid-simple'
import IconComponent from '~icons/cy/testing-type-component-solid_x64'
import { useI18n } from '@cy/i18n'

const { t } = useI18n()

gql`
fragment SidebarNavigationHeader on Query {
...SwitchTestingTypeModal
currentProject {
id
currentTestingType
title
branch
}
}
`

const showModal = ref(false)

const props = defineProps<{
gql: SidebarNavigationHeaderFragment
}>()

const TESTING_TYPE_MAP = {
e2e: {
name: t(`testingType.e2e.name`),
icon: IconE2E,
},
component: {
name: t(`testingType.component.name`),
icon: IconComponent,
},
} as const

const testingType = computed(() => {
return props.gql.currentProject?.currentTestingType ? TESTING_TYPE_MAP[props.gql.currentProject.currentTestingType] : null
})

const mainStore = useMainStore()

</script>
37 changes: 12 additions & 25 deletions packages/app/src/navigation/SidebarNavigationRow.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,31 @@
<template>
<SidebarTooltip
:class="active
? 'before:bg-jade-300 before:scale-x-100 before:transition-colors'
: 'before:scale-x-0 before:transition-transform'"
class="w-full
? 'before:(bg-indigo-300 scale-x-100 transition-colors) cursor-default'
: 'before:(scale-x-0 transition-transform bg-gray-300)'"
class="rounded-md
flex
h-40px
my-16px
w-full
min-w-40px
relative
flex
items-center
rounded-md
group
h-40px
my-16px
focus-visible:outline-none
before:content-open-square
before:mr-4px
before:rounded-r-md
before:text-transparent
before:h-40px
before:w-4px
before:bg-indigo-300
before:transform before:origin-left
before:duration-300
hover:before:scale-x-100
hover:before:bg-indigo-300
focus:before:bg-indigo-300"
before:(rounded-r-md h-40px mr-4px text-transparent transform origin-left w-4px duration-300 content-open-square) hover:before:scale-x-100 "
:disabled="mainStore.navBarExpanded"
>
<component
:is="
icon"
:class="active ? 'icon-dark-jade-300 icon-light-jade-800' : 'icon-dark-gray-500 icon-light-gray-900'"
class="w-24px h-24px flex-shrink-0 m-12px
group-hover:icon-dark-indigo-300 group-hover:icon-light-indigo-600
group-focus:icon-dark-indigo-300 group-focus:icon-light-indigo-600
:class="active ? 'icon-dark-indigo-300 icon-light-indigo-700' : 'icon-dark-gray-500 icon-light-gray-900 group-hover:(icon-dark-gray-300 icon-light-gray-800) group-focus:(icon-dark-gray-300 icon-light-gray-800)'"
class="flex-shrink-0 h-24px m-12px w-24px
children:transition children:duration-300"
/>
<span
:class="[active ? 'text-jade-300' : 'text-gray-500']"
class="ml-8px truncate group-hocus:text-indigo-300 transition-colors duration-300"
:class="[active ? 'text-indigo-300' : 'text-gray-500 group-hocus:text-gray-300']"
class="ml-8px transition-colors duration-300 truncate"
>
{{ name }}
</span>
Expand Down
Loading