✨ Register: Show list of active products
🛠 Generate apollo client typescript helpers from graphql schema
This commit is contained in:
1 parent
fa89353525
commit
f0656b34e9
13 files changed
+8165
-173
No files matched your search
@@ -64,6 +64,7 @@ TEMPLATES = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
"corsheaders.middleware.CorsMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
"django.middleware.csrf.CsrfViewMiddleware",
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
@@ -84,6 +85,7 @@ INSTALLED_APPS = [
|
|||||||
"django_extensions",
|
"django_extensions",
|
||||||
"rest_framework",
|
"rest_framework",
|
||||||
"easy_thumbnails",
|
"easy_thumbnails",
|
||||||
|
"corsheaders",
|
||||||
]
|
]
|
||||||
LOCAL_APPS = [
|
LOCAL_APPS = [
|
||||||
"main",
|
"main",
|
||||||
@@ -133,6 +135,12 @@ LOGGING = {
|
|||||||
|
|
||||||
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||||
|
|
||||||
|
CORS_ALLOWED_ORIGINS = [
|
||||||
|
"https://bbs.neuf.no",
|
||||||
|
"http://localhost:8000",
|
||||||
|
"http://localhost:3000",
|
||||||
|
]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from .local_settings import *
|
from .local_settings import *
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "bbs-schema",
|
||||||
|
"schemaPath": "schema.graphql",
|
||||||
|
"extensions": {
|
||||||
|
"endpoints": {
|
||||||
|
"default": {
|
||||||
|
"url": "http://localhost:8000/graphql/",
|
||||||
|
"introspect": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
schema: http://localhost:8000/graphql/
|
||||||
|
documents: ./src/**/*.graphql
|
||||||
|
generates:
|
||||||
|
./src/types.ts:
|
||||||
|
plugins:
|
||||||
|
- typescript
|
||||||
|
- typescript-operations
|
||||||
|
- typescript-react-apollo
|
||||||
Generated
+7977
-166
File diff suppressed because it is too large.
Load diff
+10
-3
@@ -1,23 +1,30 @@
|
|||||||
{
|
{
|
||||||
"name": "bbs",
|
"name": "bbs",
|
||||||
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "vite",
|
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
|
"generate": "graphql-codegen",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
|
"start": "vite",
|
||||||
"test": "jest"
|
"test": "jest"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@apollo/client": "^3.4.16",
|
||||||
"react": "^17.0.0",
|
"react": "^17.0.0",
|
||||||
"react-dom": "^17.0.0"
|
"react-dom": "^17.0.0",
|
||||||
|
"graphql": "^15.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@graphql-codegen/cli": "^2.2.2",
|
||||||
|
"@graphql-codegen/typescript-operations": "^2.2.0",
|
||||||
|
"@graphql-codegen/typescript-react-apollo": "^3.2.0",
|
||||||
"@types/react": "^17.0.0",
|
"@types/react": "^17.0.0",
|
||||||
"@types/react-dom": "^17.0.0",
|
"@types/react-dom": "^17.0.0",
|
||||||
"@vitejs/plugin-react": "^1.0.0",
|
"@vitejs/plugin-react": "^1.0.0",
|
||||||
"typescript": "^4.3.2",
|
|
||||||
"jest": "^27.3.1",
|
"jest": "^27.3.1",
|
||||||
|
"typescript": "^4.3.2",
|
||||||
"vite": "^2.6.4"
|
"vite": "^2.6.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,19 @@
|
|||||||
|
import {ApolloProvider} from "@apollo/client";
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import logo from './assets/brick.svg';
|
import logo from './assets/brick.svg';
|
||||||
|
|
||||||
import styles from './App.module.css'
|
import styles from './App.module.css'
|
||||||
|
import {Register} from "./features/Register";
|
||||||
|
import client from "./client";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
|
<ApolloProvider client={client}>
|
||||||
<div className={styles.app}>
|
<div className={styles.app}>
|
||||||
<img src={logo} className={styles.logo} alt="logo" />
|
<img src={logo} className={styles.logo} alt="logo" />
|
||||||
|
<Register />
|
||||||
</div>
|
</div>
|
||||||
|
</ApolloProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import {ApolloClient,InMemoryCache} from "@apollo/client";
|
||||||
|
|
||||||
|
const client = new ApolloClient({
|
||||||
|
uri: 'http://localhost:8000/graphql/', // FIXME: env
|
||||||
|
cache: new InMemoryCache()
|
||||||
|
});
|
||||||
|
|
||||||
|
export default client;
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import {Product, useAllProductsQuery} from '../types';
|
||||||
|
|
||||||
|
export const Register: React.FC = () => {
|
||||||
|
const { data, error, loading } = useAllProductsQuery({variables:{active: true}});
|
||||||
|
if(error) {
|
||||||
|
console.log('🔥', error)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if(loading) {
|
||||||
|
return <div>...</div>
|
||||||
|
}
|
||||||
|
return (<div>{data?.allProducts.map((product: Product) => {
|
||||||
|
return <div key={product.id}>{product.name}</div>
|
||||||
|
})} </div>)
|
||||||
|
};
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
query allProducts($active: Boolean!) {
|
||||||
|
allProducts(filters: {active: $active}) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
salePriceExt
|
||||||
|
salePriceInt
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
import * as Apollo from '@apollo/client';
|
||||||
|
export type Maybe<T> = T | null;
|
||||||
|
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
|
||||||
|
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
|
||||||
|
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
|
||||||
|
const defaultOptions = {}
|
||||||
|
/** All built-in and custom scalars, mapped to their actual values */
|
||||||
|
export type Scalars = {
|
||||||
|
ID: string;
|
||||||
|
String: string;
|
||||||
|
Boolean: boolean;
|
||||||
|
Int: number;
|
||||||
|
Float: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Product = {
|
||||||
|
__typename?: 'Product';
|
||||||
|
id: Scalars['ID'];
|
||||||
|
name: Scalars['String'];
|
||||||
|
salePriceExt: Scalars['Float'];
|
||||||
|
salePriceInt: Scalars['Float'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ProductFilter = {
|
||||||
|
active?: Maybe<Scalars['Boolean']>;
|
||||||
|
id?: Maybe<Scalars['ID']>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Query = {
|
||||||
|
__typename?: 'Query';
|
||||||
|
allProducts: Array<Product>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export type QueryAllProductsArgs = {
|
||||||
|
filters?: Maybe<ProductFilter>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AllProductsQueryVariables = Exact<{
|
||||||
|
active: Scalars['Boolean'];
|
||||||
|
}>;
|
||||||
|
|
||||||
|
|
||||||
|
export type AllProductsQuery = { __typename?: 'Query', allProducts: Array<{ __typename?: 'Product', id: string, name: string, salePriceExt: number, salePriceInt: number }> };
|
||||||
|
|
||||||
|
|
||||||
|
export const AllProductsDocument = gql`
|
||||||
|
query allProducts($active: Boolean!) {
|
||||||
|
allProducts(filters: {active: $active}) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
salePriceExt
|
||||||
|
salePriceInt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __useAllProductsQuery__
|
||||||
|
*
|
||||||
|
* To run a query within a React component, call `useAllProductsQuery` and pass it any options that fit your needs.
|
||||||
|
* When your component renders, `useAllProductsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||||
|
* you can use to render your UI.
|
||||||
|
*
|
||||||
|
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { data, loading, error } = useAllProductsQuery({
|
||||||
|
* variables: {
|
||||||
|
* active: // value for 'active'
|
||||||
|
* },
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
export function useAllProductsQuery(baseOptions: Apollo.QueryHookOptions<AllProductsQuery, AllProductsQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useQuery<AllProductsQuery, AllProductsQueryVariables>(AllProductsDocument, options);
|
||||||
|
}
|
||||||
|
export function useAllProductsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<AllProductsQuery, AllProductsQueryVariables>) {
|
||||||
|
const options = {...defaultOptions, ...baseOptions}
|
||||||
|
return Apollo.useLazyQuery<AllProductsQuery, AllProductsQueryVariables>(AllProductsDocument, options);
|
||||||
|
}
|
||||||
|
export type AllProductsQueryHookResult = ReturnType<typeof useAllProductsQuery>;
|
||||||
|
export type AllProductsLazyQueryHookResult = ReturnType<typeof useAllProductsLazyQuery>;
|
||||||
|
export type AllProductsQueryResult = Apollo.QueryResult<AllProductsQuery, AllProductsQueryVariables>;
|
||||||
+9
-2
@@ -1,10 +1,17 @@
|
|||||||
import strawberry
|
import strawberry
|
||||||
|
import strawberry_django
|
||||||
from strawberry_django import auto
|
from strawberry_django import auto
|
||||||
|
|
||||||
from main import models
|
from main import models
|
||||||
|
|
||||||
|
|
||||||
@strawberry.django.type(models.Product)
|
@strawberry_django.filters.filter(models.Product)
|
||||||
|
class ProductFilter:
|
||||||
|
id: auto
|
||||||
|
active: auto
|
||||||
|
|
||||||
|
|
||||||
|
@strawberry_django.type(models.Product, filters=ProductFilter)
|
||||||
class Product:
|
class Product:
|
||||||
id: auto
|
id: auto
|
||||||
name: auto
|
name: auto
|
||||||
@@ -14,7 +21,7 @@ class Product:
|
|||||||
|
|
||||||
@strawberry.type
|
@strawberry.type
|
||||||
class Query:
|
class Query:
|
||||||
all_products: list[Product] = strawberry.django.field()
|
all_products: list[Product] = strawberry_django.field()
|
||||||
|
|
||||||
|
|
||||||
schema = strawberry.Schema(query=Query)
|
schema = strawberry.Schema(query=Query)
|
||||||
Generated
+16
-1
@@ -121,6 +121,17 @@ sqlparse = ">=0.2.2"
|
|||||||
argon2 = ["argon2-cffi (>=19.1.0)"]
|
argon2 = ["argon2-cffi (>=19.1.0)"]
|
||||||
bcrypt = ["bcrypt"]
|
bcrypt = ["bcrypt"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "django-cors-headers"
|
||||||
|
version = "3.10.0"
|
||||||
|
description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
Django = ">=2.2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django-extensions"
|
name = "django-extensions"
|
||||||
version = "3.1.3"
|
version = "3.1.3"
|
||||||
@@ -509,7 +520,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "0dd39131cb6b3158ec615ee0768e068463a26f566f875d70e47d3f0e620c999c"
|
content-hash = "131f3d01c11b8a7f90734376f3f8e2b43dc37507eda0c02d6a5d9212a3b78560"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
asgiref = [
|
asgiref = [
|
||||||
@@ -552,6 +563,10 @@ django = [
|
|||||||
{file = "Django-3.2.8-py3-none-any.whl", hash = "sha256:42573831292029639b798fe4d3812996bfe4ff3275f04566da90764daec011a5"},
|
{file = "Django-3.2.8-py3-none-any.whl", hash = "sha256:42573831292029639b798fe4d3812996bfe4ff3275f04566da90764daec011a5"},
|
||||||
{file = "Django-3.2.8.tar.gz", hash = "sha256:f6d2c4069c9b9bfac03bedff927ea1f9e0d29e34525cec8a68fd28eb2a8df7af"},
|
{file = "Django-3.2.8.tar.gz", hash = "sha256:f6d2c4069c9b9bfac03bedff927ea1f9e0d29e34525cec8a68fd28eb2a8df7af"},
|
||||||
]
|
]
|
||||||
|
django-cors-headers = [
|
||||||
|
{file = "django-cors-headers-3.10.0.tar.gz", hash = "sha256:cd6f4360f5246569c149dc1c40c907c191f1ec45551e10d2a2e2e68512652f78"},
|
||||||
|
{file = "django_cors_headers-3.10.0-py3-none-any.whl", hash = "sha256:cba6e99659abb0e47cc4aaabb8fcde03f193e6bb3b92ba47c5185ec4cedc5d9e"},
|
||||||
|
]
|
||||||
django-extensions = [
|
django-extensions = [
|
||||||
{file = "django-extensions-3.1.3.tar.gz", hash = "sha256:5f0fea7bf131ca303090352577a9e7f8bfbf5489bd9d9c8aea9401db28db34a0"},
|
{file = "django-extensions-3.1.3.tar.gz", hash = "sha256:5f0fea7bf131ca303090352577a9e7f8bfbf5489bd9d9c8aea9401db28db34a0"},
|
||||||
{file = "django_extensions-3.1.3-py3-none-any.whl", hash = "sha256:50de8977794a66a91575dd40f87d5053608f679561731845edbd325ceeb387e3"},
|
{file = "django_extensions-3.1.3-py3-none-any.whl", hash = "sha256:50de8977794a66a91575dd40f87d5053608f679561731845edbd325ceeb387e3"},
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ Pillow = "8.4.0"
|
|||||||
sentry-sdk = "1.4.3"
|
sentry-sdk = "1.4.3"
|
||||||
strawberry-graphql = "^0.85.1"
|
strawberry-graphql = "^0.85.1"
|
||||||
strawberry-graphql-django = "^0.2.5"
|
strawberry-graphql-django = "^0.2.5"
|
||||||
|
django-cors-headers = "^3.10.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
pytest = "^6.2.5"
|
pytest = "^6.2.5"
|
||||||
|
|||||||
Reference in new issue
Block a user