Skip to content

Commit 0564e24

Browse files
committed
WIP types fixed
1 parent d7f96bd commit 0564e24

File tree

5 files changed

+81
-36
lines changed

5 files changed

+81
-36
lines changed

lib/ExecutionLogModel.js

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export function getWaitingItemLabel(item, finished) {
115115
* Get details for a waiting item to display in an expanded view.
116116
*
117117
* @param {import('./types').WaitingItem} item
118-
* @returns {{ label: string; value: string }[]}
118+
* @returns {import('./types').WaitingItemDetail[]}
119119
*/
120120
export function getWaitingItemDetails(item) {
121121
if (!item.data) {
@@ -236,7 +236,7 @@ export function isPendingItem(item) {
236236
* Get badge descriptors for a waiting item.
237237
*
238238
* @param {import('./types').WaitingItem} item
239-
* @returns {{ text: string, variant?: string }[]}
239+
* @returns {import('./types').WaitingItemBadge[]}
240240
*/
241241
export function getWaitingItemBadges(item) {
242242
const badges = [];
@@ -330,7 +330,7 @@ export default class ExecutionLogModel {
330330
*/
331331
addEntry(entry) {
332332
if (entry.type === 'poll') {
333-
this._handlePollEntry(entry);
333+
this._handlePollEntry(/** @type {any} */ (entry));
334334
return this._entries;
335335
}
336336

@@ -398,18 +398,7 @@ export default class ExecutionLogModel {
398398
* entries, applying key-based deduplication to avoid re-emitting unchanged
399399
* data on every poll tick.
400400
*
401-
* @param {object} pollEntry
402-
* @param {{ success: boolean, response?: { items: any[] } }} pollEntry.jobsResult
403-
* @param {{ success: boolean, response?: { items: any[] } }} pollEntry.userTasksResult
404-
* @param {{ success: boolean, response?: { items: any[] } }} pollEntry.messageSubscriptionsResult
405-
* @param {{ success: boolean, response?: { items: any[] } }} pollEntry.elementInstancesResult
406-
* @param {{ success: boolean, response?: { items: any[] } }} [pollEntry.variablesResult]
407-
* @param {string} pollEntry.elementId
408-
* @param {Set<string>} [pollEntry.childElementIds]
409-
* @param {function(string): Set<string>} [pollEntry.getChildIds]
410-
* Called with a parent element ID; returns the set of direct child IDs.
411-
* Used to resolve event sub-process children from the element hierarchy.
412-
* @param {number} pollEntry.timestamp
401+
* @param {import('./types').TaskExecutionPollData} pollEntry
413402
*/
414403
_handlePollEntry({
415404
jobsResult,
@@ -590,7 +579,7 @@ const CHILD_ELEMENT_TYPES = new Set([
590579
/**
591580
* Build a list of child element instances (tasks executed inside a sub-process).
592581
*
593-
* @param {{ success: boolean, response?: { items: any[] } }} elementInstancesResult
582+
* @param {import('./types').ApiResponse<{ items: any[] }>} elementInstancesResult
594583
* @param {string} elementId - the element being tested (excluded from children)
595584
* @param {Set<string>} [childElementIds] - set of valid direct child element IDs
596585
* @returns {import('./types').ChildElement[]}
@@ -600,7 +589,7 @@ export function buildChildElements(elementInstancesResult, elementId, childEleme
600589
return [];
601590
}
602591

603-
return (elementInstancesResult.response.items || [])
592+
return (/** @type {{ items: any[] }} */ (elementInstancesResult.response).items || [])
604593
.filter(el => {
605594
if (el.elementId === elementId) return false;
606595
if (!CHILD_ELEMENT_TYPES.has(el.type)) return false;
@@ -623,19 +612,16 @@ export function buildChildElements(elementInstancesResult, elementId, childEleme
623612
* Enrich event sub-process waiting items with their executed child element instances.
624613
*
625614
* @param {import('./types').WaitingItem[]} waitingItems
626-
* @param {{ success: boolean, response?: { items: any[] } }} elementInstancesResult
627-
* @param {Object} elementRegistry
628-
*/
629-
/**
630-
* @param {function(string): Set<string>} getChildIds
615+
* @param {import('./types').ApiResponse<{ items: any[] }>} elementInstancesResult
616+
* @param {((arg0: string) => Set<string>)} [getChildIds]
631617
* Called with a parent element ID; returns the set of direct child IDs.
632618
*/
633619
export function enrichEventSubProcessChildren(waitingItems, elementInstancesResult, getChildIds) {
634620
if (!elementInstancesResult.success || typeof getChildIds !== 'function') {
635621
return;
636622
}
637623

638-
const allInstances = elementInstancesResult.response.items || [];
624+
const allInstances = /** @type {{ items: any[] }} */ (elementInstancesResult.response).items || [];
639625

640626
for (const item of waitingItems) {
641627
if (item.type !== 'event-sub-process') {
@@ -669,17 +655,17 @@ export function enrichEventSubProcessChildren(waitingItems, elementInstancesResu
669655
* variable scopeKey to element instance keys.
670656
*
671657
* @param {import('./types').ChildElement[]} children
672-
* @param {{ success: boolean, response?: { items: any[] } }} elementInstancesResult
673-
* @param {{ success: boolean, response?: { items: any[] } }} [variablesResult]
658+
* @param {import('./types').ApiResponse<{ items: any[] }>} elementInstancesResult
659+
* @param {import('./types').ApiResponse<{ items: any[] }>} [variablesResult]
674660
* @returns {import('./types').ChildElement[]}
675661
*/
676662
export function enrichChildrenWithVariables(children, elementInstancesResult, variablesResult) {
677663
if (!variablesResult?.success || !elementInstancesResult.success) {
678664
return children;
679665
}
680666

681-
const elementInstances = elementInstancesResult.response.items || [];
682-
const variables = variablesResult.response.items || [];
667+
const elementInstances = /** @type {{ items: any[] }} */ (elementInstancesResult.response).items || [];
668+
const variables = /** @type {{ items: any[] }} */ (variablesResult.response).items || [];
683669

684670
// Build a map: elementId -> set of elementInstanceKeys
685671
const elementIdToKeys = new Map();

lib/components/Output/Output.jsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,19 @@ function capitalize(string) {
401401
return string.replace(/([A-Z])/g, ' $1').replace(/^./, (match) => match.toUpperCase());
402402
}
403403

404+
/**
405+
* @param {Object} props
406+
* @param {string} props.title
407+
* @param {string} [props.tooltip]
408+
* @param {boolean} [props.defaultOpen]
409+
* @param {boolean} [props.isExecuting]
410+
* @param {React.ReactNode} props.children
411+
*/
404412
function CollapsibleSection({ title, tooltip, defaultOpen = true, isExecuting = false, children }) {
405413
const [ isOpen, setIsOpen ] = useState(defaultOpen);
406414
const [ isStuck, setIsStuck ] = useState(false);
415+
416+
/** @type {React.MutableRefObject<HTMLDivElement|null>} */
407417
const sentinelRef = useRef(null);
408418

409419
useEffect(() => {

lib/components/TaskTesting/TaskTesting.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,9 +174,12 @@ export default function TaskTesting({
174174
*/
175175
const [ executionLog, setExecutionLog ] = useState([]);
176176
const executionLogModelRef = useRef(new ExecutionLogModel());
177+
/** @type {React.MutableRefObject<number|null>} */
177178
const executionStartTimeRef = useRef(null);
178179

179-
const [ liveVariables, setLiveVariables ] = useState(null);
180+
/** @type {[import('../../types').ElementOutputVariables|null, Function]} */
181+
const [ liveVariables, setLiveVariables ] = useState(/** @type {import('../../types').ElementOutputVariables|null} */ (null));
182+
/** @type {React.MutableRefObject<import('../../types').ElementOutputVariables|null>} */
180183
const liveVariablesRef = useRef(null);
181184

182185
const [ executionCompleted, setExecutionCompleted ] = useState(false);
@@ -311,7 +314,7 @@ export default function TaskTesting({
311314
const log = executionLogModelRef.current.getEntries();
312315

313316
// Compute variables from raw API responses for success and incident results
314-
const variables = result.variablesResult?.success && result.elementInstancesResult?.success
317+
const variables = ('variablesResult' in result) && result.variablesResult?.success && result.elementInstancesResult?.success
315318
? getVariables(
316319
result.variablesResult.response.items,
317320
result.elementInstancesResult.response.items,
@@ -363,7 +366,7 @@ export default function TaskTesting({
363366
onTaskExecutionFinished(element, result);
364367
};
365368

366-
/** @param {Object} pollData */
369+
/** @param {import('../../types').TaskExecutionPollData} pollData */
367370
const handlePoll = (pollData) => {
368371

369372
// Compute live variables from poll data
@@ -734,9 +737,9 @@ function TabContainer({ selectedIndex = 0, children }) {
734737
}, [ selectedIndex ]);
735738

736739
const tabs = useMemo(() => {
737-
return React.Children.toArray(children).filter(
738-
child => child.type === TabItem
739-
);
740+
return /** @type {React.ReactElement[]} */ (React.Children.toArray(children).filter(
741+
child => /** @type {React.ReactElement} */ (child).type === TabItem
742+
));
740743
}, [ children ]);
741744

742745
return (
@@ -762,7 +765,10 @@ function TabContainer({ selectedIndex = 0, children }) {
762765
);
763766
}
764767

765-
function TabItem() {
768+
/**
769+
* @param {{ label?: string, children?: React.ReactNode }} _props
770+
*/
771+
function TabItem(_props) {
766772
return null;
767773
}
768774

lib/types.d.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import type {
44
SearchProcessInstanceResponse,
55
SearchVariablesResponse,
66
SearchElementInstancesResponse,
7-
SearchIncidentsResponse
7+
SearchIncidentsResponse,
8+
SearchUserTasksResponse
89
} from '@camunda8/sdk/dist/c8/lib/C8Dto';
910

1011
import { TASK_EXECUTION_REASON } from './constants';
@@ -17,7 +18,7 @@ export type Output = {
1718
[elementId: string]: ElementOutput
1819
};
1920

20-
export type VARIABLE_SCOPE = 'LOCAL' | 'PROCESS';
21+
export type VARIABLE_SCOPE = 'LOCAL' | 'PROCESS' | null;
2122

2223
export type ElementOutputVariables = {
2324
[id: string]: {
@@ -90,6 +91,7 @@ export type WaitingItem =
9091
| {
9192
type: 'event-sub-process';
9293
data: any;
94+
children?: any[];
9395
};
9496

9597
export type WaitingState = {
@@ -134,6 +136,10 @@ export type ExecutionLogEntry =
134136
type: 'children';
135137
items: ChildElement[];
136138
timestamp: number;
139+
}
140+
| {
141+
type: 'poll';
142+
[key: string]: any;
137143
};
138144

139145
export type TaskExecutionStatus =
@@ -142,6 +148,7 @@ export type TaskExecutionStatus =
142148
'starting-instance' |
143149
'executing' |
144150
'completed' |
151+
'incident' |
145152
'canceled';
146153

147154
export type TaskExecutionEvents =
@@ -193,6 +200,30 @@ export type TaskExecutionError = {
193200
response?: any;
194201
};
195202

203+
export type TaskExecutionPollData = {
204+
jobsResult: ApiResponse<{ items: any[] }>; // TODO: type properly once types are available in SDK
205+
userTasksResult: ApiResponse<SearchUserTasksResponse>;
206+
messageSubscriptionsResult: ApiResponse<{ items: any[] }>; // TODO: type properly once types are available in SDK
207+
elementInstancesResult: ApiResponse<SearchElementInstancesResponse>;
208+
variablesResult?: ApiResponse<SearchVariablesResponse>;
209+
processInstanceResult?: ApiResponse<SearchProcessInstanceResponse>;
210+
processInstanceKey: string;
211+
elementId: string;
212+
childElementIds?: Set<string>;
213+
getChildIds?: (parentId: string) => Set<string>;
214+
timestamp: number;
215+
};
216+
217+
export type WaitingItemDetail = {
218+
label: string;
219+
value: string;
220+
};
221+
222+
export type WaitingItemBadge = {
223+
text: string;
224+
variant?: string;
225+
};
226+
196227
export type { Element, ModdleElement } from 'bpmn-js/lib/model/Types';
197228

198229
export type Plugin = {

lib/utils/variables.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { has, isObject } from 'min-dash';
22

3+
/**
4+
* @type {{ LOCAL: 'LOCAL', PROCESS: 'PROCESS' }}
5+
*/
36
export const SCOPES = {
47
LOCAL: 'LOCAL',
58
PROCESS: 'PROCESS'
@@ -16,6 +19,8 @@ export const SCOPES = {
1619
* @returns {import('../types').ElementOutputVariables}
1720
*/
1821
export function getVariables(variableItems, elementInstanceItems, processInstanceKey, elementId) {
22+
23+
/** @type {import('../types').ElementOutputVariables} */
1924
const variables = {};
2025

2126
for (const item of variableItems) {
@@ -41,6 +46,13 @@ export function getVariables(variableItems, elementInstanceItems, processInstanc
4146
return variables;
4247
}
4348

49+
/**
50+
* @param {Object} variable
51+
* @param {Array} elementInstances
52+
* @param {string} processInstanceKey
53+
* @param {string} elementId
54+
* @returns {import('../types').VARIABLE_SCOPE}
55+
*/
4456
function getScope(variable, elementInstances, processInstanceKey, elementId) {
4557
const { scopeKey } = variable;
4658

0 commit comments

Comments
 (0)