Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
34 changes: 25 additions & 9 deletions packages/data-context/src/actions/ProjectActions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { MutationAddProjectArgs, MutationAppCreateConfigFileArgs, SpecType } from '@packages/graphql/src/gen/nxs.gen'
import type { FindSpecs, FoundBrowser, FoundSpec, FullConfig, LaunchArgs, LaunchOpts, OpenProjectLaunchOptions } from '@packages/types'
import path from 'path'
import type { Maybe } from '../data/coreDataShape'
import type { Maybe, ProjectShape } from '../data/coreDataShape'

import type { DataContext } from '..'

Expand All @@ -16,6 +16,7 @@ export interface ProjectApiShape {
initializeProject(args: LaunchArgs, options: OpenProjectLaunchOptions, browsers: FoundBrowser[]): Promise<unknown>
launchProject(browser: FoundBrowser, spec: Cypress.Spec, options: LaunchOpts): void
insertProjectToCache(projectRoot: string): void
removeProjectFromCache(projectRoot: string): void
getProjectRootsFromCache(): Promise<string[]>
clearLatestProjectsCache(): Promise<unknown>
}
Expand All @@ -33,6 +34,14 @@ export class ProjectActions {
return
}

private get projects () {
return this.ctx.coreData.app.projects
}

private set projects (projects: ProjectShape[]) {
this.ctx.coreData.app.projects = projects
}

