Move to Zustand and add Filters to web_test (#1077)

* Moved to zustand and started refactored filters

- Move from redux to zustand
- Refactor Filters typings and add some helper types
- Add Filters button and Picker/Switch filter options
- Fixed Syosetu typings

* Add rule consistent-type-definitions

- Add consistent-type-definitions eslint rule to force consistent use of types instead of interfaces
- Run eslint to auto-change every interface to types

https://dev.to/atheodosiou/types-vs-interfaces-in-typescript-making-the-right-choice-48a4
https://www.youtube.com/watch?v=zM9UPcIyyhQ

* Add other filters and refactor

- Move Dialog to FiltersDialog
- CheckboxFilter, TextFilter, XCheckboxFilter added
- Added TripleCheckbox and TripleSwitch as tri-state checkbox/switch items using Mui stylings

* TriStateCheckbox/Switch refactor

- Change name of TripleSwitch and TripleCheckbox to TriState
- Change slightly TriStateSwitch and StyledSwitch styles
- Add option to change into TriStateSwitches via `localStorage` value `useSwitches`

* Refactor code and fix issues

* fix: prettier

---------

Co-authored-by: nyagami <hoangquan05112002@gmail.com>
This commit is contained in:
Marcin Majewski
2024-08-18 17:31:41 +02:00
committed by GitHub
parent eb5522b066
commit b2caf26da3
73 changed files with 1914 additions and 916 deletions
+4 -4
View File
@@ -2,7 +2,7 @@
import { parse as parseProto } from 'protobufjs';
interface FetchInit {
type FetchInit = {
headers?: Record<string, string | undefined> | Headers;
method?: string;
body?: FormData | string;
@@ -12,7 +12,7 @@ interface FetchInit {
| undefined
| FormData
| Headers;
}
};
const makeInit = async (init?: FetchInit) => {
const defaultHeaders: Record<string, string> = {
@@ -100,13 +100,13 @@ export const fetchText = async function (
}
};
interface ProtoRequestInit {
type ProtoRequestInit = {
// merged .proto file
proto: string;
requestType: string;
requestData?: any;
responseType: string;
}
};
const BYTE_MARK = BigInt((1 << 8) - 1);
+80 -28
View File
@@ -1,8 +1,14 @@
export interface FilterOption {
/**
* Filter's Options user can choose from
*/
export type FilterOption = {
readonly label: string;
readonly value: string;
}
};
/**
* Every currently implemented FilterType
*/
export enum FilterTypes {
TextInput = 'Text',
Picker = 'Picker',
@@ -11,59 +17,83 @@ export enum FilterTypes {
ExcludableCheckboxGroup = 'XCheckbox',
}
interface SwitchFilter {
type SwitchFilter = {
type: FilterTypes.Switch;
/** Default value */
value: boolean;
}
};
interface TextFilter {
type TextFilter = {
type: FilterTypes.TextInput;
/** Default value */
value: string;
}
};
interface CheckboxFilter {
type CheckboxFilter = {
type: FilterTypes.CheckboxGroup;
options: readonly FilterOption[];
/** Default value */
value: string[];
}
interface PickerFilter {
};
type PickerFilter = {
type: FilterTypes.Picker;
options: readonly FilterOption[];
/** Default value */
value: string;
}
};
interface ExcludableCheckboxFilter {
type ExcludableCheckboxFilter = {
type: FilterTypes.ExcludableCheckboxGroup;
options: readonly FilterOption[];
value: { include?: string[]; exclude?: string[] };
}
/** Default value */
value: {
/** Checkboxes marked as included */
include?: string[];
/** Checkboxes marked as excluded */
exclude?: string[];
};
};
export type Filters = Record<
string,
{ label: string } & (
| PickerFilter
| CheckboxFilter
| TextFilter
| SwitchFilter
| ExcludableCheckboxFilter
)
>;
/**
* key - filter pairs
*/
export type Filters = Record<string, Filter<FilterTypes>>;
/** Mapping of each FilterType to a Filter */
type FilterFromType = {
[FilterTypes.CheckboxGroup]: CheckboxFilter;
[FilterTypes.ExcludableCheckboxGroup]: ExcludableCheckboxFilter;
[FilterTypes.Picker]: PickerFilter;
[FilterTypes.Switch]: SwitchFilter;
[FilterTypes.TextInput]: TextFilter;
};
/**
* Get type of a single filter type from the {@link FilterType}
*/
export type Filter<Type extends FilterTypes> = {
label: string;
} & FilterFromType[Type];
/**
* Strip {@link FilterObject} object from 'label' and 'options' to get key - filter_value pairs
* @see {@link ValueOfFilter}
*/
export type FilterToValues<
T extends Record<string, { type: FilterTypes }> | undefined,
> = T extends undefined
FilterObject extends Record<string, { type: FilterTypes }> | undefined,
> = FilterObject extends undefined
? undefined
: {
[K in keyof T]: Omit<
{ type: NonNullable<T>[K]['type'] } & Filters[string],
'label' | 'options'
// copy the Filters object, but just get {value,type} pairs instead of the whole Filter object
[SingleFilter in keyof FilterObject]: FilterValueWithType<
FilterType<NonNullable<FilterObject>[SingleFilter]>
>;
};
/**
* Get value type for a {@link Filter} given it's FilterType
* @see {@link FilterTypes}
*/
export type ValueOfFilter<T extends FilterTypes> =
T extends FilterTypes.CheckboxGroup
? CheckboxFilter['value']
@@ -76,3 +106,25 @@ export type ValueOfFilter<T extends FilterTypes> =
: T extends FilterTypes.ExcludableCheckboxGroup
? ExcludableCheckboxFilter['value']
: never;
/** Get {@link Filter}'s type */
export type FilterType<T extends { type: unknown }> = T extends {
type: infer K;
}
? K extends FilterTypes
? K
: never
: never;
/** Get {type, value} types for given FilterType
* @see {@link ValueOfFilter}
*/
export type FilterValueWithType<T extends FilterTypes> = {
type: T;
value: ValueOfFilter<T>;
};
/**
* Any possible filter value
*/
export type AnyFilterValue = ValueOfFilter<FilterTypes>;