From 2e748b206e341b38c3c1b711be0f7bbd7ea8c1b1 Mon Sep 17 00:00:00 2001 From: Zach Smith Date: Mon, 7 Jun 2021 16:13:05 +0200 Subject: [PATCH] Improved layout of project searched items, started implementing search header, implemented edit route (not editing yet), implemented gql mutation for deleting projects (no deleting yet) --- .../mutations/delete-project/index.js | 9 ++ .../index.js} | 0 .../resolvers/queries/projects/build-query.js | 2 +- .../src/graphql/resolvers/types/mutation.js | 4 +- .../src/graphql/schema/type-defs/main.graphql | 1 + src/api/src/mssql/setup-db/sql/schema.sql | 14 ++- .../src/layout/header/appbar/breadcrumbs.jsx | 4 + src/client/src/layout/routes/index.jsx | 13 ++ src/client/src/pages/edit-project/index.jsx | 114 ++++++++++++++++++ src/client/src/pages/projects/context.jsx | 47 +------- .../pages/projects/header/_download-data.jsx | 16 +++ ...le-side-menu.jsx => _mobile-side-menu.jsx} | 18 +-- .../pages/projects/header/_submit-project.jsx | 19 +++ .../src/pages/projects/header/index.jsx | 24 ++-- .../src/pages/projects/results/index.jsx | 16 +-- .../projects/results/result-card/_delete.jsx | 25 ++++ .../results/result-card/_description.jsx | 10 ++ .../results/result-card/_download.jsx | 10 ++ .../projects/results/result-card/_edit.jsx | 18 +++ .../projects/results/result-card/_title.jsx | 26 ++++ .../projects/results/result-card/_view.jsx | 18 +++ .../projects/results/result-card/index.jsx | 26 ++++ 22 files changed, 356 insertions(+), 78 deletions(-) create mode 100644 src/api/src/graphql/resolvers/mutations/delete-project/index.js rename src/api/src/graphql/resolvers/mutations/{update-project.js => update-project/index.js} (100%) create mode 100644 src/client/src/pages/edit-project/index.jsx create mode 100644 src/client/src/pages/projects/header/_download-data.jsx rename src/client/src/pages/projects/header/{mobile-side-menu.jsx => _mobile-side-menu.jsx} (62%) create mode 100644 src/client/src/pages/projects/header/_submit-project.jsx create mode 100644 src/client/src/pages/projects/results/result-card/_delete.jsx create mode 100644 src/client/src/pages/projects/results/result-card/_description.jsx create mode 100644 src/client/src/pages/projects/results/result-card/_download.jsx create mode 100644 src/client/src/pages/projects/results/result-card/_edit.jsx create mode 100644 src/client/src/pages/projects/results/result-card/_title.jsx create mode 100644 src/client/src/pages/projects/results/result-card/_view.jsx create mode 100644 src/client/src/pages/projects/results/result-card/index.jsx diff --git a/src/api/src/graphql/resolvers/mutations/delete-project/index.js b/src/api/src/graphql/resolvers/mutations/delete-project/index.js new file mode 100644 index 0000000..d7aa70f --- /dev/null +++ b/src/api/src/graphql/resolvers/mutations/delete-project/index.js @@ -0,0 +1,9 @@ +/** + * Set project and all child entities to have deletedAt = new Date()... etc. + * return the project + */ + +// eslint-disable-next-line +export default async (_, args, ctx) => { + throw new Error('TODO') +} diff --git a/src/api/src/graphql/resolvers/mutations/update-project.js b/src/api/src/graphql/resolvers/mutations/update-project/index.js similarity index 100% rename from src/api/src/graphql/resolvers/mutations/update-project.js rename to src/api/src/graphql/resolvers/mutations/update-project/index.js diff --git a/src/api/src/graphql/resolvers/queries/projects/build-query.js b/src/api/src/graphql/resolvers/queries/projects/build-query.js index 46ab35d..adb8c4e 100644 --- a/src/api/src/graphql/resolvers/queries/projects/build-query.js +++ b/src/api/src/graphql/resolvers/queries/projects/build-query.js @@ -84,7 +84,7 @@ export default ({ fields, table, ids, vocabularyFilters }) => { }) .join('\n')} - where + where [${table}].deletedAt is null and ${ids.length ? `[${table}].id in (${ids.join(',')})` : '1 = 1'} ${vocabularyFilters.length ? 'and ' : ''} ${vocabularyFilters diff --git a/src/api/src/graphql/resolvers/types/mutation.js b/src/api/src/graphql/resolvers/types/mutation.js index 2d227ef..3c00343 100644 --- a/src/api/src/graphql/resolvers/types/mutation.js +++ b/src/api/src/graphql/resolvers/types/mutation.js @@ -1,5 +1,6 @@ import createProject from '../mutations/create-project/index.js' -import updateProject from '../mutations/update-project.js' +import updateProject from '../mutations/update-project/index.js' +import deleteProject from '../mutations/delete-project/index.js' import updateVocabulary from '../mutations/update-vocabulary/index.js' import integrateOldDb from '../mutations/integrate-old-db/index.js' @@ -8,4 +9,5 @@ export default { updateProject, updateVocabulary, integrateOldDb, + deleteProject, } diff --git a/src/api/src/graphql/schema/type-defs/main.graphql b/src/api/src/graphql/schema/type-defs/main.graphql index 2f1221c..0df9c6c 100644 --- a/src/api/src/graphql/schema/type-defs/main.graphql +++ b/src/api/src/graphql/schema/type-defs/main.graphql @@ -88,4 +88,5 @@ type Mutation { mitigationForms: [MitigationInput!] adaptationForms: [AdaptationInput!] ): Project! + deleteProject(id: ID!): Project } diff --git a/src/api/src/mssql/setup-db/sql/schema.sql b/src/api/src/mssql/setup-db/sql/schema.sql index 5913de4..bc18bd3 100644 --- a/src/api/src/mssql/setup-db/sql/schema.sql +++ b/src/api/src/mssql/setup-db/sql/schema.sql @@ -186,6 +186,7 @@ create table Projects ( alternativeContact nvarchar(255), alternativeContactEmail nvarchar(255), leadAgent nvarchar(255), + deletedAt date, interventionType int foreign key references VocabularyXrefTree (id), projectStatus int foreign key references VocabularyXrefTree (id), validationStatus int foreign key references VocabularyXrefTree (id), @@ -195,7 +196,7 @@ create table Projects ( hostSubSector int foreign key references VocabularyXrefTree (id), province int foreign key references VocabularyXrefTree (id), districtMunicipality int foreign key references VocabularyXrefTree (id), - localMunicipality int foreign key references VocabularyXrefTree (id) + localMunicipality int foreign key references VocabularyXrefTree (id) ); end @@ -228,6 +229,7 @@ create table Mitigations ( researchTargetAudience nvarchar(255), researchAuthor nvarchar(255), researchPaper nvarchar(255), + deletedAt date, energyOrEmissionsData int foreign key references VocabularyXrefTree (id), mitigationType int foreign key references VocabularyXrefTree (id), mitigationSubType int foreign key references VocabularyXrefTree (id), @@ -256,7 +258,8 @@ create table EnergyData ( year int not null, annualKwh int not null default 0, annualKwhPurchaseReduction int not null default 0, - notes nvarchar(4000) null + notes nvarchar(4000) null, + deletedAt date ); end @@ -274,7 +277,8 @@ create table EmissionsData ( mitigationId int not null foreign key references Mitigations (id), emissionType int not null foreign key references VocabularyXrefTree (id), year int not null, - notes nvarchar(4000) null + notes nvarchar(4000) null, + deletedAt date ); end @@ -291,7 +295,8 @@ create table EmissionsDataXrefVocabTreeX ( id int not null identity primary key, emissionsDataId int not null foreign key references EmissionsData (id), chemical int not null foreign key references VocabularyXrefTree (id), - tonnesPerYear int not null + tonnesPerYear int not null, + deletedAt date ); end @@ -318,6 +323,7 @@ create table Adaptations ( researchTargetAudience nvarchar(255), researchAuthor nvarchar(255), researchPaper nvarchar(255), + deletedAt date, interventionStatus int foreign key references VocabularyXrefTree (id), adaptationSector int foreign key references VocabularyXrefTree (id), adaptationPurpose int foreign key references VocabularyXrefTree (id), diff --git a/src/client/src/layout/header/appbar/breadcrumbs.jsx b/src/client/src/layout/header/appbar/breadcrumbs.jsx index 11bba69..cce0850 100644 --- a/src/client/src/layout/header/appbar/breadcrumbs.jsx +++ b/src/client/src/layout/header/appbar/breadcrumbs.jsx @@ -4,6 +4,7 @@ import Breadcrumbs from '@material-ui/core/Breadcrumbs' import { Link, useLocation } from 'react-router-dom' import MuiLink from '@material-ui/core/Link' import navItems from './nav-items' +import EditIcon from 'mdi-react/EditIcon' const useStyles = makeStyles(theme => ({ link: { @@ -41,6 +42,9 @@ export default function IconBreadcrumbs() { })} {tree.slice(-1).map(({ label, Icon } = {}) => { + if (label === 'Edit') { + Icon = EditIcon + } return ( {Icon && } diff --git a/src/client/src/layout/routes/index.jsx b/src/client/src/layout/routes/index.jsx index b07bbff..83d157f 100644 --- a/src/client/src/layout/routes/index.jsx +++ b/src/client/src/layout/routes/index.jsx @@ -6,6 +6,7 @@ const HomePage = lazy(() => import('../../pages/home')) const AccessPage = lazy(() => import('../../pages/access')) const ProjectsPage = lazy(() => import('../../pages/projects')) const ProjectPage = lazy(() => import('../../pages/project')) +const EditProjectPage = lazy(() => import('../../pages/edit-project')) const SubmitProjectPage = lazy(() => import('../../pages/submit-project')) const DeploymentsPage = lazy(() => import('../../pages/deployments')) @@ -60,6 +61,18 @@ export default withRouter(() => { )} /> + {/* EDIT PROJECT */} + ( + + + + )} + /> + {/* PROJECT */} { + const theme = useTheme() + const { error, loading, data } = useQuery( + gql` + query projects($ids: [Int!]) { + projects(ids: $ids) { + id + title + description + projectManager + link + startDate + endDate + validationComments + fundingOrganisation + fundingPartner + budgetLower + budgetUpper + hostOrganisation + hostPartner + alternativeContact + alternativeContactEmail + leadAgent + interventionType + projectStatus + validationStatus + fundingStatus + estimatedBudget + hostSector + hostSubSector + province + districtMunicipality + localMunicipality + mitigations { + id + title + description + carbonCredit + volMethodology + goldStandard + vcs + yx + otherCarbonCreditStandard + otherCarbonCreditStandardDescription + cdmProjectNumber + cdmStatus + isResearch + researchDescription + energyOrEmissionsData + energyData + emissionsData + researchType + researchTargetAudience + researchAuthor + researchPaper + mitigationType + mitigationSubType + interventionStatus + cdmMethodology + cdmExecutiveStatus + hostSector + hostSubSectorPrimary + hostSubSectorSecondary + } + adaptations { + id + title + description + startDate + endDate + yx + isResearch + interventionStatus + researchDescription + researchType + researchTargetAudience + researchAuthor + researchPaper + adaptationSector + adaptationPurpose + hazardFamily + hazardSubFamily + hazard + subHazard + } + } + } + `, + { variables: { ids: [parseInt(id, 10)] } } + ) + + if (loading) { + return + } + + if (error) { + throw error + } + + return ( + + +

