Skip to content

Commit 39ec8e6

Browse files
committed
Improvements
Signed-off-by: guido <[email protected]>
1 parent 5dcc2e1 commit 39ec8e6

File tree

14 files changed

+272
-157
lines changed

14 files changed

+272
-157
lines changed

@types/index.d.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,24 +85,47 @@ declare namespace EntitiesSearch {
8585
/*
8686
* Storage
8787
*/
88-
type EntitiesState<CO> = Readonly<{
89-
contextualEntitiesOptions: OrderedSet<EntitiesSearch.ControlOption<CO>>;
90-
entitiesOptions: EntitiesState<CO>['contextualEntitiesOptions'];
91-
selectedEntitiesOptions: EntitiesState<CO>['entitiesOptions'];
88+
type EntitiesState<
89+
E,
90+
K,
91+
OptionSet = OrderedSet<EntitiesSearch.ControlOption<E>>
92+
> = Readonly<{
93+
entities: BaseControl<E>['value'];
94+
kind: BaseControl<K>['value'];
95+
contextualEntitiesOptions: OptionSet;
96+
currentEntitiesOptions: OptionSet;
97+
selectedEntitiesOptions: OptionSet;
9298
}>;
9399

94-
type EntitiesAction<V> =
100+
type EntitiesAction<E, K> =
95101
| {
96-
type: 'UPDATE_ENTITIES_OPTIONS';
97-
entitiesOptions: EntitiesState<V>['entitiesOptions'];
102+
type: 'UPDATE_ENTITIES';
103+
entities: EntitiesState<E, K>['entities'];
104+
}
105+
| {
106+
type: 'UPDATE_KIND';
107+
kind: EntitiesState<E, K>['kind'];
108+
}
109+
| {
110+
type: 'UPDATE_CURRENT_ENTITIES_OPTIONS';
111+
currentEntitiesOptions: EntitiesState<
112+
E,
113+
K
114+
>['currentEntitiesOptions'];
98115
}
99116
| {
100117
type: 'UPDATE_CONTEXTUAL_ENTITIES_OPTIONS';
101-
contextualEntitiesOptions: EntitiesState<V>['contextualEntitiesOptions'];
118+
contextualEntitiesOptions: EntitiesState<
119+
E,
120+
K
121+
>['contextualEntitiesOptions'];
102122
}
103123
| {
104124
type: 'UPDATE_SELECTED_ENTITIES_OPTIONS';
105-
selectedEntitiesOptions: EntitiesState<V>['selectedEntitiesOptions'];
125+
selectedEntitiesOptions: EntitiesState<
126+
E,
127+
K
128+
>['selectedEntitiesOptions'];
106129
};
107130

108131
/*

jest.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ module.exports = {
44
testEnvironment: 'jsdom',
55
moduleDirectories: ['node_modules'],
66
setupFilesAfterEnv: ['<rootDir>/tests/client/setup-tests.ts'],
7+
maxWorkers: 8,
78
};

scripts/create-posts.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
3+
# Default values
4+
N=10
5+
offset=1
6+
post_type='post'
7+
title='Page'
8+
9+
# Parse command line arguments
10+
while (("$#")); do
11+
case "$1" in
12+
--num)
13+
N=$2
14+
shift 2
15+
;;
16+
--offset)
17+
offset=$2
18+
shift 2
19+
;;
20+
--title)
21+
title=$2
22+
shift 2
23+
;;
24+
--type)
25+
post_type=$2
26+
shift 2
27+
;;
28+
*)
29+
echo "Unknown option: $1"
30+
exit 1
31+
;;
32+
esac
33+
done
34+
35+
lorem_ipsum="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus."
36+
37+
for ((i=offset; i<offset+N; i++)); do
38+
yarn wp-env run cli "wp post create --post_type='$post_type' --post_status=publish --post_title='$title $i' --post_content='$lorem_ipsum'"
39+
done

scripts/create-terms.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/bash
2+
3+
N=10
4+
taxonomy='category'
5+
term_name='Term'
6+
7+
# Parse command line arguments
8+
while (("$#")); do
9+
case "$1" in
10+
--num)
11+
N=$2
12+
shift 2
13+
;;
14+
--name)
15+
term_name=$2
16+
shift 2
17+
;;
18+
--taxonomy)
19+
taxonomy=$2
20+
shift 2
21+
;;
22+
*)
23+
echo "Unknown option: $1"
24+
exit 1
25+
;;
26+
esac
27+
done
28+
29+
for ((i=1; i<=N; i++)); do
30+
yarn wp-env run cli "wp term create $taxonomy '$term_name $i'"
31+
done

sources/client/src/api/search-entities.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ export async function searchEntities<E>(
77
type: string,
88
subtype: OrderedSet<string>,
99
phrase: string,
10-
queryArguments: EntitiesSearch.QueryArguments<string>
10+
queryArguments?: EntitiesSearch.QueryArguments<string>
1111
): Promise<OrderedSet<E>> {
1212
const {
1313
exclude,
1414
include,
1515
fields = ['title', 'id'],
1616
...restArguments
17-
} = queryArguments;
17+
} = queryArguments ?? {};
1818

1919
// @ts-ignore we need to pass string[] to the URLSearchParams
2020
const params = new URLSearchParams({

sources/client/src/components/composite-entities-by-kind.tsx

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,33 @@ export function CompositeEntitiesByKind<E, K>(
1818
props: EntitiesSearch.CompositeEntitiesKinds<E, K>
1919
): JSX.Element {
2020
// TODO Move the local state into the reducer. Let's see if it is possible.
21-
const { state, dispatch } = useEntitiesOptionsStorage<E>();
22-
const [searchPhrase, setSearchPhrase] = useState('');
23-
const [entitiesAndKind, setEntitiesAndKind] = useState({
21+
const { state, dispatch } = useEntitiesOptionsStorage<E, K>({
2422
entities: props.entities.value,
2523
kind: props.kind.value,
2624
});
25+
const [searchPhrase, setSearchPhrase] = useState('');
2726

2827
useEffect(() => {
2928
const promises = Set<ReturnType<SearchEntities<E, K>>>().asMutable();
3029

3130
promises.add(
32-
props.searchEntities('', entitiesAndKind.kind, {
33-
exclude: entitiesAndKind.entities,
31+
props.searchEntities('', state.kind, {
32+
exclude: state.entities,
3433
})
3534
);
3635

37-
if (entitiesAndKind.entities.size > 0) {
36+
if (state.entities.size > 0) {
3837
promises.add(
39-
props.searchEntities('', entitiesAndKind.kind, {
40-
include: entitiesAndKind.entities,
38+
props.searchEntities('', state.kind, {
39+
include: state.entities,
4140
per_page: '-1',
4241
})
4342
);
4443
}
4544

4645
Promise.all(promises)
4746
.then((result) => {
48-
const entitiesOptions = result[0] ?? OrderedSet([]);
47+
const currentEntitiesOptions = result[0] ?? OrderedSet([]);
4948
const selectedEntitiesOptions = result[1] ?? OrderedSet([]);
5049

5150
dispatch({
@@ -54,11 +53,11 @@ export function CompositeEntitiesByKind<E, K>(
5453
});
5554
dispatch({
5655
type: 'UPDATE_CONTEXTUAL_ENTITIES_OPTIONS',
57-
contextualEntitiesOptions: entitiesOptions,
56+
contextualEntitiesOptions: currentEntitiesOptions,
5857
});
5958
dispatch({
60-
type: 'UPDATE_ENTITIES_OPTIONS',
61-
entitiesOptions,
59+
type: 'UPDATE_CURRENT_ENTITIES_OPTIONS',
60+
currentEntitiesOptions: currentEntitiesOptions,
6261
});
6362
})
6463
.catch((error) => {
@@ -68,11 +67,6 @@ export function CompositeEntitiesByKind<E, K>(
6867
}, []);
6968

7069
const onChangeEntities = (entities: Entities<E>) => {
71-
// TODO It is the state still necessary having the reducer?
72-
setEntitiesAndKind({
73-
...entitiesAndKind,
74-
entities: entities ?? OrderedSet([]),
75-
});
7670
props.entities.onChange(entities);
7771

7872
if ((entities?.size ?? 0) <= 0) {
@@ -81,34 +75,32 @@ export function CompositeEntitiesByKind<E, K>(
8175
selectedEntitiesOptions: OrderedSet([]),
8276
});
8377
dispatch({
84-
type: 'UPDATE_ENTITIES_OPTIONS',
85-
entitiesOptions: state.contextualEntitiesOptions,
78+
type: 'UPDATE_CURRENT_ENTITIES_OPTIONS',
79+
currentEntitiesOptions: state.currentEntitiesOptions,
8680
});
8781
return;
8882
}
8983

9084
const promises = Set<ReturnType<SearchEntities<E, K>>>([
91-
props.searchEntities(searchPhrase, entitiesAndKind.kind, {
92-
exclude: entities,
93-
}),
94-
props.searchEntities('', entitiesAndKind.kind, {
85+
props.searchEntities(searchPhrase, state.kind),
86+
props.searchEntities('', state.kind, {
9587
include: entities,
9688
per_page: '-1',
9789
}),
9890
]);
9991

10092
Promise.all(promises)
10193
.then((result) => {
102-
const entitiesOptions = result[0] ?? OrderedSet([]);
94+
const currentEntitiesOptions = result[0] ?? OrderedSet([]);
10395
const selectedEntitiesOptions = result[1] ?? OrderedSet([]);
10496

10597
dispatch({
10698
type: 'UPDATE_SELECTED_ENTITIES_OPTIONS',
10799
selectedEntitiesOptions,
108100
});
109101
dispatch({
110-
type: 'UPDATE_ENTITIES_OPTIONS',
111-
entitiesOptions,
102+
type: 'UPDATE_CURRENT_ENTITIES_OPTIONS',
103+
currentEntitiesOptions: currentEntitiesOptions,
112104
});
113105
})
114106
.catch((error) => {
@@ -123,7 +115,14 @@ export function CompositeEntitiesByKind<E, K>(
123115
kind instanceof OrderedSet ? kind : OrderedSet<K>([kind as K]);
124116

125117
const entities = OrderedSet([]);
126-
setEntitiesAndKind({ kind: _kind, entities });
118+
dispatch({
119+
type: 'UPDATE_ENTITIES',
120+
entities,
121+
});
122+
dispatch({
123+
type: 'UPDATE_KIND',
124+
kind: _kind,
125+
});
127126
props.kind.onChange(_kind);
128127
props.entities.onChange(entities);
129128

@@ -133,24 +132,24 @@ export function CompositeEntitiesByKind<E, K>(
133132
selectedEntitiesOptions: entities,
134133
});
135134
dispatch({
136-
type: 'UPDATE_ENTITIES_OPTIONS',
137-
entitiesOptions: entities,
135+
type: 'UPDATE_CURRENT_ENTITIES_OPTIONS',
136+
currentEntitiesOptions: entities,
138137
});
139138
return;
140139
}
141140

142141
props
143142
.searchEntities('', _kind, {
144-
exclude: entitiesAndKind.entities,
143+
exclude: state.entities,
145144
})
146145
.then((result) => {
147146
dispatch({
148147
type: 'UPDATE_CONTEXTUAL_ENTITIES_OPTIONS',
149148
contextualEntitiesOptions: result,
150149
});
151150
dispatch({
152-
type: 'UPDATE_ENTITIES_OPTIONS',
153-
entitiesOptions: result,
151+
type: 'UPDATE_CURRENT_ENTITIES_OPTIONS',
152+
currentEntitiesOptions: result,
154153
});
155154
dispatch({
156155
type: 'UPDATE_SELECTED_ENTITIES_OPTIONS',
@@ -166,19 +165,21 @@ export function CompositeEntitiesByKind<E, K>(
166165

167166
const entities: EntitiesSearch.BaseControl<E> = {
168167
...props.entities,
169-
value: entitiesAndKind.entities,
168+
value: state.entities,
170169
options: orderSelectedOptionsAtTheTop<E>(
171170
uniqueControlOptions(
172-
state.selectedEntitiesOptions.merge(state.entitiesOptions)
171+
state.selectedEntitiesOptions.merge(
172+
state.currentEntitiesOptions
173+
)
173174
),
174-
entitiesAndKind.entities
175+
state.entities
175176
),
176177
onChange: onChangeEntities,
177178
};
178179

179180
const kind: EntitiesSearch.BaseControl<K> = {
180181
...props.kind,
181-
value: entitiesAndKind.kind,
182+
value: state.kind,
182183
onChange: onChangeKind,
183184
};
184185

@@ -190,28 +191,28 @@ export function CompositeEntitiesByKind<E, K>(
190191

191192
if (_phrase === '') {
192193
dispatch({
193-
type: 'UPDATE_ENTITIES_OPTIONS',
194-
entitiesOptions: state.contextualEntitiesOptions,
194+
type: 'UPDATE_CURRENT_ENTITIES_OPTIONS',
195+
currentEntitiesOptions: state.contextualEntitiesOptions,
195196
});
196197
return;
197198
}
198199

199200
props
200-
.searchEntities(_phrase, entitiesAndKind.kind, {
201-
exclude: entitiesAndKind.entities,
201+
.searchEntities(_phrase, state.kind, {
202+
exclude: state.entities,
202203
})
203204
.then((result) =>
204205
dispatch({
205-
type: 'UPDATE_ENTITIES_OPTIONS',
206-
entitiesOptions: result,
206+
type: 'UPDATE_CURRENT_ENTITIES_OPTIONS',
207+
currentEntitiesOptions: result,
207208
})
208209
)
209210
.catch(() => {
210211
// TODO Add warning for user feedback.
211212
const emptySet = OrderedSet([]);
212213
dispatch({
213-
type: 'UPDATE_ENTITIES_OPTIONS',
214-
entitiesOptions: emptySet,
214+
type: 'UPDATE_CURRENT_ENTITIES_OPTIONS',
215+
currentEntitiesOptions: emptySet,
215216
});
216217
return emptySet;
217218
});

0 commit comments

Comments
 (0)