async setActiveProject (projectRoot: string) {
this.ctx.coreData.app.activeProject = {
projectRoot,
Expand Down Expand Up @@ -66,14 +75,14 @@ export class ProjectActions {
}

async loadProjects () {
const projectRoots = await this.ctx._apis.projectApi.getProjectRootsFromCache()
const projectRoots = await this.api.getProjectRootsFromCache()

this.ctx.coreData.app.projects = [
...this.ctx?.coreData?.app?.projects,
this.projects = [
...this.projects,
...projectRoots.map((projectRoot) => ({ projectRoot })),
]

return this.ctx.coreData.app.projects
return this.projects
}

async initializeActiveProject () {
Expand Down Expand Up @@ -107,10 +116,10 @@ export class ProjectActions {
throw new Error(`Cannot add ${args.path} as a project, it is not a directory`)
}

const found = this.ctx.projectsList.find((x) => x.projectRoot === args.path)
const found = this.projects.find((x) => x.projectRoot === args.path)

if (!found) {
this.ctx.coreData.app.projects.push({ projectRoot: args.path })
this.projects.push({ projectRoot: args.path })
this.api.insertProjectToCache(args.path)
}

Expand All @@ -136,8 +145,15 @@ export class ProjectActions {
return this.api.launchProject(browser, spec, {})
}

removeProject () {
//
removeProject (projectRoot: string) {
const found = this.ctx.projectsList.find((x) => x.projectRoot === projectRoot)

if (!found) {
throw new Error(`Cannot remove ${projectRoot}, it is not a known project`)
}

this.projects = this.projects.filter((project) => project.projectRoot !== projectRoot)
this.api.removeProjectFromCache(projectRoot)
}

syncProjects () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ export const stubMutation: MaybeResolver<Mutation> = {

return {}
},
removeProject (source, args, ctx) {
ctx.app.projects = ctx.app.projects.filter((p) => p.projectRoot !== args.path)

return ctx.app
},
}
3 changes: 3 additions & 0 deletions packages/graphql/schemas/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ type Mutation {
"""Set the current navigation item"""
navigationMenuSetItem(type: NavItem!): NavigationMenu

"""Remove project from projects array and cache"""
removeProject(path: String!): App!

"""Set active project to run tests on"""
setActiveProject(path: String!): App!

Expand Down
13 changes: 13 additions & 0 deletions packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,19 @@ export const mutation = mutationType({
},
})

t.nonNull.field('removeProject', {
type: 'App',
description: 'Remove project from projects array and cache',
args: {
path: nonNull(stringArg()),
},
async resolve (_root, args, ctx) {
await ctx.actions.project.removeProject(args.path)

return ctx.appData
},
})

t.nonNull.field('setActiveProject', {
type: 'App',
description: 'Set active project to run tests on',
Expand Down
21 changes: 19 additions & 2 deletions packages/launchpad/src/global/GlobalPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
v-for="project in filteredProjects"
:key="project.id"
:gql="project"
@removeProject="handleRemoveProject"
/>
</div>
</template>
Expand All @@ -28,13 +29,13 @@
</template>

<script setup lang="ts">
import { computed, ref, Ref } from 'vue'
import { computed, ref } from 'vue'
import { gql, useMutation } from '@urql/vue'
import WelcomeGuide from './WelcomeGuide.vue'
import GlobalProjectCard from './GlobalProjectCard.vue'
import GlobalPageHeader from './GlobalPageHeader.vue'
import GlobalEmpty from './GlobalEmpty.vue'
import { GlobalPageFragment, GlobalPage_AddProjectDocument } from '../generated/graphql'
import { GlobalPageFragment, GlobalPage_AddProjectDocument, GlobalPage_RemoveProjectDocument } from '../generated/graphql'

gql`
mutation GlobalPage_addProject($path: String!, $open: Boolean = true) {
Expand All @@ -59,12 +60,28 @@ fragment GlobalPage on App {
}
`

gql`
mutation GlobalPage_RemoveProject($path: String!) {
removeProject(path: $path) {
projects {
id
}
}
}
`

const addProject = useMutation(GlobalPage_AddProjectDocument)

function handleAddProject (path: string) {
addProject.executeMutation({ path })
}

const removeProject = useMutation(GlobalPage_RemoveProjectDocument)

function handleRemoveProject (path: string) {
removeProject.executeMutation({ path })
}

const props = defineProps<{
gql: GlobalPageFragment,
}>()
Expand Down
14 changes: 12 additions & 2 deletions packages/launchpad/src/global/GlobalProjectCard.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@ import GlobalProjectCard from './GlobalProjectCard.vue'
import { GlobalProjectCardFragmentDoc } from '../generated/graphql-test'

describe('<GlobalProjectCard />', () => {
it('renders', () => {
beforeEach(() => {
const removeProjectSpy = cy.spy().as('removeProjectSpy')

cy.mountFragment(GlobalProjectCardFragmentDoc, {
render: (gqlValue) => (
<div class="p-12 overflow-auto resize-x max-w-600px">
<GlobalProjectCard gql={gqlValue} />
<GlobalProjectCard gql={gqlValue} onRemoveProject={removeProjectSpy} />
</div>
),
})
})

it('renders', () => {
cy.findByText('Some Test Title').should('be.visible')
cy.findByText('/usr/local/dev/projects/some-test-title').should('be.visible')
})

it('emits removeProject event on click', () => {
cy.get('[data-testid=removeProjectButton]')
.click()
.get('@removeProjectSpy').should('have.been.called')
})
})
14 changes: 14 additions & 0 deletions packages/launchpad/src/global/GlobalProjectCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,24 @@
</p>
</button>
</div>
<button
class="h-10"
data-testid="removeProjectButton"
@click="$emit('removeProject', props.gql.projectRoot)"
>
<Icon
icon="ant-design:close-circle-outlined"
width="1.5em"
height="1.5em"
class="text-gray-600"
/>
</button>
</div>
</template>

<script setup lang="ts">
import { gql, useMutation } from '@urql/vue'
import { Icon } from '@iconify/vue'
import { GlobalProjectCardFragment, GlobalProjectCard_SetActiveProjectDocument } from '../generated/graphql'

gql`
Expand Down Expand Up @@ -60,6 +73,7 @@ const props = defineProps<{

const emit = defineEmits<{
(event: 'projectSelected', project: GlobalProjectCardFragment): void
(event: 'removeProject', path: string): void
}>()
</script>

Expand Down
5 changes: 4 additions & 1 deletion packages/server/lib/gui/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { openProject } from '../open_project'
import specsUtil from '../util/specs'

import { setDataContext, startGraphQLServer } from '@packages/graphql/src/server'
import { getProjectRoots, insertProject, removeLatestProjects } from '@packages/server/lib/cache'
import { getProjectRoots, insertProject, removeLatestProjects, removeProject } from '@packages/server/lib/cache'
import { checkAuthQuery } from '@packages/graphql/src/stitching/remoteGraphQLCalls'
import type { FindSpecs, FoundBrowser, LaunchArgs, LaunchOpts, OpenProjectLaunchOptions } from '@packages/types'
import type { EventEmitter } from 'events'
Expand Down Expand Up @@ -534,6 +534,9 @@ module.exports = {
insertProjectToCache (projectRoot: string) {
insertProject(projectRoot)
},
removeProjectFromCache (projectRoot: string) {
removeProject(projectRoot)
},
getProjectRootsFromCache () {
return getProjectRoots()
},
Expand Down