Edit page

+
{JSON.stringify(data, null, 2)}
+
+
+ ) +} diff --git a/src/client/src/pages/projects/context.jsx b/src/client/src/pages/projects/context.jsx index 3bf3d2c..39de8df 100644 --- a/src/client/src/pages/projects/context.jsx +++ b/src/client/src/pages/projects/context.jsx @@ -56,20 +56,6 @@ export default ({ children }) => { id title description - projectManager - link - startDate - endDate - validationComments - fundingOrganisation - fundingPartner - budgetLower - budgetUpper - hostOrganisation - hostPartner - alternativeContact - alternativeContactEmail - leadAgent interventionType projectStatus validationStatus @@ -82,26 +68,6 @@ export default ({ children }) => { localMunicipality mitigations { id - title - description - carbonCredit - volMethodology - goldStandard - vcs - yx - otherCarbonCreditStandard - otherCarbonCreditStandardDescription - cdmProjectNumber - cdmStatus - isResearch - researchDescription - energyOrEmissionsData - energyData - emissionsData - researchType - researchTargetAudience - researchAuthor - researchPaper mitigationType mitigationSubType interventionStatus @@ -113,20 +79,9 @@ export default ({ children }) => { } adaptations { id - title - description - startDate - endDate - yx - isResearch - interventionStatus - researchDescription - researchType - researchTargetAudience - researchAuthor - researchPaper adaptationSector adaptationPurpose + interventionStatus hazardFamily hazardSubFamily hazard diff --git a/src/client/src/pages/projects/header/_download-data.jsx b/src/client/src/pages/projects/header/_download-data.jsx new file mode 100644 index 0000000..32774cb --- /dev/null +++ b/src/client/src/pages/projects/header/_download-data.jsx @@ -0,0 +1,16 @@ +import DownloadIcon from 'mdi-react/DownloadIcon' +import Button from '@material-ui/core/Button' + +export default () => { + return ( + + ) +} diff --git a/src/client/src/pages/projects/header/mobile-side-menu.jsx b/src/client/src/pages/projects/header/_mobile-side-menu.jsx similarity index 62% rename from src/client/src/pages/projects/header/mobile-side-menu.jsx rename to src/client/src/pages/projects/header/_mobile-side-menu.jsx index a29b392..327270e 100644 --- a/src/client/src/pages/projects/header/mobile-side-menu.jsx +++ b/src/client/src/pages/projects/header/_mobile-side-menu.jsx @@ -12,17 +12,21 @@ export default ({ Filters, filters }) => { <> setShowSidebar(true)} onClose={() => setShowSidebar(false)} > - - setShowSidebar(false)}> - - - + + + setShowSidebar(false)}> + + + + + + setShowSidebar(true)} size="small"> diff --git a/src/client/src/pages/projects/header/_submit-project.jsx b/src/client/src/pages/projects/header/_submit-project.jsx new file mode 100644 index 0000000..b2e70c0 --- /dev/null +++ b/src/client/src/pages/projects/header/_submit-project.jsx @@ -0,0 +1,19 @@ +import SubmitIcon from 'mdi-react/DatabasePlusIcon' +import Button from '@material-ui/core/Button' +import { Link } from 'react-router-dom' + +export default () => { + return ( + + ) +} diff --git a/src/client/src/pages/projects/header/index.jsx b/src/client/src/pages/projects/header/index.jsx index ade0c23..a3c884b 100644 --- a/src/client/src/pages/projects/header/index.jsx +++ b/src/client/src/pages/projects/header/index.jsx @@ -2,11 +2,13 @@ import { useContext, cloneElement } from 'react' import AppBar from '@material-ui/core/AppBar' import Toolbar from '@material-ui/core/Toolbar' import useTheme from '@material-ui/core/styles/useTheme' -import MobileSideMenu from './mobile-side-menu' +import MobileSideMenu from './_mobile-side-menu' import Hidden from '@material-ui/core/Hidden' import Typography from '@material-ui/core/Typography' import { context as filterContext } from '../context' import useScrollTrigger from '@material-ui/core/useScrollTrigger' +import SubmitProject from './_submit-project' +import DownloadData from './_download-data' const AnimateVariant = ({ children }) => cloneElement(children, { @@ -23,7 +25,12 @@ export default ({ MobileFilters }) => { const theme = useTheme() return ( - + { transition: 'min-height 300ms cubic-bezier(0.4, 0, 0.2, 1)', }} > + {/* MOBILE FILTERS */} + + +
+ {/* RESULT COUNT */} {projects.length} project{projects.length === 1 ? '' : 's'}
- - {/* MOBILE FILTERS */} - - - + +
+ diff --git a/src/client/src/pages/projects/results/index.jsx b/src/client/src/pages/projects/results/index.jsx index d37dbf6..827e111 100644 --- a/src/client/src/pages/projects/results/index.jsx +++ b/src/client/src/pages/projects/results/index.jsx @@ -1,11 +1,11 @@ import { useContext } from 'react' import { context as filterContext } from '../context' import Card from '@material-ui/core/Card' -import CardHeader from '@material-ui/core/CardHeader' import CardContent from '@material-ui/core/CardContent' import Grid from '@material-ui/core/Grid' import Typography from '@material-ui/core/Typography' import useTheme from '@material-ui/core/styles/useTheme' +import ResultCard from './result-card' export default () => { const { projects } = useContext(filterContext) @@ -23,17 +23,9 @@ export default () => { return ( - {projects.map(({ id }) => ( - - - - - Project details here - - + {projects.map(project => ( + + ))} diff --git a/src/client/src/pages/projects/results/result-card/_delete.jsx b/src/client/src/pages/projects/results/result-card/_delete.jsx new file mode 100644 index 0000000..d87f698 --- /dev/null +++ b/src/client/src/pages/projects/results/result-card/_delete.jsx @@ -0,0 +1,25 @@ +import Button from '@material-ui/core/Button' +import DeleteIcon from 'mdi-react/DeleteIcon' +import { gql, useMutation } from '@apollo/client' + +export default ({ id }) => { + const [deleteProject] = useMutation(gql` + mutation deleteProject($id: ID!) { + deleteProject(id: $id) { + id + } + } + `) + + return ( + + ) +} diff --git a/src/client/src/pages/projects/results/result-card/_description.jsx b/src/client/src/pages/projects/results/result-card/_description.jsx new file mode 100644 index 0000000..dd17847 --- /dev/null +++ b/src/client/src/pages/projects/results/result-card/_description.jsx @@ -0,0 +1,10 @@ +import Typography from '@material-ui/core/Typography' +import CardContent from '@material-ui/core/CardContent' + +export default ({ description }) => { + return ( + + {description || 'No description'} + + ) +} diff --git a/src/client/src/pages/projects/results/result-card/_download.jsx b/src/client/src/pages/projects/results/result-card/_download.jsx new file mode 100644 index 0000000..5d4f97e --- /dev/null +++ b/src/client/src/pages/projects/results/result-card/_download.jsx @@ -0,0 +1,10 @@ +import Button from '@material-ui/core/Button' +import DownloadIcon from 'mdi-react/DownloadIcon' + +export default () => { + return ( + + ) +} diff --git a/src/client/src/pages/projects/results/result-card/_edit.jsx b/src/client/src/pages/projects/results/result-card/_edit.jsx new file mode 100644 index 0000000..69e5f4b --- /dev/null +++ b/src/client/src/pages/projects/results/result-card/_edit.jsx @@ -0,0 +1,18 @@ +import Button from '@material-ui/core/Button' +import EditIcon from 'mdi-react/EditIcon' +import { Link } from 'react-router-dom' + +export default ({ id }) => { + return ( + + ) +} diff --git a/src/client/src/pages/projects/results/result-card/_title.jsx b/src/client/src/pages/projects/results/result-card/_title.jsx new file mode 100644 index 0000000..f05fc9a --- /dev/null +++ b/src/client/src/pages/projects/results/result-card/_title.jsx @@ -0,0 +1,26 @@ +import Avatar from '@material-ui/core/Avatar' +import ProjectIcon from 'mdi-react/FormSelectIcon' +import CardHeader from '@material-ui/core/CardHeader' +import useTheme from '@material-ui/core/styles/useTheme' +import Typography from '@material-ui/core/Typography' + +export default ({ title }) => { + const theme = useTheme() + + return ( + + + + } + title={{title}} + /> + ) +} diff --git a/src/client/src/pages/projects/results/result-card/_view.jsx b/src/client/src/pages/projects/results/result-card/_view.jsx new file mode 100644 index 0000000..55aa074 --- /dev/null +++ b/src/client/src/pages/projects/results/result-card/_view.jsx @@ -0,0 +1,18 @@ +import Button from '@material-ui/core/Button' +import ViewIcon from 'mdi-react/EyeIcon' +import { Link } from 'react-router-dom' + +export default ({ id }) => { + return ( + + ) +} diff --git a/src/client/src/pages/projects/results/result-card/index.jsx b/src/client/src/pages/projects/results/result-card/index.jsx new file mode 100644 index 0000000..1c59dea --- /dev/null +++ b/src/client/src/pages/projects/results/result-card/index.jsx @@ -0,0 +1,26 @@ +import Card from '@material-ui/core/Card' +import CardActions from '@material-ui/core/CardActions' +import useTheme from '@material-ui/core/styles/useTheme' +import Delete from './_delete' +import View from './_view' +import Edit from './_edit' +import Download from './_download' +import Title from './_title' +import Description from './_description' + +export default project => { + const theme = useTheme() + + return ( + + + <Description {...project} /> + <CardActions style={{ display: 'flex', justifyContent: 'flex-end' }}> + <Delete {...project} /> + <View {...project} /> + <Edit {...project} /> + <Download /> + </CardActions> + </Card> + ) +}