Skip to content

Commit 0d08d09

Browse files
committed
feat(graphql): integrate graphql - tasks-list page
https://github.com/martis-git/learn-frontend/issues/279
1 parent c581ce0 commit 0d08d09

File tree

7 files changed

+78
-52
lines changed

7 files changed

+78
-52
lines changed

examples/graphql/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"@graphql-codegen/typescript-react-apollo": "^2.0.7",
5959
"@types/classnames": "^2.2.10",
6060
"@types/react-router": "^5.1.8",
61-
"@types/react-router-dom": "^5.1.5"
61+
"@types/react-router-dom": "^5.1.5",
62+
"bootstrap": "^4.5.2"
6263
}
6364
}

examples/graphql/src/app/index.scss

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// FIXME: specify imported modules (need only some utils-classes)
2+
@import '~bootstrap/dist/css/bootstrap.css';
3+
14
// vars
25
.app {
36
--clr-foreground: #fff;
@@ -11,9 +14,13 @@ body,
1114
.app {
1215
height: 100%;
1316
position: relative;
17+
background-color: #f0f2f5;
1418
}
1519

1620
.app {
21+
ul {
22+
padding-left: unset;
23+
}
1724
li {
1825
list-style: none;
1926
}
@@ -23,7 +30,7 @@ body,
2330
display: flex;
2431
flex-direction: column;
2532
&-content {
26-
margin: auto 10%;
33+
margin: 10px 10%;
2734
flex-grow: 1;
2835
}
2936

@@ -33,11 +40,21 @@ body,
3340
}
3441

3542
// common class-styles
43+
// NOTE: Используем подход стилизации по классам, т.к. приложение представляет собой прототип
3644
.app {
3745
.text-white {
3846
color: white;
3947
}
4048
.text-muted {
4149
color: gray;
4250
}
51+
.loading--overlay {
52+
padding-top: 10px;
53+
width: 100%;
54+
height: 100%;
55+
min-height: 72px;
56+
position: absolute;
57+
z-index: 999;
58+
background-color: rgba(255, 255, 255, 0.8);
59+
}
4360
}

examples/graphql/src/pages/tasks-list/index.tsx

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,47 @@
1-
import React, { useEffect } from 'react'
2-
import { Spin, Alert } from "antd";
3-
import { useFetch } from "shared/hooks";
1+
import React from 'react'
2+
import { Spin, Alert, Button } from "antd";
43
import { TaskItem } from "shared/components";
5-
import { useGetTodosListQuery } from "./query.gen";
6-
7-
type Foo = import("types").Album;
4+
import { useTodosQuery } from "./query.gen";
85

96
const TasksList = () => {
10-
const { data, error, loading } = useFetch<Task[]>("todos");
11-
const { data: query } = useGetTodosListQuery();
12-
13-
useEffect(() => {
14-
if (query) {
15-
console.table(query.todos?.data?.map((todo) => ({
16-
id: todo?.id,
17-
title: todo?.title,
18-
user: todo?.user?.name,
19-
})));
20-
const todo = query.todos?.data?.[0];
21-
console.log(todo);
22-
}
23-
}, [query]);
7+
const { data, error, loading, refetch } = useTodosQuery({
8+
// Чтобы при рефетчинге менялся loading статус
9+
notifyOnNetworkStatusChange: true,
10+
});
11+
const query = data?.todos?.data;
2412

2513
return (
26-
<div className="page page-tasks-list">
14+
<div className="page tasks-list">
2715
<div className="page-content">
16+
<div className="tasks-list__toolbar text-center">
17+
<Button
18+
className="btn-refetch"
19+
onClick={() => refetch()}
20+
disabled={loading}
21+
title="Refresh list of tasks"
22+
>
23+
Refresh
24+
</Button>
25+
</div>
2826
{error && (
2927
<Alert
3028
type="error"
3129
message={error}
3230
showIcon
3331
/>
3432
)}
35-
{loading && <Spin />}
36-
<ul>
37-
{data?.map((taskProps) => (
38-
<li><TaskItem {...taskProps} /></li>
39-
))}
40-
{data?.length === 0 && (
41-
<li>There are not tasks found</li>
42-
)}
43-
</ul>
33+
<div className="tasks-list__content position-relative pt-1">
34+
{loading && <Spin className="loading--overlay" />}
35+
<ul>
36+
{query?.map((task) => (
37+
<li><TaskItem {...task} /></li>
38+
))}
39+
{/* FIXME: yet (!query && !loading) */}
40+
{query?.length === 0 && (
41+
<li>There are not tasks found</li>
42+
)}
43+
</ul>
44+
</div>
4445
</div>
4546
</div>
4647
)
Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
/** @generated THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. */
2-
import * as Types from '../../types';
2+
import * as Types from '../../models';
33

44
import { gql } from '@apollo/client';
55
import * as Apollo from '@apollo/client';
6-
export type GetTodosListQueryVariables = Types.Exact<{ [key: string]: never; }>;
6+
export type TodosQueryVariables = Types.Exact<{ [key: string]: never; }>;
77

88

9-
export type GetTodosListQuery = { readonly todos: Types.Maybe<{ readonly data: Types.Maybe<ReadonlyArray<Types.Maybe<{ readonly id: Types.Maybe<string>, readonly title: Types.Maybe<string>, readonly user: Types.Maybe<{ readonly name: Types.Maybe<string> }> }>>> }> };
9+
export type TodosQuery = { readonly todos?: Types.Maybe<{ readonly data?: Types.Maybe<ReadonlyArray<Types.Maybe<{ readonly id?: Types.Maybe<string>, readonly title?: Types.Maybe<string>, readonly user?: Types.Maybe<{ readonly id?: Types.Maybe<string>, readonly name?: Types.Maybe<string> }> }>>> }> };
1010

1111

12-
export const GetTodosListDocument = gql`
13-
query getTodosList {
12+
export const TodosDocument = gql`
13+
query Todos {
1414
todos {
1515
data {
1616
id
1717
title
1818
user {
19+
id
1920
name
2021
}
2122
}
@@ -24,26 +25,26 @@ export const GetTodosListDocument = gql`
2425
`;
2526

2627
/**
27-
* __useGetTodosListQuery__
28+
* __useTodosQuery__
2829
*
29-
* To run a query within a React component, call `useGetTodosListQuery` and pass it any options that fit your needs.
30-
* When your component renders, `useGetTodosListQuery` returns an object from Apollo Client that contains loading, error, and data properties
30+
* To run a query within a React component, call `useTodosQuery` and pass it any options that fit your needs.
31+
* When your component renders, `useTodosQuery` returns an object from Apollo Client that contains loading, error, and data properties
3132
* you can use to render your UI.
3233
*
3334
* @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;
3435
*
3536
* @example
36-
* const { data, loading, error } = useGetTodosListQuery({
37+
* const { data, loading, error } = useTodosQuery({
3738
* variables: {
3839
* },
3940
* });
4041
*/
41-
export function useGetTodosListQuery(baseOptions?: Apollo.QueryHookOptions<GetTodosListQuery, GetTodosListQueryVariables>) {
42-
return Apollo.useQuery<GetTodosListQuery, GetTodosListQueryVariables>(GetTodosListDocument, baseOptions);
42+
export function useTodosQuery(baseOptions?: Apollo.QueryHookOptions<TodosQuery, TodosQueryVariables>) {
43+
return Apollo.useQuery<TodosQuery, TodosQueryVariables>(TodosDocument, baseOptions);
4344
}
44-
export function useGetTodosListLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetTodosListQuery, GetTodosListQueryVariables>) {
45-
return Apollo.useLazyQuery<GetTodosListQuery, GetTodosListQueryVariables>(GetTodosListDocument, baseOptions);
45+
export function useTodosLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<TodosQuery, TodosQueryVariables>) {
46+
return Apollo.useLazyQuery<TodosQuery, TodosQueryVariables>(TodosDocument, baseOptions);
4647
}
47-
export type GetTodosListQueryHookResult = ReturnType<typeof useGetTodosListQuery>;
48-
export type GetTodosListLazyQueryHookResult = ReturnType<typeof useGetTodosListLazyQuery>;
49-
export type GetTodosListQueryResult = Apollo.QueryResult<GetTodosListQuery, GetTodosListQueryVariables>;
48+
export type TodosQueryHookResult = ReturnType<typeof useTodosQuery>;
49+
export type TodosLazyQueryHookResult = ReturnType<typeof useTodosLazyQuery>;
50+
export type TodosQueryResult = Apollo.QueryResult<TodosQuery, TodosQueryVariables>;

examples/graphql/src/pages/tasks-list/query.gql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
query getTodosList {
1+
query Todos {
22
todos {
33
data {
44
id
55
title
66
user {
7+
id
78
name
89
}
910
}

examples/graphql/src/shared/components/task-item/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import { UserOutlined } from "@ant-design/icons";
55
import { useFetch } from "shared/hooks";
66
import "./index.scss";
77

8-
type Props = Task;
8+
type Props = import("models").Todo;
99

1010
// TODO: as feature
1111
const TaskItem = (props: Props) => {
12-
const { completed, title, userId, id } = props;
13-
const { data: author } = useFetch<User>(`users/${userId}`);
12+
const { completed, title, user, id } = props;
13+
const { data: author } = useFetch<User>(`users/${user?.id}`);
1414

1515
return (
1616
<Card className={cn("task-item", { completed })}>

examples/graphql/yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3780,6 +3780,11 @@ boolbase@^1.0.0, boolbase@~1.0.0:
37803780
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
37813781
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
37823782

3783+
bootstrap@^4.5.2:
3784+
version "4.5.2"
3785+
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.2.tgz#a85c4eda59155f0d71186b6e6ad9b875813779ab"
3786+
integrity sha512-vlGn0bcySYl/iV+BGA544JkkZP5LB3jsmkeKLFQakCOwCM3AOk7VkldBz4jrzSe+Z0Ezn99NVXa1o45cQY4R6A==
3787+
37833788
brace-expansion@^1.1.7:
37843789
version "1.1.11"
37853790
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"

0 commit comments

Comments
 (0)