From 5c05ed2a862d931755e639bd2bb07e362c6d4b67 Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Tue, 14 Jun 2022 20:27:20 +0200 Subject: [PATCH] Add components and mutations for snapshot updating and deleting Also modify the tests for MS-373 and MS-375 --- .../frontend/modules/snapshots.spec.js | 50 +++++++++-- client/src/App.vue | 2 + .../components/modules/SnapshotListItem.vue | 90 ++++++++++++++++--- .../src/components/profile/EditNameWizard.vue | 6 +- .../snapshots/EditSnapshotTitleWizard.vue | 46 ++++++++++ .../gql/mutations/snapshots/delete.gql | 13 +++ .../gql/mutations/snapshots/update.gql | 13 +++ client/src/pages/me/myTeam.vue | 1 + 8 files changed, 200 insertions(+), 21 deletions(-) create mode 100644 client/src/components/snapshots/EditSnapshotTitleWizard.vue create mode 100644 client/src/graphql/gql/mutations/snapshots/delete.gql create mode 100644 client/src/graphql/gql/mutations/snapshots/update.gql diff --git a/client/cypress/integration/frontend/modules/snapshots.spec.js b/client/cypress/integration/frontend/modules/snapshots.spec.js index 479ecf98..da66ca67 100644 --- a/client/cypress/integration/frontend/modules/snapshots.spec.js +++ b/client/cypress/integration/frontend/modules/snapshots.spec.js @@ -1,5 +1,35 @@ import module from '../../../fixtures/module.minimal'; import {getMinimalMe} from '../../../support/helpers'; +import {hasOperationName} from '../../../support/graphql'; + +const mockUpdateSnapshot = (title) => { + cy.intercept('POST', '/api/graphql', (req) => { + if (hasOperationName(req, 'UpdateSnapshot')) { + let snapshot; + if (title) { + snapshot = { + __typename: 'SnapshotNode', + id: 'U25hcHNob3ROb2RlOjQ=', + title, + }; + } else { + snapshot = { + __typename: 'NotOwner', + reason: 'Not the owner' + }; + } + req.reply({ + data: { + updateSnapshot: { + snapshot, + }, + }, + }); + } + }); + +}; + describe('Snapshot', () => { const operations = isTeacher => ({ @@ -25,8 +55,8 @@ describe('Snapshot', () => { ...module, snapshots: [ { - id: 'snapshot-id', - title: 'title', + id: 'U25hcHNob3ROb2RlOjQ=', + title: 'Old Title', created: '2020-01-01', mine: true, shared: false, @@ -90,17 +120,21 @@ describe('Snapshot', () => { }); it('Renames Snapshot', () => { + cy.mockGraphqlOps(operations(true)); + const newTitle = 'New Title'; + mockUpdateSnapshot(newTitle); cy.visit('module/miteinander-reden/snapshots'); - cy.getByDataCy('snapshot-title').should('equal', 'Old Title'); + cy.getByDataCy('snapshot-link').should('have.text', 'Old Title'); cy.getByDataCy('rename-snapshot-button').click(); - cy.getByDataCy('snapshot-title-input').type('New Title'); - cy.getByDataCy('save-button').click(); - cy.getByDataCy('snapshot-title').should('equal', 'New Title'); + cy.getByDataCy('edit-name-input').clear().type(newTitle); + cy.getByDataCy('modal-save-button').click(); + cy.getByDataCy('snapshot-link').should('have.text', 'New Title'); }); - it('Renames Snapshot', () => { + it('Deletes Snapshot', () => { + cy.mockGraphqlOps(operations(true)); cy.visit('module/miteinander-reden/snapshots'); - cy.getByDataCy('snapshot').should('have.length', 1); + cy.getByDataCy('snapshot-entry').should('have.length', 1); cy.getByDataCy('delete-snapshot-button').click(); cy.getByDataCy('confirm-button').click(); cy.getByDataCy('snapshot').should('have.length', 0); diff --git a/client/src/App.vue b/client/src/App.vue index 9dcdbda5..cd1dfe2b 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -36,6 +36,7 @@ const EditNoteWizard = () => import(/* webpackChunkName: "content-forms" */'@/components/notes/EditNoteWizard'); const EditClassNameWizard = () => import(/* webpackChunkName: "content-forms" */'@/components/school-class/EditClassNameWizard'); const EditTeamNameWizard = () => import(/* webpackChunkName: "content-forms" */'@/components/profile/EditTeamNameWizard'); + const EditSnapshotTitleWizard = () => import(/* webpackChunkName: "content-forms" */'@/components/snapshots/EditSnapshotTitleWizard'); const DefaultLayout = () => import(/* webpackChunkName: "layouts" */'@/layouts/DefaultLayout'); const SimpleLayout = () => import(/* webpackChunkName: "layouts" */'@/layouts/SimpleLayout'); const FullScreenLayout = () => import(/* webpackChunkName: "layouts" */'@/layouts/FullScreenLayout'); @@ -66,6 +67,7 @@ EditNoteWizard, EditClassNameWizard, EditTeamNameWizard, + EditSnapshotTitleWizard, ...modals }, diff --git a/client/src/components/modules/SnapshotListItem.vue b/client/src/components/modules/SnapshotListItem.vue index aa76c87a..25830075 100644 --- a/client/src/components/modules/SnapshotListItem.vue +++ b/client/src/components/modules/SnapshotListItem.vue @@ -1,6 +1,9 @@ @@ -26,7 +45,12 @@ import dateformat from '@/helpers/date-format'; import {SNAPSHOT_DETAIL} from '@/router/module.names'; import SHARE_SNAPSHOT_MUTATION from 'gql/mutations/snapshots/share.gql'; + import UPDATE_SNAPSHOT_MUTATION from 'gql/mutations/snapshots/update.gql'; + import DELETE_SNAPSHOT_MUTATION from 'gql/mutations/snapshots/delete.gql'; + import SNAPSHOTS_QUERY from 'gql/queries/moduleSnapshots.gql'; import gql from 'graphql-tag'; + import PenIcon from '@/components/icons/PenIcon'; + import TrashIcon from '@/components/icons/TrashIcon'; export default { props: { @@ -35,6 +59,10 @@ default: () => ({}), }, }, + components: { + PenIcon, + TrashIcon, + }, computed: { meta() { @@ -55,6 +83,35 @@ }, methods: { + changeTitle() { + this.$modal.open('edit-snapshot-title-wizard', {name: this.snapshot.title}) + .then((title) => { + console.log(title); + this.$apollo.mutate({ + mutation: UPDATE_SNAPSHOT_MUTATION, + variables: { + input: { + id: this.snapshot.id, + title: title, + }, + }, + update(store, {data: {updateSnapshot: {snapshot}}}) { + if (snapshot.__typename === 'SnapshotNode') { + const {id, title} = snapshot; + store.writeFragment({ + id, + fragment: gql`fragment SnapshotFragment on SnapshotNode {title}`, + data: { + title, + __typename: 'SnapshotNode', + }, + }); + } + }, + }); + }) + .catch(); + }, share() { this.$apollo.mutate({ mutation: SHARE_SNAPSHOT_MUTATION, @@ -70,10 +127,10 @@ fragment: gql`fragment SnapshotFragment on SnapshotNode { shared }`, data: { shared, - __typename: 'SnapshotNode' - } + __typename: 'SnapshotNode', + }, }); - } + }, }); }, }, @@ -100,6 +157,15 @@ &__link { @include default-link; color: $color-brand; + } + + &__icon { + @include default-icon; + } + + &__actions { + display: flex; + align-items: center; margin-left: auto; } } diff --git a/client/src/components/profile/EditNameWizard.vue b/client/src/components/profile/EditNameWizard.vue index de691aab..879c87a1 100644 --- a/client/src/components/profile/EditNameWizard.vue +++ b/client/src/components/profile/EditNameWizard.vue @@ -9,7 +9,7 @@ @@ -43,6 +43,10 @@ type: String, default: '', }, + placeholder: { + type: String, + default: 'Namen bearbeiten' + } }, components: { Modal, diff --git a/client/src/components/snapshots/EditSnapshotTitleWizard.vue b/client/src/components/snapshots/EditSnapshotTitleWizard.vue new file mode 100644 index 00000000..03eb6034 --- /dev/null +++ b/client/src/components/snapshots/EditSnapshotTitleWizard.vue @@ -0,0 +1,46 @@ + + + + + diff --git a/client/src/graphql/gql/mutations/snapshots/delete.gql b/client/src/graphql/gql/mutations/snapshots/delete.gql new file mode 100644 index 00000000..12e80df3 --- /dev/null +++ b/client/src/graphql/gql/mutations/snapshots/delete.gql @@ -0,0 +1,13 @@ +mutation DeleteSnapshot($input: DeleteSnapshotInput!) { + deleteSnapshot(input: $input) { + result { + __typename + ...on NotOwner { + reason + } + ...on Success { + message + } + } + } +} diff --git a/client/src/graphql/gql/mutations/snapshots/update.gql b/client/src/graphql/gql/mutations/snapshots/update.gql new file mode 100644 index 00000000..1736fb2a --- /dev/null +++ b/client/src/graphql/gql/mutations/snapshots/update.gql @@ -0,0 +1,13 @@ +mutation UpdateSnapshot($input: UpdateSnapshotInput!) { + updateSnapshot(input: $input) { + snapshot { + ...on SnapshotNode { + title + id + } + ...on NotOwner { + reason + } + } + } +} diff --git a/client/src/pages/me/myTeam.vue b/client/src/pages/me/myTeam.vue index 8c3aa711..d8377042 100644 --- a/client/src/pages/me/myTeam.vue +++ b/client/src/pages/me/myTeam.vue @@ -71,6 +71,7 @@ methods: { editTeamName() { + // todo: use this.$modal this.$store.dispatch('editTeamName'); }, leaveTeam() {