dce-reactkit 3.1.4 → 3.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +236 -8
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/ItemPicker/NestableItemList.d.ts +17 -0
- package/dist/cjs/types/components/ItemPicker/index.d.ts +18 -0
- package/dist/cjs/types/components/ItemPicker/index.test.d.ts +1 -0
- package/dist/cjs/types/components/ItemPicker/types/PickableItem.d.ts +16 -0
- package/dist/cjs/types/helpers/parallelLimit.d.ts +12 -0
- package/dist/cjs/types/index.d.ts +3 -1
- package/dist/esm/index.js +236 -10
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/ItemPicker/NestableItemList.d.ts +17 -0
- package/dist/esm/types/components/ItemPicker/index.d.ts +18 -0
- package/dist/esm/types/components/ItemPicker/index.test.d.ts +1 -0
- package/dist/esm/types/components/ItemPicker/types/PickableItem.d.ts +16 -0
- package/dist/esm/types/helpers/parallelLimit.d.ts +12 -0
- package/dist/esm/types/index.d.ts +3 -1
- package/dist/index.d.ts +72 -27
- package/package.json +12 -2
- package/sandbox.js +20 -0
- package/src/components/ItemPicker/NestableItemList.tsx +288 -0
- package/src/components/ItemPicker/index.test.tsx +783 -0
- package/src/components/ItemPicker/index.tsx +85 -0
- package/src/components/ItemPicker/types/PickableItem.tsx +30 -0
- package/src/helpers/parallelLimit.ts +63 -0
- package/src/index.ts +4 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reusable nested item picker
|
|
3
|
+
* @author Yuen Ler Chow
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Import React
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
// Import shared components
|
|
10
|
+
import TabBox from '../TabBox';
|
|
11
|
+
|
|
12
|
+
// Import types
|
|
13
|
+
import PickableItem from './types/PickableItem';
|
|
14
|
+
|
|
15
|
+
// Import sub-components
|
|
16
|
+
import NestableItemList from './NestableItemList';
|
|
17
|
+
|
|
18
|
+
/*------------------------------------------------------------------------*/
|
|
19
|
+
/* Types */
|
|
20
|
+
/*------------------------------------------------------------------------*/
|
|
21
|
+
|
|
22
|
+
// Props definition
|
|
23
|
+
type Props = {
|
|
24
|
+
// Title of the picker
|
|
25
|
+
title: string,
|
|
26
|
+
// List of items to show
|
|
27
|
+
items: PickableItem[],
|
|
28
|
+
/**
|
|
29
|
+
* Handler to call when item selection is changed
|
|
30
|
+
* @param updatedItems an updated copy of the list of items with checked
|
|
31
|
+
* values updated
|
|
32
|
+
*/
|
|
33
|
+
onChanged: (updatedItems: PickableItem[]) => void,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/*------------------------------------------------------------------------*/
|
|
37
|
+
/* Component */
|
|
38
|
+
/*------------------------------------------------------------------------*/
|
|
39
|
+
|
|
40
|
+
const ItemPicker: React.FC<Props> = (props) => {
|
|
41
|
+
/*------------------------------------------------------------------------*/
|
|
42
|
+
/* Setup */
|
|
43
|
+
/*------------------------------------------------------------------------*/
|
|
44
|
+
|
|
45
|
+
/* -------------- Props ------------- */
|
|
46
|
+
|
|
47
|
+
// Destructure all props
|
|
48
|
+
const {
|
|
49
|
+
title,
|
|
50
|
+
items,
|
|
51
|
+
onChanged,
|
|
52
|
+
} = props;
|
|
53
|
+
|
|
54
|
+
/*------------------------------------------------------------------------*/
|
|
55
|
+
/* Component Functions */
|
|
56
|
+
/*------------------------------------------------------------------------*/
|
|
57
|
+
|
|
58
|
+
/*------------------------------------------------------------------------*/
|
|
59
|
+
/* Render */
|
|
60
|
+
/*------------------------------------------------------------------------*/
|
|
61
|
+
|
|
62
|
+
/*----------------------------------------*/
|
|
63
|
+
/* Main UI */
|
|
64
|
+
/*----------------------------------------*/
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<TabBox
|
|
68
|
+
title={title}
|
|
69
|
+
>
|
|
70
|
+
<div style={{ overflowX: 'scroll' }}>
|
|
71
|
+
<NestableItemList
|
|
72
|
+
items={items}
|
|
73
|
+
onChanged={onChanged}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
</TabBox>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/*------------------------------------------------------------------------*/
|
|
81
|
+
/* Wrap Up */
|
|
82
|
+
/*------------------------------------------------------------------------*/
|
|
83
|
+
|
|
84
|
+
// Export component
|
|
85
|
+
export default ItemPicker;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An item that can be chosen (for use within ItemPicker)
|
|
3
|
+
* @author Gabe Abrams
|
|
4
|
+
*/
|
|
5
|
+
type PickableItem = (
|
|
6
|
+
{
|
|
7
|
+
// Unique id of the item
|
|
8
|
+
id: number | string,
|
|
9
|
+
// Name of the item (human readable)
|
|
10
|
+
name: string,
|
|
11
|
+
// Link to view the item in the browser
|
|
12
|
+
link?: string,
|
|
13
|
+
}
|
|
14
|
+
& (
|
|
15
|
+
| {
|
|
16
|
+
// True if this is a group of items
|
|
17
|
+
isGroup: false,
|
|
18
|
+
// True if item is checked
|
|
19
|
+
checked: boolean,
|
|
20
|
+
}
|
|
21
|
+
| {
|
|
22
|
+
// True if this is a group of items
|
|
23
|
+
isGroup: true,
|
|
24
|
+
// List of sub-items
|
|
25
|
+
children: PickableItem[],
|
|
26
|
+
}
|
|
27
|
+
)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export default PickableItem;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run tasks in parallel with a limit on how many tasks can execute at once.
|
|
3
|
+
* No guarantees are made about the order of task execution
|
|
4
|
+
* @author Gabe Abrams
|
|
5
|
+
* @param taskFunctions functions that start asynchronous tasks and optionally
|
|
6
|
+
* resolve with values
|
|
7
|
+
* @param [limit=no limit] maximum number of asynchronous tasks to permit to run at
|
|
8
|
+
* once
|
|
9
|
+
* @returns array of resolved values in the same order as the task functions
|
|
10
|
+
*/
|
|
11
|
+
const parallelLimit = async (
|
|
12
|
+
taskFunctions: (() => Promise<any>)[],
|
|
13
|
+
limit?: number,
|
|
14
|
+
): Promise<any[]> => {
|
|
15
|
+
const results: any[] = [];
|
|
16
|
+
|
|
17
|
+
// Wait until finished with all tasks
|
|
18
|
+
await new Promise<void>((resolve) => {
|
|
19
|
+
/* ------------- Helpers ------------ */
|
|
20
|
+
|
|
21
|
+
let nextTaskIndex = 0;
|
|
22
|
+
let numFinishedTasks = 0;
|
|
23
|
+
/**
|
|
24
|
+
* Start the next task
|
|
25
|
+
* @author Gabe Abrams
|
|
26
|
+
*/
|
|
27
|
+
const startTask = async () => {
|
|
28
|
+
const taskIndex = nextTaskIndex++;
|
|
29
|
+
|
|
30
|
+
// Get the task
|
|
31
|
+
const taskFunction = taskFunctions[taskIndex];
|
|
32
|
+
if (!taskFunction) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Execute task
|
|
37
|
+
const result = await taskFunction();
|
|
38
|
+
|
|
39
|
+
// Add results
|
|
40
|
+
results[taskIndex] = result;
|
|
41
|
+
|
|
42
|
+
// Tally and finish
|
|
43
|
+
if (++numFinishedTasks === taskFunctions.length) {
|
|
44
|
+
return resolve();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Not finished! Start another task
|
|
48
|
+
startTask();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/* ----------- Start Tasks ---------- */
|
|
52
|
+
|
|
53
|
+
// If no limit, start all tasks. At least start 1 task
|
|
54
|
+
const numTasks = Math.max((limit || taskFunctions.length), 1);
|
|
55
|
+
for (let i = 0; i < numTasks; i++) {
|
|
56
|
+
startTask();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return results;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default parallelLimit;
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ import PopSuccessMark from './components/PopSuccessMark';
|
|
|
13
13
|
import PopFailureMark from './components/PopFailureMark';
|
|
14
14
|
import PopPendingMark from './components/PopPendingMark';
|
|
15
15
|
import CopiableBox from './components/CopiableBox';
|
|
16
|
+
import ItemPicker from './components/ItemPicker';
|
|
16
17
|
|
|
17
18
|
// Import errors
|
|
18
19
|
import ErrorWithCode from './errors/ErrorWithCode';
|
|
@@ -46,6 +47,7 @@ import getHumanReadableDate from './helpers/getHumanReadableDate';
|
|
|
46
47
|
import getPartOfDay from './helpers/getPartOfDay';
|
|
47
48
|
import stringsToHumanReadableList from './helpers/stringsToHumanReadableList';
|
|
48
49
|
import onlyKeepLetters from './helpers/onlyKeepLetters';
|
|
50
|
+
import parallelLimit from './helpers/parallelLimit';
|
|
49
51
|
|
|
50
52
|
// Import types
|
|
51
53
|
import ModalButtonType from './types/ModalButtonType';
|
|
@@ -73,6 +75,7 @@ export {
|
|
|
73
75
|
PopFailureMark,
|
|
74
76
|
PopPendingMark,
|
|
75
77
|
CopiableBox,
|
|
78
|
+
ItemPicker,
|
|
76
79
|
// Global functions
|
|
77
80
|
alert,
|
|
78
81
|
confirm,
|
|
@@ -102,6 +105,7 @@ export {
|
|
|
102
105
|
getPartOfDay,
|
|
103
106
|
stringsToHumanReadableList,
|
|
104
107
|
onlyKeepLetters,
|
|
108
|
+
parallelLimit,
|
|
105
109
|
// Client helpers
|
|
106
110
|
visitServerEndpoint,
|
|
107
111
|
// Server helpers
|