diff --git a/.eslintrc.js b/.eslintrc.js
index f964eb8277..6b12d72670 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,56 +1,56 @@
module.exports = {
- parser: '@typescript-eslint/parser', // Specifies the ESLint parser
- extends: [
- 'plugin:jest/recommended',
- 'plugin:import/errors',
- 'plugin:import/warnings',
- 'plugin:import/typescript',
- 'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
- 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
- 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
- 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
- ],
- parserOptions: {
- ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
- sourceType: 'module', // Allows for the use of imports
+ parser: '@typescript-eslint/parser', // Specifies the ESLint parser
+ extends: [
+ 'plugin:jest/recommended',
+ 'plugin:import/errors',
+ 'plugin:import/warnings',
+ 'plugin:import/typescript',
+ 'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react
+ 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
+ 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
+ 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
+ ],
+ parserOptions: {
+ ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
+ sourceType: 'module', // Allows for the use of imports
+ },
+ rules: {
+ '@typescript-eslint/camelcase': 'off',
+ 'import/no-duplicates': 'error',
+ 'import/extensions': 'error',
+ 'import/order': 'error',
+ 'import/newline-after-import': 'error',
+ 'import/prefer-default-export': 'error',
+ 'import/no-named-default': 'error',
+ 'import/no-anonymous-default-export': 'error',
+ 'import/dynamic-import-chunkname': 'error',
+ '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
+ },
+ settings: {
+ react: {
+ version: 'detect',
},
- rules: {
- '@typescript-eslint/camelcase': 'off',
- 'import/no-duplicates': 'error',
- 'import/extensions': 'error',
- 'import/order': 'error',
- 'import/newline-after-import': 'error',
- 'import/prefer-default-export': 'error',
- 'import/no-named-default': 'error',
- 'import/no-anonymous-default-export': 'error',
- 'import/dynamic-import-chunkname': 'error',
- '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
+ },
+ overrides: [
+ {
+ files: ['*.js'],
+ rules: {
+ '@typescript-eslint/explicit-function-return-type': 'off',
+ '@typescript-eslint/no-var-requires': 'off',
+ },
},
- settings: {
- react: {
- version: 'detect',
- },
+ {
+ files: ['*.stories.tsx', '*.test.tsx', '__tests__/**.*'],
+ rules: {
+ 'import/no-anonymous-default-export': 'off',
+ '@typescript-eslint/no-empty-function': 'off',
+ },
},
- overrides: [
- {
- files: ['*.js'],
- rules: {
- '@typescript-eslint/explicit-function-return-type': 'off',
- '@typescript-eslint/no-var-requires': 'off',
- },
- },
- {
- files: ['*.stories.tsx', '*.test.tsx', '__tests__/**.*'],
- rules: {
- 'import/no-anonymous-default-export': 'off',
- '@typescript-eslint/no-empty-function': 'off',
- },
- },
- {
- files: ['onesky/**.ts'],
- rules: {
- '@typescript-eslint/no-var-requires': 'off',
- },
- },
- ],
+ {
+ files: ['onesky/**.ts'],
+ rules: {
+ '@typescript-eslint/no-var-requires': 'off',
+ },
+ },
+ ],
};
diff --git a/.github/workflows/merge-pr-into-stage.yml b/.github/workflows/merge-pr-into-stage.yml
index d720e8f8d5..e69b820b69 100644
--- a/.github/workflows/merge-pr-into-stage.yml
+++ b/.github/workflows/merge-pr-into-stage.yml
@@ -1,18 +1,18 @@
name: Merge PR into stage
on:
- pull_request:
- types: [labeled, synchronize]
+ pull_request:
+ types: [labeled, synchronize]
jobs:
- merge-branch:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@master
- - name: Merge by labeled
- uses: devmasx/merge-branch@v1.1.0
- if: contains( github.event.pull_request.labels.*.name, 'merged into stage')
- with:
- type: now
- target_branch: 'stage'
- env:
- GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
+ merge-branch:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@master
+ - name: Merge by labeled
+ uses: devmasx/merge-branch@v1.1.0
+ if: contains( github.event.pull_request.labels.*.name, 'merged into stage')
+ with:
+ type: now
+ target_branch: 'stage'
+ env:
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
diff --git a/.gitignore b/.gitignore
index 78e7bcd92d..6b8438f35e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,12 +15,7 @@
/node_modules/.cache
# next.js
-/.next/
-/out/
-/dist/
-
-# production
-/build
+/.next
# misc
.DS_Store
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000000..9b79d72c07
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,17 @@
+# dependencies
+.yarn
+.pnp.js
+
+# testing
+/coverage
+
+# Storybook cache
+/node_modules/.cache
+
+# next.js
+/.next
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
diff --git a/.prettierrc.js b/.prettierrc.js
index 2c66e64e9b..de2f53cdf9 100644
--- a/.prettierrc.js
+++ b/.prettierrc.js
@@ -1,7 +1,4 @@
module.exports = {
- semi: true,
- trailingComma: "all",
singleQuote: true,
- printWidth: 120,
- tabWidth: 4
+ trailingComma: 'all',
};
diff --git a/.storybook/main.js b/.storybook/main.js
index 6a043b5a98..9dec2ed020 100644
--- a/.storybook/main.js
+++ b/.storybook/main.js
@@ -1,23 +1,23 @@
const path = require('path');
module.exports = {
- webpackFinal: async (config) => {
- config.module.rules.push({
- test: /\.(graphql|gql)$/,
- include: path.resolve(__dirname, '../'),
- exclude: /node_modules/,
- use: [
- {
- loader: 'graphql-tag/loader',
- },
- ],
- });
- return config;
- },
- addons: [
- '@storybook/addon-actions/register',
- '@storybook/addon-viewport/register',
- '@storybook/addon-knobs/register',
- 'storybook-addon-i18next/register',
- ],
+ webpackFinal: async (config) => {
+ config.module.rules.push({
+ test: /\.(graphql|gql)$/,
+ include: path.resolve(__dirname, '../'),
+ exclude: /node_modules/,
+ use: [
+ {
+ loader: 'graphql-tag/loader',
+ },
+ ],
+ });
+ return config;
+ },
+ addons: [
+ '@storybook/addon-actions/register',
+ '@storybook/addon-viewport/register',
+ '@storybook/addon-knobs/register',
+ 'storybook-addon-i18next/register',
+ ],
};
diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html
index de59e2ff48..642a87b2ac 100644
--- a/.storybook/preview-head.html
+++ b/.storybook/preview-head.html
@@ -1,8 +1,11 @@
-
+
diff --git a/.storybook/preview.js b/.storybook/preview.js
index 84a9ab9508..f3ed747a98 100644
--- a/.storybook/preview.js
+++ b/.storybook/preview.js
@@ -16,37 +16,40 @@ import theme from '../src/theme';
import i18n from '../src/lib/i18n';
if (isChromatic()) {
- MockDate.set(new Date(2020, 1, 1));
+ MockDate.set(new Date(2020, 1, 1));
}
addDecorator(
- withI18next({
- i18n,
- languages: {
- en: 'English',
- de: 'German',
- },
- }),
+ withI18next({
+ i18n,
+ languages: {
+ en: 'English',
+ de: 'German',
+ },
+ }),
);
addDecorator(withKnobs);
addDecorator((StoryFn) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
));
addParameters({ chromatic: { diffThreshold: true } });
// automatically import all files ending in *.stories.tsx
-configure(require.context('../src/components', true, /\.stories\.tsx?$/), module);
+configure(
+ require.context('../src/components', true, /\.stories\.tsx?$/),
+ module,
+);
diff --git a/.travis.yml b/.travis.yml
index 48d7e50127..d725f6fc89 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,20 +1,23 @@
sudo: false
language: node_js
node_js:
- - '15'
+ - '15'
branches:
- only:
- - main
+ only:
+ - main
install:
- - yarn install --immutable --immutable-cache --check-cache
+ - yarn install --immutable --immutable-cache --check-cache
jobs:
- include:
- - stage: Test
- script:
- - yarn test
- - stage: Lint
- script:
- - yarn lint:ci
- - stage: Chromatic
- script:
- - bin/travis_chromatic.sh
+ include:
+ - stage: Test
+ script:
+ - yarn test
+ - stage: Lint
+ script:
+ - yarn lint:ci
+ - stage: Prettier Check
+ script:
+ - yarn prettier:check
+ - stage: Chromatic
+ script:
+ - bin/travis_chromatic.sh
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 922552cb7b..16de7a23f2 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,19 +1,19 @@
{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "type": "node",
- "name": "vscode-jest-tests",
- "request": "launch",
- "runtimeExecutable": "yarn",
- "runtimeArgs": ["run", "--inspect-brk", "jest", "--runInBand"],
- "cwd": "${workspaceFolder}",
- "console": "integratedTerminal",
- "internalConsoleOptions": "neverOpen",
- "disableOptimisticBPs": true
- }
- ]
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "name": "vscode-jest-tests",
+ "request": "launch",
+ "runtimeExecutable": "yarn",
+ "runtimeArgs": ["run", "--inspect-brk", "jest", "--runInBand"],
+ "cwd": "${workspaceFolder}",
+ "console": "integratedTerminal",
+ "internalConsoleOptions": "neverOpen",
+ "disableOptimisticBPs": true
+ }
+ ]
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 8907a15d92..31c9188c3b 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,16 +1,21 @@
{
- "editor.codeActionsOnSave": {
- "source.fixAll.eslint": true
- },
- "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
- "editor.formatOnSave": true,
- "typescript.tsdk": ".yarn/sdks/typescript/lib",
- "search.exclude": {
- "**/.yarn": true,
- "**/.pnp.*": true
- },
- "eslint.nodePath": ".yarn/sdks",
- "prettier.prettierPath": ".yarn/sdks/prettier/index.js",
- "typescript.enablePromptUseWorkspaceTsdk": true,
- "jest.pathToJest": "yarn jest"
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": true
+ },
+ "eslint.validate": [
+ "javascript",
+ "javascriptreact",
+ "typescript",
+ "typescriptreact"
+ ],
+ "editor.formatOnSave": true,
+ "typescript.tsdk": ".yarn/sdks/typescript/lib",
+ "search.exclude": {
+ "**/.yarn": true,
+ "**/.pnp.*": true
+ },
+ "eslint.nodePath": ".yarn/sdks",
+ "prettier.prettierPath": ".yarn/sdks/prettier/index.js",
+ "typescript.enablePromptUseWorkspaceTsdk": true,
+ "jest.pathToJest": "yarn jest"
}
diff --git a/.yarnrc.yml b/.yarnrc.yml
index 416372e15a..1d3ccdbf89 100644
--- a/.yarnrc.yml
+++ b/.yarnrc.yml
@@ -1,5 +1,5 @@
plugins:
- - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
- spec: '@yarnpkg/plugin-interactive-tools'
+ - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
+ spec: '@yarnpkg/plugin-interactive-tools'
yarnPath: .yarn/releases/yarn-berry.cjs
diff --git a/README.md b/README.md
index ea24652151..48df9f4913 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the
To learn more about Next.js, take a look at the following resources:
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/zeit/next.js/) - your feedback and contributions are welcome!
diff --git a/__tests__/pages/accountLists/[accountListId]/tasks.test.tsx b/__tests__/pages/accountLists/[accountListId]/tasks.test.tsx
index f197af665e..1f7f802fd3 100644
--- a/__tests__/pages/accountLists/[accountListId]/tasks.test.tsx
+++ b/__tests__/pages/accountLists/[accountListId]/tasks.test.tsx
@@ -1,55 +1,69 @@
import { initialFilterFromPath } from '../../../../pages/accountLists/[accountListId]/tasks';
describe('tasks', () => {
- describe('initialFilterFromPath', () => {
- it('returns completed', () => {
- expect(initialFilterFromPath('/tasks?completed=true')).toEqual({ completed: true });
- });
- it('returns wildcardSearch', () => {
- expect(initialFilterFromPath('/tasks?wildcardSearch=true+words')).toEqual({ wildcardSearch: 'true words' });
- });
- it('returns startAt[max]', () => {
- expect(initialFilterFromPath('/tasks?startAt[max]=2020-10-19')).toEqual({
- startAt: { max: '2020-10-19' },
- });
- });
+ describe('initialFilterFromPath', () => {
+ it('returns completed', () => {
+ expect(initialFilterFromPath('/tasks?completed=true')).toEqual({
+ completed: true,
+ });
+ });
+ it('returns wildcardSearch', () => {
+ expect(
+ initialFilterFromPath('/tasks?wildcardSearch=true+words'),
+ ).toEqual({ wildcardSearch: 'true words' });
+ });
+ it('returns startAt[max]', () => {
+ expect(initialFilterFromPath('/tasks?startAt[max]=2020-10-19')).toEqual({
+ startAt: { max: '2020-10-19' },
+ });
+ });
- it('returns startAt[min]', () => {
- expect(initialFilterFromPath('/tasks?startAt[min]=2020-10-19')).toEqual({
- startAt: { min: '2020-10-19' },
- });
- });
+ it('returns startAt[min]', () => {
+ expect(initialFilterFromPath('/tasks?startAt[min]=2020-10-19')).toEqual({
+ startAt: { min: '2020-10-19' },
+ });
+ });
- it('returns startAt[max] and startAt[min]', () => {
- expect(initialFilterFromPath('/tasks?startAt[min]=2020-05-19&startAt[max]=2020-10-19')).toEqual({
- startAt: { min: '2020-05-19', max: '2020-10-19' },
- });
- });
+ it('returns startAt[max] and startAt[min]', () => {
+ expect(
+ initialFilterFromPath(
+ '/tasks?startAt[min]=2020-05-19&startAt[max]=2020-10-19',
+ ),
+ ).toEqual({
+ startAt: { min: '2020-05-19', max: '2020-10-19' },
+ });
+ });
- it('returns userIds', () => {
- expect(initialFilterFromPath('/tasks?userIds[]=abc&userIds[]=def')).toEqual({
- userIds: ['abc', 'def'],
- });
- });
+ it('returns userIds', () => {
+ expect(
+ initialFilterFromPath('/tasks?userIds[]=abc&userIds[]=def'),
+ ).toEqual({
+ userIds: ['abc', 'def'],
+ });
+ });
- it('returns tags', () => {
- expect(initialFilterFromPath('/tasks?tags[]=abc&tags[]=def')).toEqual({
- tags: ['abc', 'def'],
- });
- });
+ it('returns tags', () => {
+ expect(initialFilterFromPath('/tasks?tags[]=abc&tags[]=def')).toEqual({
+ tags: ['abc', 'def'],
+ });
+ });
- it('returns contactIds', () => {
- expect(initialFilterFromPath('/tasks?contactIds[]=abc&contactIds[]=def')).toEqual({
- contactIds: ['abc', 'def'],
- });
- });
+ it('returns contactIds', () => {
+ expect(
+ initialFilterFromPath('/tasks?contactIds[]=abc&contactIds[]=def'),
+ ).toEqual({
+ contactIds: ['abc', 'def'],
+ });
+ });
- it('returns activityType', () => {
- expect(
- initialFilterFromPath('/tasks?activityType[]=PARTNER_FINANCIAL&activityType[]=PARTNER_PRAYER'),
- ).toEqual({
- activityType: ['PARTNER_FINANCIAL', 'PARTNER_PRAYER'],
- });
- });
+ it('returns activityType', () => {
+ expect(
+ initialFilterFromPath(
+ '/tasks?activityType[]=PARTNER_FINANCIAL&activityType[]=PARTNER_PRAYER',
+ ),
+ ).toEqual({
+ activityType: ['PARTNER_FINANCIAL', 'PARTNER_PRAYER'],
+ });
});
+ });
});
diff --git a/__tests__/pages/api/handoff.test.ts b/__tests__/pages/api/handoff.test.ts
index 4a6ab476d9..329f06ce96 100644
--- a/__tests__/pages/api/handoff.test.ts
+++ b/__tests__/pages/api/handoff.test.ts
@@ -5,95 +5,99 @@ import handoff from '../../../pages/api/handoff';
jest.mock('next-auth/jwt', () => ({}));
describe('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/api/handoff', () => {
+ beforeEach(() => {
+ jwt.getToken = jest.fn();
+ });
+
+ it('returns 422', async () => {
+ const { req, res } = createMocks({ method: 'GET' });
+ await handoff(req, res);
+
+ expect(res._getStatusCode()).toBe(422);
+ });
+
+ describe('session', () => {
beforeEach(() => {
- jwt.getToken = jest.fn();
+ jwt.getToken = jest.fn().mockReturnValue({ token: 'accessToken' });
});
- it('returns 422', async () => {
- const { req, res } = createMocks({ method: 'GET' });
- await handoff(req, res);
-
- expect(res._getStatusCode()).toBe(422);
+ it('returns redirect', async () => {
+ const { req, res } = createMocks({
+ method: 'GET',
+ query: {
+ accountListId: 'accountListId',
+ userId: 'userId',
+ path: 'path',
+ },
+ });
+ await handoff(req, res);
+
+ expect(res._getStatusCode()).toBe(302);
+ expect(res._getRedirectUrl()).toBe(
+ 'https://stage.mpdx.org/handoff?accessToken=accessToken&accountListId=accountListId&userId=userId&path=path',
+ );
});
- describe('session', () => {
- beforeEach(() => {
- jwt.getToken = jest.fn().mockReturnValue({ token: 'accessToken' });
- });
+ it('returns redirect for auth', async () => {
+ const { req, res } = createMocks({
+ method: 'GET',
+ query: {
+ path: 'auth/user/admin',
+ auth: 'true',
+ },
+ });
+ await handoff(req, res);
+
+ expect(res._getStatusCode()).toBe(302);
+ expect(res._getRedirectUrl()).toBe(
+ 'https://auth.stage.mpdx.org/auth/user/admin?access_token=accessToken',
+ );
+ });
- it('returns redirect', async () => {
- const { req, res } = createMocks({
- method: 'GET',
- query: {
- accountListId: 'accountListId',
- userId: 'userId',
- path: 'path',
- },
- });
- await handoff(req, res);
-
- expect(res._getStatusCode()).toBe(302);
- expect(res._getRedirectUrl()).toBe(
- 'https://stage.mpdx.org/handoff?accessToken=accessToken&accountListId=accountListId&userId=userId&path=path',
- );
+ describe('SITE_URL set', () => {
+ const OLD_ENV = process.env;
+
+ beforeEach(() => {
+ jest.resetModules();
+ process.env = { ...OLD_ENV, SITE_URL: 'https://next.mpdx.org' };
+ });
+
+ afterAll(() => {
+ process.env = OLD_ENV;
+ });
+
+ it('returns redirect', async () => {
+ const { req, res } = createMocks({
+ method: 'GET',
+ query: {
+ accountListId: 'accountListId',
+ userId: 'userId',
+ path: 'path',
+ },
});
+ await handoff(req, res);
- it('returns redirect for auth', async () => {
- const { req, res } = createMocks({
- method: 'GET',
- query: {
- path: 'auth/user/admin',
- auth: 'true',
- },
- });
- await handoff(req, res);
-
- expect(res._getStatusCode()).toBe(302);
- expect(res._getRedirectUrl()).toBe('https://auth.stage.mpdx.org/auth/user/admin?access_token=accessToken');
+ expect(res._getStatusCode()).toBe(302);
+ expect(res._getRedirectUrl()).toBe(
+ 'https://mpdx.org/handoff?accessToken=accessToken&accountListId=accountListId&userId=userId&path=path',
+ );
+ });
+
+ it('returns redirect for auth', async () => {
+ const { req, res } = createMocks({
+ method: 'GET',
+ query: {
+ path: 'auth/user/admin',
+ auth: 'true',
+ },
});
+ await handoff(req, res);
- describe('SITE_URL set', () => {
- const OLD_ENV = process.env;
-
- beforeEach(() => {
- jest.resetModules();
- process.env = { ...OLD_ENV, SITE_URL: 'https://next.mpdx.org' };
- });
-
- afterAll(() => {
- process.env = OLD_ENV;
- });
-
- it('returns redirect', async () => {
- const { req, res } = createMocks({
- method: 'GET',
- query: {
- accountListId: 'accountListId',
- userId: 'userId',
- path: 'path',
- },
- });
- await handoff(req, res);
-
- expect(res._getStatusCode()).toBe(302);
- expect(res._getRedirectUrl()).toBe(
- 'https://mpdx.org/handoff?accessToken=accessToken&accountListId=accountListId&userId=userId&path=path',
- );
- });
-
- it('returns redirect for auth', async () => {
- const { req, res } = createMocks({
- method: 'GET',
- query: {
- path: 'auth/user/admin',
- auth: 'true',
- },
- });
- await handoff(req, res);
-
- expect(res._getStatusCode()).toBe(302);
- expect(res._getRedirectUrl()).toBe('https://auth.mpdx.org/auth/user/admin?access_token=accessToken');
- });
- });
+ expect(res._getStatusCode()).toBe(302);
+ expect(res._getRedirectUrl()).toBe(
+ 'https://auth.mpdx.org/auth/user/admin?access_token=accessToken',
+ );
+ });
});
+ });
});
diff --git a/__tests__/util/TestRouter.tsx b/__tests__/util/TestRouter.tsx
index fbb1ddd97a..af723fd765 100644
--- a/__tests__/util/TestRouter.tsx
+++ b/__tests__/util/TestRouter.tsx
@@ -3,37 +3,41 @@ import Router, { NextRouter, Router as IRouter } from 'next/router'; // eslint-d
import { RouterContext } from 'next/dist/next-server/lib/router-context';
interface Props {
- children: ReactNode;
- router?: Partial;
+ children: ReactNode;
+ router?: Partial;
}
const TestRouter = ({ children, router = {} }: Props): ReactElement => {
- const defaultRouter: NextRouter = {
- basePath: '',
- route: '',
- pathname: '',
- query: {},
- asPath: '',
- push: async (): Promise => true,
- replace: async (): Promise => true,
- reload: (): void => null,
- back: (): void => null,
- prefetch: async (): Promise => undefined,
- beforePopState: (): void => null,
- isFallback: false,
- isReady: false,
- events: {
- on: (): void => null,
- off: (): void => null,
- emit: (): void => null,
- },
- };
+ const defaultRouter: NextRouter = {
+ basePath: '',
+ route: '',
+ pathname: '',
+ query: {},
+ asPath: '',
+ push: async (): Promise => true,
+ replace: async (): Promise => true,
+ reload: (): void => null,
+ back: (): void => null,
+ prefetch: async (): Promise => undefined,
+ beforePopState: (): void => null,
+ isFallback: false,
+ isReady: false,
+ events: {
+ on: (): void => null,
+ off: (): void => null,
+ emit: (): void => null,
+ },
+ };
- const configuredRouter = { ...defaultRouter, ...router };
+ const configuredRouter = { ...defaultRouter, ...router };
- Router.router = configuredRouter as IRouter;
+ Router.router = configuredRouter as IRouter;
- return {children};
+ return (
+
+ {children}
+
+ );
};
export default TestRouter;
diff --git a/__tests__/util/TestWrapper.tsx b/__tests__/util/TestWrapper.tsx
index 5f04a21bde..612a1127dc 100644
--- a/__tests__/util/TestWrapper.tsx
+++ b/__tests__/util/TestWrapper.tsx
@@ -9,35 +9,35 @@ import { AppState } from '../../src/components/App/rootReducer';
import TestRouter from './TestRouter';
interface Props {
- mocks?: MockedResponse[];
- children: ReactNode;
- initialState?: Partial;
- disableAppProvider?: boolean;
- cache?: InMemoryCache;
+ mocks?: MockedResponse[];
+ children: ReactNode;
+ initialState?: Partial;
+ disableAppProvider?: boolean;
+ cache?: InMemoryCache;
}
const TestWrapper = ({
- mocks = [],
- children,
- initialState = { accountListId: 'abc' },
- disableAppProvider = false,
- cache = new InMemoryCache({ addTypename: false }),
+ mocks = [],
+ children,
+ initialState = { accountListId: 'abc' },
+ disableAppProvider = false,
+ cache = new InMemoryCache({ addTypename: false }),
}: Props): ReactElement => {
- return (
-
-
-
-
- {disableAppProvider ? (
- <>{children}>
- ) : (
- {children}
- )}
-
-
-
-
- );
+ return (
+
+
+
+
+ {disableAppProvider ? (
+ <>{children}>
+ ) : (
+ {children}
+ )}
+
+
+
+
+ );
};
export default TestWrapper;
diff --git a/__tests__/util/fileMock.js b/__tests__/util/fileMock.js
index 2fa3141d4d..192b18b37b 100644
--- a/__tests__/util/fileMock.js
+++ b/__tests__/util/fileMock.js
@@ -1,7 +1,7 @@
const path = require('path');
module.exports = {
- process(_src, filename, _config, _options) {
- return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
- },
+ process(_src, filename, _config, _options) {
+ return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';';
+ },
};
diff --git a/__tests__/util/globalSetup.ts b/__tests__/util/globalSetup.ts
index 8999e19e89..690fccb203 100644
--- a/__tests__/util/globalSetup.ts
+++ b/__tests__/util/globalSetup.ts
@@ -1,5 +1,5 @@
const globalSetup = (): void => {
- process.env.TZ = 'UTC';
+ process.env.TZ = 'UTC';
};
export default globalSetup;
diff --git a/__tests__/util/matchMediaMock.ts b/__tests__/util/matchMediaMock.ts
index 07a1e78724..23b2548e0a 100644
--- a/__tests__/util/matchMediaMock.ts
+++ b/__tests__/util/matchMediaMock.ts
@@ -1,13 +1,13 @@
import mediaQuery, { MediaValues } from 'css-mediaquery';
const matchMediaMock = (options: Partial): void => {
- window.matchMedia = (query: string): MediaQueryList => {
- return ({
- matches: mediaQuery.match(query, options),
- addListener: jest.fn(),
- removeListener: jest.fn(),
- } as unknown) as MediaQueryList;
- };
+ window.matchMedia = (query: string): MediaQueryList => {
+ return ({
+ matches: mediaQuery.match(query, options),
+ addListener: jest.fn(),
+ removeListener: jest.fn(),
+ } as unknown) as MediaQueryList;
+ };
};
export default matchMediaMock;
diff --git a/__tests__/util/setup.ts b/__tests__/util/setup.ts
index 491c3f3daf..8554733d3f 100644
--- a/__tests__/util/setup.ts
+++ b/__tests__/util/setup.ts
@@ -1,13 +1,13 @@
import '@testing-library/jest-dom';
window.document.createRange = (): Range =>
- (({
- setStart: jest.fn(),
- setEnd: jest.fn(),
- commonAncestorContainer: ({
- nodeName: 'BODY',
- ownerDocument: document,
- } as unknown) as Node,
- } as unknown) as Range);
+ (({
+ setStart: jest.fn(),
+ setEnd: jest.fn(),
+ commonAncestorContainer: ({
+ nodeName: 'BODY',
+ ownerDocument: document,
+ } as unknown) as Node,
+ } as unknown) as Range);
window.HTMLElement.prototype.scrollIntoView = jest.fn();
diff --git a/__tests__/util/testingLibraryReactMock.tsx b/__tests__/util/testingLibraryReactMock.tsx
index 8a217287a0..4e7aa24c6c 100644
--- a/__tests__/util/testingLibraryReactMock.tsx
+++ b/__tests__/util/testingLibraryReactMock.tsx
@@ -5,17 +5,19 @@ import i18n from '../../src/lib/i18n';
import translation from '../../public/locales/en/translation.json';
interface Props {
- children: ReactNode;
+ children: ReactNode;
}
i18n.addResourceBundle('en', 'translation', translation);
const Wrapper = ({ children }: Props): ReactElement => {
- return {children};
+ return {children};
};
-const customRender = (ui: ReactElement, options?: Omit): RenderResult =>
- render(ui, { wrapper: Wrapper, ...options });
+const customRender = (
+ ui: ReactElement,
+ options?: Omit,
+): RenderResult => render(ui, { wrapper: Wrapper, ...options });
export * from '@testing-library/react';
diff --git a/apollo.config.js b/apollo.config.js
index 4a9381bd39..060934b473 100644
--- a/apollo.config.js
+++ b/apollo.config.js
@@ -1,8 +1,8 @@
module.exports = {
- client: {
- service: {
- name: 'MPDX',
- url: 'https://api.stage.mpdx.org/graphql',
- },
+ client: {
+ service: {
+ name: 'MPDX',
+ url: 'https://api.stage.mpdx.org/graphql',
},
+ },
};
diff --git a/babel.config.js b/babel.config.js
index 3d3ac68e65..f94cf8370c 100644
--- a/babel.config.js
+++ b/babel.config.js
@@ -1,6 +1,6 @@
// This file is here for Jest to pick up the "next/babel" preset
module.exports = {
- presets: ['next/babel'],
- plugins: [],
+ presets: ['next/babel'],
+ plugins: [],
};
diff --git a/i18next-parser.config.js b/i18next-parser.config.js
index ccbf9cfbeb..cd61d31096 100644
--- a/i18next-parser.config.js
+++ b/i18next-parser.config.js
@@ -1,17 +1,17 @@
module.exports = {
- indentation: 4,
- lexers: {
- js: ['JsxLexer'],
- ts: ['JsxLexer'],
- jsx: ['JsxLexer'],
- tsx: ['JsxLexer'],
- default: ['JsxLexer'],
- },
- locales: ['en'],
- output: 'public/locales/$LOCALE/$NAMESPACE.json',
- input: ['src/**/*.{js,jsx,ts,tsx}'],
- verbose: true,
- nsSeparator: false,
- keySeparator: false,
- useKeysAsDefaultValue: true,
+ indentation: 4,
+ lexers: {
+ js: ['JsxLexer'],
+ ts: ['JsxLexer'],
+ jsx: ['JsxLexer'],
+ tsx: ['JsxLexer'],
+ default: ['JsxLexer'],
+ },
+ locales: ['en'],
+ output: 'public/locales/$LOCALE/$NAMESPACE.json',
+ input: ['src/**/*.{js,jsx,ts,tsx}'],
+ verbose: true,
+ nsSeparator: false,
+ keySeparator: false,
+ useKeysAsDefaultValue: true,
};
diff --git a/jest.config.js b/jest.config.js
index 377bc400b4..c520fe58cc 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,13 +1,13 @@
module.exports = {
- roots: ['/src', '/__tests__/pages'],
- globalSetup: '/__tests__/util/globalSetup.ts',
- setupFilesAfterEnv: ['/__tests__/util/setup.ts'],
- transform: {
- '\\.[jt]sx?$': 'babel-jest',
- '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
- '/__tests__/util/fileMock.js',
- '\\.(gql|graphql)$': 'jest-transform-graphql',
- },
- moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
- clearMocks: true,
+ roots: ['/src', '/__tests__/pages'],
+ globalSetup: '/__tests__/util/globalSetup.ts',
+ setupFilesAfterEnv: ['/__tests__/util/setup.ts'],
+ transform: {
+ '\\.[jt]sx?$': 'babel-jest',
+ '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
+ '/__tests__/util/fileMock.js',
+ '\\.(gql|graphql)$': 'jest-transform-graphql',
+ },
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
+ clearMocks: true,
};
diff --git a/next-env.d.ts b/next-env.d.ts
index e27519e9bc..3b580c1601 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -1,10 +1,10 @@
///
///
declare module '*.graphql' {
- import { DocumentNode } from 'graphql';
+ import { DocumentNode } from 'graphql';
- const value: DocumentNode;
- export = value;
+ const value: DocumentNode;
+ export = value;
}
declare module '*.svg';
diff --git a/next.config.js b/next.config.js
index 125c08ab47..87f8a86e05 100644
--- a/next.config.js
+++ b/next.config.js
@@ -7,38 +7,43 @@ const prod = process.env.NODE_ENV === 'production';
let SiteUrl;
if (process.env.SITE_URL) {
- SiteUrl = process.env.SITE_URL;
+ SiteUrl = process.env.SITE_URL;
} else if (process.env.VERCEL_URL) {
- SiteUrl = `https://${process.env.VERCEL_URL}`;
+ SiteUrl = `https://${process.env.VERCEL_URL}`;
} else {
- SiteUrl = 'http://localhost:3000';
+ SiteUrl = 'http://localhost:3000';
}
const withBundleAnalyzer = require('@next/bundle-analyzer')({
- enabled: process.env.ANALYZE === 'true',
+ enabled: process.env.ANALYZE === 'true',
});
module.exports = withPlugins([
- [
- withPWA,
- {
- pwa: {
- dest: 'public',
- disable: !prod,
- },
- },
- ],
- withOptimizedImages,
- withGraphql,
- withBundleAnalyzer,
+ [
+ withPWA,
{
- env: {
- JWT_SECRET: process.env.JWT_SECRET || 'aed8e0786376a2abe15f5c8f8e2ee74565d0915897b33296594bb1b549098ba7',
- API_URL: process.env.API_URL || 'https://api.stage.mpdx.org/graphql',
- SITE_URL: SiteUrl,
- CLIENT_ID: process.env.CLIENT_ID || '4027334344069527005',
- CLIENT_SECRET: process.env.CLIENT_SECRET || 'V3WBTfLMgXBuL6XNTPm13CIK7Cwvtb0VnQpeQH-Oojx6kuzaD7durA',
- BEACON_TOKEN: process.env.BEACON_TOKEN || '01b4f5f0-7fff-492a-b5ec-d536f3657d10',
- },
+ pwa: {
+ dest: 'public',
+ disable: !prod,
+ },
},
+ ],
+ withOptimizedImages,
+ withGraphql,
+ withBundleAnalyzer,
+ {
+ env: {
+ JWT_SECRET:
+ process.env.JWT_SECRET ||
+ 'aed8e0786376a2abe15f5c8f8e2ee74565d0915897b33296594bb1b549098ba7',
+ API_URL: process.env.API_URL || 'https://api.stage.mpdx.org/graphql',
+ SITE_URL: SiteUrl,
+ CLIENT_ID: process.env.CLIENT_ID || '4027334344069527005',
+ CLIENT_SECRET:
+ process.env.CLIENT_SECRET ||
+ 'V3WBTfLMgXBuL6XNTPm13CIK7Cwvtb0VnQpeQH-Oojx6kuzaD7durA',
+ BEACON_TOKEN:
+ process.env.BEACON_TOKEN || '01b4f5f0-7fff-492a-b5ec-d536f3657d10',
+ },
+ },
]);
diff --git a/onesky/download.ts b/onesky/download.ts
index 6750cc028f..f8d972a0f2 100644
--- a/onesky/download.ts
+++ b/onesky/download.ts
@@ -3,46 +3,60 @@ const fs = require('fs');
const onesky = require('@brainly/onesky-utils');
const options = {
- secret: process.env.ONESKY_API_SECRET,
- apiKey: process.env.ONESKY_API_KEY,
- projectId: '367075',
+ secret: process.env.ONESKY_API_SECRET,
+ apiKey: process.env.ONESKY_API_KEY,
+ projectId: '367075',
};
interface OneSkyLanguage {
- code: string;
- translation_progress: string;
+ code: string;
+ translation_progress: string;
}
interface OneSkyFile {
- file_name: string;
- string_count: number;
+ file_name: string;
+ string_count: number;
}
const getLanguages = async (): Promise => {
- const { data: languages }: { data: OneSkyLanguage[] } = JSON.parse(await onesky.getLanguages(options));
- return languages.filter(({ code, translation_progress }) => parseFloat(translation_progress) > 0 && code !== 'en');
+ const { data: languages }: { data: OneSkyLanguage[] } = JSON.parse(
+ await onesky.getLanguages(options),
+ );
+ return languages.filter(
+ ({ code, translation_progress }) =>
+ parseFloat(translation_progress) > 0 && code !== 'en',
+ );
};
const getFiles = async (): Promise => {
- const { data: files }: { data: OneSkyFile[] } = JSON.parse(await onesky.getFiles(options));
- return files.filter(({ string_count, file_name }) => string_count > 0 && file_name !== 'Manually input');
+ const { data: files }: { data: OneSkyFile[] } = JSON.parse(
+ await onesky.getFiles(options),
+ );
+ return files.filter(
+ ({ string_count, file_name }) =>
+ string_count > 0 && file_name !== 'Manually input',
+ );
};
const store = async (language: string, fileName: string): Promise => {
- const content = await onesky.getFile({ ...options, language, fileName });
- if (!fs.existsSync(`public/locales/${language}`)) await fs.promises.mkdir(`public/locales/${language}`);
- await fs.promises.writeFile(`public/locales/${language}/${fileName}`, content);
+ const content = await onesky.getFile({ ...options, language, fileName });
+ if (!fs.existsSync(`public/locales/${language}`))
+ await fs.promises.mkdir(`public/locales/${language}`);
+ await fs.promises.writeFile(
+ `public/locales/${language}/${fileName}`,
+ content,
+ );
};
const download = async (): Promise => {
- const languages = await getLanguages();
- const files = await getFiles();
- console.log(languages, files);
- languages.forEach(({ code }) => {
- files.forEach(({ file_name }) => {
- store(code, file_name);
- });
+ const languages = await getLanguages();
+ const files = await getFiles();
+ console.log(languages, files);
+ languages.forEach(({ code }) => {
+ files.forEach(({ file_name }) => {
+ store(code, file_name);
});
+ });
};
download();
diff --git a/onesky/tsconfig.json b/onesky/tsconfig.json
index e94bc3e9ad..3b3f8cedad 100644
--- a/onesky/tsconfig.json
+++ b/onesky/tsconfig.json
@@ -1,6 +1,6 @@
{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "isolatedModules": false
- }
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "isolatedModules": false
+ }
}
diff --git a/onesky/upload.ts b/onesky/upload.ts
index 99e6445768..244fabe324 100644
--- a/onesky/upload.ts
+++ b/onesky/upload.ts
@@ -3,20 +3,20 @@ const glob = require('glob');
const onesky = require('@brainly/onesky-utils');
const options = {
- secret: process.env.ONESKY_API_SECRET,
- apiKey: process.env.ONESKY_API_KEY,
- projectId: '367075',
- format: 'HIERARCHICAL_JSON',
- keepStrings: false,
- language: 'en',
+ secret: process.env.ONESKY_API_SECRET,
+ apiKey: process.env.ONESKY_API_KEY,
+ projectId: '367075',
+ format: 'HIERARCHICAL_JSON',
+ keepStrings: false,
+ language: 'en',
};
glob('public/locales/en/*.json', (_er, paths) => {
- paths.forEach((path: string) => {
- const content = fs.readFileSync(path, 'utf8').toString();
- const fileName = path.split('/').pop();
- onesky.postFile({ ...options, content, fileName });
- });
+ paths.forEach((path: string) => {
+ const content = fs.readFileSync(path, 'utf8').toString();
+ const fileName = path.split('/').pop();
+ onesky.postFile({ ...options, content, fileName });
+ });
});
export {};
diff --git a/package.json b/package.json
index d696b77ec0..d96f1e6539 100644
--- a/package.json
+++ b/package.json
@@ -1,133 +1,135 @@
{
- "name": "mpdx-react",
- "version": "0.1.0",
- "private": true,
- "scripts": {
- "start": "next dev",
- "build": "next build",
- "serve": "next start",
- "lint": "tsc && eslint '*/**/*.{js,ts,tsx}' --quiet --fix",
- "lint:ci": "tsc && eslint '*/**/*.{js,ts,tsx}'",
- "storybook": "start-storybook -p 6006 -c .storybook -s ./public",
- "build-storybook": "build-storybook -c .storybook -s ./public",
- "test": "cross-env NODE_ICU_DATA=$(yarn bin node-full-icu-path) jest --silent",
- "test:watch": "cross-env NODE_ICU_DATA=$(yarn bin node-full-icu-path) jest --watch",
- "test:coverage": "cross-env NODE_ICU_DATA=$(yarn bin node-full-icu-path) jest --coverage",
- "chromatic": "chromatic",
- "extract": "i18next --config i18next-parser.config.js"
- },
- "dependencies": {
- "@apollo/client": "^3.3.9",
- "@apollo/link-context": "^2.0.0-beta.3",
- "@babel/runtime": "^7.12.13",
- "@date-io/core": "^1.3.13",
- "@date-io/date-fns": "^1.3.13",
- "@material-ui/core": "^4.11.3",
- "@material-ui/icons": "^4.11.2",
- "@material-ui/lab": "^4.0.0-alpha.57",
- "@material-ui/pickers": "^3.2.10",
- "apollo-cache-persist": "^0.1.1",
- "axios": "^0.21.1",
- "clsx": "^1.1.1",
- "date-fns": "^2.17.0",
- "formik": "^2.2.6",
- "framer-motion": "^3.3.0",
- "graphql": "^15.5.0",
- "graphql-tag": "^2.12.0",
- "i18next": "^19.8.7",
- "i18next-browser-languagedetector": "^6.0.1",
- "i18next-http-backend": "^1.1.0",
- "imagemin-svgo": "^8.0.0",
- "isomorphic-fetch": "^3.0.0",
- "lodash": "^4.17.20",
- "moment": "^2.29.1",
- "mui-datatables": "^3.7.6",
- "next": "^10.0.6",
- "next-auth": "^3.4.1",
- "next-compose-plugins": "^2.2.1",
- "next-optimized-images": "^2.6.2",
- "next-plugin-graphql": "0.0.2",
- "next-pwa": "^5.0.5",
- "notistack": "^1.0.3",
- "query-string": "^6.14.0",
- "react": "17.0.1",
- "react-dom": "17.0.1",
- "react-i18next": "^11.8.6",
- "recharts": "^2.0.6",
- "uuid": "^8.3.2",
- "yup": "^0.32.8"
- },
- "devDependencies": {
- "@babel/core": "^7.12.16",
- "@brainly/onesky-utils": "^1.4.1",
- "@next/bundle-analyzer": "^10.0.6",
- "@react-dnd/invariant": "^2.0.0",
- "@storybook/addon-actions": "^6.1.17",
- "@storybook/addon-knobs": "^6.1.17",
- "@storybook/addon-viewport": "^6.1.17",
- "@storybook/react": "^6.1.17",
- "@testing-library/dom": "^7.29.4",
- "@testing-library/jest-dom": "^5.11.9",
- "@testing-library/react": "^11.2.5",
- "@testing-library/user-event": "^12.7.0",
- "@types/axios": "^0.14.0",
- "@types/css-mediaquery": "^0.1.0",
- "@types/faker": "^5.1.6",
- "@types/jest": "^26.0.20",
- "@types/lodash": "^4.14.168",
- "@types/mui-datatables": "^3.7.0",
- "@types/next-auth": "^3.1.24",
- "@types/node": "^14.14.26",
- "@types/query-string": "^6.3.0",
- "@types/react": "^17.0.1",
- "@types/testing-library__jest-dom": "^5.9.5",
- "@types/uuid": "^8.3.0",
- "@types/yup": "^0.29.11",
- "@typescript-eslint/eslint-plugin": "^4.15.0",
- "@typescript-eslint/parser": "^4.15.0",
- "babel-loader": "^8.2.2",
- "babel-preset-react-app": "^10.0.0",
- "chromatic": "^5.6.2",
- "core-js": "^3.8.3",
- "cross-env": "^7.0.3",
- "css-mediaquery": "^0.1.2",
- "eslint": "^7.19.0",
- "eslint-config-prettier": "^7.2.0",
- "eslint-import-resolver-node": "^0.3.4",
- "eslint-plugin-import": "^2.22.1",
- "eslint-plugin-jest": "^24.1.3",
- "eslint-plugin-prettier": "^3.3.1",
- "eslint-plugin-react": "^7.22.0",
- "file-loader": "^6.2.0",
- "full-icu": "^1.3.1",
- "glob": "^7.1.6",
- "husky": "^5.0.9",
- "i18next-parser": "^3.6.0",
- "imagemin": "^7.0.1",
- "img-loader": "3.0.2",
- "jest": "^26.6.3",
- "jest-environment-jsdom-sixteen": "^1.0.3",
- "jest-transform-graphql": "^2.1.0",
- "lint-staged": "^10.5.4",
- "mockdate": "^3.0.2",
- "node-mocks-http": "^1.10.1",
- "prettier": "^2.2.1",
- "prop-types": "^15.7.2",
- "regenerator-runtime": "^0.13.7",
- "storybook-addon-i18next": "^1.3.0",
- "typescript": "^4.1.5",
- "url-loader": "4.1.1",
- "webpack": "^4.46.0"
- },
- "husky": {
- "hooks": {
- "pre-commit": "tsc --noEmit && lint-staged"
- }
- },
- "lint-staged": {
- "*.{js,ts,tsx}": [
- "eslint --fix",
- "git add"
- ]
+ "name": "mpdx-react",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "start": "next dev",
+ "build": "next build",
+ "serve": "next start",
+ "lint": "tsc && eslint '*/**/*.{js,ts,tsx}' --quiet --fix",
+ "lint:ci": "tsc && eslint '*/**/*.{js,ts,tsx}'",
+ "storybook": "start-storybook -p 6006 -c .storybook -s ./public",
+ "build-storybook": "build-storybook -c .storybook -s ./public",
+ "test": "cross-env NODE_ICU_DATA=$(yarn bin node-full-icu-path) jest --silent",
+ "test:watch": "cross-env NODE_ICU_DATA=$(yarn bin node-full-icu-path) jest --watch",
+ "test:coverage": "cross-env NODE_ICU_DATA=$(yarn bin node-full-icu-path) jest --coverage",
+ "chromatic": "chromatic",
+ "extract": "i18next --config i18next-parser.config.js",
+ "prettier:check": "prettier . --list-different",
+ "prettier:write": "prettier . --write"
+ },
+ "dependencies": {
+ "@apollo/client": "^3.3.9",
+ "@apollo/link-context": "^2.0.0-beta.3",
+ "@babel/runtime": "^7.12.13",
+ "@date-io/core": "^1.3.13",
+ "@date-io/date-fns": "^1.3.13",
+ "@material-ui/core": "^4.11.3",
+ "@material-ui/icons": "^4.11.2",
+ "@material-ui/lab": "^4.0.0-alpha.57",
+ "@material-ui/pickers": "^3.2.10",
+ "apollo-cache-persist": "^0.1.1",
+ "axios": "^0.21.1",
+ "clsx": "^1.1.1",
+ "date-fns": "^2.17.0",
+ "formik": "^2.2.6",
+ "framer-motion": "^3.3.0",
+ "graphql": "^15.5.0",
+ "graphql-tag": "^2.12.0",
+ "i18next": "^19.8.7",
+ "i18next-browser-languagedetector": "^6.0.1",
+ "i18next-http-backend": "^1.1.0",
+ "imagemin-svgo": "^8.0.0",
+ "isomorphic-fetch": "^3.0.0",
+ "lodash": "^4.17.20",
+ "moment": "^2.29.1",
+ "mui-datatables": "^3.7.6",
+ "next": "^10.0.6",
+ "next-auth": "^3.4.1",
+ "next-compose-plugins": "^2.2.1",
+ "next-optimized-images": "^2.6.2",
+ "next-plugin-graphql": "0.0.2",
+ "next-pwa": "^5.0.5",
+ "notistack": "^1.0.3",
+ "query-string": "^6.14.0",
+ "react": "17.0.1",
+ "react-dom": "17.0.1",
+ "react-i18next": "^11.8.6",
+ "recharts": "^2.0.6",
+ "uuid": "^8.3.2",
+ "yup": "^0.32.8"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.12.16",
+ "@brainly/onesky-utils": "^1.4.1",
+ "@next/bundle-analyzer": "^10.0.6",
+ "@react-dnd/invariant": "^2.0.0",
+ "@storybook/addon-actions": "^6.1.17",
+ "@storybook/addon-knobs": "^6.1.17",
+ "@storybook/addon-viewport": "^6.1.17",
+ "@storybook/react": "^6.1.17",
+ "@testing-library/dom": "^7.29.4",
+ "@testing-library/jest-dom": "^5.11.9",
+ "@testing-library/react": "^11.2.5",
+ "@testing-library/user-event": "^12.7.0",
+ "@types/axios": "^0.14.0",
+ "@types/css-mediaquery": "^0.1.0",
+ "@types/faker": "^5.1.6",
+ "@types/jest": "^26.0.20",
+ "@types/lodash": "^4.14.168",
+ "@types/mui-datatables": "^3.7.0",
+ "@types/next-auth": "^3.1.24",
+ "@types/node": "^14.14.26",
+ "@types/query-string": "^6.3.0",
+ "@types/react": "^17.0.1",
+ "@types/testing-library__jest-dom": "^5.9.5",
+ "@types/uuid": "^8.3.0",
+ "@types/yup": "^0.29.11",
+ "@typescript-eslint/eslint-plugin": "^4.15.0",
+ "@typescript-eslint/parser": "^4.15.0",
+ "babel-loader": "^8.2.2",
+ "babel-preset-react-app": "^10.0.0",
+ "chromatic": "^5.6.2",
+ "core-js": "^3.8.3",
+ "cross-env": "^7.0.3",
+ "css-mediaquery": "^0.1.2",
+ "eslint": "^7.19.0",
+ "eslint-config-prettier": "^7.2.0",
+ "eslint-import-resolver-node": "^0.3.4",
+ "eslint-plugin-import": "^2.22.1",
+ "eslint-plugin-jest": "^24.1.3",
+ "eslint-plugin-prettier": "^3.3.1",
+ "eslint-plugin-react": "^7.22.0",
+ "file-loader": "^6.2.0",
+ "full-icu": "^1.3.1",
+ "glob": "^7.1.6",
+ "husky": "^5.0.9",
+ "i18next-parser": "^3.6.0",
+ "imagemin": "^7.0.1",
+ "img-loader": "3.0.2",
+ "jest": "^26.6.3",
+ "jest-environment-jsdom-sixteen": "^1.0.3",
+ "jest-transform-graphql": "^2.1.0",
+ "lint-staged": "^10.5.4",
+ "mockdate": "^3.0.2",
+ "node-mocks-http": "^1.10.1",
+ "prettier": "^2.2.1",
+ "prop-types": "^15.7.2",
+ "regenerator-runtime": "^0.13.7",
+ "storybook-addon-i18next": "^1.3.0",
+ "typescript": "^4.1.5",
+ "url-loader": "4.1.1",
+ "webpack": "^4.46.0"
+ },
+ "husky": {
+ "hooks": {
+ "pre-commit": "tsc --noEmit && lint-staged"
}
+ },
+ "lint-staged": {
+ "*.{js,ts,tsx}": [
+ "eslint --fix",
+ "git add"
+ ]
+ }
}
diff --git a/pages/_app.tsx b/pages/_app.tsx
index 99848aeb9a..cb5843df26 100644
--- a/pages/_app.tsx
+++ b/pages/_app.tsx
@@ -19,71 +19,92 @@ import i18n from '../src/lib/i18n';
import { AppProvider } from '../src/components/App';
const handleExitComplete = (): void => {
- if (typeof window !== 'undefined') {
- window.scrollTo({ top: 0 });
- }
+ if (typeof window !== 'undefined') {
+ window.scrollTo({ top: 0 });
+ }
};
export type PageWithLayout = NextPage & {
- layout?: ({ children }) => ReactElement;
+ layout?: ({ children }) => ReactElement;
};
const App = ({ Component, pageProps, router }: AppProps): ReactElement => {
- const { session } = pageProps;
- const Layout = (Component as PageWithLayout).layout || PrimaryLayout;
+ const { session } = pageProps;
+ const Layout = (Component as PageWithLayout).layout || PrimaryLayout;
- // useEffect(() => {
- // // Remove the server-side injected CSS.
- // const jssStyles = document.querySelector('#jss-server-side');
- // if (jssStyles) {
- // jssStyles.parentElement.removeChild(jssStyles);
- // }
- // }, []);
+ // useEffect(() => {
+ // // Remove the server-side injected CSS.
+ // const jssStyles = document.querySelector('#jss-server-side');
+ // if (jssStyles) {
+ // jssStyles.parentElement.removeChild(jssStyles);
+ // }
+ // }, []);
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- );
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
};
export default App;
diff --git a/pages/_document.tsx b/pages/_document.tsx
index c4278d6672..d1b9f8db4a 100644
--- a/pages/_document.tsx
+++ b/pages/_document.tsx
@@ -1,64 +1,73 @@
import React, { ReactElement } from 'react';
-import Document, { Head, Main, NextScript, DocumentInitialProps } from 'next/document';
+import Document, {
+ Head,
+ Main,
+ NextScript,
+ DocumentInitialProps,
+} from 'next/document';
import { ServerStyleSheets } from '@material-ui/core/styles';
import { RenderPageResult } from 'next/dist/next-server/lib/utils';
import theme from '../src/theme';
class MyDocument extends Document {
- render(): ReactElement {
- return (
-
-
-
-
-
-
-
-
-
- );
- }
+ render(): ReactElement {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+ }
}
MyDocument.getInitialProps = async (ctx): Promise => {
- // Resolution order
- //
- // On the server:
- // 1. app.getInitialProps
- // 2. page.getInitialProps
- // 3. document.getInitialProps
- // 4. app.render
- // 5. page.render
- // 6. document.render
- //
- // On the server with error:
- // 1. document.getInitialProps
- // 2. app.render
- // 3. page.render
- // 4. document.render
- //
- // On the client
- // 1. app.getInitialProps
- // 2. page.getInitialProps
- // 3. app.render
- // 4. page.render
+ // Resolution order
+ //
+ // On the server:
+ // 1. app.getInitialProps
+ // 2. page.getInitialProps
+ // 3. document.getInitialProps
+ // 4. app.render
+ // 5. page.render
+ // 6. document.render
+ //
+ // On the server with error:
+ // 1. document.getInitialProps
+ // 2. app.render
+ // 3. page.render
+ // 4. document.render
+ //
+ // On the client
+ // 1. app.getInitialProps
+ // 2. page.getInitialProps
+ // 3. app.render
+ // 4. page.render
- // Render app and page and get the context of the page with collected side effects.
- const sheets = new ServerStyleSheets();
- const originalRenderPage = ctx.renderPage;
+ // Render app and page and get the context of the page with collected side effects.
+ const sheets = new ServerStyleSheets();
+ const originalRenderPage = ctx.renderPage;
- ctx.renderPage = (): RenderPageResult | Promise =>
- originalRenderPage({
- enhanceApp: (App) => (props): ReactElement => sheets.collect(),
- });
+ ctx.renderPage = (): RenderPageResult | Promise =>
+ originalRenderPage({
+ enhanceApp: (App) => (props): ReactElement =>
+ sheets.collect(),
+ });
- const initialProps = await Document.getInitialProps(ctx);
+ const initialProps = await Document.getInitialProps(ctx);
- return {
- ...initialProps,
- // Styles fragment is rendered after the app and page rendering finish.
- styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
- };
+ return {
+ ...initialProps,
+ // Styles fragment is rendered after the app and page rendering finish.
+ styles: [
+ ...React.Children.toArray(initialProps.styles),
+ sheets.getStyleElement(),
+ ],
+ };
};
export default MyDocument;
diff --git a/pages/accountLists.tsx b/pages/accountLists.tsx
index 800519a3fc..6fd75ed5d6 100644
--- a/pages/accountLists.tsx
+++ b/pages/accountLists.tsx
@@ -11,68 +11,75 @@ import BaseLayout from '../src/components/Layouts/Basic';
import { useApp } from '../src/components/App';
export const GET_ACCOUNT_LISTS_QUERY = gql`
- query GetAccountListsQuery {
- accountLists {
- nodes {
- id
- name
- monthlyGoal
- receivedPledges
- totalPledges
- currency
- }
- }
+ query GetAccountListsQuery {
+ accountLists {
+ nodes {
+ id
+ name
+ monthlyGoal
+ receivedPledges
+ totalPledges
+ currency
+ }
}
+ }
`;
interface Props {
- data: GetAccountListsQuery;
+ data: GetAccountListsQuery;
}
const AccountListsPage = ({ data }: Props): ReactElement => {
- const { dispatch } = useApp();
- const { t } = useTranslation();
+ const { dispatch } = useApp();
+ const { t } = useTranslation();
- useEffect(() => {
- dispatch({ type: 'updateBreadcrumb', breadcrumb: t('Dashboard') });
- }, []);
+ useEffect(() => {
+ dispatch({ type: 'updateBreadcrumb', breadcrumb: t('Dashboard') });
+ }, []);
- return (
- <>
-
- MPDX | {t('Account Lists')}
-
-
- >
- );
+ return (
+ <>
+
+ MPDX | {t('Account Lists')}
+
+
+ >
+ );
};
AccountListsPage.layout = BaseLayout;
export const getServerSideProps: GetServerSideProps = async ({
- res,
- req,
+ res,
+ req,
}): Promise> => {
- const session = await getSession({ req });
+ const session = await getSession({ req });
- if (!session?.user['token']) {
- res.writeHead(302, { Location: '/' });
- res.end();
- return { props: {} };
- }
+ if (!session?.user['token']) {
+ res.writeHead(302, { Location: '/' });
+ res.end();
+ return { props: {} };
+ }
- const client = await ssrClient(session?.user['token']);
- const response = await client.query({ query: GET_ACCOUNT_LISTS_QUERY });
+ const client = await ssrClient(session?.user['token']);
+ const response = await client.query({
+ query: GET_ACCOUNT_LISTS_QUERY,
+ });
- if (response.data.accountLists.nodes && response.data.accountLists.nodes.length == 1) {
- res.writeHead(302, { Location: `/accountLists/${response.data.accountLists.nodes[0].id}` });
- res.end();
- return { props: {} };
- }
+ if (
+ response.data.accountLists.nodes &&
+ response.data.accountLists.nodes.length == 1
+ ) {
+ res.writeHead(302, {
+ Location: `/accountLists/${response.data.accountLists.nodes[0].id}`,
+ });
+ res.end();
+ return { props: {} };
+ }
- return {
- props: { data: response.data },
- };
+ return {
+ props: { data: response.data },
+ };
};
export default AccountListsPage;
diff --git a/pages/accountLists/[accountListId].tsx b/pages/accountLists/[accountListId].tsx
index 150af09c83..0382e3b400 100644
--- a/pages/accountLists/[accountListId].tsx
+++ b/pages/accountLists/[accountListId].tsx
@@ -11,83 +11,90 @@ import { ssrClient } from '../../src/lib/client';
import { useApp } from '../../src/components/App';
export const GET_DASHBOARD_QUERY = gql`
- query GetDashboardQuery($accountListId: ID!) {
- user {
- firstName
- }
- accountList(id: $accountListId) {
- name
- monthlyGoal
- receivedPledges
- totalPledges
- currency
- balance
- }
- reportsDonationHistories(accountListId: $accountListId) {
- averageIgnoreCurrent
- periods {
- startDate
- convertedTotal
- totals {
- currency
- convertedAmount
- }
- }
+ query GetDashboardQuery($accountListId: ID!) {
+ user {
+ firstName
+ }
+ accountList(id: $accountListId) {
+ name
+ monthlyGoal
+ receivedPledges
+ totalPledges
+ currency
+ balance
+ }
+ reportsDonationHistories(accountListId: $accountListId) {
+ averageIgnoreCurrent
+ periods {
+ startDate
+ convertedTotal
+ totals {
+ currency
+ convertedAmount
}
+ }
}
+ }
`;
interface Props {
- data: GetDashboardQuery;
- accountListId: string;
+ data: GetDashboardQuery;
+ accountListId: string;
}
const AccountListIdPage = ({ data, accountListId }: Props): ReactElement => {
- const { dispatch } = useApp();
- const { t } = useTranslation();
+ const { dispatch } = useApp();
+ const { t } = useTranslation();
- useEffect(() => {
- dispatch({ type: 'updateBreadcrumb', breadcrumb: t('Dashboard') });
- dispatch({ type: 'updateAccountListId', accountListId });
- }, []);
+ useEffect(() => {
+ dispatch({ type: 'updateBreadcrumb', breadcrumb: t('Dashboard') });
+ dispatch({ type: 'updateAccountListId', accountListId });
+ }, []);
- return (
- <>
-
- MPDX | {data.accountList.name}
-
-
- >
- );
+ return (
+ <>
+
+ MPDX | {data.accountList.name}
+
+
+ >
+ );
};
export const getServerSideProps: GetServerSideProps = async ({
- params,
- req,
- res,
+ params,
+ req,
+ res,
}): Promise> => {
- const session = await getSession({ req });
+ const session = await getSession({ req });
- if (!session?.user['token']) {
- res.writeHead(302, { Location: '/' });
- res.end();
- return { props: {} };
- }
+ if (!session?.user['token']) {
+ res.writeHead(302, { Location: '/' });
+ res.end();
+ return { props: {} };
+ }
- const client = await ssrClient(session?.user['token']);
- const response = await client.query({
- query: GET_DASHBOARD_QUERY,
- variables: {
- accountListId: params.accountListId,
- endOfDay: moment().endOf('day').toISOString(),
- today: moment().endOf('day').toISOString().slice(0, 10),
- twoWeeksFromNow: moment().endOf('day').add(2, 'weeks').toISOString().slice(0, 10),
- },
- });
+ const client = await ssrClient(session?.user['token']);
+ const response = await client.query({
+ query: GET_DASHBOARD_QUERY,
+ variables: {
+ accountListId: params.accountListId,
+ endOfDay: moment().endOf('day').toISOString(),
+ today: moment().endOf('day').toISOString().slice(0, 10),
+ twoWeeksFromNow: moment()
+ .endOf('day')
+ .add(2, 'weeks')
+ .toISOString()
+ .slice(0, 10),
+ },
+ });
- return {
- props: { data: response.data, accountListId: params.accountListId.toString() },
- };
+ return {
+ props: {
+ data: response.data,
+ accountListId: params.accountListId.toString(),
+ },
+ };
};
export default AccountListIdPage;
diff --git a/pages/accountLists/[accountListId]/tasks.tsx b/pages/accountLists/[accountListId]/tasks.tsx
index 7577c056b6..2a4a7aa629 100644
--- a/pages/accountLists/[accountListId]/tasks.tsx
+++ b/pages/accountLists/[accountListId]/tasks.tsx
@@ -12,81 +12,92 @@ import { TaskFilter } from '../../../src/components/Task/List/List';
import reduceObject from '../../../src/lib/reduceObject';
export const initialFilterFromPath = (path: string): TaskFilter => {
- let initialFilter = {};
- const queryString = path.split('?')[1];
+ let initialFilter = {};
+ const queryString = path.split('?')[1];
- if (queryString) {
- const filter = parse(queryString);
+ if (queryString) {
+ const filter = parse(queryString);
- initialFilter = reduceObject(
- (result: TaskFilter, value: string | string[], key: string) => {
- switch (key) {
- case 'completed':
- result.completed = value === 'true';
- break;
- case 'wildcardSearch':
- result.wildcardSearch = value.toString();
- break;
- case 'startAt[max]':
- if (!result.startAt) result.startAt = {};
- result.startAt.max = value.toString();
- break;
- case 'startAt[min]':
- if (!result.startAt) result.startAt = {};
- result.startAt.min = value.toString();
- break;
- default:
- result[key.replace('[]', '')] = castArray(value);
- }
- return result;
- },
- {},
- filter,
- );
+ initialFilter = reduceObject(
+ (result: TaskFilter, value: string | string[], key: string) => {
+ switch (key) {
+ case 'completed':
+ result.completed = value === 'true';
+ break;
+ case 'wildcardSearch':
+ result.wildcardSearch = value.toString();
+ break;
+ case 'startAt[max]':
+ if (!result.startAt) result.startAt = {};
+ result.startAt.max = value.toString();
+ break;
+ case 'startAt[min]':
+ if (!result.startAt) result.startAt = {};
+ result.startAt.min = value.toString();
+ break;
+ default:
+ result[key.replace('[]', '')] = castArray(value);
+ }
+ return result;
+ },
+ {},
+ filter,
+ );
- initialFilter = pick(
- ['userIds', 'tags', 'contactIds', 'activityType', 'completed', 'wildcardSearch', 'startAt'],
- initialFilter,
- );
+ initialFilter = pick(
+ [
+ 'userIds',
+ 'tags',
+ 'contactIds',
+ 'activityType',
+ 'completed',
+ 'wildcardSearch',
+ 'startAt',
+ ],
+ initialFilter,
+ );
- return initialFilter;
- }
+ return initialFilter;
+ }
};
const TasksPage = (): ReactElement => {
- const { dispatch } = useApp();
- const { t } = useTranslation();
- const router = useRouter();
+ const { dispatch } = useApp();
+ const { t } = useTranslation();
+ const router = useRouter();
- useEffect(() => {
- dispatch({ type: 'updateBreadcrumb', breadcrumb: t('Tasks') });
- dispatch({ type: 'updateAccountListId', accountListId: router.query.accountListId.toString() });
- }, []);
+ useEffect(() => {
+ dispatch({ type: 'updateBreadcrumb', breadcrumb: t('Tasks') });
+ dispatch({
+ type: 'updateAccountListId',
+ accountListId: router.query.accountListId.toString(),
+ });
+ }, []);
- const initialFilter = initialFilterFromPath(router.asPath);
+ const initialFilter = initialFilterFromPath(router.asPath);
- return (
- <>
-
- MPDX | {t('Tasks')}
-
-
- >
- );
+ return (
+ <>
+
+ MPDX | {t('Tasks')}
+
+
+ >
+ );
};
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
- const session = await getSession({ req });
+ const session = await getSession({ req });
- if (!session?.user['token']) {
- res.writeHead(302, { Location: '/' });
- res.end();
- return { props: {} };
- }
+ if (!session?.user['token']) {
+ res.writeHead(302, { Location: '/' });
+ res.end();
+ return { props: {} };
+ }
- return {
- props: {},
- };
+ return {
+ props: {},
+ };
};
export default TasksPage;
diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts
index e8344fb64b..b9df9ef023 100644
--- a/pages/api/auth/[...nextauth].ts
+++ b/pages/api/auth/[...nextauth].ts
@@ -3,40 +3,44 @@ import NextAuth from 'next-auth';
import { Profile } from './profile';
const options = {
- providers: [
- {
- id: 'thekey',
- name: 'The Key',
- type: 'oauth',
- version: '2.0',
- scope: 'fullticket',
- params: { grant_type: 'authorization_code' },
- accessTokenUrl: 'https://thekey.me/cas/api/oauth/token',
- authorizationUrl: 'https://thekey.me/cas/login?response_type=code',
- profileUrl: `${process.env.SITE_URL}/api/auth/profile`,
- profile: (profile: Profile): Profile => profile,
- clientId: process.env.CLIENT_ID,
- clientSecret: process.env.CLIENT_SECRET,
- state: false,
- },
- ],
- callbacks: {
- session: (session, token): Promise => {
- return Promise.resolve({ ...session, user: { ...session.user, token: token.token } });
- },
- jwt: async (token, user, _account, profile): Promise => {
- if (user) {
- return Promise.resolve({ ...token, token: profile.token });
- } else {
- return Promise.resolve(token);
- }
- },
+ providers: [
+ {
+ id: 'thekey',
+ name: 'The Key',
+ type: 'oauth',
+ version: '2.0',
+ scope: 'fullticket',
+ params: { grant_type: 'authorization_code' },
+ accessTokenUrl: 'https://thekey.me/cas/api/oauth/token',
+ authorizationUrl: 'https://thekey.me/cas/login?response_type=code',
+ profileUrl: `${process.env.SITE_URL}/api/auth/profile`,
+ profile: (profile: Profile): Profile => profile,
+ clientId: process.env.CLIENT_ID,
+ clientSecret: process.env.CLIENT_SECRET,
+ state: false,
},
- jwt: {
- secret: process.env.JWT_SECRET,
+ ],
+ callbacks: {
+ session: (session, token): Promise => {
+ return Promise.resolve({
+ ...session,
+ user: { ...session.user, token: token.token },
+ });
},
+ jwt: async (token, user, _account, profile): Promise => {
+ if (user) {
+ return Promise.resolve({ ...token, token: profile.token });
+ } else {
+ return Promise.resolve(token);
+ }
+ },
+ },
+ jwt: {
+ secret: process.env.JWT_SECRET,
+ },
};
-const Auth = (req: NextApiRequest, res: NextApiResponse): Promise => NextAuth(req, res, options);
+const Auth = (req: NextApiRequest, res: NextApiResponse): Promise =>
+ NextAuth(req, res, options);
export default Auth;
diff --git a/pages/api/auth/profile.ts b/pages/api/auth/profile.ts
index 5379814ab1..83397086a3 100644
--- a/pages/api/auth/profile.ts
+++ b/pages/api/auth/profile.ts
@@ -4,42 +4,45 @@ import { gql } from '@apollo/client';
import client from '../../../src/lib/client';
export interface Profile {
- id: string;
- name: string;
- token: string;
+ id: string;
+ name: string;
+ token: string;
}
-const profile = async (req: NextApiRequest, res: NextApiResponse): Promise => {
- const {
- data: { ticket: ticket },
- } = await Axios.get('https://thekey.me/cas/api/oauth/ticket', {
- headers: {
- Authorization: req.headers.authorization,
- Accept: 'application/json',
- },
- params: {
- service: process.env.API_URL,
- },
- });
+const profile = async (
+ req: NextApiRequest,
+ res: NextApiResponse,
+): Promise => {
+ const {
+ data: { ticket: ticket },
+ } = await Axios.get('https://thekey.me/cas/api/oauth/ticket', {
+ headers: {
+ Authorization: req.headers.authorization,
+ Accept: 'application/json',
+ },
+ params: {
+ service: process.env.API_URL,
+ },
+ });
- const response = await client.mutate({
- mutation: gql`
- mutation UserKeySignIn($ticket: String!) {
- userKeySignIn(input: { casTicket: $ticket }) {
- token
- user {
- id
- name: firstName
- }
- }
- }
- `,
- variables: {
- ticket,
- },
- });
- const { user, token } = response.data.userKeySignIn;
- res.status(200).json({ ...user, token });
+ const response = await client.mutate({
+ mutation: gql`
+ mutation UserKeySignIn($ticket: String!) {
+ userKeySignIn(input: { casTicket: $ticket }) {
+ token
+ user {
+ id
+ name: firstName
+ }
+ }
+ }
+ `,
+ variables: {
+ ticket,
+ },
+ });
+ const { user, token } = response.data.userKeySignIn;
+ res.status(200).json({ ...user, token });
};
export default profile;
diff --git a/pages/api/graphql.ts b/pages/api/graphql.ts
index d98869cb6b..d62dd436ca 100644
--- a/pages/api/graphql.ts
+++ b/pages/api/graphql.ts
@@ -2,15 +2,18 @@ import { NextApiRequest, NextApiResponse } from 'next';
import Axios from 'axios';
import jwt from 'next-auth/jwt';
-const graphql = async (req: NextApiRequest, res: NextApiResponse): Promise => {
- const jwtToken = await jwt.getToken({ req, secret: process.env.JWT_SECRET });
- const response = await Axios.post(process.env.API_URL, req.body, {
- headers: {
- Authorization: jwtToken ? `Bearer ${jwtToken['token']}` : null,
- Accept: 'application/json',
- },
- });
- res.status(200).json(response.data);
+const graphql = async (
+ req: NextApiRequest,
+ res: NextApiResponse,
+): Promise => {
+ const jwtToken = await jwt.getToken({ req, secret: process.env.JWT_SECRET });
+ const response = await Axios.post(process.env.API_URL, req.body, {
+ headers: {
+ Authorization: jwtToken ? `Bearer ${jwtToken['token']}` : null,
+ Accept: 'application/json',
+ },
+ });
+ res.status(200).json(response.data);
};
export default graphql;
diff --git a/pages/api/handoff.ts b/pages/api/handoff.ts
index 217050767d..948bce2e9e 100644
--- a/pages/api/handoff.ts
+++ b/pages/api/handoff.ts
@@ -1,30 +1,44 @@
import { NextApiRequest, NextApiResponse } from 'next';
import jwt from 'next-auth/jwt';
-const handoff = async (req: NextApiRequest, res: NextApiResponse): Promise => {
- const jwtToken = await jwt.getToken({ req, secret: process.env.JWT_SECRET });
- if (jwtToken && req.query.accountListId && req.query.userId && req.query.path && req.query.auth !== 'true') {
- const url = new URL(
- `https://${process.env.SITE_URL === 'https://next.mpdx.org' ? '' : 'stage.'}mpdx.org/handoff`,
- );
+const handoff = async (
+ req: NextApiRequest,
+ res: NextApiResponse,
+): Promise => {
+ const jwtToken = await jwt.getToken({ req, secret: process.env.JWT_SECRET });
+ if (
+ jwtToken &&
+ req.query.accountListId &&
+ req.query.userId &&
+ req.query.path &&
+ req.query.auth !== 'true'
+ ) {
+ const url = new URL(
+ `https://${
+ process.env.SITE_URL === 'https://next.mpdx.org' ? '' : 'stage.'
+ }mpdx.org/handoff`,
+ );
- url.searchParams.append('accessToken', jwtToken['token']);
- url.searchParams.append('accountListId', req.query.accountListId.toString());
- url.searchParams.append('userId', req.query.userId.toString());
- url.searchParams.append('path', req.query.path.toString());
- res.redirect(url.href);
- } else if (jwtToken && req.query.path && req.query.auth === 'true') {
- const url = new URL(
- `https://auth.${
- process.env.SITE_URL === 'https://next.mpdx.org' ? '' : 'stage.'
- }mpdx.org/${req.query.path.toString().replace(/^\/+/, '')}`,
- );
+ url.searchParams.append('accessToken', jwtToken['token']);
+ url.searchParams.append(
+ 'accountListId',
+ req.query.accountListId.toString(),
+ );
+ url.searchParams.append('userId', req.query.userId.toString());
+ url.searchParams.append('path', req.query.path.toString());
+ res.redirect(url.href);
+ } else if (jwtToken && req.query.path && req.query.auth === 'true') {
+ const url = new URL(
+ `https://auth.${
+ process.env.SITE_URL === 'https://next.mpdx.org' ? '' : 'stage.'
+ }mpdx.org/${req.query.path.toString().replace(/^\/+/, '')}`,
+ );
- url.searchParams.append('access_token', jwtToken['token']);
- res.redirect(url.href);
- } else {
- res.status(422);
- }
+ url.searchParams.append('access_token', jwtToken['token']);
+ res.redirect(url.href);
+ } else {
+ res.status(422);
+ }
};
export default handoff;
diff --git a/pages/index.tsx b/pages/index.tsx
index 5563ea90cb..b2519eea2f 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -7,17 +7,19 @@ const IndexPage = (): ReactElement => <>>;
IndexPage.layout = BaseLayout;
-export const getServerSideProps: GetServerSideProps = async (context): Promise> => {
- const session = await getSession(context);
+export const getServerSideProps: GetServerSideProps = async (
+ context,
+): Promise> => {
+ const session = await getSession(context);
- if (session) {
- context.res.writeHead(302, { Location: '/accountLists' });
- context.res.end();
- } else {
- context.res.writeHead(302, { Location: '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/login' });
- context.res.end();
- }
- return { props: {} };
+ if (session) {
+ context.res.writeHead(302, { Location: '/accountLists' });
+ context.res.end();
+ } else {
+ context.res.writeHead(302, { Location: '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/login' });
+ context.res.end();
+ }
+ return { props: {} };
};
export default IndexPage;
diff --git a/pages/login.tsx b/pages/login.tsx
index e49390231b..b62f890c95 100644
--- a/pages/login.tsx
+++ b/pages/login.tsx
@@ -9,48 +9,50 @@ import BaseLayout from '../src/components/Layouts/Basic';
import logo from '../src/images/logo.svg';
const IndexPage = (): ReactElement => (
- <>
-
- MPDX | Home
-
- }
- subtitle="MPDX is fundraising software from Cru that helps you grow and maintain your ministry
+ <>
+
+ MPDX | Home
+
+ }
+ subtitle="MPDX is fundraising software from Cru that helps you grow and maintain your ministry
partners in a quick and easy way."
- >
-
- }
- href="https://help.mpdx.org"
- target="_blank"
- rel="noopener noreferrer"
- style={{ color: '#fff' }}
- >
- Find help
-
-
- >
+ >
+
+ }
+ href="https://help.mpdx.org"
+ target="_blank"
+ rel="noopener noreferrer"
+ style={{ color: '#fff' }}
+ >
+ Find help
+
+
+ >
);
IndexPage.layout = BaseLayout;
-export const getServerSideProps: GetServerSideProps = async (context): Promise> => {
- const session = await getSession(context);
-
- if (context.res && session) {
- context.res.writeHead(302, { Location: '/accountLists' });
- context.res.end();
- return { props: {} };
- }
+export const getServerSideProps: GetServerSideProps = async (
+ context,
+): Promise> => {
+ const session = await getSession(context);
+ if (context.res && session) {
+ context.res.writeHead(302, { Location: '/accountLists' });
+ context.res.end();
return { props: {} };
+ }
+
+ return { props: {} };
};
export default IndexPage;
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index 181c699c98..0af78359fd 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -1,208 +1,208 @@
{
- "My Accounts": "My Accounts",
- "Goal": "Goal",
- "Gifts Started": "Gifts Started",
- "Committed": "Committed",
- "Account Balance": "Account Balance",
- "It may take a few days to update.": "It may take a few days to update.",
- "View Gifts": "View Gifts",
- "Average": "Average",
- "No monthly activity to show.": "No monthly activity to show.",
- "Amount ({{ currencyCode }})": "Amount ({{ currencyCode }})",
- "Monthly Goal": "Monthly Goal",
- "Commitments": "Commitments",
- "Below Goal": "Below Goal",
- "Above Goal": "Above Goal",
- "Appeals": "Appeals",
- "No primary appeal to show.": "No primary appeal to show.",
- "Gifts Received": "Gifts Received",
- "View All": "View All",
- "Late Commitments": "Late Commitments",
- "View All ({{ totalCount, number }})": "View All ({{ totalCount, number }})",
- "No late commitments to show.": "No late commitments to show.",
- "Their gift is {{ count, number }} day late.": "Their gift is {{ count, number }} day late.",
- "Their gift is {{ count, number }} day late._plural": "Their gift is {{ count, number }} days late.",
- "Partner Care": "Partner Care",
- "Prayer ({{ totalCount, number }})": "Prayer ({{ totalCount, number }})",
- "Celebrations ({{ totalCount, number }})": "Celebrations ({{ totalCount, number }})",
- "No prayer requests to show.": "No prayer requests to show.",
- "No celebrations to show.": "No celebrations to show.",
- "No referrals to show.": "No referrals to show.",
- "Referrals": "Referrals",
- "Recent ({{ totalCount, number }})": "Recent ({{ totalCount, number }})",
- "On Hand ({{ totalCount, number }})": "On Hand ({{ totalCount, number }})",
- "Tasks Due This Week": "Tasks Due This Week",
- "No tasks to show.": "No tasks to show.",
- "To Do This Week": "To Do This Week",
- "Weekly Activity": "Weekly Activity",
- "Completed": "Completed",
- "Appt Produced": "Appt Produced",
- "Calls": "Calls",
- "Messages": "Messages",
- "Appointments": "Appointments",
- "Correspondence": "Correspondence",
- "View Activity Detail": "View Activity Detail",
- "Good Evening, {{ firstName }}.": "Good Evening, {{ firstName }}.",
- "Good Evening,": "Good Evening,",
- "Good Morning, {{ firstName }}.": "Good Morning, {{ firstName }}.",
- "Good Morning,": "Good Morning,",
- "Good Afternoon, {{ firstName }}.": "Good Afternoon, {{ firstName }}.",
- "Good Afternoon,": "Good Afternoon,",
- "Welcome back to MPDX. Here's what's been happening.": "Welcome back to MPDX. Here's what's been happening.",
- "Privacy Policy": "Privacy Policy",
- "What's New": "What's New",
- "Terms of Use": "Terms of Use",
- "© {{ year }}, Cru. All Rights Reserved.": "© {{ year }}, Cru. All Rights Reserved.",
- "Overview": "Overview",
- "Dashboard": "Dashboard",
- "Contacts": "Contacts",
- "Tasks": "Tasks",
- "Reports": "Reports",
- "Gifts": "Gifts",
- "14 Month Report": "14 Month Report",
- "Designation Accounts": "Designation Accounts",
- "Responsibility Centers": "Responsibility Centers",
- "Expected Monthly Total": "Expected Monthly Total",
- "Partner Giving Analysis": "Partner Giving Analysis",
- "Coaching": "Coaching",
- "Tools": "Tools",
- "Import from Google": "Import from Google",
- "Import from CSV": "Import from CSV",
- "Import from TntConnect": "Import from TntConnect",
- "Fix Commitment Info": "Fix Commitment Info",
- "Fix Email Addresses": "Fix Email Addresses",
- "Fix Mailing Addresses": "Fix Mailing Addresses",
- "Fix Phone Numbers": "Fix Phone Numbers",
- "Fix Send Newsletter": "Fix Send Newsletter",
- "Merge Contacts": "Merge Contacts",
- "Merge People": "Merge People",
- "No call logged in the past year": "No call logged in the past year",
- "Gave a gift of {{ amount, currency }} which is greater than their commitment amount": "Gave a gift of {{ amount, currency }} which is greater than their commitment amount",
- "Gave a larger gift than their commitment amount": "Gave a larger gift than their commitment amount",
- "Gave a gift of {{ amount, currency }} where commitment frequency is set to semi-annual or greater": "Gave a gift of {{ amount, currency }} where commitment frequency is set to semi-annual or greater",
- "Gave a gift where commitment frequency is set to semi-annual or greater": "Gave a gift where commitment frequency is set to semi-annual or greater",
- "On your physical newsletter list but has no mailing address": "On your physical newsletter list but has no mailing address",
- "On your email newsletter list but has no people with a valid email address": "On your email newsletter list but has no people with a valid email address",
- "Added through your Give Site subscription form": "Added through your Give Site subscription form",
- "Added and merged": "Added and merged",
- "Added but not merged": "Added but not merged",
- "Added with no duplicate found": "Added with no duplicate found",
- "Recontinued giving": "Recontinued giving",
- "Semi-annual or greater gift is expected one month from now": "Semi-annual or greater gift is expected one month from now",
- "Gave a gift of {{ amount, currency }} which is less than their commitment amount": "Gave a gift of {{ amount, currency }} which is less than their commitment amount",
- "Gave a smaller gift than their commitment amount": "Gave a smaller gift than their commitment amount",
- "Gave a special gift of {{ amount, currency }}": "Gave a special gift of {{ amount, currency }}",
- "Gave a special gift": "Gave a special gift",
- "Started giving": "Started giving",
- "Missed a gift": "Missed a gift",
- "No thank you note logged in the past year": "No thank you note logged in the past year",
- "Upcoming anniversary": "Upcoming anniversary",
- "Upcoming birthday": "Upcoming birthday",
- "Notifications": "Notifications",
- "Mark all as read": "Mark all as read",
- "Load More": "Load More",
- "No notifications to show.": "No notifications to show.",
- "See All Account Lists": "See All Account Lists",
- "Go to help": "Go to help",
- "Preferences": "Preferences",
- "Connect Services": "Connect Services",
- "Manage Accounts": "Manage Accounts",
- "Manage Coaches": "Manage Coaches",
- "Sign Out": "Sign Out",
- "No Comments to show.": "No Comments to show.",
- "Task saved successfully": "Task saved successfully",
- "Result": "Result",
- "Next Action": "Next Action",
- "Completed Date": "Completed Date",
- "OK": "OK",
- "Today": "Today",
- "Cancel": "Cancel",
- "Clear": "Clear",
- "Completed Time": "Completed Time",
- "Tags": "Tags",
- "Save": "Save",
- "No Contacts to show.": "No Contacts to show.",
- "Newsletter": "Newsletter",
- "Commitment": "Commitment",
- "Last Gift": "Last Gift",
- "Task": "Task",
- "Description": "Description",
- "Action": "Action",
- "APPOINTMENT": "Appointment",
- "CALL": "Call",
- "EMAIL": "Email",
- "FACEBOOK_MESSAGE": "Facebook Message",
- "LETTER": "Letter",
- "NEWSLETTER_EMAIL": "Newsletter - Email",
- "NEWSLETTER_PHYSICAL": "Newsletter - Physical",
- "NONE": "None",
- "PRAYER_REQUEST": "Prayer Request",
- "PRE_CALL_LETTER": "Pre-Call Letter",
- "REMINDER_LETTER": "Reminder Letter",
- "SUPPORT_LETTER": "Support Letter",
- "TALK_TO_IN_PERSON": "Talk To In Person",
- "TEXT_MESSAGE": "Text Message",
- "THANK": "Thank",
- "TO_DO": "To Do",
- "DAYS": "Days",
- "HOURS": "Hours",
- "MINUTES": "Minutes",
- "BOTH": "Both",
- "MOBILE": "Mobile",
- "APPOINTMENT_SCHEDULED": "Appointment Scheduled",
- "ASK_IN_FUTURE": "Ask In Future",
- "CALL_FOR_DECISION": "Call For Decision",
- "CONTACT_FOR_APPOINTMENT": "Contact For Appointment",
- "CULTIVATE_RELATIONSHIP": "Cultivate Relationship",
- "EXPIRED_REFERRAL": "Expired Referral",
- "NEVER_ASK": "Never Ask",
- "NEVER_CONTACTED": "Never Contacted",
- "NOT_INTERESTED": "Not Interested",
- "PARTNER_FINANCIAL": "Partner - Financial",
- "PARTNER_PRAY": "Partner - Pray",
- "PARTNER_SPECIAL": "Partner - Special",
- "RESEARCH_ABANDONED": "Research Abandoned",
- "UNRESPONSIVE": "Unresponsive",
- "List Separator": ", ",
- "PHYSICAL": "Physical",
- "ANNUAL": "Annual",
- "EVERY_2_MONTHS": "Every 2 Months",
- "EVERY_2_WEEKS": "Every 2 Weeks",
- "EVERY_2_YEARS": "Every 2 Years",
- "EVERY_4_MONTHS": "Every 4 Months",
- "EVERY_6_MONTHS": "Every 6 Months",
- "MONTHLY": "Monthly",
- "QUARTERLY": "Quarterly",
- "WEEKLY": "Weekly",
- "ATTEMPTED": "Attempted",
- "ATTEMPTED_LEFT_MESSAGE": "Attempted - Left Message",
- "COMPLETED": "Completed",
- "DONE": "Done",
- "RECEIVED": "Received",
- "Complete {{activityType}}": "Complete {{activityType}}",
- "Add Task": "Add Task",
- "Details": "Details",
- "Contacts ({{ contactCount }})": "Contacts ({{ contactCount }})",
- "Comments": "Comments",
- "Subject": "Subject",
- "Field is required": "Field is required",
- "Type": "Type",
- "None": "None",
- "Due Date": "Due Date",
- "Due Time": "Due Time",
- "Assignee": "Assignee",
- "Notification": "Notification",
- "Period": "Period",
- "Unit": "Unit",
- "Platform": "Platform",
- "Complete": "Complete",
- "Incomplete": "Incomplete",
- "Loading": "Loading",
- "Tag {{tag}}": "Tag: {{tag}}",
- "Due Date {{ minimumDate }} - {{ maximumDate }}": "Due Date: {{ minimumDate }} - {{ maximumDate }}",
- "Minimum Due Date {{ minimumDate }}": "Minimum Due Date: {{ minimumDate }}",
- "Maximum Due Date {{ maximumDate }}": "Maximum Due Date: {{ maximumDate }}",
- "Minimum": "Minimum",
- "Maximum": "Maximum",
- "No Due Date": "No Due Date"
+ "My Accounts": "My Accounts",
+ "Goal": "Goal",
+ "Gifts Started": "Gifts Started",
+ "Committed": "Committed",
+ "Account Balance": "Account Balance",
+ "It may take a few days to update.": "It may take a few days to update.",
+ "View Gifts": "View Gifts",
+ "Average": "Average",
+ "No monthly activity to show.": "No monthly activity to show.",
+ "Amount ({{ currencyCode }})": "Amount ({{ currencyCode }})",
+ "Monthly Goal": "Monthly Goal",
+ "Commitments": "Commitments",
+ "Below Goal": "Below Goal",
+ "Above Goal": "Above Goal",
+ "Appeals": "Appeals",
+ "No primary appeal to show.": "No primary appeal to show.",
+ "Gifts Received": "Gifts Received",
+ "View All": "View All",
+ "Late Commitments": "Late Commitments",
+ "View All ({{ totalCount, number }})": "View All ({{ totalCount, number }})",
+ "No late commitments to show.": "No late commitments to show.",
+ "Their gift is {{ count, number }} day late.": "Their gift is {{ count, number }} day late.",
+ "Their gift is {{ count, number }} day late._plural": "Their gift is {{ count, number }} days late.",
+ "Partner Care": "Partner Care",
+ "Prayer ({{ totalCount, number }})": "Prayer ({{ totalCount, number }})",
+ "Celebrations ({{ totalCount, number }})": "Celebrations ({{ totalCount, number }})",
+ "No prayer requests to show.": "No prayer requests to show.",
+ "No celebrations to show.": "No celebrations to show.",
+ "No referrals to show.": "No referrals to show.",
+ "Referrals": "Referrals",
+ "Recent ({{ totalCount, number }})": "Recent ({{ totalCount, number }})",
+ "On Hand ({{ totalCount, number }})": "On Hand ({{ totalCount, number }})",
+ "Tasks Due This Week": "Tasks Due This Week",
+ "No tasks to show.": "No tasks to show.",
+ "To Do This Week": "To Do This Week",
+ "Weekly Activity": "Weekly Activity",
+ "Completed": "Completed",
+ "Appt Produced": "Appt Produced",
+ "Calls": "Calls",
+ "Messages": "Messages",
+ "Appointments": "Appointments",
+ "Correspondence": "Correspondence",
+ "View Activity Detail": "View Activity Detail",
+ "Good Evening, {{ firstName }}.": "Good Evening, {{ firstName }}.",
+ "Good Evening,": "Good Evening,",
+ "Good Morning, {{ firstName }}.": "Good Morning, {{ firstName }}.",
+ "Good Morning,": "Good Morning,",
+ "Good Afternoon, {{ firstName }}.": "Good Afternoon, {{ firstName }}.",
+ "Good Afternoon,": "Good Afternoon,",
+ "Welcome back to MPDX. Here's what's been happening.": "Welcome back to MPDX. Here's what's been happening.",
+ "Privacy Policy": "Privacy Policy",
+ "What's New": "What's New",
+ "Terms of Use": "Terms of Use",
+ "© {{ year }}, Cru. All Rights Reserved.": "© {{ year }}, Cru. All Rights Reserved.",
+ "Overview": "Overview",
+ "Dashboard": "Dashboard",
+ "Contacts": "Contacts",
+ "Tasks": "Tasks",
+ "Reports": "Reports",
+ "Gifts": "Gifts",
+ "14 Month Report": "14 Month Report",
+ "Designation Accounts": "Designation Accounts",
+ "Responsibility Centers": "Responsibility Centers",
+ "Expected Monthly Total": "Expected Monthly Total",
+ "Partner Giving Analysis": "Partner Giving Analysis",
+ "Coaching": "Coaching",
+ "Tools": "Tools",
+ "Import from Google": "Import from Google",
+ "Import from CSV": "Import from CSV",
+ "Import from TntConnect": "Import from TntConnect",
+ "Fix Commitment Info": "Fix Commitment Info",
+ "Fix Email Addresses": "Fix Email Addresses",
+ "Fix Mailing Addresses": "Fix Mailing Addresses",
+ "Fix Phone Numbers": "Fix Phone Numbers",
+ "Fix Send Newsletter": "Fix Send Newsletter",
+ "Merge Contacts": "Merge Contacts",
+ "Merge People": "Merge People",
+ "No call logged in the past year": "No call logged in the past year",
+ "Gave a gift of {{ amount, currency }} which is greater than their commitment amount": "Gave a gift of {{ amount, currency }} which is greater than their commitment amount",
+ "Gave a larger gift than their commitment amount": "Gave a larger gift than their commitment amount",
+ "Gave a gift of {{ amount, currency }} where commitment frequency is set to semi-annual or greater": "Gave a gift of {{ amount, currency }} where commitment frequency is set to semi-annual or greater",
+ "Gave a gift where commitment frequency is set to semi-annual or greater": "Gave a gift where commitment frequency is set to semi-annual or greater",
+ "On your physical newsletter list but has no mailing address": "On your physical newsletter list but has no mailing address",
+ "On your email newsletter list but has no people with a valid email address": "On your email newsletter list but has no people with a valid email address",
+ "Added through your Give Site subscription form": "Added through your Give Site subscription form",
+ "Added and merged": "Added and merged",
+ "Added but not merged": "Added but not merged",
+ "Added with no duplicate found": "Added with no duplicate found",
+ "Recontinued giving": "Recontinued giving",
+ "Semi-annual or greater gift is expected one month from now": "Semi-annual or greater gift is expected one month from now",
+ "Gave a gift of {{ amount, currency }} which is less than their commitment amount": "Gave a gift of {{ amount, currency }} which is less than their commitment amount",
+ "Gave a smaller gift than their commitment amount": "Gave a smaller gift than their commitment amount",
+ "Gave a special gift of {{ amount, currency }}": "Gave a special gift of {{ amount, currency }}",
+ "Gave a special gift": "Gave a special gift",
+ "Started giving": "Started giving",
+ "Missed a gift": "Missed a gift",
+ "No thank you note logged in the past year": "No thank you note logged in the past year",
+ "Upcoming anniversary": "Upcoming anniversary",
+ "Upcoming birthday": "Upcoming birthday",
+ "Notifications": "Notifications",
+ "Mark all as read": "Mark all as read",
+ "Load More": "Load More",
+ "No notifications to show.": "No notifications to show.",
+ "See All Account Lists": "See All Account Lists",
+ "Go to help": "Go to help",
+ "Preferences": "Preferences",
+ "Connect Services": "Connect Services",
+ "Manage Accounts": "Manage Accounts",
+ "Manage Coaches": "Manage Coaches",
+ "Sign Out": "Sign Out",
+ "No Comments to show.": "No Comments to show.",
+ "Task saved successfully": "Task saved successfully",
+ "Result": "Result",
+ "Next Action": "Next Action",
+ "Completed Date": "Completed Date",
+ "OK": "OK",
+ "Today": "Today",
+ "Cancel": "Cancel",
+ "Clear": "Clear",
+ "Completed Time": "Completed Time",
+ "Tags": "Tags",
+ "Save": "Save",
+ "No Contacts to show.": "No Contacts to show.",
+ "Newsletter": "Newsletter",
+ "Commitment": "Commitment",
+ "Last Gift": "Last Gift",
+ "Task": "Task",
+ "Description": "Description",
+ "Action": "Action",
+ "APPOINTMENT": "Appointment",
+ "CALL": "Call",
+ "EMAIL": "Email",
+ "FACEBOOK_MESSAGE": "Facebook Message",
+ "LETTER": "Letter",
+ "NEWSLETTER_EMAIL": "Newsletter - Email",
+ "NEWSLETTER_PHYSICAL": "Newsletter - Physical",
+ "NONE": "None",
+ "PRAYER_REQUEST": "Prayer Request",
+ "PRE_CALL_LETTER": "Pre-Call Letter",
+ "REMINDER_LETTER": "Reminder Letter",
+ "SUPPORT_LETTER": "Support Letter",
+ "TALK_TO_IN_PERSON": "Talk To In Person",
+ "TEXT_MESSAGE": "Text Message",
+ "THANK": "Thank",
+ "TO_DO": "To Do",
+ "DAYS": "Days",
+ "HOURS": "Hours",
+ "MINUTES": "Minutes",
+ "BOTH": "Both",
+ "MOBILE": "Mobile",
+ "APPOINTMENT_SCHEDULED": "Appointment Scheduled",
+ "ASK_IN_FUTURE": "Ask In Future",
+ "CALL_FOR_DECISION": "Call For Decision",
+ "CONTACT_FOR_APPOINTMENT": "Contact For Appointment",
+ "CULTIVATE_RELATIONSHIP": "Cultivate Relationship",
+ "EXPIRED_REFERRAL": "Expired Referral",
+ "NEVER_ASK": "Never Ask",
+ "NEVER_CONTACTED": "Never Contacted",
+ "NOT_INTERESTED": "Not Interested",
+ "PARTNER_FINANCIAL": "Partner - Financial",
+ "PARTNER_PRAY": "Partner - Pray",
+ "PARTNER_SPECIAL": "Partner - Special",
+ "RESEARCH_ABANDONED": "Research Abandoned",
+ "UNRESPONSIVE": "Unresponsive",
+ "List Separator": ", ",
+ "PHYSICAL": "Physical",
+ "ANNUAL": "Annual",
+ "EVERY_2_MONTHS": "Every 2 Months",
+ "EVERY_2_WEEKS": "Every 2 Weeks",
+ "EVERY_2_YEARS": "Every 2 Years",
+ "EVERY_4_MONTHS": "Every 4 Months",
+ "EVERY_6_MONTHS": "Every 6 Months",
+ "MONTHLY": "Monthly",
+ "QUARTERLY": "Quarterly",
+ "WEEKLY": "Weekly",
+ "ATTEMPTED": "Attempted",
+ "ATTEMPTED_LEFT_MESSAGE": "Attempted - Left Message",
+ "COMPLETED": "Completed",
+ "DONE": "Done",
+ "RECEIVED": "Received",
+ "Complete {{activityType}}": "Complete {{activityType}}",
+ "Add Task": "Add Task",
+ "Details": "Details",
+ "Contacts ({{ contactCount }})": "Contacts ({{ contactCount }})",
+ "Comments": "Comments",
+ "Subject": "Subject",
+ "Field is required": "Field is required",
+ "Type": "Type",
+ "None": "None",
+ "Due Date": "Due Date",
+ "Due Time": "Due Time",
+ "Assignee": "Assignee",
+ "Notification": "Notification",
+ "Period": "Period",
+ "Unit": "Unit",
+ "Platform": "Platform",
+ "Complete": "Complete",
+ "Incomplete": "Incomplete",
+ "Loading": "Loading",
+ "Tag {{tag}}": "Tag: {{tag}}",
+ "Due Date {{ minimumDate }} - {{ maximumDate }}": "Due Date: {{ minimumDate }} - {{ maximumDate }}",
+ "Minimum Due Date {{ minimumDate }}": "Minimum Due Date: {{ minimumDate }}",
+ "Maximum Due Date {{ maximumDate }}": "Maximum Due Date: {{ maximumDate }}",
+ "Minimum": "Minimum",
+ "Maximum": "Maximum",
+ "No Due Date": "No Due Date"
}
diff --git a/public/manifest.json b/public/manifest.json
index eabef349bb..ac587fe7fe 100644
--- a/public/manifest.json
+++ b/public/manifest.json
@@ -1,53 +1,53 @@
{
- "name": "MPDX",
- "theme_color": "#05699b",
- "background_color": "#05699b",
- "display": "standalone",
- "Scope": "/",
- "start_url": "/",
- "short_name": "MPDX",
- "icons": [
- {
- "src": "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/icons/icon-72x72.png",
- "sizes": "72x72",
- "type": "image/png"
- },
- {
- "src": "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/icons/icon-96x96.png",
- "sizes": "96x96",
- "type": "image/png"
- },
- {
- "src": "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/icons/icon-128x128.png",
- "sizes": "128x128",
- "type": "image/png"
- },
- {
- "src": "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/icons/icon-144x144.png",
- "sizes": "144x144",
- "type": "image/png"
- },
- {
- "src": "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/icons/icon-152x152.png",
- "sizes": "152x152",
- "type": "image/png"
- },
- {
- "src": "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/icons/icon-192x192.png",
- "sizes": "192x192",
- "type": "image/png"
- },
- {
- "src": "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/icons/icon-384x384.png",
- "sizes": "384x384",
- "type": "image/png"
- },
- {
- "src": "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/icons/icon-512x512.png",
- "sizes": "512x512",
- "type": "image/png",
- "purpose": "any maskable"
- }
- ],
- "splash_pages": null
+ "name": "MPDX",
+ "theme_color": "#05699b",
+ "background_color": "#05699b",
+ "display": "standalone",
+ "Scope": "/",
+ "start_url": "/",
+ "short_name": "MPDX",
+ "icons": [
+ {
+ "src": "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/icons/icon-72x72.png",
+ "sizes": "72x72",
+ "type": "image/png"
+ },
+ {
+ "src": "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/icons/icon-96x96.png",
+ "sizes": "96x96",
+ "type": "image/png"
+ },
+ {
+ "src": "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/icons/icon-128x128.png",
+ "sizes": "128x128",
+ "type": "image/png"
+ },
+ {
+ "src": "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/icons/icon-144x144.png",
+ "sizes": "144x144",
+ "type": "image/png"
+ },
+ {
+ "src": "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/icons/icon-152x152.png",
+ "sizes": "152x152",
+ "type": "image/png"
+ },
+ {
+ "src": "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/icons/icon-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "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/icons/icon-384x384.png",
+ "sizes": "384x384",
+ "type": "image/png"
+ },
+ {
+ "src": "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/icons/icon-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "any maskable"
+ }
+ ],
+ "splash_pages": null
}
diff --git a/src/components/AccountLists/AccountLists.stories.tsx b/src/components/AccountLists/AccountLists.stories.tsx
index f9af781e27..8fed32cfee 100644
--- a/src/components/AccountLists/AccountLists.stories.tsx
+++ b/src/components/AccountLists/AccountLists.stories.tsx
@@ -2,48 +2,48 @@ import React, { ReactElement } from 'react';
import AccountLists from './AccountLists';
export default {
- title: 'AccountLists',
+ title: 'AccountLists',
};
export const Default = (): ReactElement => {
- return (
-
- );
+ return (
+
+ );
};
Default.story = {
- parameters: {
- chromatic: { delay: 1000 },
- },
+ parameters: {
+ chromatic: { delay: 1000 },
+ },
};
diff --git a/src/components/AccountLists/AccountLists.test.tsx b/src/components/AccountLists/AccountLists.test.tsx
index ed9b75e774..4293dd9c1c 100644
--- a/src/components/AccountLists/AccountLists.test.tsx
+++ b/src/components/AccountLists/AccountLists.test.tsx
@@ -3,43 +3,43 @@ import { render } from '@testing-library/react';
import AccountLists from '.';
describe('AccountLists', () => {
- it('has correct defaults', () => {
- const { getByTestId } = render(
- ,
- );
- expect(getByTestId('abc')).toHaveTextContent('My Personal Staff Account');
- expect(getByTestId('def')).toHaveTextContent('My Ministry Account');
- expect(getByTestId('ghi')).toHaveTextContent("My Friend's Staff Account");
- });
+ it('has correct defaults', () => {
+ const { getByTestId } = render(
+ ,
+ );
+ expect(getByTestId('abc')).toHaveTextContent('My Personal Staff Account');
+ expect(getByTestId('def')).toHaveTextContent('My Ministry Account');
+ expect(getByTestId('ghi')).toHaveTextContent("My Friend's Staff Account");
+ });
});
diff --git a/src/components/AccountLists/AccountLists.tsx b/src/components/AccountLists/AccountLists.tsx
index 76deec5714..a56139ccc9 100644
--- a/src/components/AccountLists/AccountLists.tsx
+++ b/src/components/AccountLists/AccountLists.tsx
@@ -1,5 +1,14 @@
import React, { ReactElement } from 'react';
-import { makeStyles, Theme, Container, Typography, Grid, CardActionArea, CardContent, Box } from '@material-ui/core';
+import {
+ makeStyles,
+ Theme,
+ Container,
+ Typography,
+ Grid,
+ CardActionArea,
+ CardContent,
+ Box,
+} from '@material-ui/core';
import Link from 'next/link';
import { motion } from 'framer-motion';
import { useTranslation } from 'react-i18next';
@@ -9,117 +18,138 @@ import AnimatedCard from '../AnimatedCard';
import { currencyFormat, percentageFormat } from '../../lib/intlFormat';
interface Props {
- data: GetAccountListsQuery;
+ data: GetAccountListsQuery;
}
const useStyles = makeStyles((theme: Theme) => ({
- box: {
- paddingBottom: theme.spacing(5),
- backgroundColor: '#f6f7f9',
+ box: {
+ paddingBottom: theme.spacing(5),
+ backgroundColor: '#f6f7f9',
+ },
+ cardContent: {
+ display: 'flex',
+ flexDirection: 'column',
+ height: '200px',
+ },
+ image: {
+ '& img': {
+ height: '160px',
},
- cardContent: {
- display: 'flex',
- flexDirection: 'column',
- height: '200px',
- },
- image: {
- '& img': {
- height: '160px',
- },
- [theme.breakpoints.down('xs')]: {
- display: 'none',
- },
+ [theme.breakpoints.down('xs')]: {
+ display: 'none',
},
+ },
}));
const variants = {
- animate: {
- transition: {
- staggerChildren: 0.15,
- },
+ animate: {
+ transition: {
+ staggerChildren: 0.15,
},
- exit: {
- transition: {
- staggerChildren: 0.1,
- },
+ },
+ exit: {
+ transition: {
+ staggerChildren: 0.1,
},
+ },
};
const AccountLists = ({ data }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
+ const classes = useStyles();
+ const { t } = useTranslation();
- return (
-
-
-
-
-
- {data.accountLists.nodes.map(
- ({ id, name, monthlyGoal, receivedPledges, totalPledges, currency }) => {
- const receivedPercentage = receivedPledges / monthlyGoal;
- const totalPercentage = totalPledges / monthlyGoal;
+ return (
+
+
+
+
+
+ {data.accountLists.nodes.map(
+ ({
+ id,
+ name,
+ monthlyGoal,
+ receivedPledges,
+ totalPledges,
+ currency,
+ }) => {
+ const receivedPercentage = receivedPledges / monthlyGoal;
+ const totalPercentage = totalPledges / monthlyGoal;
- return (
-
-
-
-
-
-
-
- {name}
-
-
-
- {monthlyGoal && (
-
-
- {t('Goal')}
-
-
- {currencyFormat(monthlyGoal, currency)}
-
-
- )}
-
-
- {t('Gifts Started')}
-
-
- {isNaN(receivedPercentage)
- ? '-'
- : percentageFormat(receivedPercentage)}
-
-
-
-
- {t('Committed')}
-
-
- {isNaN(totalPercentage)
- ? '-'
- : percentageFormat(totalPercentage)}
-
-
-
-
-
-
-
-
- );
- },
- )}
-
-
-
-
- );
+ return (
+
+
+
+
+
+
+
+ {name}
+
+
+
+ {monthlyGoal && (
+
+
+ {t('Goal')}
+
+
+ {currencyFormat(monthlyGoal, currency)}
+
+
+ )}
+
+
+ {t('Gifts Started')}
+
+
+ {isNaN(receivedPercentage)
+ ? '-'
+ : percentageFormat(receivedPercentage)}
+
+
+
+
+ {t('Committed')}
+
+
+ {isNaN(totalPercentage)
+ ? '-'
+ : percentageFormat(totalPercentage)}
+
+
+
+
+
+
+
+
+ );
+ },
+ )}
+
+
+
+
+ );
};
export default AccountLists;
diff --git a/src/components/AnimatedBox/AnimatedBox.test.tsx b/src/components/AnimatedBox/AnimatedBox.test.tsx
index 7912f36a4a..ea6fa68ee3 100644
--- a/src/components/AnimatedBox/AnimatedBox.test.tsx
+++ b/src/components/AnimatedBox/AnimatedBox.test.tsx
@@ -3,13 +3,13 @@ import { render } from '@testing-library/react';
import AnimatedBox from '.';
describe('AnimatedBox', () => {
- it('has correct defaults', () => {
- const { getByTestId } = render(
-
-
- ,
- );
- expect(getByTestId('TestAnimatedBox')).toBeInTheDocument();
- expect(getByTestId('TestAnimatedBoxContent')).toBeInTheDocument();
- });
+ it('has correct defaults', () => {
+ const { getByTestId } = render(
+
+
+ ,
+ );
+ expect(getByTestId('TestAnimatedBox')).toBeInTheDocument();
+ expect(getByTestId('TestAnimatedBoxContent')).toBeInTheDocument();
+ });
});
diff --git a/src/components/AnimatedBox/AnimatedBox.tsx b/src/components/AnimatedBox/AnimatedBox.tsx
index 02a05b5375..f86d979725 100644
--- a/src/components/AnimatedBox/AnimatedBox.tsx
+++ b/src/components/AnimatedBox/AnimatedBox.tsx
@@ -3,29 +3,29 @@ import { Box, BoxProps } from '@material-ui/core';
import { motion } from 'framer-motion';
const variants = {
- initial: {
- opacity: 0,
+ initial: {
+ opacity: 0,
+ },
+ animate: {
+ opacity: 1,
+ transition: {
+ duration: 0.5,
+ ease: [0.48, 0.15, 0.25, 0.96],
},
- animate: {
- opacity: 1,
- transition: {
- duration: 0.5,
- ease: [0.48, 0.15, 0.25, 0.96],
- },
- },
- exit: {
- opacity: 0,
- transition: {
- duration: 0.2,
- ease: [0.48, 0.15, 0.25, 0.96],
- },
+ },
+ exit: {
+ opacity: 0,
+ transition: {
+ duration: 0.2,
+ ease: [0.48, 0.15, 0.25, 0.96],
},
+ },
};
const AnimatedBox = (props: BoxProps): ReactElement => (
-
-
-
+
+
+
);
export default AnimatedBox;
diff --git a/src/components/AnimatedCard/AnimatedCard.test.tsx b/src/components/AnimatedCard/AnimatedCard.test.tsx
index 566475e14b..5a6ba945fd 100644
--- a/src/components/AnimatedCard/AnimatedCard.test.tsx
+++ b/src/components/AnimatedCard/AnimatedCard.test.tsx
@@ -3,13 +3,13 @@ import { render } from '@testing-library/react';
import AnimatedCard from '.';
describe('AnimatedCard', () => {
- it('has correct defaults', () => {
- const { getByTestId } = render(
-
-
- ,
- );
- expect(getByTestId('TestAnimatedCard')).toBeInTheDocument();
- expect(getByTestId('TestAnimatedCardContent')).toBeInTheDocument();
- });
+ it('has correct defaults', () => {
+ const { getByTestId } = render(
+
+
+ ,
+ );
+ expect(getByTestId('TestAnimatedCard')).toBeInTheDocument();
+ expect(getByTestId('TestAnimatedCardContent')).toBeInTheDocument();
+ });
});
diff --git a/src/components/AnimatedCard/AnimatedCard.tsx b/src/components/AnimatedCard/AnimatedCard.tsx
index f4a767f162..8ad25db0f8 100644
--- a/src/components/AnimatedCard/AnimatedCard.tsx
+++ b/src/components/AnimatedCard/AnimatedCard.tsx
@@ -3,35 +3,35 @@ import { Card, CardProps } from '@material-ui/core';
import { motion } from 'framer-motion';
const variants = {
- initial: {
- scale: 0.96,
- y: 30,
- opacity: 0,
+ initial: {
+ scale: 0.96,
+ y: 30,
+ opacity: 0,
+ },
+ animate: {
+ scale: 1,
+ y: 0,
+ opacity: 1,
+ transition: {
+ duration: 0.5,
+ ease: [0.48, 0.15, 0.25, 0.96],
},
- animate: {
- scale: 1,
- y: 0,
- opacity: 1,
- transition: {
- duration: 0.5,
- ease: [0.48, 0.15, 0.25, 0.96],
- },
- },
- exit: {
- scale: 0.6,
- y: 100,
- opacity: 0,
- transition: {
- duration: 0.2,
- ease: [0.48, 0.15, 0.25, 0.96],
- },
+ },
+ exit: {
+ scale: 0.6,
+ y: 100,
+ opacity: 0,
+ transition: {
+ duration: 0.2,
+ ease: [0.48, 0.15, 0.25, 0.96],
},
+ },
};
const AnimatedCard = (props: CardProps): ReactElement => (
-
-
-
+
+
+
);
export default AnimatedCard;
diff --git a/src/components/App/Provider.tsx b/src/components/App/Provider.tsx
index 6b2efb385e..f3d6ff8915 100644
--- a/src/components/App/Provider.tsx
+++ b/src/components/App/Provider.tsx
@@ -1,4 +1,10 @@
-import React, { ReactNode, ReactElement, useState, useReducer, Dispatch } from 'react';
+import React, {
+ ReactNode,
+ ReactElement,
+ useState,
+ useReducer,
+ Dispatch,
+} from 'react';
import { v4 as uuidv4 } from 'uuid';
import { omit, remove, find } from 'lodash/fp';
import TaskDrawer, { TaskDrawerProps } from '../Task/Drawer/Drawer';
@@ -7,65 +13,72 @@ import rootReducer, { Action, AppState } from './rootReducer';
import { AppContext } from '.';
export interface AppProviderContext {
- openTaskDrawer: (props: TaskDrawerProps) => void;
- state: AppState;
- dispatch: Dispatch;
+ openTaskDrawer: (props: TaskDrawerProps) => void;
+ state: AppState;
+ dispatch: Dispatch;
}
interface Props {
- children: ReactNode;
- initialState?: Partial;
+ children: ReactNode;
+ initialState?: Partial;
}
interface TaskDrawerPropsWithId extends TaskDrawerProps {
- id: string;
+ id: string;
}
const AppProvider = ({ initialState, children }: Props): ReactElement => {
- const [taskDrawers, setTaskDrawers] = useState([]);
- const [state, dispatch] = useReducer(rootReducer, {
- accountListId: null,
- breadcrumb: null,
- ...initialState,
- });
+ const [taskDrawers, setTaskDrawers] = useState([]);
+ const [state, dispatch] = useReducer(rootReducer, {
+ accountListId: null,
+ breadcrumb: null,
+ ...initialState,
+ });
- const openTaskDrawer = (taskDrawerProps: TaskDrawerProps): void => {
- const id = uuidv4();
- if (
- !taskDrawerProps.taskId ||
- !find({ taskId: taskDrawerProps.taskId, showCompleteForm: taskDrawerProps.showCompleteForm }, taskDrawers)
- ) {
- setTaskDrawers([
- ...taskDrawers,
- {
- id,
- ...taskDrawerProps,
- onClose: (): void => {
- taskDrawerProps.onClose && taskDrawerProps.onClose();
- setTimeout(
- () => setTaskDrawers((taskDrawers) => remove({ id }, taskDrawers)),
- theme.transitions.duration.leavingScreen,
- );
- },
- },
- ]);
- }
- };
+ const openTaskDrawer = (taskDrawerProps: TaskDrawerProps): void => {
+ const id = uuidv4();
+ if (
+ !taskDrawerProps.taskId ||
+ !find(
+ {
+ taskId: taskDrawerProps.taskId,
+ showCompleteForm: taskDrawerProps.showCompleteForm,
+ },
+ taskDrawers,
+ )
+ ) {
+ setTaskDrawers([
+ ...taskDrawers,
+ {
+ id,
+ ...taskDrawerProps,
+ onClose: (): void => {
+ taskDrawerProps.onClose && taskDrawerProps.onClose();
+ setTimeout(
+ () =>
+ setTaskDrawers((taskDrawers) => remove({ id }, taskDrawers)),
+ theme.transitions.duration.leavingScreen,
+ );
+ },
+ },
+ ]);
+ }
+ };
- const value: AppProviderContext = {
- openTaskDrawer,
- state,
- dispatch,
- };
+ const value: AppProviderContext = {
+ openTaskDrawer,
+ state,
+ dispatch,
+ };
- return (
-
- {children}
- {taskDrawers.map((props: TaskDrawerPropsWithId) => (
-
- ))}
-
- );
+ return (
+
+ {children}
+ {taskDrawers.map((props: TaskDrawerPropsWithId) => (
+
+ ))}
+
+ );
};
export default AppProvider;
diff --git a/src/components/App/rootReducer.test.ts b/src/components/App/rootReducer.test.ts
index fc174babd8..363838f8df 100644
--- a/src/components/App/rootReducer.test.ts
+++ b/src/components/App/rootReducer.test.ts
@@ -1,30 +1,33 @@
import rootReducer, { Action, AppState } from './rootReducer';
describe('rootReducer', () => {
- const state: AppState = {
- accountListId: null,
- breadcrumb: null,
- };
+ const state: AppState = {
+ accountListId: null,
+ breadcrumb: null,
+ };
- describe('updateAccountListId', () => {
- it('updates accountListId state', () => {
- const action: Action = { type: 'updateAccountListId', accountListId: 'abc' };
- expect(rootReducer(state, action).accountListId).toEqual('abc');
- });
+ describe('updateAccountListId', () => {
+ it('updates accountListId state', () => {
+ const action: Action = {
+ type: 'updateAccountListId',
+ accountListId: 'abc',
+ };
+ expect(rootReducer(state, action).accountListId).toEqual('abc');
});
+ });
- describe('updateBreadcrumb', () => {
- it('updates breadcrumb state', () => {
- const action: Action = { type: 'updateBreadcrumb', breadcrumb: 'abc' };
- expect(rootReducer(state, action).breadcrumb).toEqual('abc');
- });
+ describe('updateBreadcrumb', () => {
+ it('updates breadcrumb state', () => {
+ const action: Action = { type: 'updateBreadcrumb', breadcrumb: 'abc' };
+ expect(rootReducer(state, action).breadcrumb).toEqual('abc');
});
+ });
- describe('updateUser', () => {
- it('updates user state', () => {
- const user = { id: 'user-1', firstName: 'John', lastName: 'Smith' };
- const action: Action = { type: 'updateUser', user };
- expect(rootReducer(state, action).user).toEqual(user);
- });
+ describe('updateUser', () => {
+ it('updates user state', () => {
+ const user = { id: 'user-1', firstName: 'John', lastName: 'Smith' };
+ const action: Action = { type: 'updateUser', user };
+ expect(rootReducer(state, action).user).toEqual(user);
});
+ });
});
diff --git a/src/components/App/rootReducer.ts b/src/components/App/rootReducer.ts
index 5e1f452733..3b5c4fc489 100644
--- a/src/components/App/rootReducer.ts
+++ b/src/components/App/rootReducer.ts
@@ -1,41 +1,44 @@
export interface AppState {
- accountListId: string;
- breadcrumb: string;
- user?: User;
+ accountListId: string;
+ breadcrumb: string;
+ user?: User;
}
interface User {
- id: string;
- firstName: string;
- lastName: string;
+ id: string;
+ firstName: string;
+ lastName: string;
}
-export type Action = UpdateAccountListIdAction | UpdateBreadcrumbAction | UpdateUserAction;
+export type Action =
+ | UpdateAccountListIdAction
+ | UpdateBreadcrumbAction
+ | UpdateUserAction;
type UpdateAccountListIdAction = {
- type: 'updateAccountListId';
- accountListId: string;
+ type: 'updateAccountListId';
+ accountListId: string;
};
type UpdateBreadcrumbAction = {
- type: 'updateBreadcrumb';
- breadcrumb: string;
+ type: 'updateBreadcrumb';
+ breadcrumb: string;
};
type UpdateUserAction = {
- type: 'updateUser';
- user: User;
+ type: 'updateUser';
+ user: User;
};
const rootReducer = (state: AppState, action: Action): AppState => {
- switch (action.type) {
- case 'updateAccountListId':
- return { ...state, accountListId: action.accountListId };
- case 'updateBreadcrumb':
- return { ...state, breadcrumb: action.breadcrumb };
- case 'updateUser':
- return { ...state, user: action.user };
- }
+ switch (action.type) {
+ case 'updateAccountListId':
+ return { ...state, accountListId: action.accountListId };
+ case 'updateBreadcrumb':
+ return { ...state, breadcrumb: action.breadcrumb };
+ case 'updateUser':
+ return { ...state, user: action.user };
+ }
};
export default rootReducer;
diff --git a/src/components/Dashboard/Balance/Balance.stories.tsx b/src/components/Dashboard/Balance/Balance.stories.tsx
index d22c79e678..6cbfceea0e 100644
--- a/src/components/Dashboard/Balance/Balance.stories.tsx
+++ b/src/components/Dashboard/Balance/Balance.stories.tsx
@@ -3,27 +3,27 @@ import { Box } from '@material-ui/core';
import Balance from '.';
export default {
- title: 'Dashboard/Balance',
+ title: 'Dashboard/Balance',
};
export const Default = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Dashboard/Balance/Balance.test.tsx b/src/components/Dashboard/Balance/Balance.test.tsx
index 3300c982f0..4a6a88031e 100644
--- a/src/components/Dashboard/Balance/Balance.test.tsx
+++ b/src/components/Dashboard/Balance/Balance.test.tsx
@@ -3,22 +3,26 @@ import { render } from '@testing-library/react';
import Balance from '.';
describe('Balance', () => {
- it('default', () => {
- const { getByTestId, getByRole } = render();
- expect(getByTestId('BalanceTypography').textContent).toEqual('$1,001');
- expect(getByRole('link', { name: 'View Gifts' })).toHaveAttribute(
- 'href',
- 'https://stage.mpdx.org/reports/donations',
- );
- });
+ it('default', () => {
+ const { getByTestId, getByRole } = render();
+ expect(getByTestId('BalanceTypography').textContent).toEqual('$1,001');
+ expect(getByRole('link', { name: 'View Gifts' })).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/reports/donations',
+ );
+ });
- it('custom props', () => {
- const { getByTestId } = render();
- expect(getByTestId('BalanceTypography').textContent).toEqual('€1,001');
- });
+ it('custom props', () => {
+ const { getByTestId } = render(
+ ,
+ );
+ expect(getByTestId('BalanceTypography').textContent).toEqual('€1,001');
+ });
- it('loading', () => {
- const { getByTestId } = render();
- expect(getByTestId('BalanceTypography').children[0].className).toContain('MuiSkeleton-root');
- });
+ it('loading', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('BalanceTypography').children[0].className).toContain(
+ 'MuiSkeleton-root',
+ );
+ });
});
diff --git a/src/components/Dashboard/Balance/Balance.tsx b/src/components/Dashboard/Balance/Balance.tsx
index 4f7ffcfa34..30316f4975 100644
--- a/src/components/Dashboard/Balance/Balance.tsx
+++ b/src/components/Dashboard/Balance/Balance.tsx
@@ -1,5 +1,13 @@
import React, { ReactElement } from 'react';
-import { makeStyles, Theme, CardContent, Typography, CardActions, Button, Box } from '@material-ui/core';
+import {
+ makeStyles,
+ Theme,
+ CardContent,
+ Typography,
+ CardActions,
+ Button,
+ Box,
+} from '@material-ui/core';
import { Skeleton } from '@material-ui/lab';
import { useTranslation } from 'react-i18next';
import { currencyFormat } from '../../../lib/intlFormat';
@@ -8,52 +16,60 @@ import AnimatedBox from '../../AnimatedBox';
import HandoffLink from '../../HandoffLink';
const useStyles = makeStyles((theme: Theme) => ({
- card: {
- display: 'flex',
- flexDirection: 'column',
- [theme.breakpoints.up('sm')]: {
- height: 'calc(100% - 65px)',
- },
- },
- cardContent: {
- flex: '1',
+ card: {
+ display: 'flex',
+ flexDirection: 'column',
+ [theme.breakpoints.up('sm')]: {
+ height: 'calc(100% - 65px)',
},
+ },
+ cardContent: {
+ flex: '1',
+ },
}));
interface Props {
- loading?: boolean;
- balance?: number;
- currencyCode?: string;
+ loading?: boolean;
+ balance?: number;
+ currencyCode?: string;
}
-const Balance = ({ loading, balance, currencyCode = 'USD' }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
+const Balance = ({
+ loading,
+ balance,
+ currencyCode = 'USD',
+}: Props): ReactElement => {
+ const classes = useStyles();
+ const { t } = useTranslation();
- return (
- <>
-
-
- {t('Account Balance')}
-
-
-
-
-
- {loading ? : currencyFormat(balance, currencyCode)}
-
- {t('It may take a few days to update.')}
-
-
-
-
-
-
-
- >
- );
+ return (
+ <>
+
+
+ {t('Account Balance')}
+
+
+
+
+
+ {loading ? (
+
+ ) : (
+ currencyFormat(balance, currencyCode)
+ )}
+
+ {t('It may take a few days to update.')}
+
+
+
+
+
+
+
+ >
+ );
};
export default Balance;
diff --git a/src/components/Dashboard/Dashboard.stories.tsx b/src/components/Dashboard/Dashboard.stories.tsx
index 58dccd37ab..d184ecf4f5 100644
--- a/src/components/Dashboard/Dashboard.stories.tsx
+++ b/src/components/Dashboard/Dashboard.stories.tsx
@@ -5,105 +5,105 @@ import { GetThisWeekDefaultMocks } from './ThisWeek/ThisWeek.mock';
import Dashboard from '.';
export default {
- title: 'Dashboard',
+ title: 'Dashboard',
};
export const Default = (): ReactElement => {
- const data: GetDashboardQuery = {
- user: {
- firstName: 'Roger',
+ const data: GetDashboardQuery = {
+ user: {
+ firstName: 'Roger',
+ },
+ accountList: {
+ name: 'My Account List',
+ monthlyGoal: 1000,
+ receivedPledges: 400,
+ totalPledges: 700,
+ currency: 'USD',
+ balance: 1000,
+ },
+ reportsDonationHistories: {
+ periods: [
+ {
+ convertedTotal: 200,
+ startDate: '2011-12-1',
+ totals: [
+ {
+ currency: 'USD',
+ convertedAmount: 350,
+ },
+ ],
+ },
+ {
+ convertedTotal: 400,
+ startDate: '2012-1-1',
+ totals: [
+ {
+ currency: 'USD',
+ convertedAmount: 750,
+ },
+ ],
},
- accountList: {
- name: 'My Account List',
- monthlyGoal: 1000,
- receivedPledges: 400,
- totalPledges: 700,
- currency: 'USD',
- balance: 1000,
+ {
+ convertedTotal: 900,
+ startDate: '2012-2-1',
+ totals: [
+ {
+ currency: 'USD',
+ convertedAmount: 550,
+ },
+ {
+ currency: 'NZD',
+ convertedAmount: 400,
+ },
+ {
+ currency: 'CAD',
+ convertedAmount: 200,
+ },
+ {
+ currency: 'AUD',
+ convertedAmount: 100,
+ },
+ ],
},
- reportsDonationHistories: {
- periods: [
- {
- convertedTotal: 200,
- startDate: '2011-12-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 350,
- },
- ],
- },
- {
- convertedTotal: 400,
- startDate: '2012-1-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 750,
- },
- ],
- },
- {
- convertedTotal: 900,
- startDate: '2012-2-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 550,
- },
- {
- currency: 'NZD',
- convertedAmount: 400,
- },
- {
- currency: 'CAD',
- convertedAmount: 200,
- },
- {
- currency: 'AUD',
- convertedAmount: 100,
- },
- ],
- },
- {
- convertedTotal: 1100,
- startDate: '2012-3-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 950,
- },
- {
- currency: 'NZD',
- convertedAmount: 800,
- },
- {
- currency: 'CAD',
- convertedAmount: 300,
- },
- {
- currency: 'AUD',
- convertedAmount: 200,
- },
- {
- currency: 'HKD',
- convertedAmount: 100,
- },
- ],
- },
- ],
- averageIgnoreCurrent: 750,
+ {
+ convertedTotal: 1100,
+ startDate: '2012-3-1',
+ totals: [
+ {
+ currency: 'USD',
+ convertedAmount: 950,
+ },
+ {
+ currency: 'NZD',
+ convertedAmount: 800,
+ },
+ {
+ currency: 'CAD',
+ convertedAmount: 300,
+ },
+ {
+ currency: 'AUD',
+ convertedAmount: 200,
+ },
+ {
+ currency: 'HKD',
+ convertedAmount: 100,
+ },
+ ],
},
- };
- return (
-
-
-
- );
+ ],
+ averageIgnoreCurrent: 750,
+ },
+ };
+ return (
+
+
+
+ );
};
Default.story = {
- parameters: {
- chromatic: { delay: 1000 },
- },
+ parameters: {
+ chromatic: { delay: 1000 },
+ },
};
diff --git a/src/components/Dashboard/Dashboard.test.tsx b/src/components/Dashboard/Dashboard.test.tsx
index ecdd4889df..e802167e8c 100644
--- a/src/components/Dashboard/Dashboard.test.tsx
+++ b/src/components/Dashboard/Dashboard.test.tsx
@@ -8,140 +8,177 @@ import { GetThisWeekDefaultMocks } from './ThisWeek/ThisWeek.mock';
import Dashboard from '.';
jest.mock('../App', () => ({
- useApp: (): Partial => ({
- openTaskDrawer: jest.fn(),
- }),
+ useApp: (): Partial => ({
+ openTaskDrawer: jest.fn(),
+ }),
}));
const data: GetDashboardQuery = {
- user: {
- firstName: 'Roger',
- },
- accountList: {
- name: 'My Account List',
- monthlyGoal: 1000,
- receivedPledges: 400,
- totalPledges: 700,
- currency: 'NZD',
- balance: 1000,
- },
- reportsDonationHistories: {
- periods: [
- {
- convertedTotal: 200,
- startDate: '2011-12-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 350,
- },
- ],
- },
- {
- convertedTotal: 400,
- startDate: '2012-1-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 750,
- },
- ],
- },
- {
- convertedTotal: 900,
- startDate: '2012-2-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 550,
- },
- {
- currency: 'NZD',
- convertedAmount: 400,
- },
- {
- currency: 'CAD',
- convertedAmount: 200,
- },
- {
- currency: 'AUD',
- convertedAmount: 100,
- },
- ],
- },
- {
- convertedTotal: 1100,
- startDate: '2012-3-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 950,
- },
- {
- currency: 'NZD',
- convertedAmount: 800,
- },
- {
- currency: 'CAD',
- convertedAmount: 300,
- },
- {
- currency: 'AUD',
- convertedAmount: 200,
- },
- {
- currency: 'HKD',
- convertedAmount: 100,
- },
- ],
- },
+ user: {
+ firstName: 'Roger',
+ },
+ accountList: {
+ name: 'My Account List',
+ monthlyGoal: 1000,
+ receivedPledges: 400,
+ totalPledges: 700,
+ currency: 'NZD',
+ balance: 1000,
+ },
+ reportsDonationHistories: {
+ periods: [
+ {
+ convertedTotal: 200,
+ startDate: '2011-12-1',
+ totals: [
+ {
+ currency: 'USD',
+ convertedAmount: 350,
+ },
],
- averageIgnoreCurrent: 750,
- },
+ },
+ {
+ convertedTotal: 400,
+ startDate: '2012-1-1',
+ totals: [
+ {
+ currency: 'USD',
+ convertedAmount: 750,
+ },
+ ],
+ },
+ {
+ convertedTotal: 900,
+ startDate: '2012-2-1',
+ totals: [
+ {
+ currency: 'USD',
+ convertedAmount: 550,
+ },
+ {
+ currency: 'NZD',
+ convertedAmount: 400,
+ },
+ {
+ currency: 'CAD',
+ convertedAmount: 200,
+ },
+ {
+ currency: 'AUD',
+ convertedAmount: 100,
+ },
+ ],
+ },
+ {
+ convertedTotal: 1100,
+ startDate: '2012-3-1',
+ totals: [
+ {
+ currency: 'USD',
+ convertedAmount: 950,
+ },
+ {
+ currency: 'NZD',
+ convertedAmount: 800,
+ },
+ {
+ currency: 'CAD',
+ convertedAmount: 300,
+ },
+ {
+ currency: 'AUD',
+ convertedAmount: 200,
+ },
+ {
+ currency: 'HKD',
+ convertedAmount: 100,
+ },
+ ],
+ },
+ ],
+ averageIgnoreCurrent: 750,
+ },
};
describe('Dashboard', () => {
- beforeEach(() => {
- matchMediaMock({ width: '1024px' });
- });
+ beforeEach(() => {
+ matchMediaMock({ width: '1024px' });
+ });
- it('default', async () => {
- const { getByTestId, queryByTestId } = render(
-
-
- ,
- );
- await waitFor(() => expect(queryByTestId('PartnerCarePrayerListLoading')).not.toBeInTheDocument());
- expect(getByTestId('MonthlyGoalTypographyGoal').textContent).toEqual('NZ$1,000');
- expect(getByTestId('MonthlyGoalTypographyPledged').textContent).toEqual('NZ$700');
- expect(getByTestId('MonthlyGoalTypographyReceived').textContent).toEqual('NZ$400');
- expect(getByTestId('BalanceTypography').textContent).toEqual('NZ$1,000');
- expect(getByTestId('DonationHistoriesTypographyGoal').textContent).toEqual('Goal NZ$1,000');
- expect(getByTestId('DonationHistoriesTypographyAverage').textContent).toEqual('Average NZ$750');
- expect(getByTestId('DonationHistoriesTypographyPledged').textContent).toEqual('Committed NZ$700');
- expect(getByTestId('PartnerCarePrayerList')).toBeInTheDocument();
- expect(getByTestId('TasksDueThisWeekList')).toBeInTheDocument();
- expect(getByTestId('LateCommitmentsListContacts')).toBeInTheDocument();
- expect(getByTestId('ReferralsTabRecentList')).toBeInTheDocument();
- expect(getByTestId('AppealsBoxName')).toBeInTheDocument();
- });
+ it('default', async () => {
+ const { getByTestId, queryByTestId } = render(
+
+
+ ,
+ );
+ await waitFor(() =>
+ expect(
+ queryByTestId('PartnerCarePrayerListLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(getByTestId('MonthlyGoalTypographyGoal').textContent).toEqual(
+ 'NZ$1,000',
+ );
+ expect(getByTestId('MonthlyGoalTypographyPledged').textContent).toEqual(
+ 'NZ$700',
+ );
+ expect(getByTestId('MonthlyGoalTypographyReceived').textContent).toEqual(
+ 'NZ$400',
+ );
+ expect(getByTestId('BalanceTypography').textContent).toEqual('NZ$1,000');
+ expect(getByTestId('DonationHistoriesTypographyGoal').textContent).toEqual(
+ 'Goal NZ$1,000',
+ );
+ expect(
+ getByTestId('DonationHistoriesTypographyAverage').textContent,
+ ).toEqual('Average NZ$750');
+ expect(
+ getByTestId('DonationHistoriesTypographyPledged').textContent,
+ ).toEqual('Committed NZ$700');
+ expect(getByTestId('PartnerCarePrayerList')).toBeInTheDocument();
+ expect(getByTestId('TasksDueThisWeekList')).toBeInTheDocument();
+ expect(getByTestId('LateCommitmentsListContacts')).toBeInTheDocument();
+ expect(getByTestId('ReferralsTabRecentList')).toBeInTheDocument();
+ expect(getByTestId('AppealsBoxName')).toBeInTheDocument();
+ });
- it('handles null fields', async () => {
- const { getByTestId, queryByTestId } = render(
-
-
- ,
- );
- await waitFor(() => expect(queryByTestId('PartnerCarePrayerListLoading')).not.toBeInTheDocument());
- expect(getByTestId('MonthlyGoalTypographyGoal').textContent).toEqual('$0');
- expect(getByTestId('MonthlyGoalTypographyPledged').textContent).toEqual('$700');
- expect(getByTestId('MonthlyGoalTypographyReceived').textContent).toEqual('$400');
- expect(getByTestId('BalanceTypography').textContent).toEqual('$1,000');
- expect(queryByTestId('DonationHistoriesTypographyGoal')).not.toBeInTheDocument();
- expect(getByTestId('DonationHistoriesTypographyAverage').textContent).toEqual('Average $750');
- expect(getByTestId('DonationHistoriesTypographyPledged').textContent).toEqual('Committed $700');
- });
+ it('handles null fields', async () => {
+ const { getByTestId, queryByTestId } = render(
+
+
+ ,
+ );
+ await waitFor(() =>
+ expect(
+ queryByTestId('PartnerCarePrayerListLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(getByTestId('MonthlyGoalTypographyGoal').textContent).toEqual('$0');
+ expect(getByTestId('MonthlyGoalTypographyPledged').textContent).toEqual(
+ '$700',
+ );
+ expect(getByTestId('MonthlyGoalTypographyReceived').textContent).toEqual(
+ '$400',
+ );
+ expect(getByTestId('BalanceTypography').textContent).toEqual('$1,000');
+ expect(
+ queryByTestId('DonationHistoriesTypographyGoal'),
+ ).not.toBeInTheDocument();
+ expect(
+ getByTestId('DonationHistoriesTypographyAverage').textContent,
+ ).toEqual('Average $750');
+ expect(
+ getByTestId('DonationHistoriesTypographyPledged').textContent,
+ ).toEqual('Committed $700');
+ });
});
diff --git a/src/components/Dashboard/Dashboard.tsx b/src/components/Dashboard/Dashboard.tsx
index acd8e45695..4aaa1dd67c 100644
--- a/src/components/Dashboard/Dashboard.tsx
+++ b/src/components/Dashboard/Dashboard.tsx
@@ -9,60 +9,68 @@ import DonationHistories from './DonationHistories';
import ThisWeek from './ThisWeek';
interface Props {
- data: GetDashboardQuery;
- accountListId: string;
+ data: GetDashboardQuery;
+ accountListId: string;
}
const variants = {
- animate: {
- transition: {
- delayChildren: 1,
- staggerChildren: 0.15,
- },
+ animate: {
+ transition: {
+ delayChildren: 1,
+ staggerChildren: 0.15,
},
- exit: {
- transition: {
- staggerChildren: 0.1,
- },
+ },
+ exit: {
+ transition: {
+ staggerChildren: 0.1,
},
+ },
};
const Dashboard = ({ data, accountListId }: Props): ReactElement => {
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- );
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
};
export default Dashboard;
diff --git a/src/components/Dashboard/DonationHistories/DonationHistories.stories.tsx b/src/components/Dashboard/DonationHistories/DonationHistories.stories.tsx
index 050697ea0f..0750474234 100644
--- a/src/components/Dashboard/DonationHistories/DonationHistories.stories.tsx
+++ b/src/components/Dashboard/DonationHistories/DonationHistories.stories.tsx
@@ -3,142 +3,147 @@ import { Box } from '@material-ui/core';
import DonationHistories from '.';
export default {
- title: 'Dashboard/DonationHistories',
+ title: 'Dashboard/DonationHistories',
};
const reportsDonationHistories = {
- periods: [
+ periods: [
+ {
+ convertedTotal: 200,
+ startDate: '2011-12-1',
+ totals: [
{
- convertedTotal: 200,
- startDate: '2011-12-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 350,
- },
- ],
+ currency: 'USD',
+ convertedAmount: 350,
},
+ ],
+ },
+ {
+ convertedTotal: 400,
+ startDate: '2012-1-1',
+ totals: [
{
- convertedTotal: 400,
- startDate: '2012-1-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 750,
- },
- ],
+ currency: 'USD',
+ convertedAmount: 750,
},
+ ],
+ },
+ {
+ convertedTotal: 900,
+ startDate: '2012-2-1',
+ totals: [
{
- convertedTotal: 900,
- startDate: '2012-2-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 550,
- },
- {
- currency: 'NZD',
- convertedAmount: 400,
- },
- {
- currency: 'CAD',
- convertedAmount: 200,
- },
- {
- currency: 'AUD',
- convertedAmount: 100,
- },
- ],
+ currency: 'USD',
+ convertedAmount: 550,
},
{
- convertedTotal: 1100,
- startDate: '2012-3-1',
- totals: [
- {
- currency: 'USD',
- convertedAmount: 950,
- },
- {
- currency: 'NZD',
- convertedAmount: 800,
- },
- {
- currency: 'CAD',
- convertedAmount: 300,
- },
- {
- currency: 'AUD',
- convertedAmount: 200,
- },
- {
- currency: 'HKD',
- convertedAmount: 100,
- },
- ],
+ currency: 'NZD',
+ convertedAmount: 400,
},
- ],
- averageIgnoreCurrent: 750,
+ {
+ currency: 'CAD',
+ convertedAmount: 200,
+ },
+ {
+ currency: 'AUD',
+ convertedAmount: 100,
+ },
+ ],
+ },
+ {
+ convertedTotal: 1100,
+ startDate: '2012-3-1',
+ totals: [
+ {
+ currency: 'USD',
+ convertedAmount: 950,
+ },
+ {
+ currency: 'NZD',
+ convertedAmount: 800,
+ },
+ {
+ currency: 'CAD',
+ convertedAmount: 300,
+ },
+ {
+ currency: 'AUD',
+ convertedAmount: 200,
+ },
+ {
+ currency: 'HKD',
+ convertedAmount: 100,
+ },
+ ],
+ },
+ ],
+ averageIgnoreCurrent: 750,
};
export const Default = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const WithReferences = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- const emptyReportsDonationHistories = {
- periods: [
- {
- convertedTotal: 0,
- startDate: '2011-12-1',
- totals: [],
- },
- {
- convertedTotal: 0,
- startDate: '2012-1-1',
- totals: [],
- },
- {
- convertedTotal: 0,
- startDate: '2012-2-1',
- totals: [],
- },
- {
- convertedTotal: 0,
- startDate: '2012-3-1',
- totals: [],
- },
- ],
- averageIgnoreCurrent: 0,
- };
+ const emptyReportsDonationHistories = {
+ periods: [
+ {
+ convertedTotal: 0,
+ startDate: '2011-12-1',
+ totals: [],
+ },
+ {
+ convertedTotal: 0,
+ startDate: '2012-1-1',
+ totals: [],
+ },
+ {
+ convertedTotal: 0,
+ startDate: '2012-2-1',
+ totals: [],
+ },
+ {
+ convertedTotal: 0,
+ startDate: '2012-3-1',
+ totals: [],
+ },
+ ],
+ averageIgnoreCurrent: 0,
+ };
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Dashboard/DonationHistories/DonationHistories.test.tsx b/src/components/Dashboard/DonationHistories/DonationHistories.test.tsx
index 59103ec049..a2108b26e0 100644
--- a/src/components/Dashboard/DonationHistories/DonationHistories.test.tsx
+++ b/src/components/Dashboard/DonationHistories/DonationHistories.test.tsx
@@ -3,69 +3,85 @@ import { render } from '@testing-library/react';
import DonationHistories from '.';
describe('DonationHistories', () => {
- let reportsDonationHistories;
+ let reportsDonationHistories;
- it('default', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('DonationHistoriesBoxEmpty')).toBeInTheDocument();
- expect(queryByTestId('DonationHistoriesGridLoading')).not.toBeInTheDocument();
- });
+ it('default', () => {
+ const { getByTestId, queryByTestId } = render();
+ expect(getByTestId('DonationHistoriesBoxEmpty')).toBeInTheDocument();
+ expect(
+ queryByTestId('DonationHistoriesGridLoading'),
+ ).not.toBeInTheDocument();
+ });
- it('empty periods', () => {
- reportsDonationHistories = {
- periods: [
- {
- convertedTotal: 0,
- startDate: '1-1-2019',
- totals: [{ currency: 'USD', convertedAmount: 0 }],
- },
- {
- convertedTotal: 0,
- startDate: '1-2-2019',
- totals: [{ currency: 'NZD', convertedAmount: 0 }],
- },
- ],
- averageIgnoreCurrent: 0,
- };
- const { getByTestId, queryByTestId } = render(
- ,
- );
- expect(getByTestId('DonationHistoriesBoxEmpty')).toBeInTheDocument();
- expect(queryByTestId('DonationHistoriesGridLoading')).not.toBeInTheDocument();
- });
+ it('empty periods', () => {
+ reportsDonationHistories = {
+ periods: [
+ {
+ convertedTotal: 0,
+ startDate: '1-1-2019',
+ totals: [{ currency: 'USD', convertedAmount: 0 }],
+ },
+ {
+ convertedTotal: 0,
+ startDate: '1-2-2019',
+ totals: [{ currency: 'NZD', convertedAmount: 0 }],
+ },
+ ],
+ averageIgnoreCurrent: 0,
+ };
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('DonationHistoriesBoxEmpty')).toBeInTheDocument();
+ expect(
+ queryByTestId('DonationHistoriesGridLoading'),
+ ).not.toBeInTheDocument();
+ });
- it('loading', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('DonationHistoriesGridLoading')).toBeInTheDocument();
- expect(queryByTestId('DonationHistoriesBoxEmpty')).not.toBeInTheDocument();
- });
+ it('loading', () => {
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('DonationHistoriesGridLoading')).toBeInTheDocument();
+ expect(queryByTestId('DonationHistoriesBoxEmpty')).not.toBeInTheDocument();
+ });
- describe('populated periods', () => {
- beforeEach(() => {
- reportsDonationHistories = {
- periods: [
- {
- convertedTotal: 50,
- startDate: '1-1-2019',
- totals: [{ currency: 'USD', convertedAmount: 50 }],
- },
- {
- convertedTotal: 60,
- startDate: '1-2-2019',
- totals: [{ currency: 'NZD', convertedAmount: 60 }],
- },
- ],
- averageIgnoreCurrent: 1000,
- };
- });
+ describe('populated periods', () => {
+ beforeEach(() => {
+ reportsDonationHistories = {
+ periods: [
+ {
+ convertedTotal: 50,
+ startDate: '1-1-2019',
+ totals: [{ currency: 'USD', convertedAmount: 50 }],
+ },
+ {
+ convertedTotal: 60,
+ startDate: '1-2-2019',
+ totals: [{ currency: 'NZD', convertedAmount: 60 }],
+ },
+ ],
+ averageIgnoreCurrent: 1000,
+ };
+ });
- it('shows references', () => {
- const { getByTestId } = render(
- ,
- );
- expect(getByTestId('DonationHistoriesTypographyGoal').textContent).toEqual('Goal $100');
- expect(getByTestId('DonationHistoriesTypographyAverage').textContent).toEqual('Average $1,000');
- expect(getByTestId('DonationHistoriesTypographyPledged').textContent).toEqual('Committed $2,500');
- });
+ it('shows references', () => {
+ const { getByTestId } = render(
+ ,
+ );
+ expect(
+ getByTestId('DonationHistoriesTypographyGoal').textContent,
+ ).toEqual('Goal $100');
+ expect(
+ getByTestId('DonationHistoriesTypographyAverage').textContent,
+ ).toEqual('Average $1,000');
+ expect(
+ getByTestId('DonationHistoriesTypographyPledged').textContent,
+ ).toEqual('Committed $2,500');
});
+ });
});
diff --git a/src/components/Dashboard/DonationHistories/DonationHistories.tsx b/src/components/Dashboard/DonationHistories/DonationHistories.tsx
index ecdb1decae..46eaac08ee 100644
--- a/src/components/Dashboard/DonationHistories/DonationHistories.tsx
+++ b/src/components/Dashboard/DonationHistories/DonationHistories.tsx
@@ -1,16 +1,24 @@
import React, { ReactElement } from 'react';
-import { CardContent, Box, Typography, Grid, CardHeader, makeStyles, Theme } from '@material-ui/core';
import {
- ReferenceLine,
- BarChart,
- Bar,
- XAxis,
- YAxis,
- CartesianGrid,
- Tooltip,
- Legend,
- ResponsiveContainer,
- Text,
+ CardContent,
+ Box,
+ Typography,
+ Grid,
+ CardHeader,
+ makeStyles,
+ Theme,
+} from '@material-ui/core';
+import {
+ ReferenceLine,
+ BarChart,
+ Bar,
+ XAxis,
+ YAxis,
+ CartesianGrid,
+ Tooltip,
+ Legend,
+ ResponsiveContainer,
+ Text,
} from 'recharts';
import moment from 'moment';
import { Skeleton } from '@material-ui/lab';
@@ -21,262 +29,313 @@ import AnimatedBox from '../../AnimatedBox';
import illustration15 from '../../../images/drawkit/grape/drawkit-grape-pack-illustration-15.svg';
const useStyles = makeStyles((theme: Theme) => ({
- cardHeader: {
- textAlign: 'center',
- },
- lineKey: {
- display: 'inline-block',
- height: '5px',
- width: '20px',
- marginRight: '10px',
- marginBottom: '4px',
- borderRadius: '5px',
- },
- lineKeyGoal: {
- backgroundColor: '#17AEBF',
- },
- lineKeyAverage: {
- backgroundColor: '#9C9FA1',
- },
- lineKeyPledged: {
- backgroundColor: '#FFCF07',
- },
- boxImg: {
- display: 'flex',
- flex: 1,
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- padding: theme.spacing(2),
- [theme.breakpoints.down('xs')]: {
- padding: theme.spacing(0),
- },
+ cardHeader: {
+ textAlign: 'center',
+ },
+ lineKey: {
+ display: 'inline-block',
+ height: '5px',
+ width: '20px',
+ marginRight: '10px',
+ marginBottom: '4px',
+ borderRadius: '5px',
+ },
+ lineKeyGoal: {
+ backgroundColor: '#17AEBF',
+ },
+ lineKeyAverage: {
+ backgroundColor: '#9C9FA1',
+ },
+ lineKeyPledged: {
+ backgroundColor: '#FFCF07',
+ },
+ boxImg: {
+ display: 'flex',
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ padding: theme.spacing(2),
+ [theme.breakpoints.down('xs')]: {
+ padding: theme.spacing(0),
},
- img: {
- height: '248px',
- marginBottom: theme.spacing(2),
- [theme.breakpoints.down('xs')]: {
- height: '114px',
- },
+ },
+ img: {
+ height: '248px',
+ marginBottom: theme.spacing(2),
+ [theme.breakpoints.down('xs')]: {
+ height: '114px',
},
+ },
}));
interface Props {
- loading?: boolean;
- reportsDonationHistories?: {
- periods: {
- convertedTotal: number;
- startDate: string;
- totals: { currency: string; convertedAmount: number }[];
- }[];
- averageIgnoreCurrent: number;
- };
- currencyCode?: string;
- goal?: number;
- pledged?: number;
+ loading?: boolean;
+ reportsDonationHistories?: {
+ periods: {
+ convertedTotal: number;
+ startDate: string;
+ totals: { currency: string; convertedAmount: number }[];
+ }[];
+ averageIgnoreCurrent: number;
+ };
+ currencyCode?: string;
+ goal?: number;
+ pledged?: number;
}
const DonationHistories = ({
- loading,
- reportsDonationHistories,
- goal,
- pledged,
- currencyCode = 'USD',
+ loading,
+ reportsDonationHistories,
+ goal,
+ pledged,
+ currencyCode = 'USD',
}: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const fills = ['#FFCF07', '#30F2F2', '#1FC0D2', '#007398'];
- const currencies: { dataKey: string; fill: string }[] = [];
- const periods = reportsDonationHistories?.periods?.map((period) => {
- const data = { startDate: moment(period.startDate).format('MMM YY'), total: period.convertedTotal };
- period.totals.forEach((total) => {
- if (!currencies.find((currency) => total.currency == currency.dataKey)) {
- currencies.push({ dataKey: total.currency, fill: fills.pop() });
- }
- data[total.currency] = total.convertedAmount;
- });
- return data;
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const fills = ['#FFCF07', '#30F2F2', '#1FC0D2', '#007398'];
+ const currencies: { dataKey: string; fill: string }[] = [];
+ const periods = reportsDonationHistories?.periods?.map((period) => {
+ const data = {
+ startDate: moment(period.startDate).format('MMM YY'),
+ total: period.convertedTotal,
+ };
+ period.totals.forEach((total) => {
+ if (!currencies.find((currency) => total.currency == currency.dataKey)) {
+ currencies.push({ dataKey: total.currency, fill: fills.pop() });
+ }
+ data[total.currency] = total.convertedAmount;
});
- const empty = !loading && (periods === undefined || periods.reduce((result, { total }) => result + total, 0) === 0);
+ return data;
+ });
+ const empty =
+ !loading &&
+ (periods === undefined ||
+ periods.reduce((result, { total }) => result + total, 0) === 0);
- return (
- <>
-
-
- Monthly Activity
-
+ return (
+ <>
+
+
+ Monthly Activity
+
+
+
+ {!empty && (
+
+
+
+ {goal ? (
+ <>
+
+
+
+ {t('Goal')}{' '}
+ {currencyFormat(goal, currencyCode)}
+
+
+ |
+ >
+ ) : null}
+
+
+
+ {t('Average')}{' '}
+ {loading ? (
+
+ ) : (
+ currencyFormat(
+ reportsDonationHistories.averageIgnoreCurrent,
+ currencyCode,
+ )
+ )}
+
+
+ {pledged ? (
+ <>
+ |
+
+
+
+ {t('Committed')}{' '}
+ {currencyFormat(pledged, currencyCode)}
+
+
+ >
+ ) : null}
+
+
+ }
+ />
+
+ )}
+
+ {empty ? (
+
+
+ {t('No monthly activity to show.')}
-
- {!empty && (
-
-
-
- {goal ? (
- <>
-
-
-
- {t('Goal')}{' '}
- {currencyFormat(goal, currencyCode)}
-
-
- |
- >
- ) : null}
-
-
-
- {t('Average')}{' '}
- {loading ? (
-
- ) : (
- currencyFormat(
- reportsDonationHistories.averageIgnoreCurrent,
- currencyCode,
- )
- )}
-
-
- {pledged ? (
- <>
- |
-
-
-
- {t('Committed')}{' '}
- {currencyFormat(pledged, currencyCode)}
-
-
- >
- ) : null}
-
-
+ ) : (
+ <>
+
+ {loading ? (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ) : (
+
+
+
+
+ {goal && (
+
+ )}
+
+ {pledged && (
+
+ )}
+
+
+ {
+ t('Amount ({{ currencyCode }})', {
+ currencyCode,
+ }) as string
}
+
+ }
+ />
+
+ {currencies.map((currency) => (
+
-
+ ))}
+
+
+ )}
+
+
+ {loading ? (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ) : (
+
+
+
+
+
+
+
)}
-
- {empty ? (
-
-
- {t('No monthly activity to show.')}
-
- ) : (
- <>
-
- {loading ? (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ) : (
-
-
-
-
- {goal && }
-
- {pledged && }
-
-
- {t('Amount ({{ currencyCode }})', { currencyCode }) as string}
-
- }
- />
-
- {currencies.map((currency) => (
-
- ))}
-
-
- )}
-
-
- {loading ? (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ) : (
-
-
-
-
-
-
-
- )}
-
- >
- )}
-
-
- >
- );
+
+ >
+ )}
+
+
+ >
+ );
};
export default DonationHistories;
diff --git a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.stories.tsx b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.stories.tsx
index 738d198899..d09e004aa4 100644
--- a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.stories.tsx
+++ b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.stories.tsx
@@ -3,42 +3,52 @@ import { Box } from '@material-ui/core';
import MonthlyGoal from '.';
export default {
- title: 'Dashboard/MonthlyGoal',
+ title: 'Dashboard/MonthlyGoal',
};
export const Default = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const WhenMin = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const WhenMax = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.test.tsx b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.test.tsx
index 7a55fd0c8f..15d082b402 100644
--- a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.test.tsx
+++ b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.test.tsx
@@ -4,86 +4,170 @@ import matchMediaMock from '../../../../__tests__/util/matchMediaMock';
import MonthlyGoal from '.';
describe('MonthlyGoal', () => {
- beforeEach(() => {
- matchMediaMock({ width: '1024px' });
- });
+ beforeEach(() => {
+ matchMediaMock({ width: '1024px' });
+ });
- it('default', () => {
- const { getByTestId, queryByTestId } = render();
- expect(queryByTestId('MonthlyGoalTypographyGoalMobile')).not.toBeInTheDocument();
- expect(getByTestId('MonthlyGoalTypographyGoal').textContent).toEqual('$0');
- expect(getByTestId('MonthlyGoalTypographyReceivedPercentage').textContent).toEqual('-');
- expect(getByTestId('MonthlyGoalTypographyReceived').textContent).toEqual('$0');
- expect(getByTestId('MonthlyGoalTypographyPledgedPercentage').textContent).toEqual('-');
- expect(getByTestId('MonthlyGoalTypographyPledged').textContent).toEqual('$0');
- expect(queryByTestId('MonthlyGoalTypographyBelowGoalPercentage')).not.toBeInTheDocument();
- expect(queryByTestId('MonthlyGoalTypographyBelowGoal')).not.toBeInTheDocument();
- expect(getByTestId('MonthlyGoalTypographyAboveGoalPercentage').textContent).toEqual('-');
- expect(getByTestId('MonthlyGoalTypographyAboveGoal').textContent).toEqual('$0');
- });
+ it('default', () => {
+ const { getByTestId, queryByTestId } = render();
+ expect(
+ queryByTestId('MonthlyGoalTypographyGoalMobile'),
+ ).not.toBeInTheDocument();
+ expect(getByTestId('MonthlyGoalTypographyGoal').textContent).toEqual('$0');
+ expect(
+ getByTestId('MonthlyGoalTypographyReceivedPercentage').textContent,
+ ).toEqual('-');
+ expect(getByTestId('MonthlyGoalTypographyReceived').textContent).toEqual(
+ '$0',
+ );
+ expect(
+ getByTestId('MonthlyGoalTypographyPledgedPercentage').textContent,
+ ).toEqual('-');
+ expect(getByTestId('MonthlyGoalTypographyPledged').textContent).toEqual(
+ '$0',
+ );
+ expect(
+ queryByTestId('MonthlyGoalTypographyBelowGoalPercentage'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('MonthlyGoalTypographyBelowGoal'),
+ ).not.toBeInTheDocument();
+ expect(
+ getByTestId('MonthlyGoalTypographyAboveGoalPercentage').textContent,
+ ).toEqual('-');
+ expect(getByTestId('MonthlyGoalTypographyAboveGoal').textContent).toEqual(
+ '$0',
+ );
+ });
- it('loading', () => {
- const { getByTestId } = render();
- expect(getByTestId('MonthlyGoalTypographyGoal').children[0].className).toContain('MuiSkeleton-root');
- expect(getByTestId('MonthlyGoalTypographyReceivedPercentage').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('MonthlyGoalTypographyReceived').children[0].className).toContain('MuiSkeleton-root');
- expect(getByTestId('MonthlyGoalTypographyPledgedPercentage').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('MonthlyGoalTypographyPledged').children[0].className).toContain('MuiSkeleton-root');
- expect(getByTestId('MonthlyGoalTypographyAboveGoalPercentage').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('MonthlyGoalTypographyAboveGoal').children[0].className).toContain('MuiSkeleton-root');
- });
+ it('loading', () => {
+ const { getByTestId } = render();
+ expect(
+ getByTestId('MonthlyGoalTypographyGoal').children[0].className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('MonthlyGoalTypographyReceivedPercentage').children[0]
+ .className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('MonthlyGoalTypographyReceived').children[0].className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('MonthlyGoalTypographyPledgedPercentage').children[0]
+ .className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('MonthlyGoalTypographyPledged').children[0].className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('MonthlyGoalTypographyAboveGoalPercentage').children[0]
+ .className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('MonthlyGoalTypographyAboveGoal').children[0].className,
+ ).toContain('MuiSkeleton-root');
+ });
- it('props', () => {
- const { getByTestId, queryByTestId } = render(
- ,
- );
- expect(getByTestId('MonthlyGoalTypographyGoal').textContent).toEqual('€1,000');
- expect(getByTestId('MonthlyGoalTypographyReceivedPercentage').textContent).toEqual('50%');
- expect(getByTestId('MonthlyGoalTypographyReceived').textContent).toEqual('€500');
- expect(getByTestId('MonthlyGoalTypographyPledgedPercentage').textContent).toEqual('75%');
- expect(getByTestId('MonthlyGoalTypographyPledged').textContent).toEqual('€750');
- expect(getByTestId('MonthlyGoalTypographyBelowGoalPercentage').textContent).toEqual('25%');
- expect(getByTestId('MonthlyGoalTypographyBelowGoal').textContent).toEqual('€250');
- expect(queryByTestId('MonthlyGoalTypographyAboveGoalPercentage')).not.toBeInTheDocument();
- expect(queryByTestId('MonthlyGoalTypographyAboveGoal')).not.toBeInTheDocument();
- });
+ it('props', () => {
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('MonthlyGoalTypographyGoal').textContent).toEqual(
+ '€1,000',
+ );
+ expect(
+ getByTestId('MonthlyGoalTypographyReceivedPercentage').textContent,
+ ).toEqual('50%');
+ expect(getByTestId('MonthlyGoalTypographyReceived').textContent).toEqual(
+ '€500',
+ );
+ expect(
+ getByTestId('MonthlyGoalTypographyPledgedPercentage').textContent,
+ ).toEqual('75%');
+ expect(getByTestId('MonthlyGoalTypographyPledged').textContent).toEqual(
+ '€750',
+ );
+ expect(
+ getByTestId('MonthlyGoalTypographyBelowGoalPercentage').textContent,
+ ).toEqual('25%');
+ expect(getByTestId('MonthlyGoalTypographyBelowGoal').textContent).toEqual(
+ '€250',
+ );
+ expect(
+ queryByTestId('MonthlyGoalTypographyAboveGoalPercentage'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('MonthlyGoalTypographyAboveGoal'),
+ ).not.toBeInTheDocument();
+ });
- it('props above goal', () => {
- const { getByTestId, queryByTestId } = render(
- ,
- );
- expect(getByTestId('MonthlyGoalTypographyReceivedPercentage').textContent).toEqual('500%');
- expect(getByTestId('MonthlyGoalTypographyPledgedPercentage').textContent).toEqual('750%');
- expect(getByTestId('MonthlyGoalTypographyAboveGoalPercentage').textContent).toEqual('650%');
- expect(getByTestId('MonthlyGoalTypographyAboveGoal').textContent).toEqual('€6,501');
- expect(queryByTestId('MonthlyGoalTypographyBelowGoalPercentage')).not.toBeInTheDocument();
- expect(queryByTestId('MonthlyGoalTypographyBelowGoal')).not.toBeInTheDocument();
- });
+ it('props above goal', () => {
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(
+ getByTestId('MonthlyGoalTypographyReceivedPercentage').textContent,
+ ).toEqual('500%');
+ expect(
+ getByTestId('MonthlyGoalTypographyPledgedPercentage').textContent,
+ ).toEqual('750%');
+ expect(
+ getByTestId('MonthlyGoalTypographyAboveGoalPercentage').textContent,
+ ).toEqual('650%');
+ expect(getByTestId('MonthlyGoalTypographyAboveGoal').textContent).toEqual(
+ '€6,501',
+ );
+ expect(
+ queryByTestId('MonthlyGoalTypographyBelowGoalPercentage'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('MonthlyGoalTypographyBelowGoal'),
+ ).not.toBeInTheDocument();
+ });
- describe('mobile', () => {
- beforeEach(() => {
- matchMediaMock({ width: '599px' });
- });
+ describe('mobile', () => {
+ beforeEach(() => {
+ matchMediaMock({ width: '599px' });
+ });
- it('default', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('MonthlyGoalTypographyGoalMobile').textContent).toEqual('$0');
- expect(queryByTestId('MonthlyGoalTypographyGoal')).not.toBeInTheDocument();
- expect(queryByTestId('MonthlyGoalTypographyAboveGoalPercentage')).not.toBeInTheDocument();
- expect(queryByTestId('MonthlyGoalTypographyAboveGoal')).not.toBeInTheDocument();
- });
+ it('default', () => {
+ const { getByTestId, queryByTestId } = render();
+ expect(
+ getByTestId('MonthlyGoalTypographyGoalMobile').textContent,
+ ).toEqual('$0');
+ expect(
+ queryByTestId('MonthlyGoalTypographyGoal'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('MonthlyGoalTypographyAboveGoalPercentage'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('MonthlyGoalTypographyAboveGoal'),
+ ).not.toBeInTheDocument();
+ });
- it('props', () => {
- const { getByTestId } = render(
- ,
- );
- expect(getByTestId('MonthlyGoalTypographyGoalMobile').textContent).toEqual('€1,000');
- });
+ it('props', () => {
+ const { getByTestId } = render(
+ ,
+ );
+ expect(
+ getByTestId('MonthlyGoalTypographyGoalMobile').textContent,
+ ).toEqual('€1,000');
});
+ });
});
diff --git a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.tsx b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.tsx
index c7574c07f9..da3c689ac2 100644
--- a/src/components/Dashboard/MonthlyGoal/MonthlyGoal.tsx
+++ b/src/components/Dashboard/MonthlyGoal/MonthlyGoal.tsx
@@ -1,5 +1,13 @@
import React, { ReactElement } from 'react';
-import { Typography, makeStyles, Theme, Grid, CardContent, Box, Hidden } from '@material-ui/core';
+import {
+ Typography,
+ makeStyles,
+ Theme,
+ Grid,
+ CardContent,
+ Box,
+ Hidden,
+} from '@material-ui/core';
import { Skeleton } from '@material-ui/lab';
import { useTranslation } from 'react-i18next';
import { currencyFormat, percentageFormat } from '../../../lib/intlFormat';
@@ -8,150 +16,205 @@ import AnimatedBox from '../../AnimatedBox';
import StyledProgress from '../../StyledProgress';
const useStyles = makeStyles((_theme: Theme) => ({
- received: {
- background: 'linear-gradient(180deg, #FFE67C 0%, #FFCF07 100%)',
- },
- pledged: {
- border: '5px solid #FFCF07',
- },
- goal: {
- border: '2px solid #999999',
- },
- indicator: {
- display: 'inline-block',
- borderRadius: '18px',
- width: '18px',
- height: '18px',
- marginRight: '5px',
- marginBottom: '-3px',
- },
+ received: {
+ background: 'linear-gradient(180deg, #FFE67C 0%, #FFCF07 100%)',
+ },
+ pledged: {
+ border: '5px solid #FFCF07',
+ },
+ goal: {
+ border: '2px solid #999999',
+ },
+ indicator: {
+ display: 'inline-block',
+ borderRadius: '18px',
+ width: '18px',
+ height: '18px',
+ marginRight: '5px',
+ marginBottom: '-3px',
+ },
}));
interface Props {
- loading?: boolean;
- goal?: number;
- received?: number;
- pledged?: number;
- currencyCode?: string;
+ loading?: boolean;
+ goal?: number;
+ received?: number;
+ pledged?: number;
+ currencyCode?: string;
}
-const MonthlyGoal = ({ loading, goal, received, pledged, currencyCode = 'USD' }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const receivedPercentage = received / goal;
- const pledgedPercentage = pledged / goal;
- const belowGoal = goal - pledged;
- const belowGoalPercentage = belowGoal / goal;
+const MonthlyGoal = ({
+ loading,
+ goal,
+ received,
+ pledged,
+ currencyCode = 'USD',
+}: Props): ReactElement => {
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const receivedPercentage = received / goal;
+ const pledgedPercentage = pledged / goal;
+ const belowGoal = goal - pledged;
+ const belowGoalPercentage = belowGoal / goal;
- return (
- <>
-
-
-
-
- {t('Monthly Goal')}
-
-
- {!loading && currencyFormat(goal, currencyCode)}
-
-
-
-
-
+ return (
+ <>
+
+
+
+
+ {t('Monthly Goal')}
+
+
+ {!loading && currencyFormat(goal, currencyCode)}
+
+
-
-
-
-
-
-
-
-
- {t('Goal')}
-
-
- {loading ? : currencyFormat(goal, currencyCode)}
-
-
-
-
-
-
- {t('Gifts Started')}
-
-
- {loading ? (
-
- ) : isNaN(receivedPercentage) ? (
- '-'
- ) : (
- percentageFormat(receivedPercentage)
- )}
-
-
- {loading ? : currencyFormat(received, currencyCode)}
-
-
-
-
-
- {t('Commitments')}
-
-
- {loading ? (
-
- ) : isNaN(pledgedPercentage) ? (
- '-'
- ) : (
- percentageFormat(pledgedPercentage)
- )}
-
-
- {loading ? : currencyFormat(pledged, currencyCode)}
-
-
-
- {!isNaN(belowGoal) && belowGoal > 0 ? (
-
-
- {t('Below Goal')}
-
-
- {percentageFormat(belowGoalPercentage)}
-
-
- {currencyFormat(belowGoal, currencyCode)}
-
-
- ) : (
-
-
- {t('Above Goal')}
-
-
- {loading ? (
-
- ) : isNaN(belowGoalPercentage) ? (
- '-'
- ) : (
- percentageFormat(-belowGoalPercentage)
- )}
-
-
- {loading ? (
-
- ) : (
- currencyFormat(-belowGoal, currencyCode)
- )}
-
-
- )}
-
-
-
-
- >
- );
+
+
+
+
+
+
+
+
+
+
+
+ {t('Goal')}
+
+
+ {loading ? (
+
+ ) : (
+ currencyFormat(goal, currencyCode)
+ )}
+
+
+
+
+
+
+ {t('Gifts Started')}
+
+
+ {loading ? (
+
+ ) : isNaN(receivedPercentage) ? (
+ '-'
+ ) : (
+ percentageFormat(receivedPercentage)
+ )}
+
+
+ {loading ? (
+
+ ) : (
+ currencyFormat(received, currencyCode)
+ )}
+
+
+
+
+
+ {t('Commitments')}
+
+
+ {loading ? (
+
+ ) : isNaN(pledgedPercentage) ? (
+ '-'
+ ) : (
+ percentageFormat(pledgedPercentage)
+ )}
+
+
+ {loading ? (
+
+ ) : (
+ currencyFormat(pledged, currencyCode)
+ )}
+
+
+
+ {!isNaN(belowGoal) && belowGoal > 0 ? (
+
+
+ {t('Below Goal')}
+
+
+ {percentageFormat(belowGoalPercentage)}
+
+
+ {currencyFormat(belowGoal, currencyCode)}
+
+
+ ) : (
+
+
+ {t('Above Goal')}
+
+
+ {loading ? (
+
+ ) : isNaN(belowGoalPercentage) ? (
+ '-'
+ ) : (
+ percentageFormat(-belowGoalPercentage)
+ )}
+
+
+ {loading ? (
+
+ ) : (
+ currencyFormat(-belowGoal, currencyCode)
+ )}
+
+
+ )}
+
+
+
+
+ >
+ );
};
export default MonthlyGoal;
diff --git a/src/components/Dashboard/ThisWeek/Appeals/Appeals.stories.tsx b/src/components/Dashboard/ThisWeek/Appeals/Appeals.stories.tsx
index 361f1bc794..5a614433b5 100644
--- a/src/components/Dashboard/ThisWeek/Appeals/Appeals.stories.tsx
+++ b/src/components/Dashboard/ThisWeek/Appeals/Appeals.stories.tsx
@@ -4,37 +4,37 @@ import { GetThisWeekQuery_accountList_primaryAppeal } from '../../../../../types
import Appeals from '.';
export default {
- title: 'Dashboard/ThisWeek/Appeals',
+ title: 'Dashboard/ThisWeek/Appeals',
};
export const Default = (): ReactElement => {
- const appeal: GetThisWeekQuery_accountList_primaryAppeal = {
- id: 'appeal',
- name: '2020 End of Year Ask With Really long Appeal Name!',
- amount: 1000,
- pledgesAmountTotal: 750,
- pledgesAmountProcessed: 500,
- amountCurrency: 'GBP',
- };
- return (
-
-
-
- );
+ const appeal: GetThisWeekQuery_accountList_primaryAppeal = {
+ id: 'appeal',
+ name: '2020 End of Year Ask With Really long Appeal Name!',
+ amount: 1000,
+ pledgesAmountTotal: 750,
+ pledgesAmountProcessed: 500,
+ amountCurrency: 'GBP',
+ };
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Dashboard/ThisWeek/Appeals/Appeals.test.tsx b/src/components/Dashboard/ThisWeek/Appeals/Appeals.test.tsx
index 8d7e8f9c04..6bc68cc4bf 100644
--- a/src/components/Dashboard/ThisWeek/Appeals/Appeals.test.tsx
+++ b/src/components/Dashboard/ThisWeek/Appeals/Appeals.test.tsx
@@ -3,44 +3,65 @@ import { render } from '@testing-library/react';
import Appeals from '.';
describe('Appeals', () => {
- it('default', () => {
- const { getByTestId } = render();
- expect(getByTestId('AppealsCardContentEmpty')).toBeInTheDocument();
- });
+ it('default', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('AppealsCardContentEmpty')).toBeInTheDocument();
+ });
- it('loading', () => {
- const { getByTestId, getByRole } = render();
- expect(getByTestId('AppealsBoxName').children[0].className).toContain('MuiSkeleton-root');
- expect(getByTestId('AppealsBoxAmount').children[0].className).toContain('MuiSkeleton-root');
- expect(getByTestId('AppealsTypographyPledgesAmountProcessedPercentage').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('AppealsTypographyPledgesAmountProcessed').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('AppealsTypographyPledgesAmountTotalPercentage').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('AppealsTypographyPledgesAmountTotal').children[0].className).toContain('MuiSkeleton-root');
- expect(getByRole('link', { name: 'View All' })).toHaveAttribute('href', 'https://stage.mpdx.org/tools/appeals');
- });
+ it('loading', () => {
+ const { getByTestId, getByRole } = render();
+ expect(getByTestId('AppealsBoxName').children[0].className).toContain(
+ 'MuiSkeleton-root',
+ );
+ expect(getByTestId('AppealsBoxAmount').children[0].className).toContain(
+ 'MuiSkeleton-root',
+ );
+ expect(
+ getByTestId('AppealsTypographyPledgesAmountProcessedPercentage')
+ .children[0].className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('AppealsTypographyPledgesAmountProcessed').children[0]
+ .className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('AppealsTypographyPledgesAmountTotalPercentage').children[0]
+ .className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('AppealsTypographyPledgesAmountTotal').children[0].className,
+ ).toContain('MuiSkeleton-root');
+ expect(getByRole('link', { name: 'View All' })).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/tools/appeals',
+ );
+ });
- it('props', () => {
- const appeal = {
- id: 'appealId',
- name: 'My Appeal',
- amount: 4999.99,
- pledgesAmountTotal: 2499.99,
- pledgesAmountProcessed: 999.99,
- amountCurrency: 'EUR',
- };
- const { getByTestId } = render();
+ it('props', () => {
+ const appeal = {
+ id: 'appealId',
+ name: 'My Appeal',
+ amount: 4999.99,
+ pledgesAmountTotal: 2499.99,
+ pledgesAmountProcessed: 999.99,
+ amountCurrency: 'EUR',
+ };
+ const { getByTestId } = render();
- expect(getByTestId('AppealsBoxName').textContent).toEqual('My Appeal');
- expect(getByTestId('AppealsBoxAmount').textContent).toEqual('€5,000');
- expect(getByTestId('AppealsTypographyPledgesAmountProcessedPercentage').textContent).toEqual('20%');
- expect(getByTestId('AppealsTypographyPledgesAmountProcessed').textContent).toEqual('€1,000');
- expect(getByTestId('AppealsTypographyPledgesAmountTotalPercentage').textContent).toEqual('50%');
- expect(getByTestId('AppealsTypographyPledgesAmountTotal').textContent).toEqual('€2,500');
- });
+ expect(getByTestId('AppealsBoxName').textContent).toEqual('My Appeal');
+ expect(getByTestId('AppealsBoxAmount').textContent).toEqual('€5,000');
+ expect(
+ getByTestId('AppealsTypographyPledgesAmountProcessedPercentage')
+ .textContent,
+ ).toEqual('20%');
+ expect(
+ getByTestId('AppealsTypographyPledgesAmountProcessed').textContent,
+ ).toEqual('€1,000');
+ expect(
+ getByTestId('AppealsTypographyPledgesAmountTotalPercentage').textContent,
+ ).toEqual('50%');
+ expect(
+ getByTestId('AppealsTypographyPledgesAmountTotal').textContent,
+ ).toEqual('€2,500');
+ });
});
diff --git a/src/components/Dashboard/ThisWeek/Appeals/Appeals.tsx b/src/components/Dashboard/ThisWeek/Appeals/Appeals.tsx
index b7962c7aab..556f6b3a48 100644
--- a/src/components/Dashboard/ThisWeek/Appeals/Appeals.tsx
+++ b/src/components/Dashboard/ThisWeek/Appeals/Appeals.tsx
@@ -1,14 +1,14 @@
import React, { ReactElement } from 'react';
import {
- makeStyles,
- Theme,
- CardHeader,
- CardActions,
- Button,
- CardContent,
- Typography,
- Grid,
- Box,
+ makeStyles,
+ Theme,
+ CardHeader,
+ CardActions,
+ Button,
+ CardContent,
+ Typography,
+ Grid,
+ Box,
} from '@material-ui/core';
import { Skeleton } from '@material-ui/lab';
import { motion } from 'framer-motion';
@@ -21,183 +21,224 @@ import HandoffLink from '../../../HandoffLink';
import illustration13 from '../../../../images/drawkit/grape/drawkit-grape-pack-illustration-13.svg';
const useStyles = makeStyles((theme: Theme) => ({
- div: {
- flex: 1,
- display: 'flex',
- flexDirection: 'column',
- overflow: 'auto',
+ div: {
+ flex: 1,
+ display: 'flex',
+ flexDirection: 'column',
+ overflow: 'auto',
+ },
+ list: {
+ flex: 1,
+ padding: 0,
+ overflow: 'auto',
+ },
+ card: {
+ display: 'flex',
+ flexDirection: 'column',
+ height: '322px',
+ [theme.breakpoints.down('xs')]: {
+ height: 'auto',
},
- list: {
- flex: 1,
- padding: 0,
- overflow: 'auto',
- },
- card: {
- display: 'flex',
- flexDirection: 'column',
- height: '322px',
- [theme.breakpoints.down('xs')]: {
- height: 'auto',
- },
- },
- cardContent: {
- display: 'flex',
- flex: 1,
- flexDirection: 'column',
- justifyContent: 'center',
- alignItems: 'center',
- padding: theme.spacing(2),
- },
- cardContentExpanded: {
- padding: theme.spacing(0, 2),
- [theme.breakpoints.down('xs')]: {
- padding: theme.spacing(2),
- },
- },
- img: {
- height: '150px',
- marginBottom: theme.spacing(2),
- },
- pledgesAmountProcessed: {
- background: 'linear-gradient(180deg, #FFE67C 0%, #FFCF07 100%)',
- },
- pledgesAmountTotal: {
- border: '5px solid #FFCF07',
- },
- indicator: {
- display: 'inline-block',
- borderRadius: '18px',
- width: '18px',
- height: '18px',
- marginRight: '5px',
- marginBottom: '-3px',
- },
- titleContainer: {
- width: '100%',
- },
- title: {
- display: 'flex',
- marginBottom: theme.spacing(1),
- whiteSpace: 'nowrap',
- },
- titleContent: {
- flexGrow: 1,
- textOverflow: 'ellipsis',
- overflow: 'hidden',
+ },
+ cardContent: {
+ display: 'flex',
+ flex: 1,
+ flexDirection: 'column',
+ justifyContent: 'center',
+ alignItems: 'center',
+ padding: theme.spacing(2),
+ },
+ cardContentExpanded: {
+ padding: theme.spacing(0, 2),
+ [theme.breakpoints.down('xs')]: {
+ padding: theme.spacing(2),
},
+ },
+ img: {
+ height: '150px',
+ marginBottom: theme.spacing(2),
+ },
+ pledgesAmountProcessed: {
+ background: 'linear-gradient(180deg, #FFE67C 0%, #FFCF07 100%)',
+ },
+ pledgesAmountTotal: {
+ border: '5px solid #FFCF07',
+ },
+ indicator: {
+ display: 'inline-block',
+ borderRadius: '18px',
+ width: '18px',
+ height: '18px',
+ marginRight: '5px',
+ marginBottom: '-3px',
+ },
+ titleContainer: {
+ width: '100%',
+ },
+ title: {
+ display: 'flex',
+ marginBottom: theme.spacing(1),
+ whiteSpace: 'nowrap',
+ },
+ titleContent: {
+ flexGrow: 1,
+ textOverflow: 'ellipsis',
+ overflow: 'hidden',
+ },
}));
interface Props {
- loading?: boolean;
- appeal?: GetThisWeekQuery_accountList_primaryAppeal;
+ loading?: boolean;
+ appeal?: GetThisWeekQuery_accountList_primaryAppeal;
}
const Appeals = ({ loading, appeal }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const pledgesAmountProcessedPercentage = (appeal?.pledgesAmountProcessed || 0) / (appeal?.amount || 0);
- const pledgesAmountTotalPercentage = (appeal?.pledgesAmountTotal || 0) / (appeal?.amount || 0);
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const pledgesAmountProcessedPercentage =
+ (appeal?.pledgesAmountProcessed || 0) / (appeal?.amount || 0);
+ const pledgesAmountTotalPercentage =
+ (appeal?.pledgesAmountTotal || 0) / (appeal?.amount || 0);
- return (
-
-
- {!loading && !appeal && (
-
-
-
- {t('No primary appeal to show.')}
-
-
+ return (
+
+
+ {!loading && !appeal && (
+
+
+
+ {t('No primary appeal to show.')}
+
+
+ )}
+ {(loading || appeal) && (
+
+
+
+
+
-
-
-
-
- {loading ? : appeal.name}
-
-
- {loading ? (
-
- ) : (
- currencyFormat(appeal.amount, appeal.amountCurrency)
- )}
-
-
-
-
-
-
-
-
- {t('Gifts Received')}
-
-
- {loading ? (
-
- ) : (
- percentageFormat(pledgesAmountProcessedPercentage)
- )}
-
-
- {loading ? (
-
- ) : (
- currencyFormat(appeal.pledgesAmountProcessed, appeal.amountCurrency)
- )}
-
-
-
-
-
- {t('Commitments')}
-
-
- {loading ? (
-
- ) : (
- percentageFormat(pledgesAmountTotalPercentage)
- )}
-
-
- {loading ? (
-
- ) : (
- currencyFormat(appeal.pledgesAmountTotal, appeal.amountCurrency)
- )}
-
-
-
-
-
-
-
-
-
-
- )}
-
- );
+ {loading ? (
+
+ ) : (
+ appeal.name
+ )}
+
+
+ {loading ? (
+
+ ) : (
+ currencyFormat(appeal.amount, appeal.amountCurrency)
+ )}
+
+
+
+
+
+
+
+
+ {t('Gifts Received')}
+
+
+ {loading ? (
+
+ ) : (
+ percentageFormat(pledgesAmountProcessedPercentage)
+ )}
+
+
+ {loading ? (
+
+ ) : (
+ currencyFormat(
+ appeal.pledgesAmountProcessed,
+ appeal.amountCurrency,
+ )
+ )}
+
+
+
+
+
+ {t('Commitments')}
+
+
+ {loading ? (
+
+ ) : (
+ percentageFormat(pledgesAmountTotalPercentage)
+ )}
+
+
+ {loading ? (
+
+ ) : (
+ currencyFormat(
+ appeal.pledgesAmountTotal,
+ appeal.amountCurrency,
+ )
+ )}
+
+
+
+
+
+
+
+
+
+
+ )}
+
+ );
};
export default Appeals;
diff --git a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.stories.tsx b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.stories.tsx
index 3ce9aa9073..72cd91c9da 100644
--- a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.stories.tsx
+++ b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.stories.tsx
@@ -4,47 +4,47 @@ import { GetThisWeekQuery_latePledgeContacts } from '../../../../../types/GetThi
import LateCommitments from '.';
export default {
- title: 'Dashboard/ThisWeek/LateCommitments',
+ title: 'Dashboard/ThisWeek/LateCommitments',
};
export const Default = (): ReactElement => {
- const contact = {
- id: 'contact',
- name: 'Smith, Sarah',
- lateAt: '2012-10-01',
- };
+ const contact = {
+ id: 'contact',
+ name: 'Smith, Sarah',
+ lateAt: '2012-10-01',
+ };
- const latePledgeContacts: GetThisWeekQuery_latePledgeContacts = {
- nodes: [
- { ...contact, id: 'contact_1' },
- { ...contact, id: 'contact_2' },
- { ...contact, id: 'contact_3' },
- ],
- totalCount: 5,
- };
- return (
-
-
-
- );
+ const latePledgeContacts: GetThisWeekQuery_latePledgeContacts = {
+ nodes: [
+ { ...contact, id: 'contact_1' },
+ { ...contact, id: 'contact_2' },
+ { ...contact, id: 'contact_3' },
+ ],
+ totalCount: 5,
+ };
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- const latePledgeContacts: GetThisWeekQuery_latePledgeContacts = {
- nodes: [],
- totalCount: 0,
- };
- return (
-
-
-
- );
+ const latePledgeContacts: GetThisWeekQuery_latePledgeContacts = {
+ nodes: [],
+ totalCount: 0,
+ };
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.test.tsx b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.test.tsx
index f045bb1844..69e31aa962 100644
--- a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.test.tsx
+++ b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.test.tsx
@@ -4,69 +4,99 @@ import { render } from '../../../../../__tests__/util/testingLibraryReactMock';
import LateCommitments from '.';
describe('LateCommitments', () => {
- it('default', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('LateCommitmentsCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('LateCommitmentsDivLoading')).not.toBeInTheDocument();
- expect(queryByTestId('LateCommitmentsListContacts')).not.toBeInTheDocument();
- });
+ it('default', () => {
+ const { getByTestId, queryByTestId } = render();
+ expect(getByTestId('LateCommitmentsCardContentEmpty')).toBeInTheDocument();
+ expect(queryByTestId('LateCommitmentsDivLoading')).not.toBeInTheDocument();
+ expect(
+ queryByTestId('LateCommitmentsListContacts'),
+ ).not.toBeInTheDocument();
+ });
- it('loading', () => {
- const { getByTestId, queryByTestId } = render();
- expect(queryByTestId('LateCommitmentsCardContentEmpty')).not.toBeInTheDocument();
- expect(getByTestId('LateCommitmentsDivLoading')).toBeInTheDocument();
- expect(queryByTestId('LateCommitmentsListContacts')).not.toBeInTheDocument();
- });
+ it('loading', () => {
+ const { getByTestId, queryByTestId } = render();
+ expect(
+ queryByTestId('LateCommitmentsCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(getByTestId('LateCommitmentsDivLoading')).toBeInTheDocument();
+ expect(
+ queryByTestId('LateCommitmentsListContacts'),
+ ).not.toBeInTheDocument();
+ });
- it('empty', () => {
- const latePledgeContacts = {
- nodes: [],
- totalCount: 0,
- };
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('LateCommitmentsCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('LateCommitmentsDivLoading')).not.toBeInTheDocument();
- expect(queryByTestId('LateCommitmentsListContacts')).not.toBeInTheDocument();
- });
+ it('empty', () => {
+ const latePledgeContacts = {
+ nodes: [],
+ totalCount: 0,
+ };
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('LateCommitmentsCardContentEmpty')).toBeInTheDocument();
+ expect(queryByTestId('LateCommitmentsDivLoading')).not.toBeInTheDocument();
+ expect(
+ queryByTestId('LateCommitmentsListContacts'),
+ ).not.toBeInTheDocument();
+ });
- describe('MockDate', () => {
- beforeEach(() => {
- MockDate.set(new Date(2020, 1, 1));
- });
- afterEach(() => {
- MockDate.reset();
- });
- it('props', () => {
- const latePledgeContacts = {
- nodes: [
- {
- id: 'contact1',
- name: 'Smith, Sarah',
- lateAt: '2012-10-01',
- },
- {
- id: 'contact2',
- name: 'Smith, John',
- lateAt: '2015-12-01',
- },
- ],
- totalCount: 1595,
- };
- const { getByTestId, queryByTestId } = render();
- expect(queryByTestId('LateCommitmentsCardContentEmpty')).not.toBeInTheDocument();
- expect(queryByTestId('LateCommitmentsDivLoading')).not.toBeInTheDocument();
- const buttonElement = getByTestId('LateCommitmentsButtonViewAll');
- expect(buttonElement.textContent).toEqual('View All (1,595)');
- expect(buttonElement).toHaveAttribute(
- 'href',
- 'https://stage.mpdx.org/contacts?filters=%7B%22late_at%22%3A%221970-01-01..2020-02-01%22%2C%22status%22%3A%22Partner%20-%20Financial%22%7D',
- );
- const contact1Element = getByTestId('LateCommitmentsListItemContact-contact1');
- expect(contact1Element).toHaveAttribute('href', 'https://stage.mpdx.org/contacts/contact1');
- expect(contact1Element.textContent).toEqual('Smith, SarahTheir gift is 2,679 days late.');
- const contact2Element = getByTestId('LateCommitmentsListItemContact-contact2');
- expect(contact2Element).toHaveAttribute('href', 'https://stage.mpdx.org/contacts/contact2');
- expect(contact2Element.textContent).toEqual('Smith, JohnTheir gift is 1,523 days late.');
- });
+ describe('MockDate', () => {
+ beforeEach(() => {
+ MockDate.set(new Date(2020, 1, 1));
+ });
+ afterEach(() => {
+ MockDate.reset();
+ });
+ it('props', () => {
+ const latePledgeContacts = {
+ nodes: [
+ {
+ id: 'contact1',
+ name: 'Smith, Sarah',
+ lateAt: '2012-10-01',
+ },
+ {
+ id: 'contact2',
+ name: 'Smith, John',
+ lateAt: '2015-12-01',
+ },
+ ],
+ totalCount: 1595,
+ };
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(
+ queryByTestId('LateCommitmentsCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('LateCommitmentsDivLoading'),
+ ).not.toBeInTheDocument();
+ const buttonElement = getByTestId('LateCommitmentsButtonViewAll');
+ expect(buttonElement.textContent).toEqual('View All (1,595)');
+ expect(buttonElement).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts?filters=%7B%22late_at%22%3A%221970-01-01..2020-02-01%22%2C%22status%22%3A%22Partner%20-%20Financial%22%7D',
+ );
+ const contact1Element = getByTestId(
+ 'LateCommitmentsListItemContact-contact1',
+ );
+ expect(contact1Element).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts/contact1',
+ );
+ expect(contact1Element.textContent).toEqual(
+ 'Smith, SarahTheir gift is 2,679 days late.',
+ );
+ const contact2Element = getByTestId(
+ 'LateCommitmentsListItemContact-contact2',
+ );
+ expect(contact2Element).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts/contact2',
+ );
+ expect(contact2Element.textContent).toEqual(
+ 'Smith, JohnTheir gift is 1,523 days late.',
+ );
});
+ });
});
diff --git a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.tsx b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.tsx
index 8f1311b486..8dff5bdaec 100644
--- a/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.tsx
+++ b/src/components/Dashboard/ThisWeek/LateCommitments/LateCommitments.tsx
@@ -1,14 +1,14 @@
import React, { ReactElement } from 'react';
import {
- makeStyles,
- Theme,
- CardHeader,
- CardActions,
- Button,
- List,
- ListItem,
- ListItemText,
- CardContent,
+ makeStyles,
+ Theme,
+ CardHeader,
+ CardActions,
+ Button,
+ List,
+ ListItem,
+ ListItemText,
+ CardContent,
} from '@material-ui/core';
import moment from 'moment';
import { Skeleton } from '@material-ui/lab';
@@ -21,136 +21,155 @@ import HandoffLink from '../../../HandoffLink';
import illustration14 from '../../../../images/drawkit/grape/drawkit-grape-pack-illustration-14.svg';
const useStyles = makeStyles((theme: Theme) => ({
- div: {
- flex: 1,
- display: 'flex',
- flexDirection: 'column',
- overflow: 'auto',
- },
- list: {
- flex: 1,
- padding: 0,
- overflow: 'auto',
- },
- card: {
- display: 'flex',
- flexDirection: 'column',
- height: '322px',
- [theme.breakpoints.down('xs')]: {
- height: 'auto',
- },
- },
- cardContent: {
- padding: theme.spacing(2),
- display: 'flex',
- flex: 1,
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- },
- img: {
- height: '150px',
- marginBottom: theme.spacing(2),
+ div: {
+ flex: 1,
+ display: 'flex',
+ flexDirection: 'column',
+ overflow: 'auto',
+ },
+ list: {
+ flex: 1,
+ padding: 0,
+ overflow: 'auto',
+ },
+ card: {
+ display: 'flex',
+ flexDirection: 'column',
+ height: '322px',
+ [theme.breakpoints.down('xs')]: {
+ height: 'auto',
},
+ },
+ cardContent: {
+ padding: theme.spacing(2),
+ display: 'flex',
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ img: {
+ height: '150px',
+ marginBottom: theme.spacing(2),
+ },
}));
interface Props {
- loading?: boolean;
- latePledgeContacts?: GetThisWeekQuery_latePledgeContacts;
+ loading?: boolean;
+ latePledgeContacts?: GetThisWeekQuery_latePledgeContacts;
}
-const LateCommitments = ({ loading, latePledgeContacts }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
+const LateCommitments = ({
+ loading,
+ latePledgeContacts,
+}: Props): ReactElement => {
+ const classes = useStyles();
+ const { t } = useTranslation();
- return (
-
-
- {loading && (
-
-
- {[0, 1, 2].map((index) => (
-
- }
- secondary={}
- />
-
- ))}
-
-
-
-
-
- )}
- {!loading && (
-
+
+ {loading && (
+
+
+ {[0, 1, 2].map((index) => (
+
+ }
+ secondary={}
+ />
+
+ ))}
+
+
+
+
+
+ )}
+ {!loading && (
+
+ {(!latePledgeContacts || latePledgeContacts.nodes.length === 0) && (
+
+
+ {t('No late commitments to show.')}
+
+ )}
+ {latePledgeContacts && latePledgeContacts.nodes.length > 0 && (
+ <>
+
+ {latePledgeContacts.nodes.map((contact) => {
+ const count = moment().diff(moment(contact.lateAt), 'days');
+ return (
+
+
+
+
+
+ );
+ })}
+
+
+
- {(!latePledgeContacts || latePledgeContacts.nodes.length === 0) && (
-
-
- {t('No late commitments to show.')}
-
- )}
- {latePledgeContacts && latePledgeContacts.nodes.length > 0 && (
- <>
-
- {latePledgeContacts.nodes.map((contact) => {
- const count = moment().diff(moment(contact.lateAt), 'days');
- return (
-
-
-
-
-
- );
- })}
-
-
-
-
-
-
- >
- )}
-
- )}
-
- );
+
+
+
+ >
+ )}
+
+ )}
+
+ );
};
export default LateCommitments;
diff --git a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.stories.tsx b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.stories.tsx
index 46c99b414d..0694365b2e 100644
--- a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.stories.tsx
+++ b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.stories.tsx
@@ -2,128 +2,128 @@ import React, { ReactElement } from 'react';
import { Box } from '@material-ui/core';
import { MockedProvider } from '@apollo/client/testing';
import {
- GetThisWeekQuery_prayerRequestTasks,
- GetThisWeekQuery_reportsPeopleWithBirthdays,
- GetThisWeekQuery_reportsPeopleWithAnniversaries,
+ GetThisWeekQuery_prayerRequestTasks,
+ GetThisWeekQuery_reportsPeopleWithBirthdays,
+ GetThisWeekQuery_reportsPeopleWithAnniversaries,
} from '../../../../../types/GetThisWeekQuery';
import { ActivityTypeEnum } from '../../../../../types/globalTypes';
import PartnerCare from '.';
export default {
- title: 'Dashboard/ThisWeek/PartnerCare',
+ title: 'Dashboard/ThisWeek/PartnerCare',
};
export const Default = (): ReactElement => {
- const task = {
- id: 'task',
- subject: 'the quick brown fox jumps over the lazy dog',
- activityType: ActivityTypeEnum.PRAYER_REQUEST,
- contacts: { nodes: [{ name: 'Roger Smith' }, { name: 'Sarah Smith' }] },
- startAt: null,
- completedAt: null,
- };
- const personWithBirthday = {
- id: 'person',
- birthdayDay: 1,
- birthdayMonth: 1,
- firstName: 'John',
- lastName: 'Doe',
- parentContact: {
- id: 'contact',
- },
- };
- const personWithAnniversary = {
- id: 'person',
- anniversaryDay: 5,
- anniversaryMonth: 10,
- parentContact: {
- id: 'contact',
- name: 'John and Sarah, Doe',
- },
- };
- const prayerRequestTasks: GetThisWeekQuery_prayerRequestTasks = {
- nodes: [
- { ...task, id: 'task_4' },
- { ...task, id: 'task_5' },
- { ...task, id: 'task_6' },
+ const task = {
+ id: 'task',
+ subject: 'the quick brown fox jumps over the lazy dog',
+ activityType: ActivityTypeEnum.PRAYER_REQUEST,
+ contacts: { nodes: [{ name: 'Roger Smith' }, { name: 'Sarah Smith' }] },
+ startAt: null,
+ completedAt: null,
+ };
+ const personWithBirthday = {
+ id: 'person',
+ birthdayDay: 1,
+ birthdayMonth: 1,
+ firstName: 'John',
+ lastName: 'Doe',
+ parentContact: {
+ id: 'contact',
+ },
+ };
+ const personWithAnniversary = {
+ id: 'person',
+ anniversaryDay: 5,
+ anniversaryMonth: 10,
+ parentContact: {
+ id: 'contact',
+ name: 'John and Sarah, Doe',
+ },
+ };
+ const prayerRequestTasks: GetThisWeekQuery_prayerRequestTasks = {
+ nodes: [
+ { ...task, id: 'task_4' },
+ { ...task, id: 'task_5' },
+ { ...task, id: 'task_6' },
+ ],
+ totalCount: 80,
+ };
+ const reportsPeopleWithBirthdays: GetThisWeekQuery_reportsPeopleWithBirthdays = {
+ periods: [
+ {
+ people: [
+ { ...personWithBirthday, id: 'person_1' },
+ { ...personWithBirthday, id: 'person_2' },
],
- totalCount: 80,
- };
- const reportsPeopleWithBirthdays: GetThisWeekQuery_reportsPeopleWithBirthdays = {
- periods: [
- {
- people: [
- { ...personWithBirthday, id: 'person_1' },
- { ...personWithBirthday, id: 'person_2' },
- ],
- },
+ },
+ ],
+ };
+ const reportsPeopleWithAnniversaries: GetThisWeekQuery_reportsPeopleWithAnniversaries = {
+ periods: [
+ {
+ people: [
+ { ...personWithAnniversary, id: 'person_3' },
+ { ...personWithAnniversary, id: 'person_4' },
],
- };
- const reportsPeopleWithAnniversaries: GetThisWeekQuery_reportsPeopleWithAnniversaries = {
- periods: [
- {
- people: [
- { ...personWithAnniversary, id: 'person_3' },
- { ...personWithAnniversary, id: 'person_4' },
- ],
- },
- ],
- };
- return (
-
-
-
-
-
- );
+ },
+ ],
+ };
+ return (
+
+
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- const prayerRequestTasks: GetThisWeekQuery_prayerRequestTasks = {
- nodes: [],
- totalCount: 0,
- };
- const reportsPeopleWithBirthdays: GetThisWeekQuery_reportsPeopleWithBirthdays = {
- periods: [
- {
- people: [],
- },
- ],
- };
- const reportsPeopleWithAnniversaries: GetThisWeekQuery_reportsPeopleWithAnniversaries = {
- periods: [
- {
- people: [],
- },
- ],
- };
- return (
-
-
-
-
-
- );
+ const prayerRequestTasks: GetThisWeekQuery_prayerRequestTasks = {
+ nodes: [],
+ totalCount: 0,
+ };
+ const reportsPeopleWithBirthdays: GetThisWeekQuery_reportsPeopleWithBirthdays = {
+ periods: [
+ {
+ people: [],
+ },
+ ],
+ };
+ const reportsPeopleWithAnniversaries: GetThisWeekQuery_reportsPeopleWithAnniversaries = {
+ periods: [
+ {
+ people: [],
+ },
+ ],
+ };
+ return (
+
+
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+ );
};
diff --git a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.test.tsx b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.test.tsx
index ee6e8a5e03..3a1336d1be 100644
--- a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.test.tsx
+++ b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.test.tsx
@@ -1,161 +1,214 @@
import React from 'react';
import userEvent from '@testing-library/user-event';
-import { render, fireEvent } from '../../../../../__tests__/util/testingLibraryReactMock';
+import {
+ render,
+ fireEvent,
+} from '../../../../../__tests__/util/testingLibraryReactMock';
import { ActivityTypeEnum } from '../../../../../types/globalTypes';
import { GetThisWeekQuery_prayerRequestTasks } from '../../../../../types/GetThisWeekQuery';
import { useApp } from '../../../App';
import PartnerCare from '.';
jest.mock('../../../App', () => ({
- useApp: jest.fn(),
+ useApp: jest.fn(),
}));
const openTaskDrawer = jest.fn();
beforeEach(() => {
- (useApp as jest.Mock).mockReturnValue({
- openTaskDrawer,
- });
+ (useApp as jest.Mock).mockReturnValue({
+ openTaskDrawer,
+ });
});
describe('PartnerCare', () => {
- it('default', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('PartnerCarePrayerCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('PartnerCareCelebrationCardContentEmpty')).not.toBeInTheDocument();
- expect(getByTestId('PartnerCareTabPrayer').textContent).toEqual('Prayer (0)');
- const CelebrationsTab = getByTestId('PartnerCareTabCelebrations');
- expect(CelebrationsTab.textContent).toEqual('Celebrations (0)');
- fireEvent.click(CelebrationsTab);
- expect(getByTestId('PartnerCareCelebrationCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('PartnerCarePrayerCardContentEmpty')).not.toBeInTheDocument();
- });
+ it('default', () => {
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(
+ getByTestId('PartnerCarePrayerCardContentEmpty'),
+ ).toBeInTheDocument();
+ expect(
+ queryByTestId('PartnerCareCelebrationCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(getByTestId('PartnerCareTabPrayer').textContent).toEqual(
+ 'Prayer (0)',
+ );
+ const CelebrationsTab = getByTestId('PartnerCareTabCelebrations');
+ expect(CelebrationsTab.textContent).toEqual('Celebrations (0)');
+ fireEvent.click(CelebrationsTab);
+ expect(
+ getByTestId('PartnerCareCelebrationCardContentEmpty'),
+ ).toBeInTheDocument();
+ expect(
+ queryByTestId('PartnerCarePrayerCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ });
- it('loading', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('PartnerCarePrayerListLoading')).toBeInTheDocument();
- expect(queryByTestId('PartnerCareCelebrationListLoading')).not.toBeInTheDocument();
- fireEvent.click(getByTestId('PartnerCareTabCelebrations'));
- expect(getByTestId('PartnerCareCelebrationListLoading')).toBeInTheDocument();
- expect(queryByTestId('PartnerCarePrayerListLoading')).not.toBeInTheDocument();
- });
+ it('loading', () => {
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('PartnerCarePrayerListLoading')).toBeInTheDocument();
+ expect(
+ queryByTestId('PartnerCareCelebrationListLoading'),
+ ).not.toBeInTheDocument();
+ fireEvent.click(getByTestId('PartnerCareTabCelebrations'));
+ expect(
+ getByTestId('PartnerCareCelebrationListLoading'),
+ ).toBeInTheDocument();
+ expect(
+ queryByTestId('PartnerCarePrayerListLoading'),
+ ).not.toBeInTheDocument();
+ });
- it('empty', () => {
- const prayerRequestTasks = {
- nodes: [],
- totalCount: 0,
- };
- const reportsPeopleWithBirthdays = {
- periods: [{ people: [] }],
- totalCount: 0,
- };
- const reportsPeopleWithAnniversaries = {
- periods: [{ people: [] }],
- totalCount: 0,
- };
- const { getByTestId, queryByTestId } = render(
- ,
- );
- expect(getByTestId('PartnerCarePrayerCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('PartnerCareCelebrationCardContentEmpty')).not.toBeInTheDocument();
- expect(getByTestId('PartnerCareTabPrayer').textContent).toEqual('Prayer (0)');
- const CelebrationsTab = getByTestId('PartnerCareTabCelebrations');
- expect(CelebrationsTab.textContent).toEqual('Celebrations (0)');
- fireEvent.click(CelebrationsTab);
- expect(getByTestId('PartnerCareCelebrationCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('PartnerCarePrayerCardContentEmpty')).not.toBeInTheDocument();
- });
+ it('empty', () => {
+ const prayerRequestTasks = {
+ nodes: [],
+ totalCount: 0,
+ };
+ const reportsPeopleWithBirthdays = {
+ periods: [{ people: [] }],
+ totalCount: 0,
+ };
+ const reportsPeopleWithAnniversaries = {
+ periods: [{ people: [] }],
+ totalCount: 0,
+ };
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(
+ getByTestId('PartnerCarePrayerCardContentEmpty'),
+ ).toBeInTheDocument();
+ expect(
+ queryByTestId('PartnerCareCelebrationCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(getByTestId('PartnerCareTabPrayer').textContent).toEqual(
+ 'Prayer (0)',
+ );
+ const CelebrationsTab = getByTestId('PartnerCareTabCelebrations');
+ expect(CelebrationsTab.textContent).toEqual('Celebrations (0)');
+ fireEvent.click(CelebrationsTab);
+ expect(
+ getByTestId('PartnerCareCelebrationCardContentEmpty'),
+ ).toBeInTheDocument();
+ expect(
+ queryByTestId('PartnerCarePrayerCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ });
- it('props', () => {
- const prayerRequestTasks: GetThisWeekQuery_prayerRequestTasks = {
- nodes: [
- {
- id: 'task_1',
- subject: 'the quick brown fox jumps over the lazy dog',
- activityType: ActivityTypeEnum.PRAYER_REQUEST,
- contacts: { nodes: [{ name: 'Roger Smith' }, { name: 'Sarah Smith' }] },
- startAt: null,
- completedAt: null,
- },
- {
- id: 'task_2',
- subject: 'on the boat to see uncle johnny',
- activityType: ActivityTypeEnum.PRAYER_REQUEST,
- contacts: { nodes: [{ name: 'Roger Parker' }, { name: 'Sarah Parker' }] },
- startAt: null,
- completedAt: null,
- },
- ],
- totalCount: 2560,
- };
- const personWithBirthday = {
- birthdayDay: 1,
- birthdayMonth: 1,
- firstName: 'John',
- lastName: 'Doe',
- parentContact: {
- id: 'contact',
- },
- };
- const personWithAnniversary = {
- anniversaryDay: 5,
- anniversaryMonth: 10,
- parentContact: {
- id: 'contact',
- name: 'John and Sarah, Doe',
- },
- };
- const reportsPeopleWithBirthdays = {
- periods: [
- {
- people: [
- { ...personWithBirthday, id: 'person_1' },
- { ...personWithBirthday, id: 'person_2' },
- ],
- },
- ],
- };
- const reportsPeopleWithAnniversaries = {
- periods: [
- {
- people: [
- { ...personWithAnniversary, id: 'person_3' },
- { ...personWithAnniversary, id: 'person_4' },
- ],
- },
- ],
- };
- const { getByTestId, queryByTestId } = render(
- ,
- );
- expect(queryByTestId('PartnerCarePrayerCardContentEmpty')).not.toBeInTheDocument();
- expect(getByTestId('PartnerCarePrayerList')).toBeInTheDocument();
- expect(getByTestId('PartnerCareTabPrayer').textContent).toEqual('Prayer (2,560)');
- const task1Element = getByTestId('PartnerCarePrayerListItem-task_1');
- expect(task1Element.textContent).toEqual('Roger Smith, Sarah Smiththe quick brown fox jumps over the lazy dog');
- userEvent.click(task1Element);
- expect(openTaskDrawer).toHaveBeenCalledWith({ taskId: 'task_1' });
- expect(getByTestId('PartnerCarePrayerListItem-task_2').textContent).toEqual(
- 'Roger Parker, Sarah Parkeron the boat to see uncle johnny',
- );
- const CelebrationsTab = getByTestId('PartnerCareTabCelebrations');
- expect(CelebrationsTab.textContent).toEqual('Celebrations (4)');
- fireEvent.click(CelebrationsTab);
- expect(queryByTestId('PartnerCareCelebrationCardContentEmpty')).not.toBeInTheDocument();
- expect(getByTestId('PartnerCareCelebrationList')).toBeInTheDocument();
- expect(getByTestId('PartnerCareBirthdayListItem-person_1').textContent).toEqual('John DoeJan 1');
- expect(getByTestId('PartnerCareBirthdayListItem-person_2').textContent).toEqual('John DoeJan 1');
- expect(getByTestId('PartnerCareAnniversaryListItem-person_3').textContent).toEqual('John and Sarah, DoeOct 5');
- expect(queryByTestId('PartnerCareAnniversaryListItem-person_4')).not.toBeInTheDocument();
- });
+ it('props', () => {
+ const prayerRequestTasks: GetThisWeekQuery_prayerRequestTasks = {
+ nodes: [
+ {
+ id: 'task_1',
+ subject: 'the quick brown fox jumps over the lazy dog',
+ activityType: ActivityTypeEnum.PRAYER_REQUEST,
+ contacts: {
+ nodes: [{ name: 'Roger Smith' }, { name: 'Sarah Smith' }],
+ },
+ startAt: null,
+ completedAt: null,
+ },
+ {
+ id: 'task_2',
+ subject: 'on the boat to see uncle johnny',
+ activityType: ActivityTypeEnum.PRAYER_REQUEST,
+ contacts: {
+ nodes: [{ name: 'Roger Parker' }, { name: 'Sarah Parker' }],
+ },
+ startAt: null,
+ completedAt: null,
+ },
+ ],
+ totalCount: 2560,
+ };
+ const personWithBirthday = {
+ birthdayDay: 1,
+ birthdayMonth: 1,
+ firstName: 'John',
+ lastName: 'Doe',
+ parentContact: {
+ id: 'contact',
+ },
+ };
+ const personWithAnniversary = {
+ anniversaryDay: 5,
+ anniversaryMonth: 10,
+ parentContact: {
+ id: 'contact',
+ name: 'John and Sarah, Doe',
+ },
+ };
+ const reportsPeopleWithBirthdays = {
+ periods: [
+ {
+ people: [
+ { ...personWithBirthday, id: 'person_1' },
+ { ...personWithBirthday, id: 'person_2' },
+ ],
+ },
+ ],
+ };
+ const reportsPeopleWithAnniversaries = {
+ periods: [
+ {
+ people: [
+ { ...personWithAnniversary, id: 'person_3' },
+ { ...personWithAnniversary, id: 'person_4' },
+ ],
+ },
+ ],
+ };
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(
+ queryByTestId('PartnerCarePrayerCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(getByTestId('PartnerCarePrayerList')).toBeInTheDocument();
+ expect(getByTestId('PartnerCareTabPrayer').textContent).toEqual(
+ 'Prayer (2,560)',
+ );
+ const task1Element = getByTestId('PartnerCarePrayerListItem-task_1');
+ expect(task1Element.textContent).toEqual(
+ 'Roger Smith, Sarah Smiththe quick brown fox jumps over the lazy dog',
+ );
+ userEvent.click(task1Element);
+ expect(openTaskDrawer).toHaveBeenCalledWith({ taskId: 'task_1' });
+ expect(getByTestId('PartnerCarePrayerListItem-task_2').textContent).toEqual(
+ 'Roger Parker, Sarah Parkeron the boat to see uncle johnny',
+ );
+ const CelebrationsTab = getByTestId('PartnerCareTabCelebrations');
+ expect(CelebrationsTab.textContent).toEqual('Celebrations (4)');
+ fireEvent.click(CelebrationsTab);
+ expect(
+ queryByTestId('PartnerCareCelebrationCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(getByTestId('PartnerCareCelebrationList')).toBeInTheDocument();
+ expect(
+ getByTestId('PartnerCareBirthdayListItem-person_1').textContent,
+ ).toEqual('John DoeJan 1');
+ expect(
+ getByTestId('PartnerCareBirthdayListItem-person_2').textContent,
+ ).toEqual('John DoeJan 1');
+ expect(
+ getByTestId('PartnerCareAnniversaryListItem-person_3').textContent,
+ ).toEqual('John and Sarah, DoeOct 5');
+ expect(
+ queryByTestId('PartnerCareAnniversaryListItem-person_4'),
+ ).not.toBeInTheDocument();
+ });
});
diff --git a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.tsx b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.tsx
index e3dde6eaaa..3c5b1a0cef 100644
--- a/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.tsx
+++ b/src/components/Dashboard/ThisWeek/PartnerCare/PartnerCare.tsx
@@ -1,21 +1,21 @@
import React, { ReactElement, useState } from 'react';
import {
- Box,
- Typography,
- makeStyles,
- Theme,
- CardHeader,
- CardActions,
- Button,
- List,
- ListItem,
- ListItemText,
- ListItemSecondaryAction,
- Checkbox,
- Tabs,
- Tab,
- ListItemIcon,
- CardContent,
+ Box,
+ Typography,
+ makeStyles,
+ Theme,
+ CardHeader,
+ CardActions,
+ Button,
+ List,
+ ListItem,
+ ListItemText,
+ ListItemSecondaryAction,
+ Checkbox,
+ Tabs,
+ Tab,
+ ListItemIcon,
+ CardContent,
} from '@material-ui/core';
import CakeIcon from '@material-ui/icons/Cake';
import FavoriteIcon from '@material-ui/icons/Favorite';
@@ -27,10 +27,10 @@ import Link from 'next/link';
import { dayMonthFormat } from '../../../../lib/intlFormat';
import AnimatedCard from '../../../AnimatedCard';
import {
- GetThisWeekQuery_prayerRequestTasks,
- GetThisWeekQuery_reportsPeopleWithBirthdays,
- GetThisWeekQuery_reportsPeopleWithAnniversaries,
- GetThisWeekQuery_prayerRequestTasks_nodes as Task,
+ GetThisWeekQuery_prayerRequestTasks,
+ GetThisWeekQuery_reportsPeopleWithBirthdays,
+ GetThisWeekQuery_reportsPeopleWithAnniversaries,
+ GetThisWeekQuery_prayerRequestTasks_nodes as Task,
} from '../../../../../types/GetThisWeekQuery';
import { useApp } from '../../../App';
import TaskStatus from '../../../Task/Status';
@@ -38,323 +38,361 @@ import illustration4 from '../../../../images/drawkit/grape/drawkit-grape-pack-i
import illustration7 from '../../../../images/drawkit/grape/drawkit-grape-pack-illustration-7.svg';
const useStyles = makeStyles((theme: Theme) => ({
- div: {
- flex: 1,
- display: 'flex',
- flexDirection: 'column',
- overflow: 'auto',
+ div: {
+ flex: 1,
+ display: 'flex',
+ flexDirection: 'column',
+ overflow: 'auto',
+ },
+ list: {
+ flex: 1,
+ padding: 0,
+ overflow: 'auto',
+ },
+ card: {
+ display: 'flex',
+ flexDirection: 'column',
+ height: '322px',
+ [theme.breakpoints.down('xs')]: {
+ height: 'auto',
},
- list: {
- flex: 1,
- padding: 0,
- overflow: 'auto',
- },
- card: {
- display: 'flex',
- flexDirection: 'column',
- height: '322px',
- [theme.breakpoints.down('xs')]: {
- height: 'auto',
- },
- },
- cardContent: {
- padding: theme.spacing(2),
- display: 'flex',
- flex: 1,
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- },
- img: {
- height: '120px',
- marginBottom: 0,
- [theme.breakpoints.down('xs')]: {
- height: '150px',
- marginBottom: theme.spacing(2),
- },
+ },
+ cardContent: {
+ padding: theme.spacing(2),
+ display: 'flex',
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ img: {
+ height: '120px',
+ marginBottom: 0,
+ [theme.breakpoints.down('xs')]: {
+ height: '150px',
+ marginBottom: theme.spacing(2),
},
+ },
}));
interface Props {
- accountListId: string;
- loading?: boolean;
- prayerRequestTasks?: GetThisWeekQuery_prayerRequestTasks;
- reportsPeopleWithBirthdays?: GetThisWeekQuery_reportsPeopleWithBirthdays;
- reportsPeopleWithAnniversaries?: GetThisWeekQuery_reportsPeopleWithAnniversaries;
+ accountListId: string;
+ loading?: boolean;
+ prayerRequestTasks?: GetThisWeekQuery_prayerRequestTasks;
+ reportsPeopleWithBirthdays?: GetThisWeekQuery_reportsPeopleWithBirthdays;
+ reportsPeopleWithAnniversaries?: GetThisWeekQuery_reportsPeopleWithAnniversaries;
}
const PartnerCare = ({
- accountListId,
- loading,
- prayerRequestTasks,
- reportsPeopleWithBirthdays,
- reportsPeopleWithAnniversaries,
+ accountListId,
+ loading,
+ prayerRequestTasks,
+ reportsPeopleWithBirthdays,
+ reportsPeopleWithAnniversaries,
}: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const [value, setValue] = useState(0);
- const { openTaskDrawer } = useApp();
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const [value, setValue] = useState(0);
+ const { openTaskDrawer } = useApp();
- const handleClick = ({ id: taskId }: Task): void => {
- openTaskDrawer({ taskId });
- };
+ const handleClick = ({ id: taskId }: Task): void => {
+ openTaskDrawer({ taskId });
+ };
- const handleChange = (_event: React.ChangeEvent, newValue: number): void => {
- setValue(newValue);
- };
+ const handleChange = (_event: React.ChangeEvent, newValue: number): void => {
+ setValue(newValue);
+ };
- return (
-
-
-
-
-
-
- {value == 0 && (
-
+
+
+
+
+
+ {value == 0 && (
+
+ {loading && (
+ <>
+
+ {[0, 1].map((index) => (
+
+ }
+ secondary={}
+ />
+
+
+
+
+ ))}
+
+
+
+
+ >
+ )}
+ {!loading && (
+ <>
+ {(!prayerRequestTasks ||
+ prayerRequestTasks.nodes.length === 0) && (
+
- {loading && (
- <>
-
- {[0, 1].map((index) => (
-
- }
- secondary={}
- />
-
-
-
-
- ))}
-
-
-
-
- >
- )}
- {!loading && (
- <>
- {(!prayerRequestTasks || prayerRequestTasks.nodes.length === 0) && (
-
+ {t('No prayer requests to show.')}
+
+ )}
+ {prayerRequestTasks && prayerRequestTasks.nodes.length > 0 && (
+ <>
+
+ {prayerRequestTasks.nodes.map((task) => (
+ handleClick(task)}
+ >
+
+ {task.contacts.nodes
+ .map(({ name }) => name)
+ .join(', ')}
+
+ }
+ secondary={
+
+
+
-
- {t('No prayer requests to show.')}
-
- )}
- {prayerRequestTasks && prayerRequestTasks.nodes.length > 0 && (
- <>
-
- {prayerRequestTasks.nodes.map((task) => (
- handleClick(task)}
- >
-
- {task.contacts.nodes.map(({ name }) => name).join(', ')}
-
- }
- secondary={
-
-
-
- {task.subject}
-
-
-
- }
- />
-
-
-
-
- ))}
-
-
-
-
-
-
- >
- )}
- >
- )}
-
- )}
- {value == 1 && (
-
+
+
+ }
+ />
+
+
+
+
+ ))}
+
+
+
+
+
+
+ >
+ )}
+ >
+ )}
+
+ )}
+ {value == 1 && (
+
+ {loading && (
+
+ {[0, 1, 2].map((index) => (
+
+ }
+ secondary={}
+ />
+
+
+
+
+ ))}
+
+ )}
+ {!loading && (
+ <>
+ {(!reportsPeopleWithBirthdays ||
+ (reportsPeopleWithBirthdays.periods[0].people &&
+ reportsPeopleWithBirthdays.periods[0].people.length === 0)) &&
+ (!reportsPeopleWithAnniversaries ||
+ (reportsPeopleWithAnniversaries.periods[0].people &&
+ reportsPeopleWithAnniversaries.periods[0].people.length ===
+ 0)) ? (
+
+
+ {t('No celebrations to show.')}
+
+ ) : (
+
- {loading && (
-
- {[0, 1, 2].map((index) => (
-
- }
- secondary={}
- />
-
-
-
-
- ))}
-
- )}
- {!loading && (
- <>
- {(!reportsPeopleWithBirthdays ||
- (reportsPeopleWithBirthdays.periods[0].people &&
- reportsPeopleWithBirthdays.periods[0].people.length === 0)) &&
- (!reportsPeopleWithAnniversaries ||
- (reportsPeopleWithAnniversaries.periods[0].people &&
- reportsPeopleWithAnniversaries.periods[0].people.length === 0)) ? (
- (
+
+
+
+
+
+ {person.firstName} {person.lastName}
+
+ }
+ secondary={
+
+
+
-
- {t('No celebrations to show.')}
-
- ) : (
-
- {reportsPeopleWithBirthdays.periods[0].people.map((person) => (
-
-
-
-
-
- {person.firstName} {person.lastName}
-
- }
- secondary={
-
-
-
- {dayMonthFormat(
- person.birthdayDay,
- person.birthdayMonth - 1,
- )}
-
-
-
- }
- />
-
-
-
-
- ))}
- {uniqBy(
- ({ parentContact: id }) => id,
- reportsPeopleWithAnniversaries.periods[0].people,
- ).map((person) => (
-
-
-
-
- {person.parentContact.name}
- }
- secondary={
-
-
-
- {dayMonthFormat(
- person.anniversaryDay,
- person.anniversaryMonth - 1,
- )}
-
-
-
- }
- />
-
-
-
-
- ))}
-
- )}
- >
- )}
-
- )}
-
- );
+ {dayMonthFormat(
+ person.birthdayDay,
+ person.birthdayMonth - 1,
+ )}
+
+
+
+ }
+ />
+
+
+
+
+ ),
+ )}
+ {uniqBy(
+ ({ parentContact: id }) => id,
+ reportsPeopleWithAnniversaries.periods[0].people,
+ ).map((person) => (
+
+
+
+
+
+ {person.parentContact.name}
+
+ }
+ secondary={
+
+
+
+ {dayMonthFormat(
+ person.anniversaryDay,
+ person.anniversaryMonth - 1,
+ )}
+
+
+
+ }
+ />
+
+
+
+
+ ))}
+
+ )}
+ >
+ )}
+
+ )}
+
+ );
};
export default PartnerCare;
diff --git a/src/components/Dashboard/ThisWeek/Referrals/Referrals.stories.tsx b/src/components/Dashboard/ThisWeek/Referrals/Referrals.stories.tsx
index aa438da972..411908eb9e 100644
--- a/src/components/Dashboard/ThisWeek/Referrals/Referrals.stories.tsx
+++ b/src/components/Dashboard/ThisWeek/Referrals/Referrals.stories.tsx
@@ -1,63 +1,71 @@
import React, { ReactElement } from 'react';
import { Box } from '@material-ui/core';
import {
- GetThisWeekQuery_recentReferrals,
- GetThisWeekQuery_onHandReferrals,
+ GetThisWeekQuery_recentReferrals,
+ GetThisWeekQuery_onHandReferrals,
} from '../../../../../types/GetThisWeekQuery';
import Referrals from '.';
export default {
- title: 'Dashboard/ThisWeek/Referrals',
+ title: 'Dashboard/ThisWeek/Referrals',
};
export const Default = (): ReactElement => {
- const contact = {
- id: 'contact',
- name: 'Smith, Sarah',
- };
- const recentReferrals: GetThisWeekQuery_recentReferrals = {
- nodes: [
- { ...contact, id: 'contact_1' },
- { ...contact, id: 'contact_2' },
- { ...contact, id: 'contact_3' },
- ],
- totalCount: 5,
- };
- const onHandReferrals: GetThisWeekQuery_onHandReferrals = {
- nodes: [
- { ...contact, id: 'contact_4' },
- { ...contact, id: 'contact_5' },
- { ...contact, id: 'contact_6' },
- ],
- totalCount: 5,
- };
- return (
-
-
-
- );
+ const contact = {
+ id: 'contact',
+ name: 'Smith, Sarah',
+ };
+ const recentReferrals: GetThisWeekQuery_recentReferrals = {
+ nodes: [
+ { ...contact, id: 'contact_1' },
+ { ...contact, id: 'contact_2' },
+ { ...contact, id: 'contact_3' },
+ ],
+ totalCount: 5,
+ };
+ const onHandReferrals: GetThisWeekQuery_onHandReferrals = {
+ nodes: [
+ { ...contact, id: 'contact_4' },
+ { ...contact, id: 'contact_5' },
+ { ...contact, id: 'contact_6' },
+ ],
+ totalCount: 5,
+ };
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- const recentReferrals: GetThisWeekQuery_recentReferrals = {
- nodes: [],
- totalCount: 0,
- };
- const onHandReferrals: GetThisWeekQuery_onHandReferrals = {
- nodes: [],
- totalCount: 0,
- };
- return (
-
-
-
- );
+ const recentReferrals: GetThisWeekQuery_recentReferrals = {
+ nodes: [],
+ totalCount: 0,
+ };
+ const onHandReferrals: GetThisWeekQuery_onHandReferrals = {
+ nodes: [],
+ totalCount: 0,
+ };
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Dashboard/ThisWeek/Referrals/Referrals.test.tsx b/src/components/Dashboard/ThisWeek/Referrals/Referrals.test.tsx
index 3df6edec62..6ec558f1c8 100644
--- a/src/components/Dashboard/ThisWeek/Referrals/Referrals.test.tsx
+++ b/src/components/Dashboard/ThisWeek/Referrals/Referrals.test.tsx
@@ -1,113 +1,157 @@
import React from 'react';
import MockDate from 'mockdate';
-import { render, fireEvent } from '../../../../../__tests__/util/testingLibraryReactMock';
+import {
+ render,
+ fireEvent,
+} from '../../../../../__tests__/util/testingLibraryReactMock';
import Referrals from '.';
describe('Referrals', () => {
- beforeEach(() => {
- MockDate.set(new Date('2000-01-01'));
- });
+ beforeEach(() => {
+ MockDate.set(new Date('2000-01-01'));
+ });
- afterEach(() => {
- MockDate.reset();
- });
+ afterEach(() => {
+ MockDate.reset();
+ });
- it('default', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('ReferralsDivRecent')).toBeInTheDocument();
- expect(queryByTestId('ReferralsDivOnHand')).not.toBeInTheDocument();
- expect(getByTestId('ReferralsTabRecent').textContent).toEqual('Recent (0)');
- const OnHandTab = getByTestId('ReferralsTabOnHand');
- expect(OnHandTab.textContent).toEqual('On Hand (0)');
- fireEvent.click(OnHandTab);
- expect(queryByTestId('ReferralsDivRecent')).not.toBeInTheDocument();
- expect(getByTestId('ReferralsDivOnHand')).toBeInTheDocument();
- });
+ it('default', () => {
+ const { getByTestId, queryByTestId } = render();
+ expect(getByTestId('ReferralsDivRecent')).toBeInTheDocument();
+ expect(queryByTestId('ReferralsDivOnHand')).not.toBeInTheDocument();
+ expect(getByTestId('ReferralsTabRecent').textContent).toEqual('Recent (0)');
+ const OnHandTab = getByTestId('ReferralsTabOnHand');
+ expect(OnHandTab.textContent).toEqual('On Hand (0)');
+ fireEvent.click(OnHandTab);
+ expect(queryByTestId('ReferralsDivRecent')).not.toBeInTheDocument();
+ expect(getByTestId('ReferralsDivOnHand')).toBeInTheDocument();
+ });
- it('loading', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('ReferralsTabRecentListLoading')).toBeInTheDocument();
- expect(queryByTestId('ReferralsTabOnHandListLoading')).not.toBeInTheDocument();
- fireEvent.click(getByTestId('ReferralsTabOnHand'));
- expect(getByTestId('ReferralsTabOnHandListLoading')).toBeInTheDocument();
- expect(queryByTestId('ReferralsTabRecentListLoading')).not.toBeInTheDocument();
- });
+ it('loading', () => {
+ const { getByTestId, queryByTestId } = render();
+ expect(getByTestId('ReferralsTabRecentListLoading')).toBeInTheDocument();
+ expect(
+ queryByTestId('ReferralsTabOnHandListLoading'),
+ ).not.toBeInTheDocument();
+ fireEvent.click(getByTestId('ReferralsTabOnHand'));
+ expect(getByTestId('ReferralsTabOnHandListLoading')).toBeInTheDocument();
+ expect(
+ queryByTestId('ReferralsTabRecentListLoading'),
+ ).not.toBeInTheDocument();
+ });
- it('empty', () => {
- const referrals = {
- nodes: [],
- totalCount: 0,
- };
- const { getByTestId, queryByTestId } = render(
- ,
- );
- expect(getByTestId('ReferralsTabRecentCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('ReferralsTabOnHandCardContentEmpty')).not.toBeInTheDocument();
- expect(getByTestId('ReferralsTabRecent').textContent).toEqual('Recent (0)');
- const OnHandTab = getByTestId('ReferralsTabOnHand');
- expect(OnHandTab.textContent).toEqual('On Hand (0)');
- fireEvent.click(OnHandTab);
- expect(getByTestId('ReferralsTabOnHandCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('ReferralsTabRecentCardContentEmpty')).not.toBeInTheDocument();
- });
+ it('empty', () => {
+ const referrals = {
+ nodes: [],
+ totalCount: 0,
+ };
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(
+ getByTestId('ReferralsTabRecentCardContentEmpty'),
+ ).toBeInTheDocument();
+ expect(
+ queryByTestId('ReferralsTabOnHandCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(getByTestId('ReferralsTabRecent').textContent).toEqual('Recent (0)');
+ const OnHandTab = getByTestId('ReferralsTabOnHand');
+ expect(OnHandTab.textContent).toEqual('On Hand (0)');
+ fireEvent.click(OnHandTab);
+ expect(
+ getByTestId('ReferralsTabOnHandCardContentEmpty'),
+ ).toBeInTheDocument();
+ expect(
+ queryByTestId('ReferralsTabRecentCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ });
- it('props', () => {
- const recentReferrals = {
- nodes: [
- {
- id: 'contact_1',
- name: 'Smith, Bob',
- },
- {
- id: 'contact_2',
- name: 'Smith, Sarah',
- },
- ],
- totalCount: 1234,
- };
- const onHandReferrals = {
- nodes: [
- {
- id: 'contact_3',
- name: 'Smith, Mike',
- },
- {
- id: 'contact_4',
- name: 'Smith, Shelley',
- },
- ],
- totalCount: 5678,
- };
- const { getByTestId, queryByTestId, getByRole } = render(
- ,
- );
- expect(queryByTestId('ReferralsTabRecentCardContentEmpty')).not.toBeInTheDocument();
- expect(getByTestId('ReferralsTabRecentList')).toBeInTheDocument();
- expect(getByTestId('ReferralsTabRecent').textContent).toEqual('Recent (1,234)');
- const referralElement1 = getByTestId('ReferralsTabRecentListItem-contact_1');
- expect(referralElement1.textContent).toEqual('Smith, Bob');
- expect(referralElement1).toHaveAttribute('href', 'https://stage.mpdx.org/contacts/contact_1');
- const referralElement2 = getByTestId('ReferralsTabRecentListItem-contact_2');
- expect(referralElement2.textContent).toEqual('Smith, Sarah');
- expect(referralElement2).toHaveAttribute('href', 'https://stage.mpdx.org/contacts/contact_2');
- expect(getByRole('link', { name: 'View All (1,234)' })).toHaveAttribute(
- 'href',
- 'https://stage.mpdx.org/contacts?filters=%7B%22created_at%22%3A%221999-12-18..2000-01-01%22%2C%22referrer%22%3A%22any%22%7D',
- );
- const OnHandTab = getByTestId('ReferralsTabOnHand');
- expect(OnHandTab.textContent).toEqual('On Hand (5,678)');
- fireEvent.click(OnHandTab);
- expect(queryByTestId('ReferralsTabOnHandCardContentEmpty')).not.toBeInTheDocument();
- expect(getByTestId('ReferralsTabOnHandList')).toBeInTheDocument();
- const referralElement3 = getByTestId('ReferralsTabOnHandListItem-contact_3');
- expect(referralElement3.textContent).toEqual('Smith, Mike');
- expect(referralElement3).toHaveAttribute('href', 'https://stage.mpdx.org/contacts/contact_3');
- const referralElement4 = getByTestId('ReferralsTabOnHandListItem-contact_4');
- expect(referralElement4.textContent).toEqual('Smith, Shelley');
- expect(referralElement4).toHaveAttribute('href', 'https://stage.mpdx.org/contacts/contact_4');
- expect(getByRole('link', { name: 'View All (5,678)' })).toHaveAttribute(
- 'href',
- 'https://stage.mpdx.org/contacts?filters=%7B%22referrer%22%3A%22any%22%2C%22status%22%3A%22Never%20Contacted%2CAsk%20in%20Future%2CCultivate%20Relationship%2CContact%20for%20Appointment%22%7D',
- );
- });
+ it('props', () => {
+ const recentReferrals = {
+ nodes: [
+ {
+ id: 'contact_1',
+ name: 'Smith, Bob',
+ },
+ {
+ id: 'contact_2',
+ name: 'Smith, Sarah',
+ },
+ ],
+ totalCount: 1234,
+ };
+ const onHandReferrals = {
+ nodes: [
+ {
+ id: 'contact_3',
+ name: 'Smith, Mike',
+ },
+ {
+ id: 'contact_4',
+ name: 'Smith, Shelley',
+ },
+ ],
+ totalCount: 5678,
+ };
+ const { getByTestId, queryByTestId, getByRole } = render(
+ ,
+ );
+ expect(
+ queryByTestId('ReferralsTabRecentCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(getByTestId('ReferralsTabRecentList')).toBeInTheDocument();
+ expect(getByTestId('ReferralsTabRecent').textContent).toEqual(
+ 'Recent (1,234)',
+ );
+ const referralElement1 = getByTestId(
+ 'ReferralsTabRecentListItem-contact_1',
+ );
+ expect(referralElement1.textContent).toEqual('Smith, Bob');
+ expect(referralElement1).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts/contact_1',
+ );
+ const referralElement2 = getByTestId(
+ 'ReferralsTabRecentListItem-contact_2',
+ );
+ expect(referralElement2.textContent).toEqual('Smith, Sarah');
+ expect(referralElement2).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts/contact_2',
+ );
+ expect(getByRole('link', { name: 'View All (1,234)' })).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts?filters=%7B%22created_at%22%3A%221999-12-18..2000-01-01%22%2C%22referrer%22%3A%22any%22%7D',
+ );
+ const OnHandTab = getByTestId('ReferralsTabOnHand');
+ expect(OnHandTab.textContent).toEqual('On Hand (5,678)');
+ fireEvent.click(OnHandTab);
+ expect(
+ queryByTestId('ReferralsTabOnHandCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(getByTestId('ReferralsTabOnHandList')).toBeInTheDocument();
+ const referralElement3 = getByTestId(
+ 'ReferralsTabOnHandListItem-contact_3',
+ );
+ expect(referralElement3.textContent).toEqual('Smith, Mike');
+ expect(referralElement3).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts/contact_3',
+ );
+ const referralElement4 = getByTestId(
+ 'ReferralsTabOnHandListItem-contact_4',
+ );
+ expect(referralElement4.textContent).toEqual('Smith, Shelley');
+ expect(referralElement4).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts/contact_4',
+ );
+ expect(getByRole('link', { name: 'View All (5,678)' })).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts?filters=%7B%22referrer%22%3A%22any%22%2C%22status%22%3A%22Never%20Contacted%2CAsk%20in%20Future%2CCultivate%20Relationship%2CContact%20for%20Appointment%22%7D',
+ );
+ });
});
diff --git a/src/components/Dashboard/ThisWeek/Referrals/Referrals.tsx b/src/components/Dashboard/ThisWeek/Referrals/Referrals.tsx
index c0df410117..6ccb644089 100644
--- a/src/components/Dashboard/ThisWeek/Referrals/Referrals.tsx
+++ b/src/components/Dashboard/ThisWeek/Referrals/Referrals.tsx
@@ -1,18 +1,18 @@
import React, { ReactElement, useState } from 'react';
import {
- Typography,
- makeStyles,
- Theme,
- CardHeader,
- CardActions,
- Button,
- List,
- ListItem,
- ListItemText,
- ListItemSecondaryAction,
- Tabs,
- Tab,
- CardContent,
+ Typography,
+ makeStyles,
+ Theme,
+ CardHeader,
+ CardActions,
+ Button,
+ List,
+ ListItem,
+ ListItemText,
+ ListItemSecondaryAction,
+ Tabs,
+ Tab,
+ CardContent,
} from '@material-ui/core';
import { Skeleton } from '@material-ui/lab';
import { motion } from 'framer-motion';
@@ -20,204 +20,244 @@ import { useTranslation } from 'react-i18next';
import { endOfDay, formatISO, sub } from 'date-fns';
import AnimatedCard from '../../../AnimatedCard';
import {
- GetThisWeekQuery_onHandReferrals,
- GetThisWeekQuery_recentReferrals,
+ GetThisWeekQuery_onHandReferrals,
+ GetThisWeekQuery_recentReferrals,
} from '../../../../../types/GetThisWeekQuery';
import HandoffLink from '../../../HandoffLink';
import illustration4 from '../../../../images/drawkit/grape/drawkit-grape-pack-illustration-4.svg';
const useStyles = makeStyles((theme: Theme) => ({
- div: {
- flex: 1,
- display: 'flex',
- flexDirection: 'column',
- overflow: 'auto',
+ div: {
+ flex: 1,
+ display: 'flex',
+ flexDirection: 'column',
+ overflow: 'auto',
+ },
+ list: {
+ flex: 1,
+ padding: 0,
+ overflow: 'auto',
+ },
+ card: {
+ display: 'flex',
+ flexDirection: 'column',
+ height: '322px',
+ [theme.breakpoints.down('xs')]: {
+ height: 'auto',
},
- list: {
- flex: 1,
- padding: 0,
- overflow: 'auto',
- },
- card: {
- display: 'flex',
- flexDirection: 'column',
- height: '322px',
- [theme.breakpoints.down('xs')]: {
- height: 'auto',
- },
- },
- cardContent: {
- padding: theme.spacing(2),
- display: 'flex',
- flex: 1,
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- },
- img: {
- height: '120px',
- marginBottom: 0,
- [theme.breakpoints.down('xs')]: {
- height: '150px',
- marginBottom: theme.spacing(2),
- },
+ },
+ cardContent: {
+ padding: theme.spacing(2),
+ display: 'flex',
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ img: {
+ height: '120px',
+ marginBottom: 0,
+ [theme.breakpoints.down('xs')]: {
+ height: '150px',
+ marginBottom: theme.spacing(2),
},
+ },
}));
interface ReferralsTabProps {
- loading: boolean;
- referrals: GetThisWeekQuery_onHandReferrals | GetThisWeekQuery_recentReferrals;
- tab: 'Recent' | 'OnHand';
+ loading: boolean;
+ referrals:
+ | GetThisWeekQuery_onHandReferrals
+ | GetThisWeekQuery_recentReferrals;
+ tab: 'Recent' | 'OnHand';
}
-const ReferralsTab = ({ loading, referrals, tab }: ReferralsTabProps): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
+const ReferralsTab = ({
+ loading,
+ referrals,
+ tab,
+}: ReferralsTabProps): ReactElement => {
+ const classes = useStyles();
+ const { t } = useTranslation();
- return (
+ return (
+ <>
+ {loading && (
<>
- {loading && (
- <>
-
- {[0, 1].map((index) => (
-
- }
- secondary={}
- />
-
-
-
-
- ))}
-
-
-
-
- >
- )}
- {!loading && (
- <>
- {!referrals || referrals.nodes.length === 0 ? (
-
-
- {t('No referrals to show.')}
-
- ) : (
- <>
-
- {referrals.nodes.map((contact) => (
-
-
- {contact.name}}
- />
-
-
- ))}
-
-
-
-
-
-
- >
- )}
- >
- )}
+
+ {[0, 1].map((index) => (
+
+ }
+ secondary={}
+ />
+
+
+
+
+ ))}
+
+
+
+
>
- );
+ )}
+ {!loading && (
+ <>
+ {!referrals || referrals.nodes.length === 0 ? (
+
+
+ {t('No referrals to show.')}
+
+ ) : (
+ <>
+
+ {referrals.nodes.map((contact) => (
+
+
+
+ {contact.name}
+
+ }
+ />
+
+
+ ))}
+
+
+
+
+
+
+ >
+ )}
+ >
+ )}
+ >
+ );
};
interface Props {
- loading?: boolean;
- recentReferrals?: GetThisWeekQuery_recentReferrals;
- onHandReferrals?: GetThisWeekQuery_onHandReferrals;
+ loading?: boolean;
+ recentReferrals?: GetThisWeekQuery_recentReferrals;
+ onHandReferrals?: GetThisWeekQuery_onHandReferrals;
}
-const Referrals = ({ loading, recentReferrals, onHandReferrals }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const [value, setValue] = useState(0);
+const Referrals = ({
+ loading,
+ recentReferrals,
+ onHandReferrals,
+}: Props): ReactElement => {
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const [value, setValue] = useState(0);
- const handleChange = (_event: React.ChangeEvent, newValue: number): void => {
- setValue(newValue);
- };
+ const handleChange = (_event: React.ChangeEvent, newValue: number): void => {
+ setValue(newValue);
+ };
- return (
-
-
-
-
-
-
- {value == 0 && (
-
-
-
- )}
- {value == 1 && (
-
-
-
- )}
-
- );
+ return (
+
+
+
+
+
+
+ {value == 0 && (
+
+
+
+ )}
+ {value == 1 && (
+
+
+
+ )}
+
+ );
};
export default Referrals;
diff --git a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.stories.tsx b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.stories.tsx
index 10c1b3fd6a..0abd9db17f 100644
--- a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.stories.tsx
+++ b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.stories.tsx
@@ -1,61 +1,72 @@
import React, { ReactElement } from 'react';
import { Box } from '@material-ui/core';
import { MockedProvider } from '@apollo/client/testing';
-import { GetThisWeekQuery_dueTasks, GetThisWeekQuery_dueTasks_nodes } from '../../../../../types/GetThisWeekQuery';
+import {
+ GetThisWeekQuery_dueTasks,
+ GetThisWeekQuery_dueTasks_nodes,
+} from '../../../../../types/GetThisWeekQuery';
import { ActivityTypeEnum } from '../../../../../types/globalTypes';
import TasksDueThisWeek from '.';
export default {
- title: 'Dashboard/ThisWeek/TasksDueThisWeek',
+ title: 'Dashboard/ThisWeek/TasksDueThisWeek',
};
export const Default = (): ReactElement => {
- const task: GetThisWeekQuery_dueTasks_nodes = {
- id: 'task',
- subject: 'the quick brown fox jumps over the lazy dog',
- activityType: ActivityTypeEnum.PRAYER_REQUEST,
- contacts: { nodes: [{ name: 'Smith, Roger' }] },
- startAt: null,
- completedAt: null,
- };
+ const task: GetThisWeekQuery_dueTasks_nodes = {
+ id: 'task',
+ subject: 'the quick brown fox jumps over the lazy dog',
+ activityType: ActivityTypeEnum.PRAYER_REQUEST,
+ contacts: { nodes: [{ name: 'Smith, Roger' }] },
+ startAt: null,
+ completedAt: null,
+ };
- const dueTasks: GetThisWeekQuery_dueTasks = {
- nodes: [
- { ...task, id: 'task_1' },
- { ...task, id: 'task_2' },
- { ...task, id: 'task_3' },
- ],
- totalCount: 5,
- };
- return (
-
-
-
-
-
- );
+ const dueTasks: GetThisWeekQuery_dueTasks = {
+ nodes: [
+ { ...task, id: 'task_1' },
+ { ...task, id: 'task_2' },
+ { ...task, id: 'task_3' },
+ ],
+ totalCount: 5,
+ };
+ return (
+
+
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- const dueTasks: GetThisWeekQuery_dueTasks = {
- nodes: [],
- totalCount: 0,
- };
- return (
-
-
-
-
-
- );
+ const dueTasks: GetThisWeekQuery_dueTasks = {
+ nodes: [],
+ totalCount: 0,
+ };
+ return (
+
+
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+ );
};
diff --git a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.test.tsx b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.test.tsx
index b80001d701..7473fb55be 100644
--- a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.test.tsx
+++ b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.test.tsx
@@ -8,93 +8,113 @@ import { useApp } from '../../../App';
import TasksDueThisWeek from '.';
jest.mock('../../../App', () => ({
- useApp: jest.fn(),
+ useApp: jest.fn(),
}));
const openTaskDrawer = jest.fn();
beforeEach(() => {
- (useApp as jest.Mock).mockReturnValue({
- openTaskDrawer,
- });
+ (useApp as jest.Mock).mockReturnValue({
+ openTaskDrawer,
+ });
});
describe('TasksDueThisWeek', () => {
- it('default', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('TasksDueThisWeekCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('TasksDueThisWeekList')).not.toBeInTheDocument();
- expect(queryByTestId('TasksDueThisWeekListLoading')).not.toBeInTheDocument();
- });
+ it('default', () => {
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('TasksDueThisWeekCardContentEmpty')).toBeInTheDocument();
+ expect(queryByTestId('TasksDueThisWeekList')).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TasksDueThisWeekListLoading'),
+ ).not.toBeInTheDocument();
+ });
- it('loading', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('TasksDueThisWeekListLoading')).toBeInTheDocument();
- expect(queryByTestId('TasksDueThisWeekList')).not.toBeInTheDocument();
- expect(queryByTestId('TasksDueThisWeekCardContentEmpty')).not.toBeInTheDocument();
- });
+ it('loading', () => {
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('TasksDueThisWeekListLoading')).toBeInTheDocument();
+ expect(queryByTestId('TasksDueThisWeekList')).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TasksDueThisWeekCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ });
- it('empty', () => {
- const dueTasks: GetThisWeekQuery_dueTasks = {
- nodes: [],
- totalCount: 0,
- };
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('TasksDueThisWeekCardContentEmpty')).toBeInTheDocument();
- expect(queryByTestId('TasksDueThisWeekList')).not.toBeInTheDocument();
- expect(queryByTestId('TasksDueThisWeekListLoading')).not.toBeInTheDocument();
- });
+ it('empty', () => {
+ const dueTasks: GetThisWeekQuery_dueTasks = {
+ nodes: [],
+ totalCount: 0,
+ };
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('TasksDueThisWeekCardContentEmpty')).toBeInTheDocument();
+ expect(queryByTestId('TasksDueThisWeekList')).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TasksDueThisWeekListLoading'),
+ ).not.toBeInTheDocument();
+ });
- describe('MockDate', () => {
- beforeEach(() => {
- MockDate.set(new Date(2020, 1, 1));
- });
+ describe('MockDate', () => {
+ beforeEach(() => {
+ MockDate.set(new Date(2020, 1, 1));
+ });
- afterEach(() => {
- MockDate.reset();
- });
+ afterEach(() => {
+ MockDate.reset();
+ });
- it('props', () => {
- const dueTasks: GetThisWeekQuery_dueTasks = {
- nodes: [
- {
- id: 'task_1',
- subject: 'the quick brown fox jumps over the lazy dog',
- activityType: ActivityTypeEnum.PRAYER_REQUEST,
- contacts: { nodes: [{ name: 'Smith, Roger' }] },
- startAt: null,
- completedAt: null,
- },
- {
- id: 'task_2',
- subject: 'the quick brown fox jumps over the lazy dog',
- activityType: ActivityTypeEnum.APPOINTMENT,
- contacts: { nodes: [{ name: 'Smith, Sarah' }] },
- startAt: null,
- completedAt: null,
- },
- ],
- totalCount: 1234,
- };
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('TasksDueThisWeekList')).toBeInTheDocument();
- expect(queryByTestId('TasksDueThisWeekCardContentEmpty')).not.toBeInTheDocument();
- expect(queryByTestId('TasksDueThisWeekListLoading')).not.toBeInTheDocument();
- const viewAllElement = getByTestId('TasksDueThisWeekButtonViewAll');
- expect(viewAllElement).toHaveAttribute(
- 'href',
- '/accountLists/abc/tasks?completed=false&startAt[max]=2020-02-01',
- );
- expect(viewAllElement.textContent).toEqual('View All (1,234)');
- const task1Element = getByTestId('TasksDueThisWeekListItem-task_1');
- expect(task1Element.textContent).toEqual(
- 'Smith, RogerPrayer Request — the quick brown fox jumps over the lazy dog',
- );
- userEvent.click(task1Element);
- expect(openTaskDrawer).toHaveBeenCalledWith({ taskId: 'task_1' });
- expect(getByTestId('TasksDueThisWeekListItem-task_2').textContent).toEqual(
- 'Smith, SarahAppointment — the quick brown fox jumps over the lazy dog',
- );
- });
+ it('props', () => {
+ const dueTasks: GetThisWeekQuery_dueTasks = {
+ nodes: [
+ {
+ id: 'task_1',
+ subject: 'the quick brown fox jumps over the lazy dog',
+ activityType: ActivityTypeEnum.PRAYER_REQUEST,
+ contacts: { nodes: [{ name: 'Smith, Roger' }] },
+ startAt: null,
+ completedAt: null,
+ },
+ {
+ id: 'task_2',
+ subject: 'the quick brown fox jumps over the lazy dog',
+ activityType: ActivityTypeEnum.APPOINTMENT,
+ contacts: { nodes: [{ name: 'Smith, Sarah' }] },
+ startAt: null,
+ completedAt: null,
+ },
+ ],
+ totalCount: 1234,
+ };
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('TasksDueThisWeekList')).toBeInTheDocument();
+ expect(
+ queryByTestId('TasksDueThisWeekCardContentEmpty'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TasksDueThisWeekListLoading'),
+ ).not.toBeInTheDocument();
+ const viewAllElement = getByTestId('TasksDueThisWeekButtonViewAll');
+ expect(viewAllElement).toHaveAttribute(
+ 'href',
+ '/accountLists/abc/tasks?completed=false&startAt[max]=2020-02-01',
+ );
+ expect(viewAllElement.textContent).toEqual('View All (1,234)');
+ const task1Element = getByTestId('TasksDueThisWeekListItem-task_1');
+ expect(task1Element.textContent).toEqual(
+ 'Smith, RogerPrayer Request — the quick brown fox jumps over the lazy dog',
+ );
+ userEvent.click(task1Element);
+ expect(openTaskDrawer).toHaveBeenCalledWith({ taskId: 'task_1' });
+ expect(
+ getByTestId('TasksDueThisWeekListItem-task_2').textContent,
+ ).toEqual(
+ 'Smith, SarahAppointment — the quick brown fox jumps over the lazy dog',
+ );
});
+ });
});
diff --git a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.tsx b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.tsx
index 89671b45b7..744bc49a0c 100644
--- a/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.tsx
+++ b/src/components/Dashboard/ThisWeek/TasksDueThisWeek/TasksDueThisWeek.tsx
@@ -1,17 +1,17 @@
import React, { ReactElement } from 'react';
import {
- Box,
- Typography,
- makeStyles,
- Theme,
- CardHeader,
- CardActions,
- Button,
- List,
- ListItem,
- ListItemText,
- ListItemSecondaryAction,
- CardContent,
+ Box,
+ Typography,
+ makeStyles,
+ Theme,
+ CardHeader,
+ CardActions,
+ Button,
+ List,
+ ListItem,
+ ListItemText,
+ ListItemSecondaryAction,
+ CardContent,
} from '@material-ui/core';
import { Skeleton } from '@material-ui/lab';
import { motion } from 'framer-motion';
@@ -20,177 +20,199 @@ import Link from 'next/link';
import { formatISO } from 'date-fns';
import AnimatedCard from '../../../AnimatedCard';
import {
- GetThisWeekQuery_dueTasks,
- GetThisWeekQuery_dueTasks_nodes as Task,
+ GetThisWeekQuery_dueTasks,
+ GetThisWeekQuery_dueTasks_nodes as Task,
} from '../../../../../types/GetThisWeekQuery';
import { useApp } from '../../../App';
import TaskStatus from '../../../Task/Status';
import illustration8 from '../../../../images/drawkit/grape/drawkit-grape-pack-illustration-8.svg';
const useStyles = makeStyles((theme: Theme) => ({
- div: {
- flex: 1,
- display: 'flex',
- flexDirection: 'column',
- overflow: 'auto',
- },
- list: {
- flex: 1,
- padding: 0,
- overflow: 'auto',
- },
- card: {
- display: 'flex',
- flexDirection: 'column',
- height: '322px',
- [theme.breakpoints.down('xs')]: {
- height: 'auto',
- },
- },
- cardContent: {
- padding: theme.spacing(2),
- display: 'flex',
- flex: 1,
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- },
- img: {
- height: '150px',
- marginBottom: theme.spacing(2),
+ div: {
+ flex: 1,
+ display: 'flex',
+ flexDirection: 'column',
+ overflow: 'auto',
+ },
+ list: {
+ flex: 1,
+ padding: 0,
+ overflow: 'auto',
+ },
+ card: {
+ display: 'flex',
+ flexDirection: 'column',
+ height: '322px',
+ [theme.breakpoints.down('xs')]: {
+ height: 'auto',
},
+ },
+ cardContent: {
+ padding: theme.spacing(2),
+ display: 'flex',
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ img: {
+ height: '150px',
+ marginBottom: theme.spacing(2),
+ },
}));
interface Props {
- accountListId: string;
- loading?: boolean;
- dueTasks?: GetThisWeekQuery_dueTasks;
+ accountListId: string;
+ loading?: boolean;
+ dueTasks?: GetThisWeekQuery_dueTasks;
}
-const TasksDueThisWeek = ({ loading, dueTasks, accountListId }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const { openTaskDrawer } = useApp();
+const TasksDueThisWeek = ({
+ loading,
+ dueTasks,
+ accountListId,
+}: Props): ReactElement => {
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const { openTaskDrawer } = useApp();
- const handleClick = ({ id: taskId }: Task): void => {
- openTaskDrawer({ taskId });
- };
+ const handleClick = ({ id: taskId }: Task): void => {
+ openTaskDrawer({ taskId });
+ };
- return (
-
-
- {loading && (
-
-
- {[0, 1, 2].map((index) => (
-
- }
- secondary={}
- />
-
-
-
-
- ))}
-
-
-
-
-
- )}
- {!loading && (
-
+
+ {loading && (
+
+
+ {[0, 1, 2].map((index) => (
+
+ }
+ secondary={}
+ />
+
+
+
+
+ ))}
+
+
+
+
+
+ )}
+ {!loading && (
+
+ {!dueTasks || dueTasks.nodes.length === 0 ? (
+
+
+ {t('No tasks to show.')}
+
+ ) : (
+ <>
+
+ {dueTasks.nodes.map((task) => (
+ handleClick(task)}
+ >
+
+ {task.contacts.nodes
+ .map(({ name }) => name)
+ .join(', ')}
+
+ }
+ secondary={
+
+
+
+ {
+ t(
+ task.activityType,
+ ) /* manually added to translation file */
+ }
+ {' '}
+
+ {task.activityType && '—'} {task.subject}
+
+
+
+ }
+ />
+
+
+
+
+ ))}
+
+
+
- {!dueTasks || dueTasks.nodes.length === 0 ? (
-
-
- {t('No tasks to show.')}
-
- ) : (
- <>
-
- {dueTasks.nodes.map((task) => (
- handleClick(task)}
- >
-
- {task.contacts.nodes.map(({ name }) => name).join(', ')}
-
- }
- secondary={
-
-
-
- {
- t(
- task.activityType,
- ) /* manually added to translation file */
- }
- {' '}
-
- {task.activityType && '—'} {task.subject}
-
-
-
- }
- />
-
-
-
-
- ))}
-
-
-
-
-
-
- >
- )}
-
- )}
-
- );
+
+
+
+ >
+ )}
+
+ )}
+
+ );
};
export default TasksDueThisWeek;
diff --git a/src/components/Dashboard/ThisWeek/ThisWeek.mock.ts b/src/components/Dashboard/ThisWeek/ThisWeek.mock.ts
index 0b94803b98..8cdb104c22 100644
--- a/src/components/Dashboard/ThisWeek/ThisWeek.mock.ts
+++ b/src/components/Dashboard/ThisWeek/ThisWeek.mock.ts
@@ -4,180 +4,188 @@ import { GetThisWeekQuery } from '../../../../types/GetThisWeekQuery';
import { ActivityTypeEnum } from '../../../../types/globalTypes';
import { GET_THIS_WEEK_QUERY } from './ThisWeek';
import {
- GetWeeklyActivityQueryDefaultMocks,
- GetWeeklyActivityQueryLoadingMocks,
- GetWeeklyActivityQueryEmptyMocks,
+ GetWeeklyActivityQueryDefaultMocks,
+ GetWeeklyActivityQueryLoadingMocks,
+ GetWeeklyActivityQueryEmptyMocks,
} from './WeeklyActivity/WeeklyActivity.mock';
export const GetThisWeekDefaultMocks = (): MockedResponse[] => {
- const task = {
- id: 'task',
- subject: 'the quick brown fox jumps over the lazy dog',
- activityType: ActivityTypeEnum.PRAYER_REQUEST,
- contacts: { nodes: [{ name: 'Smith, Roger' }] },
- startAt: new Date(2012, 12, 5, 1, 2),
- completedAt: null,
- };
- const contact = {
- id: 'contact',
- name: 'Smith, Sarah',
- lateAt: '2012-10-01',
- };
- const referral = {
- id: 'contact',
- name: 'Smith, Sarah',
- };
- const personWithBirthday = {
- id: 'person',
- birthdayDay: 1,
- birthdayMonth: 1,
- firstName: 'John',
- lastName: 'Doe',
- parentContact: {
- id: 'contact',
- },
- };
- const personWithAnniversary = {
- id: 'person',
- anniversaryDay: 5,
- anniversaryMonth: 10,
- parentContact: {
- id: 'contact',
- name: 'John and Sarah, Doe',
- },
- };
- const data: GetThisWeekQuery = {
- accountList: {
- id: 'abc',
- primaryAppeal: {
- id: 'appeal_1',
- name: '2020 End of Year Ask',
- amount: 1000,
- pledgesAmountTotal: 750,
- pledgesAmountProcessed: 500,
- amountCurrency: 'EUR',
- },
- },
- dueTasks: {
- nodes: [
- { ...task, id: 'task_1' },
- { ...task, id: 'task_2' },
- { ...task, id: 'task_3' },
- ],
- totalCount: 50,
- },
- prayerRequestTasks: {
- nodes: [
- { ...task, id: 'task_4' },
- { ...task, id: 'task_5' },
- { ...task, id: 'task_6' },
- ],
- totalCount: 80,
- },
- latePledgeContacts: {
- nodes: [
- { ...contact, id: 'contact_1' },
- { ...contact, id: 'contact_2' },
- { ...contact, id: 'contact_3' },
- ],
- totalCount: 5,
- },
- reportsPeopleWithBirthdays: {
- periods: [
- {
- people: [
- { ...personWithBirthday, id: 'person_1' },
- { ...personWithBirthday, id: 'person_2' },
- ],
- },
- ],
- },
- reportsPeopleWithAnniversaries: {
- periods: [
- {
- people: [
- { ...personWithAnniversary, id: 'person_3' },
- { ...personWithAnniversary, id: 'person_4' },
- ],
- },
- ],
- },
- recentReferrals: {
- nodes: [
- { ...referral, id: 'contact_4' },
- { ...referral, id: 'contact_5' },
- { ...referral, id: 'contact_6' },
- ],
- totalCount: 5,
- },
- onHandReferrals: {
- nodes: [
- { ...referral, id: 'contact_7' },
- { ...referral, id: 'contact_8' },
- { ...referral, id: 'contact_9' },
- ],
- totalCount: 5,
+ const task = {
+ id: 'task',
+ subject: 'the quick brown fox jumps over the lazy dog',
+ activityType: ActivityTypeEnum.PRAYER_REQUEST,
+ contacts: { nodes: [{ name: 'Smith, Roger' }] },
+ startAt: new Date(2012, 12, 5, 1, 2),
+ completedAt: null,
+ };
+ const contact = {
+ id: 'contact',
+ name: 'Smith, Sarah',
+ lateAt: '2012-10-01',
+ };
+ const referral = {
+ id: 'contact',
+ name: 'Smith, Sarah',
+ };
+ const personWithBirthday = {
+ id: 'person',
+ birthdayDay: 1,
+ birthdayMonth: 1,
+ firstName: 'John',
+ lastName: 'Doe',
+ parentContact: {
+ id: 'contact',
+ },
+ };
+ const personWithAnniversary = {
+ id: 'person',
+ anniversaryDay: 5,
+ anniversaryMonth: 10,
+ parentContact: {
+ id: 'contact',
+ name: 'John and Sarah, Doe',
+ },
+ };
+ const data: GetThisWeekQuery = {
+ accountList: {
+ id: 'abc',
+ primaryAppeal: {
+ id: 'appeal_1',
+ name: '2020 End of Year Ask',
+ amount: 1000,
+ pledgesAmountTotal: 750,
+ pledgesAmountProcessed: 500,
+ amountCurrency: 'EUR',
+ },
+ },
+ dueTasks: {
+ nodes: [
+ { ...task, id: 'task_1' },
+ { ...task, id: 'task_2' },
+ { ...task, id: 'task_3' },
+ ],
+ totalCount: 50,
+ },
+ prayerRequestTasks: {
+ nodes: [
+ { ...task, id: 'task_4' },
+ { ...task, id: 'task_5' },
+ { ...task, id: 'task_6' },
+ ],
+ totalCount: 80,
+ },
+ latePledgeContacts: {
+ nodes: [
+ { ...contact, id: 'contact_1' },
+ { ...contact, id: 'contact_2' },
+ { ...contact, id: 'contact_3' },
+ ],
+ totalCount: 5,
+ },
+ reportsPeopleWithBirthdays: {
+ periods: [
+ {
+ people: [
+ { ...personWithBirthday, id: 'person_1' },
+ { ...personWithBirthday, id: 'person_2' },
+ ],
},
- };
- return [
+ ],
+ },
+ reportsPeopleWithAnniversaries: {
+ periods: [
{
- request: {
- query: GET_THIS_WEEK_QUERY,
- variables: {
- accountListId: 'abc',
- endOfDay: formatISO(endOfDay(new Date())),
- today: formatISO(endOfDay(new Date()), { representation: 'date' }),
- twoWeeksFromNow: formatISO(add(endOfDay(new Date()), { weeks: 2 }), { representation: 'date' }),
- twoWeeksAgo: formatISO(sub(endOfDay(new Date()), { weeks: 2 }), { representation: 'date' }),
- },
- },
- result: {
- data,
- },
+ people: [
+ { ...personWithAnniversary, id: 'person_3' },
+ { ...personWithAnniversary, id: 'person_4' },
+ ],
},
- ...GetWeeklyActivityQueryDefaultMocks(),
- ];
+ ],
+ },
+ recentReferrals: {
+ nodes: [
+ { ...referral, id: 'contact_4' },
+ { ...referral, id: 'contact_5' },
+ { ...referral, id: 'contact_6' },
+ ],
+ totalCount: 5,
+ },
+ onHandReferrals: {
+ nodes: [
+ { ...referral, id: 'contact_7' },
+ { ...referral, id: 'contact_8' },
+ { ...referral, id: 'contact_9' },
+ ],
+ totalCount: 5,
+ },
+ };
+ return [
+ {
+ request: {
+ query: GET_THIS_WEEK_QUERY,
+ variables: {
+ accountListId: 'abc',
+ endOfDay: formatISO(endOfDay(new Date())),
+ today: formatISO(endOfDay(new Date()), { representation: 'date' }),
+ twoWeeksFromNow: formatISO(add(endOfDay(new Date()), { weeks: 2 }), {
+ representation: 'date',
+ }),
+ twoWeeksAgo: formatISO(sub(endOfDay(new Date()), { weeks: 2 }), {
+ representation: 'date',
+ }),
+ },
+ },
+ result: {
+ data,
+ },
+ },
+ ...GetWeeklyActivityQueryDefaultMocks(),
+ ];
};
export const GetThisWeekEmptyMocks = (): MockedResponse[] => {
- const data: GetThisWeekQuery = {
- accountList: {
- id: 'abc',
- primaryAppeal: null,
+ const data: GetThisWeekQuery = {
+ accountList: {
+ id: 'abc',
+ primaryAppeal: null,
+ },
+ dueTasks: { nodes: [], totalCount: 0 },
+ prayerRequestTasks: { nodes: [], totalCount: 0 },
+ latePledgeContacts: { nodes: [], totalCount: 0 },
+ reportsPeopleWithBirthdays: { periods: [{ people: [] }] },
+ reportsPeopleWithAnniversaries: { periods: [{ people: [] }] },
+ recentReferrals: { nodes: [], totalCount: 0 },
+ onHandReferrals: { nodes: [], totalCount: 0 },
+ };
+ return [
+ {
+ request: {
+ query: GET_THIS_WEEK_QUERY,
+ variables: {
+ accountListId: 'abc',
+ endOfDay: formatISO(endOfDay(new Date())),
+ today: formatISO(endOfDay(new Date()), { representation: 'date' }),
+ twoWeeksFromNow: formatISO(add(endOfDay(new Date()), { weeks: 2 }), {
+ representation: 'date',
+ }),
+ twoWeeksAgo: formatISO(sub(endOfDay(new Date()), { weeks: 2 }), {
+ representation: 'date',
+ }),
},
- dueTasks: { nodes: [], totalCount: 0 },
- prayerRequestTasks: { nodes: [], totalCount: 0 },
- latePledgeContacts: { nodes: [], totalCount: 0 },
- reportsPeopleWithBirthdays: { periods: [{ people: [] }] },
- reportsPeopleWithAnniversaries: { periods: [{ people: [] }] },
- recentReferrals: { nodes: [], totalCount: 0 },
- onHandReferrals: { nodes: [], totalCount: 0 },
- };
- return [
- {
- request: {
- query: GET_THIS_WEEK_QUERY,
- variables: {
- accountListId: 'abc',
- endOfDay: formatISO(endOfDay(new Date())),
- today: formatISO(endOfDay(new Date()), { representation: 'date' }),
- twoWeeksFromNow: formatISO(add(endOfDay(new Date()), { weeks: 2 }), { representation: 'date' }),
- twoWeeksAgo: formatISO(sub(endOfDay(new Date()), { weeks: 2 }), { representation: 'date' }),
- },
- },
- result: {
- data,
- },
- },
- ...GetWeeklyActivityQueryEmptyMocks(),
- ];
+ },
+ result: {
+ data,
+ },
+ },
+ ...GetWeeklyActivityQueryEmptyMocks(),
+ ];
};
export const GetThisWeekLoadingMocks = (): MockedResponse[] => {
- return [
- {
- ...GetThisWeekDefaultMocks()[0],
- delay: 100931731455,
- },
- ...GetWeeklyActivityQueryLoadingMocks(),
- ];
+ return [
+ {
+ ...GetThisWeekDefaultMocks()[0],
+ delay: 100931731455,
+ },
+ ...GetWeeklyActivityQueryLoadingMocks(),
+ ];
};
diff --git a/src/components/Dashboard/ThisWeek/ThisWeek.stories.tsx b/src/components/Dashboard/ThisWeek/ThisWeek.stories.tsx
index b4be0feebd..04f4c0fab4 100644
--- a/src/components/Dashboard/ThisWeek/ThisWeek.stories.tsx
+++ b/src/components/Dashboard/ThisWeek/ThisWeek.stories.tsx
@@ -3,32 +3,41 @@ import { MockedProvider } from '@apollo/client/testing';
import withDispatch from '../../../decorators/withDispatch';
import withMargin from '../../../decorators/withMargin';
import { GetWeeklyActivityQueryLoadingMocks } from './WeeklyActivity/WeeklyActivity.mock';
-import { GetThisWeekEmptyMocks, GetThisWeekDefaultMocks } from './ThisWeek.mock';
+import {
+ GetThisWeekEmptyMocks,
+ GetThisWeekDefaultMocks,
+} from './ThisWeek.mock';
import ThisWeek from '.';
export default {
- title: 'Dashboard/ThisWeek',
- decorators: [withDispatch({ type: 'updateAccountListId', accountListId: 'abc' }), withMargin],
+ title: 'Dashboard/ThisWeek',
+ decorators: [
+ withDispatch({ type: 'updateAccountListId', accountListId: 'abc' }),
+ withMargin,
+ ],
};
export const Default = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Dashboard/ThisWeek/ThisWeek.test.tsx b/src/components/Dashboard/ThisWeek/ThisWeek.test.tsx
index 822d247baf..60b0317919 100644
--- a/src/components/Dashboard/ThisWeek/ThisWeek.test.tsx
+++ b/src/components/Dashboard/ThisWeek/ThisWeek.test.tsx
@@ -2,53 +2,69 @@ import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import { AppProviderContext } from '../../App/Provider';
-import { GetThisWeekEmptyMocks, GetThisWeekLoadingMocks, GetThisWeekDefaultMocks } from './ThisWeek.mock';
+import {
+ GetThisWeekEmptyMocks,
+ GetThisWeekLoadingMocks,
+ GetThisWeekDefaultMocks,
+} from './ThisWeek.mock';
import ThisWeek from '.';
jest.mock('../../App', () => ({
- useApp: (): Partial => ({
- openTaskDrawer: jest.fn(),
- }),
+ useApp: (): Partial => ({
+ openTaskDrawer: jest.fn(),
+ }),
}));
describe('ThisWeek', () => {
- it('default', async () => {
- const { getByTestId, queryByTestId } = render(
-
-
- ,
- );
- await waitFor(() => expect(queryByTestId('PartnerCarePrayerListLoading')).not.toBeInTheDocument());
- expect(getByTestId('PartnerCarePrayerList')).toBeInTheDocument();
- expect(getByTestId('TasksDueThisWeekList')).toBeInTheDocument();
- expect(getByTestId('LateCommitmentsListContacts')).toBeInTheDocument();
- expect(getByTestId('ReferralsTabRecentList')).toBeInTheDocument();
- expect(getByTestId('AppealsBoxName')).toBeInTheDocument();
- });
+ it('default', async () => {
+ const { getByTestId, queryByTestId } = render(
+
+
+ ,
+ );
+ await waitFor(() =>
+ expect(
+ queryByTestId('PartnerCarePrayerListLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(getByTestId('PartnerCarePrayerList')).toBeInTheDocument();
+ expect(getByTestId('TasksDueThisWeekList')).toBeInTheDocument();
+ expect(getByTestId('LateCommitmentsListContacts')).toBeInTheDocument();
+ expect(getByTestId('ReferralsTabRecentList')).toBeInTheDocument();
+ expect(getByTestId('AppealsBoxName')).toBeInTheDocument();
+ });
- it('loading', () => {
- const { getByTestId } = render(
-
-
- ,
- );
- expect(getByTestId('PartnerCarePrayerListLoading')).toBeInTheDocument();
- expect(getByTestId('TasksDueThisWeekListLoading')).toBeInTheDocument();
- expect(getByTestId('LateCommitmentsDivLoading')).toBeInTheDocument();
- expect(getByTestId('ReferralsTabRecentListLoading')).toBeInTheDocument();
- });
+ it('loading', () => {
+ const { getByTestId } = render(
+
+
+ ,
+ );
+ expect(getByTestId('PartnerCarePrayerListLoading')).toBeInTheDocument();
+ expect(getByTestId('TasksDueThisWeekListLoading')).toBeInTheDocument();
+ expect(getByTestId('LateCommitmentsDivLoading')).toBeInTheDocument();
+ expect(getByTestId('ReferralsTabRecentListLoading')).toBeInTheDocument();
+ });
- it('empty', async () => {
- const { getByTestId, queryByTestId } = render(
-
-
- ,
- );
- await waitFor(() => expect(queryByTestId('PartnerCarePrayerListLoading')).not.toBeInTheDocument());
- expect(getByTestId('PartnerCarePrayerCardContentEmpty')).toBeInTheDocument();
- expect(getByTestId('TasksDueThisWeekCardContentEmpty')).toBeInTheDocument();
- expect(getByTestId('LateCommitmentsCardContentEmpty')).toBeInTheDocument();
- expect(getByTestId('ReferralsTabRecentCardContentEmpty')).toBeInTheDocument();
- expect(getByTestId('AppealsCardContentEmpty')).toBeInTheDocument();
- });
+ it('empty', async () => {
+ const { getByTestId, queryByTestId } = render(
+
+
+ ,
+ );
+ await waitFor(() =>
+ expect(
+ queryByTestId('PartnerCarePrayerListLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(
+ getByTestId('PartnerCarePrayerCardContentEmpty'),
+ ).toBeInTheDocument();
+ expect(getByTestId('TasksDueThisWeekCardContentEmpty')).toBeInTheDocument();
+ expect(getByTestId('LateCommitmentsCardContentEmpty')).toBeInTheDocument();
+ expect(
+ getByTestId('ReferralsTabRecentCardContentEmpty'),
+ ).toBeInTheDocument();
+ expect(getByTestId('AppealsCardContentEmpty')).toBeInTheDocument();
+ });
});
diff --git a/src/components/Dashboard/ThisWeek/ThisWeek.tsx b/src/components/Dashboard/ThisWeek/ThisWeek.tsx
index ad6d2d2514..193ed27f7d 100644
--- a/src/components/Dashboard/ThisWeek/ThisWeek.tsx
+++ b/src/components/Dashboard/ThisWeek/ThisWeek.tsx
@@ -13,188 +13,221 @@ import Appeals from './Appeals';
import WeeklyActivity from './WeeklyActivity';
interface Props {
- accountListId: string;
+ accountListId: string;
}
export const GET_THIS_WEEK_QUERY = gql`
- query GetThisWeekQuery(
- $accountListId: ID!
- $endOfDay: ISO8601DateTime!
- $today: ISO8601Date!
- $twoWeeksFromNow: ISO8601Date!
- $twoWeeksAgo: ISO8601Date!
+ query GetThisWeekQuery(
+ $accountListId: ID!
+ $endOfDay: ISO8601DateTime!
+ $today: ISO8601Date!
+ $twoWeeksFromNow: ISO8601Date!
+ $twoWeeksAgo: ISO8601Date!
+ ) {
+ accountList(id: $accountListId) {
+ id
+ primaryAppeal {
+ id
+ name
+ amount
+ pledgesAmountTotal
+ pledgesAmountProcessed
+ amountCurrency
+ }
+ }
+ dueTasks: tasks(
+ accountListId: $accountListId
+ first: 3
+ startAt: { max: $endOfDay }
+ completed: false
) {
- accountList(id: $accountListId) {
- id
- primaryAppeal {
- id
- name
- amount
- pledgesAmountTotal
- pledgesAmountProcessed
- amountCurrency
- }
- }
- dueTasks: tasks(accountListId: $accountListId, first: 3, startAt: { max: $endOfDay }, completed: false) {
- nodes {
- id
- subject
- activityType
- startAt
- completedAt
- contacts {
- nodes {
- name
- }
- }
- }
- totalCount
- }
- prayerRequestTasks: tasks(
- accountListId: $accountListId
- first: 3
- activityType: PRAYER_REQUEST
- completed: false
- ) {
- nodes {
- id
- subject
- activityType
- startAt
- completedAt
- contacts {
- nodes {
- name
- }
- }
- }
- totalCount
- }
- latePledgeContacts: contacts(
- accountListId: $accountListId
- first: 3
- lateAt: { max: $today }
- status: PARTNER_FINANCIAL
- ) {
- nodes {
- id
- name
- lateAt
- }
- totalCount
+ nodes {
+ id
+ subject
+ activityType
+ startAt
+ completedAt
+ contacts {
+ nodes {
+ name
+ }
}
- reportsPeopleWithBirthdays(accountListId: $accountListId, range: "1m", endDate: $twoWeeksFromNow) {
- periods {
- people {
- id
- birthdayDay
- birthdayMonth
- firstName
- lastName
- parentContact {
- id
- }
- }
- }
- }
- reportsPeopleWithAnniversaries(accountListId: $accountListId, range: "1m", endDate: $twoWeeksFromNow) {
- periods {
- people {
- id
- anniversaryDay
- anniversaryMonth
- parentContact {
- id
- name
- }
- }
- }
+ }
+ totalCount
+ }
+ prayerRequestTasks: tasks(
+ accountListId: $accountListId
+ first: 3
+ activityType: PRAYER_REQUEST
+ completed: false
+ ) {
+ nodes {
+ id
+ subject
+ activityType
+ startAt
+ completedAt
+ contacts {
+ nodes {
+ name
+ }
}
- recentReferrals: contacts(
- accountListId: $accountListId
- first: 3
- referrer: ANY
- createdAt: { min: $twoWeeksAgo }
- ) {
- nodes {
- id
- name
- }
- totalCount
+ }
+ totalCount
+ }
+ latePledgeContacts: contacts(
+ accountListId: $accountListId
+ first: 3
+ lateAt: { max: $today }
+ status: PARTNER_FINANCIAL
+ ) {
+ nodes {
+ id
+ name
+ lateAt
+ }
+ totalCount
+ }
+ reportsPeopleWithBirthdays(
+ accountListId: $accountListId
+ range: "1m"
+ endDate: $twoWeeksFromNow
+ ) {
+ periods {
+ people {
+ id
+ birthdayDay
+ birthdayMonth
+ firstName
+ lastName
+ parentContact {
+ id
+ }
}
- onHandReferrals: contacts(
- accountListId: $accountListId
- first: 3
- status: [NEVER_CONTACTED, ASK_IN_FUTURE, CULTIVATE_RELATIONSHIP, CONTACT_FOR_APPOINTMENT]
- referrer: ANY
- ) {
- nodes {
- id
- name
- }
- totalCount
+ }
+ }
+ reportsPeopleWithAnniversaries(
+ accountListId: $accountListId
+ range: "1m"
+ endDate: $twoWeeksFromNow
+ ) {
+ periods {
+ people {
+ id
+ anniversaryDay
+ anniversaryMonth
+ parentContact {
+ id
+ name
+ }
}
+ }
+ }
+ recentReferrals: contacts(
+ accountListId: $accountListId
+ first: 3
+ referrer: ANY
+ createdAt: { min: $twoWeeksAgo }
+ ) {
+ nodes {
+ id
+ name
+ }
+ totalCount
+ }
+ onHandReferrals: contacts(
+ accountListId: $accountListId
+ first: 3
+ status: [
+ NEVER_CONTACTED
+ ASK_IN_FUTURE
+ CULTIVATE_RELATIONSHIP
+ CONTACT_FOR_APPOINTMENT
+ ]
+ referrer: ANY
+ ) {
+ nodes {
+ id
+ name
+ }
+ totalCount
}
+ }
`;
const ThisWeek = ({ accountListId }: Props): ReactElement => {
- const { t } = useTranslation();
- const { data, loading } = useQuery(GET_THIS_WEEK_QUERY, {
- variables: {
- accountListId,
- endOfDay: formatISO(endOfDay(new Date())),
- today: formatISO(endOfDay(new Date()), { representation: 'date' }),
- twoWeeksFromNow: formatISO(add(endOfDay(new Date()), { weeks: 2 }), { representation: 'date' }),
- twoWeeksAgo: formatISO(sub(endOfDay(new Date()), { weeks: 2 }), { representation: 'date' }),
- },
- });
+ const { t } = useTranslation();
+ const { data, loading } = useQuery(GET_THIS_WEEK_QUERY, {
+ variables: {
+ accountListId,
+ endOfDay: formatISO(endOfDay(new Date())),
+ today: formatISO(endOfDay(new Date()), { representation: 'date' }),
+ twoWeeksFromNow: formatISO(add(endOfDay(new Date()), { weeks: 2 }), {
+ representation: 'date',
+ }),
+ twoWeeksAgo: formatISO(sub(endOfDay(new Date()), { weeks: 2 }), {
+ representation: 'date',
+ }),
+ },
+ });
- const {
- dueTasks,
- prayerRequestTasks,
- latePledgeContacts,
- reportsPeopleWithBirthdays,
- reportsPeopleWithAnniversaries,
- recentReferrals,
- onHandReferrals,
- accountList,
- } = data || {};
+ const {
+ dueTasks,
+ prayerRequestTasks,
+ latePledgeContacts,
+ reportsPeopleWithBirthdays,
+ reportsPeopleWithAnniversaries,
+ recentReferrals,
+ onHandReferrals,
+ accountList,
+ } = data || {};
- return (
- <>
-
-
- {t('To Do This Week')}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- );
+ return (
+ <>
+
+
+ {t('To Do This Week')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
};
export default ThisWeek;
diff --git a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.mock.ts b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.mock.ts
index e5eb3858e3..32850d09c6 100644
--- a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.mock.ts
+++ b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.mock.ts
@@ -4,107 +4,113 @@ import { GetWeeklyActivityQuery } from '../../../../../types/GetWeeklyActivityQu
import { GET_WEEKLY_ACTIVITY_QUERY } from './WeeklyActivity';
const data: GetWeeklyActivityQuery = {
- completedCalls: { totalCount: 1234 },
- callsThatProducedAppointments: { totalCount: 5678 },
- completedMessages: { totalCount: 9012 },
- messagesThatProducedAppointments: { totalCount: 3456 },
- completedAppointments: { totalCount: 7890 },
- completedCorrespondence: { totalCount: 1234 },
+ completedCalls: { totalCount: 1234 },
+ callsThatProducedAppointments: { totalCount: 5678 },
+ completedMessages: { totalCount: 9012 },
+ messagesThatProducedAppointments: { totalCount: 3456 },
+ completedAppointments: { totalCount: 7890 },
+ completedCorrespondence: { totalCount: 1234 },
};
const dataPreviousWeek: GetWeeklyActivityQuery = {
- completedCalls: { totalCount: 5678 },
- callsThatProducedAppointments: { totalCount: 9012 },
- completedMessages: { totalCount: 3456 },
- messagesThatProducedAppointments: { totalCount: 7890 },
- completedAppointments: { totalCount: 1234 },
- completedCorrespondence: { totalCount: 5678 },
+ completedCalls: { totalCount: 5678 },
+ callsThatProducedAppointments: { totalCount: 9012 },
+ completedMessages: { totalCount: 3456 },
+ messagesThatProducedAppointments: { totalCount: 7890 },
+ completedAppointments: { totalCount: 1234 },
+ completedCorrespondence: { totalCount: 5678 },
};
export const GetWeeklyActivityQueryDefaultMocks = (
- startOfWeek = new Date(),
- endOfWeek = new Date(),
+ startOfWeek = new Date(),
+ endOfWeek = new Date(),
): MockedResponse[] => {
- return [
- {
- request: {
- query: GET_WEEKLY_ACTIVITY_QUERY,
- variables: {
- accountListId: 'abc',
- startOfWeek: moment(startOfWeek).startOf('week').toISOString(),
- endOfWeek: moment(endOfWeek).endOf('week').toISOString(),
- },
- },
- result: {
- data,
- },
+ return [
+ {
+ request: {
+ query: GET_WEEKLY_ACTIVITY_QUERY,
+ variables: {
+ accountListId: 'abc',
+ startOfWeek: moment(startOfWeek).startOf('week').toISOString(),
+ endOfWeek: moment(endOfWeek).endOf('week').toISOString(),
},
- {
- request: {
- query: GET_WEEKLY_ACTIVITY_QUERY,
- variables: {
- accountListId: 'abc',
- startOfWeek: moment(startOfWeek).startOf('week').subtract(1, 'week').toISOString(),
- endOfWeek: moment(endOfWeek).endOf('week').subtract(1, 'week').toISOString(),
- },
- },
- result: {
- data: dataPreviousWeek,
- },
+ },
+ result: {
+ data,
+ },
+ },
+ {
+ request: {
+ query: GET_WEEKLY_ACTIVITY_QUERY,
+ variables: {
+ accountListId: 'abc',
+ startOfWeek: moment(startOfWeek)
+ .startOf('week')
+ .subtract(1, 'week')
+ .toISOString(),
+ endOfWeek: moment(endOfWeek)
+ .endOf('week')
+ .subtract(1, 'week')
+ .toISOString(),
},
- {
- request: {
- query: GET_WEEKLY_ACTIVITY_QUERY,
- variables: {
- accountListId: 'abc',
- startOfWeek: moment(startOfWeek).startOf('week').toISOString(),
- endOfWeek: moment(endOfWeek).endOf('week').toISOString(),
- },
- },
- result: {
- data,
- },
+ },
+ result: {
+ data: dataPreviousWeek,
+ },
+ },
+ {
+ request: {
+ query: GET_WEEKLY_ACTIVITY_QUERY,
+ variables: {
+ accountListId: 'abc',
+ startOfWeek: moment(startOfWeek).startOf('week').toISOString(),
+ endOfWeek: moment(endOfWeek).endOf('week').toISOString(),
},
- ];
+ },
+ result: {
+ data,
+ },
+ },
+ ];
};
const emptyData: GetWeeklyActivityQuery = {
- completedCalls: { totalCount: 0 },
- callsThatProducedAppointments: { totalCount: 0 },
- completedMessages: { totalCount: 0 },
- messagesThatProducedAppointments: { totalCount: 0 },
- completedAppointments: { totalCount: 0 },
- completedCorrespondence: { totalCount: 0 },
+ completedCalls: { totalCount: 0 },
+ callsThatProducedAppointments: { totalCount: 0 },
+ completedMessages: { totalCount: 0 },
+ messagesThatProducedAppointments: { totalCount: 0 },
+ completedAppointments: { totalCount: 0 },
+ completedCorrespondence: { totalCount: 0 },
};
export const GetWeeklyActivityQueryEmptyMocks = (
- startOfWeek = new Date(),
- endOfWeek = new Date(),
+ startOfWeek = new Date(),
+ endOfWeek = new Date(),
): MockedResponse[] => {
- return [
- {
- request: {
- query: GET_WEEKLY_ACTIVITY_QUERY,
- variables: {
- accountListId: 'abc',
- startOfWeek: moment(startOfWeek).startOf('week').toISOString(),
- endOfWeek: moment(endOfWeek).endOf('week').toISOString(),
- },
- },
- result: {
- data: emptyData,
- },
+ return [
+ {
+ request: {
+ query: GET_WEEKLY_ACTIVITY_QUERY,
+ variables: {
+ accountListId: 'abc',
+ startOfWeek: moment(startOfWeek).startOf('week').toISOString(),
+ endOfWeek: moment(endOfWeek).endOf('week').toISOString(),
},
- ];
+ },
+ result: {
+ data: emptyData,
+ },
+ },
+ ];
};
export const GetWeeklyActivityQueryLoadingMocks = (
- startOfWeek = new Date(),
- endOfWeek = new Date(),
+ startOfWeek = new Date(),
+ endOfWeek = new Date(),
): MockedResponse[] => {
- return [
- {
- ...GetWeeklyActivityQueryDefaultMocks(startOfWeek, endOfWeek)[0],
- delay: 100931731455,
- },
- ];
+ return [
+ {
+ ...GetWeeklyActivityQueryDefaultMocks(startOfWeek, endOfWeek)[0],
+ delay: 100931731455,
+ },
+ ];
};
diff --git a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.stories.tsx b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.stories.tsx
index b728650988..2d75be2c44 100644
--- a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.stories.tsx
+++ b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.stories.tsx
@@ -1,29 +1,38 @@
import React, { ReactElement } from 'react';
import { Box } from '@material-ui/core';
import { MockedProvider } from '@apollo/client/testing';
-import { GetWeeklyActivityQueryDefaultMocks, GetWeeklyActivityQueryLoadingMocks } from './WeeklyActivity.mock';
+import {
+ GetWeeklyActivityQueryDefaultMocks,
+ GetWeeklyActivityQueryLoadingMocks,
+} from './WeeklyActivity.mock';
import WeeklyActivity from '.';
export default {
- title: 'Dashboard/ThisWeek/WeeklyActivity',
+ title: 'Dashboard/ThisWeek/WeeklyActivity',
};
export const Default = (): ReactElement => {
- return (
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+ );
};
diff --git a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.test.tsx b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.test.tsx
index 8f5454d77c..c2b35cbe39 100644
--- a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.test.tsx
+++ b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.test.tsx
@@ -2,71 +2,122 @@ import React from 'react';
import { render, waitFor, fireEvent } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import MockDate from 'mockdate';
-import { GetWeeklyActivityQueryDefaultMocks, GetWeeklyActivityQueryLoadingMocks } from './WeeklyActivity.mock';
+import {
+ GetWeeklyActivityQueryDefaultMocks,
+ GetWeeklyActivityQueryLoadingMocks,
+} from './WeeklyActivity.mock';
import WeeklyActivity from '.';
describe('WeeklyActivity', () => {
- it('loading', () => {
- const { getByTestId } = render(
-
-
- ,
- );
- expect(getByTestId('WeeklyActivityTableCellCompletedCalls').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('WeeklyActivityTableCellCallsThatProducedAppointments').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('WeeklyActivityTableCellCompletedMessages').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('WeeklyActivityTableCellMessagesThatProducedAppointments').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('WeeklyActivityTableCellCompletedAppointments').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- expect(getByTestId('WeeklyActivityTableCellCompletedCorrespondence').children[0].className).toContain(
- 'MuiSkeleton-root',
- );
- });
+ it('loading', () => {
+ const { getByTestId } = render(
+
+
+ ,
+ );
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedCalls').children[0]
+ .className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('WeeklyActivityTableCellCallsThatProducedAppointments')
+ .children[0].className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedMessages').children[0]
+ .className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('WeeklyActivityTableCellMessagesThatProducedAppointments')
+ .children[0].className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedAppointments').children[0]
+ .className,
+ ).toContain('MuiSkeleton-root');
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedCorrespondence').children[0]
+ .className,
+ ).toContain('MuiSkeleton-root');
+ });
- describe('MockDate', () => {
- beforeEach(() => {
- MockDate.set(new Date(2020, 1, 1));
- });
+ describe('MockDate', () => {
+ beforeEach(() => {
+ MockDate.set(new Date(2020, 1, 1));
+ });
- afterEach(() => {
- MockDate.reset();
- });
+ afterEach(() => {
+ MockDate.reset();
+ });
- it('default', async () => {
- const { getByTestId, queryByTestId, getByRole } = render(
-
-
- ,
- );
- expect(getByTestId('WeeklyActivityTableCellDateRange').textContent).toEqual('Jan 26 - Feb 1');
- await waitFor(() => expect(queryByTestId('WeeklyActivitySkeletonLoading')).not.toBeInTheDocument());
- expect(getByTestId('WeeklyActivityTableCellCompletedCalls').textContent).toEqual('1,234');
- expect(getByTestId('WeeklyActivityTableCellCallsThatProducedAppointments').textContent).toEqual('5,678');
- expect(getByTestId('WeeklyActivityTableCellCompletedMessages').textContent).toEqual('9,012');
- expect(getByTestId('WeeklyActivityTableCellMessagesThatProducedAppointments').textContent).toEqual('3,456');
- expect(getByTestId('WeeklyActivityTableCellCompletedAppointments').textContent).toEqual('7,890');
- expect(getByTestId('WeeklyActivityTableCellCompletedCorrespondence').textContent).toEqual('1,234');
- fireEvent.click(getByTestId('WeeklyActivityIconButtonSubtractWeek'));
- await waitFor(() => expect(queryByTestId('WeeklyActivitySkeletonLoading')).not.toBeInTheDocument());
- expect(getByTestId('WeeklyActivityTableCellDateRange').textContent).toEqual('Jan 19 - Jan 25');
- expect(getByTestId('WeeklyActivityTableCellCompletedCalls').textContent).toEqual('5,678');
- fireEvent.click(getByTestId('WeeklyActivityIconButtonAddWeek'));
- await waitFor(() => expect(queryByTestId('WeeklyActivitySkeletonLoading')).not.toBeInTheDocument());
- expect(getByTestId('WeeklyActivityTableCellDateRange').textContent).toEqual('Jan 26 - Feb 1');
- expect(getByTestId('WeeklyActivityTableCellCompletedCalls').textContent).toEqual('1,234');
- expect(getByRole('link', { name: 'View Activity Detail' })).toHaveAttribute(
- 'href',
- 'https://stage.mpdx.org/reports/coaching',
- );
- });
+ it('default', async () => {
+ const { getByTestId, queryByTestId, getByRole } = render(
+
+
+ ,
+ );
+ expect(
+ getByTestId('WeeklyActivityTableCellDateRange').textContent,
+ ).toEqual('Jan 26 - Feb 1');
+ await waitFor(() =>
+ expect(
+ queryByTestId('WeeklyActivitySkeletonLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedCalls').textContent,
+ ).toEqual('1,234');
+ expect(
+ getByTestId('WeeklyActivityTableCellCallsThatProducedAppointments')
+ .textContent,
+ ).toEqual('5,678');
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedMessages').textContent,
+ ).toEqual('9,012');
+ expect(
+ getByTestId('WeeklyActivityTableCellMessagesThatProducedAppointments')
+ .textContent,
+ ).toEqual('3,456');
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedAppointments').textContent,
+ ).toEqual('7,890');
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedCorrespondence')
+ .textContent,
+ ).toEqual('1,234');
+ fireEvent.click(getByTestId('WeeklyActivityIconButtonSubtractWeek'));
+ await waitFor(() =>
+ expect(
+ queryByTestId('WeeklyActivitySkeletonLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(
+ getByTestId('WeeklyActivityTableCellDateRange').textContent,
+ ).toEqual('Jan 19 - Jan 25');
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedCalls').textContent,
+ ).toEqual('5,678');
+ fireEvent.click(getByTestId('WeeklyActivityIconButtonAddWeek'));
+ await waitFor(() =>
+ expect(
+ queryByTestId('WeeklyActivitySkeletonLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(
+ getByTestId('WeeklyActivityTableCellDateRange').textContent,
+ ).toEqual('Jan 26 - Feb 1');
+ expect(
+ getByTestId('WeeklyActivityTableCellCompletedCalls').textContent,
+ ).toEqual('1,234');
+ expect(
+ getByRole('link', { name: 'View Activity Detail' }),
+ ).toHaveAttribute('href', 'https://stage.mpdx.org/reports/coaching');
});
+ });
});
diff --git a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.tsx b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.tsx
index c223c2e000..15ede5502c 100644
--- a/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.tsx
+++ b/src/components/Dashboard/ThisWeek/WeeklyActivity/WeeklyActivity.tsx
@@ -1,17 +1,17 @@
import React, { ReactElement, useState, useEffect } from 'react';
import {
- makeStyles,
- Theme,
- CardHeader,
- CardActions,
- Button,
- IconButton,
- Table,
- TableHead,
- TableRow,
- TableCell,
- TableBody,
- TableContainer,
+ makeStyles,
+ Theme,
+ CardHeader,
+ CardActions,
+ Button,
+ IconButton,
+ Table,
+ TableHead,
+ TableRow,
+ TableCell,
+ TableBody,
+ TableContainer,
} from '@material-ui/core';
import { motion } from 'framer-motion';
import { gql, useQuery } from '@apollo/client';
@@ -26,230 +26,282 @@ import { dayMonthFormat, numberFormat } from '../../../../lib/intlFormat';
import HandoffLink from '../../../HandoffLink';
const useStyles = makeStyles((theme: Theme) => ({
- div: {
- flex: 1,
- display: 'flex',
- flexDirection: 'column',
- overflow: 'auto',
- },
- card: {
- display: 'flex',
- flexDirection: 'column',
- height: '322px',
- [theme.breakpoints.down('xs')]: {
- height: 'auto',
- },
- },
- cardHeader: {
- height: '58px',
- padding: theme.spacing(0, 2),
- },
- cardHeaderAction: {
- alignSelf: 'inherit',
- marginTop: 0,
- },
- tableContainer: {
- flex: 1,
+ div: {
+ flex: 1,
+ display: 'flex',
+ flexDirection: 'column',
+ overflow: 'auto',
+ },
+ card: {
+ display: 'flex',
+ flexDirection: 'column',
+ height: '322px',
+ [theme.breakpoints.down('xs')]: {
+ height: 'auto',
},
+ },
+ cardHeader: {
+ height: '58px',
+ padding: theme.spacing(0, 2),
+ },
+ cardHeaderAction: {
+ alignSelf: 'inherit',
+ marginTop: 0,
+ },
+ tableContainer: {
+ flex: 1,
+ },
}));
export const GET_WEEKLY_ACTIVITY_QUERY = gql`
- query GetWeeklyActivityQuery($accountListId: ID!, $startOfWeek: ISO8601DateTime!, $endOfWeek: ISO8601DateTime!) {
- completedCalls: tasks(
- accountListId: $accountListId
- completedAt: { min: $startOfWeek, max: $endOfWeek }
- activityType: CALL
- result: [COMPLETED, DONE]
- ) {
- totalCount
- }
- callsThatProducedAppointments: tasks(
- accountListId: $accountListId
- completedAt: { min: $startOfWeek, max: $endOfWeek }
- activityType: CALL
- result: [COMPLETED, DONE]
- nextAction: APPOINTMENT
- ) {
- totalCount
- }
- completedMessages: tasks(
- accountListId: $accountListId
- completedAt: { min: $startOfWeek, max: $endOfWeek }
- activityType: [EMAIL, FACEBOOK_MESSAGE, TEXT_MESSAGE]
- result: [COMPLETED, DONE]
- ) {
- totalCount
- }
- messagesThatProducedAppointments: tasks(
- accountListId: $accountListId
- completedAt: { min: $startOfWeek, max: $endOfWeek }
- activityType: [EMAIL, FACEBOOK_MESSAGE, TEXT_MESSAGE]
- result: [COMPLETED, DONE]
- nextAction: APPOINTMENT
- ) {
- totalCount
- }
- completedAppointments: tasks(
- accountListId: $accountListId
- completedAt: { min: $startOfWeek, max: $endOfWeek }
- activityType: APPOINTMENT
- result: [COMPLETED, DONE]
- ) {
- totalCount
- }
- completedCorrespondence: tasks(
- accountListId: $accountListId
- completedAt: { min: $startOfWeek, max: $endOfWeek }
- activityType: [PRE_CALL_LETTER, REMINDER_LETTER, SUPPORT_LETTER, THANK]
- result: [COMPLETED, DONE]
- ) {
- totalCount
- }
+ query GetWeeklyActivityQuery(
+ $accountListId: ID!
+ $startOfWeek: ISO8601DateTime!
+ $endOfWeek: ISO8601DateTime!
+ ) {
+ completedCalls: tasks(
+ accountListId: $accountListId
+ completedAt: { min: $startOfWeek, max: $endOfWeek }
+ activityType: CALL
+ result: [COMPLETED, DONE]
+ ) {
+ totalCount
+ }
+ callsThatProducedAppointments: tasks(
+ accountListId: $accountListId
+ completedAt: { min: $startOfWeek, max: $endOfWeek }
+ activityType: CALL
+ result: [COMPLETED, DONE]
+ nextAction: APPOINTMENT
+ ) {
+ totalCount
+ }
+ completedMessages: tasks(
+ accountListId: $accountListId
+ completedAt: { min: $startOfWeek, max: $endOfWeek }
+ activityType: [EMAIL, FACEBOOK_MESSAGE, TEXT_MESSAGE]
+ result: [COMPLETED, DONE]
+ ) {
+ totalCount
}
+ messagesThatProducedAppointments: tasks(
+ accountListId: $accountListId
+ completedAt: { min: $startOfWeek, max: $endOfWeek }
+ activityType: [EMAIL, FACEBOOK_MESSAGE, TEXT_MESSAGE]
+ result: [COMPLETED, DONE]
+ nextAction: APPOINTMENT
+ ) {
+ totalCount
+ }
+ completedAppointments: tasks(
+ accountListId: $accountListId
+ completedAt: { min: $startOfWeek, max: $endOfWeek }
+ activityType: APPOINTMENT
+ result: [COMPLETED, DONE]
+ ) {
+ totalCount
+ }
+ completedCorrespondence: tasks(
+ accountListId: $accountListId
+ completedAt: { min: $startOfWeek, max: $endOfWeek }
+ activityType: [PRE_CALL_LETTER, REMINDER_LETTER, SUPPORT_LETTER, THANK]
+ result: [COMPLETED, DONE]
+ ) {
+ totalCount
+ }
+ }
`;
interface Props {
- accountListId: string;
+ accountListId: string;
}
const WeeklyActivity = ({ accountListId }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
+ const classes = useStyles();
+ const { t } = useTranslation();
- const [startOfWeek, setStartOfWeek] = useState(moment().startOf('week').toISOString());
- const [endOfWeek, setEndOfWeek] = useState(moment().endOf('week').toISOString());
+ const [startOfWeek, setStartOfWeek] = useState(
+ moment().startOf('week').toISOString(),
+ );
+ const [endOfWeek, setEndOfWeek] = useState(
+ moment().endOf('week').toISOString(),
+ );
- const { data, loading, refetch } = useQuery(GET_WEEKLY_ACTIVITY_QUERY, {
- variables: {
- accountListId,
- startOfWeek,
- endOfWeek,
- },
- });
+ const { data, loading, refetch } = useQuery(
+ GET_WEEKLY_ACTIVITY_QUERY,
+ {
+ variables: {
+ accountListId,
+ startOfWeek,
+ endOfWeek,
+ },
+ },
+ );
- const addWeek = (): void => {
- setStartOfWeek((startOfWeek) => moment(startOfWeek).add(1, 'week').toISOString());
- setEndOfWeek((endOfWeek) => moment(endOfWeek).add(1, 'week').toISOString());
- };
+ const addWeek = (): void => {
+ setStartOfWeek((startOfWeek) =>
+ moment(startOfWeek).add(1, 'week').toISOString(),
+ );
+ setEndOfWeek((endOfWeek) => moment(endOfWeek).add(1, 'week').toISOString());
+ };
- const subtractWeek = (): void => {
- setStartOfWeek((startOfWeek) => moment(startOfWeek).subtract(1, 'week').toISOString());
- setEndOfWeek((endOfWeek) => moment(endOfWeek).subtract(1, 'week').toISOString());
- };
+ const subtractWeek = (): void => {
+ setStartOfWeek((startOfWeek) =>
+ moment(startOfWeek).subtract(1, 'week').toISOString(),
+ );
+ setEndOfWeek((endOfWeek) =>
+ moment(endOfWeek).subtract(1, 'week').toISOString(),
+ );
+ };
- useEffect(() => {
- refetch({
- accountListId,
- startOfWeek,
- endOfWeek,
- });
- }, [startOfWeek, endOfWeek]);
+ useEffect(() => {
+ refetch({
+ accountListId,
+ startOfWeek,
+ endOfWeek,
+ });
+ }, [startOfWeek, endOfWeek]);
- return (
-
-
-
-
-
-
-
-
- >
- }
- classes={{ root: classes.cardHeader, action: classes.cardHeaderAction }}
- />
-
-
-
-
-
-
- {dayMonthFormat(moment(startOfWeek).date(), moment(startOfWeek).month())} -{' '}
- {dayMonthFormat(moment(endOfWeek).date(), moment(endOfWeek).month())}
-
- {t('Completed')}
- {t('Appt Produced')}
-
-
-
-
- {t('Calls')}
-
- {loading ? (
-
- ) : (
- numberFormat(data.completedCalls.totalCount)
- )}
-
-
- {loading ? (
-
- ) : (
- numberFormat(data.callsThatProducedAppointments.totalCount)
- )}
-
-
-
- {t('Messages')}
-
- {loading ? (
-
- ) : (
- numberFormat(data.completedMessages.totalCount)
- )}
-
-
- {loading ? (
-
- ) : (
- numberFormat(data.messagesThatProducedAppointments.totalCount)
- )}
-
-
-
- {t('Appointments')}
-
- {loading ? (
-
- ) : (
- numberFormat(data.completedAppointments.totalCount)
- )}
-
-
-
-
- {t('Correspondence')}
-
- {loading ? (
-
- ) : (
- numberFormat(data.completedCorrespondence.totalCount)
- )}
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+
+
+
+ >
+ }
+ classes={{ root: classes.cardHeader, action: classes.cardHeaderAction }}
+ />
+
+
+
+
+
+
+ {dayMonthFormat(
+ moment(startOfWeek).date(),
+ moment(startOfWeek).month(),
+ )}{' '}
+ -{' '}
+ {dayMonthFormat(
+ moment(endOfWeek).date(),
+ moment(endOfWeek).month(),
+ )}
+
+ {t('Completed')}
+ {t('Appt Produced')}
+
+
+
+
+ {t('Calls')}
+
+ {loading ? (
+
+ ) : (
+ numberFormat(data.completedCalls.totalCount)
+ )}
+
+
+ {loading ? (
+
+ ) : (
+ numberFormat(data.callsThatProducedAppointments.totalCount)
+ )}
+
+
+
+ {t('Messages')}
+
+ {loading ? (
+
+ ) : (
+ numberFormat(data.completedMessages.totalCount)
+ )}
+
+
+ {loading ? (
+
+ ) : (
+ numberFormat(
+ data.messagesThatProducedAppointments.totalCount,
+ )
+ )}
+
+
+
+ {t('Appointments')}
+
+ {loading ? (
+
+ ) : (
+ numberFormat(data.completedAppointments.totalCount)
+ )}
+
+
+
+
+ {t('Correspondence')}
+
+ {loading ? (
+
+ ) : (
+ numberFormat(data.completedCorrespondence.totalCount)
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
};
export default WeeklyActivity;
diff --git a/src/components/Dashboard/Welcome/Welcome.stories.tsx b/src/components/Dashboard/Welcome/Welcome.stories.tsx
index f4ae5a6cc9..43da0a9179 100644
--- a/src/components/Dashboard/Welcome/Welcome.stories.tsx
+++ b/src/components/Dashboard/Welcome/Welcome.stories.tsx
@@ -2,13 +2,13 @@ import React, { ReactElement } from 'react';
import Welcome from '.';
export default {
- title: 'Dashboard/Welcome',
+ title: 'Dashboard/Welcome',
};
export const Default = (): ReactElement => {
- return ;
+ return ;
};
export const Empty = (): ReactElement => {
- return ;
+ return ;
};
diff --git a/src/components/Dashboard/Welcome/Welcome.test.tsx b/src/components/Dashboard/Welcome/Welcome.test.tsx
index 65021efb53..4cc8910bef 100644
--- a/src/components/Dashboard/Welcome/Welcome.test.tsx
+++ b/src/components/Dashboard/Welcome/Welcome.test.tsx
@@ -4,54 +4,66 @@ import { render } from '../../../../__tests__/util/testingLibraryReactMock';
import Welcome from '.';
describe('Welcome', () => {
- afterEach(() => {
- MockDate.reset();
- });
+ afterEach(() => {
+ MockDate.reset();
+ });
- describe('morning', () => {
- beforeEach(() => {
- MockDate.set(new Date(2000, 1, 1, 0));
- });
+ describe('morning', () => {
+ beforeEach(() => {
+ MockDate.set(new Date(2000, 1, 1, 0));
+ });
- it('default', () => {
- const { getByTestId } = render();
- expect(getByTestId('PageHeadingHeading').textContent).toEqual('Good Morning,');
- });
+ it('default', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('PageHeadingHeading').textContent).toEqual(
+ 'Good Morning,',
+ );
+ });
- it('props', () => {
- const { getByTestId } = render();
- expect(getByTestId('PageHeadingHeading').textContent).toEqual('Good Morning, John.');
- });
+ it('props', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('PageHeadingHeading').textContent).toEqual(
+ 'Good Morning, John.',
+ );
+ });
+ });
+ describe('afternoon', () => {
+ beforeEach(() => {
+ MockDate.set(new Date(2000, 1, 1, 12));
});
- describe('afternoon', () => {
- beforeEach(() => {
- MockDate.set(new Date(2000, 1, 1, 12));
- });
- it('default', () => {
- const { getByTestId } = render();
- expect(getByTestId('PageHeadingHeading').textContent).toEqual('Good Afternoon,');
- });
+ it('default', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('PageHeadingHeading').textContent).toEqual(
+ 'Good Afternoon,',
+ );
+ });
- it('props', () => {
- const { getByTestId } = render();
- expect(getByTestId('PageHeadingHeading').textContent).toEqual('Good Afternoon, John.');
- });
+ it('props', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('PageHeadingHeading').textContent).toEqual(
+ 'Good Afternoon, John.',
+ );
});
+ });
- describe('evening', () => {
- beforeEach(() => {
- MockDate.set(new Date(2000, 1, 1, 18));
- });
+ describe('evening', () => {
+ beforeEach(() => {
+ MockDate.set(new Date(2000, 1, 1, 18));
+ });
- it('default', () => {
- const { getByTestId } = render();
- expect(getByTestId('PageHeadingHeading').textContent).toEqual('Good Evening,');
- });
+ it('default', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('PageHeadingHeading').textContent).toEqual(
+ 'Good Evening,',
+ );
+ });
- it('props', () => {
- const { getByTestId } = render();
- expect(getByTestId('PageHeadingHeading').textContent).toEqual('Good Evening, John.');
- });
+ it('props', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('PageHeadingHeading').textContent).toEqual(
+ 'Good Evening, John.',
+ );
});
+ });
});
diff --git a/src/components/Dashboard/Welcome/Welcome.tsx b/src/components/Dashboard/Welcome/Welcome.tsx
index 44eec427a0..b2535042d7 100644
--- a/src/components/Dashboard/Welcome/Welcome.tsx
+++ b/src/components/Dashboard/Welcome/Welcome.tsx
@@ -4,29 +4,35 @@ import PageHeading from '../../PageHeading';
import illustration9 from '../../../images/drawkit/grape/drawkit-grape-pack-illustration-9.svg';
interface Props {
- firstName?: string;
+ firstName?: string;
}
const Welcome = ({ firstName }: Props): ReactElement => {
- const { t } = useTranslation();
- const today = new Date();
- const currentHour = today.getHours();
+ const { t } = useTranslation();
+ const today = new Date();
+ const currentHour = today.getHours();
- let greeting = firstName ? t('Good Evening, {{ firstName }}.', { firstName }) : t('Good Evening,');
+ let greeting = firstName
+ ? t('Good Evening, {{ firstName }}.', { firstName })
+ : t('Good Evening,');
- if (currentHour < 12) {
- greeting = firstName ? t('Good Morning, {{ firstName }}.', { firstName }) : t('Good Morning,');
- } else if (currentHour < 18) {
- greeting = firstName ? t('Good Afternoon, {{ firstName }}.', { firstName }) : t('Good Afternoon,');
- }
+ if (currentHour < 12) {
+ greeting = firstName
+ ? t('Good Morning, {{ firstName }}.', { firstName })
+ : t('Good Morning,');
+ } else if (currentHour < 18) {
+ greeting = firstName
+ ? t('Good Afternoon, {{ firstName }}.', { firstName })
+ : t('Good Afternoon,');
+ }
- return (
-
- );
+ return (
+
+ );
};
export default Welcome;
diff --git a/src/components/Footer/Footer.stories.tsx b/src/components/Footer/Footer.stories.tsx
index de8051cc58..769462ad9d 100644
--- a/src/components/Footer/Footer.stories.tsx
+++ b/src/components/Footer/Footer.stories.tsx
@@ -2,7 +2,7 @@ import React, { ReactElement } from 'react';
import Footer from '.';
export default {
- title: 'Footer',
+ title: 'Footer',
};
export const Default = (): ReactElement => ;
diff --git a/src/components/Footer/Footer.test.tsx b/src/components/Footer/Footer.test.tsx
index a41ee9cab7..963207b100 100644
--- a/src/components/Footer/Footer.test.tsx
+++ b/src/components/Footer/Footer.test.tsx
@@ -4,33 +4,44 @@ import { render } from '../../../__tests__/util/testingLibraryReactMock';
import Footer from '.';
describe('Footer', () => {
- it('contains privacy link', () => {
- const { getByTestId } = render();
- expect(getByTestId('privacy')).toHaveAttribute('href', 'https://get.mpdx.org/privacy-policy/');
- });
+ it('contains privacy link', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('privacy')).toHaveAttribute(
+ 'href',
+ 'https://get.mpdx.org/privacy-policy/',
+ );
+ });
- it('contains whats-new link', () => {
- const { getByTestId } = render();
- expect(getByTestId('whats-new')).toHaveAttribute('href', 'https://get.mpdx.org/release-notes/');
- });
+ it('contains whats-new link', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('whats-new')).toHaveAttribute(
+ 'href',
+ 'https://get.mpdx.org/release-notes/',
+ );
+ });
- it('contains terms-of-use link', () => {
- const { getByTestId } = render();
- expect(getByTestId('terms-of-use')).toHaveAttribute('href', 'https://get.mpdx.org/terms-of-use/');
- });
+ it('contains terms-of-use link', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('terms-of-use')).toHaveAttribute(
+ 'href',
+ 'https://get.mpdx.org/terms-of-use/',
+ );
+ });
- describe('mocked Date', () => {
- beforeEach(() => {
- MockDate.set('2000-11-22');
- });
+ describe('mocked Date', () => {
+ beforeEach(() => {
+ MockDate.set('2000-11-22');
+ });
- afterEach(() => {
- MockDate.reset();
- });
+ afterEach(() => {
+ MockDate.reset();
+ });
- it('has correct text', () => {
- const { getByTestId } = render();
- expect(getByTestId('copyright').textContent).toEqual('© 2000, Cru. All Rights Reserved.');
- });
+ it('has correct text', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('copyright').textContent).toEqual(
+ '© 2000, Cru. All Rights Reserved.',
+ );
});
+ });
});
diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx
index f2cbe0a0af..ae2c2b15f9 100644
--- a/src/components/Footer/Footer.tsx
+++ b/src/components/Footer/Footer.tsx
@@ -5,77 +5,81 @@ import { useTranslation } from 'react-i18next';
import logo from '../../images/logo.svg';
const useStyles = makeStyles((theme: Theme) =>
- createStyles({
- box: {
- backgroundColor: '#323232',
- },
- link: {
- color: '#fff',
- },
- copyright: {
- textAlign: 'right',
- color: '#fff',
- [theme.breakpoints.down('sm')]: {
- paddingTop: theme.spacing(3),
- textAlign: 'left',
- },
- },
- logo: {
- marginTop: '5px',
- },
- }),
+ createStyles({
+ box: {
+ backgroundColor: '#323232',
+ },
+ link: {
+ color: '#fff',
+ },
+ copyright: {
+ textAlign: 'right',
+ color: '#fff',
+ [theme.breakpoints.down('sm')]: {
+ paddingTop: theme.spacing(3),
+ textAlign: 'left',
+ },
+ },
+ logo: {
+ marginTop: '5px',
+ },
+ }),
);
const Footer = (): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const year = new Date().getFullYear();
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const year = new Date().getFullYear();
- return (
-
-
-
-
-
-
-
-
-
- {t('Privacy Policy')}
-
-
-
-
- {t("What's New")}
-
-
-
-
- {t('Terms of Use')}
-
-
-
-
-
- {t('© {{ year }}, Cru. All Rights Reserved.', { year })}
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+
+
+
+
+ {t('Privacy Policy')}
+
+
+
+
+ {t("What's New")}
+
+
+
+
+ {t('Terms of Use')}
+
+
+
+
+
+ {t('© {{ year }}, Cru. All Rights Reserved.', { year })}
+
+
+
+
+
+ );
};
export default Footer;
diff --git a/src/components/HandoffLink/HandoffLink.test.tsx b/src/components/HandoffLink/HandoffLink.test.tsx
index 9771b70e07..7473af44de 100644
--- a/src/components/HandoffLink/HandoffLink.test.tsx
+++ b/src/components/HandoffLink/HandoffLink.test.tsx
@@ -5,106 +5,124 @@ import TestWrapper from '../../../__tests__/util/TestWrapper';
import HandoffLink from '.';
describe('HandoffLink', () => {
- let open: jest.Mock;
- let originalOpen: Window['open'];
+ let open: jest.Mock;
+ let originalOpen: Window['open'];
- beforeEach(() => {
- open = jest.fn();
- originalOpen = window.open;
- window.open = open;
- });
+ beforeEach(() => {
+ open = jest.fn();
+ originalOpen = window.open;
+ window.open = open;
+ });
- afterEach(() => {
- window.open = originalOpen;
- });
+ afterEach(() => {
+ window.open = originalOpen;
+ });
- it('default', async () => {
- const { getByRole } = render(
-
-
- Link
-
- ,
- );
- const linkElement = getByRole('link', { name: 'Link' });
- expect(linkElement).toHaveAttribute('href', 'https://stage.mpdx.org/contacts');
- userEvent.click(linkElement);
- expect(open).toHaveBeenCalledWith(
- 'http://localhost/api/handoff?accountListId=accountListId&userId=userId&path=%2Fcontacts',
- '_blank',
- );
- });
+ it('default', async () => {
+ const { getByRole } = render(
+
+
+ Link
+
+ ,
+ );
+ const linkElement = getByRole('link', { name: 'Link' });
+ expect(linkElement).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts',
+ );
+ userEvent.click(linkElement);
+ expect(open).toHaveBeenCalledWith(
+ 'http://localhost/api/handoff?accountListId=accountListId&userId=userId&path=%2Fcontacts',
+ '_blank',
+ );
+ });
- it('default auth', async () => {
- const { getByRole } = render(
-
- Link
- ,
- );
- const linkElement = getByRole('link', { name: 'Link' });
- expect(linkElement).toHaveAttribute('href', 'https://auth.stage.mpdx.org/contacts');
- userEvent.click(linkElement);
- expect(open).toHaveBeenCalledWith('http://localhost/api/handoff?auth=true&path=%2Fcontacts', '_blank');
- });
+ it('default auth', async () => {
+ const { getByRole } = render(
+
+ Link
+ ,
+ );
+ const linkElement = getByRole('link', { name: 'Link' });
+ expect(linkElement).toHaveAttribute(
+ 'href',
+ 'https://auth.stage.mpdx.org/contacts',
+ );
+ userEvent.click(linkElement);
+ expect(open).toHaveBeenCalledWith(
+ 'http://localhost/api/handoff?auth=true&path=%2Fcontacts',
+ '_blank',
+ );
+ });
- it('onClick defaultPrevented', async () => {
- const handleClick = jest.fn((e) => e.preventDefault());
- const { getByRole } = render(
-
- Link
- ,
- );
- const linkElement = getByRole('link', { name: 'Link' });
- expect(linkElement).toHaveAttribute('href', 'https://stage.mpdx.org/contacts');
- userEvent.click(linkElement);
- expect(handleClick).toHaveBeenCalled();
- expect(open).not.toHaveBeenCalled();
- });
+ it('onClick defaultPrevented', async () => {
+ const handleClick = jest.fn((e) => e.preventDefault());
+ const { getByRole } = render(
+
+ Link
+ ,
+ );
+ const linkElement = getByRole('link', { name: 'Link' });
+ expect(linkElement).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/contacts',
+ );
+ userEvent.click(linkElement);
+ expect(handleClick).toHaveBeenCalled();
+ expect(open).not.toHaveBeenCalled();
+ });
- it('enforces single child', async () => {
- expect(() =>
- render(
-
- Link
- Link
- ,
- ),
- ).toThrowError();
- });
+ it('enforces single child', async () => {
+ expect(() =>
+ render(
+
+ Link
+ Link
+ ,
+ ),
+ ).toThrowError();
+ });
- describe('SITE_URL set', () => {
- const OLD_ENV = process.env;
+ describe('SITE_URL set', () => {
+ const OLD_ENV = process.env;
- beforeEach(() => {
- jest.resetModules();
- process.env = { ...OLD_ENV, SITE_URL: 'https://next.mpdx.org' };
- });
+ beforeEach(() => {
+ jest.resetModules();
+ process.env = { ...OLD_ENV, SITE_URL: 'https://next.mpdx.org' };
+ });
- afterAll(() => {
- process.env = OLD_ENV;
- });
+ afterAll(() => {
+ process.env = OLD_ENV;
+ });
- it('changes base URL', () => {
- const { getByRole } = render(
-
- Link
- ,
- );
- expect(getByRole('link', { name: 'Link' })).toHaveAttribute('href', 'https://mpdx.org/contacts');
- });
+ it('changes base URL', () => {
+ const { getByRole } = render(
+
+ Link
+ ,
+ );
+ expect(getByRole('link', { name: 'Link' })).toHaveAttribute(
+ 'href',
+ 'https://mpdx.org/contacts',
+ );
+ });
- it('default auth', async () => {
- const { getByRole } = render(
-
- Link
- ,
- );
- expect(getByRole('link', { name: 'Link' })).toHaveAttribute('href', 'https://auth.mpdx.org/contacts');
- });
+ it('default auth', async () => {
+ const { getByRole } = render(
+
+ Link
+ ,
+ );
+ expect(getByRole('link', { name: 'Link' })).toHaveAttribute(
+ 'href',
+ 'https://auth.mpdx.org/contacts',
+ );
});
+ });
});
diff --git a/src/components/HandoffLink/HandoffLink.tsx b/src/components/HandoffLink/HandoffLink.tsx
index 438ca3fab3..1034007bcd 100644
--- a/src/components/HandoffLink/HandoffLink.tsx
+++ b/src/components/HandoffLink/HandoffLink.tsx
@@ -2,43 +2,45 @@ import { ReactElement, ReactNode, Children, cloneElement } from 'react';
import { useApp } from '../App';
interface Props {
- path: string;
- auth?: boolean;
- children: ReactNode;
+ path: string;
+ auth?: boolean;
+ children: ReactNode;
}
const HandoffLink = ({ path, auth, children }: Props): ReactElement => {
- const app = useApp();
-
- const url = new URL(`${process.env.SITE_URL || window.location.origin}/api/handoff`);
-
- if (auth) {
- url.searchParams.append('auth', 'true');
- } else {
- url.searchParams.append('accountListId', app?.state?.accountListId);
- url.searchParams.append('userId', app?.state?.user?.id);
- }
- url.searchParams.append('path', path);
-
- const child = Children.only(children) as ReactElement;
-
- const childProps = {
- href: `https://${auth ? 'auth.' : ''}${
- process.env.SITE_URL === 'https://next.mpdx.org' ? '' : 'stage.'
- }mpdx.org${path}`,
- target: '_blank',
- onClick: (e: React.MouseEvent) => {
- if (child.props && typeof child.props.onClick === 'function') {
- child.props.onClick(e);
- }
- if (!e.defaultPrevented) {
- window.open(url.href, '_blank');
- e.preventDefault();
- }
- },
- };
-
- return cloneElement(child, childProps);
+ const app = useApp();
+
+ const url = new URL(
+ `${process.env.SITE_URL || window.location.origin}/api/handoff`,
+ );
+
+ if (auth) {
+ url.searchParams.append('auth', 'true');
+ } else {
+ url.searchParams.append('accountListId', app?.state?.accountListId);
+ url.searchParams.append('userId', app?.state?.user?.id);
+ }
+ url.searchParams.append('path', path);
+
+ const child = Children.only(children) as ReactElement;
+
+ const childProps = {
+ href: `https://${auth ? 'auth.' : ''}${
+ process.env.SITE_URL === 'https://next.mpdx.org' ? '' : 'stage.'
+ }mpdx.org${path}`,
+ target: '_blank',
+ onClick: (e: React.MouseEvent) => {
+ if (child.props && typeof child.props.onClick === 'function') {
+ child.props.onClick(e);
+ }
+ if (!e.defaultPrevented) {
+ window.open(url.href, '_blank');
+ e.preventDefault();
+ }
+ },
+ };
+
+ return cloneElement(child, childProps);
};
export default HandoffLink;
diff --git a/src/components/InfoBlock/InfoBlock.stories.tsx b/src/components/InfoBlock/InfoBlock.stories.tsx
index 681fc67cc4..d6c25d1f32 100644
--- a/src/components/InfoBlock/InfoBlock.stories.tsx
+++ b/src/components/InfoBlock/InfoBlock.stories.tsx
@@ -3,13 +3,13 @@ import { Box } from '@material-ui/core';
import InfoBlock from '.';
export default {
- title: 'InfoBlock',
+ title: 'InfoBlock',
};
export const Default = (): ReactElement => {
- return (
-
- Hello World
-
- );
+ return (
+
+ Hello World
+
+ );
};
diff --git a/src/components/InfoBlock/InfoBlock.test.tsx b/src/components/InfoBlock/InfoBlock.test.tsx
index e3abbc9372..acef96b787 100644
--- a/src/components/InfoBlock/InfoBlock.test.tsx
+++ b/src/components/InfoBlock/InfoBlock.test.tsx
@@ -3,25 +3,25 @@ import { render } from '@testing-library/react';
import InfoBlock from '.';
describe('InfoBlock', () => {
- it('has correct defaults', () => {
- const { getByTestId, getByText } = render(
-
-
- ,
- );
- const element = getByTestId('children');
- expect(element).toBeInTheDocument();
- expect(element.parentElement.tagName).toEqual('P');
- expect(getByText('Hello World')).toBeInTheDocument();
- });
+ it('has correct defaults', () => {
+ const { getByTestId, getByText } = render(
+
+
+ ,
+ );
+ const element = getByTestId('children');
+ expect(element).toBeInTheDocument();
+ expect(element.parentElement.tagName).toEqual('P');
+ expect(getByText('Hello World')).toBeInTheDocument();
+ });
- it('has correct overrides', () => {
- const { getByTestId } = render(
-
-
- ,
- );
- const element = getByTestId('children');
- expect(element.parentElement.tagName).toEqual('DIV');
- });
+ it('has correct overrides', () => {
+ const { getByTestId } = render(
+
+
+ ,
+ );
+ const element = getByTestId('children');
+ expect(element.parentElement.tagName).toEqual('DIV');
+ });
});
diff --git a/src/components/InfoBlock/InfoBlock.tsx b/src/components/InfoBlock/InfoBlock.tsx
index 91c7631d34..6369b70cff 100644
--- a/src/components/InfoBlock/InfoBlock.tsx
+++ b/src/components/InfoBlock/InfoBlock.tsx
@@ -2,29 +2,37 @@ import React, { ReactElement, ReactNode } from 'react';
import { Typography, makeStyles, Theme } from '@material-ui/core';
const useStyles = makeStyles((_theme: Theme) => ({
- title: {
- textTransform: 'uppercase',
- fontSize: '0.8rem',
- },
+ title: {
+ textTransform: 'uppercase',
+ fontSize: '0.8rem',
+ },
}));
interface Props {
- title: string;
- children: ReactNode;
- disableChildrenTypography?: boolean;
+ title: string;
+ children: ReactNode;
+ disableChildrenTypography?: boolean;
}
-const InfoBlock = ({ title, children, disableChildrenTypography }: Props): ReactElement => {
- const classes = useStyles();
+const InfoBlock = ({
+ title,
+ children,
+ disableChildrenTypography,
+}: Props): ReactElement => {
+ const classes = useStyles();
- return (
- <>
-
- {title}
-
- {disableChildrenTypography ? children : {children}}
- >
- );
+ return (
+ <>
+
+ {title}
+
+ {disableChildrenTypography ? (
+ children
+ ) : (
+ {children}
+ )}
+ >
+ );
};
export default InfoBlock;
diff --git a/src/components/Layouts/Basic/Basic.stories.tsx b/src/components/Layouts/Basic/Basic.stories.tsx
index ee424ec66c..1e4724997f 100644
--- a/src/components/Layouts/Basic/Basic.stories.tsx
+++ b/src/components/Layouts/Basic/Basic.stories.tsx
@@ -3,15 +3,15 @@ import { Container, Box } from '@material-ui/core';
import Basic from '.';
export default {
- title: 'Layouts/Basic',
+ title: 'Layouts/Basic',
};
export const Default = (): ReactElement => {
- return (
-
-
- Basic Layout
-
-
- );
+ return (
+
+
+ Basic Layout
+
+
+ );
};
diff --git a/src/components/Layouts/Basic/Basic.test.tsx b/src/components/Layouts/Basic/Basic.test.tsx
index 8c49ca753d..02f7883d23 100644
--- a/src/components/Layouts/Basic/Basic.test.tsx
+++ b/src/components/Layouts/Basic/Basic.test.tsx
@@ -3,12 +3,12 @@ import { render } from '@testing-library/react';
import Basic from '.';
describe('Basic', () => {
- it('has correct defaults', () => {
- const { getByTestId } = render(
-
-
- ,
- );
- expect(getByTestId('PrimaryTestChildren')).toBeInTheDocument();
- });
+ it('has correct defaults', () => {
+ const { getByTestId } = render(
+
+
+ ,
+ );
+ expect(getByTestId('PrimaryTestChildren')).toBeInTheDocument();
+ });
});
diff --git a/src/components/Layouts/Basic/Basic.tsx b/src/components/Layouts/Basic/Basic.tsx
index 7a3aab0ff1..126581ea94 100644
--- a/src/components/Layouts/Basic/Basic.tsx
+++ b/src/components/Layouts/Basic/Basic.tsx
@@ -3,18 +3,18 @@ import logo from '../../../images/logo.svg';
import TopBar from './TopBar';
interface Props {
- children: ReactNode;
+ children: ReactNode;
}
const Basic = ({ children }: Props): ReactElement => {
- return (
- <>
-
-
-
- {children}
- >
- );
+ return (
+ <>
+
+
+
+ {children}
+ >
+ );
};
export default Basic;
diff --git a/src/components/Layouts/Basic/TopBar/TopBar.stories.tsx b/src/components/Layouts/Basic/TopBar/TopBar.stories.tsx
index e104008656..ed445e3477 100644
--- a/src/components/Layouts/Basic/TopBar/TopBar.stories.tsx
+++ b/src/components/Layouts/Basic/TopBar/TopBar.stories.tsx
@@ -3,32 +3,32 @@ import { Box, Container } from '@material-ui/core';
import TopBar from '.';
export default {
- title: 'Layouts/Basic/TopBar',
+ title: 'Layouts/Basic/TopBar',
};
const Content = (): ReactElement => (
- <>
-
-
-
- {[...new Array(50)]
- .map(
- () => `Cras mattis consectetur purus sit amet fermentum.
+ <>
+
+
+
+ {[...new Array(50)]
+ .map(
+ () => `Cras mattis consectetur purus sit amet fermentum.
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`,
- )
- .join('\n')}
-
-
- >
+ )
+ .join('\n')}
+
+
+ >
);
export const Default = (): ReactElement => {
- return (
- <>
-
-
- >
- );
+ return (
+ <>
+
+
+ >
+ );
};
diff --git a/src/components/Layouts/Basic/TopBar/TopBar.test.tsx b/src/components/Layouts/Basic/TopBar/TopBar.test.tsx
index ab94c0bd16..475ab3e455 100644
--- a/src/components/Layouts/Basic/TopBar/TopBar.test.tsx
+++ b/src/components/Layouts/Basic/TopBar/TopBar.test.tsx
@@ -4,14 +4,14 @@ import TestRouter from '../../../../../__tests__/util/TestRouter';
import TopBar from '.';
describe('TopBar', () => {
- it('has correct defaults', () => {
- const { getByTestId } = render(
-
-
-
-
- ,
- );
- expect(getByTestId('PrimaryTestChildren')).toBeInTheDocument();
- });
+ it('has correct defaults', () => {
+ const { getByTestId } = render(
+
+
+
+
+ ,
+ );
+ expect(getByTestId('PrimaryTestChildren')).toBeInTheDocument();
+ });
});
diff --git a/src/components/Layouts/Basic/TopBar/TopBar.tsx b/src/components/Layouts/Basic/TopBar/TopBar.tsx
index 4919158017..5da09ead89 100644
--- a/src/components/Layouts/Basic/TopBar/TopBar.tsx
+++ b/src/components/Layouts/Basic/TopBar/TopBar.tsx
@@ -1,49 +1,56 @@
import React, { ReactElement, ReactNode } from 'react';
-import { makeStyles, Toolbar, AppBar, useScrollTrigger, Theme, Grid } from '@material-ui/core';
+import {
+ makeStyles,
+ Toolbar,
+ AppBar,
+ useScrollTrigger,
+ Theme,
+ Grid,
+} from '@material-ui/core';
const useStyles = makeStyles((theme: Theme) => ({
- appBar: {
- paddingTop: `env(safe-area-inset-top)`,
- paddingLeft: `env(safe-area-inset-left)`,
- paddingRight: `env(safe-area-inset-right)`,
- backgroundColor: theme.palette.primary.main,
- },
- toolbar: {
- backgroundColor: theme.palette.primary.main,
- },
- container: {
- minHeight: '48px',
- },
+ appBar: {
+ paddingTop: `env(safe-area-inset-top)`,
+ paddingLeft: `env(safe-area-inset-left)`,
+ paddingRight: `env(safe-area-inset-right)`,
+ backgroundColor: theme.palette.primary.main,
+ },
+ toolbar: {
+ backgroundColor: theme.palette.primary.main,
+ },
+ container: {
+ minHeight: '48px',
+ },
}));
interface Props {
- children?: ReactNode;
+ children?: ReactNode;
}
const TopBar = ({ children }: Props): ReactElement => {
- const classes = useStyles();
+ const classes = useStyles();
- const trigger = useScrollTrigger({
- disableHysteresis: true,
- threshold: 0,
- });
+ const trigger = useScrollTrigger({
+ disableHysteresis: true,
+ threshold: 0,
+ });
- return (
- <>
-
-
-
- {children}
-
-
-
-
-
-
-
-
- >
- );
+ return (
+ <>
+
+
+
+ {children}
+
+
+
+
+
+
+
+
+ >
+ );
};
export default TopBar;
diff --git a/src/components/Layouts/Primary/AddFab/AddFab.stories.tsx b/src/components/Layouts/Primary/AddFab/AddFab.stories.tsx
index 4543caa396..f519ab4389 100644
--- a/src/components/Layouts/Primary/AddFab/AddFab.stories.tsx
+++ b/src/components/Layouts/Primary/AddFab/AddFab.stories.tsx
@@ -1,21 +1,29 @@
import React, { ReactElement } from 'react';
import { MockedProvider } from '@apollo/client/testing';
-import { getDataForTaskDrawerMock, createTaskMutationMock } from '../../../Task/Drawer/Form/Form.mock';
+import {
+ getDataForTaskDrawerMock,
+ createTaskMutationMock,
+} from '../../../Task/Drawer/Form/Form.mock';
import withDispatch from '../../../../decorators/withDispatch';
import AddFab from '.';
export default {
- title: 'Layouts/Primary/AddFab',
- decorators: [withDispatch({ type: 'updateAccountListId', accountListId: 'abc' })],
+ title: 'Layouts/Primary/AddFab',
+ decorators: [
+ withDispatch({ type: 'updateAccountListId', accountListId: 'abc' }),
+ ],
};
export const Default = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Layouts/Primary/AddFab/AddFab.test.tsx b/src/components/Layouts/Primary/AddFab/AddFab.test.tsx
index 85c5a2a4db..77fd3fcf8b 100644
--- a/src/components/Layouts/Primary/AddFab/AddFab.test.tsx
+++ b/src/components/Layouts/Primary/AddFab/AddFab.test.tsx
@@ -5,36 +5,39 @@ import { SnackbarProvider } from 'notistack';
import { MuiPickersUtilsProvider } from '@material-ui/pickers';
import DateFnsUtils from '@date-io/date-fns';
import userEvent from '@testing-library/user-event';
-import { getDataForTaskDrawerMock, createTaskMutationMock } from '../../../Task/Drawer/Form/Form.mock';
+import {
+ getDataForTaskDrawerMock,
+ createTaskMutationMock,
+} from '../../../Task/Drawer/Form/Form.mock';
import { useApp } from '../../../App';
import AddFab from '.';
jest.mock('../../../App', () => ({
- useApp: jest.fn(),
+ useApp: jest.fn(),
}));
const openTaskDrawer = jest.fn();
beforeEach(() => {
- (useApp as jest.Mock).mockReturnValue({
- openTaskDrawer,
- });
+ (useApp as jest.Mock).mockReturnValue({
+ openTaskDrawer,
+ });
});
describe('AddFab', () => {
- it('default', async () => {
- const mocks = [getDataForTaskDrawerMock(), createTaskMutationMock()];
- const { getByRole } = render(
-
-
-
-
-
-
- ,
- );
- userEvent.click(getByRole('button', { name: 'Add' }));
- userEvent.click(getByRole('menuitem'));
- expect(openTaskDrawer).toHaveBeenCalledWith({});
- });
+ it('default', async () => {
+ const mocks = [getDataForTaskDrawerMock(), createTaskMutationMock()];
+ const { getByRole } = render(
+
+
+
+
+
+
+ ,
+ );
+ userEvent.click(getByRole('button', { name: 'Add' }));
+ userEvent.click(getByRole('menuitem'));
+ expect(openTaskDrawer).toHaveBeenCalledWith({});
+ });
});
diff --git a/src/components/Layouts/Primary/AddFab/AddFab.tsx b/src/components/Layouts/Primary/AddFab/AddFab.tsx
index 7737954592..c7d9f1a3eb 100644
--- a/src/components/Layouts/Primary/AddFab/AddFab.tsx
+++ b/src/components/Layouts/Primary/AddFab/AddFab.tsx
@@ -6,49 +6,54 @@ import { useTranslation } from 'react-i18next';
import { useApp } from '../../../App';
const useStyles = makeStyles((theme: Theme) =>
- createStyles({
- speedDial: {
- position: 'fixed',
- bottom: theme.spacing(3),
- right: theme.spacing(3),
- },
- }),
+ createStyles({
+ speedDial: {
+ position: 'fixed',
+ bottom: theme.spacing(3),
+ right: theme.spacing(3),
+ },
+ }),
);
const AddFab = (): ReactElement => {
- const classes = useStyles();
- const [open, setOpen] = useState(false);
- const { t } = useTranslation();
- const { openTaskDrawer } = useApp();
+ const classes = useStyles();
+ const [open, setOpen] = useState(false);
+ const { t } = useTranslation();
+ const { openTaskDrawer } = useApp();
- const handleClose = (): void => {
- setOpen(false);
- };
+ const handleClose = (): void => {
+ setOpen(false);
+ };
- const handleOpen = (): void => {
- setOpen(true);
- };
+ const handleOpen = (): void => {
+ setOpen(true);
+ };
- const onTaskClick = (): void => {
- openTaskDrawer({});
- handleClose();
- };
+ const onTaskClick = (): void => {
+ openTaskDrawer({});
+ handleClose();
+ };
- return (
- <>
- }
- onClose={handleClose}
- onOpen={handleOpen}
- open={open}
- direction="up"
- >
- } tooltipTitle={t('Task')} onClick={onTaskClick} tooltipOpen />
-
- >
- );
+ return (
+ <>
+ }
+ onClose={handleClose}
+ onOpen={handleOpen}
+ open={open}
+ direction="up"
+ >
+ }
+ tooltipTitle={t('Task')}
+ onClick={onTaskClick}
+ tooltipOpen
+ />
+
+ >
+ );
};
export default AddFab;
diff --git a/src/components/Layouts/Primary/BottomBar/BottomBar.stories.tsx b/src/components/Layouts/Primary/BottomBar/BottomBar.stories.tsx
index 61e74e5318..df516f8fb4 100644
--- a/src/components/Layouts/Primary/BottomBar/BottomBar.stories.tsx
+++ b/src/components/Layouts/Primary/BottomBar/BottomBar.stories.tsx
@@ -3,31 +3,31 @@ import { Box, Container } from '@material-ui/core';
import BottomBar from '.';
export default {
- title: 'Layouts/Primary/BottomBar',
+ title: 'Layouts/Primary/BottomBar',
};
const Content = (): ReactElement => (
-
-
-
- {[...new Array(50)]
- .map(
- () => `Cras mattis consectetur purus sit amet fermentum.
+
+
+
+ {[...new Array(50)]
+ .map(
+ () => `Cras mattis consectetur purus sit amet fermentum.
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`,
- )
- .join('\n')}
-
-
-
+ )
+ .join('\n')}
+
+
+
);
export const Default = (): ReactElement => {
- return (
- <>
-
-
- >
- );
+ return (
+ <>
+
+
+ >
+ );
};
diff --git a/src/components/Layouts/Primary/BottomBar/BottomBar.test.tsx b/src/components/Layouts/Primary/BottomBar/BottomBar.test.tsx
index f732618362..0485533264 100644
--- a/src/components/Layouts/Primary/BottomBar/BottomBar.test.tsx
+++ b/src/components/Layouts/Primary/BottomBar/BottomBar.test.tsx
@@ -3,8 +3,8 @@ import { render } from '@testing-library/react';
import BottomBar from '.';
describe('BottomBar', () => {
- it('has correct defaults', () => {
- const { getByTestId } = render();
- expect(getByTestId('BottomBarOverview')).toBeInTheDocument();
- });
+ it('has correct defaults', () => {
+ const { getByTestId } = render();
+ expect(getByTestId('BottomBarOverview')).toBeInTheDocument();
+ });
});
diff --git a/src/components/Layouts/Primary/BottomBar/BottomBar.tsx b/src/components/Layouts/Primary/BottomBar/BottomBar.tsx
index c5d7075ad4..ebd5b721a1 100644
--- a/src/components/Layouts/Primary/BottomBar/BottomBar.tsx
+++ b/src/components/Layouts/Primary/BottomBar/BottomBar.tsx
@@ -1,43 +1,60 @@
import React, { ReactElement, useState } from 'react';
-import { makeStyles, BottomNavigation, BottomNavigationAction, Theme } from '@material-ui/core';
+import {
+ makeStyles,
+ BottomNavigation,
+ BottomNavigationAction,
+ Theme,
+} from '@material-ui/core';
import HomeIcon from '@material-ui/icons/Home';
import { useTranslation } from 'react-i18next';
const useStyles = makeStyles((_theme: Theme) => ({
- bottomNavigation: {
- width: '100%',
- paddingBottom: `env(safe-area-inset-bottom)`,
- boxSizing: 'content-box',
- },
- bottomNavigationBlock: {
- backgroundColor: '#f6f7f9',
- },
- bottomNavigationFixed: {
- position: 'fixed',
- bottom: 0,
- },
+ bottomNavigation: {
+ width: '100%',
+ paddingBottom: `env(safe-area-inset-bottom)`,
+ boxSizing: 'content-box',
+ },
+ bottomNavigationBlock: {
+ backgroundColor: '#f6f7f9',
+ },
+ bottomNavigationFixed: {
+ position: 'fixed',
+ bottom: 0,
+ },
}));
const BottomBar = (): ReactElement => {
- const classes = useStyles();
- const [value, setValue] = useState(0);
- const { t } = useTranslation();
+ const classes = useStyles();
+ const [value, setValue] = useState(0);
+ const { t } = useTranslation();
- return (
- <>
-
- {
- setValue(newValue);
- }}
- showLabels
- className={[classes.bottomNavigation, classes.bottomNavigationFixed].join(' ')}
- >
- } data-testid="BottomBarOverview" />
-
- >
- );
+ return (
+ <>
+
+ {
+ setValue(newValue);
+ }}
+ showLabels
+ className={[
+ classes.bottomNavigation,
+ classes.bottomNavigationFixed,
+ ].join(' ')}
+ >
+ }
+ data-testid="BottomBarOverview"
+ />
+
+ >
+ );
};
export default BottomBar;
diff --git a/src/components/Layouts/Primary/Primary.stories.tsx b/src/components/Layouts/Primary/Primary.stories.tsx
index a1ff36d987..937d0a9bcf 100644
--- a/src/components/Layouts/Primary/Primary.stories.tsx
+++ b/src/components/Layouts/Primary/Primary.stories.tsx
@@ -8,34 +8,34 @@ import { getTopBarMock } from './TopBar/TopBar.mock';
import Primary from '.';
export default {
- title: 'Layouts/Primary',
- decorators: [
- withDispatch(
- { type: 'updateAccountListId', accountListId: '1' },
- { type: 'updateBreadcrumb', breadcrumb: 'Dashboard' },
- ),
- ],
+ title: 'Layouts/Primary',
+ decorators: [
+ withDispatch(
+ { type: 'updateAccountListId', accountListId: '1' },
+ { type: 'updateBreadcrumb', breadcrumb: 'Dashboard' },
+ ),
+ ],
};
export const Default = (): ReactElement => {
- const mocks = [...getNotificationsMocks(), getTopBarMock(), getSideBarMock()];
+ const mocks = [...getNotificationsMocks(), getTopBarMock(), getSideBarMock()];
- return (
-
-
-
-
- {[...new Array(50)]
- .map(
- () => `Cras mattis consectetur purus sit amet fermentum.
+ return (
+
+
+
+
+ {[...new Array(50)]
+ .map(
+ () => `Cras mattis consectetur purus sit amet fermentum.
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`,
- )
- .join('\n')}
-
-
-
-
- );
+ )
+ .join('\n')}
+
+
+
+
+ );
};
diff --git a/src/components/Layouts/Primary/Primary.test.tsx b/src/components/Layouts/Primary/Primary.test.tsx
index 3b3a22dede..81ab38e87b 100644
--- a/src/components/Layouts/Primary/Primary.test.tsx
+++ b/src/components/Layouts/Primary/Primary.test.tsx
@@ -8,46 +8,58 @@ import { getTopBarMock } from './TopBar/TopBar.mock';
import Primary from '.';
describe('Primary', () => {
- let mocks;
- beforeEach(() => {
- mocks = [...getNotificationsMocks(), getTopBarMock(), getSideBarMock()];
- matchMediaMock({ width: '1024px' });
- });
+ let mocks;
+ beforeEach(() => {
+ mocks = [...getNotificationsMocks(), getTopBarMock(), getSideBarMock()];
+ matchMediaMock({ width: '1024px' });
+ });
- it('has correct defaults', () => {
- const { getByTestId, queryByTestId, getByRole } = render(
-
-
-
-
- ,
- );
- expect(getByTestId('PrimaryTestChildren')).toBeInTheDocument();
- expect(queryByTestId('SideBarMobileDrawer')).not.toBeInTheDocument();
- expect(getByTestId('SideBarDesktopDrawer')).toBeInTheDocument();
- expect(getByRole('link', { name: 'Dashboard' })).toBeVisible();
- });
+ it('has correct defaults', () => {
+ const { getByTestId, queryByTestId, getByRole } = render(
+
+
+
+
+ ,
+ );
+ expect(getByTestId('PrimaryTestChildren')).toBeInTheDocument();
+ expect(queryByTestId('SideBarMobileDrawer')).not.toBeInTheDocument();
+ expect(getByTestId('SideBarDesktopDrawer')).toBeInTheDocument();
+ expect(getByRole('link', { name: 'Dashboard' })).toBeVisible();
+ });
- describe('mobile', () => {
- beforeEach(() => {
- matchMediaMock({ width: '640px' });
- });
+ describe('mobile', () => {
+ beforeEach(() => {
+ matchMediaMock({ width: '640px' });
+ });
- it('allows menu to be shown and hidden', async () => {
- const { getByTestId, queryByTestId, getByRole, queryByRole } = render(
-
-
-
-
- ,
- );
- expect(queryByTestId('SideBarDesktopDrawer')).not.toBeInTheDocument();
- expect(queryByRole('link', { name: 'Dashboard' })).not.toBeInTheDocument();
- const sideBarMobileDrawer = getByTestId('SideBarMobileDrawer');
- expect(sideBarMobileDrawer).toBeInTheDocument();
- fireEvent.click(getByRole('button', { name: 'Show Menu' }));
- fireEvent.click(getByRole('link', { name: 'Dashboard' }));
- await waitFor(() => expect(queryByRole('link', { name: 'Dashboard' })).not.toBeInTheDocument());
- });
+ it('allows menu to be shown and hidden', async () => {
+ const { getByTestId, queryByTestId, getByRole, queryByRole } = render(
+
+
+
+
+ ,
+ );
+ expect(queryByTestId('SideBarDesktopDrawer')).not.toBeInTheDocument();
+ expect(
+ queryByRole('link', { name: 'Dashboard' }),
+ ).not.toBeInTheDocument();
+ const sideBarMobileDrawer = getByTestId('SideBarMobileDrawer');
+ expect(sideBarMobileDrawer).toBeInTheDocument();
+ fireEvent.click(getByRole('button', { name: 'Show Menu' }));
+ fireEvent.click(getByRole('link', { name: 'Dashboard' }));
+ await waitFor(() =>
+ expect(
+ queryByRole('link', { name: 'Dashboard' }),
+ ).not.toBeInTheDocument(),
+ );
});
+ });
});
diff --git a/src/components/Layouts/Primary/Primary.tsx b/src/components/Layouts/Primary/Primary.tsx
index 62f298a211..eba8715628 100644
--- a/src/components/Layouts/Primary/Primary.tsx
+++ b/src/components/Layouts/Primary/Primary.tsx
@@ -8,59 +8,59 @@ import { SIDE_BAR_MINIMIZED_WIDTH, SIDE_BAR_WIDTH } from './SideBar/SideBar';
import BottomBar from './BottomBar';
const useStyles = makeStyles((theme: Theme) => ({
- container: {
- backgroundColor: '#f6f7f9',
- minHeight: 'calc(100vh - 122px)',
- [theme.breakpoints.down('xs')]: {
- minHeight: '100vh',
- },
+ container: {
+ backgroundColor: '#f6f7f9',
+ minHeight: 'calc(100vh - 122px)',
+ [theme.breakpoints.down('xs')]: {
+ minHeight: '100vh',
},
- box: {
- transition: theme.transitions.create('margin-left', {
- duration: theme.transitions.duration.enteringScreen,
- }),
- marginLeft: SIDE_BAR_WIDTH,
- [theme.breakpoints.down('sm')]: {
- marginLeft: 0,
- },
+ },
+ box: {
+ transition: theme.transitions.create('margin-left', {
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ marginLeft: SIDE_BAR_WIDTH,
+ [theme.breakpoints.down('sm')]: {
+ marginLeft: 0,
},
- boxClosed: {
- marginLeft: SIDE_BAR_MINIMIZED_WIDTH,
- [theme.breakpoints.down('sm')]: {
- marginLeft: 0,
- },
- },
- addFabSpacer: {
- height: '100px',
+ },
+ boxClosed: {
+ marginLeft: SIDE_BAR_MINIMIZED_WIDTH,
+ [theme.breakpoints.down('sm')]: {
+ marginLeft: 0,
},
+ },
+ addFabSpacer: {
+ height: '100px',
+ },
}));
interface Props {
- children: ReactNode;
+ children: ReactNode;
}
const Primary = ({ children }: Props): ReactElement => {
- const classes = useStyles();
- const [open, setOpen] = useState(false);
+ const classes = useStyles();
+ const [open, setOpen] = useState(false);
- const handleOpenChange = (state = !open): void => {
- setOpen(state);
- };
+ const handleOpenChange = (state = !open): void => {
+ setOpen(state);
+ };
- return (
-
-
-
-
- {children}
-
-
-
-
-
-
-
- );
+ return (
+
+
+
+
+ {children}
+
+
+
+
+
+
+
+ );
};
export default Primary;
diff --git a/src/components/Layouts/Primary/SideBar/SideBar.mock.tsx b/src/components/Layouts/Primary/SideBar/SideBar.mock.tsx
index d9cf187b80..bb9d14ba1f 100644
--- a/src/components/Layouts/Primary/SideBar/SideBar.mock.tsx
+++ b/src/components/Layouts/Primary/SideBar/SideBar.mock.tsx
@@ -3,75 +3,75 @@ import { GetSideBarQuery } from '../../../../../types/GetSideBarQuery';
import { GET_SIDEBAR_BAR_QUERY } from './SideBar';
export const getSideBarMock = (): MockedResponse => {
- const data: GetSideBarQuery = {
- contactsFixCommitmentInfo: {
- totalCount: 100,
- },
- contactsFixMailingAddress: {
- totalCount: 200,
- },
- contactsFixSendNewsletter: {
- totalCount: 300,
- },
- peopleFixEmailAddress: {
- totalCount: 400,
- },
- peopleFixPhoneNumber: {
- totalCount: 500,
- },
- contactDuplicates: {
- totalCount: 600,
- },
- personDuplicates: {
- totalCount: 700,
- },
- };
- return {
- request: {
- query: GET_SIDEBAR_BAR_QUERY,
- variables: {
- accountListId: '1',
- },
- },
- result: {
- data,
- },
- };
+ const data: GetSideBarQuery = {
+ contactsFixCommitmentInfo: {
+ totalCount: 100,
+ },
+ contactsFixMailingAddress: {
+ totalCount: 200,
+ },
+ contactsFixSendNewsletter: {
+ totalCount: 300,
+ },
+ peopleFixEmailAddress: {
+ totalCount: 400,
+ },
+ peopleFixPhoneNumber: {
+ totalCount: 500,
+ },
+ contactDuplicates: {
+ totalCount: 600,
+ },
+ personDuplicates: {
+ totalCount: 700,
+ },
+ };
+ return {
+ request: {
+ query: GET_SIDEBAR_BAR_QUERY,
+ variables: {
+ accountListId: '1',
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export const getSideBarEmptyMock = (): MockedResponse => {
- const data: GetSideBarQuery = {
- contactsFixCommitmentInfo: {
- totalCount: 0,
- },
- contactsFixMailingAddress: {
- totalCount: 0,
- },
- contactsFixSendNewsletter: {
- totalCount: 0,
- },
- peopleFixEmailAddress: {
- totalCount: 0,
- },
- peopleFixPhoneNumber: {
- totalCount: 0,
- },
- contactDuplicates: {
- totalCount: 0,
- },
- personDuplicates: {
- totalCount: 0,
- },
- };
- return {
- request: {
- query: GET_SIDEBAR_BAR_QUERY,
- variables: {
- accountListId: '1',
- },
- },
- result: {
- data,
- },
- };
+ const data: GetSideBarQuery = {
+ contactsFixCommitmentInfo: {
+ totalCount: 0,
+ },
+ contactsFixMailingAddress: {
+ totalCount: 0,
+ },
+ contactsFixSendNewsletter: {
+ totalCount: 0,
+ },
+ peopleFixEmailAddress: {
+ totalCount: 0,
+ },
+ peopleFixPhoneNumber: {
+ totalCount: 0,
+ },
+ contactDuplicates: {
+ totalCount: 0,
+ },
+ personDuplicates: {
+ totalCount: 0,
+ },
+ };
+ return {
+ request: {
+ query: GET_SIDEBAR_BAR_QUERY,
+ variables: {
+ accountListId: '1',
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
diff --git a/src/components/Layouts/Primary/SideBar/SideBar.stories.tsx b/src/components/Layouts/Primary/SideBar/SideBar.stories.tsx
index a54c3287d2..322e5a01f2 100644
--- a/src/components/Layouts/Primary/SideBar/SideBar.stories.tsx
+++ b/src/components/Layouts/Primary/SideBar/SideBar.stories.tsx
@@ -7,60 +7,62 @@ import { getSideBarMock, getSideBarEmptyMock } from './SideBar.mock';
import SideBar from '.';
export default {
- title: 'Layouts/Primary/SideBar',
- decorators: [withDispatch({ type: 'updateAccountListId', accountListId: '1' })],
+ title: 'Layouts/Primary/SideBar',
+ decorators: [
+ withDispatch({ type: 'updateAccountListId', accountListId: '1' }),
+ ],
};
const Content = (): ReactElement => (
-
-
- {[...new Array(50)]
- .map(
- () => `Cras mattis consectetur purus sit amet fermentum.
+
+
+ {[...new Array(50)]
+ .map(
+ () => `Cras mattis consectetur purus sit amet fermentum.
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`,
- )
- .join('\n')}
-
-
+ )
+ .join('\n')}
+
+
);
export const Default = (): ReactElement => {
- return (
- <>
-
- {}} />
-
-
-
-
- >
- );
+ return (
+ <>
+
+ {}} />
+
+
+
+
+ >
+ );
};
export const Open = (): ReactElement => {
- return (
- <>
-
- {}} />
-
-
-
-
- >
- );
+ return (
+ <>
+
+ {}} />
+
+
+
+
+ >
+ );
};
export const Empty = (): ReactElement => {
- return (
- <>
-
- {}} />
-
-
-
-
- >
- );
+ return (
+ <>
+
+ {}} />
+
+
+
+
+ >
+ );
};
diff --git a/src/components/Layouts/Primary/SideBar/SideBar.test.tsx b/src/components/Layouts/Primary/SideBar/SideBar.test.tsx
index db253eaa6a..171287cd5e 100644
--- a/src/components/Layouts/Primary/SideBar/SideBar.test.tsx
+++ b/src/components/Layouts/Primary/SideBar/SideBar.test.tsx
@@ -6,53 +6,65 @@ import { getSideBarMock } from './SideBar.mock';
import Sidebar from '.';
describe('Sidebar', () => {
- beforeEach(() => {
- matchMediaMock({ width: '1024px' });
- });
+ beforeEach(() => {
+ matchMediaMock({ width: '1024px' });
+ });
- it('has correct defaults', () => {
- const { getByTestId, queryByTestId, getByRole } = render(
-
-
- ,
- );
- expect(queryByTestId('SideBarMobileDrawer')).not.toBeInTheDocument();
- expect(getByTestId('SideBarDesktopDrawer')).toBeInTheDocument();
- const dashboardElement = getByRole('link', { name: 'Dashboard' });
- expect(dashboardElement).toBeVisible();
- expect(dashboardElement).toHaveAttribute('href', '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/accountLists/1');
- const tasksElement = getByRole('link', { name: 'Tasks' });
- expect(tasksElement).toBeVisible();
- expect(tasksElement).toHaveAttribute('href', '/accountLists/1/tasks');
- const giftsElement = getByRole('link', { name: 'Gifts' });
- expect(giftsElement).toBeVisible();
- expect(giftsElement).toHaveAttribute('href', 'https://stage.mpdx.org/reports/donations');
- });
+ it('has correct defaults', () => {
+ const { getByTestId, queryByTestId, getByRole } = render(
+
+
+ ,
+ );
+ expect(queryByTestId('SideBarMobileDrawer')).not.toBeInTheDocument();
+ expect(getByTestId('SideBarDesktopDrawer')).toBeInTheDocument();
+ const dashboardElement = getByRole('link', { name: 'Dashboard' });
+ expect(dashboardElement).toBeVisible();
+ expect(dashboardElement).toHaveAttribute('href', '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/accountLists/1');
+ const tasksElement = getByRole('link', { name: 'Tasks' });
+ expect(tasksElement).toBeVisible();
+ expect(tasksElement).toHaveAttribute('href', '/accountLists/1/tasks');
+ const giftsElement = getByRole('link', { name: 'Gifts' });
+ expect(giftsElement).toBeVisible();
+ expect(giftsElement).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/reports/donations',
+ );
+ });
- describe('mobile', () => {
- beforeEach(() => {
- matchMediaMock({ width: '640px' });
- });
+ describe('mobile', () => {
+ beforeEach(() => {
+ matchMediaMock({ width: '640px' });
+ });
- it('allows menu to be shown and hidden', () => {
- const handleOpenChange = jest.fn();
- const { getByTestId, queryByTestId, getByText, rerender } = render(
-
- ,
- ,
- );
- expect(queryByTestId('SideBarDesktopDrawer')).not.toBeInTheDocument();
- expect(getByText('Dashboard')).not.toBeVisible();
- const sideBarMobileDrawer = getByTestId('SideBarMobileDrawer');
- expect(sideBarMobileDrawer).toBeInTheDocument();
- fireEvent.click(sideBarMobileDrawer.children[0]);
- expect(handleOpenChange).toHaveBeenCalled();
- rerender(
-
-
- ,
- );
- expect(getByText('Dashboard')).toBeVisible();
- });
+ it('allows menu to be shown and hidden', () => {
+ const handleOpenChange = jest.fn();
+ const { getByTestId, queryByTestId, getByText, rerender } = render(
+
+ ,
+ ,
+ );
+ expect(queryByTestId('SideBarDesktopDrawer')).not.toBeInTheDocument();
+ expect(getByText('Dashboard')).not.toBeVisible();
+ const sideBarMobileDrawer = getByTestId('SideBarMobileDrawer');
+ expect(sideBarMobileDrawer).toBeInTheDocument();
+ fireEvent.click(sideBarMobileDrawer.children[0]);
+ expect(handleOpenChange).toHaveBeenCalled();
+ rerender(
+
+
+ ,
+ );
+ expect(getByText('Dashboard')).toBeVisible();
});
+ });
});
diff --git a/src/components/Layouts/Primary/SideBar/SideBar.tsx b/src/components/Layouts/Primary/SideBar/SideBar.tsx
index 630538c7b0..0a7082cd56 100644
--- a/src/components/Layouts/Primary/SideBar/SideBar.tsx
+++ b/src/components/Layouts/Primary/SideBar/SideBar.tsx
@@ -1,20 +1,20 @@
import React, { cloneElement, ReactElement } from 'react';
import {
- Divider,
- Drawer,
- Hidden,
- List,
- ListItem,
- ListItemText,
- makeStyles,
- Theme,
- createStyles,
- Box,
- ListItemIcon,
- IconButton,
- Tooltip,
- ListSubheader,
- Badge,
+ Divider,
+ Drawer,
+ Hidden,
+ List,
+ ListItem,
+ ListItemText,
+ makeStyles,
+ Theme,
+ createStyles,
+ Box,
+ ListItemIcon,
+ IconButton,
+ Tooltip,
+ ListSubheader,
+ Badge,
} from '@material-ui/core';
import HomeIcon from '@material-ui/icons/Home';
import { useTranslation } from 'react-i18next';
@@ -54,417 +54,475 @@ export const SIDE_BAR_WIDTH = 256;
export const SIDE_BAR_MINIMIZED_WIDTH = 57;
const useStyles = makeStyles((theme: Theme) =>
- createStyles({
- container: {
- height: '100%',
- display: 'flex',
- flexDirection: 'column',
- },
- nav: {
- [theme.breakpoints.up('sm')]: {
- width: SIDE_BAR_WIDTH,
- flexShrink: 0,
- },
- },
- toolbar: {
- ...theme.mixins.toolbar,
- display: 'flex',
- alignItems: 'center',
- paddingLeft: theme.spacing(0.5),
- },
- logo: {},
- drawerPaper: {
- paddingTop: `env(safe-area-inset-top)`,
- paddingBottom: `env(safe-area-inset-bottom)`,
- paddingLeft: `env(safe-area-inset-left)`,
- backgroundColor: 'rgb(5, 30, 52)',
- backgroundImage: `url(${require('./sideBar.png')})`,
- backgroundPosition: 'left 0 bottom 0',
- backgroundRepeat: 'no-repeat',
- backgroundSize: '256px 556px',
- width: SIDE_BAR_WIDTH,
- },
- divider: {
- backgroundColor: 'rgba(255,255,255,.4)',
- },
- list: {
- flexGrow: 1,
- padding: 0,
- overflowY: 'auto',
- overflowX: 'hidden',
- },
- listItem: {
- backgroundColor: 'rgba(255,255,255,.05)',
- '&:hover': {
- backgroundColor: 'rgba(255,255,255,.1)',
- },
- '&.Mui-selected $listItemIcon, &.Mui-selected $listItemText': {
- color: '#64b5f6',
- },
- },
- listItemIcon: {
- color: 'rgba(255, 255, 255, .7)',
- fontSize: theme.typography.h5.fontSize,
- },
- listItemText: {
- color: '#fff',
- },
- listSubheader: {
- backgroundColor: 'rgba(255,255,255,.05)',
- borderTop: '1px solid rgba(255,255,255,.4)',
- fontSize: theme.typography.body1.fontSize,
- fontWeight: 'bold',
- color: '#fff',
- overflow: 'hidden',
- height: 50,
- transition: theme.transitions.create('height', {
- duration: theme.transitions.duration.leavingScreen,
- }),
- },
- iconButton: {
- color: '#fff',
- marginRight: theme.spacing(2),
- },
- drawer: {
- width: SIDE_BAR_WIDTH,
- flexShrink: 0,
- whiteSpace: 'nowrap',
- },
- drawerOpen: {
- width: SIDE_BAR_WIDTH,
- transition: theme.transitions.create('width', {
- duration: theme.transitions.duration.enteringScreen,
- }),
- },
- drawerClose: {
- transition: theme.transitions.create('width', {
- duration: theme.transitions.duration.leavingScreen,
- delay: 20,
- }),
- overflowX: 'hidden',
- width: SIDE_BAR_MINIMIZED_WIDTH,
- '& $listSubheader': {
- height: 0,
- },
- },
- }),
+ createStyles({
+ container: {
+ height: '100%',
+ display: 'flex',
+ flexDirection: 'column',
+ },
+ nav: {
+ [theme.breakpoints.up('sm')]: {
+ width: SIDE_BAR_WIDTH,
+ flexShrink: 0,
+ },
+ },
+ toolbar: {
+ ...theme.mixins.toolbar,
+ display: 'flex',
+ alignItems: 'center',
+ paddingLeft: theme.spacing(0.5),
+ },
+ logo: {},
+ drawerPaper: {
+ paddingTop: `env(safe-area-inset-top)`,
+ paddingBottom: `env(safe-area-inset-bottom)`,
+ paddingLeft: `env(safe-area-inset-left)`,
+ backgroundColor: 'rgb(5, 30, 52)',
+ backgroundImage: `url(${require('./sideBar.png')})`,
+ backgroundPosition: 'left 0 bottom 0',
+ backgroundRepeat: 'no-repeat',
+ backgroundSize: '256px 556px',
+ width: SIDE_BAR_WIDTH,
+ },
+ divider: {
+ backgroundColor: 'rgba(255,255,255,.4)',
+ },
+ list: {
+ flexGrow: 1,
+ padding: 0,
+ overflowY: 'auto',
+ overflowX: 'hidden',
+ },
+ listItem: {
+ backgroundColor: 'rgba(255,255,255,.05)',
+ '&:hover': {
+ backgroundColor: 'rgba(255,255,255,.1)',
+ },
+ '&.Mui-selected $listItemIcon, &.Mui-selected $listItemText': {
+ color: '#64b5f6',
+ },
+ },
+ listItemIcon: {
+ color: 'rgba(255, 255, 255, .7)',
+ fontSize: theme.typography.h5.fontSize,
+ },
+ listItemText: {
+ color: '#fff',
+ },
+ listSubheader: {
+ backgroundColor: 'rgba(255,255,255,.05)',
+ borderTop: '1px solid rgba(255,255,255,.4)',
+ fontSize: theme.typography.body1.fontSize,
+ fontWeight: 'bold',
+ color: '#fff',
+ overflow: 'hidden',
+ height: 50,
+ transition: theme.transitions.create('height', {
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ },
+ iconButton: {
+ color: '#fff',
+ marginRight: theme.spacing(2),
+ },
+ drawer: {
+ width: SIDE_BAR_WIDTH,
+ flexShrink: 0,
+ whiteSpace: 'nowrap',
+ },
+ drawerOpen: {
+ width: SIDE_BAR_WIDTH,
+ transition: theme.transitions.create('width', {
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ },
+ drawerClose: {
+ transition: theme.transitions.create('width', {
+ duration: theme.transitions.duration.leavingScreen,
+ delay: 20,
+ }),
+ overflowX: 'hidden',
+ width: SIDE_BAR_MINIMIZED_WIDTH,
+ '& $listSubheader': {
+ height: 0,
+ },
+ },
+ }),
);
type ItemProps = LocalLinkProps | HandoffLinkProps;
interface BaseProps {
- label: string;
- icon: ReactElement;
+ label: string;
+ icon: ReactElement;
}
interface LocalLinkProps extends BaseProps {
- type: 'local';
- href: string;
- as?: string;
+ type: 'local';
+ href: string;
+ as?: string;
}
interface HandoffLinkProps extends BaseProps {
- type: 'handoff';
- path: string;
+ type: 'handoff';
+ path: string;
}
interface Props {
- open: boolean;
- handleOpenChange: (state?: boolean) => void;
+ open: boolean;
+ handleOpenChange: (state?: boolean) => void;
}
export const GET_SIDEBAR_BAR_QUERY = gql`
- query GetSideBarQuery($accountListId: ID!) {
- contactsFixCommitmentInfo: contacts(accountListId: $accountListId, statusValid: false) {
- totalCount
- }
- contactsFixMailingAddress: contacts(accountListId: $accountListId, addressValid: false) {
- totalCount
- }
- contactsFixSendNewsletter: contacts(
- accountListId: $accountListId
- status: [PARTNER_FINANCIAL, PARTNER_SPECIAL, PARTNER_PRAY]
- newsletter: NO_VALUE
- ) {
- totalCount
- }
- peopleFixEmailAddress: people(accountListId: $accountListId, emailAddressValid: false) {
- totalCount
- }
- peopleFixPhoneNumber: people(accountListId: $accountListId, phoneNumberValid: false) {
- totalCount
- }
- contactDuplicates(accountListId: $accountListId, ignore: false) {
- totalCount
- }
- personDuplicates(accountListId: $accountListId, ignore: false) {
- totalCount
- }
+ query GetSideBarQuery($accountListId: ID!) {
+ contactsFixCommitmentInfo: contacts(
+ accountListId: $accountListId
+ statusValid: false
+ ) {
+ totalCount
+ }
+ contactsFixMailingAddress: contacts(
+ accountListId: $accountListId
+ addressValid: false
+ ) {
+ totalCount
+ }
+ contactsFixSendNewsletter: contacts(
+ accountListId: $accountListId
+ status: [PARTNER_FINANCIAL, PARTNER_SPECIAL, PARTNER_PRAY]
+ newsletter: NO_VALUE
+ ) {
+ totalCount
+ }
+ peopleFixEmailAddress: people(
+ accountListId: $accountListId
+ emailAddressValid: false
+ ) {
+ totalCount
+ }
+ peopleFixPhoneNumber: people(
+ accountListId: $accountListId
+ phoneNumberValid: false
+ ) {
+ totalCount
}
+ contactDuplicates(accountListId: $accountListId, ignore: false) {
+ totalCount
+ }
+ personDuplicates(accountListId: $accountListId, ignore: false) {
+ totalCount
+ }
+ }
`;
const SideBar = ({ open, handleOpenChange }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const {
- state: { accountListId },
- } = useApp();
- const { data } = useQuery(GET_SIDEBAR_BAR_QUERY, { variables: { accountListId } });
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const {
+ state: { accountListId },
+ } = useApp();
+ const { data } = useQuery(GET_SIDEBAR_BAR_QUERY, {
+ variables: { accountListId },
+ });
- const Item = (props: ItemProps) => {
- const { asPath } = useRouter();
+ const Item = (props: ItemProps) => {
+ const { asPath } = useRouter();
- const selected = props.type == 'local' && (asPath === props.href || asPath === props.as);
+ const selected =
+ props.type == 'local' && (asPath === props.href || asPath === props.as);
- const children = (
- handleOpenChange(false)}
- component="a"
- className={classes.listItem}
- selected={selected}
- >
-
- {cloneElement(props.icon, { fontSize: 'inherit' })}
-
-
-
- );
+ const children = (
+ handleOpenChange(false)}
+ component="a"
+ className={classes.listItem}
+ selected={selected}
+ >
+
+ {cloneElement(props.icon, { fontSize: 'inherit' })}
+
+
+
+ );
- return (
-
-
- {props.type == 'local' && (
-
- {children}
-
- )}
- {props.type == 'handoff' && {children}}
-
-
- );
- };
+ return (
+
+
+ {props.type == 'local' && (
+
+ {children}
+
+ )}
+ {props.type == 'handoff' && (
+ {children}
+ )}
+
+
+ );
+ };
- const drawer = (
-
-
- handleOpenChange()}>
- } openIcon={} open={open} />
-
-
-
-
-
-
-
- }
- />
- } />
- }
- />
-
- {t('Reports')}
-
- } />
- } />
- }
- />
- }
- />
- }
- />
- }
- />
- } />
-
- {t('Tools')}
-
- } />
- }
- />
- } />
- }
- />
+ const drawer = (
+
+
+ handleOpenChange()}
+ >
+ }
+ openIcon={}
+ open={open}
+ />
+
+
+
+
+
+
+
+ }
+ />
+ }
+ />
+ }
+ />
+
+ {t('Reports')}
+
+ }
+ />
+ }
+ />
+ }
+ />
+ }
+ />
+ }
+ />
+ }
+ />
+ }
+ />
+
+ {t('Tools')}
+
+ }
+ />
+ }
+ />
+ }
+ />
+ }
+ />
- -
-
-
- }
- />
+
-
+
+
+ }
+ />
-
-
-
-
- }
- />
-
-
-
-
- }
- />
-
-
-
-
- }
- />
-
-
-
-
- }
- />
-
-
-
-
- }
- />
-
-
-
-
- }
- />
-
-
- );
+ -
+
+
+ }
+ />
+
-
+
+
+ }
+ />
+
-
+
+
+ }
+ />
+
-
+
+
+ }
+ />
+
-
+
+
+ }
+ />
+
-
+
+
+ }
+ />
+
+
+ );
- return (
-
- );
+ return (
+
+ );
};
export default SideBar;
diff --git a/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.mock.tsx b/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.mock.tsx
index 436e69a222..646c0e3d04 100644
--- a/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.mock.tsx
+++ b/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.mock.tsx
@@ -2,27 +2,29 @@ import { MockedResponse } from '@apollo/client/testing';
import { AcknowledgeUserNotificationMutation } from '../../../../../../../types/AcknowledgeUserNotificationMutation';
import { ACKNOWLEDGE_USER_NOTIFICATION_MUTATION } from './Item';
-const acknowledgeUserNotificationMutationMock = (id: string): MockedResponse => {
- const data: AcknowledgeUserNotificationMutation = {
- acknowledgeUserNotification: {
- notification: {
- id,
- read: true,
- },
- },
- };
+const acknowledgeUserNotificationMutationMock = (
+ id: string,
+): MockedResponse => {
+ const data: AcknowledgeUserNotificationMutation = {
+ acknowledgeUserNotification: {
+ notification: {
+ id,
+ read: true,
+ },
+ },
+ };
- return {
- request: {
- query: ACKNOWLEDGE_USER_NOTIFICATION_MUTATION,
- variables: {
- notificationId: id,
- },
- },
- result: {
- data,
- },
- };
+ return {
+ request: {
+ query: ACKNOWLEDGE_USER_NOTIFICATION_MUTATION,
+ variables: {
+ notificationId: id,
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export default acknowledgeUserNotificationMutationMock;
diff --git a/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.stories.tsx b/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.stories.tsx
index 10e9bc8317..8cabededb8 100644
--- a/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.stories.tsx
+++ b/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.stories.tsx
@@ -6,93 +6,143 @@ import acknowledgeUserNotificationMutationMock from './Item.mock';
import NotificationMenuItem from '.';
export default {
- title: 'Layouts/Primary/TopBar/NotificationMenu/Item',
+ title: 'Layouts/Primary/TopBar/NotificationMenu/Item',
};
export const Default = (): ReactElement => {
- const id = 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b';
- const itemWithoutDonation = (type: NotificationTypeTypeEnum): Notification => {
- return {
- id,
- read: false,
- notification: {
- occurredAt: '2020-05-25T20:00:00-04:00',
- contact: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
- name: 'Smith, Roger',
- },
- donation: null,
- notificationType: {
- id: '6eb32493-c51b-490a-955d-595642160a95',
- type,
- descriptionTemplate: 'Partner has upcoming anniversary',
- },
- },
- };
+ const id = 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b';
+ const itemWithoutDonation = (
+ type: NotificationTypeTypeEnum,
+ ): Notification => {
+ return {
+ id,
+ read: false,
+ notification: {
+ occurredAt: '2020-05-25T20:00:00-04:00',
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
+ name: 'Smith, Roger',
+ },
+ donation: null,
+ notificationType: {
+ id: '6eb32493-c51b-490a-955d-595642160a95',
+ type,
+ descriptionTemplate: 'Partner has upcoming anniversary',
+ },
+ },
};
- const itemWithDonation = (type: NotificationTypeTypeEnum): Notification => {
- return {
- id,
- read: false,
- notification: {
- occurredAt: '2020-05-25T20:00:00-04:00',
- contact: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
- name: 'Smith, Roger',
- },
- donation: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbc4',
- amount: {
- amount: 10000,
- currency: 'AUD',
- conversionDate: '2020-10-05',
- },
- },
- notificationType: {
- id: '6eb32493-c51b-490a-955d-595642160a95',
- type,
- descriptionTemplate: 'Partner has upcoming anniversary',
- },
- },
- };
+ };
+ const itemWithDonation = (type: NotificationTypeTypeEnum): Notification => {
+ return {
+ id,
+ read: false,
+ notification: {
+ occurredAt: '2020-05-25T20:00:00-04:00',
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
+ name: 'Smith, Roger',
+ },
+ donation: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbc4',
+ amount: {
+ amount: 10000,
+ currency: 'AUD',
+ conversionDate: '2020-10-05',
+ },
+ },
+ notificationType: {
+ id: '6eb32493-c51b-490a-955d-595642160a95',
+ type,
+ descriptionTemplate: 'Partner has upcoming anniversary',
+ },
+ },
};
- return (
-
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
-
- );
+ };
+ return (
+
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+
+ );
};
export const Loading = (): ReactElement => {
- return (
- <>
-
-
- >
- );
+ return (
+ <>
+
+
+ >
+ );
};
diff --git a/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.test.tsx b/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.test.tsx
index 4dd57ae743..821cd6e295 100644
--- a/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.test.tsx
+++ b/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.test.tsx
@@ -6,409 +6,494 @@ import { InMemoryCache } from '@apollo/client';
import TestWrapper from '../../../../../../../__tests__/util/TestWrapper';
import { NotificationTypeTypeEnum } from '../../../../../../../types/globalTypes';
import {
- GetNotificationsQuery,
- GetNotificationsQuery_userNotifications_edges_node as Notification,
+ GetNotificationsQuery,
+ GetNotificationsQuery_userNotifications_edges_node as Notification,
} from '../../../../../../../types/GetNotificationsQuery';
-import { render, waitFor } from '../../../../../../../__tests__/util/testingLibraryReactMock';
+import {
+ render,
+ waitFor,
+} from '../../../../../../../__tests__/util/testingLibraryReactMock';
import GET_NOTIFICATIONS_QUERY from '../getNotificationsQuery.graphql';
import acknowledgeUserNotificationMutationMock from './Item.mock';
import NotificationMenuItem from '.';
describe('NotificationMenuItem', () => {
- const id = 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b';
- const itemWithoutDonation = (
- type: NotificationTypeTypeEnum,
- occurredAt = '2020-05-25T20:00:00-04:00',
- ): Notification => {
- return {
- id,
- read: false,
- notification: {
- occurredAt,
- contact: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
- name: 'Smith, Roger',
- },
- donation: null,
- notificationType: {
- id: '6eb32493-c51b-490a-955d-595642160a95',
- type,
- descriptionTemplate: 'Custom notification description',
- },
- },
- };
+ const id = 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b';
+ const itemWithoutDonation = (
+ type: NotificationTypeTypeEnum,
+ occurredAt = '2020-05-25T20:00:00-04:00',
+ ): Notification => {
+ return {
+ id,
+ read: false,
+ notification: {
+ occurredAt,
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
+ name: 'Smith, Roger',
+ },
+ donation: null,
+ notificationType: {
+ id: '6eb32493-c51b-490a-955d-595642160a95',
+ type,
+ descriptionTemplate: 'Custom notification description',
+ },
+ },
};
- const itemWithDonation = (type: NotificationTypeTypeEnum): Notification => {
- return {
- id,
- read: false,
- notification: {
- occurredAt: '2020-05-25T20:00:00-04:00',
- contact: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
- name: 'Smith, Roger',
- },
- donation: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbc4',
- amount: {
- amount: 10000,
- currency: 'AUD',
- conversionDate: '2020-10-05',
- },
- },
- notificationType: {
- id: '6eb32493-c51b-490a-955d-595642160a95',
- type,
- descriptionTemplate: 'Custom notification description',
- },
- },
- };
+ };
+ const itemWithDonation = (type: NotificationTypeTypeEnum): Notification => {
+ return {
+ id,
+ read: false,
+ notification: {
+ occurredAt: '2020-05-25T20:00:00-04:00',
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
+ name: 'Smith, Roger',
+ },
+ donation: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbc4',
+ amount: {
+ amount: 10000,
+ currency: 'AUD',
+ conversionDate: '2020-10-05',
+ },
+ },
+ notificationType: {
+ id: '6eb32493-c51b-490a-955d-595642160a95',
+ type,
+ descriptionTemplate: 'Custom notification description',
+ },
+ },
};
+ };
- it('default', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('listitem')).toBeInTheDocument();
- expect(getByRole('separator')).toBeInTheDocument();
- });
+ it('default', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('listitem')).toBeInTheDocument();
+ expect(getByRole('separator')).toBeInTheDocument();
+ });
- it('last', () => {
- const { queryByRole } = render(
-
-
- ,
- );
- expect(queryByRole('separator')).not.toBeInTheDocument();
- });
+ it('last', () => {
+ const { queryByRole } = render(
+
+
+ ,
+ );
+ expect(queryByRole('separator')).not.toBeInTheDocument();
+ });
- it('CALL_PARTNER_ONCE_PER_YEAR', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — No call logged in the past year');
- });
+ it('CALL_PARTNER_ONCE_PER_YEAR', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — No call logged in the past year',
+ );
+ });
- it('LARGER_GIFT', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — Gave a larger gift than their commitment amount',
- );
- });
+ it('LARGER_GIFT', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Gave a larger gift than their commitment amount',
+ );
+ });
- it('LARGER_GIFT with donation', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — Gave a gift of A$10,000 which is greater than their commitment amount',
- );
- });
+ it('LARGER_GIFT with donation', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Gave a gift of A$10,000 which is greater than their commitment amount',
+ );
+ });
- it('LONG_TIME_FRAME_GIFT', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — Gave a gift where commitment frequency is set to semi-annual or greater',
- );
- });
+ it('LONG_TIME_FRAME_GIFT', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Gave a gift where commitment frequency is set to semi-annual or greater',
+ );
+ });
- it('LONG_TIME_FRAME_GIFT with donation', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — Gave a gift of A$10,000 where commitment frequency is set to semi-annual or greater',
- );
- });
+ it('LONG_TIME_FRAME_GIFT with donation', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Gave a gift of A$10,000 where commitment frequency is set to semi-annual or greater',
+ );
+ });
- it('MISSING_ADDRESS_IN_NEWSLETTER', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — On your physical newsletter list but has no mailing address',
- );
- });
+ it('MISSING_ADDRESS_IN_NEWSLETTER', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — On your physical newsletter list but has no mailing address',
+ );
+ });
- it('MISSING_EMAIL_IN_NEWSLETTER', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — On your email newsletter list but has no people with a valid email address',
- );
- });
+ it('MISSING_EMAIL_IN_NEWSLETTER', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — On your email newsletter list but has no people with a valid email address',
+ );
+ });
- it('NEW_DESIGNATION_ACCOUNT_SUBSCRIPTION', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — Added through your Give Site subscription form',
- );
- });
+ it('NEW_DESIGNATION_ACCOUNT_SUBSCRIPTION', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Added through your Give Site subscription form',
+ );
+ });
- it('NEW_PARTNER_DUPLICATE_MERGED', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Added and merged');
- });
+ it('NEW_PARTNER_DUPLICATE_MERGED', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Added and merged',
+ );
+ });
- it('NEW_PARTNER_DUPLICATE_NOT_MERGED', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Added but not merged');
- });
+ it('NEW_PARTNER_DUPLICATE_NOT_MERGED', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Added but not merged',
+ );
+ });
- it('NEW_PARTNER_NO_DUPLICATE', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Added with no duplicate found');
- });
+ it('NEW_PARTNER_NO_DUPLICATE', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Added with no duplicate found',
+ );
+ });
- it('RECONTINUING_GIFT', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Recontinued giving');
- });
+ it('RECONTINUING_GIFT', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Recontinued giving',
+ );
+ });
- it('REMIND_PARTNER_IN_ADVANCE', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — Semi-annual or greater gift is expected one month from now',
- );
- });
+ it('REMIND_PARTNER_IN_ADVANCE', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Semi-annual or greater gift is expected one month from now',
+ );
+ });
- it('SMALLER_GIFT', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — Gave a smaller gift than their commitment amount',
- );
- });
+ it('SMALLER_GIFT', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Gave a smaller gift than their commitment amount',
+ );
+ });
- it('SMALLER_GIFT with donation', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — Gave a gift of A$10,000 which is less than their commitment amount',
- );
- });
+ it('SMALLER_GIFT with donation', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Gave a gift of A$10,000 which is less than their commitment amount',
+ );
+ });
- it('SPECIAL_GIFT', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Gave a special gift');
- });
+ it('SPECIAL_GIFT', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Gave a special gift',
+ );
+ });
- it('SPECIAL_GIFT with donation', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Gave a special gift of A$10,000');
- });
+ it('SPECIAL_GIFT with donation', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Gave a special gift of A$10,000',
+ );
+ });
- it('STARTED_GIVING', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Started giving');
- });
+ it('STARTED_GIVING', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Started giving',
+ );
+ });
- it('STOPPED_GIVING', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Missed a gift');
- });
+ it('STOPPED_GIVING', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Missed a gift',
+ );
+ });
- it('THANK_PARTNER_ONCE_PER_YEAR', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual(
- 'SSmith, RogerMay 26, 2020 — No thank you note logged in the past year',
- );
- });
+ it('THANK_PARTNER_ONCE_PER_YEAR', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — No thank you note logged in the past year',
+ );
+ });
- it('UPCOMING_ANNIVERSARY', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Upcoming anniversary');
- });
+ it('UPCOMING_ANNIVERSARY', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Upcoming anniversary',
+ );
+ });
- it('UPCOMING_BIRTHDAY', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Upcoming birthday');
- });
+ it('UPCOMING_BIRTHDAY', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Upcoming birthday',
+ );
+ });
- it('UNKNOWN_NOTIFICATION_TYPE', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('button').textContent).toEqual('SSmith, RogerMay 26, 2020 — Custom notification description');
- });
+ it('UNKNOWN_NOTIFICATION_TYPE', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('button').textContent).toEqual(
+ 'SSmith, RogerMay 26, 2020 — Custom notification description',
+ );
+ });
- describe('MockDate', () => {
- beforeEach(() => {
- MockDate.set(new Date(2020, 1, 1));
- });
+ describe('MockDate', () => {
+ beforeEach(() => {
+ MockDate.set(new Date(2020, 1, 1));
+ });
- afterEach(() => {
- MockDate.reset();
- });
+ afterEach(() => {
+ MockDate.reset();
+ });
- it('previousItem', () => {
- const { getByRole } = render(
-
-
- ,
- );
- expect(getByRole('heading').textContent).toEqual('Feb 2020');
- });
+ it('previousItem', () => {
+ const { getByRole } = render(
+
+
+ ,
+ );
+ expect(getByRole('heading').textContent).toEqual('Feb 2020');
});
+ });
- describe('onClick', () => {
- it('calls function', async () => {
- const cache = new InMemoryCache({ addTypename: false });
- jest.spyOn(cache, 'writeQuery');
- const data: GetNotificationsQuery = {
- userNotifications: {
- edges: [],
- pageInfo: {
- endCursor: null,
- hasNextPage: false,
- },
- unreadCount: 2,
- },
- };
- cache.writeQuery({
- query: GET_NOTIFICATIONS_QUERY,
- variables: {
- accountListId: '1',
- after: null,
- },
- data,
- });
- const handleClick = jest.fn();
- const { getByRole } = render(
-
-
- ,
- );
- userEvent.click(getByRole('button'));
- await waitFor(() => expect(handleClick).toHaveBeenCalled());
- expect(cache.writeQuery).toHaveBeenCalledWith({
- query: GET_NOTIFICATIONS_QUERY,
- variables: {
- accountListId: '1',
- after: null,
- },
- data: {
- userNotifications: {
- edges: [],
- pageInfo: {
- endCursor: null,
- hasNextPage: false,
- },
- unreadCount: 1,
- },
- },
- });
- });
+ describe('onClick', () => {
+ it('calls function', async () => {
+ const cache = new InMemoryCache({ addTypename: false });
+ jest.spyOn(cache, 'writeQuery');
+ const data: GetNotificationsQuery = {
+ userNotifications: {
+ edges: [],
+ pageInfo: {
+ endCursor: null,
+ hasNextPage: false,
+ },
+ unreadCount: 2,
+ },
+ };
+ cache.writeQuery({
+ query: GET_NOTIFICATIONS_QUERY,
+ variables: {
+ accountListId: '1',
+ after: null,
+ },
+ data,
+ });
+ const handleClick = jest.fn();
+ const { getByRole } = render(
+
+
+ ,
+ );
+ userEvent.click(getByRole('button'));
+ await waitFor(() => expect(handleClick).toHaveBeenCalled());
+ expect(cache.writeQuery).toHaveBeenCalledWith({
+ query: GET_NOTIFICATIONS_QUERY,
+ variables: {
+ accountListId: '1',
+ after: null,
+ },
+ data: {
+ userNotifications: {
+ edges: [],
+ pageInfo: {
+ endCursor: null,
+ hasNextPage: false,
+ },
+ unreadCount: 1,
+ },
+ },
+ });
});
+ });
});
diff --git a/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.tsx b/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.tsx
index c59c48c840..8ead1060cc 100644
--- a/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.tsx
+++ b/src/components/Layouts/Primary/TopBar/NotificationMenu/Item/Item.tsx
@@ -1,14 +1,14 @@
import { useMutation, gql } from '@apollo/client';
import {
- Avatar,
- Badge,
- Box,
- Divider,
- ListItem,
- ListItemAvatar,
- ListItemText,
- ListSubheader,
- Typography,
+ Avatar,
+ Badge,
+ Box,
+ Divider,
+ ListItem,
+ ListItemAvatar,
+ ListItemText,
+ ListSubheader,
+ Typography,
} from '@material-ui/core';
import { Skeleton } from '@material-ui/lab';
import React, { ReactElement } from 'react';
@@ -17,218 +17,249 @@ import { cloneDeep, isFunction } from 'lodash/fp';
import { isSameMonth } from 'date-fns';
import { AcknowledgeUserNotificationMutation } from '../../../../../../../types/AcknowledgeUserNotificationMutation';
import {
- GetNotificationsQuery,
- GetNotificationsQuery_userNotifications_edges_node as Notification,
+ GetNotificationsQuery,
+ GetNotificationsQuery_userNotifications_edges_node as Notification,
} from '../../../../../../../types/GetNotificationsQuery';
import { NotificationTypeTypeEnum } from '../../../../../../../types/globalTypes';
-import { dateFormat, monthYearFormat } from '../../../../../../lib/intlFormat/intlFormat';
+import {
+ dateFormat,
+ monthYearFormat,
+} from '../../../../../../lib/intlFormat/intlFormat';
import { useApp } from '../../../../../App';
import HandoffLink from '../../../../../HandoffLink';
import GET_NOTIFICATIONS_QUERY from '../getNotificationsQuery.graphql';
export const ACKNOWLEDGE_USER_NOTIFICATION_MUTATION = gql`
- mutation AcknowledgeUserNotificationMutation($notificationId: ID!) {
- acknowledgeUserNotification(input: { notificationId: $notificationId }) {
- notification {
- id
- read
- }
- }
+ mutation AcknowledgeUserNotificationMutation($notificationId: ID!) {
+ acknowledgeUserNotification(input: { notificationId: $notificationId }) {
+ notification {
+ id
+ read
+ }
}
+ }
`;
interface Props {
- item?: Notification;
- last?: boolean;
- previousItem?: Notification;
- onClick?: () => void;
+ item?: Notification;
+ last?: boolean;
+ previousItem?: Notification;
+ onClick?: () => void;
}
-const NotificationMenuItem = ({ item, previousItem, last, onClick }: Props): ReactElement => {
- const { t } = useTranslation();
- const { state } = useApp();
-
- if (!item) {
- return (
-
-
-
-
-
- } secondary={} />
-
- {!last && }
-
- );
- }
+const NotificationMenuItem = ({
+ item,
+ previousItem,
+ last,
+ onClick,
+}: Props): ReactElement => {
+ const { t } = useTranslation();
+ const { state } = useApp();
- const amount = item.notification.donation?.amount;
- const [acknoweldgeUserNotification] = useMutation(
- ACKNOWLEDGE_USER_NOTIFICATION_MUTATION,
+ if (!item) {
+ return (
+
+
+
+
+
+ }
+ secondary={}
+ />
+
+ {!last && }
+
);
- const handleClick = async () => {
- let optimisticResponse = true;
- if (!item.read) {
- await acknoweldgeUserNotification({
- variables: { notificationId: item.id },
- optimisticResponse: {
- acknowledgeUserNotification: {
- notification: {
- id: item.id,
- read: true,
- },
- },
- },
- update: (cache) => {
- if (!optimisticResponse) return;
-
- const query = {
- query: GET_NOTIFICATIONS_QUERY,
- variables: {
- accountListId: state.accountListId,
- after: null,
- },
- };
- const data = cloneDeep(cache.readQuery(query));
- data.userNotifications.unreadCount--;
- cache.writeQuery({ ...query, data });
- optimisticResponse = false;
- },
- });
- }
- if (isFunction(onClick)) onClick();
- };
+ }
- let message;
+ const amount = item.notification.donation?.amount;
+ const [
+ acknoweldgeUserNotification,
+ ] = useMutation(
+ ACKNOWLEDGE_USER_NOTIFICATION_MUTATION,
+ );
+ const handleClick = async () => {
+ let optimisticResponse = true;
+ if (!item.read) {
+ await acknoweldgeUserNotification({
+ variables: { notificationId: item.id },
+ optimisticResponse: {
+ acknowledgeUserNotification: {
+ notification: {
+ id: item.id,
+ read: true,
+ },
+ },
+ },
+ update: (cache) => {
+ if (!optimisticResponse) return;
- switch (item.notification.notificationType.type) {
- case NotificationTypeTypeEnum.CALL_PARTNER_ONCE_PER_YEAR:
- message = t('No call logged in the past year');
- break;
- case NotificationTypeTypeEnum.LARGER_GIFT:
- if (amount) {
- message = t('Gave a gift of {{ amount, currency }} which is greater than their commitment amount', {
- amount,
- });
- } else {
- message = t('Gave a larger gift than their commitment amount');
- }
- break;
- case NotificationTypeTypeEnum.LONG_TIME_FRAME_GIFT:
- if (amount) {
- message = t(
- 'Gave a gift of {{ amount, currency }} where commitment frequency is set to semi-annual or greater',
- {
- amount,
- },
- );
- } else {
- message = t('Gave a gift where commitment frequency is set to semi-annual or greater');
- }
- break;
- case NotificationTypeTypeEnum.MISSING_ADDRESS_IN_NEWSLETTER:
- message = t('On your physical newsletter list but has no mailing address');
- break;
- case NotificationTypeTypeEnum.MISSING_EMAIL_IN_NEWSLETTER:
- message = t('On your email newsletter list but has no people with a valid email address');
- break;
- case NotificationTypeTypeEnum.NEW_DESIGNATION_ACCOUNT_SUBSCRIPTION:
- message = t('Added through your Give Site subscription form');
- break;
- case NotificationTypeTypeEnum.NEW_PARTNER_DUPLICATE_MERGED:
- message = t('Added and merged');
- break;
- case NotificationTypeTypeEnum.NEW_PARTNER_DUPLICATE_NOT_MERGED:
- message = t('Added but not merged');
- break;
- case NotificationTypeTypeEnum.NEW_PARTNER_NO_DUPLICATE:
- message = t('Added with no duplicate found');
- break;
- case NotificationTypeTypeEnum.RECONTINUING_GIFT:
- message = t('Recontinued giving');
- break;
- case NotificationTypeTypeEnum.REMIND_PARTNER_IN_ADVANCE:
- message = t('Semi-annual or greater gift is expected one month from now');
- break;
- case NotificationTypeTypeEnum.SMALLER_GIFT:
- if (amount) {
- message = t('Gave a gift of {{ amount, currency }} which is less than their commitment amount', {
- amount,
- });
- } else {
- message = t('Gave a smaller gift than their commitment amount');
- }
- break;
- case NotificationTypeTypeEnum.SPECIAL_GIFT:
- if (amount) {
- message = t('Gave a special gift of {{ amount, currency }}', { amount });
- } else {
- message = t('Gave a special gift');
- }
- break;
- case NotificationTypeTypeEnum.STARTED_GIVING:
- message = t('Started giving');
- break;
- case NotificationTypeTypeEnum.STOPPED_GIVING:
- message = t('Missed a gift');
- break;
- case NotificationTypeTypeEnum.THANK_PARTNER_ONCE_PER_YEAR:
- message = t('No thank you note logged in the past year');
- break;
- case NotificationTypeTypeEnum.UPCOMING_ANNIVERSARY:
- message = t('Upcoming anniversary');
- break;
- case NotificationTypeTypeEnum.UPCOMING_BIRTHDAY:
- message = t('Upcoming birthday');
- break;
- default:
- message = item.notification.notificationType.descriptionTemplate;
- break;
+ const query = {
+ query: GET_NOTIFICATIONS_QUERY,
+ variables: {
+ accountListId: state.accountListId,
+ after: null,
+ },
+ };
+ const data = cloneDeep(cache.readQuery(query));
+ data.userNotifications.unreadCount--;
+ cache.writeQuery({ ...query, data });
+ optimisticResponse = false;
+ },
+ });
}
+ if (isFunction(onClick)) onClick();
+ };
- return (
-
- {previousItem?.notification?.occurredAt &&
- !isSameMonth(
- new Date(previousItem.notification.occurredAt),
- new Date(item.notification.occurredAt),
- ) && (
-
- {monthYearFormat(
- new Date(item.notification.occurredAt).getMonth(),
- new Date(item.notification.occurredAt).getFullYear(),
- )}
-
- )}
-
-
-
-
- {item.notification.contact.name[0]}
-
-
-
-
- {dateFormat(new Date(item.notification.occurredAt))}
- {' '}
- — {message}
- >
- }
- />
-
-
- {!last && }
-
- );
+ let message;
+
+ switch (item.notification.notificationType.type) {
+ case NotificationTypeTypeEnum.CALL_PARTNER_ONCE_PER_YEAR:
+ message = t('No call logged in the past year');
+ break;
+ case NotificationTypeTypeEnum.LARGER_GIFT:
+ if (amount) {
+ message = t(
+ 'Gave a gift of {{ amount, currency }} which is greater than their commitment amount',
+ {
+ amount,
+ },
+ );
+ } else {
+ message = t('Gave a larger gift than their commitment amount');
+ }
+ break;
+ case NotificationTypeTypeEnum.LONG_TIME_FRAME_GIFT:
+ if (amount) {
+ message = t(
+ 'Gave a gift of {{ amount, currency }} where commitment frequency is set to semi-annual or greater',
+ {
+ amount,
+ },
+ );
+ } else {
+ message = t(
+ 'Gave a gift where commitment frequency is set to semi-annual or greater',
+ );
+ }
+ break;
+ case NotificationTypeTypeEnum.MISSING_ADDRESS_IN_NEWSLETTER:
+ message = t(
+ 'On your physical newsletter list but has no mailing address',
+ );
+ break;
+ case NotificationTypeTypeEnum.MISSING_EMAIL_IN_NEWSLETTER:
+ message = t(
+ 'On your email newsletter list but has no people with a valid email address',
+ );
+ break;
+ case NotificationTypeTypeEnum.NEW_DESIGNATION_ACCOUNT_SUBSCRIPTION:
+ message = t('Added through your Give Site subscription form');
+ break;
+ case NotificationTypeTypeEnum.NEW_PARTNER_DUPLICATE_MERGED:
+ message = t('Added and merged');
+ break;
+ case NotificationTypeTypeEnum.NEW_PARTNER_DUPLICATE_NOT_MERGED:
+ message = t('Added but not merged');
+ break;
+ case NotificationTypeTypeEnum.NEW_PARTNER_NO_DUPLICATE:
+ message = t('Added with no duplicate found');
+ break;
+ case NotificationTypeTypeEnum.RECONTINUING_GIFT:
+ message = t('Recontinued giving');
+ break;
+ case NotificationTypeTypeEnum.REMIND_PARTNER_IN_ADVANCE:
+ message = t('Semi-annual or greater gift is expected one month from now');
+ break;
+ case NotificationTypeTypeEnum.SMALLER_GIFT:
+ if (amount) {
+ message = t(
+ 'Gave a gift of {{ amount, currency }} which is less than their commitment amount',
+ {
+ amount,
+ },
+ );
+ } else {
+ message = t('Gave a smaller gift than their commitment amount');
+ }
+ break;
+ case NotificationTypeTypeEnum.SPECIAL_GIFT:
+ if (amount) {
+ message = t('Gave a special gift of {{ amount, currency }}', {
+ amount,
+ });
+ } else {
+ message = t('Gave a special gift');
+ }
+ break;
+ case NotificationTypeTypeEnum.STARTED_GIVING:
+ message = t('Started giving');
+ break;
+ case NotificationTypeTypeEnum.STOPPED_GIVING:
+ message = t('Missed a gift');
+ break;
+ case NotificationTypeTypeEnum.THANK_PARTNER_ONCE_PER_YEAR:
+ message = t('No thank you note logged in the past year');
+ break;
+ case NotificationTypeTypeEnum.UPCOMING_ANNIVERSARY:
+ message = t('Upcoming anniversary');
+ break;
+ case NotificationTypeTypeEnum.UPCOMING_BIRTHDAY:
+ message = t('Upcoming birthday');
+ break;
+ default:
+ message = item.notification.notificationType.descriptionTemplate;
+ break;
+ }
+
+ return (
+
+ {previousItem?.notification?.occurredAt &&
+ !isSameMonth(
+ new Date(previousItem.notification.occurredAt),
+ new Date(item.notification.occurredAt),
+ ) && (
+
+ {monthYearFormat(
+ new Date(item.notification.occurredAt).getMonth(),
+ new Date(item.notification.occurredAt).getFullYear(),
+ )}
+
+ )}
+
+
+
+
+ {item.notification.contact.name[0]}
+
+
+
+
+ {dateFormat(new Date(item.notification.occurredAt))}
+ {' '}
+ — {message}
+ >
+ }
+ />
+
+
+ {!last && }
+
+ );
};
export default NotificationMenuItem;
diff --git a/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.mock.tsx b/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.mock.tsx
index 323d1b4169..319b7727d0 100644
--- a/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.mock.tsx
+++ b/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.mock.tsx
@@ -7,175 +7,179 @@ import { ACKNOWLEDGE_ALL_USER_NOTIFICATIONS_MUTATION } from './NotificationMenu'
import GET_NOTIFICATIONS_QUERY from './getNotificationsQuery.graphql';
export const getNotificationsMocks = (): MockedResponse[] => {
- const data: GetNotificationsQuery = {
- userNotifications: {
- edges: [
- {
- node: {
- id: 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b',
- read: false,
- notification: {
- occurredAt: '2020-05-25T20:00:00-04:00',
- contact: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
- name: 'Smith, Roger',
- },
- donation: null,
- notificationType: {
- id: '6eb32493-c51b-490a-955d-595642160a95',
- type: NotificationTypeTypeEnum.UPCOMING_ANNIVERSARY,
- descriptionTemplate: 'Partner has upcoming anniversary',
- },
- },
- },
- },
- {
- node: {
- id: '5055f90b-fb09-4bf2-bbcd-09f29aeb5147',
- read: true,
- notification: {
- occurredAt: '2020-05-25T20:00:00-04:00',
- contact: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbce',
- name: 'Robertson, Tara',
- },
- donation: null,
- notificationType: {
- id: '577da384-5452-4501-9ec5-d5b2754d29ae',
- type: NotificationTypeTypeEnum.UPCOMING_BIRTHDAY,
- descriptionTemplate: 'Partner has upcoming birthday',
- },
- },
- },
- },
- ],
- pageInfo: { endCursor: 'Mg', hasNextPage: true },
- unreadCount: 2,
- },
- };
- const mock = {
- request: {
- query: GET_NOTIFICATIONS_QUERY,
- variables: {
- accountListId: '1',
- after: null,
+ const data: GetNotificationsQuery = {
+ userNotifications: {
+ edges: [
+ {
+ node: {
+ id: 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b',
+ read: false,
+ notification: {
+ occurredAt: '2020-05-25T20:00:00-04:00',
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
+ name: 'Smith, Roger',
+ },
+ donation: null,
+ notificationType: {
+ id: '6eb32493-c51b-490a-955d-595642160a95',
+ type: NotificationTypeTypeEnum.UPCOMING_ANNIVERSARY,
+ descriptionTemplate: 'Partner has upcoming anniversary',
+ },
},
+ },
},
- result: {
- data,
- },
- };
- const data2: GetNotificationsQuery = {
- userNotifications: {
- edges: [
- {
- node: {
- id: 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7z',
- read: false,
- notification: {
- occurredAt: '2020-05-25T20:00:00-04:00',
- contact: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbcx',
- name: 'Johnson, Ryan',
- },
- donation: null,
- notificationType: {
- id: '6eb32493-c51b-490a-955d-595642160a9l',
- type: NotificationTypeTypeEnum.UPCOMING_ANNIVERSARY,
- descriptionTemplate: 'Partner has upcoming anniversary',
- },
- },
- },
- },
- {
- node: {
- id: '5055f90b-fb09-4bf2-bbcd-09f29aeb514e',
- read: true,
- notification: {
- occurredAt: '2020-05-25T20:00:00-04:00',
- contact: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbcl',
- name: 'Michaelson, Michelle',
- },
- donation: null,
- notificationType: {
- id: '577da384-5452-4501-9ec5-d5b2754d29sh',
- type: NotificationTypeTypeEnum.UPCOMING_BIRTHDAY,
- descriptionTemplate: 'Partner has upcoming birthday',
- },
- },
- },
- },
- ],
- pageInfo: { endCursor: 'Np', hasNextPage: false },
- unreadCount: 2,
+ {
+ node: {
+ id: '5055f90b-fb09-4bf2-bbcd-09f29aeb5147',
+ read: true,
+ notification: {
+ occurredAt: '2020-05-25T20:00:00-04:00',
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbce',
+ name: 'Robertson, Tara',
+ },
+ donation: null,
+ notificationType: {
+ id: '577da384-5452-4501-9ec5-d5b2754d29ae',
+ type: NotificationTypeTypeEnum.UPCOMING_BIRTHDAY,
+ descriptionTemplate: 'Partner has upcoming birthday',
+ },
+ },
+ },
},
- };
- const mock2 = {
- request: {
- query: GET_NOTIFICATIONS_QUERY,
- variables: {
- accountListId: '1',
- after: 'Mg',
+ ],
+ pageInfo: { endCursor: 'Mg', hasNextPage: true },
+ unreadCount: 2,
+ },
+ };
+ const mock = {
+ request: {
+ query: GET_NOTIFICATIONS_QUERY,
+ variables: {
+ accountListId: '1',
+ after: null,
+ },
+ },
+ result: {
+ data,
+ },
+ };
+ const data2: GetNotificationsQuery = {
+ userNotifications: {
+ edges: [
+ {
+ node: {
+ id: 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7z',
+ read: false,
+ notification: {
+ occurredAt: '2020-05-25T20:00:00-04:00',
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbcx',
+ name: 'Johnson, Ryan',
+ },
+ donation: null,
+ notificationType: {
+ id: '6eb32493-c51b-490a-955d-595642160a9l',
+ type: NotificationTypeTypeEnum.UPCOMING_ANNIVERSARY,
+ descriptionTemplate: 'Partner has upcoming anniversary',
+ },
},
+ },
},
- result: {
- data: data2,
+ {
+ node: {
+ id: '5055f90b-fb09-4bf2-bbcd-09f29aeb514e',
+ read: true,
+ notification: {
+ occurredAt: '2020-05-25T20:00:00-04:00',
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbcl',
+ name: 'Michaelson, Michelle',
+ },
+ donation: null,
+ notificationType: {
+ id: '577da384-5452-4501-9ec5-d5b2754d29sh',
+ type: NotificationTypeTypeEnum.UPCOMING_BIRTHDAY,
+ descriptionTemplate: 'Partner has upcoming birthday',
+ },
+ },
+ },
},
- };
- return [
- mock,
- mock2,
- acknowledgeUserNotificationMutationMock(data.userNotifications.edges[0].node.id),
- acknowledgeUserNotificationMutationMock(data.userNotifications.edges[1].node.id),
- ];
+ ],
+ pageInfo: { endCursor: 'Np', hasNextPage: false },
+ unreadCount: 2,
+ },
+ };
+ const mock2 = {
+ request: {
+ query: GET_NOTIFICATIONS_QUERY,
+ variables: {
+ accountListId: '1',
+ after: 'Mg',
+ },
+ },
+ result: {
+ data: data2,
+ },
+ };
+ return [
+ mock,
+ mock2,
+ acknowledgeUserNotificationMutationMock(
+ data.userNotifications.edges[0].node.id,
+ ),
+ acknowledgeUserNotificationMutationMock(
+ data.userNotifications.edges[1].node.id,
+ ),
+ ];
};
export const getNotificationsEmptyMock = (): MockedResponse => {
- const data: GetNotificationsQuery = {
- userNotifications: {
- edges: [],
- pageInfo: { endCursor: null, hasNextPage: false },
- unreadCount: 0,
- },
- };
- return {
- request: {
- query: GET_NOTIFICATIONS_QUERY,
- variables: {
- after: null,
- accountListId: '1',
- },
- },
- result: {
- data,
- },
- };
+ const data: GetNotificationsQuery = {
+ userNotifications: {
+ edges: [],
+ pageInfo: { endCursor: null, hasNextPage: false },
+ unreadCount: 0,
+ },
+ };
+ return {
+ request: {
+ query: GET_NOTIFICATIONS_QUERY,
+ variables: {
+ after: null,
+ accountListId: '1',
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export const getNotificationsLoadingMock = (): MockedResponse => {
- return {
- ...getNotificationsEmptyMock(),
- delay: 100931731455,
- };
+ return {
+ ...getNotificationsEmptyMock(),
+ delay: 100931731455,
+ };
};
export const acknowledgeAllUserNotificationsMutationMock = (): MockedResponse => {
- const data: AcknowledgeAllUserNotificationsMutation = {
- acknowledgeAllUserNotifications: {
- notificationIds: ['d1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b'],
- },
- };
+ const data: AcknowledgeAllUserNotificationsMutation = {
+ acknowledgeAllUserNotifications: {
+ notificationIds: ['d1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b'],
+ },
+ };
- return {
- request: {
- query: ACKNOWLEDGE_ALL_USER_NOTIFICATIONS_MUTATION,
- variables: {
- accountListId: '1',
- },
- },
- result: {
- data,
- },
- };
+ return {
+ request: {
+ query: ACKNOWLEDGE_ALL_USER_NOTIFICATIONS_MUTATION,
+ variables: {
+ accountListId: '1',
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
diff --git a/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.stories.tsx b/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.stories.tsx
index 4a5ef6190f..371c38c093 100644
--- a/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.stories.tsx
+++ b/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.stories.tsx
@@ -3,64 +3,70 @@ import { MockedProvider } from '@apollo/client/testing';
import { AppBar, Box } from '@material-ui/core';
import withDispatch from '../../../../../decorators/withDispatch';
import {
- getNotificationsMocks,
- getNotificationsEmptyMock,
- getNotificationsLoadingMock,
- acknowledgeAllUserNotificationsMutationMock,
+ getNotificationsMocks,
+ getNotificationsEmptyMock,
+ getNotificationsLoadingMock,
+ acknowledgeAllUserNotificationsMutationMock,
} from './NotificationMenu.mock';
import NotificationMenu from '.';
export default {
- title: 'Layouts/Primary/TopBar/NotificationMenu',
- decorators: [
- withDispatch(
- { type: 'updateAccountListId', accountListId: '1' },
- { type: 'updateBreadcrumb', breadcrumb: 'Dashboard' },
- ),
- ],
+ title: 'Layouts/Primary/TopBar/NotificationMenu',
+ decorators: [
+ withDispatch(
+ { type: 'updateAccountListId', accountListId: '1' },
+ { type: 'updateBreadcrumb', breadcrumb: 'Dashboard' },
+ ),
+ ],
};
export const Default = (): ReactElement => {
- return (
- <>
-
-
-
-
-
-
-
- >
- );
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ );
};
export const Empty = (): ReactElement => {
- return (
- <>
-
-
-
-
-
-
-
- >
- );
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ );
};
export const Loading = (): ReactElement => {
- return (
- <>
-
-
-
-
-
-
-
- >
- );
+ return (
+ <>
+
+
+
+
+
+
+
+ >
+ );
};
diff --git a/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.test.tsx b/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.test.tsx
index ac77647fce..dc873e8bef 100644
--- a/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.test.tsx
+++ b/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.test.tsx
@@ -1,109 +1,144 @@
import React from 'react';
import userEvent from '@testing-library/user-event';
import { InMemoryCache } from '@apollo/client';
-import { render, waitFor } from '../../../../../../__tests__/util/testingLibraryReactMock';
+import {
+ render,
+ waitFor,
+} from '../../../../../../__tests__/util/testingLibraryReactMock';
import TestWrapper from '../../../../../../__tests__/util/TestWrapper';
import {
- acknowledgeAllUserNotificationsMutationMock,
- getNotificationsEmptyMock,
- getNotificationsLoadingMock,
- getNotificationsMocks,
+ acknowledgeAllUserNotificationsMutationMock,
+ getNotificationsEmptyMock,
+ getNotificationsLoadingMock,
+ getNotificationsMocks,
} from './NotificationMenu.mock';
import GET_NOTIFICATIONS_QUERY from './getNotificationsQuery.graphql';
import NotificationMenu from '.';
describe('NotificationMenu', () => {
- it('default', async () => {
- const cache = new InMemoryCache({ addTypename: false });
- jest.spyOn(cache, 'writeQuery');
- const { getByRole, queryByRole } = render(
-
-
- ,
- );
- userEvent.click(getByRole('button'));
- await waitFor(() => expect(getByRole('button', { name: 'Load More' })).toBeInTheDocument());
- expect(getByRole('button', { name: 'S Smith, Roger May 26, 2020 — Upcoming anniversary' })).toBeInTheDocument();
- expect(getByRole('button', { name: 'R Robertson, Tara May 26, 2020 — Upcoming birthday' })).toBeInTheDocument();
- userEvent.click(getByRole('button', { name: 'Load More' }));
- await waitFor(() => expect(queryByRole('button', { name: 'Load More' })).not.toBeInTheDocument());
- userEvent.click(getByRole('button', { name: 'Mark all as read' }));
- await waitFor(() =>
- expect(cache.writeQuery).toHaveBeenCalledWith({
- query: GET_NOTIFICATIONS_QUERY,
- variables: {
- accountListId: '1',
- after: null,
+ it('default', async () => {
+ const cache = new InMemoryCache({ addTypename: false });
+ jest.spyOn(cache, 'writeQuery');
+ const { getByRole, queryByRole } = render(
+
+
+ ,
+ );
+ userEvent.click(getByRole('button'));
+ await waitFor(() =>
+ expect(getByRole('button', { name: 'Load More' })).toBeInTheDocument(),
+ );
+ expect(
+ getByRole('button', {
+ name: 'S Smith, Roger May 26, 2020 — Upcoming anniversary',
+ }),
+ ).toBeInTheDocument();
+ expect(
+ getByRole('button', {
+ name: 'R Robertson, Tara May 26, 2020 — Upcoming birthday',
+ }),
+ ).toBeInTheDocument();
+ userEvent.click(getByRole('button', { name: 'Load More' }));
+ await waitFor(() =>
+ expect(
+ queryByRole('button', { name: 'Load More' }),
+ ).not.toBeInTheDocument(),
+ );
+ userEvent.click(getByRole('button', { name: 'Mark all as read' }));
+ await waitFor(() =>
+ expect(cache.writeQuery).toHaveBeenCalledWith({
+ query: GET_NOTIFICATIONS_QUERY,
+ variables: {
+ accountListId: '1',
+ after: null,
+ },
+ data: {
+ userNotifications: {
+ edges: [
+ {
+ node: {
+ id: 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b',
+ read: true,
+ notification: {
+ occurredAt: '2020-05-25T20:00:00-04:00',
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbc7',
+ name: 'Smith, Roger',
+ },
+ donation: null,
+ notificationType: {
+ id: '6eb32493-c51b-490a-955d-595642160a95',
+ type: 'UPCOMING_ANNIVERSARY',
+ descriptionTemplate: 'Partner has upcoming anniversary',
+ },
+ },
},
- data: {
- userNotifications: {
- edges: [
- {
- node: {
- id: 'd1b7a8c1-9b2e-4234-b2d6-e52c151bbc7b',
- read: true,
- notification: {
- occurredAt: '2020-05-25T20:00:00-04:00',
- contact: { id: '942ea954-c251-44d6-8166-7a1879ecdbc7', name: 'Smith, Roger' },
- donation: null,
- notificationType: {
- id: '6eb32493-c51b-490a-955d-595642160a95',
- type: 'UPCOMING_ANNIVERSARY',
- descriptionTemplate: 'Partner has upcoming anniversary',
- },
- },
- },
- },
- {
- node: {
- id: '5055f90b-fb09-4bf2-bbcd-09f29aeb5147',
- read: true,
- notification: {
- occurredAt: '2020-05-25T20:00:00-04:00',
- contact: {
- id: '942ea954-c251-44d6-8166-7a1879ecdbce',
- name: 'Robertson, Tara',
- },
- donation: null,
- notificationType: {
- id: '577da384-5452-4501-9ec5-d5b2754d29ae',
- type: 'UPCOMING_BIRTHDAY',
- descriptionTemplate: 'Partner has upcoming birthday',
- },
- },
- },
- },
- ],
- pageInfo: { endCursor: 'Mg', hasNextPage: true },
- unreadCount: 0,
+ },
+ {
+ node: {
+ id: '5055f90b-fb09-4bf2-bbcd-09f29aeb5147',
+ read: true,
+ notification: {
+ occurredAt: '2020-05-25T20:00:00-04:00',
+ contact: {
+ id: '942ea954-c251-44d6-8166-7a1879ecdbce',
+ name: 'Robertson, Tara',
+ },
+ donation: null,
+ notificationType: {
+ id: '577da384-5452-4501-9ec5-d5b2754d29ae',
+ type: 'UPCOMING_BIRTHDAY',
+ descriptionTemplate: 'Partner has upcoming birthday',
},
+ },
},
- }),
- );
- expect(queryByRole('button', { name: 'Mark all as read' })).not.toBeInTheDocument();
- });
+ },
+ ],
+ pageInfo: { endCursor: 'Mg', hasNextPage: true },
+ unreadCount: 0,
+ },
+ },
+ }),
+ );
+ expect(
+ queryByRole('button', { name: 'Mark all as read' }),
+ ).not.toBeInTheDocument();
+ });
- it('loading', async () => {
- const { getByRole, getByTestId } = render(
-
-
- ,
- );
- userEvent.click(getByRole('button'));
- await waitFor(() => expect(getByTestId('NotificationMenuLoading')).toBeInTheDocument());
- });
+ it('loading', async () => {
+ const { getByRole, getByTestId } = render(
+
+
+ ,
+ );
+ userEvent.click(getByRole('button'));
+ await waitFor(() =>
+ expect(getByTestId('NotificationMenuLoading')).toBeInTheDocument(),
+ );
+ });
- it('empty', async () => {
- const { getByRole, getByText } = render(
-
-
- ,
- );
- userEvent.click(getByRole('button'));
- await waitFor(() => expect(getByText('No notifications to show.')).toBeInTheDocument());
- });
+ it('empty', async () => {
+ const { getByRole, getByText } = render(
+
+
+ ,
+ );
+ userEvent.click(getByRole('button'));
+ await waitFor(() =>
+ expect(getByText('No notifications to show.')).toBeInTheDocument(),
+ );
+ });
});
diff --git a/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.tsx b/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.tsx
index 6ce3436b03..646c878639 100644
--- a/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.tsx
+++ b/src/components/Layouts/Primary/TopBar/NotificationMenu/NotificationMenu.tsx
@@ -1,4 +1,14 @@
-import { Badge, Box, Button, IconButton, ListItem, ListSubheader, makeStyles, Menu, Theme } from '@material-ui/core';
+import {
+ Badge,
+ Box,
+ Button,
+ IconButton,
+ ListItem,
+ ListSubheader,
+ makeStyles,
+ Menu,
+ Theme,
+} from '@material-ui/core';
import React, { ReactElement, useEffect, useState } from 'react';
import NotificationsIcon from '@material-ui/icons/Notifications';
import { gql, useMutation, useLazyQuery } from '@apollo/client';
@@ -12,197 +22,208 @@ import NotificationMenuItem from './Item';
import GET_NOTIFICATIONS_QUERY from './getNotificationsQuery.graphql';
const useStyles = makeStyles((theme: Theme) => ({
- link: {
- textTransform: 'none',
- color: 'rgba(255,255,255,0.75)',
- transition: 'color 0.2s ease-in-out',
- '&:hover': {
- color: 'rgba(255,255,255,1)',
- },
- },
- menuPaper: {
- width: '50ch',
- [theme.breakpoints.down('xs')]: {
- width: '100%',
- },
- },
- menuList: {
- padding: 0,
- },
- menuButton: {
- width: '100%',
- marginBottom: theme.spacing(1),
- },
- listSubheader: {
- outline: 0,
- backgroundColor: theme.palette.background.paper,
- zIndex: 2,
+ link: {
+ textTransform: 'none',
+ color: 'rgba(255,255,255,0.75)',
+ transition: 'color 0.2s ease-in-out',
+ '&:hover': {
+ color: 'rgba(255,255,255,1)',
},
- listItemEmpty: {
- flexDirection: 'column',
- paddingBottom: theme.spacing(2),
- },
- img: {
- height: '150px',
- marginBottom: theme.spacing(2),
+ },
+ menuPaper: {
+ width: '50ch',
+ [theme.breakpoints.down('xs')]: {
+ width: '100%',
},
+ },
+ menuList: {
+ padding: 0,
+ },
+ menuButton: {
+ width: '100%',
+ marginBottom: theme.spacing(1),
+ },
+ listSubheader: {
+ outline: 0,
+ backgroundColor: theme.palette.background.paper,
+ zIndex: 2,
+ },
+ listItemEmpty: {
+ flexDirection: 'column',
+ paddingBottom: theme.spacing(2),
+ },
+ img: {
+ height: '150px',
+ marginBottom: theme.spacing(2),
+ },
}));
export const ACKNOWLEDGE_ALL_USER_NOTIFICATIONS_MUTATION = gql`
- mutation AcknowledgeAllUserNotificationsMutation($accountListId: ID!) {
- acknowledgeAllUserNotifications(input: { accountListId: $accountListId }) {
- notificationIds
- }
+ mutation AcknowledgeAllUserNotificationsMutation($accountListId: ID!) {
+ acknowledgeAllUserNotifications(input: { accountListId: $accountListId }) {
+ notificationIds
}
+ }
`;
const NotificationMenu = (): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const { state } = useApp();
- const [anchorEl, setAnchorEl] = useState(null);
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const { state } = useApp();
+ const [anchorEl, setAnchorEl] = useState(null);
- const [getNotifications, { data, loading, fetchMore }] = useLazyQuery(
- GET_NOTIFICATIONS_QUERY,
- { notifyOnNetworkStatusChange: true },
- );
+ const [
+ getNotifications,
+ { data, loading, fetchMore },
+ ] = useLazyQuery(GET_NOTIFICATIONS_QUERY, {
+ notifyOnNetworkStatusChange: true,
+ });
- const [acknoweldgeAllUserNotifications] = useMutation(
- ACKNOWLEDGE_ALL_USER_NOTIFICATIONS_MUTATION,
- );
+ const [
+ acknoweldgeAllUserNotifications,
+ ] = useMutation(
+ ACKNOWLEDGE_ALL_USER_NOTIFICATIONS_MUTATION,
+ );
- const handleAcknowledgeAllClick = () => {
- const optimisticResponse = true;
- acknoweldgeAllUserNotifications({
- variables: { accountListId: state.accountListId },
- optimisticResponse: {
- acknowledgeAllUserNotifications: {
- notificationIds: [],
- },
- },
- update: (cache) => {
- console.log(cache);
- if (!optimisticResponse) return;
+ const handleAcknowledgeAllClick = () => {
+ const optimisticResponse = true;
+ acknoweldgeAllUserNotifications({
+ variables: { accountListId: state.accountListId },
+ optimisticResponse: {
+ acknowledgeAllUserNotifications: {
+ notificationIds: [],
+ },
+ },
+ update: (cache) => {
+ console.log(cache);
+ if (!optimisticResponse) return;
- const query = {
- query: GET_NOTIFICATIONS_QUERY,
- variables: {
- accountListId: state.accountListId,
- after: null,
- },
- };
- const data = cloneDeep(cache.readQuery(query));
- data.userNotifications.unreadCount = 0;
- data.userNotifications.edges = data.userNotifications.edges.map(({ node }) => ({
- node: {
- ...node,
- read: true,
- },
- }));
- cache.writeQuery({ ...query, data });
+ const query = {
+ query: GET_NOTIFICATIONS_QUERY,
+ variables: {
+ accountListId: state.accountListId,
+ after: null,
+ },
+ };
+ const data = cloneDeep(cache.readQuery(query));
+ data.userNotifications.unreadCount = 0;
+ data.userNotifications.edges = data.userNotifications.edges.map(
+ ({ node }) => ({
+ node: {
+ ...node,
+ read: true,
},
- });
- handleClose();
- };
+ }),
+ );
+ cache.writeQuery({ ...query, data });
+ },
+ });
+ handleClose();
+ };
- const handleClick = (event) => {
- setAnchorEl(event.currentTarget);
- };
+ const handleClick = (event) => {
+ setAnchorEl(event.currentTarget);
+ };
- const handleClose = () => {
- setAnchorEl(null);
- };
+ const handleClose = () => {
+ setAnchorEl(null);
+ };
- const handleFetchMore = () => {
- fetchMore({
- variables: { after: data.userNotifications.pageInfo.endCursor },
- });
- };
+ const handleFetchMore = () => {
+ fetchMore({
+ variables: { after: data.userNotifications.pageInfo.endCursor },
+ });
+ };
- useEffect(() => {
- if (state?.accountListId) {
- getNotifications({
- variables: {
- accountListId: state.accountListId,
- after: null,
- },
- });
- }
- }, [state?.accountListId]);
+ useEffect(() => {
+ if (state?.accountListId) {
+ getNotifications({
+ variables: {
+ accountListId: state.accountListId,
+ after: null,
+ },
+ });
+ }
+ }, [state?.accountListId]);
- return (
- <>
-
-
-
-
-
-
+ >
+ );
};
export default NotificationMenu;
diff --git a/src/components/Layouts/Primary/TopBar/NotificationMenu/getNotificationsQuery.graphql b/src/components/Layouts/Primary/TopBar/NotificationMenu/getNotificationsQuery.graphql
index f6651c6267..d77bf8de02 100644
--- a/src/components/Layouts/Primary/TopBar/NotificationMenu/getNotificationsQuery.graphql
+++ b/src/components/Layouts/Primary/TopBar/NotificationMenu/getNotificationsQuery.graphql
@@ -1,35 +1,35 @@
query GetNotificationsQuery($accountListId: ID!, $after: String) {
- userNotifications(accountListId: $accountListId, after: $after, first: 20) {
- edges {
- node {
- id
- read
- notification {
- occurredAt
- contact {
- id
- name
- }
- donation {
- id
- amount {
- amount
- currency
- conversionDate
- }
- }
- notificationType {
- id
- type
- descriptionTemplate
- }
- }
+ userNotifications(accountListId: $accountListId, after: $after, first: 20) {
+ edges {
+ node {
+ id
+ read
+ notification {
+ occurredAt
+ contact {
+ id
+ name
+ }
+ donation {
+ id
+ amount {
+ amount
+ currency
+ conversionDate
}
+ }
+ notificationType {
+ id
+ type
+ descriptionTemplate
+ }
}
- pageInfo {
- endCursor
- hasNextPage
- }
- unreadCount
+ }
+ }
+ pageInfo {
+ endCursor
+ hasNextPage
}
+ unreadCount
+ }
}
diff --git a/src/components/Layouts/Primary/TopBar/TopBar.mock.tsx b/src/components/Layouts/Primary/TopBar/TopBar.mock.tsx
index 5dbca2060c..c97538ad44 100644
--- a/src/components/Layouts/Primary/TopBar/TopBar.mock.tsx
+++ b/src/components/Layouts/Primary/TopBar/TopBar.mock.tsx
@@ -3,58 +3,58 @@ import { GetTopBarQuery } from '../../../../../types/GetTopBarQuery';
import { GET_TOP_BAR_QUERY } from './TopBar';
export const getTopBarMock = (): MockedResponse => {
- const data: GetTopBarQuery = {
- accountLists: {
- nodes: [{ id: '1', name: 'Staff Account' }],
- },
- user: {
- id: 'user-1',
- firstName: 'John',
- lastName: 'Smith',
- admin: true,
- developer: true,
- keyAccounts: [{ id: '1', email: 'john.smith@gmail.com' }],
- administrativeOrganizations: {
- nodes: [{ id: '1' }],
- },
- },
- };
- return {
- request: {
- query: GET_TOP_BAR_QUERY,
- },
- result: {
- data,
- },
- };
+ const data: GetTopBarQuery = {
+ accountLists: {
+ nodes: [{ id: '1', name: 'Staff Account' }],
+ },
+ user: {
+ id: 'user-1',
+ firstName: 'John',
+ lastName: 'Smith',
+ admin: true,
+ developer: true,
+ keyAccounts: [{ id: '1', email: 'john.smith@gmail.com' }],
+ administrativeOrganizations: {
+ nodes: [{ id: '1' }],
+ },
+ },
+ };
+ return {
+ request: {
+ query: GET_TOP_BAR_QUERY,
+ },
+ result: {
+ data,
+ },
+ };
};
export const getTopBarMultipleMock = (): MockedResponse => {
- const data: GetTopBarQuery = {
- accountLists: {
- nodes: [
- { id: '1', name: 'Staff Account' },
- { id: '2', name: 'Ministry Account' },
- ],
- },
- user: {
- id: 'user-1',
- firstName: 'John',
- lastName: 'Smith',
- admin: false,
- developer: false,
- keyAccounts: [{ id: '1', email: 'john.smith@gmail.com' }],
- administrativeOrganizations: {
- nodes: [],
- },
- },
- };
- return {
- request: {
- query: GET_TOP_BAR_QUERY,
- },
- result: {
- data,
- },
- };
+ const data: GetTopBarQuery = {
+ accountLists: {
+ nodes: [
+ { id: '1', name: 'Staff Account' },
+ { id: '2', name: 'Ministry Account' },
+ ],
+ },
+ user: {
+ id: 'user-1',
+ firstName: 'John',
+ lastName: 'Smith',
+ admin: false,
+ developer: false,
+ keyAccounts: [{ id: '1', email: 'john.smith@gmail.com' }],
+ administrativeOrganizations: {
+ nodes: [],
+ },
+ },
+ };
+ return {
+ request: {
+ query: GET_TOP_BAR_QUERY,
+ },
+ result: {
+ data,
+ },
+ };
};
diff --git a/src/components/Layouts/Primary/TopBar/TopBar.stories.tsx b/src/components/Layouts/Primary/TopBar/TopBar.stories.tsx
index c5a2424406..c08c1c94b2 100644
--- a/src/components/Layouts/Primary/TopBar/TopBar.stories.tsx
+++ b/src/components/Layouts/Primary/TopBar/TopBar.stories.tsx
@@ -7,55 +7,55 @@ import { getTopBarMock, getTopBarMultipleMock } from './TopBar.mock';
import TopBar from '.';
export default {
- title: 'Layouts/Primary/TopBar',
- decorators: [
- withDispatch(
- { type: 'updateAccountListId', accountListId: '1' },
- { type: 'updateBreadcrumb', breadcrumb: 'Dashboard' },
- ),
- ],
+ title: 'Layouts/Primary/TopBar',
+ decorators: [
+ withDispatch(
+ { type: 'updateAccountListId', accountListId: '1' },
+ { type: 'updateBreadcrumb', breadcrumb: 'Dashboard' },
+ ),
+ ],
};
const Content = (): ReactElement => (
- <>
-
-
-
- {[...new Array(50)]
- .map(
- () => `Cras mattis consectetur purus sit amet fermentum.
+ <>
+
+
+
+ {[...new Array(50)]
+ .map(
+ () => `Cras mattis consectetur purus sit amet fermentum.
Cras justo odio, dapibus ac facilisis in, egestas eget quam.
Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
Praesent commodo cursus magna, vel scelerisque nisl consectetur et.`,
- )
- .join('\n')}
-
-
- >
+ )
+ .join('\n')}
+
+
+ >
);
export const Default = (): ReactElement => {
- const mocks = [getTopBarMock(), ...getNotificationsMocks()];
+ const mocks = [getTopBarMock(), ...getNotificationsMocks()];
- return (
- <>
-
- {}} />
-
-
- >
- );
+ return (
+ <>
+
+ {}} />
+
+
+ >
+ );
};
export const MultipleAccountLists = (): ReactElement => {
- const mocks = [getTopBarMultipleMock(), ...getNotificationsMocks()];
+ const mocks = [getTopBarMultipleMock(), ...getNotificationsMocks()];
- return (
- <>
-
- {}} />
-
-
- >
- );
+ return (
+ <>
+
+ {}} />
+
+
+ >
+ );
};
diff --git a/src/components/Layouts/Primary/TopBar/TopBar.test.tsx b/src/components/Layouts/Primary/TopBar/TopBar.test.tsx
index 19f282ef10..c211e806ce 100644
--- a/src/components/Layouts/Primary/TopBar/TopBar.test.tsx
+++ b/src/components/Layouts/Primary/TopBar/TopBar.test.tsx
@@ -14,112 +14,122 @@ let state: AppState;
const dispatch = jest.fn();
jest.mock('../../../App', () => ({
- useApp: jest.fn(),
+ useApp: jest.fn(),
}));
describe('TopBar', () => {
- let mocks;
- beforeEach(() => {
- mocks = [getTopBarMultipleMock(), ...getNotificationsMocks()];
- state = { accountListId: null, breadcrumb: null };
- (useApp as jest.Mock).mockReturnValue({
- state,
- dispatch,
- });
+ let mocks;
+ beforeEach(() => {
+ mocks = [getTopBarMultipleMock(), ...getNotificationsMocks()];
+ state = { accountListId: null, breadcrumb: null };
+ (useApp as jest.Mock).mockReturnValue({
+ state,
+ dispatch,
});
+ });
- it('has correct defaults', () => {
- const { queryByTestId, queryByText, getByTestId } = render(
-
-
- ,
- );
- expect(queryByTestId('TopBarBreadcrumb')).not.toBeInTheDocument();
- userEvent.click(getByTestId('profileMenuButton'));
- expect(queryByText('Manage Organizations')).not.toBeInTheDocument();
- expect(queryByText('Admin Console')).not.toBeInTheDocument();
- expect(queryByText('Backend Admin')).not.toBeInTheDocument();
- expect(queryByText('Sidekiq')).not.toBeInTheDocument();
- });
+ it('has correct defaults', () => {
+ const { queryByTestId, queryByText, getByTestId } = render(
+
+
+ ,
+ );
+ expect(queryByTestId('TopBarBreadcrumb')).not.toBeInTheDocument();
+ userEvent.click(getByTestId('profileMenuButton'));
+ expect(queryByText('Manage Organizations')).not.toBeInTheDocument();
+ expect(queryByText('Admin Console')).not.toBeInTheDocument();
+ expect(queryByText('Backend Admin')).not.toBeInTheDocument();
+ expect(queryByText('Sidekiq')).not.toBeInTheDocument();
+ });
- describe('client state set', () => {
- beforeEach(() => {
- matchMediaMock({ width: '1024px' });
- state = { accountListId: '1', breadcrumb: 'Dashboard' };
- (useApp as jest.Mock).mockReturnValue({
- state,
- dispatch,
- });
- });
+ describe('client state set', () => {
+ beforeEach(() => {
+ matchMediaMock({ width: '1024px' });
+ state = { accountListId: '1', breadcrumb: 'Dashboard' };
+ (useApp as jest.Mock).mockReturnValue({
+ state,
+ dispatch,
+ });
+ });
- it('adjusts menu configuration', async () => {
- const { getByTestId, queryByTestId } = render(
-
-
-
-
- ,
- );
- expect(getByTestId('TopBarBreadcrumb').textContent).toEqual('Dashboard');
- await waitFor(() => expect(getByTestId('TopBarButton')).toBeInTheDocument());
- fireEvent.click(getByTestId('TopBarButton'));
- await waitFor(() => expect(getByTestId('TopBarMenu')).toBeInTheDocument());
- const TopBarMenuItem1 = getByTestId('TopBarMenuItem1');
- expect(TopBarMenuItem1.textContent).toEqual('Staff Account');
- expect(TopBarMenuItem1).toHaveClass('Mui-selected');
- fireEvent.click(TopBarMenuItem1);
- await waitFor(() => expect(queryByTestId('TopBarMenu')).not.toBeInTheDocument());
- expect(dispatch).toHaveBeenCalledWith({
- type: 'updateUser',
- user: {
- id: 'user-1',
- firstName: 'John',
- lastName: 'Smith',
- admin: false,
- developer: false,
- keyAccounts: [{ id: '1', email: 'john.smith@gmail.com' }],
- administrativeOrganizations: {
- nodes: [],
- },
- },
- });
- });
+ it('adjusts menu configuration', async () => {
+ const { getByTestId, queryByTestId } = render(
+
+
+
+
+ ,
+ );
+ expect(getByTestId('TopBarBreadcrumb').textContent).toEqual('Dashboard');
+ await waitFor(() =>
+ expect(getByTestId('TopBarButton')).toBeInTheDocument(),
+ );
+ fireEvent.click(getByTestId('TopBarButton'));
+ await waitFor(() =>
+ expect(getByTestId('TopBarMenu')).toBeInTheDocument(),
+ );
+ const TopBarMenuItem1 = getByTestId('TopBarMenuItem1');
+ expect(TopBarMenuItem1.textContent).toEqual('Staff Account');
+ expect(TopBarMenuItem1).toHaveClass('Mui-selected');
+ fireEvent.click(TopBarMenuItem1);
+ await waitFor(() =>
+ expect(queryByTestId('TopBarMenu')).not.toBeInTheDocument(),
+ );
+ expect(dispatch).toHaveBeenCalledWith({
+ type: 'updateUser',
+ user: {
+ id: 'user-1',
+ firstName: 'John',
+ lastName: 'Smith',
+ admin: false,
+ developer: false,
+ keyAccounts: [{ id: '1', email: 'john.smith@gmail.com' }],
+ administrativeOrganizations: {
+ nodes: [],
+ },
+ },
+ });
});
+ });
- describe('single accountList', () => {
- beforeEach(() => {
- mocks = [getTopBarMock(), ...getNotificationsMocks()];
- state = { accountListId: '1', breadcrumb: 'Dashboard' };
- (useApp as jest.Mock).mockReturnValue({
- state,
- dispatch,
- });
- });
+ describe('single accountList', () => {
+ beforeEach(() => {
+ mocks = [getTopBarMock(), ...getNotificationsMocks()];
+ state = { accountListId: '1', breadcrumb: 'Dashboard' };
+ (useApp as jest.Mock).mockReturnValue({
+ state,
+ dispatch,
+ });
+ });
- it('shows single accountList name', async () => {
- const { getByTestId, getByText } = render(
-
-
- ,
- );
- await waitFor(() => expect(getByTestId('TopBarSingleAccountList').textContent).toEqual('Staff Account'));
- userEvent.click(getByTestId('profileMenuButton'));
- expect(getByText('Manage Organizations').parentElement.parentElement).toHaveAttribute(
- 'href',
- 'https://stage.mpdx.org/preferences/organizations',
- );
- expect(getByText('Admin Console').parentElement.parentElement).toHaveAttribute(
- 'href',
- 'https://stage.mpdx.org/preferences/admin',
- );
- expect(getByText('Backend Admin').parentElement.parentElement).toHaveAttribute(
- 'href',
- 'https://auth.stage.mpdx.org/auth/user/admin',
- );
- expect(getByText('Sidekiq').parentElement.parentElement).toHaveAttribute(
- 'href',
- 'https://auth.stage.mpdx.org/auth/user/sidekiq',
- );
- });
+ it('shows single accountList name', async () => {
+ const { getByTestId, getByText } = render(
+
+
+ ,
+ );
+ await waitFor(() =>
+ expect(getByTestId('TopBarSingleAccountList').textContent).toEqual(
+ 'Staff Account',
+ ),
+ );
+ userEvent.click(getByTestId('profileMenuButton'));
+ expect(
+ getByText('Manage Organizations').parentElement.parentElement,
+ ).toHaveAttribute(
+ 'href',
+ 'https://stage.mpdx.org/preferences/organizations',
+ );
+ expect(
+ getByText('Admin Console').parentElement.parentElement,
+ ).toHaveAttribute('href', 'https://stage.mpdx.org/preferences/admin');
+ expect(
+ getByText('Backend Admin').parentElement.parentElement,
+ ).toHaveAttribute('href', 'https://auth.stage.mpdx.org/auth/user/admin');
+ expect(getByText('Sidekiq').parentElement.parentElement).toHaveAttribute(
+ 'href',
+ 'https://auth.stage.mpdx.org/auth/user/sidekiq',
+ );
});
+ });
});
diff --git a/src/components/Layouts/Primary/TopBar/TopBar.tsx b/src/components/Layouts/Primary/TopBar/TopBar.tsx
index a4f2d1f3ec..0bc8fd6f20 100644
--- a/src/components/Layouts/Primary/TopBar/TopBar.tsx
+++ b/src/components/Layouts/Primary/TopBar/TopBar.tsx
@@ -1,23 +1,23 @@
import React, { ReactElement, useState, useEffect } from 'react';
import {
- Avatar,
- IconButton,
- Button,
- MenuItem,
- Box,
- Menu,
- ListSubheader,
- makeStyles,
- Toolbar,
- AppBar,
- useScrollTrigger,
- Theme,
- Grid,
- Hidden,
- ListItemText,
- Divider,
- ListItemAvatar,
- Link,
+ Avatar,
+ IconButton,
+ Button,
+ MenuItem,
+ Box,
+ Menu,
+ ListSubheader,
+ makeStyles,
+ Toolbar,
+ AppBar,
+ useScrollTrigger,
+ Theme,
+ Grid,
+ Hidden,
+ ListItemText,
+ Divider,
+ ListItemAvatar,
+ Link,
} from '@material-ui/core';
import { useQuery, gql } from '@apollo/client';
import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
@@ -36,396 +36,428 @@ import logo from '../../../../images/logo.svg';
import NotificationMenu from './NotificationMenu';
const useStyles = makeStyles((theme: Theme) => ({
- appBar: {
- paddingTop: `env(safe-area-inset-top)`,
- paddingLeft: `env(safe-area-inset-left)`,
- paddingRight: `env(safe-area-inset-right)`,
- backgroundColor: theme.palette.primary.main,
- width: 'auto',
- left: SIDE_BAR_MINIMIZED_WIDTH,
- [theme.breakpoints.down('sm')]: {
- left: 0,
- },
+ appBar: {
+ paddingTop: `env(safe-area-inset-top)`,
+ paddingLeft: `env(safe-area-inset-left)`,
+ paddingRight: `env(safe-area-inset-right)`,
+ backgroundColor: theme.palette.primary.main,
+ width: 'auto',
+ left: SIDE_BAR_MINIMIZED_WIDTH,
+ [theme.breakpoints.down('sm')]: {
+ left: 0,
},
- toolbar: {
- backgroundColor: theme.palette.primary.main,
+ },
+ toolbar: {
+ backgroundColor: theme.palette.primary.main,
+ },
+ container: {
+ minHeight: '48px',
+ },
+ sideBarGrid: {
+ order: 1,
+ },
+ accountListsGrid: {
+ order: 2,
+ [theme.breakpoints.down('xs')]: {
+ order: 6,
+ marginRight: theme.spacing(1),
},
- container: {
- minHeight: '48px',
+ },
+ breadcrumbGrid: {
+ order: 3,
+ marginLeft: theme.spacing(1),
+ height: '48px',
+ overflow: 'hidden',
+ flexGrow: 1,
+ },
+ helpGrid: {
+ order: 4,
+ [theme.breakpoints.down('xs')]: {
+ display: 'none',
},
- sideBarGrid: {
- order: 1,
+ },
+ notificationsGrid: {
+ order: 5,
+ },
+ avatarGrid: {
+ order: 6,
+ },
+ avatar: {
+ height: '32px',
+ width: '32px',
+ },
+ link: {
+ textTransform: 'none',
+ color: 'rgba(255,255,255,0.75)',
+ transition: 'color 0.2s ease-in-out',
+ '&:hover': {
+ color: 'rgba(255,255,255,1)',
},
- accountListsGrid: {
- order: 2,
- [theme.breakpoints.down('xs')]: {
- order: 6,
- marginRight: theme.spacing(1),
- },
- },
- breadcrumbGrid: {
- order: 3,
- marginLeft: theme.spacing(1),
- height: '48px',
- overflow: 'hidden',
- flexGrow: 1,
- },
- helpGrid: {
- order: 4,
- [theme.breakpoints.down('xs')]: {
- display: 'none',
- },
- },
- notificationsGrid: {
- order: 5,
- },
- avatarGrid: {
- order: 6,
- },
- avatar: {
- height: '32px',
- width: '32px',
- },
- link: {
- textTransform: 'none',
- color: 'rgba(255,255,255,0.75)',
- transition: 'color 0.2s ease-in-out',
- '&:hover': {
- color: 'rgba(255,255,255,1)',
- },
- },
- button: {
- textTransform: 'none',
- },
- breadcrumb: {
- fontWeight: 'bold',
- transform: 'translate(0, 48px)',
- transition: 'opacity .15s ease, transform .15s ease',
- lineHeight: '48px',
- opacity: 0,
- },
- breadcrumbTrigger: {
- transform: 'translate(0, 0)',
- opacity: 1,
- },
- menuList: {
- paddingTop: 0,
- },
- menuItemAccount: {
- paddingTop: 0,
- outline: 0,
- },
- menuItemFooter: {
- fontSize: theme.typography.body2.fontSize,
- justifyContent: 'center',
- paddingTop: theme.spacing(2),
- outline: 0,
- },
- menuButton: {
- width: '100%',
- marginTop: theme.spacing(1),
- },
- logo: {
- width: 70,
- transition: theme.transitions.create('margin-right', {
- duration: theme.transitions.duration.enteringScreen,
- }),
- marginRight: theme.spacing(2),
- '& img': {
- marginLeft: -13,
- },
- },
- logoOpen: {
- marginRight: SIDE_BAR_WIDTH - 70 - SIDE_BAR_MINIMIZED_WIDTH,
+ },
+ button: {
+ textTransform: 'none',
+ },
+ breadcrumb: {
+ fontWeight: 'bold',
+ transform: 'translate(0, 48px)',
+ transition: 'opacity .15s ease, transform .15s ease',
+ lineHeight: '48px',
+ opacity: 0,
+ },
+ breadcrumbTrigger: {
+ transform: 'translate(0, 0)',
+ opacity: 1,
+ },
+ menuList: {
+ paddingTop: 0,
+ },
+ menuItemAccount: {
+ paddingTop: 0,
+ outline: 0,
+ },
+ menuItemFooter: {
+ fontSize: theme.typography.body2.fontSize,
+ justifyContent: 'center',
+ paddingTop: theme.spacing(2),
+ outline: 0,
+ },
+ menuButton: {
+ width: '100%',
+ marginTop: theme.spacing(1),
+ },
+ logo: {
+ width: 70,
+ transition: theme.transitions.create('margin-right', {
+ duration: theme.transitions.duration.enteringScreen,
+ }),
+ marginRight: theme.spacing(2),
+ '& img': {
+ marginLeft: -13,
},
+ },
+ logoOpen: {
+ marginRight: SIDE_BAR_WIDTH - 70 - SIDE_BAR_MINIMIZED_WIDTH,
+ },
}));
export const GET_TOP_BAR_QUERY = gql`
- query GetTopBarQuery {
- accountLists {
- nodes {
- id
- name
- }
- }
- user {
- id
- firstName
- lastName
- admin
- developer
- keyAccounts {
- id
- email
- }
- administrativeOrganizations {
- nodes {
- id
- }
- }
+ query GetTopBarQuery {
+ accountLists {
+ nodes {
+ id
+ name
+ }
+ }
+ user {
+ id
+ firstName
+ lastName
+ admin
+ developer
+ keyAccounts {
+ id
+ email
+ }
+ administrativeOrganizations {
+ nodes {
+ id
}
+ }
}
+ }
`;
interface Props {
- open: boolean;
- handleOpenChange: (state?: boolean) => void;
+ open: boolean;
+ handleOpenChange: (state?: boolean) => void;
}
const TopBar = ({ open, handleOpenChange }: Props): ReactElement => {
- const classes = useStyles();
- const { dispatch, state } = useApp();
- const { t } = useTranslation();
- const trigger = useScrollTrigger({
- disableHysteresis: true,
- threshold: 0,
- });
- const { data } = useQuery(GET_TOP_BAR_QUERY);
- const [accountListMenuAnchorEl, setAccountListMenuAnchorEl] = useState(null);
- const accountListMenuOpen = Boolean(accountListMenuAnchorEl);
- const [profileMenuAnchorEl, setProfileMenuAnchorEl] = useState(null);
- const profileMenuOpen = Boolean(profileMenuAnchorEl);
+ const classes = useStyles();
+ const { dispatch, state } = useApp();
+ const { t } = useTranslation();
+ const trigger = useScrollTrigger({
+ disableHysteresis: true,
+ threshold: 0,
+ });
+ const { data } = useQuery(GET_TOP_BAR_QUERY);
+ const [accountListMenuAnchorEl, setAccountListMenuAnchorEl] = useState(null);
+ const accountListMenuOpen = Boolean(accountListMenuAnchorEl);
+ const [profileMenuAnchorEl, setProfileMenuAnchorEl] = useState(null);
+ const profileMenuOpen = Boolean(profileMenuAnchorEl);
- const handleAccountListMenuOpen = (event) => {
- setAccountListMenuAnchorEl(event.currentTarget);
- };
+ const handleAccountListMenuOpen = (event) => {
+ setAccountListMenuAnchorEl(event.currentTarget);
+ };
- const handleAccountListMenuClose = (accountListId?: string): void => {
- if (accountListId) {
- dispatch({ type: 'updateAccountListId', accountListId });
- }
- setAccountListMenuAnchorEl(null);
- };
+ const handleAccountListMenuClose = (accountListId?: string): void => {
+ if (accountListId) {
+ dispatch({ type: 'updateAccountListId', accountListId });
+ }
+ setAccountListMenuAnchorEl(null);
+ };
- const handleProfileMenuOpen = (event) => {
- setProfileMenuAnchorEl(event.currentTarget);
- };
+ const handleProfileMenuOpen = (event) => {
+ setProfileMenuAnchorEl(event.currentTarget);
+ };
- const handleProfileMenuClose = () => {
- setProfileMenuAnchorEl(null);
- };
+ const handleProfileMenuClose = () => {
+ setProfileMenuAnchorEl(null);
+ };
- const currentAccountList = data?.accountLists?.nodes?.find((node) => node.id == state.accountListId);
+ const currentAccountList = data?.accountLists?.nodes?.find(
+ (node) => node.id == state.accountListId,
+ );
- useEffect(() => {
- data?.user && state.user?.id !== data.user.id && dispatch({ type: 'updateUser', user: data.user });
- }, [data?.user]);
+ useEffect(() => {
+ data?.user &&
+ state.user?.id !== data.user.id &&
+ dispatch({ type: 'updateUser', user: data.user });
+ }, [data?.user]);
- return (
- <>
-
-
-
-
-
- handleOpenChange(true)}
- aria-label="Show Menu"
- >
-
-
-
+ return (
+ <>
+
+
+
+
+
+ handleOpenChange(true)}
+ aria-label="Show Menu"
+ >
+
+
+
-
-
-
-
-
-
-
- {data?.accountLists?.nodes && (
- <>
- {data.accountLists.nodes.length == 1 && (
-
- {currentAccountList?.name}
-
- )}
- {data.accountLists.nodes.length > 1 && (
- <>
-
- }
- size="small"
- data-testid="TopBarButton"
- >
- {currentAccountList?.name}
-
-
-
-
-
-
-
-
- >
- )}
- >
- )}
-
-
- {state.breadcrumb && (
-
- {state.breadcrumb}
-
- )}
-
-
-
+
+ {data?.accountLists?.nodes && (
+ <>
+ {data.accountLists.nodes.length == 1 && (
+
+ {currentAccountList?.name}
+
+ )}
+ {data.accountLists.nodes.length > 1 && (
+ <>
+
+ }
+ size="small"
+ data-testid="TopBarButton"
+ >
+ {currentAccountList?.name}
+
+
+
+
+
+
+
+
-
-
-
-
-
- {state.user?.firstName[0]}
-
-
-
-
-
-
-
-
-
-
-
- >
- );
+ {name}
+
+
+ ))}
+
+ >
+ )}
+ >
+ )}
+
+
+ {state.breadcrumb && (
+
+ {state.breadcrumb}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+ {state.user?.firstName[0]}
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
};
export default TopBar;
diff --git a/src/components/Loading/Loading.stories.tsx b/src/components/Loading/Loading.stories.tsx
index d96ee5f85d..a235838473 100644
--- a/src/components/Loading/Loading.stories.tsx
+++ b/src/components/Loading/Loading.stories.tsx
@@ -2,9 +2,9 @@ import React, { ReactElement } from 'react';
import Loading from '.';
export default {
- title: 'Loading',
+ title: 'Loading',
};
export const Default = (): ReactElement => {
- return ;
+ return ;
};
diff --git a/src/components/Loading/Loading.test.tsx b/src/components/Loading/Loading.test.tsx
index 8ff7a77bc5..bc03cf4c32 100644
--- a/src/components/Loading/Loading.test.tsx
+++ b/src/components/Loading/Loading.test.tsx
@@ -4,66 +4,88 @@ import TestRouter from '../../../__tests__/util/TestRouter';
import Loading from '.';
describe('Loading', () => {
- let router, events: { [key: string]: () => void };
- beforeEach(() => {
- events = {};
- router = {
- events: {
- on: jest.fn().mockImplementation((key, eventFn) => (events[key] = eventFn)),
- off: jest.fn().mockImplementation((key, _eventFn) => delete events[key]),
- emit: (key): void => events[key](),
- },
- };
- });
+ let router, events: { [key: string]: () => void };
+ beforeEach(() => {
+ events = {};
+ router = {
+ events: {
+ on: jest
+ .fn()
+ .mockImplementation((key, eventFn) => (events[key] = eventFn)),
+ off: jest
+ .fn()
+ .mockImplementation((key, _eventFn) => delete events[key]),
+ emit: (key): void => events[key](),
+ },
+ };
+ });
- it('has correct overrides', () => {
- const { getByTestId } = render(
-
-
- ,
- );
- expect(getByTestId('Loading')).toBeInTheDocument();
- });
+ it('has correct overrides', () => {
+ const { getByTestId } = render(
+
+
+ ,
+ );
+ expect(getByTestId('Loading')).toBeInTheDocument();
+ });
- it('adds and removes event handlers', () => {
- const { unmount } = render(
-
-
- ,
- );
- expect(router.events.on).toHaveBeenCalledWith('routeChangeStart', expect.any(Function));
- expect(router.events.on).toHaveBeenCalledWith('routeChangeComplete', expect.any(Function));
- expect(router.events.on).toHaveBeenCalledWith('routeChangeError', expect.any(Function));
- unmount();
- expect(router.events.off).toHaveBeenCalledWith('routeChangeStart', expect.any(Function));
- expect(router.events.off).toHaveBeenCalledWith('routeChangeComplete', expect.any(Function));
- expect(router.events.off).toHaveBeenCalledWith('routeChangeError', expect.any(Function));
- });
+ it('adds and removes event handlers', () => {
+ const { unmount } = render(
+
+
+ ,
+ );
+ expect(router.events.on).toHaveBeenCalledWith(
+ 'routeChangeStart',
+ expect.any(Function),
+ );
+ expect(router.events.on).toHaveBeenCalledWith(
+ 'routeChangeComplete',
+ expect.any(Function),
+ );
+ expect(router.events.on).toHaveBeenCalledWith(
+ 'routeChangeError',
+ expect.any(Function),
+ );
+ unmount();
+ expect(router.events.off).toHaveBeenCalledWith(
+ 'routeChangeStart',
+ expect.any(Function),
+ );
+ expect(router.events.off).toHaveBeenCalledWith(
+ 'routeChangeComplete',
+ expect.any(Function),
+ );
+ expect(router.events.off).toHaveBeenCalledWith(
+ 'routeChangeError',
+ expect.any(Function),
+ );
+ });
- it('changes loading state', async () => {
- const { queryByTestId } = render(
-
-
- ,
- );
- await waitFor(() => {
- expect(queryByTestId('Loading')).not.toBeInTheDocument();
- });
- router.events.emit('routeChangeStart');
- await waitFor(() => {
- expect(queryByTestId('Loading')).toBeInTheDocument();
- });
- router.events.emit('routeChangeComplete');
- await waitFor(() => {
- expect(queryByTestId('Loading')).not.toBeInTheDocument();
- });
- router.events.emit('routeChangeStart');
- await waitFor(() => {
- expect(queryByTestId('Loading')).toBeInTheDocument();
- });
- router.events.emit('routeChangeError');
- await waitFor(() => {
- expect(queryByTestId('Loading')).not.toBeInTheDocument();
- });
+ it('changes loading state', async () => {
+ const { queryByTestId } = render(
+
+
+ ,
+ );
+ await waitFor(() => {
+ expect(queryByTestId('Loading')).not.toBeInTheDocument();
+ });
+ router.events.emit('routeChangeStart');
+ await waitFor(() => {
+ expect(queryByTestId('Loading')).toBeInTheDocument();
+ });
+ router.events.emit('routeChangeComplete');
+ await waitFor(() => {
+ expect(queryByTestId('Loading')).not.toBeInTheDocument();
+ });
+ router.events.emit('routeChangeStart');
+ await waitFor(() => {
+ expect(queryByTestId('Loading')).toBeInTheDocument();
+ });
+ router.events.emit('routeChangeError');
+ await waitFor(() => {
+ expect(queryByTestId('Loading')).not.toBeInTheDocument();
});
+ });
});
diff --git a/src/components/Loading/Loading.tsx b/src/components/Loading/Loading.tsx
index f7e3cd776f..b28b3d6a1f 100644
--- a/src/components/Loading/Loading.tsx
+++ b/src/components/Loading/Loading.tsx
@@ -4,69 +4,69 @@ import { useRouter } from 'next/router';
import { motion, AnimatePresence } from 'framer-motion';
const useStyles = makeStyles((_theme: Theme) => ({
- box: {
- position: 'fixed',
- top: '50%',
- left: '50%',
- marginLeft: '-28px',
- marginTop: '-28px',
- },
- fab: {
- backgroundColor: '#fff',
- cursor: 'default',
- '&:hover': {
- backgroundColor: '#fff',
- },
+ box: {
+ position: 'fixed',
+ top: '50%',
+ left: '50%',
+ marginLeft: '-28px',
+ marginTop: '-28px',
+ },
+ fab: {
+ backgroundColor: '#fff',
+ cursor: 'default',
+ '&:hover': {
+ backgroundColor: '#fff',
},
+ },
}));
interface Props {
- loading?: boolean;
+ loading?: boolean;
}
const Loading = ({ loading = false }: Props): ReactElement => {
- const classes = useStyles();
- const router = useRouter();
+ const classes = useStyles();
+ const router = useRouter();
- const [currentlyLoading, setCurrentlyLoading] = useState(loading);
+ const [currentlyLoading, setCurrentlyLoading] = useState(loading);
- useEffect(() => {
- const handleStart = (): void => {
- setCurrentlyLoading(true);
- };
+ useEffect(() => {
+ const handleStart = (): void => {
+ setCurrentlyLoading(true);
+ };
- const handleComplete = (): void => {
- setCurrentlyLoading(false);
- };
+ const handleComplete = (): void => {
+ setCurrentlyLoading(false);
+ };
- router.events.on('routeChangeStart', handleStart);
- router.events.on('routeChangeComplete', handleComplete);
- router.events.on('routeChangeError', handleComplete);
+ router.events.on('routeChangeStart', handleStart);
+ router.events.on('routeChangeComplete', handleComplete);
+ router.events.on('routeChangeError', handleComplete);
- return (): void => {
- router.events.off('routeChangeStart', handleStart);
- router.events.off('routeChangeComplete', handleComplete);
- router.events.off('routeChangeError', handleComplete);
- };
- });
+ return (): void => {
+ router.events.off('routeChangeStart', handleStart);
+ router.events.off('routeChangeComplete', handleComplete);
+ router.events.off('routeChangeError', handleComplete);
+ };
+ });
- return (
-
- {currentlyLoading && (
-
-
-
-
-
- )}
-
- );
+ return (
+
+ {currentlyLoading && (
+
+
+
+
+
+ )}
+
+ );
};
export default Loading;
diff --git a/src/components/PageHeading/PageHeading.stories.tsx b/src/components/PageHeading/PageHeading.stories.tsx
index 1bc1e90320..7346e9a876 100644
--- a/src/components/PageHeading/PageHeading.stories.tsx
+++ b/src/components/PageHeading/PageHeading.stories.tsx
@@ -3,33 +3,39 @@ import { text, select, number } from '@storybook/addon-knobs';
import PageHeading from './PageHeading';
export default {
- title: 'PageHeading',
+ title: 'PageHeading',
};
export const Default = (): ReactElement => {
- const options = {
- range: true,
- min: 20,
- max: 100,
- step: 1,
- };
+ const options = {
+ range: true,
+ min: 20,
+ max: 100,
+ step: 1,
+ };
- return (
-
- );
+ return (
+
+ );
};
Default.story = {
- parameters: {
- chromatic: { delay: 1000 },
- },
+ parameters: {
+ chromatic: { delay: 1000 },
+ },
};
diff --git a/src/components/PageHeading/PageHeading.test.tsx b/src/components/PageHeading/PageHeading.test.tsx
index 214f8e33b6..0b08a7ca10 100644
--- a/src/components/PageHeading/PageHeading.test.tsx
+++ b/src/components/PageHeading/PageHeading.test.tsx
@@ -3,33 +3,49 @@ import { render } from '@testing-library/react';
import PageHeading from '.';
describe('PageHeading', () => {
- it('has correct defaults', () => {
- const { getByTestId } = render();
- expect(getByTestId('PageHeading')).toHaveStyle('margin-bottom: -20px');
- expect(getByTestId('PageHeadingContainer')).toHaveStyle('padding-bottom: 20px');
- expect(getByTestId('PageHeadingHeading')).toHaveTextContent('test heading');
- expect(getByTestId('PageHeadingSubheading')).toHaveTextContent('test subheading');
- expect(getByTestId('PageHeadingImg')).toHaveAttribute('src', 'drawkit-grape-pack-illustration-20.svg');
- });
+ it('has correct defaults', () => {
+ const { getByTestId } = render(
+ ,
+ );
+ expect(getByTestId('PageHeading')).toHaveStyle('margin-bottom: -20px');
+ expect(getByTestId('PageHeadingContainer')).toHaveStyle(
+ 'padding-bottom: 20px',
+ );
+ expect(getByTestId('PageHeadingHeading')).toHaveTextContent('test heading');
+ expect(getByTestId('PageHeadingSubheading')).toHaveTextContent(
+ 'test subheading',
+ );
+ expect(getByTestId('PageHeadingImg')).toHaveAttribute(
+ 'src',
+ 'drawkit-grape-pack-illustration-20.svg',
+ );
+ });
- it('has correct overrides', () => {
- const { getByTestId, queryByTestId } = render(
- ,
- );
- expect(getByTestId('PageHeading')).toHaveStyle('margin-bottom: -100px');
- expect(getByTestId('PageHeading')).toHaveStyle('height: 400px');
- expect(getByTestId('PageHeadingContainer')).toHaveStyle('padding-bottom: 100px');
- expect(queryByTestId('PageHeadingSubheading')).toBeNull();
- expect(getByTestId('PageHeadingImg')).toHaveAttribute('src', 'drawkit-grape-pack-illustration-1.svg');
- });
+ it('has correct overrides', () => {
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(getByTestId('PageHeading')).toHaveStyle('margin-bottom: -100px');
+ expect(getByTestId('PageHeading')).toHaveStyle('height: 400px');
+ expect(getByTestId('PageHeadingContainer')).toHaveStyle(
+ 'padding-bottom: 100px',
+ );
+ expect(queryByTestId('PageHeadingSubheading')).toBeNull();
+ expect(getByTestId('PageHeadingImg')).toHaveAttribute(
+ 'src',
+ 'drawkit-grape-pack-illustration-1.svg',
+ );
+ });
- it('has correct overrides for image', () => {
- const { queryByTestId } = render();
- expect(queryByTestId('PageHeadingImg')).not.toBeInTheDocument();
- });
+ it('has correct overrides for image', () => {
+ const { queryByTestId } = render(
+ ,
+ );
+ expect(queryByTestId('PageHeadingImg')).not.toBeInTheDocument();
+ });
});
diff --git a/src/components/PageHeading/PageHeading.tsx b/src/components/PageHeading/PageHeading.tsx
index a23cc24ae2..6a992976e5 100644
--- a/src/components/PageHeading/PageHeading.tsx
+++ b/src/components/PageHeading/PageHeading.tsx
@@ -1,95 +1,107 @@
import React, { ReactElement } from 'react';
-import { makeStyles, Theme, Container, Typography, Box } from '@material-ui/core';
+import {
+ makeStyles,
+ Theme,
+ Container,
+ Typography,
+ Box,
+} from '@material-ui/core';
import { motion } from 'framer-motion';
import illustration20 from '../../images/drawkit/grape/drawkit-grape-pack-illustration-20.svg';
interface Props {
- heading: string;
- subheading?: string;
- imgSrc?: string;
- overlap?: number;
- height?: number;
- image?: boolean;
+ heading: string;
+ subheading?: string;
+ imgSrc?: string;
+ overlap?: number;
+ height?: number;
+ image?: boolean;
}
const useStyles = makeStyles((theme: Theme) => ({
- div: {
- backgroundColor: theme.palette.primary.main,
- height: '250px',
- display: 'flex',
- alignItems: 'flex-end',
- marginBottom: theme.spacing(2),
- },
- container: {
- display: 'flex',
- alignItems: 'flex-end',
- },
- pageHeading: {
- flex: 1,
- color: '#FFF',
- },
+ div: {
+ backgroundColor: theme.palette.primary.main,
+ height: '250px',
+ display: 'flex',
+ alignItems: 'flex-end',
+ marginBottom: theme.spacing(2),
+ },
+ container: {
+ display: 'flex',
+ alignItems: 'flex-end',
+ },
+ pageHeading: {
+ flex: 1,
+ color: '#FFF',
+ },
}));
const PageHeading = ({
- heading,
- subheading,
- imgSrc,
- overlap = 20,
- height = 250,
- image = true,
+ heading,
+ subheading,
+ imgSrc,
+ overlap = 20,
+ height = 250,
+ image = true,
}: Props): ReactElement => {
- const classes = useStyles();
+ const classes = useStyles();
- return (
-
-
+
+
+
+
-
-
-
- {heading}
-
-
- {subheading && (
-
- {subheading}
-
- )}
-
- {image && (
-
-
-
- )}
-
-
- );
+ {heading}
+
+
+ {subheading && (
+
+
+ {subheading}
+
+
+ )}
+
+ {image && (
+
+
+
+ )}
+
+
+ );
};
export default PageHeading;
diff --git a/src/components/StyledProgress/StyledProgress.stories.tsx b/src/components/StyledProgress/StyledProgress.stories.tsx
index 86201d7c13..c7a05b0859 100644
--- a/src/components/StyledProgress/StyledProgress.stories.tsx
+++ b/src/components/StyledProgress/StyledProgress.stories.tsx
@@ -4,53 +4,53 @@ import { number, boolean } from '@storybook/addon-knobs';
import StyledProgress from '.';
export default {
- title: 'StyledProgress',
+ title: 'StyledProgress',
};
export const Default = (): ReactElement => {
- const options = {
- range: true,
- min: 0,
- max: 100,
- step: 1,
- };
+ const options = {
+ range: true,
+ min: 0,
+ max: 100,
+ step: 1,
+ };
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const WhenMin = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const WhenMax = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/StyledProgress/StyledProgress.test.tsx b/src/components/StyledProgress/StyledProgress.test.tsx
index f348f9ab95..96616466f1 100644
--- a/src/components/StyledProgress/StyledProgress.test.tsx
+++ b/src/components/StyledProgress/StyledProgress.test.tsx
@@ -3,24 +3,26 @@ import { render } from '@testing-library/react';
import StyledProgress from '.';
describe('StyledProgress', () => {
- it('has correct defaults', () => {
- const { getByTestId, queryByTestId } = render();
- expect(queryByTestId('styledProgressLoading')).toBeNull();
- expect(getByTestId('styledProgressPrimary')).toHaveStyle('width: 0%;');
- expect(getByTestId('styledProgressSecondary')).toHaveStyle('width: 0%;');
- });
+ it('has correct defaults', () => {
+ const { getByTestId, queryByTestId } = render();
+ expect(queryByTestId('styledProgressLoading')).toBeNull();
+ expect(getByTestId('styledProgressPrimary')).toHaveStyle('width: 0%;');
+ expect(getByTestId('styledProgressSecondary')).toHaveStyle('width: 0%;');
+ });
- it('has correct overrides', () => {
- const { getByTestId, queryByTestId } = render();
- expect(queryByTestId('styledProgressLoading')).toBeNull();
- expect(getByTestId('styledProgressPrimary')).toHaveStyle('width: 50%;');
- expect(getByTestId('styledProgressSecondary')).toHaveStyle('width: 75%;');
- });
+ it('has correct overrides', () => {
+ const { getByTestId, queryByTestId } = render(
+ ,
+ );
+ expect(queryByTestId('styledProgressLoading')).toBeNull();
+ expect(getByTestId('styledProgressPrimary')).toHaveStyle('width: 50%;');
+ expect(getByTestId('styledProgressSecondary')).toHaveStyle('width: 75%;');
+ });
- it('allows loading', () => {
- const { getByTestId, queryByTestId } = render();
- expect(getByTestId('styledProgressLoading')).toBeTruthy();
- expect(queryByTestId('styledProgressPrimary')).toBeNull();
- expect(queryByTestId('styledProgressSecondary')).toBeNull();
- });
+ it('allows loading', () => {
+ const { getByTestId, queryByTestId } = render();
+ expect(getByTestId('styledProgressLoading')).toBeTruthy();
+ expect(queryByTestId('styledProgressPrimary')).toBeNull();
+ expect(queryByTestId('styledProgressSecondary')).toBeNull();
+ });
});
diff --git a/src/components/StyledProgress/StyledProgress.tsx b/src/components/StyledProgress/StyledProgress.tsx
index 51baa6346e..36caeb9004 100644
--- a/src/components/StyledProgress/StyledProgress.tsx
+++ b/src/components/StyledProgress/StyledProgress.tsx
@@ -4,67 +4,75 @@ import { Skeleton } from '@material-ui/lab';
import { percentageFormat } from '../../lib/intlFormat';
const useStyles = makeStyles((theme: Theme) => ({
- box: {
- width: '100%',
- height: '54px',
- border: '2px solid #999999',
- borderRadius: '50px',
- padding: '2px',
- position: 'relative',
- marginBottom: theme.spacing(2),
- },
- progress: {
- position: 'absolute',
- left: '2px',
- height: '46px',
- minWidth: '46px',
- maxWidth: '99.6%',
- borderRadius: '46px',
- transition: 'width 1s ease-out',
- width: '0%',
- },
- skeleton: {
- borderRadius: '46px',
- height: '46px',
- transform: 'none',
- },
- primary: {
- background: 'linear-gradient(180deg, #FFE67C 0%, #FFCF07 100%)',
- },
- secondary: {
- border: '5px solid #FFCF07',
- },
+ box: {
+ width: '100%',
+ height: '54px',
+ border: '2px solid #999999',
+ borderRadius: '50px',
+ padding: '2px',
+ position: 'relative',
+ marginBottom: theme.spacing(2),
+ },
+ progress: {
+ position: 'absolute',
+ left: '2px',
+ height: '46px',
+ minWidth: '46px',
+ maxWidth: '99.6%',
+ borderRadius: '46px',
+ transition: 'width 1s ease-out',
+ width: '0%',
+ },
+ skeleton: {
+ borderRadius: '46px',
+ height: '46px',
+ transform: 'none',
+ },
+ primary: {
+ background: 'linear-gradient(180deg, #FFE67C 0%, #FFCF07 100%)',
+ },
+ secondary: {
+ border: '5px solid #FFCF07',
+ },
}));
interface Props {
- loading?: boolean;
- primary?: number;
- secondary?: number;
+ loading?: boolean;
+ primary?: number;
+ secondary?: number;
}
-const StyledProgress = ({ loading, primary = 0, secondary = 0 }: Props): ReactElement => {
- const classes = useStyles();
+const StyledProgress = ({
+ loading,
+ primary = 0,
+ secondary = 0,
+}: Props): ReactElement => {
+ const classes = useStyles();
- return (
-
- {loading ? (
-
- ) : (
- <>
-
-
- >
- )}
-
- );
+ return (
+
+ {loading ? (
+
+ ) : (
+ <>
+
+
+ >
+ )}
+
+ );
};
export default StyledProgress;
diff --git a/src/components/Task/Drawer/CommentList/CommentList.mock.tsx b/src/components/Task/Drawer/CommentList/CommentList.mock.tsx
index bf716a394c..6445027330 100644
--- a/src/components/Task/Drawer/CommentList/CommentList.mock.tsx
+++ b/src/components/Task/Drawer/CommentList/CommentList.mock.tsx
@@ -3,123 +3,123 @@ import { GetCommentsForTaskDrawerCommentListQuery } from '../../../../../types/G
import { GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY } from './CommentList';
export const getCommentsForTaskDrawerCommentListMock = (): MockedResponse => {
- const data: GetCommentsForTaskDrawerCommentListQuery = {
- task: {
- id: 'task-1',
- comments: {
- nodes: [
- {
- id: 'comment-1',
- body: 'Hello',
- createdAt: '2019-10-09T05:55:20',
- person: {
- id: 'person-b',
- firstName: 'Sarah',
- lastName: 'Jones',
- },
- me: true,
- },
- {
- id: 'comment-2',
- body: 'How are you doing today?',
- createdAt: '2019-10-09T05:56:20',
- person: {
- id: 'person-b',
- firstName: 'Sarah',
- lastName: 'Jones',
- },
- me: true,
- },
- {
- id: 'comment-3',
- body: 'Doing well thank you!',
- createdAt: '2020-01-11T05:55:20',
- person: {
- id: 'person-a',
- firstName: 'Bob',
- lastName: 'Jones',
- },
- me: false,
- },
- {
- id: 'comment-4',
- body: 'How about you?',
- createdAt: '2020-01-11T05:56:20',
- person: {
- id: 'person-a',
- firstName: 'Bob',
- lastName: 'Jones',
- },
- me: false,
- },
- {
- id: 'comment-5',
- body: 'Nice weather we are having?',
- createdAt: '2020-01-12T05:55:20',
- person: {
- id: 'person-b',
- firstName: 'Sarah',
- lastName: 'Jones',
- },
- me: true,
- },
- {
- id: 'comment-6',
- body: 'Fine.',
- createdAt: '2020-01-12T05:56:20',
- person: {
- id: 'person-b',
- firstName: 'Sarah',
- lastName: 'Jones',
- },
- me: true,
- },
- ],
+ const data: GetCommentsForTaskDrawerCommentListQuery = {
+ task: {
+ id: 'task-1',
+ comments: {
+ nodes: [
+ {
+ id: 'comment-1',
+ body: 'Hello',
+ createdAt: '2019-10-09T05:55:20',
+ person: {
+ id: 'person-b',
+ firstName: 'Sarah',
+ lastName: 'Jones',
},
- },
- };
-
- return {
- request: {
- query: GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
- variables: {
- accountListId: 'abc',
- taskId: 'task-1',
+ me: true,
+ },
+ {
+ id: 'comment-2',
+ body: 'How are you doing today?',
+ createdAt: '2019-10-09T05:56:20',
+ person: {
+ id: 'person-b',
+ firstName: 'Sarah',
+ lastName: 'Jones',
+ },
+ me: true,
+ },
+ {
+ id: 'comment-3',
+ body: 'Doing well thank you!',
+ createdAt: '2020-01-11T05:55:20',
+ person: {
+ id: 'person-a',
+ firstName: 'Bob',
+ lastName: 'Jones',
+ },
+ me: false,
+ },
+ {
+ id: 'comment-4',
+ body: 'How about you?',
+ createdAt: '2020-01-11T05:56:20',
+ person: {
+ id: 'person-a',
+ firstName: 'Bob',
+ lastName: 'Jones',
+ },
+ me: false,
+ },
+ {
+ id: 'comment-5',
+ body: 'Nice weather we are having?',
+ createdAt: '2020-01-12T05:55:20',
+ person: {
+ id: 'person-b',
+ firstName: 'Sarah',
+ lastName: 'Jones',
},
- },
- result: {
- data,
- },
- };
+ me: true,
+ },
+ {
+ id: 'comment-6',
+ body: 'Fine.',
+ createdAt: '2020-01-12T05:56:20',
+ person: {
+ id: 'person-b',
+ firstName: 'Sarah',
+ lastName: 'Jones',
+ },
+ me: true,
+ },
+ ],
+ },
+ },
+ };
+
+ return {
+ request: {
+ query: GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
+ variables: {
+ accountListId: 'abc',
+ taskId: 'task-1',
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export const getCommentsForTaskDrawerCommentListEmptyMock = (): MockedResponse => {
- const data: GetCommentsForTaskDrawerCommentListQuery = {
- task: {
- id: 'task-1',
- comments: {
- nodes: [],
- },
- },
- };
+ const data: GetCommentsForTaskDrawerCommentListQuery = {
+ task: {
+ id: 'task-1',
+ comments: {
+ nodes: [],
+ },
+ },
+ };
- return {
- request: {
- query: GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
- variables: {
- accountListId: 'abc',
- taskId: 'task-1',
- },
- },
- result: {
- data,
- },
- };
+ return {
+ request: {
+ query: GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
+ variables: {
+ accountListId: 'abc',
+ taskId: 'task-1',
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export const getCommentsForTaskDrawerCommentListLoadingMock = (): MockedResponse => {
- return {
- ...getCommentsForTaskDrawerCommentListMock(),
- delay: 100931731455,
- };
+ return {
+ ...getCommentsForTaskDrawerCommentListMock(),
+ delay: 100931731455,
+ };
};
diff --git a/src/components/Task/Drawer/CommentList/CommentList.stories.tsx b/src/components/Task/Drawer/CommentList/CommentList.stories.tsx
index ada0b857bc..f472dad038 100644
--- a/src/components/Task/Drawer/CommentList/CommentList.stories.tsx
+++ b/src/components/Task/Drawer/CommentList/CommentList.stories.tsx
@@ -1,35 +1,41 @@
import React, { ReactElement } from 'react';
import { MockedProvider } from '@apollo/client/testing';
import {
- getCommentsForTaskDrawerCommentListMock,
- getCommentsForTaskDrawerCommentListEmptyMock,
+ getCommentsForTaskDrawerCommentListMock,
+ getCommentsForTaskDrawerCommentListEmptyMock,
} from './CommentList.mock';
import TaskDrawerCommentList from '.';
export default {
- title: 'Task/Drawer/CommentList',
+ title: 'Task/Drawer/CommentList',
};
export const Default = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Task/Drawer/CommentList/CommentList.test.tsx b/src/components/Task/Drawer/CommentList/CommentList.test.tsx
index b9359451b5..008ea8247d 100644
--- a/src/components/Task/Drawer/CommentList/CommentList.test.tsx
+++ b/src/components/Task/Drawer/CommentList/CommentList.test.tsx
@@ -3,65 +3,84 @@ import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import TestWrapper from '../../../../../__tests__/util/TestWrapper';
import {
- getCommentsForTaskDrawerCommentListMock,
- getCommentsForTaskDrawerCommentListEmptyMock,
- getCommentsForTaskDrawerCommentListLoadingMock,
+ getCommentsForTaskDrawerCommentListMock,
+ getCommentsForTaskDrawerCommentListEmptyMock,
+ getCommentsForTaskDrawerCommentListLoadingMock,
} from './CommentList.mock';
import { createTaskCommentMutationMock } from './Form/Form.mock';
import TaskDrawerCommentList from '.';
jest.mock('uuid', () => ({
- v4: (): string => 'comment-0',
+ v4: (): string => 'comment-0',
}));
describe('TaskDrawerCommentList', () => {
- it('default', async () => {
- const { queryByTestId, getAllByTestId, getByRole } = render(
-
-
- ,
- );
- await waitFor(() => expect(queryByTestId('TaskDrawerCommentListLoading')).not.toBeInTheDocument());
- userEvent.type(getByRole('textbox'), 'comment{enter}');
- await waitFor(() => expect(getByRole('textbox')).toHaveValue(''));
- expect(
- getAllByTestId(/TaskDrawerCommentListItem-comment-./).map((element) => element.getAttribute('data-testid')),
- ).toEqual([
- 'TaskDrawerCommentListItem-comment-1',
- 'TaskDrawerCommentListItem-comment-2',
- 'TaskDrawerCommentListItem-comment-3',
- 'TaskDrawerCommentListItem-comment-4',
- 'TaskDrawerCommentListItem-comment-5',
- 'TaskDrawerCommentListItem-comment-6',
- 'TaskDrawerCommentListItem-comment-0',
- ]);
- });
+ it('default', async () => {
+ const { queryByTestId, getAllByTestId, getByRole } = render(
+
+
+ ,
+ );
+ await waitFor(() =>
+ expect(
+ queryByTestId('TaskDrawerCommentListLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ userEvent.type(getByRole('textbox'), 'comment{enter}');
+ await waitFor(() => expect(getByRole('textbox')).toHaveValue(''));
+ expect(
+ getAllByTestId(/TaskDrawerCommentListItem-comment-./).map((element) =>
+ element.getAttribute('data-testid'),
+ ),
+ ).toEqual([
+ 'TaskDrawerCommentListItem-comment-1',
+ 'TaskDrawerCommentListItem-comment-2',
+ 'TaskDrawerCommentListItem-comment-3',
+ 'TaskDrawerCommentListItem-comment-4',
+ 'TaskDrawerCommentListItem-comment-5',
+ 'TaskDrawerCommentListItem-comment-6',
+ 'TaskDrawerCommentListItem-comment-0',
+ ]);
+ });
- it('loading', () => {
- const { getByTestId } = render(
-
-
- ,
- );
- expect(getByTestId('TaskDrawerCommentListLoading')).toBeInTheDocument();
- });
+ it('loading', () => {
+ const { getByTestId } = render(
+
+
+ ,
+ );
+ expect(getByTestId('TaskDrawerCommentListLoading')).toBeInTheDocument();
+ });
- it('empty', async () => {
- const { queryByTestId, getByTestId } = render(
-
-
- ,
- );
- await waitFor(() => expect(queryByTestId('TaskDrawerCommentListLoading')).not.toBeInTheDocument());
- expect(getByTestId('TaskDrawerCommentListEmpty')).toBeInTheDocument();
- });
+ it('empty', async () => {
+ const { queryByTestId, getByTestId } = render(
+
+
+ ,
+ );
+ await waitFor(() =>
+ expect(
+ queryByTestId('TaskDrawerCommentListLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(getByTestId('TaskDrawerCommentListEmpty')).toBeInTheDocument();
+ });
});
diff --git a/src/components/Task/Drawer/CommentList/CommentList.tsx b/src/components/Task/Drawer/CommentList/CommentList.tsx
index c01947818e..dd6ea1fdb4 100644
--- a/src/components/Task/Drawer/CommentList/CommentList.tsx
+++ b/src/components/Task/Drawer/CommentList/CommentList.tsx
@@ -9,114 +9,132 @@ import TaskDrawerCommentListItem from './Item';
import TaskDrawerCommentListForm from './Form';
const useStyles = makeStyles((theme: Theme) => ({
- cardContent: {
- padding: theme.spacing(2),
- display: 'flex',
- flex: 1,
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- },
- img: {
- height: '120px',
- marginBottom: 0,
- [theme.breakpoints.down('xs')]: {
- height: '150px',
- marginBottom: theme.spacing(2),
- },
+ cardContent: {
+ padding: theme.spacing(2),
+ display: 'flex',
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ img: {
+ height: '120px',
+ marginBottom: 0,
+ [theme.breakpoints.down('xs')]: {
+ height: '150px',
+ marginBottom: theme.spacing(2),
},
+ },
}));
export const GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY = gql`
- query GetCommentsForTaskDrawerCommentListQuery($accountListId: ID!, $taskId: ID!) {
- task(accountListId: $accountListId, id: $taskId) {
+ query GetCommentsForTaskDrawerCommentListQuery(
+ $accountListId: ID!
+ $taskId: ID!
+ ) {
+ task(accountListId: $accountListId, id: $taskId) {
+ id
+ comments {
+ nodes {
+ id
+ body
+ createdAt
+ me
+ person {
id
- comments {
- nodes {
- id
- body
- createdAt
- me
- person {
- id
- firstName
- lastName
- }
- }
- }
+ firstName
+ lastName
+ }
}
+ }
}
+ }
`;
interface Props {
- accountListId: string;
- taskId: string;
+ accountListId: string;
+ taskId: string;
}
-const TaskDrawerCommentList = ({ accountListId, taskId }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
+const TaskDrawerCommentList = ({
+ accountListId,
+ taskId,
+}: Props): ReactElement => {
+ const classes = useStyles();
+ const { t } = useTranslation();
- const { data, loading } = useQuery(
- GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
- {
- variables: {
- accountListId,
- taskId,
- },
- },
- );
+ const { data, loading } = useQuery(
+ GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
+ {
+ variables: {
+ accountListId,
+ taskId,
+ },
+ },
+ );
- const ref = useRef(null);
+ const ref = useRef(null);
- useEffect(() => {
- ref.current.scrollIntoView({ behaviour: 'smooth' });
- }, [data?.task?.comments?.nodes]);
+ useEffect(() => {
+ ref.current.scrollIntoView({ behaviour: 'smooth' });
+ }, [data?.task?.comments?.nodes]);
- return (
- <>
-
- {loading ? (
-
-
-
-
-
-
- ) : (
- <>
- {data.task.comments.nodes.length === 0 && (
-
-
-
- {t('No Comments to show.')}
-
-
- )}
- {data.task.comments.nodes.length > 0 &&
- reduce(
- (result, comment) => {
- return [
- ...result,
-
-
- ,
- ];
- },
- [],
- data.task.comments.nodes,
- )}
- >
- )}
-
-
-
- >
- );
+ return (
+ <>
+
+ {loading ? (
+
+
+
+
+
+
+ ) : (
+ <>
+ {data.task.comments.nodes.length === 0 && (
+
+
+
+ {t('No Comments to show.')}
+
+
+ )}
+ {data.task.comments.nodes.length > 0 &&
+ reduce(
+ (result, comment) => {
+ return [
+ ...result,
+
+
+ ,
+ ];
+ },
+ [],
+ data.task.comments.nodes,
+ )}
+ >
+ )}
+
+
+
+ >
+ );
};
export default TaskDrawerCommentList;
diff --git a/src/components/Task/Drawer/CommentList/Form/Form.mock.tsx b/src/components/Task/Drawer/CommentList/Form/Form.mock.tsx
index 4953fe5b2d..3fb4e6af71 100644
--- a/src/components/Task/Drawer/CommentList/Form/Form.mock.tsx
+++ b/src/components/Task/Drawer/CommentList/Form/Form.mock.tsx
@@ -3,38 +3,38 @@ import { CreateTaskCommentMutation } from '../../../../../../types/CreateTaskCom
import { CREATE_TASK_COMMENT_MUTATION } from './Form';
export const createTaskCommentMutationMock = (): MockedResponse => {
- const data: CreateTaskCommentMutation = {
- createTaskComment: {
- comment: {
- id: 'comment-0',
- body: 'comment',
- createdAt: new Date().toISOString(),
- me: true,
- person: {
- id: 'user-1',
- firstName: 'John',
- lastName: 'Smith',
- },
- },
+ const data: CreateTaskCommentMutation = {
+ createTaskComment: {
+ comment: {
+ id: 'comment-0',
+ body: 'comment',
+ createdAt: new Date().toISOString(),
+ me: true,
+ person: {
+ id: 'user-1',
+ firstName: 'John',
+ lastName: 'Smith',
},
- };
+ },
+ },
+ };
- return {
- request: {
- query: CREATE_TASK_COMMENT_MUTATION,
- variables: {
- accountListId: 'abc',
- taskId: 'task-1',
- attributes: {
- id: 'comment-0',
- body: 'comment',
- },
- },
+ return {
+ request: {
+ query: CREATE_TASK_COMMENT_MUTATION,
+ variables: {
+ accountListId: 'abc',
+ taskId: 'task-1',
+ attributes: {
+ id: 'comment-0',
+ body: 'comment',
},
- result: {
- data,
- },
- };
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export default createTaskCommentMutationMock;
diff --git a/src/components/Task/Drawer/CommentList/Form/Form.stories.tsx b/src/components/Task/Drawer/CommentList/Form/Form.stories.tsx
index 6020ab2a0a..1741959af8 100644
--- a/src/components/Task/Drawer/CommentList/Form/Form.stories.tsx
+++ b/src/components/Task/Drawer/CommentList/Form/Form.stories.tsx
@@ -6,18 +6,25 @@ import { createTaskCommentMutationMock } from './Form.mock';
import TaskDrawerCommentListForm from '.';
export default {
- title: 'Task/Drawer/CommentList/Form',
+ title: 'Task/Drawer/CommentList/Form',
};
export const Default = (): ReactElement => {
- return (
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+ );
};
diff --git a/src/components/Task/Drawer/CommentList/Form/Form.test.tsx b/src/components/Task/Drawer/CommentList/Form/Form.test.tsx
index 6cf9061509..74af24eef6 100644
--- a/src/components/Task/Drawer/CommentList/Form/Form.test.tsx
+++ b/src/components/Task/Drawer/CommentList/Form/Form.test.tsx
@@ -9,36 +9,44 @@ import { createTaskCommentMutationMock } from './Form.mock';
import TaskDrawerCommentListForm from '.';
jest.mock('uuid', () => ({
- v4: (): string => 'comment-0',
+ v4: (): string => 'comment-0',
}));
describe('TaskDrawerCommentListForm', () => {
- it('has correct defaults', async () => {
- const cache = new InMemoryCache({ addTypename: false });
- const query = {
- query: GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
- variables: {
- accountListId: 'abc',
- taskId: 'task-1',
- },
- data: {
- task: {
- id: 'task-1',
- comments: [],
- },
- },
- };
- cache.writeQuery(query);
- const { getByRole } = render(
-
-
-
-
- ,
- );
- userEvent.type(getByRole('textbox'), 'c{backspace}');
- await waitFor(() => expect(getByRole('button')).toBeDisabled());
- userEvent.type(getByRole('textbox'), 'comment{enter}');
- await waitFor(() => expect(getByRole('textbox')).toHaveValue(''));
- });
+ it('has correct defaults', async () => {
+ const cache = new InMemoryCache({ addTypename: false });
+ const query = {
+ query: GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
+ variables: {
+ accountListId: 'abc',
+ taskId: 'task-1',
+ },
+ data: {
+ task: {
+ id: 'task-1',
+ comments: [],
+ },
+ },
+ };
+ cache.writeQuery(query);
+ const { getByRole } = render(
+
+
+
+
+ ,
+ );
+ userEvent.type(getByRole('textbox'), 'c{backspace}');
+ await waitFor(() => expect(getByRole('button')).toBeDisabled());
+ userEvent.type(getByRole('textbox'), 'comment{enter}');
+ await waitFor(() => expect(getByRole('textbox')).toHaveValue(''));
+ });
});
diff --git a/src/components/Task/Drawer/CommentList/Form/Form.tsx b/src/components/Task/Drawer/CommentList/Form/Form.tsx
index 4ca03b7f52..14e4ad7031 100644
--- a/src/components/Task/Drawer/CommentList/Form/Form.tsx
+++ b/src/components/Task/Drawer/CommentList/Form/Form.tsx
@@ -1,5 +1,13 @@
import React, { ReactElement } from 'react';
-import { makeStyles, Theme, Box, TextField, IconButton, Grid, Divider } from '@material-ui/core';
+import {
+ makeStyles,
+ Theme,
+ Box,
+ TextField,
+ IconButton,
+ Grid,
+ Divider,
+} from '@material-ui/core';
import { Formik, FormikHelpers } from 'formik';
import * as yup from 'yup';
import SendIcon from '@material-ui/icons/Send';
@@ -14,154 +22,183 @@ import { GetCommentsForTaskDrawerCommentListQuery } from '../../../../../../type
import { useApp } from '../../../../App';
const useStyles = makeStyles((theme: Theme) => ({
- div: {
- backgroundColor: theme.palette.background.paper,
- position: 'fixed',
- bottom: 0,
- width: 500,
- [theme.breakpoints.down('xs')]: {
- width: '100%',
- },
- },
- gridItem: {
- flexGrow: 1,
- },
- spacerBox: {
- height: 81,
+ div: {
+ backgroundColor: theme.palette.background.paper,
+ position: 'fixed',
+ bottom: 0,
+ width: 500,
+ [theme.breakpoints.down('xs')]: {
+ width: '100%',
},
+ },
+ gridItem: {
+ flexGrow: 1,
+ },
+ spacerBox: {
+ height: 81,
+ },
}));
export const CREATE_TASK_COMMENT_MUTATION = gql`
- mutation CreateTaskCommentMutation($accountListId: ID!, $taskId: ID!, $attributes: TaskCommentCreateInput!) {
- createTaskComment(input: { accountListId: $accountListId, taskId: $taskId, attributes: $attributes }) {
- comment {
- id
- body
- createdAt
- me
- person {
- id
- firstName
- lastName
- }
- }
+ mutation CreateTaskCommentMutation(
+ $accountListId: ID!
+ $taskId: ID!
+ $attributes: TaskCommentCreateInput!
+ ) {
+ createTaskComment(
+ input: {
+ accountListId: $accountListId
+ taskId: $taskId
+ attributes: $attributes
+ }
+ ) {
+ comment {
+ id
+ body
+ createdAt
+ me
+ person {
+ id
+ firstName
+ lastName
}
+ }
}
+ }
`;
-const commentSchema: yup.SchemaOf> = yup.object({
- body: yup.string().trim().required(),
+const commentSchema: yup.SchemaOf<
+ Omit
+> = yup.object({
+ body: yup.string().trim().required(),
});
interface Props {
- accountListId: string;
- taskId: string;
+ accountListId: string;
+ taskId: string;
}
const Form = ({ accountListId, taskId }: Props): ReactElement => {
- const classes = useStyles();
- const [createTaskComment] = useMutation(CREATE_TASK_COMMENT_MUTATION);
- const {
- state: { user },
- } = useApp();
- const onSubmit = async (
- values: TaskCommentCreateInput,
- { resetForm }: FormikHelpers,
- ): Promise => {
- const id = uuidv4();
- const body = values.body.trim();
- resetForm();
- createTaskComment({
- variables: { accountListId, taskId, attributes: { id, body } },
- optimisticResponse: {
- createTaskComment: {
- comment: {
- id,
- body,
- createdAt: new Date().toISOString(),
- me: true,
- person: {
- id: user.id,
- firstName: user.firstName,
- lastName: user.lastName,
- },
- },
- },
+ const classes = useStyles();
+ const [createTaskComment] = useMutation(
+ CREATE_TASK_COMMENT_MUTATION,
+ );
+ const {
+ state: { user },
+ } = useApp();
+ const onSubmit = async (
+ values: TaskCommentCreateInput,
+ { resetForm }: FormikHelpers,
+ ): Promise => {
+ const id = uuidv4();
+ const body = values.body.trim();
+ resetForm();
+ createTaskComment({
+ variables: { accountListId, taskId, attributes: { id, body } },
+ optimisticResponse: {
+ createTaskComment: {
+ comment: {
+ id,
+ body,
+ createdAt: new Date().toISOString(),
+ me: true,
+ person: {
+ id: user.id,
+ firstName: user.firstName,
+ lastName: user.lastName,
},
- update: (
- cache,
- {
- data: {
- createTaskComment: { comment },
- },
- },
- ) => {
- const query = {
- query: GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
- variables: {
- accountListId,
- taskId,
- },
- };
- const data = cloneDeep(cache.readQuery(query));
- data.task.comments.nodes = [
- ...reject(({ id: commentId }) => id === commentId, data.task.comments.nodes),
- comment,
- ];
- cache.writeQuery({ ...query, data });
- },
- });
- };
- return (
- <>
-
-
-
-
-
- {({ values: { body }, handleChange, handleSubmit, isSubmitting, isValid }): ReactElement => (
-
- )}
-
-
-
- >
- );
+ },
+ },
+ },
+ update: (
+ cache,
+ {
+ data: {
+ createTaskComment: { comment },
+ },
+ },
+ ) => {
+ const query = {
+ query: GET_COMMENTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
+ variables: {
+ accountListId,
+ taskId,
+ },
+ };
+ const data = cloneDeep(
+ cache.readQuery(query),
+ );
+ data.task.comments.nodes = [
+ ...reject(
+ ({ id: commentId }) => id === commentId,
+ data.task.comments.nodes,
+ ),
+ comment,
+ ];
+ cache.writeQuery({ ...query, data });
+ },
+ });
+ };
+ return (
+ <>
+
+
+
+
+
+ {({
+ values: { body },
+ handleChange,
+ handleSubmit,
+ isSubmitting,
+ isValid,
+ }): ReactElement => (
+
+ )}
+
+
+
+ >
+ );
};
export default Form;
diff --git a/src/components/Task/Drawer/CommentList/Item/Item.stories.tsx b/src/components/Task/Drawer/CommentList/Item/Item.stories.tsx
index cc9959b448..5b6a09e066 100644
--- a/src/components/Task/Drawer/CommentList/Item/Item.stories.tsx
+++ b/src/components/Task/Drawer/CommentList/Item/Item.stories.tsx
@@ -4,45 +4,45 @@ import { GetCommentsForTaskDrawerCommentListQuery_task_comments_nodes as Comment
import TaskDrawerCommentListItem from '.';
export default {
- title: 'Task/Drawer/CommentList/Item',
+ title: 'Task/Drawer/CommentList/Item',
};
const comment: Comment = {
- id: 'def',
- body:
- 'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. ' +
- 'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. ' +
- 'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. ' +
- 'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. ',
- createdAt: '2019-10-12',
- me: false,
- person: {
- id: 'person-a',
- firstName: 'Bob',
- lastName: 'Jones',
- },
+ id: 'def',
+ body:
+ 'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. ' +
+ 'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. ' +
+ 'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. ' +
+ 'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. ',
+ createdAt: '2019-10-12',
+ me: false,
+ person: {
+ id: 'person-a',
+ firstName: 'Bob',
+ lastName: 'Jones',
+ },
};
export const Default = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const User = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Task/Drawer/CommentList/Item/Item.test.tsx b/src/components/Task/Drawer/CommentList/Item/Item.test.tsx
index 9dc815040e..747ed6007a 100644
--- a/src/components/Task/Drawer/CommentList/Item/Item.test.tsx
+++ b/src/components/Task/Drawer/CommentList/Item/Item.test.tsx
@@ -5,41 +5,47 @@ import { GetCommentsForTaskDrawerCommentListQuery_task_comments_nodes as Comment
import Item from '.';
describe('Item', () => {
- const comment: Comment = {
- id: 'def',
- body: 'The quick brown fox jumped over the lazy dog.',
- createdAt: '2019-10-12',
- me: false,
- person: {
- id: 'person-a',
- firstName: 'Bob',
- lastName: 'Jones',
- },
- };
+ const comment: Comment = {
+ id: 'def',
+ body: 'The quick brown fox jumped over the lazy dog.',
+ createdAt: '2019-10-12',
+ me: false,
+ person: {
+ id: 'person-a',
+ firstName: 'Bob',
+ lastName: 'Jones',
+ },
+ };
- beforeEach(() => {
- MockDate.set(new Date('2019-10-13'));
- });
+ beforeEach(() => {
+ MockDate.set(new Date('2019-10-13'));
+ });
- afterEach(() => {
- MockDate.reset();
- });
+ afterEach(() => {
+ MockDate.reset();
+ });
- it('has correct defaults', () => {
- const { getByTestId, getByText } = render( );
- expect(getByTestId('TaskDrawerCommentListItemAvatar')).toBeInTheDocument();
- expect(getByText('The quick brown fox jumped over the lazy dog.')).toBeInTheDocument();
- expect(getByText('B')).toBeInTheDocument();
- expect(getByText('1 day ago')).toBeInTheDocument();
- });
+ it('has correct defaults', () => {
+ const { getByTestId, getByText } = render( );
+ expect(getByTestId('TaskDrawerCommentListItemAvatar')).toBeInTheDocument();
+ expect(
+ getByText('The quick brown fox jumped over the lazy dog.'),
+ ).toBeInTheDocument();
+ expect(getByText('B')).toBeInTheDocument();
+ expect(getByText('1 day ago')).toBeInTheDocument();
+ });
- it('has correct overrides', () => {
- const { queryByTestId } = render( );
- expect(queryByTestId('TaskDrawerCommentListItemAvatar')).not.toBeInTheDocument();
- });
+ it('has correct overrides', () => {
+ const { queryByTestId } = render( );
+ expect(
+ queryByTestId('TaskDrawerCommentListItemAvatar'),
+ ).not.toBeInTheDocument();
+ });
- it('has loading state', () => {
- const { queryByTestId } = render( );
- expect(queryByTestId('TaskDrawerCommentListItemAvatar')).not.toBeInTheDocument();
- });
+ it('has loading state', () => {
+ const { queryByTestId } = render( );
+ expect(
+ queryByTestId('TaskDrawerCommentListItemAvatar'),
+ ).not.toBeInTheDocument();
+ });
});
diff --git a/src/components/Task/Drawer/CommentList/Item/Item.tsx b/src/components/Task/Drawer/CommentList/Item/Item.tsx
index ee3dbcdc2e..fcaf37b01a 100644
--- a/src/components/Task/Drawer/CommentList/Item/Item.tsx
+++ b/src/components/Task/Drawer/CommentList/Item/Item.tsx
@@ -1,142 +1,161 @@
import React, { ReactElement } from 'react';
-import { makeStyles, Theme, Avatar, Typography, Box, Tooltip, Slide } from '@material-ui/core';
+import {
+ makeStyles,
+ Theme,
+ Avatar,
+ Typography,
+ Box,
+ Tooltip,
+ Slide,
+} from '@material-ui/core';
import { formatDistanceToNow, isSameHour } from 'date-fns';
import { compact } from 'lodash/fp';
import { Skeleton } from '@material-ui/lab';
import { GetCommentsForTaskDrawerCommentListQuery_task_comments_nodes as Comment } from '../../../../../../types/GetCommentsForTaskDrawerCommentListQuery';
const useStyles = makeStyles((theme: Theme) => ({
- container: {
- display: 'grid',
- gridTemplateColumns: '40px 5px 1fr',
- alignItems: 'end',
- marginBottom: theme.spacing(2),
+ container: {
+ display: 'grid',
+ gridTemplateColumns: '40px 5px 1fr',
+ alignItems: 'end',
+ marginBottom: theme.spacing(2),
+ },
+ triangle: {
+ width: '0',
+ height: '0',
+ borderTop: '5px solid transparent',
+ borderRight: `5px solid ${theme.palette.divider}`,
+ },
+ box: {
+ display: 'inline-block',
+ backgroundColor: theme.palette.divider,
+ padding: theme.spacing(2),
+ borderRadius: '8px',
+ borderBottomLeftRadius: 0,
+ maxWidth: '80%',
+ },
+ typography: {
+ gridColumn: 3,
+ display: 'flex',
+ },
+ content: {},
+ avatar: {},
+ reverse: {
+ gridTemplateColumns: '1fr 5px',
+ '& $triangle': {
+ gridColumn: 2,
+ gridRow: 1,
+ borderLeft: `5px solid ${theme.palette.primary.main}`,
+ borderRight: 0,
},
- triangle: {
- width: '0',
- height: '0',
- borderTop: '5px solid transparent',
- borderRight: `5px solid ${theme.palette.divider}`,
+ '& $content': {
+ gridColumn: 1,
+ gridRow: 1,
+ textAlign: 'right',
},
- box: {
- display: 'inline-block',
- backgroundColor: theme.palette.divider,
- padding: theme.spacing(2),
- borderRadius: '8px',
- borderBottomLeftRadius: 0,
- maxWidth: '80%',
+ '& $box': {
+ backgroundColor: theme.palette.primary.main,
+ color: theme.palette.primary.contrastText,
+ borderBottomLeftRadius: '8px',
+ borderBottomRightRadius: 0,
},
- typography: {
- gridColumn: 3,
- display: 'flex',
+ '& $typography': {
+ gridColumn: 1,
+ justifyContent: 'flex-end',
},
- content: {},
- avatar: {},
- reverse: {
- gridTemplateColumns: '1fr 5px',
- '& $triangle': {
- gridColumn: 2,
- gridRow: 1,
- borderLeft: `5px solid ${theme.palette.primary.main}`,
- borderRight: 0,
- },
- '& $content': {
- gridColumn: 1,
- gridRow: 1,
- textAlign: 'right',
- },
- '& $box': {
- backgroundColor: theme.palette.primary.main,
- color: theme.palette.primary.contrastText,
- borderBottomLeftRadius: '8px',
- borderBottomRightRadius: 0,
- },
- '& $typography': {
- gridColumn: 1,
- justifyContent: 'flex-end',
- },
+ },
+ compact: {
+ marginBottom: 4,
+ '& $triangle': {
+ border: 0,
},
- compact: {
- marginBottom: 4,
- '& $triangle': {
- border: 0,
- },
- '& $box': {
- borderRadius: '8px',
- },
- '& $typography': {
- display: 'none',
- },
- '& $avatar': {
- display: 'none',
- },
+ '& $box': {
+ borderRadius: '8px',
},
+ '& $typography': {
+ display: 'none',
+ },
+ '& $avatar': {
+ display: 'none',
+ },
+ },
}));
interface Props {
- comment?: Comment;
- reverse?: boolean;
- nextComment?: Comment;
+ comment?: Comment;
+ reverse?: boolean;
+ nextComment?: Comment;
}
-const TaskDrawerCommentListItem = ({ comment, reverse, nextComment }: Props): ReactElement => {
- const classes = useStyles();
+const TaskDrawerCommentListItem = ({
+ comment,
+ reverse,
+ nextComment,
+}: Props): ReactElement => {
+ const classes = useStyles();
- const nextCommentMatches =
- comment?.person &&
- nextComment?.person &&
- nextComment.person.id === comment.person.id &&
- isSameHour(new Date(nextComment.createdAt), new Date(comment.createdAt));
+ const nextCommentMatches =
+ comment?.person &&
+ nextComment?.person &&
+ nextComment.person.id === comment.person.id &&
+ isSameHour(new Date(nextComment.createdAt), new Date(comment.createdAt));
- return (
-
-
- {!reverse && (
-
- {comment ? (
-
-
- {comment.person.firstName[0]}
-
-
- ) : (
-
- )}
-
- )}
-
-
-
- {comment ? (
- {comment.body}
- ) : (
- <>
-
-
- >
- )}
-
-
-
- {comment ? (
- formatDistanceToNow(new Date(comment.createdAt), { addSuffix: true })
- ) : (
-
- )}
-
-
-
- );
+ return (
+
+
+ {!reverse && (
+
+ {comment ? (
+
+
+ {comment.person.firstName[0]}
+
+
+ ) : (
+
+ )}
+
+ )}
+
+
+
+ {comment ? (
+ {comment.body}
+ ) : (
+ <>
+
+
+ >
+ )}
+
+
+
+ {comment ? (
+ formatDistanceToNow(new Date(comment.createdAt), {
+ addSuffix: true,
+ })
+ ) : (
+
+ )}
+
+
+
+ );
};
export default TaskDrawerCommentListItem;
diff --git a/src/components/Task/Drawer/CompleteForm/CompleteForm.mock.tsx b/src/components/Task/Drawer/CompleteForm/CompleteForm.mock.tsx
index bed55fb8ae..9d2de4c71a 100644
--- a/src/components/Task/Drawer/CompleteForm/CompleteForm.mock.tsx
+++ b/src/components/Task/Drawer/CompleteForm/CompleteForm.mock.tsx
@@ -1,114 +1,114 @@
import { MockedResponse } from '@apollo/client/testing';
import {
- CompleteTaskMutation,
- CompleteTaskMutation_updateTask_task as Task,
+ CompleteTaskMutation,
+ CompleteTaskMutation_updateTask_task as Task,
} from '../../../../../types/CompleteTaskMutation';
import {
- ResultEnum,
- ActivityTypeEnum,
- TaskUpdateInput,
- NotificationTypeEnum,
- NotificationTimeUnitEnum,
+ ResultEnum,
+ ActivityTypeEnum,
+ TaskUpdateInput,
+ NotificationTypeEnum,
+ NotificationTimeUnitEnum,
} from '../../../../../types/globalTypes';
import { GetTaskForTaskDrawerQuery } from '../../../../../types/GetTaskForTaskDrawerQuery';
import { GET_TASK_FOR_TASK_DRAWER_QUERY } from '../Drawer';
import { COMPLETE_TASK_MUTATION } from './CompleteForm';
export const getCompleteTaskForTaskDrawerMock = (): MockedResponse => {
- const data: GetTaskForTaskDrawerQuery = {
- task: {
- id: 'task-1',
- activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
- subject: 'On the Journey with the Johnson Family',
- startAt: new Date(2012, 12, 5, 1, 2),
- completedAt: new Date(2015, 12, 5, 1, 2),
- tagList: ['tag-1', 'tag-2'],
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
- },
- user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
- notificationTimeBefore: 20,
- notificationType: NotificationTypeEnum.BOTH,
- notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
- },
- };
- return {
- request: {
- query: GET_TASK_FOR_TASK_DRAWER_QUERY,
- variables: {
- accountListId: 'abc',
- taskId: 'task-1',
- },
- },
- result: {
- data,
- },
- };
+ const data: GetTaskForTaskDrawerQuery = {
+ task: {
+ id: 'task-1',
+ activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
+ subject: 'On the Journey with the Johnson Family',
+ startAt: new Date(2012, 12, 5, 1, 2),
+ completedAt: new Date(2015, 12, 5, 1, 2),
+ tagList: ['tag-1', 'tag-2'],
+ contacts: {
+ nodes: [
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
+ ],
+ },
+ user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
+ notificationTimeBefore: 20,
+ notificationType: NotificationTypeEnum.BOTH,
+ notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
+ },
+ };
+ return {
+ request: {
+ query: GET_TASK_FOR_TASK_DRAWER_QUERY,
+ variables: {
+ accountListId: 'abc',
+ taskId: 'task-1',
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export const completeSimpleTaskMutationMock = (): MockedResponse => {
- const task: Task = {
- id: 'task-1',
- completedAt: new Date(2015, 12, 5, 1, 2),
- tagList: ['tag-1', 'tag-2'],
- result: ResultEnum.NONE,
- nextAction: null,
- };
- const attributes: TaskUpdateInput = {
- id: 'task-1',
- completedAt: new Date(2015, 12, 5, 1, 2),
- tagList: ['tag-1', 'tag-2'],
- result: ResultEnum.NONE,
- };
- console.log(attributes);
- const data: CompleteTaskMutation = {
- updateTask: {
- task,
- },
- };
- return {
- request: {
- query: COMPLETE_TASK_MUTATION,
- variables: {
- accountListId: 'abc',
- attributes,
- },
- },
- result: { data },
- };
+ const task: Task = {
+ id: 'task-1',
+ completedAt: new Date(2015, 12, 5, 1, 2),
+ tagList: ['tag-1', 'tag-2'],
+ result: ResultEnum.NONE,
+ nextAction: null,
+ };
+ const attributes: TaskUpdateInput = {
+ id: 'task-1',
+ completedAt: new Date(2015, 12, 5, 1, 2),
+ tagList: ['tag-1', 'tag-2'],
+ result: ResultEnum.NONE,
+ };
+ console.log(attributes);
+ const data: CompleteTaskMutation = {
+ updateTask: {
+ task,
+ },
+ };
+ return {
+ request: {
+ query: COMPLETE_TASK_MUTATION,
+ variables: {
+ accountListId: 'abc',
+ attributes,
+ },
+ },
+ result: { data },
+ };
};
export const completeTaskMutationMock = (): MockedResponse => {
- const task: Task = {
- id: 'task-1',
- completedAt: new Date(2015, 12, 5, 1, 2),
- tagList: ['tag-1', 'tag-2'],
- result: ResultEnum.COMPLETED,
- nextAction: ActivityTypeEnum.APPOINTMENT,
- };
- const attributes: TaskUpdateInput = {
- id: 'task-1',
- completedAt: new Date(2015, 12, 5, 1, 2),
- tagList: ['tag-1', 'tag-2'],
- result: ResultEnum.COMPLETED,
- nextAction: ActivityTypeEnum.APPOINTMENT,
- };
- const data: CompleteTaskMutation = {
- updateTask: {
- task,
- },
- };
- return {
- request: {
- query: COMPLETE_TASK_MUTATION,
- variables: {
- accountListId: 'abc',
- attributes,
- },
- },
- result: { data },
- };
+ const task: Task = {
+ id: 'task-1',
+ completedAt: new Date(2015, 12, 5, 1, 2),
+ tagList: ['tag-1', 'tag-2'],
+ result: ResultEnum.COMPLETED,
+ nextAction: ActivityTypeEnum.APPOINTMENT,
+ };
+ const attributes: TaskUpdateInput = {
+ id: 'task-1',
+ completedAt: new Date(2015, 12, 5, 1, 2),
+ tagList: ['tag-1', 'tag-2'],
+ result: ResultEnum.COMPLETED,
+ nextAction: ActivityTypeEnum.APPOINTMENT,
+ };
+ const data: CompleteTaskMutation = {
+ updateTask: {
+ task,
+ },
+ };
+ return {
+ request: {
+ query: COMPLETE_TASK_MUTATION,
+ variables: {
+ accountListId: 'abc',
+ attributes,
+ },
+ },
+ result: { data },
+ };
};
export default completeTaskMutationMock;
diff --git a/src/components/Task/Drawer/CompleteForm/CompleteForm.stories.tsx b/src/components/Task/Drawer/CompleteForm/CompleteForm.stories.tsx
index 88eab11e02..4f29f79d33 100644
--- a/src/components/Task/Drawer/CompleteForm/CompleteForm.stories.tsx
+++ b/src/components/Task/Drawer/CompleteForm/CompleteForm.stories.tsx
@@ -1,63 +1,80 @@
import React, { ReactElement } from 'react';
import { MockedProvider } from '@apollo/client/testing';
import { getDataForTaskDrawerMock } from '../Form/Form.mock';
-import { ActivityTypeEnum, NotificationTypeEnum, NotificationTimeUnitEnum } from '../../../../../types/globalTypes';
-import { completeTaskMutationMock, completeSimpleTaskMutationMock } from './CompleteForm.mock';
+import {
+ ActivityTypeEnum,
+ NotificationTypeEnum,
+ NotificationTimeUnitEnum,
+} from '../../../../../types/globalTypes';
+import {
+ completeTaskMutationMock,
+ completeSimpleTaskMutationMock,
+} from './CompleteForm.mock';
import TaskDrawerCompletedForm from '.';
export default {
- title: 'Task/Drawer/CompleteForm',
+ title: 'Task/Drawer/CompleteForm',
};
const task = {
- id: 'task-1',
- activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
- subject: 'On the Journey with the Johnson Family',
- startAt: new Date(2012, 12, 5, 1, 2),
- completedAt: null,
- tagList: ['tag-1', 'tag-2'],
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
- },
- user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
- notificationTimeBefore: 20,
- notificationType: NotificationTypeEnum.BOTH,
- notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
+ id: 'task-1',
+ activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
+ subject: 'On the Journey with the Johnson Family',
+ startAt: new Date(2012, 12, 5, 1, 2),
+ completedAt: null,
+ tagList: ['tag-1', 'tag-2'],
+ contacts: {
+ nodes: [
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
+ ],
+ },
+ user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
+ notificationTimeBefore: 20,
+ notificationType: NotificationTypeEnum.BOTH,
+ notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
};
export const Default = (): ReactElement => {
- return (
-
- {}}
- />
-
- );
+ return (
+
+ {}}
+ />
+
+ );
};
export const WithResults = (): ReactElement => {
- return (
-
- {}}
- />
-
- );
+ return (
+
+ {}}
+ />
+
+ );
};
diff --git a/src/components/Task/Drawer/CompleteForm/CompleteForm.test.tsx b/src/components/Task/Drawer/CompleteForm/CompleteForm.test.tsx
index 0a38725fcf..caa78a6e36 100644
--- a/src/components/Task/Drawer/CompleteForm/CompleteForm.test.tsx
+++ b/src/components/Task/Drawer/CompleteForm/CompleteForm.test.tsx
@@ -5,354 +5,444 @@ import { getDataForTaskDrawerMock } from '../Form/Form.mock';
import TestWrapper from '../../../../../__tests__/util/TestWrapper';
import { dateFormat } from '../../../../lib/intlFormat/intlFormat';
import {
- ActivityTypeEnum,
- NotificationTypeEnum,
- NotificationTimeUnitEnum,
- ResultEnum,
+ ActivityTypeEnum,
+ NotificationTypeEnum,
+ NotificationTimeUnitEnum,
+ ResultEnum,
} from '../../../../../types/globalTypes';
import { useApp } from '../../../App';
-import { completeTaskMutationMock, completeSimpleTaskMutationMock } from './CompleteForm.mock';
+import {
+ completeTaskMutationMock,
+ completeSimpleTaskMutationMock,
+} from './CompleteForm.mock';
import TaskDrawerCompleteForm from '.';
jest.mock('../../../App', () => ({
- useApp: jest.fn(),
+ useApp: jest.fn(),
}));
const openTaskDrawer = jest.fn();
beforeEach(() => {
- (useApp as jest.Mock).mockReturnValue({
- openTaskDrawer,
- });
+ (useApp as jest.Mock).mockReturnValue({
+ openTaskDrawer,
+ });
});
describe('TaskDrawerCompleteForm', () => {
- const task = {
- id: 'task-1',
- activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
- subject: 'On the Journey with the Johnson Family',
- startAt: new Date(2012, 12, 5, 1, 2),
- completedAt: null,
- tagList: ['tag-1', 'tag-2'],
+ const task = {
+ id: 'task-1',
+ activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
+ subject: 'On the Journey with the Johnson Family',
+ startAt: new Date(2012, 12, 5, 1, 2),
+ completedAt: null,
+ tagList: ['tag-1', 'tag-2'],
+ contacts: {
+ nodes: [
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
+ ],
+ },
+ user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
+ notificationTimeBefore: 20,
+ notificationType: NotificationTypeEnum.BOTH,
+ notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
+ };
+
+ it('default', async () => {
+ const { getAllByRole } = render(
+
+
+ ,
+ );
+ const dateString = dateFormat(new Date());
+ expect(
+ getAllByRole('textbox').find(
+ (item: HTMLInputElement) => item.value === dateString,
+ ),
+ ).toBeInTheDocument();
+ });
+
+ it('saves simple', async () => {
+ const onClose = jest.fn();
+ const { getByText } = render(
+
+
+ ,
+ );
+ userEvent.click(getByText('Save'));
+ await waitFor(() => expect(onClose).toHaveBeenCalled());
+ expect(openTaskDrawer).not.toHaveBeenCalled();
+ });
+
+ it('saves complex', async () => {
+ const onClose = jest.fn();
+ const { getByRole, getByText } = render(
+
+
+ ,
+ );
+ userEvent.click(getByRole('button', { name: 'Result' }));
+ userEvent.click(
+ within(getByRole('listbox', { name: 'Result' })).getByText('COMPLETED'),
+ );
+ userEvent.click(getByRole('button', { name: 'Next Action' }));
+ userEvent.click(
+ within(getByRole('listbox', { name: 'Next Action' })).getByText(
+ 'APPOINTMENT',
+ ),
+ );
+ const tagsElement = getByRole('textbox', { name: 'Tags' });
+ userEvent.click(tagsElement);
+ userEvent.click(
+ await within(getByRole('presentation')).findByText('tag-1'),
+ );
+ userEvent.click(tagsElement);
+ userEvent.click(within(getByRole('presentation')).getByText('tag-2'));
+ userEvent.click(getByText('Save'));
+ await waitFor(() => expect(onClose).toHaveBeenCalled());
+ expect(openTaskDrawer).toHaveBeenCalledWith({
+ defaultValues: {
+ activityType: ActivityTypeEnum.APPOINTMENT,
contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
+ nodes: [
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
+ ],
},
user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
- notificationTimeBefore: 20,
- notificationType: NotificationTypeEnum.BOTH,
- notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
- };
-
- it('default', async () => {
- const { getAllByRole } = render(
-
-
- ,
- );
- const dateString = dateFormat(new Date());
- expect(getAllByRole('textbox').find((item: HTMLInputElement) => item.value === dateString)).toBeInTheDocument();
+ },
});
+ });
- it('saves simple', async () => {
- const onClose = jest.fn();
- const { getByText } = render(
-
-
- ,
- );
- userEvent.click(getByText('Save'));
- await waitFor(() => expect(onClose).toHaveBeenCalled());
- expect(openTaskDrawer).not.toHaveBeenCalled();
- });
+ const getOptions = (
+ activityType: ActivityTypeEnum,
+ ): { results: ResultEnum[]; nextActions: ActivityTypeEnum[] } => {
+ const { getByRole, queryByRole } = render(
+
+
+ ,
+ );
+ let results = [];
+ if (queryByRole('button', { name: 'Result' })) {
+ userEvent.click(getByRole('button', { name: 'Result' }));
+ results = within(getByRole('listbox', { name: 'Result' }))
+ .getAllByRole('option')
+ .map((option) => ResultEnum[option.textContent]);
+ userEvent.click(getByRole('option', { name: 'NONE' }));
+ }
+ let nextActions = [];
+ if (queryByRole('button', { name: 'Next Action' })) {
+ userEvent.click(getByRole('button', { name: 'Next Action' }));
+ nextActions = within(getByRole('listbox', { name: 'Next Action' }))
+ .getAllByRole('option')
+ .map((option) => ActivityTypeEnum[option.textContent]);
+ }
+ return { results, nextActions };
+ };
- it('saves complex', async () => {
- const onClose = jest.fn();
- const { getByRole, getByText } = render(
-
-
- ,
- );
- userEvent.click(getByRole('button', { name: 'Result' }));
- userEvent.click(within(getByRole('listbox', { name: 'Result' })).getByText('COMPLETED'));
- userEvent.click(getByRole('button', { name: 'Next Action' }));
- userEvent.click(within(getByRole('listbox', { name: 'Next Action' })).getByText('APPOINTMENT'));
- const tagsElement = getByRole('textbox', { name: 'Tags' });
- userEvent.click(tagsElement);
- userEvent.click(await within(getByRole('presentation')).findByText('tag-1'));
- userEvent.click(tagsElement);
- userEvent.click(within(getByRole('presentation')).getByText('tag-2'));
- userEvent.click(getByText('Save'));
- await waitFor(() => expect(onClose).toHaveBeenCalled());
- expect(openTaskDrawer).toHaveBeenCalledWith({
- defaultValues: {
- activityType: ActivityTypeEnum.APPOINTMENT,
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
- },
- user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
- },
- });
- });
+ it('has correct options for APPOINTMENT', () => {
+ const { results, nextActions } = getOptions(ActivityTypeEnum.APPOINTMENT);
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.ATTEMPTED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ActivityTypeEnum.PRAYER_REQUEST,
+ ActivityTypeEnum.THANK,
+ ]);
+ });
- const getOptions = (activityType: ActivityTypeEnum): { results: ResultEnum[]; nextActions: ActivityTypeEnum[] } => {
- const { getByRole, queryByRole } = render(
-
-
- ,
- );
- let results = [];
- if (queryByRole('button', { name: 'Result' })) {
- userEvent.click(getByRole('button', { name: 'Result' }));
- results = within(getByRole('listbox', { name: 'Result' }))
- .getAllByRole('option')
- .map((option) => ResultEnum[option.textContent]);
- userEvent.click(getByRole('option', { name: 'NONE' }));
- }
- let nextActions = [];
- if (queryByRole('button', { name: 'Next Action' })) {
- userEvent.click(getByRole('button', { name: 'Next Action' }));
- nextActions = within(getByRole('listbox', { name: 'Next Action' }))
- .getAllByRole('option')
- .map((option) => ActivityTypeEnum[option.textContent]);
- }
- return { results, nextActions };
- };
+ it('has correct options for CALL', () => {
+ const { results, nextActions } = getOptions(ActivityTypeEnum.CALL);
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.ATTEMPTED,
+ ResultEnum.ATTEMPTED_LEFT_MESSAGE,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ActivityTypeEnum.APPOINTMENT,
+ ActivityTypeEnum.PRAYER_REQUEST,
+ ActivityTypeEnum.THANK,
+ ]);
+ });
- it('has correct options for APPOINTMENT', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.APPOINTMENT);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.ATTEMPTED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ActivityTypeEnum.PRAYER_REQUEST,
- ActivityTypeEnum.THANK,
- ]);
- });
+ it('has correct options for EMAIL', () => {
+ const { results, nextActions } = getOptions(ActivityTypeEnum.EMAIL);
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ActivityTypeEnum.APPOINTMENT,
+ ActivityTypeEnum.PRAYER_REQUEST,
+ ActivityTypeEnum.THANK,
+ ]);
+ });
- it('has correct options for CALL', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.CALL);
- expect(results).toEqual([
- ResultEnum.NONE,
- ResultEnum.COMPLETED,
- ResultEnum.ATTEMPTED,
- ResultEnum.ATTEMPTED_LEFT_MESSAGE,
- ResultEnum.RECEIVED,
- ]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ActivityTypeEnum.APPOINTMENT,
- ActivityTypeEnum.PRAYER_REQUEST,
- ActivityTypeEnum.THANK,
- ]);
- });
+ it('has correct options for FACEBOOK_MESSAGE', () => {
+ const { results, nextActions } = getOptions(
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ );
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ActivityTypeEnum.APPOINTMENT,
+ ActivityTypeEnum.PRAYER_REQUEST,
+ ActivityTypeEnum.THANK,
+ ]);
+ });
- it('has correct options for EMAIL', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.EMAIL);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.RECEIVED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ActivityTypeEnum.APPOINTMENT,
- ActivityTypeEnum.PRAYER_REQUEST,
- ActivityTypeEnum.THANK,
- ]);
- });
+ it('has correct options for LETTER', () => {
+ const { results, nextActions } = getOptions(ActivityTypeEnum.LETTER);
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ]);
+ });
- it('has correct options for FACEBOOK_MESSAGE', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.FACEBOOK_MESSAGE);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.RECEIVED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ActivityTypeEnum.APPOINTMENT,
- ActivityTypeEnum.PRAYER_REQUEST,
- ActivityTypeEnum.THANK,
- ]);
- });
+ it('has correct options for NEWSLETTER_EMAIL', () => {
+ const { results, nextActions } = getOptions(
+ ActivityTypeEnum.NEWSLETTER_EMAIL,
+ );
+ expect(results).toEqual([]);
+ expect(nextActions).toEqual([]);
+ });
- it('has correct options for LETTER', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.LETTER);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.RECEIVED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ]);
- });
+ it('has correct options for NEWSLETTER_PHYSICAL', () => {
+ const { results, nextActions } = getOptions(
+ ActivityTypeEnum.NEWSLETTER_PHYSICAL,
+ );
+ expect(results).toEqual([]);
+ expect(nextActions).toEqual([]);
+ });
- it('has correct options for NEWSLETTER_EMAIL', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.NEWSLETTER_EMAIL);
- expect(results).toEqual([]);
- expect(nextActions).toEqual([]);
- });
+ it('has correct options for NONE', () => {
+ const { results, nextActions } = getOptions(ActivityTypeEnum.NONE);
+ expect(results).toEqual([]);
+ expect(nextActions).toEqual([]);
+ });
- it('has correct options for NEWSLETTER_PHYSICAL', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.NEWSLETTER_PHYSICAL);
- expect(results).toEqual([]);
- expect(nextActions).toEqual([]);
- });
+ it('has correct options for PRAYER_REQUEST', () => {
+ const { results, nextActions } = getOptions(
+ ActivityTypeEnum.PRAYER_REQUEST,
+ );
+ expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ActivityTypeEnum.APPOINTMENT,
+ ActivityTypeEnum.PRAYER_REQUEST,
+ ActivityTypeEnum.THANK,
+ ]);
+ });
- it('has correct options for NONE', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.NONE);
- expect(results).toEqual([]);
- expect(nextActions).toEqual([]);
- });
+ it('has correct options for PRE_CALL_LETTER', () => {
+ const { results, nextActions } = getOptions(
+ ActivityTypeEnum.PRE_CALL_LETTER,
+ );
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ]);
+ });
- it('has correct options for PRAYER_REQUEST', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.PRAYER_REQUEST);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ActivityTypeEnum.APPOINTMENT,
- ActivityTypeEnum.PRAYER_REQUEST,
- ActivityTypeEnum.THANK,
- ]);
- });
+ it('has correct options for REMINDER_LETTER', () => {
+ const { results, nextActions } = getOptions(
+ ActivityTypeEnum.REMINDER_LETTER,
+ );
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ]);
+ });
- it('has correct options for PRE_CALL_LETTER', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.PRE_CALL_LETTER);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.RECEIVED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ]);
- });
+ it('has correct options for SUPPORT_LETTER', () => {
+ const { results, nextActions } = getOptions(
+ ActivityTypeEnum.SUPPORT_LETTER,
+ );
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ]);
+ });
- it('has correct options for REMINDER_LETTER', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.REMINDER_LETTER);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.RECEIVED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ]);
- });
+ it('has correct options for TALK_TO_IN_PERSON', () => {
+ const { results, nextActions } = getOptions(
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ );
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ActivityTypeEnum.APPOINTMENT,
+ ActivityTypeEnum.PRAYER_REQUEST,
+ ActivityTypeEnum.THANK,
+ ]);
+ });
- it('has correct options for SUPPORT_LETTER', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.SUPPORT_LETTER);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.RECEIVED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ]);
- });
+ it('has correct options for TEXT_MESSAGE', () => {
+ const { results, nextActions } = getOptions(ActivityTypeEnum.TEXT_MESSAGE);
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ActivityTypeEnum.APPOINTMENT,
+ ActivityTypeEnum.PRAYER_REQUEST,
+ ActivityTypeEnum.THANK,
+ ]);
+ });
- it('has correct options for TALK_TO_IN_PERSON', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.TALK_TO_IN_PERSON);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.RECEIVED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ActivityTypeEnum.APPOINTMENT,
- ActivityTypeEnum.PRAYER_REQUEST,
- ActivityTypeEnum.THANK,
- ]);
- });
+ it('has correct options for THANK', () => {
+ const { results, nextActions } = getOptions(ActivityTypeEnum.THANK);
+ expect(results).toEqual([
+ ResultEnum.NONE,
+ ResultEnum.COMPLETED,
+ ResultEnum.RECEIVED,
+ ]);
+ expect(nextActions).toEqual([
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ]);
+ });
- it('has correct options for TEXT_MESSAGE', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.TEXT_MESSAGE);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.RECEIVED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ActivityTypeEnum.APPOINTMENT,
- ActivityTypeEnum.PRAYER_REQUEST,
- ActivityTypeEnum.THANK,
- ]);
- });
-
- it('has correct options for THANK', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.THANK);
- expect(results).toEqual([ResultEnum.NONE, ResultEnum.COMPLETED, ResultEnum.RECEIVED]);
- expect(nextActions).toEqual([
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
- ]);
- });
+ it('has correct options for TO_DO', () => {
+ const { results, nextActions } = getOptions(ActivityTypeEnum.TO_DO);
+ expect(results).toEqual([]);
+ expect(nextActions).toEqual([]);
+ });
- it('has correct options for TO_DO', () => {
- const { results, nextActions } = getOptions(ActivityTypeEnum.TO_DO);
- expect(results).toEqual([]);
- expect(nextActions).toEqual([]);
- });
-
- it('has correct options for null', () => {
- const { results, nextActions } = getOptions(null);
- expect(results).toEqual([]);
- expect(nextActions).toEqual([]);
- });
+ it('has correct options for null', () => {
+ const { results, nextActions } = getOptions(null);
+ expect(results).toEqual([]);
+ expect(nextActions).toEqual([]);
+ });
});
diff --git a/src/components/Task/Drawer/CompleteForm/CompleteForm.tsx b/src/components/Task/Drawer/CompleteForm/CompleteForm.tsx
index 445e18e14e..1d31b1c249 100644
--- a/src/components/Task/Drawer/CompleteForm/CompleteForm.tsx
+++ b/src/components/Task/Drawer/CompleteForm/CompleteForm.tsx
@@ -1,18 +1,18 @@
import React, { ReactElement } from 'react';
import {
- makeStyles,
- Theme,
- TextField,
- Select,
- MenuItem,
- InputLabel,
- FormControl,
- Chip,
- Grid,
- Box,
- CircularProgress,
- Button,
- Divider,
+ makeStyles,
+ Theme,
+ TextField,
+ Select,
+ MenuItem,
+ InputLabel,
+ FormControl,
+ Chip,
+ Grid,
+ Box,
+ CircularProgress,
+ Button,
+ Divider,
} from '@material-ui/core';
import { useTranslation } from 'react-i18next';
import { Autocomplete } from '@material-ui/lab';
@@ -25,293 +25,342 @@ import { dateFormat } from '../../../../lib/intlFormat/intlFormat';
import { GetDataForTaskDrawerQuery } from '../../../../../types/GetDataForTaskDrawerQuery';
import { GetTaskForTaskDrawerQuery_task as Task } from '../../../../../types/GetTaskForTaskDrawerQuery';
import { GET_DATA_FOR_TASK_DRAWER_QUERY } from '../Form/Form';
-import { ResultEnum, ActivityTypeEnum, TaskUpdateInput } from '../../../../../types/globalTypes';
+import {
+ ResultEnum,
+ ActivityTypeEnum,
+ TaskUpdateInput,
+} from '../../../../../types/globalTypes';
import { CompleteTaskMutation } from '../../../../../types/CompleteTaskMutation';
import { useApp } from '../../../App';
const useStyles = makeStyles((theme: Theme) => ({
- formControl: {
- width: '100%',
- },
- select: {
- fontSize: theme.typography.h6.fontSize,
- minHeight: 'auto',
- '&:focus': {
- backgroundColor: 'transparent',
- },
- },
- container: {
- padding: theme.spacing(2, 2),
- },
- title: {
- flexGrow: 1,
+ formControl: {
+ width: '100%',
+ },
+ select: {
+ fontSize: theme.typography.h6.fontSize,
+ minHeight: 'auto',
+ '&:focus': {
+ backgroundColor: 'transparent',
},
+ },
+ container: {
+ padding: theme.spacing(2, 2),
+ },
+ title: {
+ flexGrow: 1,
+ },
}));
export const COMPLETE_TASK_MUTATION = gql`
- mutation CompleteTaskMutation($accountListId: ID!, $attributes: TaskUpdateInput!) {
- updateTask(input: { accountListId: $accountListId, attributes: $attributes }) {
- task {
- id
- result
- nextAction
- tagList
- completedAt
- }
- }
+ mutation CompleteTaskMutation(
+ $accountListId: ID!
+ $attributes: TaskUpdateInput!
+ ) {
+ updateTask(
+ input: { accountListId: $accountListId, attributes: $attributes }
+ ) {
+ task {
+ id
+ result
+ nextAction
+ tagList
+ completedAt
+ }
}
+ }
`;
const taskSchema: yup.SchemaOf<
- Required>
+ Required<
+ Pick<
+ TaskUpdateInput,
+ 'id' | 'result' | 'nextAction' | 'tagList' | 'completedAt'
+ >
+ >
> = yup.object({
- id: yup.string(),
- result: yup.mixed().required(),
- nextAction: yup.mixed(),
- tagList: yup.array().of(yup.string()).default([]),
- completedAt: yup.date(),
+ id: yup.string(),
+ result: yup.mixed().required(),
+ nextAction: yup.mixed(),
+ tagList: yup.array().of(yup.string()).default([]),
+ completedAt: yup.date(),
});
interface Props {
- accountListId: string;
- task: Task;
- onClose: () => void;
+ accountListId: string;
+ task: Task;
+ onClose: () => void;
}
-const TaskDrawerCompleteForm = ({ accountListId, task, onClose }: Props): ReactElement => {
- const initialTask: TaskUpdateInput = {
- id: task.id,
- completedAt: task.completedAt || new Date(),
- result: ResultEnum.NONE,
- tagList: task.tagList,
- };
+const TaskDrawerCompleteForm = ({
+ accountListId,
+ task,
+ onClose,
+}: Props): ReactElement => {
+ const initialTask: TaskUpdateInput = {
+ id: task.id,
+ completedAt: task.completedAt || new Date(),
+ result: ResultEnum.NONE,
+ tagList: task.tagList,
+ };
- const classes = useStyles();
- const { t } = useTranslation();
- const { enqueueSnackbar } = useSnackbar();
- const { openTaskDrawer } = useApp();
- const { data } = useQuery(GET_DATA_FOR_TASK_DRAWER_QUERY, {
- variables: { accountListId },
- });
- const [updateTask, { loading: saving }] = useMutation(COMPLETE_TASK_MUTATION);
- const onSubmit = async (attributes: TaskUpdateInput): Promise => {
- try {
- await updateTask({ variables: { accountListId, attributes } });
- enqueueSnackbar(t('Task saved successfully'), { variant: 'success' });
- onClose();
- if (attributes.nextAction && attributes.nextAction !== ActivityTypeEnum.NONE) {
- openTaskDrawer({
- defaultValues: {
- activityType: attributes.nextAction,
- contacts: task.contacts,
- user: task.user,
- },
- });
- }
- } catch (error) {
- enqueueSnackbar(error.message, { variant: 'error' });
- }
- };
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const { enqueueSnackbar } = useSnackbar();
+ const { openTaskDrawer } = useApp();
+ const { data } = useQuery(
+ GET_DATA_FOR_TASK_DRAWER_QUERY,
+ {
+ variables: { accountListId },
+ },
+ );
+ const [updateTask, { loading: saving }] = useMutation(
+ COMPLETE_TASK_MUTATION,
+ );
+ const onSubmit = async (attributes: TaskUpdateInput): Promise => {
+ try {
+ await updateTask({ variables: { accountListId, attributes } });
+ enqueueSnackbar(t('Task saved successfully'), { variant: 'success' });
+ onClose();
+ if (
+ attributes.nextAction &&
+ attributes.nextAction !== ActivityTypeEnum.NONE
+ ) {
+ openTaskDrawer({
+ defaultValues: {
+ activityType: attributes.nextAction,
+ contacts: task.contacts,
+ user: task.user,
+ },
+ });
+ }
+ } catch (error) {
+ enqueueSnackbar(error.message, { variant: 'error' });
+ }
+ };
- const availableResults = ((): ResultEnum[] => {
- const common = [ResultEnum.NONE, ResultEnum.COMPLETED];
- switch (task.activityType) {
- case ActivityTypeEnum.CALL:
- return [...common, ResultEnum.ATTEMPTED, ResultEnum.ATTEMPTED_LEFT_MESSAGE, ResultEnum.RECEIVED];
- case ActivityTypeEnum.APPOINTMENT:
- return [...common, ResultEnum.ATTEMPTED];
- case ActivityTypeEnum.EMAIL:
- case ActivityTypeEnum.TEXT_MESSAGE:
- case ActivityTypeEnum.FACEBOOK_MESSAGE:
- case ActivityTypeEnum.TALK_TO_IN_PERSON:
- case ActivityTypeEnum.LETTER:
- case ActivityTypeEnum.PRE_CALL_LETTER:
- case ActivityTypeEnum.REMINDER_LETTER:
- case ActivityTypeEnum.SUPPORT_LETTER:
- case ActivityTypeEnum.THANK:
- return [...common, ResultEnum.RECEIVED];
- case ActivityTypeEnum.PRAYER_REQUEST:
- return common;
- default:
- return [];
- }
- })();
+ const availableResults = ((): ResultEnum[] => {
+ const common = [ResultEnum.NONE, ResultEnum.COMPLETED];
+ switch (task.activityType) {
+ case ActivityTypeEnum.CALL:
+ return [
+ ...common,
+ ResultEnum.ATTEMPTED,
+ ResultEnum.ATTEMPTED_LEFT_MESSAGE,
+ ResultEnum.RECEIVED,
+ ];
+ case ActivityTypeEnum.APPOINTMENT:
+ return [...common, ResultEnum.ATTEMPTED];
+ case ActivityTypeEnum.EMAIL:
+ case ActivityTypeEnum.TEXT_MESSAGE:
+ case ActivityTypeEnum.FACEBOOK_MESSAGE:
+ case ActivityTypeEnum.TALK_TO_IN_PERSON:
+ case ActivityTypeEnum.LETTER:
+ case ActivityTypeEnum.PRE_CALL_LETTER:
+ case ActivityTypeEnum.REMINDER_LETTER:
+ case ActivityTypeEnum.SUPPORT_LETTER:
+ case ActivityTypeEnum.THANK:
+ return [...common, ResultEnum.RECEIVED];
+ case ActivityTypeEnum.PRAYER_REQUEST:
+ return common;
+ default:
+ return [];
+ }
+ })();
- const availableNextActions = ((): ActivityTypeEnum[] => {
- const common = [
- ActivityTypeEnum.NONE,
- ActivityTypeEnum.CALL,
- ActivityTypeEnum.EMAIL,
- ActivityTypeEnum.TEXT_MESSAGE,
- ActivityTypeEnum.FACEBOOK_MESSAGE,
- ActivityTypeEnum.TALK_TO_IN_PERSON,
+ const availableNextActions = ((): ActivityTypeEnum[] => {
+ const common = [
+ ActivityTypeEnum.NONE,
+ ActivityTypeEnum.CALL,
+ ActivityTypeEnum.EMAIL,
+ ActivityTypeEnum.TEXT_MESSAGE,
+ ActivityTypeEnum.FACEBOOK_MESSAGE,
+ ActivityTypeEnum.TALK_TO_IN_PERSON,
+ ];
+ switch (task.activityType) {
+ case ActivityTypeEnum.CALL:
+ case ActivityTypeEnum.EMAIL:
+ case ActivityTypeEnum.TEXT_MESSAGE:
+ case ActivityTypeEnum.FACEBOOK_MESSAGE:
+ case ActivityTypeEnum.TALK_TO_IN_PERSON:
+ case ActivityTypeEnum.PRAYER_REQUEST:
+ return [
+ ...common,
+ ActivityTypeEnum.APPOINTMENT,
+ ActivityTypeEnum.PRAYER_REQUEST,
+ ActivityTypeEnum.THANK,
];
- switch (task.activityType) {
- case ActivityTypeEnum.CALL:
- case ActivityTypeEnum.EMAIL:
- case ActivityTypeEnum.TEXT_MESSAGE:
- case ActivityTypeEnum.FACEBOOK_MESSAGE:
- case ActivityTypeEnum.TALK_TO_IN_PERSON:
- case ActivityTypeEnum.PRAYER_REQUEST:
- return [
- ...common,
- ActivityTypeEnum.APPOINTMENT,
- ActivityTypeEnum.PRAYER_REQUEST,
- ActivityTypeEnum.THANK,
- ];
- case ActivityTypeEnum.APPOINTMENT:
- return [...common, ActivityTypeEnum.PRAYER_REQUEST, ActivityTypeEnum.THANK];
- case ActivityTypeEnum.LETTER:
- case ActivityTypeEnum.PRE_CALL_LETTER:
- case ActivityTypeEnum.REMINDER_LETTER:
- case ActivityTypeEnum.SUPPORT_LETTER:
- case ActivityTypeEnum.THANK:
- return common;
- default:
- return [];
- }
- })();
+ case ActivityTypeEnum.APPOINTMENT:
+ return [
+ ...common,
+ ActivityTypeEnum.PRAYER_REQUEST,
+ ActivityTypeEnum.THANK,
+ ];
+ case ActivityTypeEnum.LETTER:
+ case ActivityTypeEnum.PRE_CALL_LETTER:
+ case ActivityTypeEnum.REMINDER_LETTER:
+ case ActivityTypeEnum.SUPPORT_LETTER:
+ case ActivityTypeEnum.THANK:
+ return common;
+ default:
+ return [];
+ }
+ })();
- return (
-
- {({
- values: { result, nextAction, completedAt, tagList },
- setFieldValue,
- handleChange,
- handleSubmit,
- isSubmitting,
- isValid,
- }): ReactElement => (
-
- )}
-
- );
+ return (
+
+ {({
+ values: { result, nextAction, completedAt, tagList },
+ setFieldValue,
+ handleChange,
+ handleSubmit,
+ isSubmitting,
+ isValid,
+ }): ReactElement => (
+
+ )}
+
+ );
};
export default TaskDrawerCompleteForm;
diff --git a/src/components/Task/Drawer/ContactList/ContactList.mock.tsx b/src/components/Task/Drawer/ContactList/ContactList.mock.tsx
index e9417cd8cd..b4a0511913 100644
--- a/src/components/Task/Drawer/ContactList/ContactList.mock.tsx
+++ b/src/components/Task/Drawer/ContactList/ContactList.mock.tsx
@@ -1,107 +1,111 @@
import { MockedResponse } from '@apollo/client/testing';
import { GetContactsForTaskDrawerContactListQuery } from '../../../../../types/GetContactsForTaskDrawerContactListQuery';
-import { StatusEnum, PledgeFrequencyEnum, SendNewsletterEnum } from '../../../../../types/globalTypes';
+import {
+ StatusEnum,
+ PledgeFrequencyEnum,
+ SendNewsletterEnum,
+} from '../../../../../types/globalTypes';
import { GET_CONTACTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY } from './ContactList';
export const getContactsForTaskDrawerContactListMock = (): MockedResponse => {
- const data: GetContactsForTaskDrawerContactListQuery = {
- contacts: {
- nodes: [
- {
- id: 'contact-1',
- name: 'Quinn, Anthony',
- primaryAddress: {
- id: 'primaryAddress-a',
- street: '125 Michael Ave',
- city: 'Hamilton',
- state: 'Waikato',
- postalCode: '3210',
- location: 'Work',
- },
- primaryPerson: {
- id: 'primaryPerson-a',
- title: 'Mr',
- firstName: 'Anthony',
- lastName: 'Quinn',
- suffix: 'Phd.',
- primaryEmailAddress: {
- id: 'primaryEmailAddress-a',
- email: 'anthony.quinn@gmail.com',
- location: 'Home',
- },
- primaryPhoneNumber: {
- id: 'primaryPhoneNumber-a',
- number: '(021) 986-821',
- location: 'Work',
- },
- },
- status: StatusEnum.PARTNER_FINANCIAL,
- sendNewsletter: SendNewsletterEnum.BOTH,
- lastDonation: {
- id: 'lastDonation-a',
- amount: {
- amount: 50,
- currency: 'NZD',
- conversionDate: '2020-10-12',
- },
- },
- pledgeAmount: 20,
- pledgeCurrency: 'NZD',
- pledgeFrequency: PledgeFrequencyEnum.MONTHLY,
- tagList: ['test', 'post'],
- },
- {
- id: 'contact-2',
- name: 'Phillips, Guy',
- primaryAddress: null,
- primaryPerson: null,
- status: null,
- sendNewsletter: null,
- lastDonation: null,
- pledgeAmount: null,
- pledgeCurrency: null,
- pledgeFrequency: null,
- tagList: [],
- },
- ],
- },
- };
- return {
- request: {
- query: GET_CONTACTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
- variables: {
- accountListId: 'abc',
- contactIds: ['contact-1', 'contact-2'],
+ const data: GetContactsForTaskDrawerContactListQuery = {
+ contacts: {
+ nodes: [
+ {
+ id: 'contact-1',
+ name: 'Quinn, Anthony',
+ primaryAddress: {
+ id: 'primaryAddress-a',
+ street: '125 Michael Ave',
+ city: 'Hamilton',
+ state: 'Waikato',
+ postalCode: '3210',
+ location: 'Work',
+ },
+ primaryPerson: {
+ id: 'primaryPerson-a',
+ title: 'Mr',
+ firstName: 'Anthony',
+ lastName: 'Quinn',
+ suffix: 'Phd.',
+ primaryEmailAddress: {
+ id: 'primaryEmailAddress-a',
+ email: 'anthony.quinn@gmail.com',
+ location: 'Home',
+ },
+ primaryPhoneNumber: {
+ id: 'primaryPhoneNumber-a',
+ number: '(021) 986-821',
+ location: 'Work',
+ },
+ },
+ status: StatusEnum.PARTNER_FINANCIAL,
+ sendNewsletter: SendNewsletterEnum.BOTH,
+ lastDonation: {
+ id: 'lastDonation-a',
+ amount: {
+ amount: 50,
+ currency: 'NZD',
+ conversionDate: '2020-10-12',
},
+ },
+ pledgeAmount: 20,
+ pledgeCurrency: 'NZD',
+ pledgeFrequency: PledgeFrequencyEnum.MONTHLY,
+ tagList: ['test', 'post'],
},
- result: {
- data,
+ {
+ id: 'contact-2',
+ name: 'Phillips, Guy',
+ primaryAddress: null,
+ primaryPerson: null,
+ status: null,
+ sendNewsletter: null,
+ lastDonation: null,
+ pledgeAmount: null,
+ pledgeCurrency: null,
+ pledgeFrequency: null,
+ tagList: [],
},
- };
+ ],
+ },
+ };
+ return {
+ request: {
+ query: GET_CONTACTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
+ variables: {
+ accountListId: 'abc',
+ contactIds: ['contact-1', 'contact-2'],
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export const getContactsForTaskDrawerContactListEmptyMock = (): MockedResponse => {
- return {
- request: {
- query: GET_CONTACTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
- variables: {
- accountListId: 'abc',
- contactIds: ['contact-1', 'contact-2'],
- },
- },
- result: {
- data: {
- contacts: {
- nodes: [],
- },
- },
+ return {
+ request: {
+ query: GET_CONTACTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
+ variables: {
+ accountListId: 'abc',
+ contactIds: ['contact-1', 'contact-2'],
+ },
+ },
+ result: {
+ data: {
+ contacts: {
+ nodes: [],
},
- };
+ },
+ },
+ };
};
export const getContactsForTaskDrawerContactListLoadingMock = (): MockedResponse => {
- return {
- ...getContactsForTaskDrawerContactListMock(),
- delay: 100931731455,
- };
+ return {
+ ...getContactsForTaskDrawerContactListMock(),
+ delay: 100931731455,
+ };
};
diff --git a/src/components/Task/Drawer/ContactList/ContactList.stories.tsx b/src/components/Task/Drawer/ContactList/ContactList.stories.tsx
index 5f0d802215..4e5009150a 100644
--- a/src/components/Task/Drawer/ContactList/ContactList.stories.tsx
+++ b/src/components/Task/Drawer/ContactList/ContactList.stories.tsx
@@ -1,35 +1,50 @@
import React, { ReactElement } from 'react';
import { MockedProvider } from '@apollo/client/testing';
import {
- getContactsForTaskDrawerContactListEmptyMock,
- getContactsForTaskDrawerContactListMock,
+ getContactsForTaskDrawerContactListEmptyMock,
+ getContactsForTaskDrawerContactListMock,
} from './ContactList.mock';
import TaskDrawerContactList from '.';
export default {
- title: 'Task/Drawer/ContactList',
+ title: 'Task/Drawer/ContactList',
};
export const Default = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const Empty = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Task/Drawer/ContactList/ContactList.test.tsx b/src/components/Task/Drawer/ContactList/ContactList.test.tsx
index ea7b83d2fa..b6469f31cc 100644
--- a/src/components/Task/Drawer/ContactList/ContactList.test.tsx
+++ b/src/components/Task/Drawer/ContactList/ContactList.test.tsx
@@ -2,42 +2,75 @@ import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { MockedProvider } from '@apollo/client/testing';
import {
- getContactsForTaskDrawerContactListMock,
- getContactsForTaskDrawerContactListEmptyMock,
- getContactsForTaskDrawerContactListLoadingMock,
+ getContactsForTaskDrawerContactListMock,
+ getContactsForTaskDrawerContactListEmptyMock,
+ getContactsForTaskDrawerContactListLoadingMock,
} from './ContactList.mock';
import TaskDrawerContactList from '.';
describe('TaskDrawerContactList', () => {
- it('default', async () => {
- const { queryByTestId, getAllByTestId, findByTestId } = render(
-
-
- ,
- );
- await findByTestId('TaskDrawerContactListLoading');
- await waitFor(() => expect(queryByTestId('TaskDrawerContactListLoading')).not.toBeInTheDocument());
- expect(
- getAllByTestId(/TaskDrawerContactListItem-contact-./).map((element) => element.getAttribute('data-testid')),
- ).toEqual(['TaskDrawerContactListItem-contact-2', 'TaskDrawerContactListItem-contact-1']);
- });
+ it('default', async () => {
+ const { queryByTestId, getAllByTestId, findByTestId } = render(
+
+
+ ,
+ );
+ await findByTestId('TaskDrawerContactListLoading');
+ await waitFor(() =>
+ expect(
+ queryByTestId('TaskDrawerContactListLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(
+ getAllByTestId(/TaskDrawerContactListItem-contact-./).map((element) =>
+ element.getAttribute('data-testid'),
+ ),
+ ).toEqual([
+ 'TaskDrawerContactListItem-contact-2',
+ 'TaskDrawerContactListItem-contact-1',
+ ]);
+ });
- it('loading', async () => {
- const { findByTestId } = render(
-
-
- ,
- );
- expect(await findByTestId('TaskDrawerContactListLoading')).toBeInTheDocument();
- });
+ it('loading', async () => {
+ const { findByTestId } = render(
+
+
+ ,
+ );
+ expect(
+ await findByTestId('TaskDrawerContactListLoading'),
+ ).toBeInTheDocument();
+ });
- it('empty', async () => {
- const { queryByTestId, getByTestId } = render(
-
-
- ,
- );
- await waitFor(() => expect(queryByTestId('TaskDrawerContactListLoading')).not.toBeInTheDocument());
- expect(getByTestId('TaskDrawerContactListEmpty')).toBeInTheDocument();
- });
+ it('empty', async () => {
+ const { queryByTestId, getByTestId } = render(
+
+
+ ,
+ );
+ await waitFor(() =>
+ expect(
+ queryByTestId('TaskDrawerContactListLoading'),
+ ).not.toBeInTheDocument(),
+ );
+ expect(getByTestId('TaskDrawerContactListEmpty')).toBeInTheDocument();
+ });
});
diff --git a/src/components/Task/Drawer/ContactList/ContactList.tsx b/src/components/Task/Drawer/ContactList/ContactList.tsx
index f34bea3e60..f04229f6af 100644
--- a/src/components/Task/Drawer/ContactList/ContactList.tsx
+++ b/src/components/Task/Drawer/ContactList/ContactList.tsx
@@ -1,5 +1,12 @@
import React, { ReactElement, useEffect } from 'react';
-import { makeStyles, Theme, Box, Card, Grid, CardContent } from '@material-ui/core';
+import {
+ makeStyles,
+ Theme,
+ Box,
+ Card,
+ Grid,
+ CardContent,
+} from '@material-ui/core';
import { useTranslation } from 'react-i18next';
import { gql, useLazyQuery } from '@apollo/client';
import { sortBy } from 'lodash/fp';
@@ -8,132 +15,150 @@ import illustration4 from '../../../../images/drawkit/grape/drawkit-grape-pack-i
import TaskDrawerContactListItem from './Item';
const useStyles = makeStyles((theme: Theme) => ({
- cardContent: {
- padding: theme.spacing(2),
- display: 'flex',
- flex: 1,
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- },
- img: {
- height: '120px',
- marginBottom: 0,
- [theme.breakpoints.down('xs')]: {
- height: '150px',
- marginBottom: theme.spacing(2),
- },
+ cardContent: {
+ padding: theme.spacing(2),
+ display: 'flex',
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ img: {
+ height: '120px',
+ marginBottom: 0,
+ [theme.breakpoints.down('xs')]: {
+ height: '150px',
+ marginBottom: theme.spacing(2),
},
+ },
}));
export const GET_CONTACTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY = gql`
- query GetContactsForTaskDrawerContactListQuery($accountListId: ID!, $contactIds: [ID!]) {
- contacts(accountListId: $accountListId, ids: $contactIds) {
- nodes {
- id
- name
- primaryAddress {
- id
- street
- city
- state
- postalCode
- location
- }
- primaryPerson {
- id
- title
- firstName
- lastName
- suffix
- primaryEmailAddress {
- id
- email
- location
- }
- primaryPhoneNumber {
- id
- number
- location
- }
- }
- status
- sendNewsletter
- lastDonation {
- id
- amount {
- amount
- currency
- conversionDate
- }
- }
- pledgeAmount
- pledgeCurrency
- pledgeFrequency
- tagList
- }
+ query GetContactsForTaskDrawerContactListQuery(
+ $accountListId: ID!
+ $contactIds: [ID!]
+ ) {
+ contacts(accountListId: $accountListId, ids: $contactIds) {
+ nodes {
+ id
+ name
+ primaryAddress {
+ id
+ street
+ city
+ state
+ postalCode
+ location
+ }
+ primaryPerson {
+ id
+ title
+ firstName
+ lastName
+ suffix
+ primaryEmailAddress {
+ id
+ email
+ location
+ }
+ primaryPhoneNumber {
+ id
+ number
+ location
+ }
+ }
+ status
+ sendNewsletter
+ lastDonation {
+ id
+ amount {
+ amount
+ currency
+ conversionDate
+ }
}
+ pledgeAmount
+ pledgeCurrency
+ pledgeFrequency
+ tagList
+ }
}
+ }
`;
interface Props {
- accountListId: string;
- contactIds: string[];
+ accountListId: string;
+ contactIds: string[];
}
-const TaskDrawerContactList = ({ accountListId, contactIds }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
+const TaskDrawerContactList = ({
+ accountListId,
+ contactIds,
+}: Props): ReactElement => {
+ const classes = useStyles();
+ const { t } = useTranslation();
- const [getContacts, { data, loading }] = useLazyQuery(
- GET_CONTACTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
- );
+ const [
+ getContacts,
+ { data, loading },
+ ] = useLazyQuery(
+ GET_CONTACTS_FOR_TASK_DRAWER_CONTACT_LIST_QUERY,
+ );
- useEffect(() => {
- if (contactIds.length > 0) {
- getContacts({
- variables: {
- accountListId,
- contactIds,
- },
- });
- }
- }, [contactIds]);
+ useEffect(() => {
+ if (contactIds.length > 0) {
+ getContacts({
+ variables: {
+ accountListId,
+ contactIds,
+ },
+ });
+ }
+ }, [contactIds]);
- return (
-
- {loading ? (
-
-
-
-
-
-
-
+ return (
+
+ {loading ? (
+
+
+
+
+
+
+
+
+ ) : (
+ <>
+ {(contactIds.length === 0 || data?.contacts?.nodes?.length === 0) && (
+
+
+
+ {t('No Contacts to show.')}
+
+
+ )}
+ {data?.contacts?.nodes && data.contacts.nodes.length > 0 && (
+
+ {sortBy('name', data.contacts.nodes).map((contact) => (
+
+
- ) : (
- <>
- {(contactIds.length === 0 || data?.contacts?.nodes?.length === 0) && (
-
-
-
- {t('No Contacts to show.')}
-
-
- )}
- {data?.contacts?.nodes && data.contacts.nodes.length > 0 && (
-
- {sortBy('name', data.contacts.nodes).map((contact) => (
-
-
-
- ))}
-
- )}
- >
- )}
-
- );
+ ))}
+
+ )}
+ >
+ )}
+
+ );
};
export default TaskDrawerContactList;
diff --git a/src/components/Task/Drawer/ContactList/Item/Item.stories.tsx b/src/components/Task/Drawer/ContactList/Item/Item.stories.tsx
index 3341f8e7bc..ec4732dfce 100644
--- a/src/components/Task/Drawer/ContactList/Item/Item.stories.tsx
+++ b/src/components/Task/Drawer/ContactList/Item/Item.stories.tsx
@@ -1,89 +1,93 @@
import React, { ReactElement } from 'react';
import { Box } from '@material-ui/core';
import { GetContactsForTaskDrawerContactListQuery_contacts_nodes as Contact } from '../../../../../../types/GetContactsForTaskDrawerContactListQuery';
-import { StatusEnum, SendNewsletterEnum, PledgeFrequencyEnum } from '../../../../../../types/globalTypes';
+import {
+ StatusEnum,
+ SendNewsletterEnum,
+ PledgeFrequencyEnum,
+} from '../../../../../../types/globalTypes';
import TaskDrawerContactListItem from '.';
export default {
- title: 'Task/Drawer/ContactList/Item',
+ title: 'Task/Drawer/ContactList/Item',
};
export const Default = (): ReactElement => {
- const contact: Contact = {
- id: 'def',
- name: 'Quinn, Anthony',
- primaryAddress: {
- id: 'primaryAddress-a',
- street: '125 Michael Ave',
- city: 'Hamilton',
- state: 'Waikato',
- postalCode: '3210',
- location: 'Work',
- },
- primaryPerson: {
- id: 'primaryPerson-a',
- title: 'Mr',
- firstName: 'Anthony',
- lastName: 'Quinn',
- suffix: 'Phd.',
- primaryEmailAddress: {
- id: 'primaryEmailAddress-a',
- email: 'anthony.quinn@gmail.com',
- location: 'Home',
- },
- primaryPhoneNumber: {
- id: 'primaryPhoneNumber-a',
- number: '(021) 986-821',
- location: 'Work',
- },
- },
- status: StatusEnum.PARTNER_FINANCIAL,
- sendNewsletter: SendNewsletterEnum.BOTH,
- lastDonation: {
- id: 'lastDonation-a',
- amount: {
- amount: 50,
- currency: 'NZD',
- conversionDate: '2020-10-12',
- },
- },
- pledgeAmount: 20,
- pledgeCurrency: 'NZD',
- pledgeFrequency: PledgeFrequencyEnum.MONTHLY,
- tagList: ['test', 'post', 'long', 'list'],
- };
- return (
-
-
-
- );
+ const contact: Contact = {
+ id: 'def',
+ name: 'Quinn, Anthony',
+ primaryAddress: {
+ id: 'primaryAddress-a',
+ street: '125 Michael Ave',
+ city: 'Hamilton',
+ state: 'Waikato',
+ postalCode: '3210',
+ location: 'Work',
+ },
+ primaryPerson: {
+ id: 'primaryPerson-a',
+ title: 'Mr',
+ firstName: 'Anthony',
+ lastName: 'Quinn',
+ suffix: 'Phd.',
+ primaryEmailAddress: {
+ id: 'primaryEmailAddress-a',
+ email: 'anthony.quinn@gmail.com',
+ location: 'Home',
+ },
+ primaryPhoneNumber: {
+ id: 'primaryPhoneNumber-a',
+ number: '(021) 986-821',
+ location: 'Work',
+ },
+ },
+ status: StatusEnum.PARTNER_FINANCIAL,
+ sendNewsletter: SendNewsletterEnum.BOTH,
+ lastDonation: {
+ id: 'lastDonation-a',
+ amount: {
+ amount: 50,
+ currency: 'NZD',
+ conversionDate: '2020-10-12',
+ },
+ },
+ pledgeAmount: 20,
+ pledgeCurrency: 'NZD',
+ pledgeFrequency: PledgeFrequencyEnum.MONTHLY,
+ tagList: ['test', 'post', 'long', 'list'],
+ };
+ return (
+
+
+
+ );
};
export const Minimal = (): ReactElement => {
- const contact: Contact = {
- id: 'ghi',
- name: 'Phillips, Guy',
- primaryAddress: null,
- primaryPerson: null,
- status: null,
- sendNewsletter: null,
- lastDonation: null,
- pledgeAmount: null,
- pledgeCurrency: null,
- pledgeFrequency: null,
- tagList: [],
- };
- return (
-
-
-
- );
+ const contact: Contact = {
+ id: 'ghi',
+ name: 'Phillips, Guy',
+ primaryAddress: null,
+ primaryPerson: null,
+ status: null,
+ sendNewsletter: null,
+ lastDonation: null,
+ pledgeAmount: null,
+ pledgeCurrency: null,
+ pledgeFrequency: null,
+ tagList: [],
+ };
+ return (
+
+
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Task/Drawer/ContactList/Item/Item.test.tsx b/src/components/Task/Drawer/ContactList/Item/Item.test.tsx
index e861d1ac75..4f814b4b8c 100644
--- a/src/components/Task/Drawer/ContactList/Item/Item.test.tsx
+++ b/src/components/Task/Drawer/ContactList/Item/Item.test.tsx
@@ -1,138 +1,191 @@
import React from 'react';
import { render } from '@testing-library/react';
import { GetContactsForTaskDrawerContactListQuery_contacts_nodes as Contact } from '../../../../../../types/GetContactsForTaskDrawerContactListQuery';
-import { StatusEnum, SendNewsletterEnum, PledgeFrequencyEnum } from '../../../../../../types/globalTypes';
+import {
+ StatusEnum,
+ SendNewsletterEnum,
+ PledgeFrequencyEnum,
+} from '../../../../../../types/globalTypes';
import Item from '.';
describe('Item', () => {
- const contact: Contact = {
- id: 'def',
- name: 'Quinn, Anthony',
- primaryAddress: {
- id: 'primaryAddress-a',
- street: '125 Michael Ave',
- city: 'Hamilton',
- state: 'Waikato',
- postalCode: '3210',
- location: 'Work',
- },
- primaryPerson: {
- id: 'primaryPerson-a',
- title: 'Mr',
- firstName: 'Anthony',
- lastName: 'Quinn',
- suffix: 'Phd.',
- primaryEmailAddress: {
- id: 'primaryEmailAddress-a',
- email: 'anthony.quinn@gmail.com',
- location: 'Home',
- },
- primaryPhoneNumber: {
- id: 'primaryPhoneNumber-a',
- number: '(021) 986-821',
- location: 'Work',
- },
- },
- status: StatusEnum.PARTNER_FINANCIAL,
- sendNewsletter: SendNewsletterEnum.BOTH,
- lastDonation: {
- id: 'lastDonation-a',
- amount: {
- amount: 50,
- currency: 'NZD',
- conversionDate: '2020-10-12',
- },
- },
- pledgeAmount: 20,
- pledgeCurrency: 'NZD',
- pledgeFrequency: PledgeFrequencyEnum.MONTHLY,
- tagList: ['test', 'post', 'long', 'list'],
- };
+ const contact: Contact = {
+ id: 'def',
+ name: 'Quinn, Anthony',
+ primaryAddress: {
+ id: 'primaryAddress-a',
+ street: '125 Michael Ave',
+ city: 'Hamilton',
+ state: 'Waikato',
+ postalCode: '3210',
+ location: 'Work',
+ },
+ primaryPerson: {
+ id: 'primaryPerson-a',
+ title: 'Mr',
+ firstName: 'Anthony',
+ lastName: 'Quinn',
+ suffix: 'Phd.',
+ primaryEmailAddress: {
+ id: 'primaryEmailAddress-a',
+ email: 'anthony.quinn@gmail.com',
+ location: 'Home',
+ },
+ primaryPhoneNumber: {
+ id: 'primaryPhoneNumber-a',
+ number: '(021) 986-821',
+ location: 'Work',
+ },
+ },
+ status: StatusEnum.PARTNER_FINANCIAL,
+ sendNewsletter: SendNewsletterEnum.BOTH,
+ lastDonation: {
+ id: 'lastDonation-a',
+ amount: {
+ amount: 50,
+ currency: 'NZD',
+ conversionDate: '2020-10-12',
+ },
+ },
+ pledgeAmount: 20,
+ pledgeCurrency: 'NZD',
+ pledgeFrequency: PledgeFrequencyEnum.MONTHLY,
+ tagList: ['test', 'post', 'long', 'list'],
+ };
- const minimalContact: Contact = {
- id: 'ghi',
- name: 'Phillips, Guy',
- primaryAddress: null,
- primaryPerson: null,
- status: null,
- sendNewsletter: null,
- lastDonation: null,
- pledgeAmount: null,
- pledgeCurrency: null,
- pledgeFrequency: null,
- tagList: [],
- };
+ const minimalContact: Contact = {
+ id: 'ghi',
+ name: 'Phillips, Guy',
+ primaryAddress: null,
+ primaryPerson: null,
+ status: null,
+ sendNewsletter: null,
+ lastDonation: null,
+ pledgeAmount: null,
+ pledgeCurrency: null,
+ pledgeFrequency: null,
+ tagList: [],
+ };
- it('has correct defaults', () => {
- const { getByTestId } = render( );
- expect(getByTestId('TaskDrawerContactListItemCard')).toBeInTheDocument();
- });
+ it('has correct defaults', () => {
+ const { getByTestId } = render( );
+ expect(getByTestId('TaskDrawerContactListItemCard')).toBeInTheDocument();
+ });
- it('displays minimal contact', () => {
- const { getByTestId, getByText, queryByTestId, rerender } = render( );
- expect(getByTestId('TaskDrawerContactListItemCard')).toBeInTheDocument();
- expect(queryByTestId('TaskDrawerContactListItemAddress')).not.toBeInTheDocument();
- expect(queryByTestId('TaskDrawerContactListItemEmailAddress')).not.toBeInTheDocument();
- expect(queryByTestId('TaskDrawerContactListItemPhoneNumber')).not.toBeInTheDocument();
- expect(queryByTestId('TaskDrawerContactListItemSendNewsletter')).not.toBeInTheDocument();
- expect(queryByTestId('TaskDrawerContactListItemPledge')).not.toBeInTheDocument();
- expect(queryByTestId('TaskDrawerContactListItemLastDonation')).not.toBeInTheDocument();
- expect(queryByTestId('TaskDrawerContactListItemTags')).not.toBeInTheDocument();
- expect(getByText('Phillips, Guy')).toBeInTheDocument();
- rerender( );
- expect(getByTestId('TaskDrawerContactListItemAddress')).toBeInTheDocument();
- rerender(
- ,
- );
- expect(getByTestId('TaskDrawerContactListItemEmailAddress')).toBeInTheDocument();
- rerender(
- ,
- );
- expect(getByTestId('TaskDrawerContactListItemPhoneNumber')).toBeInTheDocument();
- rerender( );
- expect(getByTestId('TaskDrawerContactListItemSendNewsletter')).toBeInTheDocument();
- rerender( );
- expect(getByTestId('TaskDrawerContactListItemLastDonation')).toBeInTheDocument();
- rerender( );
- expect(getByTestId('TaskDrawerContactListItemTags')).toBeInTheDocument();
- rerender(
- ,
- );
- expect(getByText('NZ$20')).toBeInTheDocument();
- rerender(
- ,
- );
- expect(getByText('NZ$20 MONTHLY')).toBeInTheDocument();
- rerender(
- ,
- );
- expect(getByText('PARTNER_FINANCIAL')).toBeInTheDocument();
- });
+ it('displays minimal contact', () => {
+ const { getByTestId, getByText, queryByTestId, rerender } = render(
+ ,
+ );
+ expect(getByTestId('TaskDrawerContactListItemCard')).toBeInTheDocument();
+ expect(
+ queryByTestId('TaskDrawerContactListItemAddress'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TaskDrawerContactListItemEmailAddress'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TaskDrawerContactListItemPhoneNumber'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TaskDrawerContactListItemSendNewsletter'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TaskDrawerContactListItemPledge'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TaskDrawerContactListItemLastDonation'),
+ ).not.toBeInTheDocument();
+ expect(
+ queryByTestId('TaskDrawerContactListItemTags'),
+ ).not.toBeInTheDocument();
+ expect(getByText('Phillips, Guy')).toBeInTheDocument();
+ rerender(
+ ,
+ );
+ expect(getByTestId('TaskDrawerContactListItemAddress')).toBeInTheDocument();
+ rerender(
+ ,
+ );
+ expect(
+ getByTestId('TaskDrawerContactListItemEmailAddress'),
+ ).toBeInTheDocument();
+ rerender(
+ ,
+ );
+ expect(
+ getByTestId('TaskDrawerContactListItemPhoneNumber'),
+ ).toBeInTheDocument();
+ rerender(
+ ,
+ );
+ expect(
+ getByTestId('TaskDrawerContactListItemSendNewsletter'),
+ ).toBeInTheDocument();
+ rerender(
+ ,
+ );
+ expect(
+ getByTestId('TaskDrawerContactListItemLastDonation'),
+ ).toBeInTheDocument();
+ rerender(
+ ,
+ );
+ expect(getByTestId('TaskDrawerContactListItemTags')).toBeInTheDocument();
+ rerender(
+ ,
+ );
+ expect(getByText('NZ$20')).toBeInTheDocument();
+ rerender(
+ ,
+ );
+ expect(getByText('NZ$20 MONTHLY')).toBeInTheDocument();
+ rerender(
+ ,
+ );
+ expect(getByText('PARTNER_FINANCIAL')).toBeInTheDocument();
+ });
- it('has loading state', () => {
- const { queryByTestId } = render( );
- expect(queryByTestId('TaskDrawerContactListItemCard')).not.toBeInTheDocument();
- });
+ it('has loading state', () => {
+ const { queryByTestId } = render( );
+ expect(
+ queryByTestId('TaskDrawerContactListItemCard'),
+ ).not.toBeInTheDocument();
+ });
});
diff --git a/src/components/Task/Drawer/ContactList/Item/Item.tsx b/src/components/Task/Drawer/ContactList/Item/Item.tsx
index b3cb000938..ffcf817ae8 100644
--- a/src/components/Task/Drawer/ContactList/Item/Item.tsx
+++ b/src/components/Task/Drawer/ContactList/Item/Item.tsx
@@ -1,21 +1,21 @@
import React, { ReactElement } from 'react';
import {
- makeStyles,
- Theme,
- Card,
- Avatar,
- IconButton,
- CardHeader,
- Grid,
- CardContent,
- Chip,
- List,
- ListItem,
- ListItemText,
- ListItemSecondaryAction,
- ListItemAvatar,
- Typography,
- Divider,
+ makeStyles,
+ Theme,
+ Card,
+ Avatar,
+ IconButton,
+ CardHeader,
+ Grid,
+ CardContent,
+ Chip,
+ List,
+ ListItem,
+ ListItemText,
+ ListItemSecondaryAction,
+ ListItemAvatar,
+ Typography,
+ Divider,
} from '@material-ui/core';
import { useTranslation } from 'react-i18next';
import { compact } from 'lodash/fp';
@@ -30,202 +30,226 @@ import { currencyFormat } from '../../../../../lib/intlFormat';
import { dateFormat } from '../../../../../lib/intlFormat/intlFormat';
const useStyles = makeStyles((theme: Theme) => ({
- cardContent: {
- padding: theme.spacing(3, 3, 3, 9),
- },
- chip: {
- marginRight: theme.spacing(0.5),
- marginBottom: theme.spacing(0.5),
- },
+ cardContent: {
+ padding: theme.spacing(3, 3, 3, 9),
+ },
+ chip: {
+ marginRight: theme.spacing(0.5),
+ marginBottom: theme.spacing(0.5),
+ },
}));
interface Props {
- contact?: Contact;
+ contact?: Contact;
}
const TaskDrawerContactListItem = ({ contact }: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
+ const classes = useStyles();
+ const { t } = useTranslation();
- return contact ? (
-
- {contact.name[0]}}
- title={contact.name}
- subheader={contact.status && t(contact.status)}
- />
- {(contact.sendNewsletter ||
- (contact.pledgeAmount && contact.pledgeCurrency) ||
- contact.pledgeFrequency ||
- contact.lastDonation ||
- contact.tagList.length > 0) && (
- <>
-
-
- {contact.sendNewsletter && (
-
-
- {t(contact.sendNewsletter) /* manually added to translation file */}
-
-
- )}
- {contact.pledgeAmount && contact.pledgeCurrency && (
-
-
- {currencyFormat(contact.pledgeAmount, contact.pledgeCurrency)}{' '}
- {
- contact.pledgeFrequency &&
- t(contact.pledgeFrequency) /* manually added to translation file */
- }
-
-
- )}
- {contact.lastDonation && (
-
-
- {currencyFormat(
- contact.lastDonation.amount.amount,
- contact.lastDonation.amount.currency,
- )}{' '}
-
- {` — ${dateFormat(new Date(contact.lastDonation.amount.conversionDate))}`}
-
-
-
- )}
- {contact.tagList.length > 0 && (
-
-
- {contact.tagList.map((tag) => (
-
- ))}
-
-
- )}
-
-
- {(contact.primaryAddress ||
- contact.primaryPerson?.primaryEmailAddress ||
- contact.primaryPerson?.primaryPhoneNumber) && }
- >
+ return contact ? (
+
+ {contact.name[0]}}
+ title={contact.name}
+ subheader={contact.status && t(contact.status)}
+ />
+ {(contact.sendNewsletter ||
+ (contact.pledgeAmount && contact.pledgeCurrency) ||
+ contact.pledgeFrequency ||
+ contact.lastDonation ||
+ contact.tagList.length > 0) && (
+ <>
+
+
+ {contact.sendNewsletter && (
+
+
+ {
+ t(
+ contact.sendNewsletter,
+ ) /* manually added to translation file */
+ }
+
+
+ )}
+ {contact.pledgeAmount && contact.pledgeCurrency && (
+
+
+ {currencyFormat(
+ contact.pledgeAmount,
+ contact.pledgeCurrency,
+ )}{' '}
+ {
+ contact.pledgeFrequency &&
+ t(
+ contact.pledgeFrequency,
+ ) /* manually added to translation file */
+ }
+
+
+ )}
+ {contact.lastDonation && (
+
+
+ {currencyFormat(
+ contact.lastDonation.amount.amount,
+ contact.lastDonation.amount.currency,
+ )}{' '}
+
+ {` — ${dateFormat(
+ new Date(contact.lastDonation.amount.conversionDate),
+ )}`}
+
+
+
+ )}
+ {contact.tagList.length > 0 && (
+
+
+ {contact.tagList.map((tag) => (
+
+ ))}
+
+
+ )}
+
+
+ {(contact.primaryAddress ||
+ contact.primaryPerson?.primaryEmailAddress ||
+ contact.primaryPerson?.primaryPhoneNumber) && (
+
+ )}
+ >
+ )}
+ {(contact.primaryAddress ||
+ contact.primaryPerson?.primaryEmailAddress ||
+ contact.primaryPerson?.primaryPhoneNumber) && (
+
+ <>
+ {contact.primaryAddress && (
+
+
+
+
+
+
+
+
)}
- {(contact.primaryAddress ||
- contact.primaryPerson?.primaryEmailAddress ||
- contact.primaryPerson?.primaryPhoneNumber) && (
-
+ {contact.primaryPerson?.primaryEmailAddress && (
+
+
+
+
+
+
+
- {contact.primaryAddress && (
-
-
-
-
-
-
-
-
- )}
- {contact.primaryPerson?.primaryEmailAddress && (
-
-
-
-
-
-
-
-
- {compact([
- contact.primaryPerson.title,
- contact.primaryPerson.firstName,
- contact.primaryPerson.lastName,
- contact.primaryPerson.suffix,
- ]).join(' ')}
-
- {contact.primaryPerson.primaryEmailAddress.location &&
- ` — ${contact.primaryPerson.primaryEmailAddress.location}`}
- >
- }
- />
-
- )}
- {contact.primaryPerson?.primaryPhoneNumber && (
-
-
-
-
-
-
-
-
- {compact([
- contact.primaryPerson.title,
- contact.primaryPerson.firstName,
- contact.primaryPerson.lastName,
- contact.primaryPerson.suffix,
- ]).join(' ')}
-
- {contact.primaryPerson.primaryPhoneNumber.location &&
- ` — ${contact.primaryPerson.primaryPhoneNumber.location}`}
- >
- }
- />
-
-
-
-
-
-
- )}
+
+ {compact([
+ contact.primaryPerson.title,
+ contact.primaryPerson.firstName,
+ contact.primaryPerson.lastName,
+ contact.primaryPerson.suffix,
+ ]).join(' ')}
+
+ {contact.primaryPerson.primaryEmailAddress.location &&
+ ` — ${contact.primaryPerson.primaryEmailAddress.location}`}
>
-
+ }
+ />
+
)}
-
- ) : (
-
- }
- title={}
- subheader={}
- />
-
- );
+ {contact.primaryPerson?.primaryPhoneNumber && (
+
+
+
+
+
+
+
+
+ {compact([
+ contact.primaryPerson.title,
+ contact.primaryPerson.firstName,
+ contact.primaryPerson.lastName,
+ contact.primaryPerson.suffix,
+ ]).join(' ')}
+
+ {contact.primaryPerson.primaryPhoneNumber.location &&
+ ` — ${contact.primaryPerson.primaryPhoneNumber.location}`}
+ >
+ }
+ />
+
+
+
+
+
+
+ )}
+ >
+
+ )}
+
+ ) : (
+
+ }
+ title={}
+ subheader={}
+ />
+
+ );
};
export default TaskDrawerContactListItem;
diff --git a/src/components/Task/Drawer/Drawer.mock.tsx b/src/components/Task/Drawer/Drawer.mock.tsx
index 123b997e79..1351822f80 100644
--- a/src/components/Task/Drawer/Drawer.mock.tsx
+++ b/src/components/Task/Drawer/Drawer.mock.tsx
@@ -1,41 +1,45 @@
import { MockedResponse } from '@apollo/client/testing';
-import { ActivityTypeEnum, NotificationTypeEnum, NotificationTimeUnitEnum } from '../../../../types/globalTypes';
+import {
+ ActivityTypeEnum,
+ NotificationTypeEnum,
+ NotificationTimeUnitEnum,
+} from '../../../../types/globalTypes';
import { GetTaskForTaskDrawerQuery } from '../../../../types/GetTaskForTaskDrawerQuery';
import { GET_TASK_FOR_TASK_DRAWER_QUERY } from './Drawer';
export const getTaskForTaskDrawerMock = (): MockedResponse => {
- const data: GetTaskForTaskDrawerQuery = {
- task: {
- id: 'task-1',
- activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
- subject: 'On the Journey with the Johnson Family',
- startAt: new Date(2012, 12, 5, 1, 2),
- completedAt: null,
- tagList: ['tag-1', 'tag-2'],
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
- },
- user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
- notificationTimeBefore: 20,
- notificationType: NotificationTypeEnum.BOTH,
- notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
- },
- };
- return {
- request: {
- query: GET_TASK_FOR_TASK_DRAWER_QUERY,
- variables: {
- accountListId: 'abc',
- taskId: 'task-1',
- },
- },
- result: {
- data,
- },
- };
+ const data: GetTaskForTaskDrawerQuery = {
+ task: {
+ id: 'task-1',
+ activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
+ subject: 'On the Journey with the Johnson Family',
+ startAt: new Date(2012, 12, 5, 1, 2),
+ completedAt: null,
+ tagList: ['tag-1', 'tag-2'],
+ contacts: {
+ nodes: [
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
+ ],
+ },
+ user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
+ notificationTimeBefore: 20,
+ notificationType: NotificationTypeEnum.BOTH,
+ notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
+ },
+ };
+ return {
+ request: {
+ query: GET_TASK_FOR_TASK_DRAWER_QUERY,
+ variables: {
+ accountListId: 'abc',
+ taskId: 'task-1',
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export default getTaskForTaskDrawerMock;
diff --git a/src/components/Task/Drawer/Drawer.stories.tsx b/src/components/Task/Drawer/Drawer.stories.tsx
index 0ef49273c8..539726dcb8 100644
--- a/src/components/Task/Drawer/Drawer.stories.tsx
+++ b/src/components/Task/Drawer/Drawer.stories.tsx
@@ -1,7 +1,11 @@
import React, { ReactElement } from 'react';
import { MockedProvider } from '@apollo/client/testing';
import withDispatch from '../../../decorators/withDispatch';
-import { getDataForTaskDrawerMock, updateTaskMutationMock, createTaskMutationMock } from './Form/Form.mock';
+import {
+ getDataForTaskDrawerMock,
+ updateTaskMutationMock,
+ createTaskMutationMock,
+} from './Form/Form.mock';
import { getContactsForTaskDrawerContactListMock } from './ContactList/ContactList.mock';
import { getCommentsForTaskDrawerCommentListMock } from './CommentList/CommentList.mock';
import { getTaskForTaskDrawerMock } from './Drawer.mock';
@@ -9,47 +13,52 @@ import { completeTaskMutationMock } from './CompleteForm/CompleteForm.mock';
import TaskDrawer from '.';
export default {
- title: 'Task/Drawer',
- decorators: [withDispatch({ type: 'updateAccountListId', accountListId: 'abc' })],
+ title: 'Task/Drawer',
+ decorators: [
+ withDispatch({ type: 'updateAccountListId', accountListId: 'abc' }),
+ ],
};
export const Default = (): ReactElement => {
- const mocks = [getDataForTaskDrawerMock(), { ...createTaskMutationMock(), delay: 500 }];
- return (
-
-
-
- );
+ const mocks = [
+ getDataForTaskDrawerMock(),
+ { ...createTaskMutationMock(), delay: 500 },
+ ];
+ return (
+
+
+
+ );
};
export const Persisted = (): ReactElement => {
- const mocks = [
- getDataForTaskDrawerMock(),
- getContactsForTaskDrawerContactListMock(),
- getCommentsForTaskDrawerCommentListMock(),
- { ...updateTaskMutationMock(), delay: 500 },
- getTaskForTaskDrawerMock(),
- ];
+ const mocks = [
+ getDataForTaskDrawerMock(),
+ getContactsForTaskDrawerContactListMock(),
+ getCommentsForTaskDrawerCommentListMock(),
+ { ...updateTaskMutationMock(), delay: 500 },
+ getTaskForTaskDrawerMock(),
+ ];
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
export const showCompleteForm = (): ReactElement => {
- const mocks = [
- getDataForTaskDrawerMock(),
- getContactsForTaskDrawerContactListMock(),
- getCommentsForTaskDrawerCommentListMock(),
- { ...completeTaskMutationMock(), delay: 500 },
- getTaskForTaskDrawerMock(),
- ];
+ const mocks = [
+ getDataForTaskDrawerMock(),
+ getContactsForTaskDrawerContactListMock(),
+ getCommentsForTaskDrawerCommentListMock(),
+ { ...completeTaskMutationMock(), delay: 500 },
+ getTaskForTaskDrawerMock(),
+ ];
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Task/Drawer/Drawer.test.tsx b/src/components/Task/Drawer/Drawer.test.tsx
index a22b677aa8..10c9de2d16 100644
--- a/src/components/Task/Drawer/Drawer.test.tsx
+++ b/src/components/Task/Drawer/Drawer.test.tsx
@@ -2,60 +2,73 @@ import React from 'react';
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import TestWrapper from '../../../../__tests__/util/TestWrapper';
-import { getDataForTaskDrawerMock, createTaskMutationMock, updateTaskMutationMock } from './Form/Form.mock';
+import {
+ getDataForTaskDrawerMock,
+ createTaskMutationMock,
+ updateTaskMutationMock,
+} from './Form/Form.mock';
import { getCommentsForTaskDrawerCommentListMock } from './CommentList/CommentList.mock';
import { getContactsForTaskDrawerContactListMock } from './ContactList/ContactList.mock';
import { getTaskForTaskDrawerMock } from './Drawer.mock';
-import { completeTaskMutationMock, getCompleteTaskForTaskDrawerMock } from './CompleteForm/CompleteForm.mock';
+import {
+ completeTaskMutationMock,
+ getCompleteTaskForTaskDrawerMock,
+} from './CompleteForm/CompleteForm.mock';
import TaskDrawer from '.';
describe('TaskDrawer', () => {
- it('default', async () => {
- const onClose = jest.fn();
- const mocks = [getDataForTaskDrawerMock(), createTaskMutationMock()];
- const { getByText, getByRole, getByTestId } = render(
-
-
- ,
- );
- expect(getByRole('tab', { name: 'Contacts ({{ contactCount }})' })).toBeDisabled();
- expect(getByRole('tab', { name: 'Comments' })).toBeDisabled();
- expect(getByTestId('TaskDrawerTitle')).toHaveTextContent('Add Task');
- userEvent.click(getByText('Save'));
- await waitFor(() => expect(onClose).toHaveBeenCalled());
- });
+ it('default', async () => {
+ const onClose = jest.fn();
+ const mocks = [getDataForTaskDrawerMock(), createTaskMutationMock()];
+ const { getByText, getByRole, getByTestId } = render(
+
+
+ ,
+ );
+ expect(
+ getByRole('tab', { name: 'Contacts ({{ contactCount }})' }),
+ ).toBeDisabled();
+ expect(getByRole('tab', { name: 'Comments' })).toBeDisabled();
+ expect(getByTestId('TaskDrawerTitle')).toHaveTextContent('Add Task');
+ userEvent.click(getByText('Save'));
+ await waitFor(() => expect(onClose).toHaveBeenCalled());
+ });
- it('persisted', async () => {
- const onClose = jest.fn();
- const mocks = [
- getDataForTaskDrawerMock(),
- getContactsForTaskDrawerContactListMock(),
- getCommentsForTaskDrawerCommentListMock(),
- updateTaskMutationMock(),
- getTaskForTaskDrawerMock(),
- ];
- const { findByTestId } = render(
-
-
- ,
- );
- expect(await findByTestId('TaskDrawerTitle')).toHaveTextContent('NEWSLETTER_EMAIL');
- });
+ it('persisted', async () => {
+ const onClose = jest.fn();
+ const mocks = [
+ getDataForTaskDrawerMock(),
+ getContactsForTaskDrawerContactListMock(),
+ getCommentsForTaskDrawerCommentListMock(),
+ updateTaskMutationMock(),
+ getTaskForTaskDrawerMock(),
+ ];
+ const { findByTestId } = render(
+
+
+ ,
+ );
+ expect(await findByTestId('TaskDrawerTitle')).toHaveTextContent(
+ 'NEWSLETTER_EMAIL',
+ );
+ });
- it('showCompleteForm', async () => {
- const onClose = jest.fn();
- const mocks = [
- getDataForTaskDrawerMock(),
- getContactsForTaskDrawerContactListMock(),
- getCommentsForTaskDrawerCommentListMock(),
- completeTaskMutationMock(),
- getCompleteTaskForTaskDrawerMock(),
- ];
- const { findByTestId } = render(
-
-
- ,
- );
- expect(await findByTestId('TaskDrawerTitle')).toHaveTextContent('Complete {{activityType}}');
- });
+ it('showCompleteForm', async () => {
+ const onClose = jest.fn();
+ const mocks = [
+ getDataForTaskDrawerMock(),
+ getContactsForTaskDrawerContactListMock(),
+ getCommentsForTaskDrawerCommentListMock(),
+ completeTaskMutationMock(),
+ getCompleteTaskForTaskDrawerMock(),
+ ];
+ const { findByTestId } = render(
+
+
+ ,
+ );
+ expect(await findByTestId('TaskDrawerTitle')).toHaveTextContent(
+ 'Complete {{activityType}}',
+ );
+ });
});
diff --git a/src/components/Task/Drawer/Drawer.tsx b/src/components/Task/Drawer/Drawer.tsx
index 039b95969e..d6b8cc9e25 100644
--- a/src/components/Task/Drawer/Drawer.tsx
+++ b/src/components/Task/Drawer/Drawer.tsx
@@ -1,15 +1,15 @@
import React, { ReactElement, useState, useEffect } from 'react';
import {
- makeStyles,
- Theme,
- IconButton,
- Box,
- Container,
- Grid,
- Drawer,
- AppBar,
- Tab,
- Typography,
+ makeStyles,
+ Theme,
+ IconButton,
+ Box,
+ Container,
+ Grid,
+ Drawer,
+ AppBar,
+ Tab,
+ Typography,
} from '@material-ui/core';
import CloseIcon from '@material-ui/icons/Close';
import { useTranslation } from 'react-i18next';
@@ -17,8 +17,8 @@ import { TabContext, TabList, TabPanel } from '@material-ui/lab';
import { gql, useLazyQuery } from '@apollo/client';
import { AnimatePresence, motion } from 'framer-motion';
import {
- GetTaskForTaskDrawerQuery,
- GetTaskForTaskDrawerQuery_task as Task,
+ GetTaskForTaskDrawerQuery,
+ GetTaskForTaskDrawerQuery_task as Task,
} from '../../../../types/GetTaskForTaskDrawerQuery';
import { useApp } from '../../App';
import Loading from '../../Loading';
@@ -29,235 +29,255 @@ import TaskDrawerCommentList from './CommentList';
import TaskDrawerCompleteForm from './CompleteForm';
const useStyles = makeStyles((theme: Theme) => ({
- fixed: {
- position: 'fixed',
- top: 0,
- background: theme.palette.background.paper,
- zIndex: 1,
- },
- content: {
- marginTop: 120,
- },
- container: {
- padding: theme.spacing(2, 2),
- },
- title: {
- display: 'flex',
- alignItems: 'center',
- flexGrow: 1,
- },
- tabPanel: {
- padding: 0,
- },
- paper: {
- width: 500,
- [theme.breakpoints.down('xs')]: {
- width: '100%',
- },
+ fixed: {
+ position: 'fixed',
+ top: 0,
+ background: theme.palette.background.paper,
+ zIndex: 1,
+ },
+ content: {
+ marginTop: 120,
+ },
+ container: {
+ padding: theme.spacing(2, 2),
+ },
+ title: {
+ display: 'flex',
+ alignItems: 'center',
+ flexGrow: 1,
+ },
+ tabPanel: {
+ padding: 0,
+ },
+ paper: {
+ width: 500,
+ [theme.breakpoints.down('xs')]: {
+ width: '100%',
},
+ },
}));
export const GET_TASK_FOR_TASK_DRAWER_QUERY = gql`
- query GetTaskForTaskDrawerQuery($accountListId: ID!, $taskId: ID!) {
- task(accountListId: $accountListId, id: $taskId) {
- id
- activityType
- subject
- startAt
- completedAt
- tagList
- contacts {
- nodes {
- id
- name
- }
- }
- user {
- id
- firstName
- lastName
- }
- notificationTimeBefore
- notificationType
- notificationTimeUnit
+ query GetTaskForTaskDrawerQuery($accountListId: ID!, $taskId: ID!) {
+ task(accountListId: $accountListId, id: $taskId) {
+ id
+ activityType
+ subject
+ startAt
+ completedAt
+ tagList
+ contacts {
+ nodes {
+ id
+ name
}
+ }
+ user {
+ id
+ firstName
+ lastName
+ }
+ notificationTimeBefore
+ notificationType
+ notificationTimeUnit
}
+ }
`;
export interface TaskDrawerProps {
- taskId?: string;
- onClose?: () => void;
- showCompleteForm?: boolean;
- defaultValues?: Partial;
+ taskId?: string;
+ onClose?: () => void;
+ showCompleteForm?: boolean;
+ defaultValues?: Partial;
}
-const TaskDrawer = ({ taskId, onClose, showCompleteForm, defaultValues }: TaskDrawerProps): ReactElement => {
- const { state } = useApp();
- const classes = useStyles();
- const [open, setOpen] = useState(false);
- const { t } = useTranslation();
- const [tab, setTab] = useState('1');
- const [getTask, { data, loading }] = useLazyQuery(GET_TASK_FOR_TASK_DRAWER_QUERY);
- const [task, setTask] = useState(null);
+const TaskDrawer = ({
+ taskId,
+ onClose,
+ showCompleteForm,
+ defaultValues,
+}: TaskDrawerProps): ReactElement => {
+ const { state } = useApp();
+ const classes = useStyles();
+ const [open, setOpen] = useState(false);
+ const { t } = useTranslation();
+ const [tab, setTab] = useState('1');
+ const [getTask, { data, loading }] = useLazyQuery(
+ GET_TASK_FOR_TASK_DRAWER_QUERY,
+ );
+ const [task, setTask] = useState(null);
- const onLoad = async (): Promise => {
- if (taskId) {
- await getTask({ variables: { accountListId: state.accountListId, taskId } });
- } else {
- setOpen(true);
- }
- };
+ const onLoad = async (): Promise => {
+ if (taskId) {
+ await getTask({
+ variables: { accountListId: state.accountListId, taskId },
+ });
+ } else {
+ setOpen(true);
+ }
+ };
- const handleTabChange = (_, tab: string): void => {
- setTab(tab);
- };
+ const handleTabChange = (_, tab: string): void => {
+ setTab(tab);
+ };
- const onDrawerClose = (): void => {
- setOpen(false);
- onClose && onClose();
- };
+ const onDrawerClose = (): void => {
+ setOpen(false);
+ onClose && onClose();
+ };
- useEffect(() => {
- onLoad();
- }, []);
+ useEffect(() => {
+ onLoad();
+ }, []);
- if (data?.task && task !== data?.task) {
- setTask(data.task);
- setOpen(true);
- }
+ if (data?.task && task !== data?.task) {
+ setTask(data.task);
+ setOpen(true);
+ }
- useEffect(() => {
- onLoad();
- }, [taskId]);
+ useEffect(() => {
+ onLoad();
+ }, [taskId]);
- const title = ((): string => {
- if (task) {
- if (task.activityType) {
- if (showCompleteForm) {
- return t('Complete {{activityType}}', { activityType: t(task.activityType) });
- } else {
- return t(task.activityType);
- }
- } else {
- if (showCompleteForm) {
- return t('Complete {{activityType}}', { activityType: t('Task') });
- } else {
- return t('Task');
- }
- }
+ const title = ((): string => {
+ if (task) {
+ if (task.activityType) {
+ if (showCompleteForm) {
+ return t('Complete {{activityType}}', {
+ activityType: t(task.activityType),
+ });
} else {
- return t('Add Task');
+ return t(task.activityType);
}
- })();
+ } else {
+ if (showCompleteForm) {
+ return t('Complete {{activityType}}', { activityType: t('Task') });
+ } else {
+ return t('Task');
+ }
+ }
+ } else {
+ return t('Add Task');
+ }
+ })();
- return (
-
- {loading && }
-
-
-
-
-
-
-
- {task ? (
-
- ) : (
-
- )}
-
-
- {title}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {!loading && (
- <>
- {showCompleteForm ? (
-
- ) : (
-
- )}
- >
- )}
-
-
- {task && (
- <>
-
-
- id)}
- />
-
-
-
-
-
-
-
- >
- )}
-
-
-
-
-
- );
+ return (
+
+ {loading && }
+
+
+
+
+
+
+
+ {task ? (
+
+ ) : (
+
+ )}
+
+
+ {title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {!loading && (
+ <>
+ {showCompleteForm ? (
+
+ ) : (
+
+ )}
+ >
+ )}
+
+
+ {task && (
+ <>
+
+
+ id)}
+ />
+
+
+
+
+
+
+
+ >
+ )}
+
+
+
+
+
+ );
};
export default TaskDrawer;
diff --git a/src/components/Task/Drawer/Form/Form.mock.tsx b/src/components/Task/Drawer/Form/Form.mock.tsx
index 6f232694ad..5af469823c 100644
--- a/src/components/Task/Drawer/Form/Form.mock.tsx
+++ b/src/components/Task/Drawer/Form/Form.mock.tsx
@@ -4,123 +4,133 @@ import { addHours, startOfHour } from 'date-fns';
import { GetDataForTaskDrawerQuery } from '../../../../../types/GetDataForTaskDrawerQuery';
import { CreateTaskMutation } from '../../../../../types/CreateTaskMutation';
import {
- ActivityTypeEnum,
- NotificationTypeEnum,
- NotificationTimeUnitEnum,
- TaskCreateInput,
- TaskUpdateInput,
+ ActivityTypeEnum,
+ NotificationTypeEnum,
+ NotificationTimeUnitEnum,
+ TaskCreateInput,
+ TaskUpdateInput,
} from '../../../../../types/globalTypes';
import { UpdateTaskMutation } from '../../../../../types/UpdateTaskMutation';
import { GetTaskForTaskDrawerQuery_task as Task } from '../../../../../types/GetTaskForTaskDrawerQuery';
-import { GET_DATA_FOR_TASK_DRAWER_QUERY, CREATE_TASK_MUTATION, UPDATE_TASK_MUTATION } from './Form';
+import {
+ GET_DATA_FOR_TASK_DRAWER_QUERY,
+ CREATE_TASK_MUTATION,
+ UPDATE_TASK_MUTATION,
+} from './Form';
export const getDataForTaskDrawerMock = (): MockedResponse => {
- const data: GetDataForTaskDrawerQuery = {
- accountList: {
- id: 'abc',
- taskTagList: ['tag-1', 'tag-2', 'tag-3'],
- },
- accountListUsers: {
- nodes: [
- { id: 'def', user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' } },
- { id: 'ghi', user: { id: 'user-2', firstName: 'John', lastName: 'Smith' } },
- ],
- },
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
+ const data: GetDataForTaskDrawerQuery = {
+ accountList: {
+ id: 'abc',
+ taskTagList: ['tag-1', 'tag-2', 'tag-3'],
+ },
+ accountListUsers: {
+ nodes: [
+ {
+ id: 'def',
+ user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' },
},
- };
- return {
- request: {
- query: GET_DATA_FOR_TASK_DRAWER_QUERY,
- variables: {
- accountListId: 'abc',
- },
+ {
+ id: 'ghi',
+ user: { id: 'user-2', firstName: 'John', lastName: 'Smith' },
},
- result: {
- data,
- },
- };
+ ],
+ },
+ contacts: {
+ nodes: [
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
+ ],
+ },
+ };
+ return {
+ request: {
+ query: GET_DATA_FOR_TASK_DRAWER_QUERY,
+ variables: {
+ accountListId: 'abc',
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export const createTaskMutationMock = (): MockedResponse => {
- const task: Task = {
- id: null,
- activityType: null,
- subject: 'abc',
- startAt: startOfHour(addHours(new Date(), 1)),
- completedAt: null,
- tagList: [],
- contacts: {
- nodes: [],
- },
- user: null,
- notificationTimeBefore: null,
- notificationType: null,
- notificationTimeUnit: null,
- };
- const data: CreateTaskMutation = {
- createTask: {
- task: { ...task, id: 'task-1' },
- },
- };
- const attributes: TaskCreateInput = omit(['contacts', 'user'], {
- ...task,
- userId: null,
- contactIds: [],
- });
- return {
- request: {
- query: CREATE_TASK_MUTATION,
- variables: {
- accountListId: 'abc',
- attributes: omit('id', attributes),
- },
- },
- result: { data },
- };
+ const task: Task = {
+ id: null,
+ activityType: null,
+ subject: 'abc',
+ startAt: startOfHour(addHours(new Date(), 1)),
+ completedAt: null,
+ tagList: [],
+ contacts: {
+ nodes: [],
+ },
+ user: null,
+ notificationTimeBefore: null,
+ notificationType: null,
+ notificationTimeUnit: null,
+ };
+ const data: CreateTaskMutation = {
+ createTask: {
+ task: { ...task, id: 'task-1' },
+ },
+ };
+ const attributes: TaskCreateInput = omit(['contacts', 'user'], {
+ ...task,
+ userId: null,
+ contactIds: [],
+ });
+ return {
+ request: {
+ query: CREATE_TASK_MUTATION,
+ variables: {
+ accountListId: 'abc',
+ attributes: omit('id', attributes),
+ },
+ },
+ result: { data },
+ };
};
export const updateTaskMutationMock = (): MockedResponse => {
- const task: Task = {
- id: 'task-1',
- activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
- subject: 'On the Journey with the Johnson Family',
- startAt: new Date(2012, 12, 5, 1, 2),
- completedAt: new Date(2015, 12, 5, 1, 2),
- tagList: ['tag-1', 'tag-2'],
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
- },
- user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' },
- notificationTimeBefore: 20,
- notificationType: NotificationTypeEnum.BOTH,
- notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
- };
- const data: UpdateTaskMutation = {
- updateTask: {
- task,
- },
- };
- const attributes: TaskUpdateInput = omit(['contacts', 'user'], {
- ...task,
- userId: task.user.id,
- contactIds: task.contacts.nodes.map(({ id }) => id),
- });
- return {
- request: {
- query: UPDATE_TASK_MUTATION,
- variables: {
- accountListId: 'abc',
- attributes,
- },
- },
- result: { data },
- };
+ const task: Task = {
+ id: 'task-1',
+ activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
+ subject: 'On the Journey with the Johnson Family',
+ startAt: new Date(2012, 12, 5, 1, 2),
+ completedAt: new Date(2015, 12, 5, 1, 2),
+ tagList: ['tag-1', 'tag-2'],
+ contacts: {
+ nodes: [
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
+ ],
+ },
+ user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' },
+ notificationTimeBefore: 20,
+ notificationType: NotificationTypeEnum.BOTH,
+ notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
+ };
+ const data: UpdateTaskMutation = {
+ updateTask: {
+ task,
+ },
+ };
+ const attributes: TaskUpdateInput = omit(['contacts', 'user'], {
+ ...task,
+ userId: task.user.id,
+ contactIds: task.contacts.nodes.map(({ id }) => id),
+ });
+ return {
+ request: {
+ query: UPDATE_TASK_MUTATION,
+ variables: {
+ accountListId: 'abc',
+ attributes,
+ },
+ },
+ result: { data },
+ };
};
diff --git a/src/components/Task/Drawer/Form/Form.stories.tsx b/src/components/Task/Drawer/Form/Form.stories.tsx
index 118aa1d866..70d8cb2127 100644
--- a/src/components/Task/Drawer/Form/Form.stories.tsx
+++ b/src/components/Task/Drawer/Form/Form.stories.tsx
@@ -1,58 +1,76 @@
import React, { ReactElement } from 'react';
import { MockedProvider } from '@apollo/client/testing';
-import { ActivityTypeEnum, NotificationTimeUnitEnum, NotificationTypeEnum } from '../../../../../types/globalTypes';
-import { getDataForTaskDrawerMock, createTaskMutationMock, updateTaskMutationMock } from './Form.mock';
+import {
+ ActivityTypeEnum,
+ NotificationTimeUnitEnum,
+ NotificationTypeEnum,
+} from '../../../../../types/globalTypes';
+import {
+ getDataForTaskDrawerMock,
+ createTaskMutationMock,
+ updateTaskMutationMock,
+} from './Form.mock';
import TaskDrawerForm from '.';
export default {
- title: 'Task/Drawer/Form',
+ title: 'Task/Drawer/Form',
};
export const Default = (): ReactElement => {
- return (
-
- {}} />
-
- );
+ return (
+
+ {}} />
+
+ );
};
export const Loading = (): ReactElement => {
- return (
-
- {}} />
-
- );
+ return (
+
+ {}} />
+
+ );
};
const task = {
- id: 'task-1',
- activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
- subject: 'On the Journey with the Johnson Family',
- startAt: new Date(2012, 12, 5, 1, 2),
- completedAt: new Date(2015, 12, 5, 1, 2),
- tagList: ['tag-1', 'tag-2'],
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
- },
- user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
- notificationTimeBefore: 20,
- notificationType: NotificationTypeEnum.BOTH,
- notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
+ id: 'task-1',
+ activityType: ActivityTypeEnum.NEWSLETTER_EMAIL,
+ subject: 'On the Journey with the Johnson Family',
+ startAt: new Date(2012, 12, 5, 1, 2),
+ completedAt: new Date(2015, 12, 5, 1, 2),
+ tagList: ['tag-1', 'tag-2'],
+ contacts: {
+ nodes: [
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
+ ],
+ },
+ user: { id: 'user-1', firstName: 'Anderson', lastName: 'Robert' },
+ notificationTimeBefore: 20,
+ notificationType: NotificationTypeEnum.BOTH,
+ notificationTimeUnit: NotificationTimeUnitEnum.HOURS,
};
export const Persisted = (): ReactElement => {
- return (
-
- {}} />
-
- );
+ return (
+
+ {}}
+ />
+
+ );
};
diff --git a/src/components/Task/Drawer/Form/Form.test.tsx b/src/components/Task/Drawer/Form/Form.test.tsx
index 0a26613638..4fc64d0e12 100644
--- a/src/components/Task/Drawer/Form/Form.test.tsx
+++ b/src/components/Task/Drawer/Form/Form.test.tsx
@@ -5,96 +5,125 @@ import { SnackbarProvider } from 'notistack';
import { MuiPickersUtilsProvider } from '@material-ui/pickers';
import DateFnsUtils from '@date-io/date-fns';
import userEvent from '@testing-library/user-event';
-import { getDataForTaskDrawerMock, createTaskMutationMock, updateTaskMutationMock } from './Form.mock';
+import {
+ getDataForTaskDrawerMock,
+ createTaskMutationMock,
+ updateTaskMutationMock,
+} from './Form.mock';
import TaskDrawerForm from '.';
describe('TaskDrawerForm', () => {
- it('default', async () => {
- const onClose = jest.fn();
- const { getByText, getByRole, findByText } = render(
-
-
-
-
-
-
- ,
- );
- userEvent.click(getByText('Cancel'));
- expect(onClose).toHaveBeenCalled();
- onClose.mockClear();
- userEvent.click(getByText('Save'));
- expect(await findByText('Field is required')).toBeInTheDocument();
- userEvent.type(getByRole('textbox', { name: 'Subject' }), 'abc');
- userEvent.click(getByRole('checkbox', { name: 'Notification' }));
- userEvent.type(getByRole('spinbutton', { name: 'Period' }), '20');
- userEvent.click(getByRole('checkbox', { name: 'Notification' }));
- await waitFor(() => expect(getByText('Save')).not.toBeDisabled());
- userEvent.click(getByText('Save'));
- await waitFor(() => expect(onClose).toHaveBeenCalled());
- }, 10000);
+ it('default', async () => {
+ const onClose = jest.fn();
+ const { getByText, getByRole, findByText } = render(
+
+
+
+
+
+
+ ,
+ );
+ userEvent.click(getByText('Cancel'));
+ expect(onClose).toHaveBeenCalled();
+ onClose.mockClear();
+ userEvent.click(getByText('Save'));
+ expect(await findByText('Field is required')).toBeInTheDocument();
+ userEvent.type(getByRole('textbox', { name: 'Subject' }), 'abc');
+ userEvent.click(getByRole('checkbox', { name: 'Notification' }));
+ userEvent.type(getByRole('spinbutton', { name: 'Period' }), '20');
+ userEvent.click(getByRole('checkbox', { name: 'Notification' }));
+ await waitFor(() => expect(getByText('Save')).not.toBeDisabled());
+ userEvent.click(getByText('Save'));
+ await waitFor(() => expect(onClose).toHaveBeenCalled());
+ }, 10000);
- it('persisted', async () => {
- const onClose = jest.fn();
- const { getByText, getByRole, getAllByRole } = render(
-
-
-
-
-
-
- ,
- );
- expect(
- getAllByRole('textbox').find((item: HTMLInputElement) => item.value === 'Jan 5, 2016'),
- ).toBeInTheDocument();
- userEvent.click(getByRole('button', { name: 'Type' }));
- userEvent.click(within(getByRole('listbox', { name: 'Type' })).getByText('NEWSLETTER_EMAIL'));
+ it('persisted', async () => {
+ const onClose = jest.fn();
+ const { getByText, getByRole, getAllByRole } = render(
+
+
+
+
+
+
+ ,
+ );
+ expect(
+ getAllByRole('textbox').find(
+ (item: HTMLInputElement) => item.value === 'Jan 5, 2016',
+ ),
+ ).toBeInTheDocument();
+ userEvent.click(getByRole('button', { name: 'Type' }));
+ userEvent.click(
+ within(getByRole('listbox', { name: 'Type' })).getByText(
+ 'NEWSLETTER_EMAIL',
+ ),
+ );
- userEvent.type(getByRole('textbox', { name: 'Subject' }), 'On the Journey with the Johnson Family');
+ userEvent.type(
+ getByRole('textbox', { name: 'Subject' }),
+ 'On the Journey with the Johnson Family',
+ );
- const tagsElement = getByRole('textbox', { name: 'Tags' });
- userEvent.click(tagsElement);
- userEvent.click(await within(getByRole('presentation')).findByText('tag-1'));
- userEvent.click(tagsElement);
- userEvent.click(within(getByRole('presentation')).getByText('tag-2'));
+ const tagsElement = getByRole('textbox', { name: 'Tags' });
+ userEvent.click(tagsElement);
+ userEvent.click(
+ await within(getByRole('presentation')).findByText('tag-1'),
+ );
+ userEvent.click(tagsElement);
+ userEvent.click(within(getByRole('presentation')).getByText('tag-2'));
- const assigneeElement = getByRole('textbox', { name: 'Assignee' });
- userEvent.click(assigneeElement);
- userEvent.click(await within(getByRole('presentation')).findByText('Robert Anderson'));
+ const assigneeElement = getByRole('textbox', { name: 'Assignee' });
+ userEvent.click(assigneeElement);
+ userEvent.click(
+ await within(getByRole('presentation')).findByText('Robert Anderson'),
+ );
- const contactsElement = getByRole('textbox', { name: 'Contacts' });
- userEvent.click(contactsElement);
- userEvent.click(await within(getByRole('presentation')).findByText('Anderson, Robert'));
- userEvent.click(contactsElement);
- userEvent.click(within(getByRole('presentation')).getByText('Smith, John'));
+ const contactsElement = getByRole('textbox', { name: 'Contacts' });
+ userEvent.click(contactsElement);
+ userEvent.click(
+ await within(getByRole('presentation')).findByText('Anderson, Robert'),
+ );
+ userEvent.click(contactsElement);
+ userEvent.click(within(getByRole('presentation')).getByText('Smith, John'));
- userEvent.click(getByRole('checkbox', { name: 'Notification' }));
- userEvent.type(getByRole('spinbutton', { name: 'Period' }), '20');
- userEvent.click(getByRole('button', { name: 'Unit' }));
- userEvent.click(within(getByRole('listbox', { name: 'Unit' })).getByText('HOURS'));
- userEvent.click(getByRole('button', { name: 'Platform' }));
- userEvent.click(within(getByRole('listbox', { name: 'Platform' })).getByText('BOTH'));
+ userEvent.click(getByRole('checkbox', { name: 'Notification' }));
+ userEvent.type(getByRole('spinbutton', { name: 'Period' }), '20');
+ userEvent.click(getByRole('button', { name: 'Unit' }));
+ userEvent.click(
+ within(getByRole('listbox', { name: 'Unit' })).getByText('HOURS'),
+ );
+ userEvent.click(getByRole('button', { name: 'Platform' }));
+ userEvent.click(
+ within(getByRole('listbox', { name: 'Platform' })).getByText('BOTH'),
+ );
- userEvent.click(getByText('Save'));
- await waitFor(() => expect(onClose).toHaveBeenCalled());
- }, 20000);
+ userEvent.click(getByText('Save'));
+ await waitFor(() => expect(onClose).toHaveBeenCalled());
+ }, 20000);
});
diff --git a/src/components/Task/Drawer/Form/Form.tsx b/src/components/Task/Drawer/Form/Form.tsx
index da493be680..a33d9cea4a 100644
--- a/src/components/Task/Drawer/Form/Form.tsx
+++ b/src/components/Task/Drawer/Form/Form.tsx
@@ -1,20 +1,20 @@
import React, { ReactElement, useState } from 'react';
import {
- makeStyles,
- Theme,
- TextField,
- Select,
- MenuItem,
- InputLabel,
- FormControl,
- FormControlLabel,
- Switch,
- Chip,
- Grid,
- Box,
- CircularProgress,
- Button,
- Divider,
+ makeStyles,
+ Theme,
+ TextField,
+ Select,
+ MenuItem,
+ InputLabel,
+ FormControl,
+ FormControlLabel,
+ Switch,
+ Chip,
+ Grid,
+ Box,
+ CircularProgress,
+ Button,
+ Divider,
} from '@material-ui/core';
import { useTranslation } from 'react-i18next';
import { Autocomplete } from '@material-ui/lab';
@@ -26,510 +26,597 @@ import { gql, useQuery, useMutation } from '@apollo/client';
import { omit, sortBy } from 'lodash/fp';
import { useSnackbar } from 'notistack';
import { startOfHour, addHours } from 'date-fns';
-import { ActivityTypeEnum, NotificationTypeEnum, NotificationTimeUnitEnum } from '../../../../../types/globalTypes';
+import {
+ ActivityTypeEnum,
+ NotificationTypeEnum,
+ NotificationTimeUnitEnum,
+} from '../../../../../types/globalTypes';
import { dateFormat } from '../../../../lib/intlFormat/intlFormat';
import {
- GetDataForTaskDrawerQuery,
- GetDataForTaskDrawerQuery_contacts_nodes,
+ GetDataForTaskDrawerQuery,
+ GetDataForTaskDrawerQuery_contacts_nodes,
} from '../../../../../types/GetDataForTaskDrawerQuery';
import { GetTaskForTaskDrawerQuery_task as Task } from '../../../../../types/GetTaskForTaskDrawerQuery';
import { CreateTaskMutation } from '../../../../../types/CreateTaskMutation';
import { UpdateTaskMutation } from '../../../../../types/UpdateTaskMutation';
const useStyles = makeStyles((theme: Theme) => ({
- formControl: {
- width: '100%',
- },
- select: {
- fontSize: theme.typography.h6.fontSize,
- minHeight: 'auto',
- '&:focus': {
- backgroundColor: 'transparent',
- },
- },
- container: {
- padding: theme.spacing(2, 2),
- },
- title: {
- flexGrow: 1,
+ formControl: {
+ width: '100%',
+ },
+ select: {
+ fontSize: theme.typography.h6.fontSize,
+ minHeight: 'auto',
+ '&:focus': {
+ backgroundColor: 'transparent',
},
+ },
+ container: {
+ padding: theme.spacing(2, 2),
+ },
+ title: {
+ flexGrow: 1,
+ },
}));
export const GET_DATA_FOR_TASK_DRAWER_QUERY = gql`
- query GetDataForTaskDrawerQuery($accountListId: ID!) {
- accountList(id: $accountListId) {
- id
- taskTagList
- }
- accountListUsers(accountListId: $accountListId) {
- nodes {
- id
- user {
- id
- firstName
- lastName
- }
- }
- }
- contacts(accountListId: $accountListId) {
- nodes {
- id
- name
- }
+ query GetDataForTaskDrawerQuery($accountListId: ID!) {
+ accountList(id: $accountListId) {
+ id
+ taskTagList
+ }
+ accountListUsers(accountListId: $accountListId) {
+ nodes {
+ id
+ user {
+ id
+ firstName
+ lastName
}
+ }
}
+ contacts(accountListId: $accountListId) {
+ nodes {
+ id
+ name
+ }
+ }
+ }
`;
export const CREATE_TASK_MUTATION = gql`
- mutation CreateTaskMutation($accountListId: ID!, $attributes: TaskCreateInput!) {
- createTask(input: { accountListId: $accountListId, attributes: $attributes }) {
- task {
- id
- activityType
- subject
- startAt
- completedAt
- tagList
- contacts {
- nodes {
- id
- name
- }
- }
- user {
- id
- firstName
- lastName
- }
- notificationTimeBefore
- notificationType
- notificationTimeUnit
- }
+ mutation CreateTaskMutation(
+ $accountListId: ID!
+ $attributes: TaskCreateInput!
+ ) {
+ createTask(
+ input: { accountListId: $accountListId, attributes: $attributes }
+ ) {
+ task {
+ id
+ activityType
+ subject
+ startAt
+ completedAt
+ tagList
+ contacts {
+ nodes {
+ id
+ name
+ }
}
+ user {
+ id
+ firstName
+ lastName
+ }
+ notificationTimeBefore
+ notificationType
+ notificationTimeUnit
+ }
}
+ }
`;
export const UPDATE_TASK_MUTATION = gql`
- mutation UpdateTaskMutation($accountListId: ID!, $attributes: TaskUpdateInput!) {
- updateTask(input: { accountListId: $accountListId, attributes: $attributes }) {
- task {
- id
- activityType
- subject
- startAt
- completedAt
- tagList
- contacts {
- nodes {
- id
- name
- }
- }
- user {
- id
- firstName
- lastName
- }
- notificationTimeBefore
- notificationType
- notificationTimeUnit
- }
+ mutation UpdateTaskMutation(
+ $accountListId: ID!
+ $attributes: TaskUpdateInput!
+ ) {
+ updateTask(
+ input: { accountListId: $accountListId, attributes: $attributes }
+ ) {
+ task {
+ id
+ activityType
+ subject
+ startAt
+ completedAt
+ tagList
+ contacts {
+ nodes {
+ id
+ name
+ }
+ }
+ user {
+ id
+ firstName
+ lastName
}
+ notificationTimeBefore
+ notificationType
+ notificationTimeUnit
+ }
}
+ }
`;
const taskSchema: yup.SchemaOf = yup.object({
- id: yup.string().nullable(),
- activityType: yup.mixed(),
- subject: yup.string().required(),
- startAt: yup.date().nullable(),
- completedAt: yup.date().nullable(),
- tagList: yup.array().of(yup.string()).default([]),
- contacts: yup.object({
- nodes: yup
- .array()
- .of(yup.object({ id: yup.string(), name: yup.string() }))
- .nullable(),
- }),
- user: yup.object({ id: yup.string(), firstName: yup.string(), lastName: yup.string() }).nullable(),
- notificationTimeBefore: yup.number().nullable(),
- notificationType: yup.mixed(),
- notificationTimeUnit: yup.mixed(),
+ id: yup.string().nullable(),
+ activityType: yup.mixed(),
+ subject: yup.string().required(),
+ startAt: yup.date().nullable(),
+ completedAt: yup.date().nullable(),
+ tagList: yup.array().of(yup.string()).default([]),
+ contacts: yup.object({
+ nodes: yup
+ .array()
+ .of(yup.object({ id: yup.string(), name: yup.string() }))
+ .nullable(),
+ }),
+ user: yup
+ .object({
+ id: yup.string(),
+ firstName: yup.string(),
+ lastName: yup.string(),
+ })
+ .nullable(),
+ notificationTimeBefore: yup.number().nullable(),
+ notificationType: yup.mixed(),
+ notificationTimeUnit: yup.mixed(),
});
interface Props {
- accountListId: string;
- task?: Task;
- onClose: () => void;
- defaultValues?: Partial;
+ accountListId: string;
+ task?: Task;
+ onClose: () => void;
+ defaultValues?: Partial;
}
-const TaskDrawerForm = ({ accountListId, task, onClose, defaultValues }: Props): ReactElement => {
- const initialTask: Task = task || {
- id: null,
- activityType: null,
- subject: '',
- startAt: startOfHour(addHours(new Date(), 1)),
- completedAt: null,
- tagList: [],
- contacts: {
- nodes: [],
- },
- user: null,
- notificationTimeBefore: null,
- notificationType: null,
- notificationTimeUnit: null,
- ...defaultValues,
- };
- const classes = useStyles();
- const { t } = useTranslation();
- const { enqueueSnackbar } = useSnackbar();
- const [notification, setNotification] = useState(
- initialTask.notificationTimeBefore !== null ||
- initialTask.notificationType !== null ||
- initialTask.notificationTimeUnit !== null,
- );
- const handleNotificationChange = (
- event: React.ChangeEvent,
- setFieldValue: (name: string, value: null) => void,
- ): void => {
- setNotification(event.target.checked);
+const TaskDrawerForm = ({
+ accountListId,
+ task,
+ onClose,
+ defaultValues,
+}: Props): ReactElement => {
+ const initialTask: Task = task || {
+ id: null,
+ activityType: null,
+ subject: '',
+ startAt: startOfHour(addHours(new Date(), 1)),
+ completedAt: null,
+ tagList: [],
+ contacts: {
+ nodes: [],
+ },
+ user: null,
+ notificationTimeBefore: null,
+ notificationType: null,
+ notificationTimeUnit: null,
+ ...defaultValues,
+ };
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const { enqueueSnackbar } = useSnackbar();
+ const [notification, setNotification] = useState(
+ initialTask.notificationTimeBefore !== null ||
+ initialTask.notificationType !== null ||
+ initialTask.notificationTimeUnit !== null,
+ );
+ const handleNotificationChange = (
+ event: React.ChangeEvent,
+ setFieldValue: (name: string, value: null) => void,
+ ): void => {
+ setNotification(event.target.checked);
- if (!event.target.checked) {
- setFieldValue('notificationTimeBefore', null);
- setFieldValue('notificationType', null);
- setFieldValue('notificationTimeUnit', null);
- }
- };
- const { data, loading } = useQuery(GET_DATA_FOR_TASK_DRAWER_QUERY, {
- variables: { accountListId },
+ if (!event.target.checked) {
+ setFieldValue('notificationTimeBefore', null);
+ setFieldValue('notificationType', null);
+ setFieldValue('notificationTimeUnit', null);
+ }
+ };
+ const { data, loading } = useQuery(
+ GET_DATA_FOR_TASK_DRAWER_QUERY,
+ {
+ variables: { accountListId },
+ },
+ );
+ const [createTask, { loading: creating }] = useMutation(
+ CREATE_TASK_MUTATION,
+ );
+ const [updateTask, { loading: saving }] = useMutation(
+ UPDATE_TASK_MUTATION,
+ );
+ const onSubmit = async (values: Task): Promise => {
+ const attributes = omit(['contacts', 'user', '__typename'], {
+ ...values,
+ userId: values.user?.id || null,
+ contactIds: values.contacts.nodes.map(({ id }) => id),
});
- const [createTask, { loading: creating }] = useMutation(CREATE_TASK_MUTATION);
- const [updateTask, { loading: saving }] = useMutation(UPDATE_TASK_MUTATION);
- const onSubmit = async (values: Task): Promise => {
- const attributes = omit(['contacts', 'user', '__typename'], {
- ...values,
- userId: values.user?.id || null,
- contactIds: values.contacts.nodes.map(({ id }) => id),
+ try {
+ if (task) {
+ await updateTask({ variables: { accountListId, attributes } });
+ } else {
+ await createTask({
+ variables: { accountListId, attributes: omit('id', attributes) },
});
- try {
- if (task) {
- await updateTask({ variables: { accountListId, attributes } });
- } else {
- await createTask({ variables: { accountListId, attributes: omit('id', attributes) } });
- }
- enqueueSnackbar(t('Task saved successfully'), { variant: 'success' });
- onClose();
- } catch (error) {
- enqueueSnackbar(error.message, { variant: 'error' });
- }
- };
+ }
+ enqueueSnackbar(t('Task saved successfully'), { variant: 'success' });
+ onClose();
+ } catch (error) {
+ enqueueSnackbar(error.message, { variant: 'error' });
+ }
+ };
- return (
-
- {({
- values: {
- activityType,
- subject,
- startAt,
- completedAt,
- tagList,
- user,
- contacts,
- notificationTimeBefore,
- notificationType,
- notificationTimeUnit,
- },
- setFieldValue,
- handleChange,
- handleSubmit,
- isSubmitting,
- isValid,
- errors,
- touched,
- }): ReactElement => (
-
+ )}
+
+ );
};
export default TaskDrawerForm;
diff --git a/src/components/Task/Home/Home.stories.tsx b/src/components/Task/Home/Home.stories.tsx
index 5882034279..f84c7799e6 100644
--- a/src/components/Task/Home/Home.stories.tsx
+++ b/src/components/Task/Home/Home.stories.tsx
@@ -1,30 +1,41 @@
import React, { ReactElement } from 'react';
import { MockedProvider } from '@apollo/client/testing';
import withDispatch from '../../../decorators/withDispatch';
-import { getTasksForTaskListMock, getFilteredTasksForTaskListMock } from '../List/List.mock';
+import {
+ getTasksForTaskListMock,
+ getFilteredTasksForTaskListMock,
+} from '../List/List.mock';
import { getDataForTaskDrawerMock } from '../Drawer/Form/Form.mock';
import TaskHome from '.';
export default {
- title: 'Task/Home',
- decorators: [withDispatch({ type: 'updateAccountListId', accountListId: 'abc' })],
+ title: 'Task/Home',
+ decorators: [
+ withDispatch({ type: 'updateAccountListId', accountListId: 'abc' }),
+ ],
};
export const Default = (): ReactElement => (
-
-
-
+
+
+
);
export const WithInitialFilter = (): ReactElement => {
- const filter = { activityType: ['APPOINTMENT'], completed: true };
+ const filter = { activityType: ['APPOINTMENT'], completed: true };
- return (
-
-
-
- );
+ return (
+
+
+
+ );
};
diff --git a/src/components/Task/Home/Home.test.tsx b/src/components/Task/Home/Home.test.tsx
index 6e42577709..405c1f45cd 100644
--- a/src/components/Task/Home/Home.test.tsx
+++ b/src/components/Task/Home/Home.test.tsx
@@ -2,34 +2,46 @@ import React from 'react';
import TestWrapper from '../../../../__tests__/util/TestWrapper';
import { getDataForTaskDrawerMock } from '../Drawer/Form/Form.mock';
import { render } from '../../../../__tests__/util/testingLibraryReactMock';
-import { getTasksForTaskListMock, getFilteredTasksForTaskListMock } from '../List/List.mock';
+import {
+ getTasksForTaskListMock,
+ getFilteredTasksForTaskListMock,
+} from '../List/List.mock';
import TaskHome from '.';
describe('TaskHome', () => {
- it('has correct defaults', async () => {
- const mocks = [getTasksForTaskListMock(), getDataForTaskDrawerMock()];
- const { findByText } = render(
-
-
- ,
- );
- expect(await findByText('On the Journey with the Johnson Family')).toBeInTheDocument();
- });
+ it('has correct defaults', async () => {
+ const mocks = [getTasksForTaskListMock(), getDataForTaskDrawerMock()];
+ const { findByText } = render(
+
+
+ ,
+ );
+ expect(
+ await findByText('On the Journey with the Johnson Family'),
+ ).toBeInTheDocument();
+ });
- it('has correct overrides', async () => {
- const filter = {
- activityType: ['APPOINTMENT'],
- completed: true,
- tags: ['tag-1', 'tag-2'],
- userIds: ['user-1'],
- contactIds: ['contact-1'],
- wildcardSearch: 'journey',
- };
- const { findByText } = render(
-
-
- ,
- );
- expect(await findByText('On the Journey with the Johnson Family')).toBeInTheDocument();
- });
+ it('has correct overrides', async () => {
+ const filter = {
+ activityType: ['APPOINTMENT'],
+ completed: true,
+ tags: ['tag-1', 'tag-2'],
+ userIds: ['user-1'],
+ contactIds: ['contact-1'],
+ wildcardSearch: 'journey',
+ };
+ const { findByText } = render(
+
+
+ ,
+ );
+ expect(
+ await findByText('On the Journey with the Johnson Family'),
+ ).toBeInTheDocument();
+ });
});
diff --git a/src/components/Task/Home/Home.tsx b/src/components/Task/Home/Home.tsx
index 0775ff5223..e734042beb 100644
--- a/src/components/Task/Home/Home.tsx
+++ b/src/components/Task/Home/Home.tsx
@@ -7,29 +7,29 @@ import { TaskFilter } from '../List/List';
import illustration8 from '../../../images/drawkit/grape/drawkit-grape-pack-illustration-8.svg';
const useStyles = makeStyles((theme: Theme) => ({
- container: {
- paddingTop: 40,
- },
- tabpanel: {
- padding: theme.spacing(3, 0, 0),
- },
+ container: {
+ paddingTop: 40,
+ },
+ tabpanel: {
+ padding: theme.spacing(3, 0, 0),
+ },
}));
interface Props {
- initialFilter?: TaskFilter;
+ initialFilter?: TaskFilter;
}
const TaskHome = ({ initialFilter }: Props): ReactElement => {
- const { t } = useTranslation();
- const classes = useStyles();
- return (
- <>
-
-
-
-
- >
- );
+ const { t } = useTranslation();
+ const classes = useStyles();
+ return (
+ <>
+
+
+
+
+ >
+ );
};
export default TaskHome;
diff --git a/src/components/Task/List/List.mock.tsx b/src/components/Task/List/List.mock.tsx
index 943b35f264..000055e3db 100644
--- a/src/components/Task/List/List.mock.tsx
+++ b/src/components/Task/List/List.mock.tsx
@@ -4,155 +4,157 @@ import { GetTasksForTaskListQuery } from '../../../../types/GetTasksForTaskListQ
import { GET_TASKS_FOR_TASK_LIST_QUERY, TaskFilter } from './List';
export const getTasksForTaskListMock = (): MockedResponse => {
- const data: GetTasksForTaskListQuery = {
- tasks: {
+ const data: GetTasksForTaskListQuery = {
+ tasks: {
+ nodes: [
+ {
+ id: 'task-1',
+ activityType: ActivityTypeEnum.APPOINTMENT,
+ subject: 'On the Journey with the Johnson Family',
+ startAt: new Date(2012, 12, 5, 1, 2),
+ completedAt: null,
+ tagList: ['tag-1', 'tag-2'],
+ contacts: {
nodes: [
- {
- id: 'task-1',
- activityType: ActivityTypeEnum.APPOINTMENT,
- subject: 'On the Journey with the Johnson Family',
- startAt: new Date(2012, 12, 5, 1, 2),
- completedAt: null,
- tagList: ['tag-1', 'tag-2'],
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
- },
- user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' },
- },
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
],
- totalCount: 1,
- pageInfo: {
- startCursor: 'A',
- endCursor: 'B',
- },
+ },
+ user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' },
},
- };
+ ],
+ totalCount: 1,
+ pageInfo: {
+ startCursor: 'A',
+ endCursor: 'B',
+ },
+ },
+ };
- return {
- request: {
- query: GET_TASKS_FOR_TASK_LIST_QUERY,
- variables: {
- accountListId: 'abc',
- first: 100,
- after: null,
- before: null,
- userIds: [],
- tags: [],
- contactIds: [],
- activityType: [],
- completed: null,
- startAt: null,
- },
- },
- result: {
- data,
- },
- };
+ return {
+ request: {
+ query: GET_TASKS_FOR_TASK_LIST_QUERY,
+ variables: {
+ accountListId: 'abc',
+ first: 100,
+ after: null,
+ before: null,
+ userIds: [],
+ tags: [],
+ contactIds: [],
+ activityType: [],
+ completed: null,
+ startAt: null,
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
export const getEmptyTasksForTaskListMock = (): MockedResponse => {
- const data: GetTasksForTaskListQuery = {
- tasks: {
- nodes: [],
- totalCount: 0,
- pageInfo: {
- startCursor: 'A',
- endCursor: 'B',
- },
- },
- };
+ const data: GetTasksForTaskListQuery = {
+ tasks: {
+ nodes: [],
+ totalCount: 0,
+ pageInfo: {
+ startCursor: 'A',
+ endCursor: 'B',
+ },
+ },
+ };
- return {
- request: {
- query: GET_TASKS_FOR_TASK_LIST_QUERY,
- variables: {
- accountListId: 'abc',
- first: 100,
- after: null,
- before: null,
- userIds: [],
- tags: [],
- contactIds: [],
- activityType: [],
- completed: null,
- startAt: null,
- },
- },
- result: {
- data,
- },
- };
+ return {
+ request: {
+ query: GET_TASKS_FOR_TASK_LIST_QUERY,
+ variables: {
+ accountListId: 'abc',
+ first: 100,
+ after: null,
+ before: null,
+ userIds: [],
+ tags: [],
+ contactIds: [],
+ activityType: [],
+ completed: null,
+ startAt: null,
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
interface Attributes extends TaskFilter {
- first?: number;
+ first?: number;
}
-export const getFilteredTasksForTaskListMock = (filter: Attributes): MockedResponse => {
- const data: GetTasksForTaskListQuery = {
- tasks: {
+export const getFilteredTasksForTaskListMock = (
+ filter: Attributes,
+): MockedResponse => {
+ const data: GetTasksForTaskListQuery = {
+ tasks: {
+ nodes: [
+ {
+ id: 'task-1',
+ activityType: ActivityTypeEnum.APPOINTMENT,
+ subject: 'On the Journey with the Johnson Family',
+ startAt: new Date(2012, 12, 5, 1, 2),
+ completedAt: null,
+ tagList: ['tag-1', 'tag-2'],
+ contacts: {
nodes: [
- {
- id: 'task-1',
- activityType: ActivityTypeEnum.APPOINTMENT,
- subject: 'On the Journey with the Johnson Family',
- startAt: new Date(2012, 12, 5, 1, 2),
- completedAt: null,
- tagList: ['tag-1', 'tag-2'],
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
- },
- user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' },
- },
- {
- id: 'task-1',
- activityType: ActivityTypeEnum.APPOINTMENT,
- subject: 'On the Journey with the Johnson Family 2020',
- startAt: new Date('2020-09-01'),
- completedAt: null,
- tagList: ['tag-1', 'tag-2'],
- contacts: {
- nodes: [
- { id: 'contact-1', name: 'Anderson, Robert' },
- { id: 'contact-2', name: 'Smith, John' },
- ],
- },
- user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' },
- },
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
],
- totalCount: 1000,
- pageInfo: {
- startCursor: 'A',
- endCursor: 'B',
- },
+ },
+ user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' },
},
- };
-
- return {
- request: {
- query: GET_TASKS_FOR_TASK_LIST_QUERY,
- variables: {
- accountListId: 'abc',
- first: 100,
- after: null,
- before: null,
- userIds: [],
- tags: [],
- contactIds: [],
- activityType: [],
- completed: null,
- startAt: null,
- ...filter,
- },
- },
- result: {
- data,
+ {
+ id: 'task-1',
+ activityType: ActivityTypeEnum.APPOINTMENT,
+ subject: 'On the Journey with the Johnson Family 2020',
+ startAt: new Date('2020-09-01'),
+ completedAt: null,
+ tagList: ['tag-1', 'tag-2'],
+ contacts: {
+ nodes: [
+ { id: 'contact-1', name: 'Anderson, Robert' },
+ { id: 'contact-2', name: 'Smith, John' },
+ ],
+ },
+ user: { id: 'user-1', firstName: 'Robert', lastName: 'Anderson' },
},
- };
+ ],
+ totalCount: 1000,
+ pageInfo: {
+ startCursor: 'A',
+ endCursor: 'B',
+ },
+ },
+ };
+
+ return {
+ request: {
+ query: GET_TASKS_FOR_TASK_LIST_QUERY,
+ variables: {
+ accountListId: 'abc',
+ first: 100,
+ after: null,
+ before: null,
+ userIds: [],
+ tags: [],
+ contactIds: [],
+ activityType: [],
+ completed: null,
+ startAt: null,
+ ...filter,
+ },
+ },
+ result: {
+ data,
+ },
+ };
};
diff --git a/src/components/Task/List/List.stories.tsx b/src/components/Task/List/List.stories.tsx
index 4fe7d42463..e13c7b078c 100644
--- a/src/components/Task/List/List.stories.tsx
+++ b/src/components/Task/List/List.stories.tsx
@@ -3,55 +3,68 @@ import { MockedProvider } from '@apollo/client/testing';
import withDispatch from '../../../decorators/withDispatch';
import { getDataForTaskDrawerMock } from '../Drawer/Form/Form.mock';
import withMargin from '../../../decorators/withMargin';
-import { getTasksForTaskListMock, getFilteredTasksForTaskListMock, getEmptyTasksForTaskListMock } from './List.mock';
+import {
+ getTasksForTaskListMock,
+ getFilteredTasksForTaskListMock,
+ getEmptyTasksForTaskListMock,
+} from './List.mock';
import TaskList from '.';
export default {
- title: 'Task/List',
- decorators: [withDispatch({ type: 'updateAccountListId', accountListId: 'abc' }), withMargin],
+ title: 'Task/List',
+ decorators: [
+ withDispatch({ type: 'updateAccountListId', accountListId: 'abc' }),
+ withMargin,
+ ],
};
export const Default = (): ReactElement => (
-
-
-
+
+
+
);
export const Loading = (): ReactElement => (
-
+
);
export const Empty = (): ReactElement => (
-
-
-
+
+
+
);
export const WithInitialFilter = (): ReactElement => {
- const filter = {
- activityType: ['APPOINTMENT'],
- completed: false,
- tags: ['tag-1', 'tag-2'],
- userIds: ['user-1'],
- contactIds: ['contact-1'],
- wildcardSearch: 'journey',
- };
- return (
-
-
-
- );
+ const filter = {
+ activityType: ['APPOINTMENT'],
+ completed: false,
+ tags: ['tag-1', 'tag-2'],
+ userIds: ['user-1'],
+ contactIds: ['contact-1'],
+ wildcardSearch: 'journey',
+ };
+ return (
+
+
+
+ );
};
diff --git a/src/components/Task/List/List.test.tsx b/src/components/Task/List/List.test.tsx
index 92ccc97679..19cbaf1a62 100644
--- a/src/components/Task/List/List.test.tsx
+++ b/src/components/Task/List/List.test.tsx
@@ -5,187 +5,205 @@ import TestWrapper from '../../../../__tests__/util/TestWrapper';
import { getDataForTaskDrawerMock } from '../Drawer/Form/Form.mock';
import { render } from '../../../../__tests__/util/testingLibraryReactMock';
import { useApp } from '../../App';
-import { getTasksForTaskListMock, getFilteredTasksForTaskListMock, getEmptyTasksForTaskListMock } from './List.mock';
+import {
+ getTasksForTaskListMock,
+ getFilteredTasksForTaskListMock,
+ getEmptyTasksForTaskListMock,
+} from './List.mock';
import TaskList from '.';
const openTaskDrawer = jest.fn();
jest.mock('../../App', () => ({
- useApp: jest.fn(),
+ useApp: jest.fn(),
}));
beforeEach(() => {
- (useApp as jest.Mock).mockReturnValue({
- openTaskDrawer,
- state: { accountListId: 'abc', breadcrumb: 'Tasks' },
- });
+ (useApp as jest.Mock).mockReturnValue({
+ openTaskDrawer,
+ state: { accountListId: 'abc', breadcrumb: 'Tasks' },
+ });
});
-jest.mock('lodash/fp/debounce', () => jest.fn().mockImplementation((_time, fn) => fn));
+jest.mock('lodash/fp/debounce', () =>
+ jest.fn().mockImplementation((_time, fn) => fn),
+);
describe('TaskList', () => {
- beforeEach(() => {
- MockDate.set(new Date('2020-09-01'));
- });
+ beforeEach(() => {
+ MockDate.set(new Date('2020-09-01'));
+ });
- afterEach(() => {
- MockDate.reset();
- });
+ afterEach(() => {
+ MockDate.reset();
+ });
- it('has correct defaults', async () => {
- const mocks = [
- getTasksForTaskListMock(),
- getDataForTaskDrawerMock(),
- getFilteredTasksForTaskListMock({ completed: false }),
- getFilteredTasksForTaskListMock({ activityType: ['APPOINTMENT'], completed: false }),
- getFilteredTasksForTaskListMock({
- contactIds: ['contact-1'],
- activityType: ['APPOINTMENT'],
- completed: false,
- }),
- getFilteredTasksForTaskListMock({
- tags: ['tag-1'],
- contactIds: ['contact-1'],
- activityType: ['APPOINTMENT'],
- completed: false,
- }),
- getFilteredTasksForTaskListMock({
- userIds: ['user-1'],
- tags: ['tag-1'],
- contactIds: ['contact-1'],
- activityType: ['APPOINTMENT'],
- completed: false,
- }),
- getFilteredTasksForTaskListMock({
- userIds: ['user-1'],
- tags: ['tag-1'],
- contactIds: ['contact-1'],
- activityType: ['APPOINTMENT'],
- completed: false,
- wildcardSearch: 'a',
- }),
- getFilteredTasksForTaskListMock({
- userIds: ['user-1'],
- tags: ['tag-1'],
- contactIds: ['contact-1'],
- activityType: ['APPOINTMENT'],
- completed: false,
- wildcardSearch: 'a',
- first: 250,
- }),
- getFilteredTasksForTaskListMock({
- userIds: ['user-1'],
- tags: ['tag-1'],
- contactIds: ['contact-1'],
- activityType: ['APPOINTMENT'],
- completed: false,
- wildcardSearch: 'a',
- first: 250,
- after: 'B',
- }),
- getFilteredTasksForTaskListMock({
- userIds: ['user-1'],
- tags: ['tag-1'],
- contactIds: ['contact-1'],
- activityType: ['APPOINTMENT'],
- completed: false,
- wildcardSearch: 'a',
- first: 250,
- before: 'A',
- }),
- ];
- const { findByText, getByRole, getAllByRole } = render(
-
-
- ,
- );
- userEvent.click(await findByText('On the Journey with the Johnson Family'));
- expect(openTaskDrawer).toHaveBeenCalledWith({ taskId: 'task-1' });
- userEvent.click(getByRole('button', { name: 'Filter Table' }));
- const buttons = getAllByRole('button').filter((element) => element.id);
- const buttonWithIdThatEndsWith = (value): HTMLElement => buttons.find((element) => element.id.endsWith(value));
- userEvent.click(buttonWithIdThatEndsWith('completedAt'));
- userEvent.click(getByRole('option', { name: 'Incomplete' }));
- userEvent.click(buttonWithIdThatEndsWith('activityType'));
- userEvent.click(getByRole('option', { name: 'Appointment' }));
- userEvent.tab();
- userEvent.click(buttonWithIdThatEndsWith('contacts'));
- userEvent.click(getByRole('option', { name: 'Anderson, Robert' }));
- userEvent.tab();
- userEvent.click(buttonWithIdThatEndsWith('tagList'));
- userEvent.click(getByRole('option', { name: 'tag-1' }));
- userEvent.tab();
- userEvent.click(buttonWithIdThatEndsWith('user'));
- userEvent.click(getByRole('option', { name: 'Robert Anderson' }));
- userEvent.tab();
- userEvent.click(getByRole('button', { name: 'Close' }));
- userEvent.click(getByRole('button', { name: 'Search' }));
- userEvent.type(getByRole('textbox', { name: 'Search' }), 'a');
- userEvent.click(getByRole('button', { name: 'Rows per page: 100' }));
- userEvent.click(getByRole('option', { name: '250' }));
- userEvent.click(getByRole('button', { name: 'Next Page' }));
- userEvent.click(getByRole('button', { name: 'Previous Page' }));
- });
+ it('has correct defaults', async () => {
+ const mocks = [
+ getTasksForTaskListMock(),
+ getDataForTaskDrawerMock(),
+ getFilteredTasksForTaskListMock({ completed: false }),
+ getFilteredTasksForTaskListMock({
+ activityType: ['APPOINTMENT'],
+ completed: false,
+ }),
+ getFilteredTasksForTaskListMock({
+ contactIds: ['contact-1'],
+ activityType: ['APPOINTMENT'],
+ completed: false,
+ }),
+ getFilteredTasksForTaskListMock({
+ tags: ['tag-1'],
+ contactIds: ['contact-1'],
+ activityType: ['APPOINTMENT'],
+ completed: false,
+ }),
+ getFilteredTasksForTaskListMock({
+ userIds: ['user-1'],
+ tags: ['tag-1'],
+ contactIds: ['contact-1'],
+ activityType: ['APPOINTMENT'],
+ completed: false,
+ }),
+ getFilteredTasksForTaskListMock({
+ userIds: ['user-1'],
+ tags: ['tag-1'],
+ contactIds: ['contact-1'],
+ activityType: ['APPOINTMENT'],
+ completed: false,
+ wildcardSearch: 'a',
+ }),
+ getFilteredTasksForTaskListMock({
+ userIds: ['user-1'],
+ tags: ['tag-1'],
+ contactIds: ['contact-1'],
+ activityType: ['APPOINTMENT'],
+ completed: false,
+ wildcardSearch: 'a',
+ first: 250,
+ }),
+ getFilteredTasksForTaskListMock({
+ userIds: ['user-1'],
+ tags: ['tag-1'],
+ contactIds: ['contact-1'],
+ activityType: ['APPOINTMENT'],
+ completed: false,
+ wildcardSearch: 'a',
+ first: 250,
+ after: 'B',
+ }),
+ getFilteredTasksForTaskListMock({
+ userIds: ['user-1'],
+ tags: ['tag-1'],
+ contactIds: ['contact-1'],
+ activityType: ['APPOINTMENT'],
+ completed: false,
+ wildcardSearch: 'a',
+ first: 250,
+ before: 'A',
+ }),
+ ];
+ const { findByText, getByRole, getAllByRole } = render(
+
+
+ ,
+ );
+ userEvent.click(await findByText('On the Journey with the Johnson Family'));
+ expect(openTaskDrawer).toHaveBeenCalledWith({ taskId: 'task-1' });
+ userEvent.click(getByRole('button', { name: 'Filter Table' }));
+ const buttons = getAllByRole('button').filter((element) => element.id);
+ const buttonWithIdThatEndsWith = (value): HTMLElement =>
+ buttons.find((element) => element.id.endsWith(value));
+ userEvent.click(buttonWithIdThatEndsWith('completedAt'));
+ userEvent.click(getByRole('option', { name: 'Incomplete' }));
+ userEvent.click(buttonWithIdThatEndsWith('activityType'));
+ userEvent.click(getByRole('option', { name: 'Appointment' }));
+ userEvent.tab();
+ userEvent.click(buttonWithIdThatEndsWith('contacts'));
+ userEvent.click(getByRole('option', { name: 'Anderson, Robert' }));
+ userEvent.tab();
+ userEvent.click(buttonWithIdThatEndsWith('tagList'));
+ userEvent.click(getByRole('option', { name: 'tag-1' }));
+ userEvent.tab();
+ userEvent.click(buttonWithIdThatEndsWith('user'));
+ userEvent.click(getByRole('option', { name: 'Robert Anderson' }));
+ userEvent.tab();
+ userEvent.click(getByRole('button', { name: 'Close' }));
+ userEvent.click(getByRole('button', { name: 'Search' }));
+ userEvent.type(getByRole('textbox', { name: 'Search' }), 'a');
+ userEvent.click(getByRole('button', { name: 'Rows per page: 100' }));
+ userEvent.click(getByRole('option', { name: '250' }));
+ userEvent.click(getByRole('button', { name: 'Next Page' }));
+ userEvent.click(getByRole('button', { name: 'Previous Page' }));
+ });
- it('has correct overrides', async () => {
- const filter = {
- activityType: ['APPOINTMENT'],
- completed: true,
- tags: ['tag-1', 'tag-2'],
+ it('has correct overrides', async () => {
+ const filter = {
+ activityType: ['APPOINTMENT'],
+ completed: true,
+ tags: ['tag-1', 'tag-2'],
+ userIds: ['user-1'],
+ contactIds: ['contact-1'],
+ wildcardSearch: 'journey',
+ startAt: { min: '2020-10-10', max: '2020-12-10' },
+ };
+ const { getByRole, getByText, findByText } = render(
+
+
+ ,
+ );
+ expect(getByText('Appointment')).toBeInTheDocument();
+ expect(getByText('Complete')).toBeInTheDocument();
+ expect(getByText('Tag: tag-1')).toBeInTheDocument();
+ expect(getByText('Tag: tag-2')).toBeInTheDocument();
+ expect(getByText('Minimum Due Date: Oct 10, 2020')).toBeInTheDocument();
+ expect(getByText('Maximum Due Date: Dec 10, 2020')).toBeInTheDocument();
+ expect(getByRole('textbox')).toHaveValue('journey');
+ expect(await findByText('Anderson, Robert')).toBeInTheDocument();
+ expect(getByText('Robert Anderson')).toBeInTheDocument();
+ });
+
+ it('has loading state', () => {
+ const mocks = [
+ { ...getDataForTaskDrawerMock(), delay: 100931731455 },
+ {
+ ...getFilteredTasksForTaskListMock({
+ userIds: ['user-1'],
+ contactIds: ['contact-1'],
+ }),
+ delay: 100931731455,
+ },
+ ];
+ const { getAllByRole } = render(
+
+
-
- ,
- );
- expect(getByText('Appointment')).toBeInTheDocument();
- expect(getByText('Complete')).toBeInTheDocument();
- expect(getByText('Tag: tag-1')).toBeInTheDocument();
- expect(getByText('Tag: tag-2')).toBeInTheDocument();
- expect(getByText('Minimum Due Date: Oct 10, 2020')).toBeInTheDocument();
- expect(getByText('Maximum Due Date: Dec 10, 2020')).toBeInTheDocument();
- expect(getByRole('textbox')).toHaveValue('journey');
- expect(await findByText('Anderson, Robert')).toBeInTheDocument();
- expect(getByText('Robert Anderson')).toBeInTheDocument();
- });
-
- it('has loading state', () => {
- const mocks = [
- { ...getDataForTaskDrawerMock(), delay: 100931731455 },
- {
- ...getFilteredTasksForTaskListMock({
- userIds: ['user-1'],
- contactIds: ['contact-1'],
- }),
- delay: 100931731455,
- },
- ];
- const { getAllByRole } = render(
-
-
- ,
- );
- expect(getAllByRole('button', { name: 'Loading' }).length).toEqual(2);
- });
+ }}
+ />
+ ,
+ );
+ expect(getAllByRole('button', { name: 'Loading' }).length).toEqual(2);
+ });
- it('has empty state', () => {
- const { queryByTestId } = render(
-
-
- ,
- );
- expect(queryByTestId('TaskDrawerCommentListItemAvatar')).not.toBeInTheDocument();
- });
+ it('has empty state', () => {
+ const { queryByTestId } = render(
+
+
+ ,
+ );
+ expect(
+ queryByTestId('TaskDrawerCommentListItemAvatar'),
+ ).not.toBeInTheDocument();
+ });
});
diff --git a/src/components/Task/List/List.tsx b/src/components/Task/List/List.tsx
index cf14f938ed..a32fe5fc77 100644
--- a/src/components/Task/List/List.tsx
+++ b/src/components/Task/List/List.tsx
@@ -1,18 +1,21 @@
import React, { ReactElement, useState, useCallback } from 'react';
import { gql, useQuery } from '@apollo/client';
-import MUIDataTable, { MUIDataTableOptions, MUIDataTableColumn } from 'mui-datatables';
+import MUIDataTable, {
+ MUIDataTableOptions,
+ MUIDataTableColumn,
+} from 'mui-datatables';
import { useTranslation } from 'react-i18next';
import {
- Chip,
- CircularProgress,
- Avatar,
- Tooltip,
- makeStyles,
- Theme,
- Grid,
- Card,
- FormLabel,
- Box,
+ Chip,
+ CircularProgress,
+ Avatar,
+ Tooltip,
+ makeStyles,
+ Theme,
+ Grid,
+ Card,
+ FormLabel,
+ Box,
} from '@material-ui/core';
import { find, reduce } from 'lodash/fp';
import debounce from 'lodash/fp/debounce';
@@ -28,487 +31,540 @@ import { GetDataForTaskDrawerQuery } from '../../../../types/GetDataForTaskDrawe
import illustration15 from '../../../images/drawkit/grape/drawkit-grape-pack-illustration-15.svg';
export const GET_TASKS_FOR_TASK_LIST_QUERY = gql`
- query GetTasksForTaskListQuery(
- $accountListId: ID!
- $first: Int
- $before: String
- $after: String
- $activityType: [ActivityTypeEnum!]
- $contactIds: [ID!]
- $userIds: [ID!]
- $tags: [String!]
- $completed: Boolean
- $wildcardSearch: String
- $startAt: DateTimeRangeInput
+ query GetTasksForTaskListQuery(
+ $accountListId: ID!
+ $first: Int
+ $before: String
+ $after: String
+ $activityType: [ActivityTypeEnum!]
+ $contactIds: [ID!]
+ $userIds: [ID!]
+ $tags: [String!]
+ $completed: Boolean
+ $wildcardSearch: String
+ $startAt: DateTimeRangeInput
+ ) {
+ tasks(
+ accountListId: $accountListId
+ first: $first
+ before: $before
+ after: $after
+ activityType: $activityType
+ contactIds: $contactIds
+ userIds: $userIds
+ tags: $tags
+ completed: $completed
+ wildcardSearch: $wildcardSearch
+ startAt: $startAt
) {
- tasks(
- accountListId: $accountListId
- first: $first
- before: $before
- after: $after
- activityType: $activityType
- contactIds: $contactIds
- userIds: $userIds
- tags: $tags
- completed: $completed
- wildcardSearch: $wildcardSearch
- startAt: $startAt
- ) {
- nodes {
- id
- activityType
- subject
- startAt
- completedAt
- tagList
- contacts {
- nodes {
- id
- name
- }
- }
- user {
- id
- firstName
- lastName
- }
- }
- totalCount
- pageInfo {
- startCursor
- endCursor
- }
+ nodes {
+ id
+ activityType
+ subject
+ startAt
+ completedAt
+ tagList
+ contacts {
+ nodes {
+ id
+ name
+ }
}
+ user {
+ id
+ firstName
+ lastName
+ }
+ }
+ totalCount
+ pageInfo {
+ startCursor
+ endCursor
+ }
}
+ }
`;
const useStyles = makeStyles((theme: Theme) => ({
- chip: {
- marginRight: theme.spacing(0.5),
- },
- card: {
- display: 'flex',
- flex: 1,
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- padding: theme.spacing(4),
- [theme.breakpoints.down('xs')]: {
- padding: theme.spacing(0),
- },
+ chip: {
+ marginRight: theme.spacing(0.5),
+ },
+ card: {
+ display: 'flex',
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ padding: theme.spacing(4),
+ [theme.breakpoints.down('xs')]: {
+ padding: theme.spacing(0),
},
- img: {
- height: '200px',
- marginBottom: theme.spacing(2),
- [theme.breakpoints.down('xs')]: {
- height: '114px',
- },
+ },
+ img: {
+ height: '200px',
+ marginBottom: theme.spacing(2),
+ [theme.breakpoints.down('xs')]: {
+ height: '114px',
},
+ },
}));
export interface TaskFilter {
- userIds?: string[];
- tags?: string[];
- contactIds?: string[];
- activityType?: string[];
- completed?: boolean;
- wildcardSearch?: string;
- startAt?: { min?: string; max?: string };
- before?: string;
- after?: string;
+ userIds?: string[];
+ tags?: string[];
+ contactIds?: string[];
+ activityType?: string[];
+ completed?: boolean;
+ wildcardSearch?: string;
+ startAt?: { min?: string; max?: string };
+ before?: string;
+ after?: string;
}
interface Props {
- initialFilter?: TaskFilter;
+ initialFilter?: TaskFilter;
}
const TaskList = ({ initialFilter }: Props): ReactElement => {
- const [filter, setFilter] = useState({
- userIds: [],
- tags: [],
- contactIds: [],
- activityType: [],
- completed: null,
- startAt: null,
- before: null,
- after: null,
- ...initialFilter,
- });
- const classes = useStyles();
- const { t } = useTranslation();
- const [rowsPerPage, setRowsPerPage] = useState(100);
- const [currentPage, setCurrentPage] = useState(0);
+ const [filter, setFilter] = useState({
+ userIds: [],
+ tags: [],
+ contactIds: [],
+ activityType: [],
+ completed: null,
+ startAt: null,
+ before: null,
+ after: null,
+ ...initialFilter,
+ });
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const [rowsPerPage, setRowsPerPage] = useState(100);
+ const [currentPage, setCurrentPage] = useState(0);
- const {
- state: { accountListId },
- openTaskDrawer,
- } = useApp();
+ const {
+ state: { accountListId },
+ openTaskDrawer,
+ } = useApp();
- const { data: filterData } = useQuery(GET_DATA_FOR_TASK_DRAWER_QUERY, {
- variables: { accountListId },
- });
+ const { data: filterData } = useQuery(
+ GET_DATA_FOR_TASK_DRAWER_QUERY,
+ {
+ variables: { accountListId },
+ },
+ );
- const { loading, data } = useQuery(GET_TASKS_FOR_TASK_LIST_QUERY, {
- variables: {
- accountListId,
- first: rowsPerPage,
- ...filter,
- },
- });
+ const { loading, data } = useQuery(
+ GET_TASKS_FOR_TASK_LIST_QUERY,
+ {
+ variables: {
+ accountListId,
+ first: rowsPerPage,
+ ...filter,
+ },
+ },
+ );
- const columns: MUIDataTableColumn[] = [
- {
- name: 'completedAt',
- label: t('Completed'),
- options: {
- filter: true,
- sort: false,
- filterType: 'dropdown',
- filterList: initialFilter?.completed !== undefined && [initialFilter.completed.toString()],
- filterOptions: {
- names: ['true', 'false'],
- renderValue: (val): string => (val === 'true' ? t('Complete') : t('Incomplete')),
- fullWidth: true,
- },
- customFilterListOptions: {
- render: (val): string => (val === 'true' ? t('Complete') : t('Incomplete')),
- },
- customHeadLabelRender: (): string => '',
- customBodyRender: (completedAt, { rowIndex }): ReactElement => {
- if (!loading) {
- const { id, startAt } = data.tasks.nodes[rowIndex];
- return ;
- } else {
- return ;
- }
- },
- },
+ const columns: MUIDataTableColumn[] = [
+ {
+ name: 'completedAt',
+ label: t('Completed'),
+ options: {
+ filter: true,
+ sort: false,
+ filterType: 'dropdown',
+ filterList: initialFilter?.completed !== undefined && [
+ initialFilter.completed.toString(),
+ ],
+ filterOptions: {
+ names: ['true', 'false'],
+ renderValue: (val): string =>
+ val === 'true' ? t('Complete') : t('Incomplete'),
+ fullWidth: true,
},
- {
- name: 'subject',
- label: t('Subject'),
- options: {
- filter: false,
- sort: false,
- },
+ customFilterListOptions: {
+ render: (val): string =>
+ val === 'true' ? t('Complete') : t('Incomplete'),
},
- {
- name: 'activityType',
- label: t('Type'),
- options: {
- display: false,
- filter: true,
- sort: false,
- customBodyRender: t,
- filterList: initialFilter?.activityType,
- filterOptions: {
- names: Object.keys(ActivityTypeEnum).sort(),
- renderValue: t,
- fullWidth: true,
- },
- customFilterListOptions: { render: t },
- filterType: 'multiselect',
- },
+ customHeadLabelRender: (): string => '',
+ customBodyRender: (completedAt, { rowIndex }): ReactElement => {
+ if (!loading) {
+ const { id, startAt } = data.tasks.nodes[rowIndex];
+ return (
+
+ );
+ } else {
+ return ;
+ }
},
- {
- name: 'contacts',
- label: t('Contacts'),
- options: {
- display: false,
- filter: true,
- sort: false,
- filterList: initialFilter?.contactIds,
- customFilterListOptions: {
- render: (id): string => {
- if (filterData?.contacts?.nodes) {
- return find({ id }, filterData.contacts.nodes)?.name;
- }
- return t('Loading');
- },
- },
- filterOptions: {
- names: filterData?.contacts?.nodes?.map(({ id }) => id) || [],
- renderValue: (id): string => {
- if (filterData?.contacts?.nodes) {
- return find({ id }, filterData.contacts.nodes)?.name;
- }
- },
- fullWidth: true,
- },
- filterType: 'multiselect',
- customBodyRender: (contacts): string =>
- contacts && contacts.nodes.map(({ name }) => name).join(t('List Separator')),
- },
+ },
+ },
+ {
+ name: 'subject',
+ label: t('Subject'),
+ options: {
+ filter: false,
+ sort: false,
+ },
+ },
+ {
+ name: 'activityType',
+ label: t('Type'),
+ options: {
+ display: false,
+ filter: true,
+ sort: false,
+ customBodyRender: t,
+ filterList: initialFilter?.activityType,
+ filterOptions: {
+ names: Object.keys(ActivityTypeEnum).sort(),
+ renderValue: t,
+ fullWidth: true,
},
- {
- name: 'tagList',
- label: t('Tags'),
- options: {
- filter: true,
- sort: true,
- filterList: initialFilter?.tags,
- filterOptions: {
- names: filterData?.accountList?.taskTagList || [],
- fullWidth: true,
- },
- filterType: 'multiselect',
- customFilterListOptions: { render: (tag): string => t('Tag {{tag}}', { tag }) },
- customBodyRender: (tagList): ReactElement => {
- if (loading) {
- return (
-
-
-
-
-
-
-
-
- );
- } else {
- return (
- tagList &&
- tagList.map((tag) => (
-
- ))
- );
- }
- },
- },
+ customFilterListOptions: { render: t },
+ filterType: 'multiselect',
+ },
+ },
+ {
+ name: 'contacts',
+ label: t('Contacts'),
+ options: {
+ display: false,
+ filter: true,
+ sort: false,
+ filterList: initialFilter?.contactIds,
+ customFilterListOptions: {
+ render: (id): string => {
+ if (filterData?.contacts?.nodes) {
+ return find({ id }, filterData.contacts.nodes)?.name;
+ }
+ return t('Loading');
+ },
},
- {
- name: 'user',
- label: t('Assignee'),
- options: {
- filter: true,
- sort: true,
- display: false,
- filterList: initialFilter?.userIds,
- customFilterListOptions: {
- render: (id): string => {
- if (filterData?.accountListUsers?.nodes) {
- const accountListUser = find({ user: { id } }, filterData.accountListUsers.nodes);
- return `${accountListUser.user.firstName} ${accountListUser.user.lastName}`;
- }
- return t('Loading');
- },
- },
- filterOptions: {
- names: filterData?.accountListUsers?.nodes?.map(({ user: { id } }) => id) || [],
- renderValue: (id): string => {
- if (filterData?.accountListUsers?.nodes) {
- const accountListUser = find({ user: { id } }, filterData.accountListUsers.nodes);
- return `${accountListUser.user.firstName} ${accountListUser.user.lastName}`;
- }
- },
- fullWidth: true,
- },
- filterType: 'multiselect',
- customBodyRender: (user): ReactElement => {
- if (user) {
- return (
-
- {user.firstName[0]}
-
- );
- }
- },
- },
+ filterOptions: {
+ names: filterData?.contacts?.nodes?.map(({ id }) => id) || [],
+ renderValue: (id): string => {
+ if (filterData?.contacts?.nodes) {
+ return find({ id }, filterData.contacts.nodes)?.name;
+ }
+ },
+ fullWidth: true,
},
- {
- name: 'startAt',
- label: t('Due Date'),
- options: {
- filter: true,
- filterType: 'custom',
- filterList:
- initialFilter?.startAt &&
- (([
- initialFilter.startAt.min && new Date(initialFilter.startAt.min),
- initialFilter.startAt.max && new Date(initialFilter.startAt.max),
- ] as unknown) as string[]),
- customFilterListOptions: {
- render: (v) => {
- const returnable: string[] = [];
- if (v[0]) {
- returnable.push(t('Minimum Due Date {{ minimumDate }}', { minimumDate: dateFormat(v[0]) }));
- }
- if (v[1]) {
- returnable.push(t('Maximum Due Date {{ maximumDate }}', { maximumDate: dateFormat(v[1]) }));
- }
- return returnable;
- },
- },
- filterOptions: {
- display: (filterList, onChange, index, column) => {
- const StartAtFilter = (
-
- {t('Due Date')}
-
-
- {
- ((filterList as unknown) as Date[])[index][0] = date;
- onChange(filterList[index], index, column);
- }}
- okLabel={t('OK')}
- todayLabel={t('Today')}
- cancelLabel={t('Cancel')}
- clearLabel={t('Clear')}
- />
-
-
- {
- ((filterList as unknown) as Date[])[index][1] = date;
- onChange(filterList[index], index, column);
- }}
- okLabel={t('OK')}
- todayLabel={t('Today')}
- cancelLabel={t('Cancel')}
- clearLabel={t('Clear')}
- />
-
-
-
- );
-
- return StartAtFilter;
- },
- fullWidth: true,
- },
- sort: true,
- customBodyRender: (startAt): string | ReactElement => {
- if (startAt) {
- const date = new Date(startAt);
- if (new Date().getFullYear() == date.getFullYear()) {
- return dayMonthFormat(date.getDate(), date.getMonth());
- } else {
- return dateFormat(date);
- }
- } else if (loading) {
- return ;
- }
- },
- },
+ filterType: 'multiselect',
+ customBodyRender: (contacts): string =>
+ contacts &&
+ contacts.nodes.map(({ name }) => name).join(t('List Separator')),
+ },
+ },
+ {
+ name: 'tagList',
+ label: t('Tags'),
+ options: {
+ filter: true,
+ sort: true,
+ filterList: initialFilter?.tags,
+ filterOptions: {
+ names: filterData?.accountList?.taskTagList || [],
+ fullWidth: true,
},
- ];
-
- const onSearchChange = useCallback(
- debounce(1000, (wildcardSearch) => {
- setFilter((filter) => {
- return { ...filter, wildcardSearch, after: null, before: null };
- });
- }),
- [],
- );
-
- const options: MUIDataTableOptions = {
- serverSide: true,
- rowsPerPage,
- onChangeRowsPerPage: (rowsPerPage) => {
- setRowsPerPage(rowsPerPage);
+ filterType: 'multiselect',
+ customFilterListOptions: {
+ render: (tag): string => t('Tag {{tag}}', { tag }),
},
- onChangePage: (newPage) => {
- if (newPage > currentPage) {
- setFilter({ ...filter, before: null, after: data.tasks.pageInfo.endCursor });
- } else {
- setFilter({ ...filter, before: data.tasks.pageInfo.startCursor, after: null });
+ customBodyRender: (tagList): ReactElement => {
+ if (loading) {
+ return (
+
+
+
+
+
+
+
+
+ );
+ } else {
+ return (
+ tagList &&
+ tagList.map((tag) => (
+
+ ))
+ );
+ }
+ },
+ },
+ },
+ {
+ name: 'user',
+ label: t('Assignee'),
+ options: {
+ filter: true,
+ sort: true,
+ display: false,
+ filterList: initialFilter?.userIds,
+ customFilterListOptions: {
+ render: (id): string => {
+ if (filterData?.accountListUsers?.nodes) {
+ const accountListUser = find(
+ { user: { id } },
+ filterData.accountListUsers.nodes,
+ );
+ return `${accountListUser.user.firstName} ${accountListUser.user.lastName}`;
+ }
+ return t('Loading');
+ },
+ },
+ filterOptions: {
+ names:
+ filterData?.accountListUsers?.nodes?.map(
+ ({ user: { id } }) => id,
+ ) || [],
+ renderValue: (id): string => {
+ if (filterData?.accountListUsers?.nodes) {
+ const accountListUser = find(
+ { user: { id } },
+ filterData.accountListUsers.nodes,
+ );
+ return `${accountListUser.user.firstName} ${accountListUser.user.lastName}`;
}
- setCurrentPage(newPage);
+ },
+ fullWidth: true,
},
- onRowClick: (_rowData, rowMeta) => {
- openTaskDrawer({ taskId: data.tasks.nodes[rowMeta.dataIndex].id });
+ filterType: 'multiselect',
+ customBodyRender: (user): ReactElement => {
+ if (user) {
+ return (
+
+ {user.firstName[0]}
+
+ );
+ }
},
- count: data?.tasks?.totalCount || 0,
- rowsPerPageOptions: [10, 25, 50, 100, 250, 500],
- fixedHeader: true,
- fixedSelectColumn: true,
- tableBodyMaxHeight: 'calc(100vh - 300px)',
- print: false,
- download: false,
- selectableRows: 'none',
- onFilterChange: (_changedColumn, filterList) => {
- let counter = 0;
- const updatedFilter = reduce(
- (result, value) => {
- if (value.length !== 0) {
- const name = columns[counter].name;
- switch (name) {
- case 'completedAt':
- result.completed = value[0] === 'true';
- break;
- case 'user':
- result.userIds = value;
- break;
- case 'tagList':
- result.tags = value;
- break;
- case 'contacts':
- result.contactIds = value;
- break;
- case 'startAt':
- if (value[0] && value[1]) {
- result.startAt = {
- min: new Date(value[0]).toISOString(),
- max: new Date(value[1]).toISOString(),
- };
- } else if (value[0]) {
- result.startAt = { min: new Date(value[0]).toISOString() };
- } else if (value[1]) {
- result.startAt = { max: new Date(value[1]).toISOString() };
- }
- break;
- default:
- result[name] = value;
- }
- }
- counter++;
- return result;
- },
- {
- ...filter,
- after: null,
- before: null,
- },
- filterList,
+ },
+ },
+ {
+ name: 'startAt',
+ label: t('Due Date'),
+ options: {
+ filter: true,
+ filterType: 'custom',
+ filterList:
+ initialFilter?.startAt &&
+ (([
+ initialFilter.startAt.min && new Date(initialFilter.startAt.min),
+ initialFilter.startAt.max && new Date(initialFilter.startAt.max),
+ ] as unknown) as string[]),
+ customFilterListOptions: {
+ render: (v) => {
+ const returnable: string[] = [];
+ if (v[0]) {
+ returnable.push(
+ t('Minimum Due Date {{ minimumDate }}', {
+ minimumDate: dateFormat(v[0]),
+ }),
+ );
+ }
+ if (v[1]) {
+ returnable.push(
+ t('Maximum Due Date {{ maximumDate }}', {
+ maximumDate: dateFormat(v[1]),
+ }),
+ );
+ }
+ return returnable;
+ },
+ },
+ filterOptions: {
+ display: (filterList, onChange, index, column) => {
+ const StartAtFilter = (
+
+ {t('Due Date')}
+
+
+ {
+ ((filterList as unknown) as Date[])[index][0] = date;
+ onChange(filterList[index], index, column);
+ }}
+ okLabel={t('OK')}
+ todayLabel={t('Today')}
+ cancelLabel={t('Cancel')}
+ clearLabel={t('Clear')}
+ />
+
+
+ {
+ ((filterList as unknown) as Date[])[index][1] = date;
+ onChange(filterList[index], index, column);
+ }}
+ okLabel={t('OK')}
+ todayLabel={t('Today')}
+ cancelLabel={t('Cancel')}
+ clearLabel={t('Clear')}
+ />
+
+
+
);
- setFilter(updatedFilter);
+
+ return StartAtFilter;
+ },
+ fullWidth: true,
+ },
+ sort: true,
+ customBodyRender: (startAt): string | ReactElement => {
+ if (startAt) {
+ const date = new Date(startAt);
+ if (new Date().getFullYear() == date.getFullYear()) {
+ return dayMonthFormat(date.getDate(), date.getMonth());
+ } else {
+ return dateFormat(date);
+ }
+ } else if (loading) {
+ return ;
+ }
+ },
+ },
+ },
+ ];
+
+ const onSearchChange = useCallback(
+ debounce(1000, (wildcardSearch) => {
+ setFilter((filter) => {
+ return { ...filter, wildcardSearch, after: null, before: null };
+ });
+ }),
+ [],
+ );
+
+ const options: MUIDataTableOptions = {
+ serverSide: true,
+ rowsPerPage,
+ onChangeRowsPerPage: (rowsPerPage) => {
+ setRowsPerPage(rowsPerPage);
+ },
+ onChangePage: (newPage) => {
+ if (newPage > currentPage) {
+ setFilter({
+ ...filter,
+ before: null,
+ after: data.tasks.pageInfo.endCursor,
+ });
+ } else {
+ setFilter({
+ ...filter,
+ before: data.tasks.pageInfo.startCursor,
+ after: null,
+ });
+ }
+ setCurrentPage(newPage);
+ },
+ onRowClick: (_rowData, rowMeta) => {
+ openTaskDrawer({ taskId: data.tasks.nodes[rowMeta.dataIndex].id });
+ },
+ count: data?.tasks?.totalCount || 0,
+ rowsPerPageOptions: [10, 25, 50, 100, 250, 500],
+ fixedHeader: true,
+ fixedSelectColumn: true,
+ tableBodyMaxHeight: 'calc(100vh - 300px)',
+ print: false,
+ download: false,
+ selectableRows: 'none',
+ onFilterChange: (_changedColumn, filterList) => {
+ let counter = 0;
+ const updatedFilter = reduce(
+ (result, value) => {
+ if (value.length !== 0) {
+ const name = columns[counter].name;
+ switch (name) {
+ case 'completedAt':
+ result.completed = value[0] === 'true';
+ break;
+ case 'user':
+ result.userIds = value;
+ break;
+ case 'tagList':
+ result.tags = value;
+ break;
+ case 'contacts':
+ result.contactIds = value;
+ break;
+ case 'startAt':
+ if (value[0] && value[1]) {
+ result.startAt = {
+ min: new Date(value[0]).toISOString(),
+ max: new Date(value[1]).toISOString(),
+ };
+ } else if (value[0]) {
+ result.startAt = { min: new Date(value[0]).toISOString() };
+ } else if (value[1]) {
+ result.startAt = { max: new Date(value[1]).toISOString() };
+ }
+ break;
+ default:
+ result[name] = value;
+ }
+ }
+ counter++;
+ return result;
},
- onSearchChange,
- searchText: initialFilter?.wildcardSearch,
- textLabels: {
- body: {
- noMatch: (
-
-
- {t('No tasks to show.')}
-
- ),
- },
+ {
+ ...filter,
+ after: null,
+ before: null,
},
- };
+ filterList,
+ );
+ setFilter(updatedFilter);
+ },
+ onSearchChange,
+ searchText: initialFilter?.wildcardSearch,
+ textLabels: {
+ body: {
+ noMatch: (
+
+
+ {t('No tasks to show.')}
+
+ ),
+ },
+ },
+ };
- return (
- }
- data={loading ? [['', ]] : data.tasks.nodes}
- columns={columns}
- options={options}
- />
- );
+ return (
+ }
+ data={loading ? [['', ]] : data.tasks.nodes}
+ columns={columns}
+ options={options}
+ />
+ );
};
export default TaskList;
diff --git a/src/components/Task/Status/Status.stories.tsx b/src/components/Task/Status/Status.stories.tsx
index 46f9020180..bbf4f2d7db 100644
--- a/src/components/Task/Status/Status.stories.tsx
+++ b/src/components/Task/Status/Status.stories.tsx
@@ -3,8 +3,8 @@ import withMargin from '../../../decorators/withMargin';
import TaskStatus from '.';
export default {
- title: 'Task/Status',
- decorators: [withMargin],
+ title: 'Task/Status',
+ decorators: [withMargin],
};
export const Default = (): ReactElement => ;
@@ -13,10 +13,18 @@ export const ColorPrimary = (): ReactElement => ;
export const NoDueDate = (): ReactElement => ;
-export const Due = (): ReactElement => ;
+export const Due = (): ReactElement => (
+
+);
-export const Overdue = (): ReactElement => ;
+export const Overdue = (): ReactElement => (
+
+);
-export const Completed = (): ReactElement => ;
+export const Completed = (): ReactElement => (
+
+);
-export const TooltipDisabled = (): ReactElement => ;
+export const TooltipDisabled = (): ReactElement => (
+
+);
diff --git a/src/components/Task/Status/Status.test.tsx b/src/components/Task/Status/Status.test.tsx
index c1b92045ff..3550bbc004 100644
--- a/src/components/Task/Status/Status.test.tsx
+++ b/src/components/Task/Status/Status.test.tsx
@@ -6,50 +6,61 @@ import { useApp } from '../../App';
import TaskStatus from '.';
jest.mock('../../App', () => ({
- useApp: jest.fn(),
+ useApp: jest.fn(),
}));
const openTaskDrawer = jest.fn();
beforeEach(() => {
- (useApp as jest.Mock).mockReturnValue({
- openTaskDrawer,
- });
- MockDate.set(new Date(2020, 1, 1));
+ (useApp as jest.Mock).mockReturnValue({
+ openTaskDrawer,
+ });
+ MockDate.set(new Date(2020, 1, 1));
});
afterEach(() => {
- MockDate.reset();
+ MockDate.reset();
});
describe('TaskStatus', () => {
- it('default', async () => {
- const { getByRole, findByText } = render();
- userEvent.hover(getByRole('button'));
- expect(await findByText('No Due Date')).toBeInTheDocument();
- });
+ it('default', async () => {
+ const { getByRole, findByText } = render();
+ userEvent.hover(getByRole('button'));
+ expect(await findByText('No Due Date')).toBeInTheDocument();
+ });
- it('completedAt', async () => {
- const { getByRole, findByText } = render();
- userEvent.hover(getByRole('button'));
- expect(await findByText('Completed about 10 years ago')).toBeInTheDocument();
- });
+ it('completedAt', async () => {
+ const { getByRole, findByText } = render(
+ ,
+ );
+ userEvent.hover(getByRole('button'));
+ expect(
+ await findByText('Completed about 10 years ago'),
+ ).toBeInTheDocument();
+ });
- it('startAt in past', async () => {
- const { getByRole, findByText } = render();
- userEvent.hover(getByRole('button'));
- expect(await findByText('Overdue about 10 years ago')).toBeInTheDocument();
- });
+ it('startAt in past', async () => {
+ const { getByRole, findByText } = render(
+ ,
+ );
+ userEvent.hover(getByRole('button'));
+ expect(await findByText('Overdue about 10 years ago')).toBeInTheDocument();
+ });
- it('startAt in future', async () => {
- const { getByRole, findByText } = render();
- userEvent.hover(getByRole('button'));
- expect(await findByText('Due in in almost 31 years')).toBeInTheDocument();
- });
+ it('startAt in future', async () => {
+ const { getByRole, findByText } = render(
+ ,
+ );
+ userEvent.hover(getByRole('button'));
+ expect(await findByText('Due in in almost 31 years')).toBeInTheDocument();
+ });
- it('taskId', async () => {
- const { getByRole } = render();
- userEvent.click(getByRole('button'));
- expect(openTaskDrawer).toHaveBeenCalledWith({ taskId: 'task-1', showCompleteForm: true });
+ it('taskId', async () => {
+ const { getByRole } = render();
+ userEvent.click(getByRole('button'));
+ expect(openTaskDrawer).toHaveBeenCalledWith({
+ taskId: 'task-1',
+ showCompleteForm: true,
});
+ });
});
diff --git a/src/components/Task/Status/Status.tsx b/src/components/Task/Status/Status.tsx
index 8dd757d66a..a463e2f2b3 100644
--- a/src/components/Task/Status/Status.tsx
+++ b/src/components/Task/Status/Status.tsx
@@ -11,180 +11,195 @@ import DoneIcon from '@material-ui/icons/Done';
import { useApp } from '../../App';
const useStyles = makeStyles((theme: Theme) => ({
- buttonGreen: {
- color: '#fff',
- backgroundColor: green[500],
- cursor: 'default',
- '&:hover': {
- backgroundColor: green[500],
- },
+ buttonGreen: {
+ color: '#fff',
+ backgroundColor: green[500],
+ cursor: 'default',
+ '&:hover': {
+ backgroundColor: green[500],
},
- buttonOrange: {
- color: '#fff',
- backgroundColor: orange[500],
+ },
+ buttonOrange: {
+ color: '#fff',
+ backgroundColor: orange[500],
+ },
+ buttonPrimary: {
+ color: '#fff',
+ backgroundColor: theme.palette.primary.main,
+ },
+ buttonSmall: {
+ width: theme.spacing(4.5),
+ height: theme.spacing(4.5),
+ fontSize: '1.4rem',
+ cursor: 'pointer',
+ },
+ buttonWithHover: {
+ transition: theme.transitions.create(['background'], {
+ duration: theme.transitions.duration.short,
+ }),
+ '&:hover': {
+ backgroundColor: green[500],
},
- buttonPrimary: {
- color: '#fff',
- backgroundColor: theme.palette.primary.main,
+ '&:hover $icon': {
+ opacity: 0,
+ transform: 'rotate(45deg)',
},
- buttonSmall: {
- width: theme.spacing(4.5),
- height: theme.spacing(4.5),
- fontSize: '1.4rem',
- cursor: 'pointer',
- },
- buttonWithHover: {
- transition: theme.transitions.create(['background'], {
- duration: theme.transitions.duration.short,
- }),
- '&:hover': {
- backgroundColor: green[500],
- },
- '&:hover $icon': {
- opacity: 0,
- transform: 'rotate(45deg)',
- },
- '&:hover $hoverIcon': {
- opacity: 1,
- transform: 'rotate(0deg)',
- },
- },
- icon: {
- position: 'absolute',
- left: '7px',
- transition: theme.transitions.create(['transform', 'opacity'], {
- duration: theme.transitions.duration.short,
- }),
- transform: 'rotate(0deg)',
- },
- hoverIcon: {
- opacity: 0,
- left: '6px',
- transform: 'rotate(-45deg)',
- color: '#fff',
+ '&:hover $hoverIcon': {
+ opacity: 1,
+ transform: 'rotate(0deg)',
},
+ },
+ icon: {
+ position: 'absolute',
+ left: '7px',
+ transition: theme.transitions.create(['transform', 'opacity'], {
+ duration: theme.transitions.duration.short,
+ }),
+ transform: 'rotate(0deg)',
+ },
+ hoverIcon: {
+ opacity: 0,
+ left: '6px',
+ transform: 'rotate(-45deg)',
+ color: '#fff',
+ },
}));
interface Props {
- taskId?: string;
- startAt?: string;
- completedAt?: string;
- color?: 'primary';
- disableTooltip?: boolean;
- tooltipPlacement?:
- | 'bottom-end'
- | 'bottom-start'
- | 'bottom'
- | 'left-end'
- | 'left-start'
- | 'left'
- | 'right-end'
- | 'right-start'
- | 'right'
- | 'top-end'
- | 'top-start'
- | 'top';
+ taskId?: string;
+ startAt?: string;
+ completedAt?: string;
+ color?: 'primary';
+ disableTooltip?: boolean;
+ tooltipPlacement?:
+ | 'bottom-end'
+ | 'bottom-start'
+ | 'bottom'
+ | 'left-end'
+ | 'left-start'
+ | 'left'
+ | 'right-end'
+ | 'right-start'
+ | 'right'
+ | 'top-end'
+ | 'top-start'
+ | 'top';
}
const TaskStatus = ({
- taskId,
- startAt,
- completedAt,
- color,
- disableTooltip = false,
- tooltipPlacement = 'right',
+ taskId,
+ startAt,
+ completedAt,
+ color,
+ disableTooltip = false,
+ tooltipPlacement = 'right',
}: Props): ReactElement => {
- const classes = useStyles();
- const { t } = useTranslation();
- const { openTaskDrawer } = useApp();
- const handleClick = (event: React.MouseEvent): void => {
- taskId && openTaskDrawer({ taskId, showCompleteForm: true });
- event.stopPropagation();
- };
+ const classes = useStyles();
+ const { t } = useTranslation();
+ const { openTaskDrawer } = useApp();
+ const handleClick = (
+ event: React.MouseEvent,
+ ): void => {
+ taskId && openTaskDrawer({ taskId, showCompleteForm: true });
+ event.stopPropagation();
+ };
- if (completedAt) {
- return (
-
-
-
-
-
- );
- } else if (startAt) {
- if (isPast(new Date(startAt))) {
- return (
-
-
-
-
-
-
- );
- } else {
- return (
-
-
-
-
-
-
- );
- }
+ if (completedAt) {
+ return (
+
+
+
+
+
+ );
+ } else if (startAt) {
+ if (isPast(new Date(startAt))) {
+ return (
+
+
+
+
+
+
+ );
} else {
- return (
-
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+
+ );
}
+ } else {
+ return (
+
+
+
+
+
+
+ );
+ }
};
export default TaskStatus;
diff --git a/src/components/Welcome/Welcome.stories.tsx b/src/components/Welcome/Welcome.stories.tsx
index 5572dacb0c..392918f727 100644
--- a/src/components/Welcome/Welcome.stories.tsx
+++ b/src/components/Welcome/Welcome.stories.tsx
@@ -5,42 +5,45 @@ import { text, select } from '@storybook/addon-knobs';
import Welcome from '.';
export default {
- title: 'Welcome',
+ title: 'Welcome',
};
export const Default = (): ReactElement => {
- return (
-
-
- }
- href="https://help.mpdx.org"
- target="_blank"
- rel="noopener noreferrer"
- style={{ color: '#fff' }}
- >
- Find help
-
-
- );
+ return (
+
+
+ }
+ href="https://help.mpdx.org"
+ target="_blank"
+ rel="noopener noreferrer"
+ style={{ color: '#fff' }}
+ >
+ Find help
+
+
+ );
};
Default.story = {
- parameters: {
- chromatic: { delay: 1000 },
- },
+ parameters: {
+ chromatic: { delay: 1000 },
+ },
};
diff --git a/src/components/Welcome/Welcome.test.tsx b/src/components/Welcome/Welcome.test.tsx
index 2b83fd606a..6b5d3458f8 100644
--- a/src/components/Welcome/Welcome.test.tsx
+++ b/src/components/Welcome/Welcome.test.tsx
@@ -3,30 +3,36 @@ import { render } from '@testing-library/react';
import Welcome from '.';
describe('Welcome', () => {
- it('has correct defaults', () => {
- const { getByTestId } = render(
-
- children
- ,
- );
- expect(getByTestId('welcomeTitle')).toHaveTextContent('test title');
- expect(getByTestId('welcomeSubtitle')).toHaveTextContent('test subtitle');
- expect(getByTestId('welcomeImg')).toHaveAttribute('src', 'drawkit-grape-pack-illustration-2.svg');
- expect(getByTestId('children')).toHaveTextContent('children');
- });
+ it('has correct defaults', () => {
+ const { getByTestId } = render(
+
+ children
+ ,
+ );
+ expect(getByTestId('welcomeTitle')).toHaveTextContent('test title');
+ expect(getByTestId('welcomeSubtitle')).toHaveTextContent('test subtitle');
+ expect(getByTestId('welcomeImg')).toHaveAttribute(
+ 'src',
+ 'drawkit-grape-pack-illustration-2.svg',
+ );
+ expect(getByTestId('children')).toHaveTextContent('children');
+ });
- it('has correct overrides', () => {
- const { getByTestId } = render(
- test title}
- subtitle={test subtitle
}
- imgSrc={require(`../../images/drawkit/grape/drawkit-grape-pack-illustration-1.svg`)}
- />,
- );
- expect(() => getByTestId('welcomeTitle')).toThrowError();
- expect(() => getByTestId('welcomeSubtitle')).toThrowError();
- expect(getByTestId('testTitle')).toHaveTextContent('test title');
- expect(getByTestId('testSubtitle')).toHaveTextContent('test subtitle');
- expect(getByTestId('welcomeImg')).toHaveAttribute('src', 'drawkit-grape-pack-illustration-1.svg');
- });
+ it('has correct overrides', () => {
+ const { getByTestId } = render(
+ test title}
+ subtitle={test subtitle
}
+ imgSrc={require(`../../images/drawkit/grape/drawkit-grape-pack-illustration-1.svg`)}
+ />,
+ );
+ expect(() => getByTestId('welcomeTitle')).toThrowError();
+ expect(() => getByTestId('welcomeSubtitle')).toThrowError();
+ expect(getByTestId('testTitle')).toHaveTextContent('test title');
+ expect(getByTestId('testSubtitle')).toHaveTextContent('test subtitle');
+ expect(getByTestId('welcomeImg')).toHaveAttribute(
+ 'src',
+ 'drawkit-grape-pack-illustration-1.svg',
+ );
+ });
});
diff --git a/src/components/Welcome/Welcome.tsx b/src/components/Welcome/Welcome.tsx
index c2a34f0d7d..8dd3b6c34a 100644
--- a/src/components/Welcome/Welcome.tsx
+++ b/src/components/Welcome/Welcome.tsx
@@ -1,99 +1,125 @@
import React, { ReactElement, ReactNode } from 'react';
-import { Box, Container, Typography, makeStyles, Theme, Grid } from '@material-ui/core';
+import {
+ Box,
+ Container,
+ Typography,
+ makeStyles,
+ Theme,
+ Grid,
+} from '@material-ui/core';
import { motion } from 'framer-motion';
import illustration2 from '../../images/drawkit/grape/drawkit-grape-pack-illustration-2.svg';
interface Props {
- title: string | ReactNode;
- subtitle: string | ReactNode;
- imgSrc?: string;
- children?: ReactNode;
+ title: string | ReactNode;
+ subtitle: string | ReactNode;
+ imgSrc?: string;
+ children?: ReactNode;
}
const useStyles = makeStyles((theme: Theme) => ({
- container: {
- '& > *': {
- marginRight: theme.spacing(2),
- '&:last-child': {
- marginRight: 0,
- },
- },
- },
- box: {
- display: 'flex',
- alignItems: 'center',
- minHeight: '100vh',
- minWidth: '100vw',
- backgroundColor: theme.palette.primary.main,
- color: '#fff',
- },
- subtitle: {
- maxWidth: '450px',
+ container: {
+ '& > *': {
+ marginRight: theme.spacing(2),
+ '&:last-child': {
+ marginRight: 0,
+ },
},
+ },
+ box: {
+ display: 'flex',
+ alignItems: 'center',
+ minHeight: '100vh',
+ minWidth: '100vw',
+ backgroundColor: theme.palette.primary.main,
+ color: '#fff',
+ },
+ subtitle: {
+ maxWidth: '450px',
+ },
}));
const variants = {
- animate: {
- transition: {
- staggerChildren: 0.15,
- },
+ animate: {
+ transition: {
+ staggerChildren: 0.15,
},
- exit: {
- transition: {
- staggerChildren: 0.1,
- },
+ },
+ exit: {
+ transition: {
+ staggerChildren: 0.1,
},
+ },
};
const divVariants = {
- initial: { x: -25, opacity: 0 },
- animate: { x: 0, opacity: 1 },
+ initial: { x: -25, opacity: 0 },
+ animate: { x: 0, opacity: 1 },
};
-const Welcome = ({ title, subtitle, imgSrc, children }: Props): ReactElement => {
- const classes = useStyles();
+const Welcome = ({
+ title,
+ subtitle,
+ imgSrc,
+ children,
+}: Props): ReactElement => {
+ const classes = useStyles();
- return (
-
-
-
-
-
-
- {typeof title === 'string' ? (
-
- {title}
-
- ) : (
- title
- )}
-
-
- {typeof subtitle === 'string' ? (
-
- {subtitle}
-
- ) : (
- subtitle
- )}
-
-
- {children}
-
-
-
-
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+
+ {typeof title === 'string' ? (
+
+ {title}
+
+ ) : (
+ title
+ )}
+
+
+ {typeof subtitle === 'string' ? (
+
+
+ {subtitle}
+
+
+ ) : (
+ subtitle
+ )}
+
+
+ {children}
+
+
+
+
+
+
+
+
+
+ );
};
export default Welcome;
diff --git a/src/decorators/withDispatch.tsx b/src/decorators/withDispatch.tsx
index b3dd091a0c..0e979c085f 100644
--- a/src/decorators/withDispatch.tsx
+++ b/src/decorators/withDispatch.tsx
@@ -3,12 +3,14 @@ import { useApp } from '../components/App';
import { Action } from '../components/App/rootReducer';
// eslint-disable-next-line react/display-name
-const withDispatch = (...actions: Action[]) => (StoryFn: () => ReactElement): ReactElement => {
- const { dispatch } = useApp();
- useEffect(() => {
- actions.map((action) => dispatch(action));
- }, []);
- return ;
+const withDispatch = (...actions: Action[]) => (
+ StoryFn: () => ReactElement,
+): ReactElement => {
+ const { dispatch } = useApp();
+ useEffect(() => {
+ actions.map((action) => dispatch(action));
+ }, []);
+ return ;
};
export default withDispatch;
diff --git a/src/decorators/withMargin.tsx b/src/decorators/withMargin.tsx
index e2702579d3..babf7b84d5 100644
--- a/src/decorators/withMargin.tsx
+++ b/src/decorators/withMargin.tsx
@@ -2,9 +2,9 @@ import React, { ReactElement } from 'react';
import { Box } from '@material-ui/core';
const withMargin = (StoryFn: () => ReactElement): ReactElement => (
-
-
-
+
+
+
);
export default withMargin;
diff --git a/src/lib/client.ts b/src/lib/client.ts
index 7c115fafa2..2d4d205fc4 100644
--- a/src/lib/client.ts
+++ b/src/lib/client.ts
@@ -1,50 +1,57 @@
-import { ApolloClient, createHttpLink, InMemoryCache, NormalizedCacheObject } from '@apollo/client';
+import {
+ ApolloClient,
+ createHttpLink,
+ InMemoryCache,
+ NormalizedCacheObject,
+} from '@apollo/client';
import { relayStylePagination } from '@apollo/client/utilities';
import { persistCache } from 'apollo-cache-persist';
import fetch from 'isomorphic-fetch';
export const cache = new InMemoryCache({
- typePolicies: {
- Query: {
- fields: {
- userNotifications: relayStylePagination(['accountListId']),
- },
- },
+ typePolicies: {
+ Query: {
+ fields: {
+ userNotifications: relayStylePagination(['accountListId']),
+ },
},
+ },
});
const httpLink = createHttpLink({
- uri: `${process.env.SITE_URL}/api/graphql`,
- fetch,
+ uri: `${process.env.SITE_URL}/api/graphql`,
+ fetch,
});
if (process.browser && process.env.NODE_ENV === 'production') {
- persistCache({
- cache,
- storage: window.localStorage,
- });
+ persistCache({
+ cache,
+ storage: window.localStorage,
+ });
}
const client = new ApolloClient({
- link: httpLink,
- cache,
+ link: httpLink,
+ cache,
});
-export const ssrClient = (token?: string): ApolloClient => {
- const httpLink = createHttpLink({
- uri: process.env.API_URL,
- fetch,
- headers: {
- Authorization: token ? `Bearer ${token}` : null,
- Accept: 'application/json',
- },
- });
+export const ssrClient = (
+ token?: string,
+): ApolloClient => {
+ const httpLink = createHttpLink({
+ uri: process.env.API_URL,
+ fetch,
+ headers: {
+ Authorization: token ? `Bearer ${token}` : null,
+ Accept: 'application/json',
+ },
+ });
- return new ApolloClient({
- link: httpLink,
- ssrMode: true,
- cache: new InMemoryCache(),
- });
+ return new ApolloClient({
+ link: httpLink,
+ ssrMode: true,
+ cache: new InMemoryCache(),
+ });
};
export default client;
diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts
index 9ebab2a4be..9104809cd5 100644
--- a/src/lib/i18n.ts
+++ b/src/lib/i18n.ts
@@ -5,31 +5,31 @@ import LanguageDetector from 'i18next-browser-languagedetector';
import { currencyFormat, numberFormat } from './intlFormat';
i18next
- .use(Backend)
- .use(initReactI18next)
- .use(LanguageDetector)
- .init({
- lng: 'en',
- nsSeparator: false,
- keySeparator: false,
- fallbackLng: 'en',
- interpolation: {
- escapeValue: false,
- format: (value, format): string => {
- switch (format) {
- case 'number':
- return numberFormat(value);
- case 'currency':
- return currencyFormat(value.amount, value.currency);
- default:
- return value;
- }
- },
- },
- react: {
- wait: true,
- useSuspense: false,
- },
- });
+ .use(Backend)
+ .use(initReactI18next)
+ .use(LanguageDetector)
+ .init({
+ lng: 'en',
+ nsSeparator: false,
+ keySeparator: false,
+ fallbackLng: 'en',
+ interpolation: {
+ escapeValue: false,
+ format: (value, format): string => {
+ switch (format) {
+ case 'number':
+ return numberFormat(value);
+ case 'currency':
+ return currencyFormat(value.amount, value.currency);
+ default:
+ return value;
+ }
+ },
+ },
+ react: {
+ wait: true,
+ useSuspense: false,
+ },
+ });
export default i18next;
diff --git a/src/lib/intlFormat/index.ts b/src/lib/intlFormat/index.ts
index b48c90127a..fbf0a2fc29 100644
--- a/src/lib/intlFormat/index.ts
+++ b/src/lib/intlFormat/index.ts
@@ -1,3 +1,8 @@
-import { numberFormat, percentageFormat, currencyFormat, dayMonthFormat } from './intlFormat';
+import {
+ numberFormat,
+ percentageFormat,
+ currencyFormat,
+ dayMonthFormat,
+} from './intlFormat';
export { numberFormat, percentageFormat, currencyFormat, dayMonthFormat };
diff --git a/src/lib/intlFormat/intlFormat.test.ts b/src/lib/intlFormat/intlFormat.test.ts
index 5cd148db8b..460bf5df55 100644
--- a/src/lib/intlFormat/intlFormat.test.ts
+++ b/src/lib/intlFormat/intlFormat.test.ts
@@ -1,183 +1,188 @@
import { dateFormat, monthYearFormat } from './intlFormat';
-import { numberFormat, percentageFormat, currencyFormat, dayMonthFormat } from '.';
+import {
+ numberFormat,
+ percentageFormat,
+ currencyFormat,
+ dayMonthFormat,
+} from '.';
describe('intlFormat', () => {
- let languageMock: jest.SpyInstance;
+ let languageMock: jest.SpyInstance;
- beforeEach(() => {
- languageMock = jest.spyOn(window.navigator, 'language', 'get');
- languageMock.mockReturnValue(undefined);
+ beforeEach(() => {
+ languageMock = jest.spyOn(window.navigator, 'language', 'get');
+ languageMock.mockReturnValue(undefined);
+ });
+
+ describe('numberFormat', () => {
+ it('formats number', () => {
+ expect(numberFormat(1000.1)).toEqual('1,000.1');
});
- describe('numberFormat', () => {
- it('formats number', () => {
- expect(numberFormat(1000.1)).toEqual('1,000.1');
- });
-
- it('handles NaN case', () => {
- expect(numberFormat(NaN)).toEqual('0');
- });
+ it('handles NaN case', () => {
+ expect(numberFormat(NaN)).toEqual('0');
+ });
- it('handles null case', () => {
- expect(numberFormat(null)).toEqual('0');
- });
+ it('handles null case', () => {
+ expect(numberFormat(null)).toEqual('0');
+ });
- it('handles undefined case', () => {
- expect(numberFormat(undefined)).toEqual('0');
- });
+ it('handles undefined case', () => {
+ expect(numberFormat(undefined)).toEqual('0');
+ });
- it('handles language', () => {
- expect(numberFormat(1000.01, 'fr')).toEqual('1 000,01');
- });
-
- describe('default language', () => {
- beforeEach(() => {
- languageMock.mockReturnValue('fr');
- });
-
- it('formats number', () => {
- expect(numberFormat(1000.01)).toEqual('1 000,01');
- });
- });
+ it('handles language', () => {
+ expect(numberFormat(1000.01, 'fr')).toEqual('1 000,01');
});
- describe('percentageFormat', () => {
- it('formats number as percentage', () => {
- expect(percentageFormat(0.95)).toEqual('95%');
- });
+ describe('default language', () => {
+ beforeEach(() => {
+ languageMock.mockReturnValue('fr');
+ });
- it('handles NaN case', () => {
- expect(percentageFormat(NaN)).toEqual('0%');
- });
-
- it('handles null case', () => {
- expect(percentageFormat(null)).toEqual('0%');
- });
-
- it('handles undefined case', () => {
- expect(percentageFormat(undefined)).toEqual('0%');
- });
+ it('formats number', () => {
+ expect(numberFormat(1000.01)).toEqual('1 000,01');
+ });
+ });
+ });
- it('handles language', () => {
- expect(percentageFormat(1000.01, 'fr')).toEqual('100 001 %');
- });
+ describe('percentageFormat', () => {
+ it('formats number as percentage', () => {
+ expect(percentageFormat(0.95)).toEqual('95%');
+ });
- describe('default language', () => {
- beforeEach(() => {
- languageMock.mockReturnValue('fr');
- });
+ it('handles NaN case', () => {
+ expect(percentageFormat(NaN)).toEqual('0%');
+ });
- it('handles language', () => {
- expect(percentageFormat(1000.01)).toEqual('100 001 %');
- });
- });
+ it('handles null case', () => {
+ expect(percentageFormat(null)).toEqual('0%');
});
- describe('currencyFormat', () => {
- it('formats number as currency', () => {
- expect(currencyFormat(1234.56, 'USD', 2)).toEqual('$1,234.56');
- });
-
- it('handles language', () => {
- expect(currencyFormat(1000.1, 'EUR', 2, 'fr')).toEqual('1 000,10 €');
- });
+ it('handles undefined case', () => {
+ expect(percentageFormat(undefined)).toEqual('0%');
+ });
- describe('value', () => {
- it('handles NaN case', () => {
- expect(currencyFormat(NaN, 'NZD')).toEqual('NZ$0');
- });
+ it('handles language', () => {
+ expect(percentageFormat(1000.01, 'fr')).toEqual('100 001 %');
+ });
- it('handles null case', () => {
- expect(currencyFormat(null, 'NZD')).toEqual('NZ$0');
- });
+ describe('default language', () => {
+ beforeEach(() => {
+ languageMock.mockReturnValue('fr');
+ });
- it('handles undefined case', () => {
- expect(currencyFormat(undefined, 'NZD')).toEqual('NZ$0');
- });
- });
+ it('handles language', () => {
+ expect(percentageFormat(1000.01)).toEqual('100 001 %');
+ });
+ });
+ });
- describe('currency', () => {
- it('handles null case', () => {
- expect(currencyFormat(1000, null)).toEqual('$1,000');
- });
+ describe('currencyFormat', () => {
+ it('formats number as currency', () => {
+ expect(currencyFormat(1234.56, 'USD', 2)).toEqual('$1,234.56');
+ });
- it('handles undefined case', () => {
- expect(currencyFormat(1000, undefined)).toEqual('$1,000');
- });
- });
+ it('handles language', () => {
+ expect(currencyFormat(1000.1, 'EUR', 2, 'fr')).toEqual('1 000,10 €');
+ });
- describe('default language', () => {
- beforeEach(() => {
- languageMock.mockReturnValue('fr');
- });
-
- it('handles language', () => {
- expect(currencyFormat(1000.1, 'EUR', 2)).toEqual('1 000,10 €');
- });
- });
- });
-
- describe('dayMonthFormat', () => {
- it('formats day and month as date', () => {
- expect(dayMonthFormat(5, 12)).toEqual('Jan 5');
- });
+ describe('value', () => {
+ it('handles NaN case', () => {
+ expect(currencyFormat(NaN, 'NZD')).toEqual('NZ$0');
+ });
- it('handles language', () => {
- expect(dayMonthFormat(5, 12, 'fr')).toEqual('5 janv.');
- });
+ it('handles null case', () => {
+ expect(currencyFormat(null, 'NZD')).toEqual('NZ$0');
+ });
- describe('default language', () => {
- beforeEach(() => {
- languageMock.mockReturnValue('fr');
- });
-
- it('handles language', () => {
- expect(dayMonthFormat(5, 12)).toEqual('5 janv.');
- });
- });
- });
-
- describe('monthYearFormat', () => {
- it('formats day and month as date', () => {
- expect(monthYearFormat(5, 2020)).toEqual('Jun 2020');
- });
-
- it('handles language', () => {
- expect(monthYearFormat(5, 2020, 'fr')).toEqual('juin 2020');
- });
+ it('handles undefined case', () => {
+ expect(currencyFormat(undefined, 'NZD')).toEqual('NZ$0');
+ });
+ });
- describe('default language', () => {
- beforeEach(() => {
- languageMock.mockReturnValue('fr');
- });
-
- it('handles language', () => {
- expect(monthYearFormat(5, 2020)).toEqual('juin 2020');
- });
- });
- });
-
- describe('dateFormat', () => {
- it('formats day and month as date', () => {
- expect(dateFormat(new Date(2019, 12, 5))).toEqual('Jan 5, 2020');
- });
+ describe('currency', () => {
+ it('handles null case', () => {
+ expect(currencyFormat(1000, null)).toEqual('$1,000');
+ });
+
+ it('handles undefined case', () => {
+ expect(currencyFormat(1000, undefined)).toEqual('$1,000');
+ });
+ });
- it('handles language', () => {
- expect(dateFormat(new Date(2019, 12, 5), 'fr')).toEqual('5 janv. 2020');
- });
+ describe('default language', () => {
+ beforeEach(() => {
+ languageMock.mockReturnValue('fr');
+ });
+
+ it('handles language', () => {
+ expect(currencyFormat(1000.1, 'EUR', 2)).toEqual('1 000,10 €');
+ });
+ });
+ });
+
+ describe('dayMonthFormat', () => {
+ it('formats day and month as date', () => {
+ expect(dayMonthFormat(5, 12)).toEqual('Jan 5');
+ });
+
+ it('handles language', () => {
+ expect(dayMonthFormat(5, 12, 'fr')).toEqual('5 janv.');
+ });
+
+ describe('default language', () => {
+ beforeEach(() => {
+ languageMock.mockReturnValue('fr');
+ });
+
+ it('handles language', () => {
+ expect(dayMonthFormat(5, 12)).toEqual('5 janv.');
+ });
+ });
+ });
+
+ describe('monthYearFormat', () => {
+ it('formats day and month as date', () => {
+ expect(monthYearFormat(5, 2020)).toEqual('Jun 2020');
+ });
+
+ it('handles language', () => {
+ expect(monthYearFormat(5, 2020, 'fr')).toEqual('juin 2020');
+ });
+
+ describe('default language', () => {
+ beforeEach(() => {
+ languageMock.mockReturnValue('fr');
+ });
+
+ it('handles language', () => {
+ expect(monthYearFormat(5, 2020)).toEqual('juin 2020');
+ });
+ });
+ });
+
+ describe('dateFormat', () => {
+ it('formats day and month as date', () => {
+ expect(dateFormat(new Date(2019, 12, 5))).toEqual('Jan 5, 2020');
+ });
+
+ it('handles language', () => {
+ expect(dateFormat(new Date(2019, 12, 5), 'fr')).toEqual('5 janv. 2020');
+ });
+
+ it('handles null case', () => {
+ expect(dateFormat(null)).toEqual('');
+ });
- it('handles null case', () => {
- expect(dateFormat(null)).toEqual('');
- });
+ describe('default language', () => {
+ beforeEach(() => {
+ languageMock.mockReturnValue('fr');
+ });
- describe('default language', () => {
- beforeEach(() => {
- languageMock.mockReturnValue('fr');
- });
-
- it('handles language', () => {
- expect(dateFormat(new Date(2019, 12, 5))).toEqual('5 janv. 2020');
- });
- });
+ it('handles language', () => {
+ expect(dateFormat(new Date(2019, 12, 5))).toEqual('5 janv. 2020');
+ });
});
+ });
});
diff --git a/src/lib/intlFormat/intlFormat.ts b/src/lib/intlFormat/intlFormat.ts
index d8ec0781ed..b22a56acec 100644
--- a/src/lib/intlFormat/intlFormat.ts
+++ b/src/lib/intlFormat/intlFormat.ts
@@ -1,55 +1,74 @@
import { isFinite, isNil } from 'lodash/fp';
const getLanguage = (): string => {
- const language = (typeof window !== 'undefined' && window.navigator.language) || 'en-US';
- return language;
+ const language =
+ (typeof window !== 'undefined' && window.navigator.language) || 'en-US';
+ return language;
};
export const numberFormat = (value: number, language = getLanguage()): string =>
- new Intl.NumberFormat(language, {
- style: 'decimal',
- }).format(isFinite(value) ? value : 0);
+ new Intl.NumberFormat(language, {
+ style: 'decimal',
+ }).format(isFinite(value) ? value : 0);
-export const percentageFormat = (value: number, language = getLanguage()): string =>
- new Intl.NumberFormat(language, {
- style: 'percent',
- }).format(isFinite(value) ? value : 0);
+export const percentageFormat = (
+ value: number,
+ language = getLanguage(),
+): string =>
+ new Intl.NumberFormat(language, {
+ style: 'percent',
+ }).format(isFinite(value) ? value : 0);
export const currencyFormat = (
- value: number,
- currency: string,
- minimumFractionDigits = 0,
- language = getLanguage(),
+ value: number,
+ currency: string,
+ minimumFractionDigits = 0,
+ language = getLanguage(),
+): string =>
+ new Intl.NumberFormat(language, {
+ style: 'currency',
+ currency: isNil(currency) ? 'USD' : currency,
+ minimumFractionDigits,
+ }).format(
+ isFinite(value) ? parseFloat(value.toFixed(minimumFractionDigits)) : 0,
+ );
+
+export const dayMonthFormat = (
+ day: number,
+ month: number,
+ language = getLanguage(),
): string =>
- new Intl.NumberFormat(language, {
- style: 'currency',
- currency: isNil(currency) ? 'USD' : currency,
- minimumFractionDigits,
- }).format(isFinite(value) ? parseFloat(value.toFixed(minimumFractionDigits)) : 0);
-
-export const dayMonthFormat = (day: number, month: number, language = getLanguage()): string =>
- new Intl.DateTimeFormat(language, {
- day: 'numeric',
- month: 'short',
- }).format(new Date(new Date().getFullYear(), month, day));
-
-export const monthYearFormat = (month: number, year: number, language = getLanguage()): string =>
- new Intl.DateTimeFormat(language, {
- month: 'short',
- year: 'numeric',
- }).format(new Date(year, month, 1));
+ new Intl.DateTimeFormat(language, {
+ day: 'numeric',
+ month: 'short',
+ }).format(new Date(new Date().getFullYear(), month, day));
+
+export const monthYearFormat = (
+ month: number,
+ year: number,
+ language = getLanguage(),
+): string =>
+ new Intl.DateTimeFormat(language, {
+ month: 'short',
+ year: 'numeric',
+ }).format(new Date(year, month, 1));
export const dateFormat = (date: Date, language = getLanguage()): string => {
- if (date === null) {
- return '';
- }
- return new Intl.DateTimeFormat(language, {
- day: 'numeric',
- month: 'short',
- year: 'numeric',
- }).format(date);
+ if (date === null) {
+ return '';
+ }
+ return new Intl.DateTimeFormat(language, {
+ day: 'numeric',
+ month: 'short',
+ year: 'numeric',
+ }).format(date);
};
-const intlFormat = { numberFormat, percentageFormat, currencyFormat, dayMonthFormat };
+const intlFormat = {
+ numberFormat,
+ percentageFormat,
+ currencyFormat,
+ dayMonthFormat,
+};
export default intlFormat;
diff --git a/src/lib/reduceObject/reduceObject.test.ts b/src/lib/reduceObject/reduceObject.test.ts
index abf377db74..0154477f3d 100644
--- a/src/lib/reduceObject/reduceObject.test.ts
+++ b/src/lib/reduceObject/reduceObject.test.ts
@@ -2,24 +2,24 @@ import { isFunction } from 'lodash/fp';
import reduceObject from './reduceObject';
const obj = {
- a: 'b',
+ a: 'b',
};
describe('common.fp.reduceObject', () => {
- it('should curry', () => {
- expect(isFunction(reduceObject())).toEqual(true);
- });
+ it('should curry', () => {
+ expect(isFunction(reduceObject())).toEqual(true);
+ });
- it('should create an object', () => {
- expect(
- reduceObject(
- (result, value, key) => {
- result[key] = value;
- return result;
- },
- {},
- obj,
- ),
- ).toEqual({ a: 'b' });
- });
+ it('should create an object', () => {
+ expect(
+ reduceObject(
+ (result, value, key) => {
+ result[key] = value;
+ return result;
+ },
+ {},
+ obj,
+ ),
+ ).toEqual({ a: 'b' });
+ });
});
diff --git a/src/theme.ts b/src/theme.ts
index 2a6037fe3b..4bf3e604ad 100644
--- a/src/theme.ts
+++ b/src/theme.ts
@@ -3,69 +3,69 @@ import { createMuiTheme } from '@material-ui/core/styles';
const defaultTheme = createMuiTheme();
const theme = createMuiTheme({
- typography: {
- fontFamily: "'Source Sans Pro', sans-serif",
+ typography: {
+ fontFamily: "'Source Sans Pro', sans-serif",
+ },
+ palette: {
+ primary: {
+ main: '#05699b',
},
- palette: {
- primary: {
- main: '#05699b',
- },
- secondary: {
- main: '#f5be19',
- },
+ secondary: {
+ main: '#f5be19',
},
- overrides: {
- MuiCard: {
- root: {
- borderRadius: '10px',
- },
- },
- MuiChip: {
- root: {
- borderRadius: '5px',
- },
- },
- MuiCardHeader: {
- root: {
- borderBottom: '1px solid #EBECEC',
- },
- title: {
- fontSize: '1.2rem',
- },
- },
- MuiCardContent: {
- root: {
- padding: defaultTheme.spacing(4),
- [defaultTheme.breakpoints.down('sm')]: {
- padding: defaultTheme.spacing(2),
- },
- },
+ },
+ overrides: {
+ MuiCard: {
+ root: {
+ borderRadius: '10px',
+ },
+ },
+ MuiChip: {
+ root: {
+ borderRadius: '5px',
+ },
+ },
+ MuiCardHeader: {
+ root: {
+ borderBottom: '1px solid #EBECEC',
+ },
+ title: {
+ fontSize: '1.2rem',
+ },
+ },
+ MuiCardContent: {
+ root: {
+ padding: defaultTheme.spacing(4),
+ [defaultTheme.breakpoints.down('sm')]: {
+ padding: defaultTheme.spacing(2),
},
- MuiCardActions: {
- root: {
- borderTop: '1px solid #EBECEC',
- justifyContent: 'flex-end',
- [defaultTheme.breakpoints.down('xs')]: {
- justifyContent: 'center',
- },
- },
+ },
+ },
+ MuiCardActions: {
+ root: {
+ borderTop: '1px solid #EBECEC',
+ justifyContent: 'flex-end',
+ [defaultTheme.breakpoints.down('xs')]: {
+ justifyContent: 'center',
},
- MuiTableCell: {
- head: {
- fontWeight: 700,
- },
+ },
+ },
+ MuiTableCell: {
+ head: {
+ fontWeight: 700,
+ },
+ },
+ MuiCssBaseline: {
+ '@global': {
+ html: {
+ backgroundColor: '#f6f7f9',
},
- MuiCssBaseline: {
- '@global': {
- html: {
- backgroundColor: '#f6f7f9',
- },
- body: {
- backgroundColor: '#05699b',
- },
- },
+ body: {
+ backgroundColor: '#05699b',
},
+ },
},
+ },
});
export default theme;
diff --git a/tsconfig.json b/tsconfig.json
index 954a8dbb7b..cb4b6dea3f 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,19 +1,19 @@
{
- "compilerOptions": {
- "target": "es5",
- "lib": ["dom", "dom.iterable", "esnext"],
- "allowJs": true,
- "skipLibCheck": true,
- "strict": false,
- "forceConsistentCasingInFileNames": true,
- "noEmit": true,
- "esModuleInterop": true,
- "module": "esnext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "preserve"
- },
- "exclude": ["node_modules"],
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".env"]
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve"
+ },
+ "exclude": ["node_modules"],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".env"]
}
diff --git a/types/CompleteTaskMutation.ts b/types/CompleteTaskMutation.ts
index cd789cc2f4..a06fea7bfe 100644
--- a/types/CompleteTaskMutation.ts
+++ b/types/CompleteTaskMutation.ts
@@ -3,7 +3,7 @@
// @generated
// This file was automatically generated and should not be edited.
-import { TaskUpdateInput, ResultEnum, ActivityTypeEnum } from "./globalTypes";
+import { TaskUpdateInput, ResultEnum, ActivityTypeEnum } from './globalTypes';
// ====================================================
// GraphQL mutation operation: CompleteTaskMutation
diff --git a/types/CreateTaskCommentMutation.ts b/types/CreateTaskCommentMutation.ts
index 642e28a831..95e15ec7bc 100644
--- a/types/CreateTaskCommentMutation.ts
+++ b/types/CreateTaskCommentMutation.ts
@@ -3,7 +3,7 @@
// @generated
// This file was automatically generated and should not be edited.
-import { TaskCommentCreateInput } from "./globalTypes";
+import { TaskCommentCreateInput } from './globalTypes';
// ====================================================
// GraphQL mutation operation: CreateTaskCommentMutation
diff --git a/types/CreateTaskMutation.ts b/types/CreateTaskMutation.ts
index 4a3aa19159..da22bed657 100644
--- a/types/CreateTaskMutation.ts
+++ b/types/CreateTaskMutation.ts
@@ -3,7 +3,12 @@
// @generated
// This file was automatically generated and should not be edited.
-import { TaskCreateInput, ActivityTypeEnum, NotificationTypeEnum, NotificationTimeUnitEnum } from "./globalTypes";
+import {
+ TaskCreateInput,
+ ActivityTypeEnum,
+ NotificationTypeEnum,
+ NotificationTimeUnitEnum,
+} from './globalTypes';
// ====================================================
// GraphQL mutation operation: CreateTaskMutation
diff --git a/types/GetCommentsForTaskDrawerCommentListQuery.ts b/types/GetCommentsForTaskDrawerCommentListQuery.ts
index df44102b66..16d0490c7b 100644
--- a/types/GetCommentsForTaskDrawerCommentListQuery.ts
+++ b/types/GetCommentsForTaskDrawerCommentListQuery.ts
@@ -25,7 +25,9 @@ export interface GetCommentsForTaskDrawerCommentListQuery_task_comments {
/**
* A list of nodes.
*/
- nodes: (GetCommentsForTaskDrawerCommentListQuery_task_comments_nodes | null)[] | null;
+ nodes:
+ | (GetCommentsForTaskDrawerCommentListQuery_task_comments_nodes | null)[]
+ | null;
}
export interface GetCommentsForTaskDrawerCommentListQuery_task {
diff --git a/types/GetContactsForTaskDrawerContactListQuery.ts b/types/GetContactsForTaskDrawerContactListQuery.ts
index c6c70927a8..340562adb5 100644
--- a/types/GetContactsForTaskDrawerContactListQuery.ts
+++ b/types/GetContactsForTaskDrawerContactListQuery.ts
@@ -3,7 +3,11 @@
// @generated
// This file was automatically generated and should not be edited.
-import { StatusEnum, SendNewsletterEnum, PledgeFrequencyEnum } from "./globalTypes";
+import {
+ StatusEnum,
+ SendNewsletterEnum,
+ PledgeFrequencyEnum,
+} from './globalTypes';
// ====================================================
// GraphQL query operation: GetContactsForTaskDrawerContactListQuery
@@ -69,7 +73,9 @@ export interface GetContactsForTaskDrawerContactListQuery_contacts {
/**
* A list of nodes.
*/
- nodes: (GetContactsForTaskDrawerContactListQuery_contacts_nodes | null)[] | null;
+ nodes:
+ | (GetContactsForTaskDrawerContactListQuery_contacts_nodes | null)[]
+ | null;
}
export interface GetContactsForTaskDrawerContactListQuery {
diff --git a/types/GetNotificationsQuery.ts b/types/GetNotificationsQuery.ts
index b794843f74..2511246bd8 100644
--- a/types/GetNotificationsQuery.ts
+++ b/types/GetNotificationsQuery.ts
@@ -3,7 +3,7 @@
// @generated
// This file was automatically generated and should not be edited.
-import { NotificationTypeTypeEnum } from "./globalTypes";
+import { NotificationTypeTypeEnum } from './globalTypes';
// ====================================================
// GraphQL query operation: GetNotificationsQuery
diff --git a/types/GetTaskForTaskDrawerQuery.ts b/types/GetTaskForTaskDrawerQuery.ts
index 9b514edbfe..fd9026844e 100644
--- a/types/GetTaskForTaskDrawerQuery.ts
+++ b/types/GetTaskForTaskDrawerQuery.ts
@@ -3,7 +3,11 @@
// @generated
// This file was automatically generated and should not be edited.
-import { ActivityTypeEnum, NotificationTypeEnum, NotificationTimeUnitEnum } from "./globalTypes";
+import {
+ ActivityTypeEnum,
+ NotificationTypeEnum,
+ NotificationTimeUnitEnum,
+} from './globalTypes';
// ====================================================
// GraphQL query operation: GetTaskForTaskDrawerQuery
diff --git a/types/GetTasksForTaskListQuery.ts b/types/GetTasksForTaskListQuery.ts
index 4ca21beb0c..3bf35f6ab7 100644
--- a/types/GetTasksForTaskListQuery.ts
+++ b/types/GetTasksForTaskListQuery.ts
@@ -3,7 +3,7 @@
// @generated
// This file was automatically generated and should not be edited.
-import { ActivityTypeEnum, DateTimeRangeInput } from "./globalTypes";
+import { ActivityTypeEnum, DateTimeRangeInput } from './globalTypes';
// ====================================================
// GraphQL query operation: GetTasksForTaskListQuery
diff --git a/types/GetThisWeekQuery.ts b/types/GetThisWeekQuery.ts
index 8898f3811c..7f37a74a88 100644
--- a/types/GetThisWeekQuery.ts
+++ b/types/GetThisWeekQuery.ts
@@ -3,7 +3,7 @@
// @generated
// This file was automatically generated and should not be edited.
-import { ActivityTypeEnum } from "./globalTypes";
+import { ActivityTypeEnum } from './globalTypes';
// ====================================================
// GraphQL query operation: GetThisWeekQuery
@@ -62,7 +62,9 @@ export interface GetThisWeekQuery_prayerRequestTasks_nodes_contacts {
/**
* A list of nodes.
*/
- nodes: (GetThisWeekQuery_prayerRequestTasks_nodes_contacts_nodes | null)[] | null;
+ nodes:
+ | (GetThisWeekQuery_prayerRequestTasks_nodes_contacts_nodes | null)[]
+ | null;
}
export interface GetThisWeekQuery_prayerRequestTasks_nodes {
diff --git a/types/GetTopBarQuery.ts b/types/GetTopBarQuery.ts
index fadc048edb..d60aaaaf52 100644
--- a/types/GetTopBarQuery.ts
+++ b/types/GetTopBarQuery.ts
@@ -32,7 +32,9 @@ export interface GetTopBarQuery_user_administrativeOrganizations {
/**
* A list of nodes.
*/
- nodes: (GetTopBarQuery_user_administrativeOrganizations_nodes | null)[] | null;
+ nodes:
+ | (GetTopBarQuery_user_administrativeOrganizations_nodes | null)[]
+ | null;
}
export interface GetTopBarQuery_user {
diff --git a/types/UpdateTaskMutation.ts b/types/UpdateTaskMutation.ts
index 19571e9182..cc6c70c733 100644
--- a/types/UpdateTaskMutation.ts
+++ b/types/UpdateTaskMutation.ts
@@ -3,7 +3,12 @@
// @generated
// This file was automatically generated and should not be edited.
-import { TaskUpdateInput, ActivityTypeEnum, NotificationTypeEnum, NotificationTimeUnitEnum } from "./globalTypes";
+import {
+ TaskUpdateInput,
+ ActivityTypeEnum,
+ NotificationTypeEnum,
+ NotificationTimeUnitEnum,
+} from './globalTypes';
// ====================================================
// GraphQL mutation operation: UpdateTaskMutation
diff --git a/types/globalTypes.ts b/types/globalTypes.ts
index 3648c65ffb..dc4172641d 100644
--- a/types/globalTypes.ts
+++ b/types/globalTypes.ts
@@ -8,101 +8,101 @@
//==============================================================
export enum ActivityTypeEnum {
- APPOINTMENT = "APPOINTMENT",
- CALL = "CALL",
- EMAIL = "EMAIL",
- FACEBOOK_MESSAGE = "FACEBOOK_MESSAGE",
- LETTER = "LETTER",
- NEWSLETTER_EMAIL = "NEWSLETTER_EMAIL",
- NEWSLETTER_PHYSICAL = "NEWSLETTER_PHYSICAL",
- NONE = "NONE",
- PRAYER_REQUEST = "PRAYER_REQUEST",
- PRE_CALL_LETTER = "PRE_CALL_LETTER",
- REMINDER_LETTER = "REMINDER_LETTER",
- SUPPORT_LETTER = "SUPPORT_LETTER",
- TALK_TO_IN_PERSON = "TALK_TO_IN_PERSON",
- TEXT_MESSAGE = "TEXT_MESSAGE",
- THANK = "THANK",
- TO_DO = "TO_DO",
+ APPOINTMENT = 'APPOINTMENT',
+ CALL = 'CALL',
+ EMAIL = 'EMAIL',
+ FACEBOOK_MESSAGE = 'FACEBOOK_MESSAGE',
+ LETTER = 'LETTER',
+ NEWSLETTER_EMAIL = 'NEWSLETTER_EMAIL',
+ NEWSLETTER_PHYSICAL = 'NEWSLETTER_PHYSICAL',
+ NONE = 'NONE',
+ PRAYER_REQUEST = 'PRAYER_REQUEST',
+ PRE_CALL_LETTER = 'PRE_CALL_LETTER',
+ REMINDER_LETTER = 'REMINDER_LETTER',
+ SUPPORT_LETTER = 'SUPPORT_LETTER',
+ TALK_TO_IN_PERSON = 'TALK_TO_IN_PERSON',
+ TEXT_MESSAGE = 'TEXT_MESSAGE',
+ THANK = 'THANK',
+ TO_DO = 'TO_DO',
}
export enum NotificationTimeUnitEnum {
- DAYS = "DAYS",
- HOURS = "HOURS",
- MINUTES = "MINUTES",
+ DAYS = 'DAYS',
+ HOURS = 'HOURS',
+ MINUTES = 'MINUTES',
}
export enum NotificationTypeEnum {
- BOTH = "BOTH",
- EMAIL = "EMAIL",
- MOBILE = "MOBILE",
+ BOTH = 'BOTH',
+ EMAIL = 'EMAIL',
+ MOBILE = 'MOBILE',
}
export enum NotificationTypeTypeEnum {
- CALL_PARTNER_ONCE_PER_YEAR = "CALL_PARTNER_ONCE_PER_YEAR",
- LARGER_GIFT = "LARGER_GIFT",
- LONG_TIME_FRAME_GIFT = "LONG_TIME_FRAME_GIFT",
- MISSING_ADDRESS_IN_NEWSLETTER = "MISSING_ADDRESS_IN_NEWSLETTER",
- MISSING_EMAIL_IN_NEWSLETTER = "MISSING_EMAIL_IN_NEWSLETTER",
- NEW_DESIGNATION_ACCOUNT_SUBSCRIPTION = "NEW_DESIGNATION_ACCOUNT_SUBSCRIPTION",
- NEW_PAGE_SUBSCRIPTION = "NEW_PAGE_SUBSCRIPTION",
- NEW_PARTNER_DUPLICATE_MERGED = "NEW_PARTNER_DUPLICATE_MERGED",
- NEW_PARTNER_DUPLICATE_NOT_MERGED = "NEW_PARTNER_DUPLICATE_NOT_MERGED",
- NEW_PARTNER_NO_DUPLICATE = "NEW_PARTNER_NO_DUPLICATE",
- RECONTINUING_GIFT = "RECONTINUING_GIFT",
- REMIND_PARTNER_IN_ADVANCE = "REMIND_PARTNER_IN_ADVANCE",
- SMALLER_GIFT = "SMALLER_GIFT",
- SPECIAL_GIFT = "SPECIAL_GIFT",
- STARTED_GIVING = "STARTED_GIVING",
- STOPPED_GIVING = "STOPPED_GIVING",
- THANK_PARTNER_ONCE_PER_YEAR = "THANK_PARTNER_ONCE_PER_YEAR",
- UPCOMING_ANNIVERSARY = "UPCOMING_ANNIVERSARY",
- UPCOMING_BIRTHDAY = "UPCOMING_BIRTHDAY",
+ CALL_PARTNER_ONCE_PER_YEAR = 'CALL_PARTNER_ONCE_PER_YEAR',
+ LARGER_GIFT = 'LARGER_GIFT',
+ LONG_TIME_FRAME_GIFT = 'LONG_TIME_FRAME_GIFT',
+ MISSING_ADDRESS_IN_NEWSLETTER = 'MISSING_ADDRESS_IN_NEWSLETTER',
+ MISSING_EMAIL_IN_NEWSLETTER = 'MISSING_EMAIL_IN_NEWSLETTER',
+ NEW_DESIGNATION_ACCOUNT_SUBSCRIPTION = 'NEW_DESIGNATION_ACCOUNT_SUBSCRIPTION',
+ NEW_PAGE_SUBSCRIPTION = 'NEW_PAGE_SUBSCRIPTION',
+ NEW_PARTNER_DUPLICATE_MERGED = 'NEW_PARTNER_DUPLICATE_MERGED',
+ NEW_PARTNER_DUPLICATE_NOT_MERGED = 'NEW_PARTNER_DUPLICATE_NOT_MERGED',
+ NEW_PARTNER_NO_DUPLICATE = 'NEW_PARTNER_NO_DUPLICATE',
+ RECONTINUING_GIFT = 'RECONTINUING_GIFT',
+ REMIND_PARTNER_IN_ADVANCE = 'REMIND_PARTNER_IN_ADVANCE',
+ SMALLER_GIFT = 'SMALLER_GIFT',
+ SPECIAL_GIFT = 'SPECIAL_GIFT',
+ STARTED_GIVING = 'STARTED_GIVING',
+ STOPPED_GIVING = 'STOPPED_GIVING',
+ THANK_PARTNER_ONCE_PER_YEAR = 'THANK_PARTNER_ONCE_PER_YEAR',
+ UPCOMING_ANNIVERSARY = 'UPCOMING_ANNIVERSARY',
+ UPCOMING_BIRTHDAY = 'UPCOMING_BIRTHDAY',
}
export enum PledgeFrequencyEnum {
- ANNUAL = "ANNUAL",
- EVERY_2_MONTHS = "EVERY_2_MONTHS",
- EVERY_2_WEEKS = "EVERY_2_WEEKS",
- EVERY_2_YEARS = "EVERY_2_YEARS",
- EVERY_4_MONTHS = "EVERY_4_MONTHS",
- EVERY_6_MONTHS = "EVERY_6_MONTHS",
- MONTHLY = "MONTHLY",
- QUARTERLY = "QUARTERLY",
- WEEKLY = "WEEKLY",
+ ANNUAL = 'ANNUAL',
+ EVERY_2_MONTHS = 'EVERY_2_MONTHS',
+ EVERY_2_WEEKS = 'EVERY_2_WEEKS',
+ EVERY_2_YEARS = 'EVERY_2_YEARS',
+ EVERY_4_MONTHS = 'EVERY_4_MONTHS',
+ EVERY_6_MONTHS = 'EVERY_6_MONTHS',
+ MONTHLY = 'MONTHLY',
+ QUARTERLY = 'QUARTERLY',
+ WEEKLY = 'WEEKLY',
}
export enum ResultEnum {
- ATTEMPTED = "ATTEMPTED",
- ATTEMPTED_LEFT_MESSAGE = "ATTEMPTED_LEFT_MESSAGE",
- COMPLETED = "COMPLETED",
- DONE = "DONE",
- NONE = "NONE",
- RECEIVED = "RECEIVED",
+ ATTEMPTED = 'ATTEMPTED',
+ ATTEMPTED_LEFT_MESSAGE = 'ATTEMPTED_LEFT_MESSAGE',
+ COMPLETED = 'COMPLETED',
+ DONE = 'DONE',
+ NONE = 'NONE',
+ RECEIVED = 'RECEIVED',
}
export enum SendNewsletterEnum {
- BOTH = "BOTH",
- EMAIL = "EMAIL",
- NONE = "NONE",
- PHYSICAL = "PHYSICAL",
+ BOTH = 'BOTH',
+ EMAIL = 'EMAIL',
+ NONE = 'NONE',
+ PHYSICAL = 'PHYSICAL',
}
export enum StatusEnum {
- APPOINTMENT_SCHEDULED = "APPOINTMENT_SCHEDULED",
- ASK_IN_FUTURE = "ASK_IN_FUTURE",
- CALL_FOR_DECISION = "CALL_FOR_DECISION",
- CONTACT_FOR_APPOINTMENT = "CONTACT_FOR_APPOINTMENT",
- CULTIVATE_RELATIONSHIP = "CULTIVATE_RELATIONSHIP",
- EXPIRED_REFERRAL = "EXPIRED_REFERRAL",
- NEVER_ASK = "NEVER_ASK",
- NEVER_CONTACTED = "NEVER_CONTACTED",
- NOT_INTERESTED = "NOT_INTERESTED",
- PARTNER_FINANCIAL = "PARTNER_FINANCIAL",
- PARTNER_PRAY = "PARTNER_PRAY",
- PARTNER_SPECIAL = "PARTNER_SPECIAL",
- RESEARCH_ABANDONED = "RESEARCH_ABANDONED",
- UNRESPONSIVE = "UNRESPONSIVE",
+ APPOINTMENT_SCHEDULED = 'APPOINTMENT_SCHEDULED',
+ ASK_IN_FUTURE = 'ASK_IN_FUTURE',
+ CALL_FOR_DECISION = 'CALL_FOR_DECISION',
+ CONTACT_FOR_APPOINTMENT = 'CONTACT_FOR_APPOINTMENT',
+ CULTIVATE_RELATIONSHIP = 'CULTIVATE_RELATIONSHIP',
+ EXPIRED_REFERRAL = 'EXPIRED_REFERRAL',
+ NEVER_ASK = 'NEVER_ASK',
+ NEVER_CONTACTED = 'NEVER_CONTACTED',
+ NOT_INTERESTED = 'NOT_INTERESTED',
+ PARTNER_FINANCIAL = 'PARTNER_FINANCIAL',
+ PARTNER_PRAY = 'PARTNER_PRAY',
+ PARTNER_SPECIAL = 'PARTNER_SPECIAL',
+ RESEARCH_ABANDONED = 'RESEARCH_ABANDONED',
+ UNRESPONSIVE = 'UNRESPONSIVE',
}
/**