Skip to content

Commit

Permalink
Add Alert Table columns event, event category, region, country, admin…
Browse files Browse the repository at this point in the history
… and view details in the table
  • Loading branch information
roshni73 committed Apr 5, 2024
1 parent 0903ceb commit feb5328
Show file tree
Hide file tree
Showing 16 changed files with 1,936 additions and 186 deletions.
4 changes: 4 additions & 0 deletions codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@ generates:
- "typescript-operations"
./generated/schema.json:
plugins:
<<<<<<< HEAD
- "introspection"
=======
- "introspection"
>>>>>>> 7246516 (Add Alert Table columns event, event category, region, country, admin and view details in the table)
Empty file added generated/schema.json
Empty file.
Empty file added generated/types.ts
Empty file.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
</noscript>
<div id="webapp-root">
<div id="webapp-preload">
%APP_TITLE% loading...
ALERT HUB
</div>
</div>
<script
Expand Down
166 changes: 83 additions & 83 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,84 +1,84 @@
{
"name": "ifrc-alert-hub",
"version": "0.0.0",
"type": "module",
"private": true,
"scripts": {
"start": "vite",
"build": "vite build",
"preview": "vite preview",
"generate": "graphql-codegen --config codegen.yml && eslint --fix src/generated/types.ts",
"lint:js": "eslint src",
"lint:css": "stylelint \"./src/**/*.css\"",
"lint:unused": "unimported",
"lint": "yarn lint:js && yarn lint:css && yarn lint:unused",
"test": "vitest",
"test:coverage": "vitest run --coverage",
"typecheck": "tsc"
},
"dependencies": {
"@apollo/client": "^3.9.9",
"@graphql-codegen/introspection": "^4.0.3",
"@graphql-codegen/typescript-operations": "^4.2.0",
"@ifrc-go/icons": "^1.3.3",
"@ifrc-go/ui": "^1.0.0",
"@mapbox/mapbox-gl-draw": "^1.4.3",
"@sentry/react": "^7.81.1",
"@togglecorp/fujs": "^2.1.1",
"@togglecorp/re-map": "^0.1.4",
"graphql": "^16.8.1",
"mapbox-gl": "^1.13.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.3"
},
"devDependencies": {
"@eslint/eslintrc": "^3.0.2",
"@julr/vite-plugin-validate-env": "^1.0.1",
"@types/mapbox-gl": "^1.13.0",
"@types/node": "^20.1.3",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.2.22",
"@types/react-router-dom": "^5.3.3",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.4.0",
"@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.19",
"cross-var": "^1.1.0",
"dotenv-cli": "^7.2.1",
"eslint": "^8.40.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-import-exports-imports-resolver": "^1.0.1",
"eslint-plugin-import-newlines": "^1.3.4",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"eslint-plugin-simple-import-sort": "^12.0.0",
"fast-glob": "^3.3.0",
"happy-dom": "^14.3.8",
"postcss": "^8.4.38",
"postcss-nested": "^6.0.1",
"postcss-normalize": "^10.0.1",
"postcss-preset-env": "^9.5.2",
"postinstall-postinstall": "^2.1.0",
"rollup-plugin-visualizer": "^5.9.0",
"stylelint": "^15.11.0",
"stylelint-config-concentric-order": "^5.2.0",
"stylelint-config-recommended": "^14.0.0",
"stylelint-no-unused-selectors": "git+https://github.com/toggle-corp/stylelint-no-unused-selectors#e0831e1",
"stylelint-value-no-unknown-custom-properties": "^5.0.0",
"surge": "^0.23.1",
"typescript": "^5.4.3",
"unimported": "1.31.1",
"vite": "^5.2.6",
"vite-plugin-checker": "^0.6.2",
"vite-plugin-compression2": "^1.0.0",
"vite-plugin-svgr": "^4.2.0",
"vite-plugin-webfont-dl": "^3.9.1",
"vite-tsconfig-paths": "^4.2.2",
"vitest": "^1.1.0"
}
}
"name": "alert-hub",
"version": "0.0.0",
"type": "module",
"private": true,
"scripts": {
"start": "vite",
"build": "vite build",
"generate": "graphql-codegen --config codegen.yml && eslint --fix generated/types.ts",
"lint:js": "eslint src",
"lint:css": "stylelint \"./src/**/*.css\"",
"lint:unused": "unimported",
"lint": "yarn lint:js && yarn lint:css && yarn lint:unused",
"test": "vitest",
"test:coverage": "vitest run --coverage",
"typecheck": "tsc"
},
"dependencies": {
"@apollo/client": "^3.9.7",
"@graphql-codegen/introspection": "^4.0.3",
"@graphql-codegen/typescript-operations": "^4.2.0",
"@ifrc-go/icons": "^1.3.3",
"@ifrc-go/ui": "^1.0.0",
"@sentry/react": "^7.81.1",
"@togglecorp/fujs": "^2.1.1",
"@togglecorp/re-map": "^0.2.0-beta-6",
"@togglecorp/toggle-form": "^2.0.4",
"graphql": "^16.8.1",
"mapbox-gl": "^1.13.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.3"
},
"devDependencies": {
"@eslint/eslintrc": "^2.0.3",
"@julr/vite-plugin-validate-env": "^1.0.1",
"@types/mapbox-gl": "^1.13.0",
"@types/node": "^20.1.3",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.2.22",
"@types/react-router-dom": "^5.3.3",
"@typescript-eslint/eslint-plugin": "^5.59.5",
"@typescript-eslint/parser": "^5.59.5",
"@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.14",
"cross-var": "^1.1.0",
"dotenv-cli": "^7.2.1",
"eslint": "^8.40.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-import-exports-imports-resolver": "^1.0.1",
"eslint-plugin-import-newlines": "^1.3.4",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.4",
"eslint-plugin-simple-import-sort": "^10.0.0",
"fast-glob": "^3.3.0",
"happy-dom": "^9.18.3",
"postcss": "^8.3.0",
"postcss-nested": "^6.0.1",
"postcss-normalize": "^10.0.1",
"postcss-preset-env": "^8.3.2",
"postinstall-postinstall": "^2.1.0",
"rollup-plugin-visualizer": "^5.9.0",
"stylelint": "^15.6.1",
"stylelint-config-concentric": "^2.0.2",
"stylelint-config-recommended": "^12.0.0",
"stylelint-no-unused-selectors": "git+https://github.com/toggle-corp/stylelint-no-unused-selectors#e0831e1",
"stylelint-value-no-unknown-custom-properties": "^4.0.0",
"surge": "^0.23.1",
"typescript": "^5.0.4",
"unimported": "1.28.0",
"vite": "^5.0.10",
"vite-plugin-checker": "^0.6.2",
"vite-plugin-compression2": "^0.11.0",
"vite-plugin-radar": "^0.9.2",
"vite-plugin-svgr": "^4.2.0",
"vite-plugin-webfont-dl": "^3.9.1",
"vite-tsconfig-paths": "^4.2.2",
"vitest": "^1.1.0"
}
}
205 changes: 205 additions & 0 deletions src/hooks/useFilterState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
import {
type SetStateAction,
useCallback,
useMemo,
useReducer,
} from 'react';
import { hasSomeDefinedValue } from '@ifrc-go/ui/utils';
import { isNotDefined } from '@togglecorp/fujs';
import { EntriesAsList } from '@togglecorp/toggle-form';

