From 738ed64a2cb85bb1e9f5aff2fcbf3be71cabd881 Mon Sep 17 00:00:00 2001
From: Dwayne Harris
Date: Sun, 8 Sep 2019 15:29:49 -0400
Subject: [PATCH] WIP
---
package-lock.json | 5 ++
package.json | 1 +
src/actions/directory.ts | 73 ++++++++++++++++
src/actions/entities.ts | 8 +-
src/actions/groups.ts | 46 ----------
src/api/groups.ts | 4 +-
src/components/app/app.tsx | 9 +-
src/components/pages/directory/directory.tsx | 2 +-
src/components/pages/directory/index.ts | 5 +-
src/components/pages/register/register.tsx | 13 +--
src/components/spinner/index.tsx | 17 ++++
src/components/spinner/spinner.scss | 62 ++++++++++++++
src/components/user-info/user-info.tsx | 6 +-
src/reducers/directory.ts | 36 ++++++++
src/reducers/entities.ts | 3 +
src/reducers/requests.ts | 1 +
src/selectors/index.ts | 7 +-
src/store/schemas.ts | 12 +++
src/types/index.ts | 88 ++++++--------------
src/types/store.ts | 71 ++++++++++++++++
20 files changed, 335 insertions(+), 134 deletions(-)
create mode 100644 src/actions/directory.ts
delete mode 100644 src/actions/groups.ts
create mode 100644 src/components/spinner/index.tsx
create mode 100644 src/components/spinner/spinner.scss
create mode 100644 src/reducers/directory.ts
create mode 100644 src/store/schemas.ts
create mode 100644 src/types/store.ts
diff --git a/package-lock.json b/package-lock.json
index 9ef52a6..005de9d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5295,6 +5295,11 @@
"sort-keys": "^1.0.0"
}
},
+ "normalizr": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/normalizr/-/normalizr-3.4.1.tgz",
+ "integrity": "sha512-gei+tJucERU8vYN6TFQL2k5YMLX2Yh7nlylKMJC65+Uu/LS3xQCDJc8cies72aHouycKYyVgcnyLRbaJsigXKw=="
+ },
"npm-run-all": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
diff --git a/package.json b/package.json
index ba01fc4..85bd795 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"@fortawesome/free-solid-svg-icons": "^5.10.2",
"@fortawesome/react-fontawesome": "^0.1.4",
"lodash": "^4.17.15",
+ "normalizr": "^3.4.1",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-redux": "^7.1.1",
diff --git a/src/actions/directory.ts b/src/actions/directory.ts
new file mode 100644
index 0000000..07ed7a4
--- /dev/null
+++ b/src/actions/directory.ts
@@ -0,0 +1,73 @@
+import { Action, AnyAction } from 'redux'
+import { ThunkAction, ThunkDispatch } from 'redux-thunk'
+import { normalize } from 'normalizr'
+
+import { getGroups } from '../api/groups'
+import { setEntities } from '../actions/entities'
+import { startRequest, finishRequest } from '../actions/requests'
+import { group } from '../store/schemas'
+import { AppState } from '../types'
+
+const FETCH_ID = 'groups'
+
+export interface SetGroupsAction extends Action {
+ type: 'DIRECTORY_SET_GROUPS'
+ payload: string[]
+}
+
+export interface AppendGroupsAction extends Action {
+ type: 'DIRECTORY_APPEND_GROUPS',
+ payload: string[]
+}
+
+export interface SetContinuationAction extends Action {
+ type: 'DIRECTORY_SET_CONTINUATION'
+ payload: string
+}
+
+export type DirectoryActions = SetGroupsAction | AppendGroupsAction | SetContinuationAction
+
+const setGroups = (groups: string[]): SetGroupsAction => ({
+ type: 'DIRECTORY_SET_GROUPS',
+ payload: groups,
+})
+
+const appendGroups = (groups: string[]): AppendGroupsAction => ({
+ type: 'DIRECTORY_APPEND_GROUPS',
+ payload: groups,
+})
+
+const setContinuation = (continuation: string): SetContinuationAction => ({
+ type: 'DIRECTORY_SET_CONTINUATION',
+ payload: continuation,
+})
+
+const fetchGroups = (sort?: string, continuation?: string): ThunkAction, AppState, void, AnyAction> => {
+ return async (dispatch: ThunkDispatch) => {
+ dispatch(startRequest(FETCH_ID))
+
+ try {
+ const response = await getGroups(sort, continuation)
+ const groups = normalize(response.groups, group)
+
+ dispatch(setEntities(groups.entities))
+ dispatch(setGroups(groups.result))
+
+ if (response.continuation) {
+ dispatch(setContinuation(response.continuation))
+ }
+
+ dispatch(finishRequest(FETCH_ID, true))
+ } catch (err) {
+ console.error(err)
+ dispatch(finishRequest(FETCH_ID, false))
+ }
+ }
+}
+
+export {
+ setGroups,
+ appendGroups,
+ setContinuation,
+ fetchGroups,
+}
diff --git a/src/actions/entities.ts b/src/actions/entities.ts
index be7bfa2..9b771a1 100644
--- a/src/actions/entities.ts
+++ b/src/actions/entities.ts
@@ -1,5 +1,5 @@
import { Action } from 'redux'
-import { Entity } from '../types/entities'
+import { Entity, EntityStore } from '../types'
export interface SetEntityAction extends Action {
type: 'ENTITIES_SET_ENTITY'
@@ -12,8 +12,7 @@ export interface SetEntityAction extends Action {
export interface SetEntitiesAction extends Action {
type: 'ENTITIES_SET_ENTITIES'
payload: {
- type: string
- entities: Entity[]
+ entities: EntityStore
}
}
@@ -27,10 +26,9 @@ const setEntity = (type: string, entity: Entity): SetEntityAction => ({
}
})
-const setEntities = (type: string, entities: Entity[]): SetEntitiesAction => ({
+const setEntities = (entities: EntityStore): SetEntitiesAction => ({
type: 'ENTITIES_SET_ENTITIES',
payload: {
- type,
entities,
}
})
diff --git a/src/actions/groups.ts b/src/actions/groups.ts
deleted file mode 100644
index b44481d..0000000
--- a/src/actions/groups.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { ThunkAction, ThunkDispatch } from 'redux-thunk'
-import { Action, AnyAction } from 'redux'
-
-import { getGroups } from '../api/groups'
-import { startRequest, finishRequest } from '../actions/requests'
-
-import { AppState } from '../types'
-import { Entity } from '../types/entities'
-
-const FETCH_ID = 'groups'
-
-export interface FetchGroupsAction extends Action {
- type: 'GROUPS_FETCH'
- payload: {
- groups: Entity[]
- continuation?: string
- }
-}
-
-const setGroups = (groups: Entity[], continuation?: string): FetchGroupsAction => ({
- type: 'GROUPS_FETCH',
- payload: {
- groups,
- continuation,
- },
-})
-
-const fetchGroups = (sort?: string, continuation?: string): ThunkAction, AppState, void, AnyAction> => {
- return async (dispatch: ThunkDispatch) => {
- dispatch(startRequest(FETCH_ID))
-
- try {
- const response = await getGroups(sort, continuation)
-
- dispatch(setGroups(response.groups, response.continuation))
- dispatch(finishRequest(FETCH_ID, true))
- } catch (err) {
- console.error(err)
- dispatch(finishRequest(FETCH_ID, false))
- }
- }
-}
-
-export {
- fetchGroups,
-}
diff --git a/src/api/groups.ts b/src/api/groups.ts
index 761dc49..6bff0a5 100644
--- a/src/api/groups.ts
+++ b/src/api/groups.ts
@@ -1,5 +1,5 @@
import { fetch } from './fetch'
-import { Entity } from '../types/entities'
+import { Entity } from '../types'
interface GroupsResponse {
groups: Entity[]
@@ -13,7 +13,7 @@ export async function getGroups(sort: string = 'members', continuation?: string)
}
const querystring = Object.entries(params).filter(([name, value]) => value !== undefined).map(([name, value]) => `${name}=${value}`).join('&')
-
+
return await fetch({
path: `/api/groups?${querystring}`
})
diff --git a/src/components/app/app.tsx b/src/components/app/app.tsx
index 195b605..34fdee9 100644
--- a/src/components/app/app.tsx
+++ b/src/components/app/app.tsx
@@ -1,8 +1,12 @@
import React, { FC } from 'react'
import { HashRouter as Router, Route, Link } from 'react-router-dom'
+import Spinner from '../spinner'
import UserInfo from '../user-info'
+
import Home from '../pages/home'
+import Register from '../pages/register'
+import Directory from '../pages/directory'
import './app.scss'
@@ -30,6 +34,8 @@ const App: FC = ({ menuCollapsed, fetching }) => {
+ {fetching && }
+