Skip to content

Commit 862b3ca

Browse files
authored
feat: move query utils to shared-ui (#1347)
1 parent f17b1ff commit 862b3ca

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

packages/javascript/bh-shared-ui/src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export * from './mocks';
2727
export * from './parseItemId';
2828
export * from './passwd';
2929
export * from './permissions';
30+
export * from './queries';
3031
export * from './searchParams';
3132
export * from './theme';
3233
export * from './user';
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright 2025 Specter Ops, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
export * from './queries';
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2025 Specter Ops, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
import { queriesAreLoadingOrErrored } from './queries';
18+
19+
describe('queriesAreLoadingOrErrored', () => {
20+
it.each(['isLoading', 'isError'] as const)('%s returns as expected based on all queries combined', (key) => {
21+
// all keys to true
22+
const allTrueActual = queriesAreLoadingOrErrored(
23+
{ [key]: true } as any,
24+
...([{ [key]: true }, { [key]: true }] as any),
25+
...([{ [key]: true }] as any)
26+
);
27+
expect(allTrueActual[key]).toBe(true);
28+
29+
// Partial keys are true
30+
const partialTrueActual = queriesAreLoadingOrErrored(
31+
{ [key]: true } as any,
32+
...([{ [key]: false }, { [key]: true }] as any),
33+
...([{ [key]: false }] as any)
34+
);
35+
expect(partialTrueActual[key]).toBe(true);
36+
37+
// set all keys to false
38+
const allFalseActual = queriesAreLoadingOrErrored(
39+
{ [key]: false } as any,
40+
...([{ [key]: false }, { [key]: false }] as any),
41+
...([{ [key]: false }] as any)
42+
);
43+
expect(allFalseActual[key]).toBe(false);
44+
});
45+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2025 Specter Ops, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
17+
import { UseQueryOptions, UseQueryResult } from 'react-query';
18+
19+
export type GenericQueryOptions<T> = Omit<UseQueryOptions<T, unknown, T, string[]>, 'queryFn'>;
20+
21+
export const getQueryKey = (baseKey: string[], customKeys?: string[]) => {
22+
return customKeys?.length ? [...baseKey, ...customKeys] : baseKey;
23+
};
24+
25+
/**
26+
* Use this when you want to treat the loading or error state of multiple queries as one.
27+
* For example, display a component when 2 separate APIs are done loading.
28+
* @param queries Variadic function that will check if any query isLoading or isError
29+
* @returns isLoading = true if any query is loading, and isError = true if any query has an error
30+
*/
31+
export const queriesAreLoadingOrErrored = (...queries: UseQueryResult<unknown, unknown>[]) => {
32+
let isLoading = false;
33+
let isError = false;
34+
35+
queries.forEach((query) => {
36+
if (query.isLoading) isLoading = true;
37+
if (query.isError) isError = true;
38+
});
39+
40+
return { isLoading, isError };
41+
};

0 commit comments

Comments
 (0)