From ad1bd1266056622a3ba550fd27fa570ea75eee33 Mon Sep 17 00:00:00 2001 From: Hazem Krimi Date: Sun, 30 May 2021 02:34:09 +0100 Subject: [PATCH] Add template creation page --- src/pages/AddTemplate/index.tsx | 824 ++++++++++++++++++++++++++++++++ src/pages/AddTemplate/styles.ts | 5 + 2 files changed, 829 insertions(+) create mode 100644 src/pages/AddTemplate/index.tsx create mode 100644 src/pages/AddTemplate/styles.ts diff --git a/src/pages/AddTemplate/index.tsx b/src/pages/AddTemplate/index.tsx new file mode 100644 index 0000000..8a9a6d7 --- /dev/null +++ b/src/pages/AddTemplate/index.tsx @@ -0,0 +1,824 @@ +import * as Yup from 'yup'; +import { useFormik } from 'formik'; +import { Redirect, useHistory } from 'react-router'; +import { + useLazyQuery, + useMutation, + useQuery, + useReactiveVar, +} from '@apollo/client'; +import React, { useState } from 'react'; +import { roleVar } from '../../graphql/state'; +import { + Box, + Button, + Text, + SectionSelector, + Input, + Alert, + TextArea, + Select, + Spinner, + FeatureCard, +} from '../../components'; +import { Wrapper } from './styles'; +import { ArrowLeft, General, Specification, Features } from '../../assets'; +import { + AddTemplateMutation, + AddTemplateMutationVariables, + FeatureOutput, + GetAllCategoriesQuery, + GetAllCategoriesQueryVariables, + GetAllFeaturesQuery, + GetAllFeaturesQueryVariables, + TemplateInput, +} from '../../graphql/types'; +import { ADD_TEMPLATE } from '../../graphql/template.api'; +import { GET_ALL_CATEGORIES } from '../../graphql/category.api'; +import { GET_ALL_FEATURES } from '../../graphql/feature.api'; + +const AddTemplate = () => { + const history = useHistory(); + const role = useReactiveVar(roleVar); + const [newTemplate, setNewTemplate] = useState({ + name: '', + description: '', + image: { + name: '', + src: '', + }, + category: '', + specification: { + introduction: { + purpose: '', + documentConventions: '', + intendedAudience: '', + projectScope: '', + }, + overallDescription: { + perspective: '', + userCharacteristics: '', + operatingEnvironment: '', + designImplementationConstraints: '', + userDocumentation: '', + assemptionsDependencies: '', + }, + nonFunctionalRequirements: { + performanceRequirements: '', + safetyRequirements: '', + securityRequirements: '', + softwareQualityAttributes: '', + }, + otherRequirements: '', + glossary: '', + analysisModels: '', + issuesList: '', + }, + features: [], + }); + + const [availableFeatures, setAvailableFeatures] = useState< + Array + >(); + + const [selectedSection, setSelectedSection] = useState< + 'general' | 'specification' | 'features' + >('general'); + const [error, setError] = useState(''); + + const { data: categories, loading: categoriesLoading } = useQuery< + GetAllCategoriesQuery, + GetAllCategoriesQueryVariables + >(GET_ALL_CATEGORIES, { + fetchPolicy: 'network-only', + }); + + const [getFeatures, { loading: featuresLoading }] = useLazyQuery< + GetAllFeaturesQuery, + GetAllFeaturesQueryVariables + >(GET_ALL_FEATURES, { + onCompleted({ getAllFeatures }) { + setAvailableFeatures(getAllFeatures); + }, + fetchPolicy: 'network-only', + }); + + const [addTemplate, { loading }] = useMutation< + AddTemplateMutation, + AddTemplateMutationVariables + >(ADD_TEMPLATE, { + onCompleted({ addTemplate: { id } }) { + history.push(`/template/${id}`); + }, + onError({ graphQLErrors }) { + setError(graphQLErrors[0]?.extensions?.info); + setTimeout(() => setError(''), 3000); + }, + }); + + const generalForm = useFormik({ + initialValues: { + name: '', + description: '', + imageName: '', + imageSource: '', + category: '', + }, + validationSchema: Yup.object().shape({ + name: Yup.string().required('Name is required'), + description: Yup.string().required('Description is required'), + imageName: Yup.string().required('Image is required'), + imageSource: Yup.string().required('Image is required'), + category: Yup.string().required('Category is required'), + }), + onSubmit: ({ name, description, category, imageName, imageSource }) => { + setNewTemplate({ + name, + description, + image: { name: imageName, src: imageSource }, + category, + }); + setSelectedSection('specification'); + }, + }); + + const specificationForm = useFormik({ + initialValues: { + purpose: '', + documentConventions: '', + intendedAudience: '', + projectScope: '', + perspective: '', + userCharacteristics: '', + operatingEnvironment: '', + designImplementationConstraints: '', + userDocumentation: '', + assemptionsDependencies: '', + performanceRequirements: '', + safetyRequirements: '', + securityRequirements: '', + softwareQualityAttributes: '', + otherRequirements: '', + glossary: '', + analysisModels: '', + issuesList: '', + }, + validationSchema: Yup.object().shape({ + purpose: Yup.string().required('Purpose is required'), + documentConventions: Yup.string().required( + 'Document conventions is required' + ), + intendedAudience: Yup.string().required('Intented audience is required'), + projectScope: Yup.string().required('Project scope is required'), + perspective: Yup.string().required('Perspective is required'), + userCharacteristics: Yup.string().required( + 'User characteristics is required' + ), + operatingEnvironment: Yup.string().required( + 'Operating environment is required' + ), + designImplementationConstraints: Yup.string().required( + 'Design and implementation constraints is required' + ), + userDocumentation: Yup.string().required( + 'User documentation is required' + ), + assemptionsDependencies: Yup.string().required( + 'Assumptions and dependencies is required' + ), + performanceRequirements: Yup.string().required( + 'Performance requirements is required' + ), + safetyRequirements: Yup.string().required( + 'Safety requirements is required' + ), + securityRequirements: Yup.string().required( + 'Security requirements is required' + ), + softwareQualityAttributes: Yup.string().required( + 'Software quality attributes is required' + ), + otherRequirements: Yup.string().required( + 'Other requirements is required' + ), + glossary: Yup.string().required('Glossary is required'), + analysisModels: Yup.string().required('Analysis models is required'), + issuesList: Yup.string().required('Issues list is required'), + }), + onSubmit: ({ + purpose, + documentConventions, + intendedAudience, + projectScope, + perspective, + userCharacteristics, + operatingEnvironment, + designImplementationConstraints, + userDocumentation, + assemptionsDependencies, + performanceRequirements, + safetyRequirements, + securityRequirements, + softwareQualityAttributes, + otherRequirements, + glossary, + analysisModels, + issuesList, + }) => { + setNewTemplate({ + ...newTemplate, + specification: { + introduction: { + purpose, + documentConventions, + intendedAudience, + projectScope, + }, + overallDescription: { + perspective, + userCharacteristics, + operatingEnvironment, + designImplementationConstraints, + userDocumentation, + assemptionsDependencies, + }, + nonFunctionalRequirements: { + performanceRequirements, + safetyRequirements, + securityRequirements, + softwareQualityAttributes, + }, + otherRequirements, + glossary, + analysisModels, + issuesList, + }, + }); + setSelectedSection('features'); + getFeatures(); + }, + }); + + const featuresForm = useFormik<{ features: Array }>({ + initialValues: { + features: [], + }, + onSubmit: ({ features }) => { + addTemplate({ variables: { template: { ...newTemplate, features } } }); + }, + }); + + return role === 'productOwner' ? ( + + +