import useDebouncedValue from '#hooks/useDebouncedValue';

type SortDirection = 'asc' | 'dsc';
interface SortParameter {
name: string;
direction: SortDirection;
}
function getOrdering(sorting: SortParameter | undefined) {
if (isNotDefined(sorting)) {
return undefined;
}
if (sorting.direction === 'asc') {
return sorting.name;
}
return `-${sorting.name}`;
}

interface ResetFilterAction {
type: 'reset-filter';
}

interface SetFilterAction<FILTER extends object> {
type: 'set-filter';
value: SetStateAction<FILTER>;
}

interface SetPageAction {
type: 'set-page';
value: number;
}

interface SetOrderingAction {
type: 'set-ordering'
value: SetStateAction<SortParameter | undefined>;
}

type FilterActions<FILTER extends object> = (
ResetFilterAction
| SetFilterAction<FILTER>
| SetPageAction
| SetOrderingAction
);

interface FilterState<FILTER> {
filter: FILTER,
ordering: SortParameter | undefined,
page: number,
}

const defaultOrdering: SortParameter = {
name: 'id',
direction: 'dsc',
};

function useFilterState<FILTER extends object>(options: {
filter: FILTER,
ordering?: SortParameter | undefined,
page?: number,
pageSize?: number,
debounceTime?: number,
}) {
const {
filter,
ordering = defaultOrdering,
page = 1,
pageSize = 10,
debounceTime = 200,
} = options;

type Reducer = (
prevState: FilterState<FILTER>,
action: FilterActions<FILTER>,
) => FilterState<FILTER>;

const [state, dispatch] = useReducer<Reducer>(
(prevState, action) => {
if (action.type === 'reset-filter') {
return {
filter,
ordering,
page,
};
}
if (action.type === 'set-filter') {
return {
...prevState,
filter: typeof action.value === 'function'
? action.value(prevState.filter)
: action.value,
page: 1,
};
}
if (action.type === 'set-page') {
return {
...prevState,
page: action.value,
};
}
if (action.type === 'set-ordering') {
return {
...prevState,
ordering: typeof action.value === 'function'
? action.value(prevState.ordering)
: action.value,
page: 1,
};
}
return prevState;
},
{
filter,
ordering,
page,
},
);

const setFilter = useCallback(
(value: SetStateAction<FILTER>) => {
dispatch({
type: 'set-filter',
value,
});
},
[],
);

const setFilterField = useCallback(
(...args: EntriesAsList<FILTER>) => {
const [val, key] = args;
setFilter((oldFilterValue) => {
const newFilterValue = {
...oldFilterValue,
[key]: val,
};
return newFilterValue;
});
},
[setFilter],
);

const setPage = useCallback(
(value: number) => {
dispatch({
type: 'set-page',
value,
});
},
[],
);
const setOrdering = useCallback(
(value: SetStateAction<SortParameter | undefined>) => {
dispatch({
type: 'set-ordering',
value,
});
},
[],
);

const debouncedState = useDebouncedValue(state, debounceTime);

const sortState = useMemo(
() => ({
sorting: state.ordering,
setSorting: setOrdering,
}),
[state.ordering, setOrdering],
);

const filtered = useMemo(
() => hasSomeDefinedValue(debouncedState.filter),
[debouncedState.filter],
);

return {
rawFilter: state.filter,

filter: debouncedState.filter,
filtered,
setFilter,
setFilterField,

page: state.page,
offset: pageSize * (debouncedState.page - 1),
limit: pageSize,
setPage,

rawOrdering: getOrdering(ordering),
ordering: getOrdering(debouncedState.ordering),

sortState,
};
}

export default useFilterState;
Loading

0 comments on commit feb5328

Please sign in to comment.