Skip to content

Commit

Permalink
feat: SB-863 update crud plop
Browse files Browse the repository at this point in the history
  • Loading branch information
voytek98 committed Mar 3, 2023
1 parent 9271ab2 commit ed5a55d
Show file tree
Hide file tree
Showing 18 changed files with 279 additions and 58 deletions.
12 changes: 12 additions & 0 deletions packages/webapp/plop/crud/actions/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ const componentActions = (name, templatePath, routeName = `{{ camelCase name }}`
},
];

const graphqlActions = (name, templatePath, routeName = `{{ camelCase name }}`) => [
{
type: 'add',
path: `src/routes/${routeName}/${name}/${name}.graphql.ts`,
templateFile: path.join(templatesPath, `${templatePath}/${templatePath}.graphql.hbs`),
},
];

module.exports = [
{
type: 'add',
Expand All @@ -50,6 +58,10 @@ module.exports = [
...componentActions('{{ camelCase name }}Details', 'itemDetails'),
...componentActions('add{{ pascalCase name }}', 'addItem'),
...componentActions('{{ camelCase name }}List', 'itemList'),
...graphqlActions('add{{ pascalCase name }}', 'addItem'),
...graphqlActions('edit{{ pascalCase name }}', 'editItem'),
...graphqlActions('{{ camelCase name }}Details', 'itemDetails'),
...graphqlActions('{{ camelCase name }}List', 'itemList'),
{
type: 'add',
path: `src/routes/{{ camelCase name }}/{{ camelCase name }}List/{{ camelCase name }}ListItem/__tests__/{{ camelCase name }}ListItem.component.spec.tsx`,
Expand Down
2 changes: 1 addition & 1 deletion packages/webapp/plop/crud/actions/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = [
type: 'modify',
path: 'src/app/config/routes.ts',
pattern: /(\/\/<-- INJECT ROUTE DEFINITION -->)/g,
template: `{{ camelCase name }}: nestedPath('/{{ dashCase name }}', {
template: `{{ camelCase name }}: nestedPath('{{ dashCase name }}', {
list: '',
details: ':id',
edit: ':id/edit',
Expand Down
5 changes: 0 additions & 5 deletions packages/webapp/plop/crud/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ module.exports = (plop) => {
name: 'name',
message: 'Name:',
},
{
type: 'input',
name: 'apiUrl',
message: 'API URL:',
},
],
actions: [...moduleActions, ...componentsActions],
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,72 @@
import { useState } from 'react';
import { useMutation } from '@apollo/client';
import { FormattedMessage, useIntl } from 'react-intl';
import { useNavigate } from 'react-router';

import { RoutesConfig } from '../../../app/config/routes';
import { useSnackbar } from '../../../modules/snackbar';
import { BackButton } from '../../../shared/components/backButton';
import { useGenerateLocalePath } from '../../../shared/hooks/';
import {{ pascalCase name }}Form from '../{{ camelCase name }}Form';
import { {{ pascalCase name }}FormFields } from '../{{ camelCase name }}Form/{{ camelCase name }}Form.component';
import { Container } from './add{{ pascalCase name }}.styles';
import { {{ camelCase name }}ListItemFragment } from '../{{ camelCase name }}List/{{ camelCase name }}List.graphql';
import { add{{ pascalCase name }}Mutation } from './add{{ pascalCase name }}.graphql';
import { Container, Header } from './add{{ pascalCase name }}.styles';

export const Add{{ pascalCase name }} = () => {
const [isLoading, setIsLoading] = useState(false);
const generateLocalePath = useGenerateLocalePath();
const { showMessage } = useSnackbar();
const intl = useIntl();
const navigate = useNavigate();

const successMessage = intl.formatMessage({
id: '{{ pascalCase name }} form / Success message',
defaultMessage: '🎉 Changes saved successfully!',
});

const [commit{{ pascalCase name }}FormMutation, { error, loading: loadingMutation }] = useMutation(add{{ pascalCase name }}Mutation, {
update(cache, { data }) {
cache.modify({
fields: {
{{ camelCase name }}List(existingConnection = { edges: [] }) {
const node = data?.create{{ pascalCase name }}?.{{ camelCase name }}Edge?.node;
if (!node) {
return existingConnection;
}
const newItem = {
node: cache.writeFragment({
data: node,
fragment: {{ camelCase name }}ListItemFragment,
}),
__typename: '{{ pascalCase name }}Edge',
};
return { ...existingConnection, edges: [...existingConnection.edges, newItem] };
},
},
});
},
onCompleted: (data) => {
const id = data?.create{{ pascalCase name }}?.{{ camelCase name }}Edge?.node?.id;

showMessage(successMessage);
if (id) navigate(generateLocalePath(RoutesConfig.{{ camelCase name }}.details, { id }));
},
});

const onFormSubmit = (formData: {{ pascalCase name }}FormFields) => {
if (formData) {
// send form
setIsLoading(true);
}
commit{{ pascalCase name }}FormMutation({
variables: {
input: { name: formData.name },
},
});
};

return (
<Container>
<{{ pascalCase name }}Form onSubmit={onFormSubmit} error={undefined} loading={isLoading} />
<BackButton to={generateLocalePath(RoutesConfig.{{ camelCase name }}.list)} />
<Header>
<FormattedMessage defaultMessage="Add CRUD Example Item" id="{{ pascalCase name }} / Header" />
</Header>
<{{ pascalCase name }}Form onSubmit={onFormSubmit} error={error} loading={loadingMutation} />
</Container>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { gql } from '../../../shared/services/graphqlApi/__generated/gql';

export const add{{ pascalCase name }}Mutation = gql(/* GraphQL */ `
mutation add{{ pascalCase name }}Mutation($input: Create{{ pascalCase name }}MutationInput!) {
create{{ pascalCase name }}(input: $input) {
{{ camelCase name }}Edge {
node {
id
name
}
}
}
}
`);
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import styled from 'styled-components';

export const Container = styled.div``;
export const Header = styled.h1``;
Original file line number Diff line number Diff line change
@@ -1,26 +1,56 @@
import { useState } from 'react';
import { useParams } from 'react-router';
import { useMutation } from '@apollo/client';
import { FormattedMessage, useIntl } from 'react-intl';
import { Navigate, useParams } from 'react-router';

import { RoutesConfig } from '../../../app/config/routes';
import { useSnackbar } from '../../../modules/snackbar';
import { BackButton } from '../../../shared/components/backButton';
import { useGenerateLocalePath } from '../../../shared/hooks/';
import {{ pascalCase name }}Form from '../{{ camelCase name }}Form';
import { {{ pascalCase name }}FormFields } from '../{{ camelCase name }}Form/{{ camelCase name }}Form.component';
import { use{{ pascalCase name }} } from '../use{{ pascalCase name }}';
import { Container } from './edit{{ pascalCase name }}.styles';
import { edit{{ pascalCase name }}Mutation } from './edit{{ pascalCase name }}.graphql';
import { Container, Header } from './edit{{ pascalCase name }}.styles';

export const Edit{{ pascalCase name }} = () => {
const { id } = useParams<{ id: string }>();
const [isLoading, setIsLoading] = useState(false);
const itemData = use{{ pascalCase name }}(id);
const { itemData, loading } = use{{ pascalCase name }}(id);

const onFormSubmit = (formData: {{ pascalCase name }}FormFields) => {
if (formData) {
// send form
setIsLoading(true);
const { showMessage } = useSnackbar();
const intl = useIntl();

const successMessage = intl.formatMessage({
id: '{{ pascalCase name }} form / Success message',
defaultMessage: '🎉 Changes saved successfully!',
});

const generateLocalePath = useGenerateLocalePath();
const [commitEdit{{ pascalCase name }}Mutation, { error, loading: loadingMutation }] = useMutation(
edit{{ pascalCase name }}Mutation,
{
onCompleted: () => showMessage(successMessage),
}
);
if (loading)
return (
<Container>
<FormattedMessage defaultMessage="Loading ..." id="Loading message" />
</Container>
);
if (!itemData) return <Navigate to={generateLocalePath(RoutesConfig.{{ camelCase name }}.index)} />;


const onFormSubmit = (formData: {{ pascalCase name }}FormFields) => {
commitEdit{{ pascalCase name }}Mutation({ variables: { input: { id: itemData.id, name: formData.name } } });
};

return (
<Container>
<{{ pascalCase name }}Form initialData={itemData} loading={isLoading} onSubmit={onFormSubmit} />
<BackButton to={generateLocalePath(RoutesConfig.{{ camelCase name }}.list)} />
<Header>
<FormattedMessage defaultMessage="Edit CRUD Example Item" id="Edit{{ pascalCase name }} / Header" />
</Header>
<{{ pascalCase name }}Form initialData={itemData} loading={loadingMutation} error={error} onSubmit={onFormSubmit} />
</Container>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { gql } from '../../../shared/services/graphqlApi/__generated/gql';

export const edit{{ pascalCase name }}Mutation = gql(/* GraphQL */ `
mutation edit{{ pascalCase name }}ContentMutation($input: Update{{ pascalCase name }}MutationInput!) {
update{{ pascalCase name }}(input: $input) {
{{ camelCase name }} {
id
name
}
}
}
`);
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import styled from 'styled-components';

export const Container = styled.div``;
export const Header = styled.h1``;
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import { FormattedMessage } from 'react-intl';
import { useParams } from 'react-router';

import { RoutesConfig } from '../../../app/config/routes';
import { BackButton } from '../../../shared/components/backButton';
import { useGenerateLocalePath } from '../../../shared/hooks/';
import { use{{ pascalCase name }} } from '../use{{ pascalCase name }}';
import { H1 } from '../../../theme/typography';
import { Container } from './{{ camelCase name }}Details.styles';
import { Container, Header } from './{{ camelCase name }}Details.styles';

export const {{ pascalCase name }}Details = () => {
const generateLocalePath = useGenerateLocalePath();
const { id } = useParams<{ id: string }>();
const itemData = use{{ pascalCase name }}(id);
const { itemData, loading } = use{{ pascalCase name }}(id);

if (loading) {
return (
<span>
<FormattedMessage defaultMessage="Loading ..." id="Loading message" />
</span>
);
}

return (
<Container>
<H1>
[{itemData?.id}] {itemData?.name}
</H1>
<BackButton to={generateLocalePath(RoutesConfig.{{ camelCase name }}.list)} />
<Header>{itemData?.name}</Header>
</Container>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { gql } from '../../../shared/services/graphqlApi/__generated/gql';

export const {{ camelCase name }}DetailsQuery = gql(/* GraphQL */ `
query {{ camelCase name }}DetailsQuery($id: ID!) {
{{ camelCase name }}(id: $id) {
id
name
}
}
`);
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import styled from 'styled-components';

export const Container = styled.div``;
export const Header = styled.h1``;
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { useQuery } from '@apollo/client';
import { FormattedMessage } from 'react-intl';

import { RoutesConfig } from '../../../app/config/routes';
import { ButtonVariant } from '../../../shared/components/forms/button';
import { useGenerateLocalePath } from '../../../shared/hooks/localePaths';
import { {{ pascalCase name }} } from '../../../shared/services/api/{{ camelCase name }}/types';
import { mapConnection } from '../../../shared/utils/graphql';
import { {{ camelCase name }}ListQuery } from './{{ camelCase name }}List.graphql';
import { AddNewLink, Container, Header, List } from './{{ camelCase name }}List.styles';
import { {{ pascalCase name }}ListItem } from './{{ camelCase name }}ListItem';

export const {{ pascalCase name }}List = () => {
const generateLocalePath = useGenerateLocalePath();
const data: {{ pascalCase name }}[] = [];
const isLoading = false;
const { loading, data } = useQuery({{ camelCase name }}ListQuery);

const renderList = () => {
if (!data) return null;
return (
<List>
{data.map((item) => (
<{{ pascalCase name }}ListItem item={item} key={item.id} />
))}
{mapConnection(
(item) => (
<{{ pascalCase name }}ListItem item={item} key={item.id} />
),
data.{{ camelCase name }}List
)}
</List>
);
};
Expand All @@ -30,7 +34,7 @@ export const {{ pascalCase name }}List = () => {
<FormattedMessage id="{{ pascalCase name }}List / Add new" defaultMessage="Add new item" />
</AddNewLink>

{isLoading ? (
{loading ? (
<span>
<FormattedMessage defaultMessage="Loading ..." id="Loading message" />
</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { gql } from '../../../shared/services/graphqlApi/__generated/gql';

export const {{ camelCase name }}ListQuery = gql(/* GraphQL */ `
query {{ camelCase name }}ListQuery {
{{ camelCase name }}List(first: 100) {
edges {
node {
id
name
...{{ camelCase name }}ListItemFragment
}
}
}
}
`);

export const {{ camelCase name }}ListItemDeleteMutation = gql(/* GraphQL */ `
mutation {{ camelCase name }}ListItemDeleteMutation($input: Delete{{ pascalCase name }}MutationInput!) {
delete{{ pascalCase name }}(input: $input) {
deletedIds
}
}
`);

export const {{ camelCase name }}ListItemFragment = gql(/* GraphQL */ `
fragment {{ camelCase name }}ListItemFragment on {{ pascalCase name }}Type {
id
name
}
`);
Loading

0 comments on commit ed5a55d

Please sign in to comment.